diff --git a/bootstrap/src/main/java/io/bitsquare/app/bootstrap/BootstrapNode.java b/bootstrap/src/main/java/io/bitsquare/app/bootstrap/BootstrapNode.java index 0afd70e990..8c5552abcd 100644 --- a/bootstrap/src/main/java/io/bitsquare/app/bootstrap/BootstrapNode.java +++ b/bootstrap/src/main/java/io/bitsquare/app/bootstrap/BootstrapNode.java @@ -44,9 +44,6 @@ public class BootstrapNode { private static final String VERSION = "0.1.3"; - public static final String P2P_ID = "node.p2pId"; - public static int DEFAULT_P2P_ID = 2; // 0 | 1 | 2 for mainnet/testnet/regtest - private static Peer peer = null; private final Environment env; @@ -58,9 +55,9 @@ public class BootstrapNode { public void start() { - int p2pId = env.getProperty(P2P_ID, Integer.class, DEFAULT_P2P_ID); - int port = env.getProperty(Node.PORT_KEY, Integer.class, BootstrapNodes.BASE_PORT + p2pId); - String name = env.getProperty(Node.NAME_KEY, BootstrapNodes.LOCALHOST.getName()); + String name = env.getProperty(Node.NAME_KEY, BootstrapNodes.getLocalhostNode().getName()); + int p2pId = env.getProperty(Node.P2P_ID_KEY, Integer.class, BootstrapNodes.getLocalhostNode().getP2pId()); + int port = env.getProperty(Node.PORT_KEY, Integer.class, BootstrapNodes.getLocalhostNode().getPort()); Logging.setup(name + "_" + port); try { @@ -89,16 +86,17 @@ public class BootstrapNode { PeerDHT peerDHT = new PeerBuilderDHT(peer).start(); new PeerBuilderNAT(peer).start(); - if (!name.equals(BootstrapNodes.LOCALHOST.getName())) { - Collection bootstrapNodes = BootstrapNodes.getAllBootstrapNodes().stream().filter(e -> !e.getName().equals(name)) - .map(e -> e.toPeerAddressWithPort(port)).collect(Collectors.toList()); + final int _port = port; + if (!name.equals(BootstrapNodes.getLocalhostNode().getName())) { + Collection bootstrapNodes = BootstrapNodes.getAllBootstrapNodes(p2pId).stream().filter(e -> !e.getName().equals(name)) + .map(e -> e.toPeerAddressWithPort(_port)).collect(Collectors.toList()); log.info("Bootstrapping to " + bootstrapNodes.size() + " bootstrapNode(s)"); log.info("Bootstrapping bootstrapNodes " + bootstrapNodes); peer.bootstrap().bootstrapTo(bootstrapNodes).start().awaitUninterruptibly(); } else { - log.info("Localhost, no bootstrap"); + log.info("We are localhost, we do not bootstrap to other nodes"); } peer.peerBean().peerMap().addPeerMapChangeListener(new PeerMapChangeListener() { @Override @@ -129,7 +127,7 @@ public class BootstrapNode { } }); - log.info("Bootstrap node started with name " + name + " ,port " + port + " and version " + VERSION); + log.info("Bootstrap node started with name=" + name + " ,p2pId=" + p2pId + " ,port=" + port + " and version=" + VERSION); new Thread(() -> { while (true) { if (peer.peerBean().peerMap().all().size() > 0) { diff --git a/bootstrap/src/main/java/io/bitsquare/app/bootstrap/BootstrapNodeMain.java b/bootstrap/src/main/java/io/bitsquare/app/bootstrap/BootstrapNodeMain.java index 64a8c9039f..438c4141a6 100644 --- a/bootstrap/src/main/java/io/bitsquare/app/bootstrap/BootstrapNodeMain.java +++ b/bootstrap/src/main/java/io/bitsquare/app/bootstrap/BootstrapNodeMain.java @@ -32,13 +32,14 @@ public class BootstrapNodeMain extends BitsquareExecutable { } protected void customizeOptionParsing(OptionParser parser) { - parser.accepts(Node.NAME_KEY, description("Name of this node", BootstrapNodes.LOCALHOST.getName())) + parser.accepts(Node.NAME_KEY, description("Name of this node", BootstrapNodes.getLocalhostNode().getName())) .withRequiredArg() .ofType(String.class); - parser.accepts(Node.PORT_KEY, description("Port to listen on", BootstrapNodes.BASE_PORT)) + parser.accepts(Node.P2P_ID_KEY, description("P2P network ID", + BootstrapNodes.getLocalhostNode().getP2pId())) .withRequiredArg() .ofType(int.class); - parser.accepts(BootstrapNode.P2P_ID, description("P2P Network ID [0 | 1 | 2 for mainnet/testnet/regtest]", BootstrapNode.DEFAULT_P2P_ID)) + parser.accepts(Node.PORT_KEY, description("Port to listen on", BootstrapNodes.getLocalhostNode().getPort())) .withRequiredArg() .ofType(int.class); } diff --git a/core/src/main/java/io/bitsquare/app/BitsquareEnvironment.java b/core/src/main/java/io/bitsquare/app/BitsquareEnvironment.java index 5c864266a2..9d6cc6ed59 100644 --- a/core/src/main/java/io/bitsquare/app/BitsquareEnvironment.java +++ b/core/src/main/java/io/bitsquare/app/BitsquareEnvironment.java @@ -21,7 +21,6 @@ import io.bitsquare.BitsquareException; import io.bitsquare.btc.UserAgent; import io.bitsquare.btc.WalletService; import io.bitsquare.crypto.KeyStorage; -import io.bitsquare.p2p.BootstrapNodes; import io.bitsquare.p2p.tomp2p.TomP2PModule; import io.bitsquare.storage.Storage; import io.bitsquare.util.Utilities; @@ -88,7 +87,7 @@ public class BitsquareEnvironment extends StandardEnvironment { appDataDir(userDataDir, appName); this.bootstrapNodePort = commandLineProperties.containsProperty(TomP2PModule.BOOTSTRAP_NODE_PORT_KEY) ? - (String) commandLineProperties.getProperty(TomP2PModule.BOOTSTRAP_NODE_PORT_KEY) : String.valueOf(BootstrapNodes.BASE_PORT); + (String) commandLineProperties.getProperty(TomP2PModule.BOOTSTRAP_NODE_PORT_KEY) : "-1"; MutablePropertySources propertySources = this.getPropertySources(); propertySources.addFirst(commandLineProperties); diff --git a/core/src/main/java/io/bitsquare/p2p/BootstrapNodes.java b/core/src/main/java/io/bitsquare/p2p/BootstrapNodes.java index e2ce52d0ec..de367dd812 100644 --- a/core/src/main/java/io/bitsquare/p2p/BootstrapNodes.java +++ b/core/src/main/java/io/bitsquare/p2p/BootstrapNodes.java @@ -17,9 +17,12 @@ package io.bitsquare.p2p; +import io.bitsquare.BitsquareException; + import java.util.Arrays; import java.util.List; import java.util.Random; +import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,27 +30,72 @@ import org.slf4j.LoggerFactory; public class BootstrapNodes { private static final Logger log = LoggerFactory.getLogger(BootstrapNodes.class); - public static final int BASE_PORT = 7366; // port will be evaluated from btc network 7366 for mainnet, 7367 for testnet and 7368 for regtest - - private static List bootstrapNodes = Arrays.asList( - Node.at("digitalocean1.bitsquare.io", "188.226.179.109", BASE_PORT), - Node.at("aws1.bitsquare.io", "52.24.144.42", BASE_PORT), - Node.at("aws2.bitsquare.io", "52.11.125.194", BASE_PORT) + private static final List bootstrapNodes = Arrays.asList( + Node.at("digitalocean1.bitsquare.io", "188.226.179.109"), + Node.at("aws1.bitsquare.io", "52.24.144.42"), + Node.at("aws2.bitsquare.io", "52.11.125.194") ); + private static Node selectedNode; - /** - * A locally-running BootstrapNode instance. - * Typically used only for testing. Not included in results from {@link #getAllBootstrapNodes()}. - */ - public static Node LOCALHOST = Node.at("localhost", "127.0.0.1", BASE_PORT); + public static List getAllBootstrapNodes(int p2pId) { + switch (p2pId) { + case Node.MAIN_NET_P2P_ID: + return bootstrapNodes.stream().map(e -> e.withP2pIdAndPort(Node.MAIN_NET_P2P_ID, Node.MAIN_NET_PORT)).collect(Collectors.toList()); + case Node.TEST_NET_P2P_ID: + return bootstrapNodes.stream().map(e -> e.withP2pIdAndPort(Node.TEST_NET_P2P_ID, Node.TEST_NET_PORT)).collect(Collectors.toList()); + case Node.REG_TEST_P2P_ID: + return bootstrapNodes.stream().map(e -> e.withP2pIdAndPort(Node.REG_TEST_P2P_ID, Node.REG_TEST_PORT)).collect(Collectors.toList()); + default: + throw new BitsquareException("Unsupported P2pId. p2pId=" + p2pId); + } + } - private static Node selectedNode = bootstrapNodes.get(new Random().nextInt(bootstrapNodes.size())); + public static Node selectNode(int p2pId) { + if (selectedNode == null) + selectedNode = getAllBootstrapNodes(p2pId).get(new Random().nextInt(bootstrapNodes.size())); + else + throw new BitsquareException("selectNode must be called only once."); - public static List getAllBootstrapNodes() { - return bootstrapNodes; + return selectedNode; } public static Node getSelectedNode() { + if (selectedNode == null) + throw new BitsquareException("selectNode must be called first."); + return selectedNode; } + + public static Node getFallbackNode() { + if (bootstrapNodes.size() > 1) + return BootstrapNodes.getAllBootstrapNodes(selectedNode.getP2pId()).stream().filter(e -> !e.equals(selectedNode)).findAny().get(); + else + return null; + + } + + // Localhost default use regtest + private static Node localhostNode = selectLocalhostNode(Node.REG_TEST_P2P_ID); + + public static Node selectLocalhostNode(int p2pId) { + final Node localhostNode = Node.at("localhost", "127.0.0.1"); + switch (p2pId) { + case Node.MAIN_NET_P2P_ID: + BootstrapNodes.localhostNode = localhostNode.withP2pIdAndPort(Node.MAIN_NET_P2P_ID, Node.MAIN_NET_PORT); + break; + case Node.TEST_NET_P2P_ID: + BootstrapNodes.localhostNode = localhostNode.withP2pIdAndPort(Node.TEST_NET_P2P_ID, Node.TEST_NET_PORT); + break; + case Node.REG_TEST_P2P_ID: + BootstrapNodes.localhostNode = localhostNode.withP2pIdAndPort(Node.REG_TEST_P2P_ID, Node.REG_TEST_PORT); + break; + default: + throw new BitsquareException("Unsupported P2pId. p2pId=" + p2pId); + } + return BootstrapNodes.localhostNode; + } + + public static Node getLocalhostNode() { + return localhostNode; + } } diff --git a/core/src/main/java/io/bitsquare/p2p/ClientNode.java b/core/src/main/java/io/bitsquare/p2p/ClientNode.java index b4e0e3b045..5f06f3cb0e 100644 --- a/core/src/main/java/io/bitsquare/p2p/ClientNode.java +++ b/core/src/main/java/io/bitsquare/p2p/ClientNode.java @@ -30,9 +30,9 @@ import rx.Observable; public interface ClientNode { BootstrappedPeerBuilder.ConnectionType getConnectionType(); - Node getAddress(); + String getClientNodeInfo(); - Node getBootstrapNodeAddress(); + Node getBootstrapNode(); Observable bootstrap(int networkId, KeyPair keyPair); diff --git a/core/src/main/java/io/bitsquare/p2p/Node.java b/core/src/main/java/io/bitsquare/p2p/Node.java index 24e3747cb3..177a86b867 100644 --- a/core/src/main/java/io/bitsquare/p2p/Node.java +++ b/core/src/main/java/io/bitsquare/p2p/Node.java @@ -36,52 +36,54 @@ public final class Node { public static final String NAME_KEY = "node.name"; public static final String PORT_KEY = "node.port"; + public static final String P2P_ID_KEY = "node.p2pId"; + + //public static int DEFAULT_PORT = findFreeSystemPort(); + + // P2P network ids + public static final int MAIN_NET_P2P_ID = 10; + public static final int TEST_NET_P2P_ID = 11; + public static final int REG_TEST_P2P_ID = 12; + + // ports + public static final int MAIN_NET_PORT = 7370; + public static final int TEST_NET_PORT = 7371; + public static final int REG_TEST_PORT = 7372; - public static int DEFAULT_PORT = findFreeSystemPort(); private final String name; private final String ip; private final int port; + private final int p2pId; - private Node(String name, String ip, int port) { + private Node(String name, String ip, int p2pId, int port) { this.name = name; this.ip = ip; + this.p2pId = p2pId; this.port = port; } + // Not fully defined node public static Node at(String name, String ip) { - return Node.at(name, ip, DEFAULT_PORT); + return Node.at(name, ip, -1, -1); } - public static Node at(String name, String ip, int port) { - return new Node(name, ip, port); + public static Node at(String name, String ip, int p2pId, int port) { + return new Node(name, ip, p2pId, port); } - public static Node at(String name, String ip, String port) { - return new Node(name, ip, Integer.valueOf(port)); + public Node withP2pIdAndPort(int p2pId, int port) { + return Node.at(this.name, this.ip, p2pId, port); } - public String getName() { - return name; - } + /* public static Node at(String name, int p2pId, String ip) { + return Node.at(name, ip, p2pId, DEFAULT_PORT); + }*/ - public String getIp() { - return ip; - } + public static final int CLIENT_PORT = findFreeSystemPort(); - public int getPort() { - return port; - } - - /** - * Return a copy of this node with the port updated to the given value. - */ - public Node withPort(int newPort) { - return Node.at(this.name, this.ip, newPort); - } - - private static int findFreeSystemPort() { - int port = 7366; + public static int findFreeSystemPort() { + int port = 7369; try { ServerSocket server = new ServerSocket(0); port = server.getLocalPort(); @@ -101,11 +103,29 @@ public final class Node { port, port); } catch (UnknownHostException e) { - log.error("toPeerAddress failed: " + e.getMessage()); - return null; + log.error(e.getMessage()); + throw new RuntimeException(e); } } + + public String getName() { + return name; + } + + public String getIp() { + return ip; + } + + public int getP2pId() { + return p2pId; + } + + public int getPort() { + return port; + } + + @Override public boolean equals(Object object) { if (this == object) @@ -125,11 +145,19 @@ public final class Node { return Objects.hashCode(name, ip, port); } + public String getClientNodeInfo() { + return "Node with: " + + ", ip='" + ip + '\'' + + ", p2pId='" + p2pId + '\'' + + ", port=" + port; + } + @Override public String toString() { return "Node with: " + - "name='" + name + '\'' + - ", ip='" + ip + '\'' + - ", port=" + port; + "Name='" + name + '\'' + + "; IP='" + ip + '\'' + + "; P2P network ID=" + p2pId + + "; port=" + port; } } diff --git a/core/src/main/java/io/bitsquare/p2p/tomp2p/BootstrappedPeerBuilder.java b/core/src/main/java/io/bitsquare/p2p/tomp2p/BootstrappedPeerBuilder.java index 0da9545450..dde18f6084 100644 --- a/core/src/main/java/io/bitsquare/p2p/tomp2p/BootstrappedPeerBuilder.java +++ b/core/src/main/java/io/bitsquare/p2p/tomp2p/BootstrappedPeerBuilder.java @@ -32,7 +32,6 @@ import java.net.UnknownHostException; import java.security.KeyPair; -import java.util.Optional; import java.util.concurrent.Executor; import javax.inject.Inject; @@ -167,11 +166,27 @@ public class BootstrappedPeerBuilder { this.executor = executor; } - public SettableFuture start(int networkId) { + public SettableFuture start(int p2pId) { try { - // port is evaluated from btc network. 7366 for mainnet, 7367 for testnet and 7368 for regtest - bootstrapNode = Node.at(bootstrapNode.getName(), bootstrapNode.getIp(), bootstrapNode.getPort() + networkId); - log.debug("Bootstrap to {} with networkId {}", bootstrapNode.toString(), networkId); + Node selectedNode = BootstrapNodes.selectNode(p2pId); + String bootstrapNodeName = bootstrapNode.getName(); + if (bootstrapNodeName == null) + bootstrapNodeName = selectedNode.getName(); + + String bootstrapNodeIp = bootstrapNode.getIp(); + if (bootstrapNodeIp == null) + bootstrapNodeIp = selectedNode.getIp(); + + int bootstrapNodeP2pId = bootstrapNode.getP2pId(); + if (bootstrapNodeP2pId == -1) + bootstrapNodeP2pId = selectedNode.getP2pId(); + + int bootstrapNodePort = bootstrapNode.getPort(); + if (bootstrapNodePort == -1) + bootstrapNodePort = selectedNode.getPort(); + + bootstrapNode = Node.at(bootstrapNodeName, bootstrapNodeIp, bootstrapNodeP2pId, bootstrapNodePort); + log.debug("Bootstrap to {}", bootstrapNode.toString()); DefaultEventExecutorGroup eventExecutorGroup = new DefaultEventExecutorGroup(20); ChannelClientConfiguration clientConf = PeerBuilder.createDefaultChannelClientConfiguration(); @@ -187,7 +202,7 @@ public class BootstrappedPeerBuilder { if (useManualPortForwarding) { peer = new PeerBuilder(keyPair) - .p2pId(networkId) + .p2pId(p2pId) .channelClientConfiguration(clientConf) .channelServerConfiguration(serverConf) .ports(port) @@ -198,7 +213,7 @@ public class BootstrappedPeerBuilder { } else { peer = new PeerBuilder(keyPair) - .p2pId(networkId) + .p2pId(p2pId) .channelClientConfiguration(clientConf) .channelServerConfiguration(serverConf) .ports(port) @@ -294,19 +309,16 @@ public class BootstrappedPeerBuilder { bootstrap(); } else { - if (!retriedOtherBootstrapNode && BootstrapNodes.getAllBootstrapNodes().size() > 1) { - log.warn("Bootstrap failed with bootstrapNode: " + bootstrapNode + ". We try again with another node."); + Node fallbackNode = BootstrapNodes.getFallbackNode(); + if (!retriedOtherBootstrapNode && fallbackNode != null) { retriedOtherBootstrapNode = true; - Optional optional = BootstrapNodes.getAllBootstrapNodes().stream().filter(e -> !e.equals(bootstrapNode)).findAny(); - if (optional.isPresent()) { - bootstrapNode = optional.get(); - executor.execute(() -> discoverExternalAddress()); - } + bootstrapNode = fallbackNode; + log.warn("Bootstrap failed with bootstrapNode: " + bootstrapNode + ". We try again with another node."); + executor.execute(() -> discoverExternalAddress()); } else { // All attempts failed. Give up... - handleError(State.RELAY_FAILED, "NAT traversal using relay mode failed " + - futureRelayNAT.failedReason()); + handleError(State.RELAY_FAILED, "NAT traversal using relay mode failed " + futureRelayNAT.failedReason()); } } } @@ -351,19 +363,16 @@ public class BootstrappedPeerBuilder { bootstrap(); } else { - if (!retriedOtherBootstrapNode && BootstrapNodes.getAllBootstrapNodes().size() > 1) { - log.warn("Bootstrap failed with bootstrapNode: " + bootstrapNode + ". We try again with another node."); + Node fallbackNode = BootstrapNodes.getFallbackNode(); + if (!retriedOtherBootstrapNode && fallbackNode != null) { retriedOtherBootstrapNode = true; - Optional optional = BootstrapNodes.getAllBootstrapNodes().stream().filter(e -> !e.equals(bootstrapNode)).findAny(); - if (optional.isPresent()) { - bootstrapNode = optional.get(); - executor.execute(() -> discoverExternalAddress()); - } + bootstrapNode = fallbackNode; + log.warn("Bootstrap failed with bootstrapNode: " + bootstrapNode + ". We try again with another node."); + executor.execute(() -> discoverExternalAddress()); } else { // All attempts failed. Give up... - handleError(State.RELAY_FAILED, "NAT traversal using relay mode failed " + - futureRelayNAT.failedReason()); + handleError(State.RELAY_FAILED, "NAT traversal using relay mode failed " + futureRelayNAT.failedReason()); } } } diff --git a/core/src/main/java/io/bitsquare/p2p/tomp2p/TomP2PModule.java b/core/src/main/java/io/bitsquare/p2p/tomp2p/TomP2PModule.java index 10004de9a6..ef22157ea2 100644 --- a/core/src/main/java/io/bitsquare/p2p/tomp2p/TomP2PModule.java +++ b/core/src/main/java/io/bitsquare/p2p/tomp2p/TomP2PModule.java @@ -18,7 +18,6 @@ package io.bitsquare.p2p.tomp2p; import io.bitsquare.p2p.AddressService; -import io.bitsquare.p2p.BootstrapNodes; import io.bitsquare.p2p.ClientNode; import io.bitsquare.p2p.MailboxService; import io.bitsquare.p2p.MessageService; @@ -40,6 +39,7 @@ public class TomP2PModule extends P2PModule { private static final Logger log = LoggerFactory.getLogger(TomP2PModule.class); public static final String BOOTSTRAP_NODE_NAME_KEY = "bootstrap.node.name"; public static final String BOOTSTRAP_NODE_IP_KEY = "bootstrap.node.ip"; + public static final String BOOTSTRAP_NODE_P2P_ID_KEY = "bootstrap.node.p2pId"; public static final String BOOTSTRAP_NODE_PORT_KEY = "bootstrap.node.port"; public static final String NETWORK_INTERFACE_KEY = BootstrappedPeerBuilder.NETWORK_INTERFACE_KEY; public static final String USE_MANUAL_PORT_FORWARDING_KEY = BootstrappedPeerBuilder.USE_MANUAL_PORT_FORWARDING_KEY; @@ -60,16 +60,16 @@ public class TomP2PModule extends P2PModule { bind(MessageService.class).to(TomP2PMessageService.class).in(Singleton.class); bind(MailboxService.class).to(TomP2PMailboxService.class).in(Singleton.class); - bind(int.class).annotatedWith(Names.named(Node.PORT_KEY)).toInstance(env.getProperty(Node.PORT_KEY, int.class, Node.DEFAULT_PORT)); + bind(int.class).annotatedWith(Names.named(Node.PORT_KEY)).toInstance(env.getProperty(Node.PORT_KEY, int.class, Node.CLIENT_PORT)); bind(boolean.class).annotatedWith(Names.named(USE_MANUAL_PORT_FORWARDING_KEY)).toInstance( env.getProperty(USE_MANUAL_PORT_FORWARDING_KEY, boolean.class, false)); bind(Node.class).annotatedWith(Names.named(BOOTSTRAP_NODE_KEY)).toInstance( - Node.at(env.getProperty(BOOTSTRAP_NODE_NAME_KEY, BootstrapNodes.getSelectedNode().getName()), - env.getProperty(BOOTSTRAP_NODE_IP_KEY, BootstrapNodes.getSelectedNode().getIp()), - env.getProperty(BOOTSTRAP_NODE_PORT_KEY, int.class, BootstrapNodes.getSelectedNode().getPort()) - ) - ); + Node.at(env.getProperty(BOOTSTRAP_NODE_NAME_KEY, ""), + env.getProperty(BOOTSTRAP_NODE_IP_KEY, ""), + Integer.valueOf(env.getProperty(BOOTSTRAP_NODE_P2P_ID_KEY, "-1")), + Integer.valueOf(env.getProperty(BOOTSTRAP_NODE_PORT_KEY, "-1")) + )); bindConstant().annotatedWith(Names.named(NETWORK_INTERFACE_KEY)).to(env.getProperty(NETWORK_INTERFACE_KEY, NETWORK_INTERFACE_UNSPECIFIED)); } diff --git a/core/src/main/java/io/bitsquare/p2p/tomp2p/TomP2PNode.java b/core/src/main/java/io/bitsquare/p2p/tomp2p/TomP2PNode.java index bcef4754bb..81d6e647a8 100644 --- a/core/src/main/java/io/bitsquare/p2p/tomp2p/TomP2PNode.java +++ b/core/src/main/java/io/bitsquare/p2p/tomp2p/TomP2PNode.java @@ -91,7 +91,7 @@ public class TomP2PNode implements ClientNode { bootstrappedPeerBuilder.setExecutor(executor); } - public Observable bootstrap(int networkId, KeyPair keyPair) { + public Observable bootstrap(int p2pId, KeyPair keyPair) { bootstrappedPeerBuilder.setKeyPair(keyPair); bootstrappedPeerBuilder.getState().addListener((ov, oldValue, newValue) -> { @@ -99,7 +99,7 @@ public class TomP2PNode implements ClientNode { bootstrapStateSubject.onNext(newValue); }); - SettableFuture bootstrapFuture = bootstrappedPeerBuilder.start(networkId); + SettableFuture bootstrapFuture = bootstrappedPeerBuilder.start(p2pId); Futures.addCallback(bootstrapFuture, new FutureCallback() { @Override public void onSuccess(@Nullable PeerDHT peerDHT) { @@ -172,17 +172,15 @@ public class TomP2PNode implements ClientNode { return bootstrappedPeerBuilder.getConnectionType(); } - @Override - public Node getAddress() { + public String getClientNodeInfo() { PeerAddress peerAddress = peerDHT.peerBean().serverPeerAddress(); - return Node.at( - peerDHT.peerID().toString(), - peerAddress.inetAddress().getHostAddress(), - peerAddress.peerSocketAddress().tcpPort()); + return "IP='" + peerAddress.inetAddress().getHostAddress() + '\'' + + "; P2P network ID='" + peerDHT.peer().p2pId() + '\'' + + "; port=" + peerAddress.peerSocketAddress().tcpPort(); } @Override - public Node getBootstrapNodeAddress() { + public Node getBootstrapNode() { return bootstrappedPeerBuilder.getBootstrapNode(); } diff --git a/core/src/test/java/io/bitsquare/p2p/NodeTests.java b/core/src/test/java/io/bitsquare/p2p/NodeTests.java index da9d16df4a..b3e74f5bd7 100644 --- a/core/src/test/java/io/bitsquare/p2p/NodeTests.java +++ b/core/src/test/java/io/bitsquare/p2p/NodeTests.java @@ -39,23 +39,9 @@ public class NodeTests { assertThat(node1a, not(equalTo(Node.at("bitsquare2.example.com", node1a.getIp())))); assertThat(node1a, not(equalTo(Node.at(node1a.getName(), "203.0.113.2")))); - assertThat(node1a, not(equalTo(Node.at(node1a.getName(), node1a.getIp(), Node.DEFAULT_PORT + 1)))); Node node2 = Node.at("bitsquare2.example.com", "203.0.113.2"); assertThat(node1a.hashCode(), equalTo(node1b.hashCode())); assertThat(node1a.hashCode(), not(equalTo(node2.hashCode()))); - - assertThat(node1a.getPort(), equalTo(Node.DEFAULT_PORT)); - - Node node3a = Node.at("bitsquare3.example.com", "203.0.113.3", 1234); - Node node3b = Node.at("bitsquare3.example.com", "203.0.113.3", "1234"); - - assertThat(node3a, equalTo(node3b)); - } - - @Test - public void testToString() { - Node node = Node.at("bitsquare1.example.com", "203.0.113.1", 5001); - assertThat(node.toString(), equalTo("Node{name=bitsquare1.example.com, ip=203.0.113.1, port=5001}")); } } \ No newline at end of file diff --git a/core/src/test/java/io/bitsquare/msg/TomP2PTests.java b/core/src/test/java/io/bitsquare/p2p/TomP2PTests.java similarity index 97% rename from core/src/test/java/io/bitsquare/msg/TomP2PTests.java rename to core/src/test/java/io/bitsquare/p2p/TomP2PTests.java index 249fc07e12..e9dde3dae9 100644 --- a/core/src/test/java/io/bitsquare/msg/TomP2PTests.java +++ b/core/src/test/java/io/bitsquare/p2p/TomP2PTests.java @@ -15,10 +15,8 @@ * along with Bitsquare. If not, see . */ -package io.bitsquare.msg; +package io.bitsquare.p2p; -import io.bitsquare.p2p.BootstrapNodes; -import io.bitsquare.p2p.Node; import io.bitsquare.p2p.tomp2p.BootstrappedPeerBuilder; import io.bitsquare.util.Repeat; import io.bitsquare.util.RepeatRule; @@ -73,9 +71,9 @@ import static org.junit.Assert.*; /** * Test bootstrapping, DHT operations like put/get/add/remove and sendDirect in both LAN and WAN environment * Test scenarios in direct connection, auto port forwarding or relay mode. - *

- * To start a bootstrap node code use the {@link io.bitsquare.app.bootstrap.BootstrapNode} class. - *

+ *

+ * To start a bootstrap node use the {@link io.bitsquare.app.bootstrap.BootstrapNode} class. + *

* To configure your test environment edit the static fields for id, IP and port. * In the configure method and the connectionType you can define your test scenario. */ @@ -88,12 +86,20 @@ public class TomP2PTests { // Typically you run the bootstrap node in localhost to test direct connection. // If you have a setup where you are not behind a router you can also use a WAN bootstrap node. - private static final Node BOOTSTRAP_NODE = (FORCED_CONNECTION_TYPE == BootstrappedPeerBuilder.ConnectionType.DIRECT) ? - BootstrapNodes.LOCALHOST : Node.at("digitalocean1.dev.bitsquare.io", "188.226.179.109", 7367); + private static final Node BOOTSTRAP_NODE; private static final PeerAddress BOOTSTRAP_NODE_ADDRESS; static { + int p2pId = 1; + if (FORCED_CONNECTION_TYPE == BootstrappedPeerBuilder.ConnectionType.DIRECT) { + BootstrapNodes.selectLocalhostNode(p2pId); + BOOTSTRAP_NODE = BootstrapNodes.getLocalhostNode(); + } + else { + BOOTSTRAP_NODE = Node.at("digitalocean1.dev.bitsquare.io", "188.226.179.109", p2pId, 7367); + } + try { BOOTSTRAP_NODE_ADDRESS = new PeerAddress( Number160.createHash(BOOTSTRAP_NODE.getName()), @@ -312,9 +318,9 @@ public class TomP2PTests { PeerDHT peer1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash("peer1")).ports(3006).start()).start(); PeerDHT peer2 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash("peer2")).ports(3007).start()).start(); */ - PeerAddress masterPeerAddress = new PeerAddress(Number160.createHash(BootstrapNodes.LOCALHOST.getName()), - BootstrapNodes.LOCALHOST.getIp(), BootstrapNodes.LOCALHOST.getPort(), - BootstrapNodes.LOCALHOST.getPort()); + PeerAddress masterPeerAddress = new PeerAddress(Number160.createHash(BootstrapNodes.getLocalhostNode().getName()), + BootstrapNodes.getLocalhostNode().getIp(), BootstrapNodes.getLocalhostNode().getPort(), + BootstrapNodes.getLocalhostNode().getPort()); // start both at the same time BaseFuture fb1 = peer1.peer().bootstrap().peerAddress(masterPeerAddress).start(); diff --git a/gui/src/main/java/io/bitsquare/app/BitsquareAppMain.java b/gui/src/main/java/io/bitsquare/app/BitsquareAppMain.java index 1e1e8298b1..1675ecb63c 100644 --- a/gui/src/main/java/io/bitsquare/app/BitsquareAppMain.java +++ b/gui/src/main/java/io/bitsquare/app/BitsquareAppMain.java @@ -117,7 +117,7 @@ public class BitsquareAppMain extends BitsquareExecutable { .ofType(boolean.class); parser.accepts(NAME_KEY, description("Name of this node", null)) .withRequiredArg(); - parser.accepts(PORT_KEY, description("Port to listen on", Node.DEFAULT_PORT)) + parser.accepts(PORT_KEY, description("Port to listen on", Node.CLIENT_PORT)) .withRequiredArg() .ofType(int.class); parser.accepts(USE_MANUAL_PORT_FORWARDING_KEY, description("Use manual port forwarding", false)) @@ -134,11 +134,14 @@ public class BitsquareAppMain extends BitsquareExecutable { .withValuesConvertedBy(new EnumValueConverter(RegTestHost.class)); - parser.accepts(BOOTSTRAP_NODE_NAME_KEY, description("", BootstrapNodes.getSelectedNode().getName())) + parser.accepts(BOOTSTRAP_NODE_NAME_KEY, description("Bootstrap node name", BootstrapNodes.getLocalhostNode().getName())) .withRequiredArg(); - parser.accepts(BOOTSTRAP_NODE_IP_KEY, description("", BootstrapNodes.getSelectedNode().getIp())) + parser.accepts(BOOTSTRAP_NODE_IP_KEY, description("Bootstrap node IP", BootstrapNodes.getLocalhostNode().getIp())) .withRequiredArg(); - parser.accepts(BOOTSTRAP_NODE_PORT_KEY, description("", BootstrapNodes.getSelectedNode().getPort())) + parser.accepts(BOOTSTRAP_NODE_P2P_ID_KEY, description("Bootstrap node p2p network ID", BootstrapNodes.getLocalhostNode().getPort())) + .withRequiredArg() + .ofType(int.class); + parser.accepts(BOOTSTRAP_NODE_PORT_KEY, description("Bootstrap node port", BootstrapNodes.getLocalhostNode().getPort())) .withRequiredArg() .ofType(int.class); parser.accepts(NETWORK_INTERFACE_KEY, description("Network interface", null)) diff --git a/gui/src/main/java/io/bitsquare/gui/main/MainViewModel.java b/gui/src/main/java/io/bitsquare/gui/main/MainViewModel.java index fd505cdc85..283afb050e 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/MainViewModel.java +++ b/gui/src/main/java/io/bitsquare/gui/main/MainViewModel.java @@ -77,7 +77,7 @@ class MainViewModel implements ViewModel { private final OpenOfferManager openOfferManager; private final UpdateProcess updateProcess; private final BSFormatter formatter; - private final int networkId; + private final int p2pId; // BTC network final StringProperty blockchainSyncInfo = new SimpleStringProperty("Initializing"); @@ -132,7 +132,7 @@ class MainViewModel implements ViewModel { this.formatter = formatter; bitcoinNetworkAsString = formatter.formatBitcoinNetwork(preferences.getBitcoinNetwork()); - networkId = preferences.getBitcoinNetwork().ordinal(); + p2pId = preferences.getBitcoinNetwork().ordinal() + 10; // p2pId: Mainnet 10, testnet 11, regtest 12 updateProcess.state.addListener((observableValue, oldValue, newValue) -> applyUpdateState(newValue)); applyUpdateState(updateProcess.state.get()); @@ -206,7 +206,7 @@ class MainViewModel implements ViewModel { }); clientNode.setExecutor(Platform::runLater); - Observable bootstrapStateAsObservable = clientNode.bootstrap(networkId, keyRing.getDhtSignatureKeyPair()); + Observable bootstrapStateAsObservable = clientNode.bootstrap(p2pId, keyRing.getDhtSignatureKeyPair()); bootstrapStateAsObservable.publish(); bootstrapStateAsObservable.subscribe( state -> Platform.runLater(() -> setBootstrapState(state)), diff --git a/gui/src/main/java/io/bitsquare/gui/main/settings/network/NetworkSettingsView.java b/gui/src/main/java/io/bitsquare/gui/main/settings/network/NetworkSettingsView.java index 60e1361494..35eaffbae5 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/settings/network/NetworkSettingsView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/settings/network/NetworkSettingsView.java @@ -71,8 +71,8 @@ public class NetworkSettingsView extends InitializableView { connectionType.setText(clientNode.getConnectionType().toString()); connectedPeersP2P.textProperty().bind(createStringBinding(() -> String.valueOf(clientNode.numPeersProperty().get()), clientNode.numPeersProperty())); - nodeAddress.setText(clientNode.getAddress().toString()); - bootstrapNodeAddress.setText(clientNode.getBootstrapNodeAddress().toString()); + nodeAddress.setText(clientNode.getClientNodeInfo()); + bootstrapNodeAddress.setText(clientNode.getBootstrapNode().toString()); useUPnP.setSelected(preferences.getUseUPnP());