diff --git a/core/src/main/java/com/google/bitcoin/core/NetworkParameters.java b/core/src/main/java/com/google/bitcoin/core/NetworkParameters.java index 749dce59..f355a099 100644 --- a/core/src/main/java/com/google/bitcoin/core/NetworkParameters.java +++ b/core/src/main/java/com/google/bitcoin/core/NetworkParameters.java @@ -17,6 +17,7 @@ package com.google.bitcoin.core; import com.google.common.base.Objects; +import com.google.common.collect.Lists; import org.spongycastle.util.encoders.Hex; import java.io.ByteArrayOutputStream; @@ -31,8 +32,8 @@ import static com.google.common.base.Preconditions.checkState; /** *

NetworkParameters contains the data needed for working with an instantiation of a Bitcoin chain.

* - * Currently there are only two, the production chain and the test chain. But in future as Bitcoin - * evolves there may be more. You can create your own as long as they don't conflict. + *

Currently there are only two, the production chain and the test chain. There is also a "unit test chain" which + * is internal to bitcoinj and can't be used on a real network. In future there may be others.

*/ public class NetworkParameters implements Serializable { private static final long serialVersionUID = 3L; @@ -126,6 +127,11 @@ public class NetworkParameters implements Serializable { */ public final int[] acceptableAddressCodes; + /** + * DNS names that when resolved, give active peers on the network. Used to bootstrap the P2P connectivity. + */ + private final String[] dnsSeeds; + /** * Block checkpoints are a safety mechanism that hard-codes the hashes of blocks at particular heights. Re-orgs @@ -167,6 +173,13 @@ public class NetworkParameters implements Serializable { checkpoints.put(91842, new Sha256Hash("00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")); checkpoints.put(91880, new Sha256Hash("00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")); checkpoints.put(200000, new Sha256Hash("000000000000034a7dedef4a161fa058a2d67a173a90155f3a2fe6fc132e0ebf")); + + dnsSeeds = new String[] { + "seed.bitcoin.sipa.be", // Pieter Wuille + "dnsseed.bluematt.me", // Matt Corallo + "dnsseed.bitcoin.dashjr.org", // Luke Dashjr + "bitseed.xf2.org", // Jeff Garzik + }; } else if (type == 3) { // Testnet3 id = ID_TESTNET; @@ -188,6 +201,11 @@ public class NetworkParameters implements Serializable { String genesisHash = genesisBlock.getHashAsString(); checkState(genesisHash.equals("000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"), genesisHash); + + dnsSeeds = new String[] { + "testnet-seed.bitcoin.petertodd.org", + "testnet-seed.bluematt.me" + }; } else if (type == 2) { id = ID_TESTNET; packetMagic = 0xfabfb5daL; @@ -207,6 +225,7 @@ public class NetworkParameters implements Serializable { String genesisHash = genesisBlock.getHashAsString(); checkState(genesisHash.equals("00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008"), genesisHash); + dnsSeeds = null; } else if (type == -1) { id = ID_UNITTESTNET; packetMagic = 0x0b110907; @@ -223,6 +242,7 @@ public class NetworkParameters implements Serializable { spendableCoinbaseDepth = 5; acceptableAddressCodes = new int[] { 111 }; subsidyDecreaseBlockCount = 100; + dnsSeeds = null; } else { throw new RuntimeException(); } @@ -361,4 +381,9 @@ public class NetworkParameters implements Serializable { public int getSubsidyDecreaseBlockCount() { return subsidyDecreaseBlockCount; } + + /** Returns DNS names that when resolved, give IP addresses of active peers. */ + public String[] getDnsSeeds() { + return dnsSeeds; + } } diff --git a/core/src/main/java/com/google/bitcoin/core/PeerGroup.java b/core/src/main/java/com/google/bitcoin/core/PeerGroup.java index 72a407f0..9dcfd0ed 100644 --- a/core/src/main/java/com/google/bitcoin/core/PeerGroup.java +++ b/core/src/main/java/com/google/bitcoin/core/PeerGroup.java @@ -510,7 +510,7 @@ public class PeerGroup extends AbstractIdleService { Set addressSet = Sets.newHashSet(); for (PeerDiscovery peerDiscovery : peerDiscoverers) { InetSocketAddress[] addresses; - addresses = peerDiscovery.getPeers(10, TimeUnit.SECONDS); + addresses = peerDiscovery.getPeers(5, TimeUnit.SECONDS); for (InetSocketAddress address : addresses) addressSet.add(new PeerAddress(address)); if (addressSet.size() > 0) break; } diff --git a/core/src/main/java/com/google/bitcoin/discovery/DnsDiscovery.java b/core/src/main/java/com/google/bitcoin/discovery/DnsDiscovery.java index fdb9395b..32e66740 100644 --- a/core/src/main/java/com/google/bitcoin/discovery/DnsDiscovery.java +++ b/core/src/main/java/com/google/bitcoin/discovery/DnsDiscovery.java @@ -42,8 +42,7 @@ import java.util.concurrent.*; * *

DNS seeds do not attempt to enumerate every peer on the network. {@link DnsDiscovery#getPeers(long, java.util.concurrent.TimeUnit)} * will return up to 30 random peers from the set of those returned within the timeout period. If you want more peers - * to connect to, you need to discover them via other means (like addr broadcasts). - *

+ * to connect to, you need to discover them via other means (like addr broadcasts).

*/ public class DnsDiscovery implements PeerDiscovery { private static final Logger log = LoggerFactory.getLogger(DnsDiscovery.class); @@ -51,20 +50,13 @@ public class DnsDiscovery implements PeerDiscovery { private String[] hostNames; private NetworkParameters netParams; - public static final String[] defaultHosts = new String[]{ - "seed.bitcoin.sipa.be", // Pieter Wuille - "dnsseed.bluematt.me", // Matt Corallo - "dnsseed.bitcoin.dashjr.org", // Luke Dashjr - "bitseed.xf2.org", // Jeff Garzik - }; - /** * Supports finding peers through DNS A records. Community run DNS entry points will be used. * * @param netParams Network parameters to be used for port information. */ public DnsDiscovery(NetworkParameters netParams) { - this(getDefaultHostNames(), netParams); + this(netParams.getDnsSeeds(), netParams); } /** @@ -122,14 +114,7 @@ public class DnsDiscovery implements PeerDiscovery { ArrayList shuffledAddrs = new ArrayList(addrs); Collections.shuffle(shuffledAddrs); pool.shutdown(); - return shuffledAddrs.toArray(new InetSocketAddress[]{}); - } - - /** - * Returns the well known discovery host names on the production network. - */ - public static String[] getDefaultHostNames() { - return defaultHosts; + return shuffledAddrs.toArray(new InetSocketAddress[shuffledAddrs.size()]); } /** We don't have a way to abort a DNS lookup, so this does nothing */ diff --git a/core/src/main/java/com/google/bitcoin/discovery/IrcDiscovery.java b/core/src/main/java/com/google/bitcoin/discovery/IrcDiscovery.java index 005ebf2f..bdddb639 100644 --- a/core/src/main/java/com/google/bitcoin/discovery/IrcDiscovery.java +++ b/core/src/main/java/com/google/bitcoin/discovery/IrcDiscovery.java @@ -30,7 +30,10 @@ import java.util.concurrent.TimeUnit; /** * IrcDiscovery provides a way to find network peers by joining a pre-agreed rendevouz point on the LFnet IRC network. + * This class is deprecated because LFnet has ceased to operate and DNS seeds now exist for both prod and test + * networks. It may conceivably still be useful for running small ad-hoc networks by yourself. */ +@Deprecated public class IrcDiscovery implements PeerDiscovery { private static final Logger log = LoggerFactory.getLogger(IrcDiscovery.class); diff --git a/core/src/test/java/com/google/bitcoin/discovery/IrcDiscoveryTest.java b/core/src/test/java/com/google/bitcoin/discovery/IrcDiscoveryTest.java deleted file mode 100644 index b24b51c8..00000000 --- a/core/src/test/java/com/google/bitcoin/discovery/IrcDiscoveryTest.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright John Sample - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.bitcoin.discovery; - -import org.junit.Test; - -import java.net.InetSocketAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; - -import static org.junit.Assert.assertEquals; - -public class IrcDiscoveryTest { - // TODO: Inject a mock IRC server and more thoroughly exercise this class. - - @Test - public void testParseUserList() throws UnknownHostException { - // Test some random addresses grabbed from the channel. - String[] userList = new String[]{ "x201500200","u4stwEBjT6FYyVV", "u5BKEqDApa8SbA7"}; - - ArrayList addresses = IrcDiscovery.parseUserList(userList); - - // Make sure the "x" address is excluded. - assertEquals("Too many addresses.", 2, addresses.size()); - - String[] ips = new String[]{"69.4.98.82:8333","74.92.222.129:8333"}; - InetSocketAddress[] decoded = addresses.toArray(new InetSocketAddress[]{}); - - for (int i = 0; i < decoded.length; i++) { - String formattedIP = decoded[i].getAddress().getHostAddress() + ":" + ((Integer)decoded[i].getPort()) - .toString(); - assertEquals("IPs decoded improperly", ips[i], formattedIP); - } - } - -} diff --git a/examples/src/main/java/com/google/bitcoin/examples/PingService.java b/examples/src/main/java/com/google/bitcoin/examples/PingService.java index 4d032b03..f4c347de 100644 --- a/examples/src/main/java/com/google/bitcoin/examples/PingService.java +++ b/examples/src/main/java/com/google/bitcoin/examples/PingService.java @@ -19,7 +19,6 @@ package com.google.bitcoin.examples; import com.google.bitcoin.core.*; import com.google.bitcoin.crypto.KeyCrypterException; import com.google.bitcoin.discovery.DnsDiscovery; -import com.google.bitcoin.discovery.IrcDiscovery; import com.google.bitcoin.store.BlockStore; import com.google.bitcoin.store.SPVBlockStore; import com.google.bitcoin.utils.BriefLogFormatter; @@ -101,11 +100,7 @@ public class PingService { chain = new BlockChain(params, wallet, blockStore); peerGroup = new PeerGroup(params, chain); peerGroup.setUserAgent("PingService", "1.0"); - if (testNet) { - peerGroup.addPeerDiscovery(new IrcDiscovery("#bitcoinTEST3")); - } else { - peerGroup.addPeerDiscovery(new DnsDiscovery(params)); - } + peerGroup.addPeerDiscovery(new DnsDiscovery(params)); peerGroup.addWallet(wallet); // We want to know when the balance changes. diff --git a/examples/src/main/java/com/google/bitcoin/examples/PrintPeers.java b/examples/src/main/java/com/google/bitcoin/examples/PrintPeers.java index 012b9ef4..d87ea9ee 100644 --- a/examples/src/main/java/com/google/bitcoin/examples/PrintPeers.java +++ b/examples/src/main/java/com/google/bitcoin/examples/PrintPeers.java @@ -20,7 +20,6 @@ import com.google.bitcoin.core.NetworkParameters; import com.google.bitcoin.core.TCPNetworkConnection; import com.google.bitcoin.core.VersionMessage; import com.google.bitcoin.discovery.DnsDiscovery; -import com.google.bitcoin.discovery.IrcDiscovery; import com.google.bitcoin.discovery.PeerDiscoveryException; import com.google.bitcoin.utils.BriefLogFormatter; import com.google.common.collect.Lists; @@ -35,10 +34,10 @@ import java.util.List; import java.util.concurrent.TimeUnit; /** - * Prints a list of IP addresses connected to the rendezvous point on the LFnet IRC channel. + * Prints a list of IP addresses obtained from DNS. */ public class PrintPeers { - private static InetSocketAddress[] dnsPeers, ircPeers; + private static InetSocketAddress[] dnsPeers; private static void printElapsed(long start) { long now = System.currentTimeMillis(); @@ -48,28 +47,10 @@ public class PrintPeers { private static void printPeers(InetSocketAddress[] addresses) { for (InetSocketAddress address : addresses) { String hostAddress = address.getAddress().getHostAddress(); - System.out.println(String.format("%s:%d", hostAddress.toString(), address.getPort())); + System.out.println(String.format("%s:%d", hostAddress, address.getPort())); } } - private static void printIRC() throws PeerDiscoveryException { - long start = System.currentTimeMillis(); - IrcDiscovery d = new IrcDiscovery("#bitcoinTEST3") { - @Override - protected void onIRCReceive(String message) { - System.out.println("<- " + message); - } - - @Override - protected void onIRCSend(String message) { - System.out.println("-> " + message); - } - }; - ircPeers = d.getPeers(10, TimeUnit.SECONDS); - printPeers(ircPeers); - printElapsed(start); - } - private static void printDNS() throws PeerDiscoveryException { long start = System.currentTimeMillis(); DnsDiscovery dns = new DnsDiscovery(NetworkParameters.prodNet()); @@ -80,15 +61,12 @@ public class PrintPeers { public static void main(String[] args) throws Exception { BriefLogFormatter.init(); - System.out.println("=== IRC ==="); - printIRC(); System.out.println("=== DNS ==="); printDNS(); System.out.println("=== Version/chain heights ==="); ArrayList addrs = new ArrayList(); for (InetSocketAddress peer : dnsPeers) addrs.add(peer.getAddress()); - for (InetSocketAddress peer : ircPeers) addrs.add(peer.getAddress()); System.out.println("Scanning " + addrs.size() + " peers:"); final NetworkParameters params = NetworkParameters.prodNet(); diff --git a/examples/src/main/java/com/google/bitcoin/examples/toywallet/ToyWallet.java b/examples/src/main/java/com/google/bitcoin/examples/toywallet/ToyWallet.java index 2efa7cfa..43ae4b7d 100644 --- a/examples/src/main/java/com/google/bitcoin/examples/toywallet/ToyWallet.java +++ b/examples/src/main/java/com/google/bitcoin/examples/toywallet/ToyWallet.java @@ -18,8 +18,6 @@ package com.google.bitcoin.examples.toywallet; import com.google.bitcoin.core.*; import com.google.bitcoin.discovery.DnsDiscovery; -import com.google.bitcoin.discovery.IrcDiscovery; -import com.google.bitcoin.store.BoundedOverheadBlockStore; import com.google.bitcoin.store.H2FullPrunedBlockStore; import com.google.bitcoin.store.SPVBlockStore; import com.google.bitcoin.utils.BriefLogFormatter; @@ -174,11 +172,7 @@ public class ToyWallet { peerGroup = new PeerGroup(params, chain); peerGroup.setUserAgent("ToyWallet", "1.0"); - if (testnet) { - peerGroup.addPeerDiscovery(new IrcDiscovery("#bitcoinTEST3")); - } else { - peerGroup.addPeerDiscovery(new DnsDiscovery(params)); - } + peerGroup.addPeerDiscovery(new DnsDiscovery(params)); peerGroup.addWallet(wallet); // Watch for peers coming and going so we can update the UI. diff --git a/tools/src/main/java/com/google/bitcoin/tools/WalletTool.java b/tools/src/main/java/com/google/bitcoin/tools/WalletTool.java index 9b6f3fde..f1ed77dd 100644 --- a/tools/src/main/java/com/google/bitcoin/tools/WalletTool.java +++ b/tools/src/main/java/com/google/bitcoin/tools/WalletTool.java @@ -19,7 +19,6 @@ package com.google.bitcoin.tools; import com.google.bitcoin.core.*; import com.google.bitcoin.crypto.KeyCrypterException; import com.google.bitcoin.discovery.DnsDiscovery; -import com.google.bitcoin.discovery.IrcDiscovery; import com.google.bitcoin.discovery.PeerDiscovery; import com.google.bitcoin.store.*; import com.google.bitcoin.utils.BriefLogFormatter; @@ -272,17 +271,16 @@ public class WalletTool { logger = LogManager.getLogManager().getLogger(""); logger.setLevel(Level.SEVERE); } - + discovery = new DnsDiscovery(params); switch (netFlag.value(options)) { case PROD: params = NetworkParameters.prodNet(); chainFileName = new File("prodnet.chain"); - discovery = new DnsDiscovery(params); + break; case TEST: params = NetworkParameters.testNet(); chainFileName = new File("testnet.chain"); - discovery = new IrcDiscovery("#bitcoinTEST3"); break; default: throw new RuntimeException("Unreachable.");