Merge branch 'wip-cbeams'

* wip-cbeams: (24 commits)
  Allow configurability of bitcoin network with --bitcoin.network
  Eliminate BootstrapNodes#DIGITAL_OCEAN_1_DEV
  Move comments regarding default ports to Node#DEFAULT_PORT
  Rename BootstrapNodes#{DEFAULT_BOOTSTRAP_NODE=>DEFAULT}
  Rename app.cli.{SeedNode => BootstrapNode}
  Remove dead code from UtilsDHT2.java
  Remove commented code from SeedNode
  Remove obsolete SeedNodeForTesting class
  Rename networkInterface => interface
  Eliminate the option to use TomP2P disk storage (for now)
  Expose --port command-line option
  Rename Node#{id => name}
  Allow command-line configuration of local node id and port
  Polish whitespace
  Qualify id, ip and port options with 'bootstrap.node.*'
  Extract clientPort constant
  Introduce NETWORK_INTERFACE_UNSPECIFIED contstant
  Move {MessageModule=>TomP2PMessageModule}#NETWORK_INTERFACE_KEY
  Use extracted NETWORK_INTERFACE_KEY consistently
  Polish TomP2PMessageModule#doConfigure
  ...

Conflicts:
	src/test/java/io/bitsquare/msg/TomP2PTests.java
This commit is contained in:
Chris Beams 2014-11-10 15:43:28 +01:00
commit efe6c1bec9
No known key found for this signature in database
GPG key ID: 3D214F8F5BC5ED73
22 changed files with 251 additions and 638 deletions

View file

@ -1,80 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.msg;
import io.bitsquare.network.Node;
import net.tomp2p.connection.Bindings;
import net.tomp2p.connection.ChannelServerConfiguration;
import net.tomp2p.connection.Ports;
import net.tomp2p.connection.StandardProtocolFamily;
import net.tomp2p.dht.PeerBuilderDHT;
import net.tomp2p.nat.PeerBuilderNAT;
import net.tomp2p.p2p.Peer;
import net.tomp2p.p2p.PeerBuilder;
import net.tomp2p.peers.Number160;
import net.tomp2p.peers.PeerAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Used for testing with {@link TomP2PTests}
*/
public class SeedNodeForTesting {
private static final Logger log = LoggerFactory.getLogger(SeedNodeForTesting.class);
public static void main(String[] args) throws Exception {
Peer peer = null;
try {
ChannelServerConfiguration csc = PeerBuilder.createDefaultChannelServerConfiguration();
csc.ports(new Ports(Node.DEFAULT_PORT, Node.DEFAULT_PORT));
csc.portsForwarding(new Ports(Node.DEFAULT_PORT, Node.DEFAULT_PORT));
csc.connectionTimeoutTCPMillis(10 * 1000);
csc.idleTCPSeconds(10);
csc.idleUDPSeconds(10);
Bindings bindings = new Bindings();
bindings.addProtocol(StandardProtocolFamily.INET);
peer = new PeerBuilder(Number160.createHash("localhost")).bindings(bindings)
.channelServerConfiguration(csc).ports(Node.DEFAULT_PORT).start();
peer.objectDataReply((sender, request) -> {
log.trace("received request: ", request.toString());
return "pong";
});
// Needed for DHT support
new PeerBuilderDHT(peer).start();
// Needed for NAT support
new PeerBuilderNAT(peer).start();
log.debug("SeedNode started.");
for (; ; ) {
for (PeerAddress pa : peer.peerBean().peerMap().all()) {
log.debug("peer online:" + pa);
}
Thread.sleep(2000);
}
} catch (Exception e) {
if (peer != null)
peer.shutdown().awaitUninterruptibly();
}
}
}

View file

@ -70,7 +70,7 @@ 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.
* <p>
* The start a seed node code use the {@link SeedNodeForTesting} class.
* To start a bootstrap node code use the {@link io.bitsquare.app.cli.BootstrapNode} class.
* <p>
* 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.
@ -86,18 +86,17 @@ public class TomP2PTests {
// If you want to test in one specific connection mode define it directly, otherwise use UNKNOWN
private static final ConnectionType FORCED_CONNECTION_TYPE = ConnectionType.DIRECT;
// Typically you run the seed 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 side seed node.
private static final Node BOOTSTRAP_NODE =
(FORCED_CONNECTION_TYPE == ConnectionType.DIRECT) ? BootstrapNodes.LOCALHOST : BootstrapNodes
.DIGITAL_OCEAN_1_DEV;
// 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 == ConnectionType.DIRECT) ?
BootstrapNodes.LOCALHOST : BootstrapNodes.DIGITAL_OCEAN_1.withPort(7367);
private static final PeerAddress BOOTSTRAP_NODE_ADDRESS;
static {
try {
BOOTSTRAP_NODE_ADDRESS = new PeerAddress(
Number160.createHash(BOOTSTRAP_NODE.getId()),
Number160.createHash(BOOTSTRAP_NODE.getName()),
BOOTSTRAP_NODE.getIp(), BOOTSTRAP_NODE.getPort(), BOOTSTRAP_NODE.getPort());
} catch (UnknownHostException ex) {
throw new RuntimeException(BOOTSTRAP_NODE.toString(), ex);
@ -252,7 +251,7 @@ public class TomP2PTests {
futureRemove.awaitUninterruptibly();
futureRemove.awaitListenersUninterruptibly();
// We don't test futureRemove.isSuccess() as this API does not fit well to that operation,
// We don't test futureRemove.isSuccess() as this API does not fit well to that operation,
// it might change in future to something like foundAndRemoved and notFound
// See discussion at: https://github.com/tomp2p/TomP2P/issues/57#issuecomment-62069840
@ -305,7 +304,7 @@ public class TomP2PTests {
}
}
// That test should always succeed as we use the server seed node as receiver.
// This test should always succeed as we use the bootstrap node as receiver.
// A node can send a message to another peer which is not in the same LAN.
@Test
@Repeat(STRESS_TEST_COUNT)

View file

@ -38,8 +38,8 @@ public class NodeTests {
assertThat(node1a, not((Object) equalTo("not a node")));
assertThat(node1a, not(equalTo(Node.at("bitsquare2.example.com", node1a.getIp()))));
assertThat(node1a, not(equalTo(Node.at(node1a.getId(), "203.0.113.2"))));
assertThat(node1a, not(equalTo(Node.at(node1a.getId(), node1a.getIp(), Node.DEFAULT_PORT + 1))));
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()));
@ -57,6 +57,6 @@ public class NodeTests {
@Test
public void testToString() {
Node node = Node.at("bitsquare1.example.com", "203.0.113.1", 5001);
assertThat(node.toString(), equalTo("Node{id=bitsquare1.example.com, ip=203.0.113.1, port=5001}"));
assertThat(node.toString(), equalTo("Node{name=bitsquare1.example.com, ip=203.0.113.1, port=5001}"));
}
}

View file

@ -16,99 +16,20 @@
package net.tomp2p.dht;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.NavigableSet;
import java.util.Random;
import java.util.TreeSet;
import net.tomp2p.connection.Bindings;
import net.tomp2p.futures.FutureBootstrap;
import net.tomp2p.futures.FutureDiscover;
import net.tomp2p.message.Message;
import net.tomp2p.message.Message.Type;
import net.tomp2p.p2p.AutomaticFuture;
import net.tomp2p.p2p.Peer;
import net.tomp2p.p2p.PeerBuilder;
import net.tomp2p.peers.Number160;
import net.tomp2p.peers.PeerAddress;
import net.tomp2p.peers.PeerMap;
import net.tomp2p.peers.PeerMapConfiguration;
import net.tomp2p.peers.PeerSocketAddress;
public class UtilsDHT2 {
/**
* Used to make the testcases predictable. Used as an input for {@link Random}.
*/
public static final long THE_ANSWER = 42L;
/**
* Having two peers in a network, the seed needs to be different, otherwise we create a peer with the same id twice.
*/
public static final long THE_ANSWER2 = 43L;
public static Message createDummyMessage() throws UnknownHostException {
return createDummyMessage(false, false);
}
public static Message createDummyMessage(boolean firewallUDP, boolean firewallTCP)
throws UnknownHostException {
return createDummyMessage(new Number160("0x4321"), "127.0.0.1", 8001, 8002, new Number160("0x1234"),
"127.0.0.1", 8003, 8004, (byte) 0, Type.REQUEST_1, firewallUDP, firewallTCP);
}
public static PeerAddress createAddress(Number160 id) throws UnknownHostException {
return createAddress(id, "127.0.0.1", 8005, 8006, false, false);
}
public static PeerAddress createAddress() throws UnknownHostException {
return createAddress(new Number160("0x5678"), "127.0.0.1", 8005, 8006, false, false);
}
public static PeerAddress createAddress(int id) throws UnknownHostException {
return createAddress(new Number160(id), "127.0.0.1", 8005, 8006, false, false);
}
public static PeerAddress createAddress(String id) throws UnknownHostException {
return createAddress(new Number160(id), "127.0.0.1", 8005, 8006, false, false);
}
public static PeerAddress createAddress(Number160 idSender, String inetSender, int tcpPortSender,
int udpPortSender, boolean firewallUDP,
boolean firewallTCP) throws UnknownHostException {
InetAddress inetSend = InetAddress.getByName(inetSender);
PeerSocketAddress peerSocketAddress = new PeerSocketAddress(inetSend, tcpPortSender, udpPortSender);
PeerAddress n1 = new PeerAddress(idSender, peerSocketAddress, firewallTCP, firewallUDP, false, false, false,
PeerAddress.EMPTY_PEER_SOCKET_ADDRESSES);
return n1;
}
public static Message createDummyMessage(Number160 idSender, String inetSender, int tcpPortSendor,
int udpPortSender, Number160 idRecipien, String inetRecipient,
int tcpPortRecipient,
int udpPortRecipient, byte command, Type type, boolean firewallUDP,
boolean firewallTCP)
throws UnknownHostException {
Message message = new Message();
PeerAddress n1 = createAddress(idSender, inetSender, tcpPortSendor, udpPortSender, firewallUDP,
firewallTCP);
message.sender(n1);
//
PeerAddress n2 = createAddress(idRecipien, inetRecipient, tcpPortRecipient, udpPortRecipient,
firewallUDP, firewallTCP);
message.recipient(n2);
message.type(type);
message.command(command);
return message;
}
public static PeerDHT[] createNodes(int nrOfPeers, Random rnd, int port) throws Exception {
return createNodes(nrOfPeers, rnd, port, null);
@ -177,34 +98,6 @@ public class UtilsDHT2 {
return peers;
}
public static Peer[] createRealNodes(int nrOfPeers, Random rnd, int startPort,
AutomaticFuture automaticFuture) throws Exception {
if (nrOfPeers < 1) {
throw new IllegalArgumentException("Cannot create less than 1 peer");
}
Peer[] peers = new Peer[nrOfPeers];
for (int i = 0; i < nrOfPeers; i++) {
peers[i] = new PeerBuilder(new Number160(rnd))
.ports(startPort + i).start().addAutomaticFuture(automaticFuture);
}
System.err.println("real peers created.");
return peers;
}
public static Peer[] createNonMaintenanceNodes(int nrOfPeers, Random rnd, int port) throws IOException {
if (nrOfPeers < 1) {
throw new IllegalArgumentException("Cannot create less than 1 peer");
}
Peer[] peers = new Peer[nrOfPeers];
peers[0] = new PeerBuilder(new Number160(rnd)).enableMaintenance(false).ports(port).start();
for (int i = 1; i < nrOfPeers; i++) {
peers[i] = new PeerBuilder(new Number160(rnd)).enableMaintenance(false).masterPeer(peers[0])
.start();
}
System.err.println("non-maintenance peers created.");
return peers;
}
/**
* Perfect routing, where each neighbor has contacted each other. This means that for small number of peers, every
* peer knows every other peer.
@ -219,14 +112,6 @@ public class UtilsDHT2 {
System.err.println("perfect routing done.");
}
public static void perfectRoutingIndirect(PeerDHT... peers) {
for (int i = 0; i < peers.length; i++) {
for (int j = 0; j < peers.length; j++)
peers[i].peerBean().peerMap().peerFound(peers[j].peerAddress(), peers[j].peerAddress(), null);
}
System.err.println("perfect routing done.");
}
public static void main(String[] args) throws IOException {
createTempDirectory();
}
@ -246,121 +131,4 @@ public class UtilsDHT2 {
throw new IllegalStateException("Failed to create directory within " + TEMP_DIR_ATTEMPTS
+ " attempts (tried " + baseName + "0 to " + baseName + (TEMP_DIR_ATTEMPTS - 1) + ')');
}
public static Peer[] createAndAttachNodes(int nr, int port, Random rnd) throws Exception {
Peer[] peers = new Peer[nr];
for (int i = 0; i < nr; i++) {
if (i == 0) {
peers[0] = new PeerBuilder(new Number160(rnd)).ports(port).start();
}
else {
peers[i] = new PeerBuilder(new Number160(rnd)).masterPeer(peers[0]).start();
}
}
return peers;
}
public static void bootstrap(Peer[] peers) {
List<FutureBootstrap> futures1 = new ArrayList<FutureBootstrap>();
List<FutureDiscover> futures2 = new ArrayList<FutureDiscover>();
for (int i = 1; i < peers.length; i++) {
FutureDiscover tmp = peers[i].discover().peerAddress(peers[0].peerAddress()).start();
futures2.add(tmp);
}
for (FutureDiscover future : futures2) {
future.awaitUninterruptibly();
}
for (int i = 1; i < peers.length; i++) {
FutureBootstrap tmp = peers[i].bootstrap().peerAddress(peers[0].peerAddress()).start();
futures1.add(tmp);
}
for (int i = 1; i < peers.length; i++) {
FutureBootstrap tmp = peers[0].bootstrap().peerAddress(peers[i].peerAddress()).start();
futures1.add(tmp);
}
for (FutureBootstrap future : futures1)
future.awaitUninterruptibly();
}
public static void routing(Number160 key, Peer[] peers, int start) {
System.out.println("routing: searching for key " + key);
NavigableSet<PeerAddress> pa1 = new TreeSet<PeerAddress>(PeerMap.createComparator(key));
NavigableSet<PeerAddress> queried = new TreeSet<PeerAddress>(PeerMap.createComparator(key));
Number160 result = Number160.ZERO;
Number160 resultPeer = new Number160("0xd75d1a3d57841fbc9e2a3d175d6a35dc2e15b9f");
int round = 0;
while (!resultPeer.equals(result)) {
System.out.println("round " + round);
round++;
pa1.addAll(peers[start].peerBean().peerMap().all());
queried.add(peers[start].peerAddress());
System.out.println("closest so far: " + queried.first());
PeerAddress next = pa1.pollFirst();
while (queried.contains(next)) {
next = pa1.pollFirst();
}
result = next.peerId();
start = findNr(next.peerId().toString(), peers);
}
}
public static void findInMap(PeerAddress key, Peer[] peers) {
for (int i = 0; i < peers.length; i++) {
if (peers[i].peerBean().peerMap().contains(key)) {
System.out.println("Peer " + i + " with the id " + peers[i].peerID() + " knows the peer "
+ key);
}
}
}
public static int findNr(String string, Peer[] peers) {
for (int i = 0; i < peers.length; i++) {
if (peers[i].peerID().equals(new Number160(string))) {
System.out.println("we found the number " + i + " for peer with id " + string);
return i;
}
}
return -1;
}
public static Peer find(String string, Peer[] peers) {
for (int i = 0; i < peers.length; i++) {
if (peers[i].peerID().equals(new Number160(string))) {
System.out.println("!!we found the number " + i + " for peer with id " + string);
return peers[i];
}
}
return null;
}
public static void exec(String cmd) throws Exception {
Process p = Runtime.getRuntime().exec(cmd);
p.waitFor();
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
}
public static PeerAddress createAddressIP(String inet) throws UnknownHostException {
return createAddress(Number160.createHash(inet), inet, 8005, 8006, false, false);
}
public static PeerAddress[] createDummyAddress(int size, int portTCP, int portUDP) throws UnknownHostException {
PeerAddress[] pa = new PeerAddress[size];
for (int i = 0; i < size; i++) {
pa[i] = createAddress(i + 1, portTCP, portUDP);
}
return pa;
}
public static PeerAddress createAddress(int iid, int portTCP, int portUDP) throws UnknownHostException {
Number160 id = new Number160(iid);
InetAddress address = InetAddress.getByName("127.0.0.1");
return new PeerAddress(id, address, portTCP, portUDP);
}
}