mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-07-26 08:25:23 -04:00
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:
commit
efe6c1bec9
22 changed files with 251 additions and 638 deletions
|
@ -17,9 +17,6 @@
|
||||||
|
|
||||||
|
|
||||||
# Supported properties:
|
# Supported properties:
|
||||||
# networkType=regtest | testnet | mainnet
|
# bitcoin.network=regtest | testnet | mainnet
|
||||||
|
|
||||||
# defaultSeedNode=localhost | server
|
bitcoin.network=regtest
|
||||||
|
|
||||||
networkType=regtest
|
|
||||||
defaultSeedNode=localhost
|
|
||||||
|
|
|
@ -36,8 +36,6 @@ import com.google.inject.name.Names;
|
||||||
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import net.tomp2p.connection.Ports;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures all non-UI modules necessary to run a Bitsquare application.
|
* Configures all non-UI modules necessary to run a Bitsquare application.
|
||||||
*/
|
*/
|
||||||
|
@ -64,9 +62,6 @@ public class AppModule extends BitsquareModule {
|
||||||
Preconditions.checkArgument(appName != null, "App name must be non-null");
|
Preconditions.checkArgument(appName != null, "App name must be non-null");
|
||||||
|
|
||||||
bindConstant().annotatedWith(Names.named("appName")).to(appName);
|
bindConstant().annotatedWith(Names.named("appName")).to(appName);
|
||||||
|
|
||||||
int randomPort = new Ports().tcpPort();
|
|
||||||
bindConstant().annotatedWith(Names.named("clientPort")).to(randomPort);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MessageModule messageModule() {
|
protected MessageModule messageModule() {
|
||||||
|
|
|
@ -17,12 +17,15 @@
|
||||||
|
|
||||||
package io.bitsquare.app;
|
package io.bitsquare.app;
|
||||||
|
|
||||||
|
import io.bitsquare.btc.BitcoinModule;
|
||||||
|
import io.bitsquare.network.Node;
|
||||||
|
|
||||||
import net.sourceforge.argparse4j.ArgumentParsers;
|
import net.sourceforge.argparse4j.ArgumentParsers;
|
||||||
import net.sourceforge.argparse4j.inf.ArgumentParserException;
|
import net.sourceforge.argparse4j.inf.ArgumentParserException;
|
||||||
import net.sourceforge.argparse4j.inf.Namespace;
|
import net.sourceforge.argparse4j.inf.Namespace;
|
||||||
|
|
||||||
import static io.bitsquare.app.AppModule.APP_NAME_KEY;
|
import static io.bitsquare.app.AppModule.APP_NAME_KEY;
|
||||||
import static io.bitsquare.msg.MessageModule.*;
|
import static io.bitsquare.msg.tomp2p.TomP2PMessageModule.*;
|
||||||
|
|
||||||
public class ArgumentParser {
|
public class ArgumentParser {
|
||||||
|
|
||||||
|
@ -33,18 +36,28 @@ public class ArgumentParser {
|
||||||
.defaultHelp(true)
|
.defaultHelp(true)
|
||||||
.description("Bitsquare - The decentralized bitcoin exchange");
|
.description("Bitsquare - The decentralized bitcoin exchange");
|
||||||
|
|
||||||
// Args for seed node config
|
// Args for local node config
|
||||||
parser.addArgument("-d", "--" + BOOTSTRAP_NODE_ID_KEY)
|
parser.addArgument("--" + Node.NAME_KEY)
|
||||||
.help("Seed node ID");
|
.help("Local node name");
|
||||||
parser.addArgument("-s", "--" + BOOTSTRAP_NODE_IP_KEY)
|
parser.addArgument("--" + Node.PORT_KEY)
|
||||||
.help("Seed node IP");
|
.help("Local node port");
|
||||||
parser.addArgument("-p", "--" + BOOTSTRAP_NODE_PORT_KEY)
|
|
||||||
.help("Seed node port");
|
// Args for bootstrap node config
|
||||||
|
parser.addArgument("--" + BOOTSTRAP_NODE_NAME_KEY)
|
||||||
|
.help("Bootstrap node name");
|
||||||
|
parser.addArgument("--" + BOOTSTRAP_NODE_IP_KEY)
|
||||||
|
.help("Bootstrap node IP address");
|
||||||
|
parser.addArgument("--" + BOOTSTRAP_NODE_PORT_KEY)
|
||||||
|
.help("Bootstrap node port");
|
||||||
|
|
||||||
// A custom network interface (needed at the moment for windows, but might be useful also later)
|
// A custom network interface (needed at the moment for windows, but might be useful also later)
|
||||||
parser.addArgument("-i", "--" + NETWORK_INTERFACE_KEY)
|
parser.addArgument("--" + NETWORK_INTERFACE_KEY)
|
||||||
.help("Network interface");
|
.help("Network interface");
|
||||||
|
|
||||||
|
parser.addArgument("--" + BitcoinModule.BITCOIN_NETWORK_KEY)
|
||||||
|
.setDefault(BitcoinModule.DEFAULT_BITCOIN_NETWORK.toString())
|
||||||
|
.help("Bitcoin network to use");
|
||||||
|
|
||||||
// Args for app config
|
// Args for app config
|
||||||
parser.addArgument("-n", "--" + APP_NAME_KEY)
|
parser.addArgument("-n", "--" + APP_NAME_KEY)
|
||||||
.help("Name to append to default application name");
|
.help("Name to append to default application name");
|
||||||
|
|
101
src/main/java/io/bitsquare/app/cli/BootstrapNode.java
Normal file
101
src/main/java/io/bitsquare/app/cli/BootstrapNode.java
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* 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.app.cli;
|
||||||
|
|
||||||
|
import io.bitsquare.app.ArgumentParser;
|
||||||
|
import io.bitsquare.network.Node;
|
||||||
|
|
||||||
|
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 net.tomp2p.peers.PeerMap;
|
||||||
|
import net.tomp2p.peers.PeerMapConfiguration;
|
||||||
|
import net.tomp2p.rpc.ObjectDataReply;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import net.sourceforge.argparse4j.inf.Namespace;
|
||||||
|
|
||||||
|
public class BootstrapNode {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(BootstrapNode.class);
|
||||||
|
|
||||||
|
private static Peer peer = null;
|
||||||
|
private static boolean running = true;
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
ArgumentParser parser = new ArgumentParser();
|
||||||
|
Namespace namespace = parser.parseArgs(args);
|
||||||
|
|
||||||
|
String name = namespace.getString(Node.NAME_KEY);
|
||||||
|
if (name == null)
|
||||||
|
throw new IllegalArgumentException(String.format("--%s option is required", Node.NAME_KEY));
|
||||||
|
|
||||||
|
String portValue = namespace.getString(Node.PORT_KEY);
|
||||||
|
int port = portValue != null ? Integer.valueOf(portValue) : Node.DEFAULT_PORT;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Number160 peerId = Number160.createHash(name);
|
||||||
|
PeerMapConfiguration pmc = new PeerMapConfiguration(peerId).peerNoVerification();
|
||||||
|
PeerMap pm = new PeerMap(pmc);
|
||||||
|
peer = new PeerBuilder(peerId).ports(port).peerMap(pm).start();
|
||||||
|
peer.objectDataReply(new ObjectDataReply() {
|
||||||
|
@Override
|
||||||
|
public Object reply(PeerAddress sender, Object request) throws Exception {
|
||||||
|
log.trace("received request: ", request.toString());
|
||||||
|
return "pong";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
new PeerBuilderDHT(peer).start();
|
||||||
|
new PeerBuilderNAT(peer).start();
|
||||||
|
|
||||||
|
log.debug("started");
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (running) {
|
||||||
|
for (PeerAddress pa : peer.peerBean().peerMap().all()) {
|
||||||
|
log.debug("peer online:" + pa);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Thread.sleep(2000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (peer != null)
|
||||||
|
peer.shutdown().awaitUninterruptibly();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void stop() {
|
||||||
|
running = false;
|
||||||
|
if (peer != null) {
|
||||||
|
peer.shutdown().awaitUninterruptibly();
|
||||||
|
}
|
||||||
|
peer = null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,169 +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.app.cli;
|
|
||||||
|
|
||||||
import io.bitsquare.app.ArgumentParser;
|
|
||||||
import io.bitsquare.network.BootstrapNodes;
|
|
||||||
import io.bitsquare.network.Node;
|
|
||||||
|
|
||||||
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 net.tomp2p.peers.PeerMap;
|
|
||||||
import net.tomp2p.peers.PeerMapConfiguration;
|
|
||||||
import net.tomp2p.rpc.ObjectDataReply;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import net.sourceforge.argparse4j.inf.Namespace;
|
|
||||||
|
|
||||||
import static io.bitsquare.msg.MessageModule.*;
|
|
||||||
|
|
||||||
public class SeedNode {
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(SeedNode.class);
|
|
||||||
|
|
||||||
private static Peer peer = null;
|
|
||||||
private static boolean running = true;
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
|
||||||
ArgumentParser parser = new ArgumentParser();
|
|
||||||
Namespace namespace = parser.parseArgs(args);
|
|
||||||
|
|
||||||
Node defaultNode = BootstrapNodes.DIGITAL_OCEAN_1;
|
|
||||||
String id = defaultNode.getId();
|
|
||||||
int port = defaultNode.getPort();
|
|
||||||
|
|
||||||
// Passed program args will override the properties of the default bootstrapNode
|
|
||||||
// So you can use the same id but different ports (e.g. running several nodes on one server with
|
|
||||||
// different ports)
|
|
||||||
if (namespace.getString(BOOTSTRAP_NODE_ID_KEY) != null)
|
|
||||||
id = namespace.getString(BOOTSTRAP_NODE_ID_KEY);
|
|
||||||
|
|
||||||
if (namespace.getString(BOOTSTRAP_NODE_PORT_KEY) != null)
|
|
||||||
port = Integer.valueOf(namespace.getString(BOOTSTRAP_NODE_PORT_KEY));
|
|
||||||
|
|
||||||
try {
|
|
||||||
Number160 peerId = Number160.createHash(id);
|
|
||||||
PeerMapConfiguration pmc = new PeerMapConfiguration(peerId).peerNoVerification();
|
|
||||||
PeerMap pm = new PeerMap(pmc);
|
|
||||||
peer = new PeerBuilder(peerId).ports(port).peerMap(pm).start();
|
|
||||||
peer.objectDataReply(new ObjectDataReply() {
|
|
||||||
@Override
|
|
||||||
public Object reply(PeerAddress sender, Object request) throws Exception {
|
|
||||||
log.trace("received request: ", request.toString());
|
|
||||||
return "pong";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
new PeerBuilderDHT(peer).start();
|
|
||||||
new PeerBuilderNAT(peer).start();
|
|
||||||
|
|
||||||
log.debug("SeedNode started.");
|
|
||||||
new Thread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
while (running) {
|
|
||||||
for (PeerAddress pa : peer.peerBean().peerMap().all()) {
|
|
||||||
log.debug("peer online:" + pa);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Thread.sleep(2000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
if (peer != null)
|
|
||||||
peer.shutdown().awaitUninterruptibly();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void stop() {
|
|
||||||
running = false;
|
|
||||||
if (peer != null) {
|
|
||||||
peer.shutdown().awaitUninterruptibly();
|
|
||||||
}
|
|
||||||
peer = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*public static void main(String[] args) throws Exception {
|
|
||||||
ArgumentParser parser = new ArgumentParser();
|
|
||||||
Namespace namespace = parser.parseArgs(args);
|
|
||||||
|
|
||||||
Node defaultNode = BootstrapNodes.DIGITAL_OCEAN_1;
|
|
||||||
String id = defaultNode.getId();
|
|
||||||
int port = defaultNode.getPort();
|
|
||||||
|
|
||||||
// Passed program args will override the properties of the default bootstrapNode
|
|
||||||
// So you can use the same id but different ports (e.g. running several nodes on one server with
|
|
||||||
// different ports)
|
|
||||||
if (namespace.getString(ArgumentParser.SEED_ID_FLAG) != null)
|
|
||||||
id = namespace.getString(ArgumentParser.SEED_ID_FLAG);
|
|
||||||
|
|
||||||
if (namespace.getString(ArgumentParser.SEED_PORT_FLAG) != null)
|
|
||||||
port = Integer.valueOf(namespace.getString(ArgumentParser.SEED_PORT_FLAG));
|
|
||||||
|
|
||||||
log.info("This node use ID: [" + id + "] and port: [" + port + "]");
|
|
||||||
|
|
||||||
Peer peer = null;
|
|
||||||
try {
|
|
||||||
// Lets test with different settings
|
|
||||||
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(id)).bindings(bindings)
|
|
||||||
.channelServerConfiguration(csc).ports(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();
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
|
|
@ -50,7 +50,9 @@ import lighthouse.files.AppDirectory;
|
||||||
import net.sourceforge.argparse4j.inf.Namespace;
|
import net.sourceforge.argparse4j.inf.Namespace;
|
||||||
|
|
||||||
import static io.bitsquare.app.AppModule.APP_NAME_KEY;
|
import static io.bitsquare.app.AppModule.APP_NAME_KEY;
|
||||||
import static io.bitsquare.msg.MessageModule.*;
|
import static io.bitsquare.btc.BitcoinModule.BITCOIN_NETWORK_KEY;
|
||||||
|
import static io.bitsquare.msg.tomp2p.TomP2PMessageModule.*;
|
||||||
|
import static io.bitsquare.network.Node.*;
|
||||||
|
|
||||||
public class Main extends Application {
|
public class Main extends Application {
|
||||||
private static final Logger log = LoggerFactory.getLogger(Main.class);
|
private static final Logger log = LoggerFactory.getLogger(Main.class);
|
||||||
|
@ -70,8 +72,14 @@ public class Main extends Application {
|
||||||
|
|
||||||
properties.setProperty(APP_NAME_KEY, appName);
|
properties.setProperty(APP_NAME_KEY, appName);
|
||||||
|
|
||||||
if (argumentsNamespace.getString(BOOTSTRAP_NODE_ID_KEY) != null)
|
if (argumentsNamespace.getString(NAME_KEY) != null)
|
||||||
properties.setProperty(BOOTSTRAP_NODE_ID_KEY, argumentsNamespace.getString(BOOTSTRAP_NODE_ID_KEY));
|
properties.setProperty(NAME_KEY, argumentsNamespace.getString(NAME_KEY));
|
||||||
|
|
||||||
|
if (argumentsNamespace.getString(PORT_KEY) != null)
|
||||||
|
properties.setProperty(PORT_KEY, argumentsNamespace.getString(PORT_KEY));
|
||||||
|
|
||||||
|
if (argumentsNamespace.getString(BOOTSTRAP_NODE_NAME_KEY) != null)
|
||||||
|
properties.setProperty(BOOTSTRAP_NODE_NAME_KEY, argumentsNamespace.getString(BOOTSTRAP_NODE_NAME_KEY));
|
||||||
|
|
||||||
if (argumentsNamespace.getString(BOOTSTRAP_NODE_IP_KEY) != null)
|
if (argumentsNamespace.getString(BOOTSTRAP_NODE_IP_KEY) != null)
|
||||||
properties.setProperty(BOOTSTRAP_NODE_IP_KEY, argumentsNamespace.getString(BOOTSTRAP_NODE_IP_KEY));
|
properties.setProperty(BOOTSTRAP_NODE_IP_KEY, argumentsNamespace.getString(BOOTSTRAP_NODE_IP_KEY));
|
||||||
|
@ -82,6 +90,9 @@ public class Main extends Application {
|
||||||
if (argumentsNamespace.getString(NETWORK_INTERFACE_KEY) != null)
|
if (argumentsNamespace.getString(NETWORK_INTERFACE_KEY) != null)
|
||||||
properties.setProperty(NETWORK_INTERFACE_KEY, argumentsNamespace.getString(NETWORK_INTERFACE_KEY));
|
properties.setProperty(NETWORK_INTERFACE_KEY, argumentsNamespace.getString(NETWORK_INTERFACE_KEY));
|
||||||
|
|
||||||
|
if (argumentsNamespace.getString(BITCOIN_NETWORK_KEY) != null)
|
||||||
|
properties.setProperty(BITCOIN_NETWORK_KEY, argumentsNamespace.getString(BITCOIN_NETWORK_KEY));
|
||||||
|
|
||||||
Application.launch(Main.class, args);
|
Application.launch(Main.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,17 +30,11 @@ import java.util.Properties;
|
||||||
|
|
||||||
public class BitcoinModule extends BitsquareModule {
|
public class BitcoinModule extends BitsquareModule {
|
||||||
|
|
||||||
private static final BitcoinNetwork DEFAULT_NETWORK = BitcoinNetwork.TESTNET;
|
public static final String BITCOIN_NETWORK_KEY = "bitcoin.network";
|
||||||
|
public static final String DEFAULT_BITCOIN_NETWORK = BitcoinNetwork.TESTNET.toString();
|
||||||
private final BitcoinNetwork network;
|
|
||||||
|
|
||||||
public BitcoinModule(Properties properties) {
|
public BitcoinModule(Properties properties) {
|
||||||
this(properties, DEFAULT_NETWORK);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BitcoinModule(Properties properties, BitcoinNetwork network) {
|
|
||||||
super(properties);
|
super(properties);
|
||||||
this.network = network;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -57,9 +51,10 @@ public class BitcoinModule extends BitsquareModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
private NetworkParameters network() {
|
private NetworkParameters network() {
|
||||||
String networkName = properties.getProperty("networkType", network.name());
|
BitcoinNetwork network = BitcoinNetwork.valueOf(
|
||||||
|
properties.getProperty(BITCOIN_NETWORK_KEY, DEFAULT_BITCOIN_NETWORK).toUpperCase());
|
||||||
|
|
||||||
switch (BitcoinNetwork.valueOf(networkName.toUpperCase())) {
|
switch (network) {
|
||||||
case MAINNET:
|
case MAINNET:
|
||||||
return MainNetParams.get();
|
return MainNetParams.get();
|
||||||
case TESTNET:
|
case TESTNET:
|
||||||
|
@ -67,7 +62,7 @@ public class BitcoinModule extends BitsquareModule {
|
||||||
case REGTEST:
|
case REGTEST:
|
||||||
return RegTestParams.get();
|
return RegTestParams.get();
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unknown bitcoin network name: " + networkName);
|
throw new IllegalArgumentException("Unknown bitcoin network: " + network);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,5 +18,5 @@
|
||||||
package io.bitsquare.btc;
|
package io.bitsquare.btc;
|
||||||
|
|
||||||
public enum BitcoinNetwork {
|
public enum BitcoinNetwork {
|
||||||
MAINNET, TESTNET, REGTEST
|
MAINNET, TESTNET, REGTEST;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,6 @@ import io.bitsquare.user.User;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
import javax.inject.Named;
|
|
||||||
|
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.property.BooleanProperty;
|
import javafx.beans.property.BooleanProperty;
|
||||||
import javafx.beans.property.DoubleProperty;
|
import javafx.beans.property.DoubleProperty;
|
||||||
|
@ -56,7 +54,6 @@ class MainModel extends UIModel {
|
||||||
private final MessageFacade messageFacade;
|
private final MessageFacade messageFacade;
|
||||||
private final TradeManager tradeManager;
|
private final TradeManager tradeManager;
|
||||||
private final Persistence persistence;
|
private final Persistence persistence;
|
||||||
private final int clientPort;
|
|
||||||
|
|
||||||
private boolean messageFacadeInited;
|
private boolean messageFacadeInited;
|
||||||
private boolean walletFacadeInited;
|
private boolean walletFacadeInited;
|
||||||
|
@ -75,14 +72,12 @@ class MainModel extends UIModel {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private MainModel(User user, WalletFacade walletFacade, MessageFacade messageFacade,
|
private MainModel(User user, WalletFacade walletFacade, MessageFacade messageFacade,
|
||||||
TradeManager tradeManager, Persistence persistence,
|
TradeManager tradeManager, Persistence persistence) {
|
||||||
@Named("clientPort") int clientPort) {
|
|
||||||
this.user = user;
|
this.user = user;
|
||||||
this.walletFacade = walletFacade;
|
this.walletFacade = walletFacade;
|
||||||
this.messageFacade = messageFacade;
|
this.messageFacade = messageFacade;
|
||||||
this.tradeManager = tradeManager;
|
this.tradeManager = tradeManager;
|
||||||
this.persistence = persistence;
|
this.persistence = persistence;
|
||||||
this.clientPort = clientPort;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -109,10 +104,10 @@ class MainModel extends UIModel {
|
||||||
|
|
||||||
void initBackend() {
|
void initBackend() {
|
||||||
|
|
||||||
// For testing with the serverside seednode we need the BootstrappedPeerFactory which gets started form
|
// For testing with the bootstrap node we need the BootstrappedPeerFactory which gets started from
|
||||||
// messageFacade.init
|
// messageFacade.init
|
||||||
|
|
||||||
messageFacade.init(clientPort, new BootstrapListener() {
|
messageFacade.init(new BootstrapListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCompleted() {
|
public void onCompleted() {
|
||||||
messageFacadeInited = true;
|
messageFacadeInited = true;
|
||||||
|
|
|
@ -45,7 +45,7 @@ public interface MessageFacade extends MessageBroker {
|
||||||
|
|
||||||
void getArbitrators(Locale defaultLanguageLocale);
|
void getArbitrators(Locale defaultLanguageLocale);
|
||||||
|
|
||||||
void init(int clientPort, BootstrapListener bootstrapListener);
|
void init(BootstrapListener bootstrapListener);
|
||||||
|
|
||||||
void getPeerAddress(PublicKey messagePublicKey, GetPeerAddressListener getPeerAddressListener);
|
void getPeerAddress(PublicKey messagePublicKey, GetPeerAddressListener getPeerAddressListener);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,22 +18,13 @@
|
||||||
package io.bitsquare.msg;
|
package io.bitsquare.msg;
|
||||||
|
|
||||||
import io.bitsquare.BitsquareModule;
|
import io.bitsquare.BitsquareModule;
|
||||||
import io.bitsquare.network.Node;
|
|
||||||
|
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.name.Names;
|
|
||||||
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import static io.bitsquare.network.BootstrapNodes.DEFAULT_BOOTSTRAP_NODE;
|
|
||||||
|
|
||||||
public abstract class MessageModule extends BitsquareModule {
|
public abstract class MessageModule extends BitsquareModule {
|
||||||
|
|
||||||
public static final String BOOTSTRAP_NODE_ID_KEY = "id";
|
|
||||||
public static final String BOOTSTRAP_NODE_IP_KEY = "ip";
|
|
||||||
public static final String BOOTSTRAP_NODE_PORT_KEY = "port";
|
|
||||||
public static final String NETWORK_INTERFACE_KEY = "networkInterface";
|
|
||||||
|
|
||||||
protected MessageModule(Properties properties) {
|
protected MessageModule(Properties properties) {
|
||||||
super(properties);
|
super(properties);
|
||||||
}
|
}
|
||||||
|
@ -42,23 +33,6 @@ public abstract class MessageModule extends BitsquareModule {
|
||||||
protected final void configure() {
|
protected final void configure() {
|
||||||
bind(MessageFacade.class).to(messageFacade()).asEagerSingleton();
|
bind(MessageFacade.class).to(messageFacade()).asEagerSingleton();
|
||||||
|
|
||||||
// we will probably later use disk storage instead of memory storage for TomP2P
|
|
||||||
bind(Boolean.class).annotatedWith(Names.named("useDiskStorage")).toInstance(false);
|
|
||||||
|
|
||||||
Node bootstrapNode = Node.at(
|
|
||||||
properties.getProperty(BOOTSTRAP_NODE_ID_KEY, DEFAULT_BOOTSTRAP_NODE.getId()),
|
|
||||||
properties.getProperty(BOOTSTRAP_NODE_IP_KEY, DEFAULT_BOOTSTRAP_NODE.getIp()),
|
|
||||||
properties.getProperty(BOOTSTRAP_NODE_PORT_KEY, DEFAULT_BOOTSTRAP_NODE.getPortAsString())
|
|
||||||
);
|
|
||||||
|
|
||||||
bind(Node.class)
|
|
||||||
.annotatedWith(Names.named("bootstrapNode"))
|
|
||||||
.toInstance(bootstrapNode);
|
|
||||||
|
|
||||||
bind(String.class)
|
|
||||||
.annotatedWith(Names.named("networkInterface"))
|
|
||||||
.toInstance(properties.getProperty(NETWORK_INTERFACE_KEY, ""));
|
|
||||||
|
|
||||||
doConfigure();
|
doConfigure();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,12 +68,17 @@ import org.jetbrains.annotations.NotNull;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a DHT peer and bootstrap to the network via a seed node
|
* Creates a DHT peer and bootstraps to the network via a bootstrap node
|
||||||
*/
|
*/
|
||||||
class BootstrappedPeerFactory {
|
class BootstrappedPeerFactory {
|
||||||
private static final Logger log = LoggerFactory.getLogger(BootstrappedPeerFactory.class);
|
private static final Logger log = LoggerFactory.getLogger(BootstrappedPeerFactory.class);
|
||||||
|
|
||||||
|
static final String BOOTSTRAP_NODE_KEY = "bootstrapNode";
|
||||||
|
static final String NETWORK_INTERFACE_KEY = "interface";
|
||||||
|
static final String NETWORK_INTERFACE_UNSPECIFIED = "<unspecified>";
|
||||||
|
|
||||||
private KeyPair keyPair;
|
private KeyPair keyPair;
|
||||||
private Storage storage;
|
private Storage storage;
|
||||||
private final Node bootstrapNode;
|
private final Node bootstrapNode;
|
||||||
|
@ -91,8 +96,9 @@ class BootstrappedPeerFactory {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public BootstrappedPeerFactory(Persistence persistence, @Named("bootstrapNode") Node bootstrapNode,
|
public BootstrappedPeerFactory(Persistence persistence,
|
||||||
@Named("networkInterface") String networkInterface) {
|
@Named(BOOTSTRAP_NODE_KEY) Node bootstrapNode,
|
||||||
|
@Named(NETWORK_INTERFACE_KEY) String networkInterface) {
|
||||||
this.persistence = persistence;
|
this.persistence = persistence;
|
||||||
this.bootstrapNode = bootstrapNode;
|
this.bootstrapNode = bootstrapNode;
|
||||||
this.networkInterface = networkInterface;
|
this.networkInterface = networkInterface;
|
||||||
|
@ -127,7 +133,7 @@ class BootstrappedPeerFactory {
|
||||||
cc.maxPermitsTCP(100);
|
cc.maxPermitsTCP(100);
|
||||||
cc.maxPermitsUDP(100);
|
cc.maxPermitsUDP(100);
|
||||||
Bindings bindings = new Bindings();
|
Bindings bindings = new Bindings();
|
||||||
if (!networkInterface.equals(""))
|
if (!NETWORK_INTERFACE_UNSPECIFIED.equals(networkInterface))
|
||||||
bindings.addInterface(networkInterface);
|
bindings.addInterface(networkInterface);
|
||||||
|
|
||||||
peer = new PeerBuilder(keyPair).ports(port).peerMap(pm).bindings(bindings)
|
peer = new PeerBuilder(keyPair).ports(port).peerMap(pm).bindings(bindings)
|
||||||
|
@ -197,7 +203,7 @@ class BootstrappedPeerFactory {
|
||||||
|
|
||||||
// 1. Attempt: Try to discover our outside visible address
|
// 1. Attempt: Try to discover our outside visible address
|
||||||
private void discover() {
|
private void discover() {
|
||||||
setState(BootstrapState.DIRECT_INIT, "We are starting to bootstrap to a seed node.");
|
setState(BootstrapState.DIRECT_INIT, "We are starting discovery against a bootstrap node.");
|
||||||
FutureDiscover futureDiscover = peer.discover().peerAddress(getBootstrapAddress()).start();
|
FutureDiscover futureDiscover = peer.discover().peerAddress(getBootstrapAddress()).start();
|
||||||
futureDiscover.addListener(new BaseFutureListener<BaseFuture>() {
|
futureDiscover.addListener(new BaseFutureListener<BaseFuture>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -324,7 +330,7 @@ class BootstrappedPeerFactory {
|
||||||
|
|
||||||
private PeerAddress getBootstrapAddress() {
|
private PeerAddress getBootstrapAddress() {
|
||||||
try {
|
try {
|
||||||
return new PeerAddress(Number160.createHash(bootstrapNode.getId()),
|
return new PeerAddress(Number160.createHash(bootstrapNode.getName()),
|
||||||
InetAddress.getByName(bootstrapNode.getIp()),
|
InetAddress.getByName(bootstrapNode.getIp()),
|
||||||
bootstrapNode.getPort(),
|
bootstrapNode.getPort(),
|
||||||
bootstrapNode.getPort());
|
bootstrapNode.getPort());
|
||||||
|
|
|
@ -92,11 +92,10 @@ class TomP2PMessageFacade implements MessageFacade {
|
||||||
// Public Methods
|
// Public Methods
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public void init(int port, BootstrapListener bootstrapListener) {
|
public void init(BootstrapListener bootstrapListener) {
|
||||||
p2pNode.setMessageBroker(this);
|
p2pNode.setMessageBroker(this);
|
||||||
p2pNode.setKeyPair(user.getMessageKeyPair());
|
p2pNode.setKeyPair(user.getMessageKeyPair());
|
||||||
|
p2pNode.start(bootstrapListener);
|
||||||
p2pNode.start(port, bootstrapListener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void shutDown() {
|
public void shutDown() {
|
||||||
|
|
|
@ -19,18 +19,41 @@ package io.bitsquare.msg.tomp2p;
|
||||||
|
|
||||||
import io.bitsquare.msg.MessageFacade;
|
import io.bitsquare.msg.MessageFacade;
|
||||||
import io.bitsquare.msg.MessageModule;
|
import io.bitsquare.msg.MessageModule;
|
||||||
|
import io.bitsquare.network.BootstrapNodes;
|
||||||
|
import io.bitsquare.network.Node;
|
||||||
|
|
||||||
|
import com.google.inject.name.Names;
|
||||||
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import static io.bitsquare.msg.tomp2p.BootstrappedPeerFactory.*;
|
||||||
|
|
||||||
public class TomP2PMessageModule extends MessageModule {
|
public class TomP2PMessageModule extends MessageModule {
|
||||||
|
|
||||||
|
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_PORT_KEY = "bootstrap.node.port";
|
||||||
|
public static final String NETWORK_INTERFACE_KEY = BootstrappedPeerFactory.NETWORK_INTERFACE_KEY;
|
||||||
|
|
||||||
public TomP2PMessageModule(Properties properties) {
|
public TomP2PMessageModule(Properties properties) {
|
||||||
super(properties);
|
super(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doConfigure() {
|
protected void doConfigure() {
|
||||||
|
bind(int.class).annotatedWith(Names.named(Node.PORT_KEY)).toInstance(
|
||||||
|
Integer.valueOf(properties.getProperty(Node.PORT_KEY, String.valueOf(Node.DEFAULT_PORT))));
|
||||||
bind(TomP2PNode.class).asEagerSingleton();
|
bind(TomP2PNode.class).asEagerSingleton();
|
||||||
|
|
||||||
|
bind(Node.class).annotatedWith(Names.named(BOOTSTRAP_NODE_KEY)).toInstance(
|
||||||
|
Node.at(
|
||||||
|
properties.getProperty(BOOTSTRAP_NODE_NAME_KEY, BootstrapNodes.DEFAULT.getName()),
|
||||||
|
properties.getProperty(BOOTSTRAP_NODE_IP_KEY, BootstrapNodes.DEFAULT.getIp()),
|
||||||
|
properties.getProperty(BOOTSTRAP_NODE_PORT_KEY, BootstrapNodes.DEFAULT.getPortAsString())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
bindConstant().annotatedWith(Names.named(NETWORK_INTERFACE_KEY)).to(
|
||||||
|
properties.getProperty(NETWORK_INTERFACE_KEY, NETWORK_INTERFACE_UNSPECIFIED));
|
||||||
bind(BootstrappedPeerFactory.class).asEagerSingleton();
|
bind(BootstrappedPeerFactory.class).asEagerSingleton();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ package io.bitsquare.msg.tomp2p;
|
||||||
|
|
||||||
import io.bitsquare.msg.MessageBroker;
|
import io.bitsquare.msg.MessageBroker;
|
||||||
import io.bitsquare.msg.listeners.BootstrapListener;
|
import io.bitsquare.msg.listeners.BootstrapListener;
|
||||||
|
import io.bitsquare.network.Node;
|
||||||
import io.bitsquare.network.tomp2p.TomP2PPeer;
|
import io.bitsquare.network.tomp2p.TomP2PPeer;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.FutureCallback;
|
import com.google.common.util.concurrent.FutureCallback;
|
||||||
|
@ -27,7 +28,6 @@ import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
import com.google.inject.name.Named;
|
import com.google.inject.name.Named;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
|
@ -42,13 +42,11 @@ import javax.inject.Inject;
|
||||||
|
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
|
|
||||||
import net.tomp2p.connection.DSASignatureFactory;
|
|
||||||
import net.tomp2p.connection.PeerConnection;
|
import net.tomp2p.connection.PeerConnection;
|
||||||
import net.tomp2p.dht.FutureGet;
|
import net.tomp2p.dht.FutureGet;
|
||||||
import net.tomp2p.dht.FuturePut;
|
import net.tomp2p.dht.FuturePut;
|
||||||
import net.tomp2p.dht.FutureRemove;
|
import net.tomp2p.dht.FutureRemove;
|
||||||
import net.tomp2p.dht.PeerDHT;
|
import net.tomp2p.dht.PeerDHT;
|
||||||
import net.tomp2p.dht.StorageMemory;
|
|
||||||
import net.tomp2p.futures.BaseFuture;
|
import net.tomp2p.futures.BaseFuture;
|
||||||
import net.tomp2p.futures.BaseFutureListener;
|
import net.tomp2p.futures.BaseFutureListener;
|
||||||
import net.tomp2p.futures.FutureDirect;
|
import net.tomp2p.futures.FutureDirect;
|
||||||
|
@ -57,7 +55,6 @@ import net.tomp2p.peers.Number160;
|
||||||
import net.tomp2p.peers.PeerAddress;
|
import net.tomp2p.peers.PeerAddress;
|
||||||
import net.tomp2p.storage.Data;
|
import net.tomp2p.storage.Data;
|
||||||
import net.tomp2p.storage.Storage;
|
import net.tomp2p.storage.Storage;
|
||||||
import net.tomp2p.storage.StorageDisk;
|
|
||||||
import net.tomp2p.utils.Utils;
|
import net.tomp2p.utils.Utils;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
@ -65,8 +62,6 @@ import org.jetbrains.annotations.NotNull;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import lighthouse.files.AppDirectory;
|
|
||||||
|
|
||||||
import static io.bitsquare.util.tomp2p.BaseFutureUtil.isSuccess;
|
import static io.bitsquare.util.tomp2p.BaseFutureUtil.isSuccess;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -79,8 +74,7 @@ public class TomP2PNode {
|
||||||
private static final Logger log = LoggerFactory.getLogger(TomP2PNode.class);
|
private static final Logger log = LoggerFactory.getLogger(TomP2PNode.class);
|
||||||
|
|
||||||
private KeyPair keyPair;
|
private KeyPair keyPair;
|
||||||
private String appName;
|
private final int port;
|
||||||
private final Boolean useDiskStorage;
|
|
||||||
private MessageBroker messageBroker;
|
private MessageBroker messageBroker;
|
||||||
|
|
||||||
private PeerAddress storedPeerAddress;
|
private PeerAddress storedPeerAddress;
|
||||||
|
@ -94,12 +88,9 @@ public class TomP2PNode {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TomP2PNode(BootstrappedPeerFactory bootstrappedPeerFactory,
|
public TomP2PNode(BootstrappedPeerFactory bootstrappedPeerFactory, @Named(Node.PORT_KEY) int port) {
|
||||||
@Named("appName") String appName,
|
|
||||||
@Named("useDiskStorage") Boolean useDiskStorage) {
|
|
||||||
this.bootstrappedPeerFactory = bootstrappedPeerFactory;
|
this.bootstrappedPeerFactory = bootstrappedPeerFactory;
|
||||||
this.appName = appName;
|
this.port = port;
|
||||||
this.useDiskStorage = useDiskStorage;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// for unit testing
|
// for unit testing
|
||||||
|
@ -109,7 +100,7 @@ public class TomP2PNode {
|
||||||
peerDHT.peerBean().keyPair(keyPair);
|
peerDHT.peerBean().keyPair(keyPair);
|
||||||
messageBroker = (message, peerAddress) -> {
|
messageBroker = (message, peerAddress) -> {
|
||||||
};
|
};
|
||||||
useDiskStorage = false;
|
port = Node.DEFAULT_PORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -126,9 +117,7 @@ public class TomP2PNode {
|
||||||
bootstrappedPeerFactory.setKeyPair(keyPair);
|
bootstrappedPeerFactory.setKeyPair(keyPair);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start(int port, BootstrapListener bootstrapListener) {
|
public void start(BootstrapListener bootstrapListener) {
|
||||||
useDiscStorage(useDiskStorage);
|
|
||||||
|
|
||||||
bootstrappedPeerFactory.setStorage(storage);
|
bootstrappedPeerFactory.setStorage(storage);
|
||||||
setupTimerForIPCheck();
|
setupTimerForIPCheck();
|
||||||
|
|
||||||
|
@ -391,19 +380,4 @@ public class TomP2PNode {
|
||||||
log.debug("storePeerAddress " + peerDHT.peerAddress().toString());
|
log.debug("storePeerAddress " + peerDHT.peerAddress().toString());
|
||||||
return putDomainProtectedData(locationKey, data);
|
return putDomainProtectedData(locationKey, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void useDiscStorage(boolean useDiscStorage) {
|
|
||||||
if (useDiscStorage) {
|
|
||||||
File path = new File(AppDirectory.dir(appName).toFile() + "/tomP2P");
|
|
||||||
if (!path.exists()) {
|
|
||||||
boolean created = path.mkdir();
|
|
||||||
if (!created)
|
|
||||||
throw new RuntimeException("Could not create the directory '" + path + "'");
|
|
||||||
}
|
|
||||||
storage = new StorageDisk(Number160.ZERO, path, new DSASignatureFactory());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
storage = new StorageMemory();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,20 +20,27 @@ package io.bitsquare.network;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
// Ports 7366-7390 are not registered @see
|
|
||||||
// <a href="https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?&page=103</a>
|
|
||||||
// Lets use ports in that range 7366-7390
|
|
||||||
// 7366 will be used as default port
|
|
||||||
public interface BootstrapNodes {
|
public interface BootstrapNodes {
|
||||||
Node LOCALHOST = Node.at("localhost", "127.0.0.1");
|
|
||||||
Node DIGITAL_OCEAN_1 = Node.at("digitalocean1.bitsquare.io", "188.226.179.109");
|
Node DIGITAL_OCEAN_1 = Node.at("digitalocean1.bitsquare.io", "188.226.179.109");
|
||||||
Node DIGITAL_OCEAN_1_DEV = Node.at("digitalocean1.bitsquare.io", "188.226.179.109", 7367);
|
|
||||||
|
|
||||||
Node DEFAULT_BOOTSTRAP_NODE = DIGITAL_OCEAN_1;
|
/**
|
||||||
|
* Alias to the default bootstrap node.
|
||||||
|
*/
|
||||||
|
Node DEFAULT = DIGITAL_OCEAN_1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A locally-running {@link io.bitsquare.app.cli.BootstrapNode} instance.
|
||||||
|
* Typically used only for testing. Not included in results from {@link #all()}.
|
||||||
|
*/
|
||||||
|
Node LOCALHOST = Node.at("localhost", "127.0.0.1");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All known public bootstrap nodes.
|
||||||
|
*/
|
||||||
static List<Node> all() {
|
static List<Node> all() {
|
||||||
return Arrays.asList(
|
return Arrays.asList(
|
||||||
LOCALHOST, DIGITAL_OCEAN_1
|
DIGITAL_OCEAN_1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,32 +20,40 @@ package io.bitsquare.network;
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
|
|
||||||
public final class Node {
|
public final class Node {
|
||||||
|
public static final String NAME_KEY = "name";
|
||||||
|
public static final String PORT_KEY = "port";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default port is one <a
|
||||||
|
* href="https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?&page=103">
|
||||||
|
* currently unassigned by IANA</a> (7366-7390).
|
||||||
|
*/
|
||||||
public static final int DEFAULT_PORT = 7366;
|
public static final int DEFAULT_PORT = 7366;
|
||||||
|
|
||||||
private final String id;
|
private final String name;
|
||||||
private final String ip;
|
private final String ip;
|
||||||
private final int port;
|
private final int port;
|
||||||
|
|
||||||
private Node(String id, String ip, int port) {
|
private Node(String name, String ip, int port) {
|
||||||
this.id = id;
|
this.name = name;
|
||||||
this.ip = ip;
|
this.ip = ip;
|
||||||
this.port = port;
|
this.port = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Node at(String id, String ip) {
|
public static Node at(String name, String ip) {
|
||||||
return Node.at(id, ip, DEFAULT_PORT);
|
return Node.at(name, ip, DEFAULT_PORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Node at(String id, String ip, int port) {
|
public static Node at(String name, String ip, int port) {
|
||||||
return new Node(id, ip, port);
|
return new Node(name, ip, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Node at(String id, String ip, String port) {
|
public static Node at(String name, String ip, String port) {
|
||||||
return new Node(id, ip, Integer.valueOf(port));
|
return new Node(name, ip, Integer.valueOf(port));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getId() {
|
public String getName() {
|
||||||
return id;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getIp() {
|
public String getIp() {
|
||||||
|
@ -60,6 +68,13 @@ public final class Node {
|
||||||
return String.valueOf(port);
|
return String.valueOf(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);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object object) {
|
public boolean equals(Object object) {
|
||||||
if (this == object)
|
if (this == object)
|
||||||
|
@ -69,20 +84,20 @@ public final class Node {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Node that = (Node) object;
|
Node that = (Node) object;
|
||||||
return Objects.equal(this.id, that.id) &&
|
return Objects.equal(this.name, that.name) &&
|
||||||
Objects.equal(this.ip, that.ip) &&
|
Objects.equal(this.ip, that.ip) &&
|
||||||
Objects.equal(this.port, that.port);
|
Objects.equal(this.port, that.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hashCode(id, ip, port);
|
return Objects.hashCode(name, ip, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return Objects.toStringHelper(Node.class.getSimpleName())
|
return Objects.toStringHelper(Node.class.getSimpleName())
|
||||||
.add("id", id)
|
.add("name", name)
|
||||||
.add("ip", ip)
|
.add("ip", ip)
|
||||||
.add("port", port)
|
.add("port", port)
|
||||||
.toString();
|
.toString();
|
||||||
|
|
|
@ -1,11 +1 @@
|
||||||
seed.0.id=digitalocean1.bitsquare.io
|
# Empty for now; see ConfigLoader
|
||||||
seed.0.address=188.226.179.109
|
|
||||||
seed.0.port=5000
|
|
||||||
|
|
||||||
seed.1.id=digitalocean2.bitsquare.io
|
|
||||||
seed.1.address=128.199.251.106
|
|
||||||
seed.1.port=5000
|
|
||||||
|
|
||||||
seed.2.id=localhost
|
|
||||||
seed.2.address=127.0.0.1
|
|
||||||
seed.2.port=5001
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 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.
|
* Test scenarios in direct connection, auto port forwarding or relay mode.
|
||||||
* <p>
|
* <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>
|
* <p>
|
||||||
* To configure your test environment edit the static fields for id, IP and port.
|
* 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.
|
* 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
|
// 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;
|
private static final ConnectionType FORCED_CONNECTION_TYPE = ConnectionType.DIRECT;
|
||||||
|
|
||||||
// Typically you run the seed node in localhost to test direct connection.
|
// 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 side seed node.
|
// 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 =
|
private static final Node BOOTSTRAP_NODE = (FORCED_CONNECTION_TYPE == ConnectionType.DIRECT) ?
|
||||||
(FORCED_CONNECTION_TYPE == ConnectionType.DIRECT) ? BootstrapNodes.LOCALHOST : BootstrapNodes
|
BootstrapNodes.LOCALHOST : BootstrapNodes.DIGITAL_OCEAN_1.withPort(7367);
|
||||||
.DIGITAL_OCEAN_1_DEV;
|
|
||||||
|
|
||||||
private static final PeerAddress BOOTSTRAP_NODE_ADDRESS;
|
private static final PeerAddress BOOTSTRAP_NODE_ADDRESS;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
BOOTSTRAP_NODE_ADDRESS = new PeerAddress(
|
BOOTSTRAP_NODE_ADDRESS = new PeerAddress(
|
||||||
Number160.createHash(BOOTSTRAP_NODE.getId()),
|
Number160.createHash(BOOTSTRAP_NODE.getName()),
|
||||||
BOOTSTRAP_NODE.getIp(), BOOTSTRAP_NODE.getPort(), BOOTSTRAP_NODE.getPort());
|
BOOTSTRAP_NODE.getIp(), BOOTSTRAP_NODE.getPort(), BOOTSTRAP_NODE.getPort());
|
||||||
} catch (UnknownHostException ex) {
|
} catch (UnknownHostException ex) {
|
||||||
throw new RuntimeException(BOOTSTRAP_NODE.toString(), ex);
|
throw new RuntimeException(BOOTSTRAP_NODE.toString(), ex);
|
||||||
|
@ -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.
|
// A node can send a message to another peer which is not in the same LAN.
|
||||||
@Test
|
@Test
|
||||||
@Repeat(STRESS_TEST_COUNT)
|
@Repeat(STRESS_TEST_COUNT)
|
||||||
|
|
|
@ -38,8 +38,8 @@ public class NodeTests {
|
||||||
assertThat(node1a, not((Object) equalTo("not a node")));
|
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("bitsquare2.example.com", node1a.getIp()))));
|
||||||
assertThat(node1a, not(equalTo(Node.at(node1a.getId(), "203.0.113.2"))));
|
assertThat(node1a, not(equalTo(Node.at(node1a.getName(), "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(), node1a.getIp(), Node.DEFAULT_PORT + 1))));
|
||||||
|
|
||||||
Node node2 = Node.at("bitsquare2.example.com", "203.0.113.2");
|
Node node2 = Node.at("bitsquare2.example.com", "203.0.113.2");
|
||||||
assertThat(node1a.hashCode(), equalTo(node1b.hashCode()));
|
assertThat(node1a.hashCode(), equalTo(node1b.hashCode()));
|
||||||
|
@ -57,6 +57,6 @@ public class NodeTests {
|
||||||
@Test
|
@Test
|
||||||
public void testToString() {
|
public void testToString() {
|
||||||
Node node = Node.at("bitsquare1.example.com", "203.0.113.1", 5001);
|
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}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,99 +16,20 @@
|
||||||
|
|
||||||
package net.tomp2p.dht;
|
package net.tomp2p.dht;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
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.Random;
|
||||||
import java.util.TreeSet;
|
|
||||||
|
|
||||||
import net.tomp2p.connection.Bindings;
|
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.AutomaticFuture;
|
||||||
import net.tomp2p.p2p.Peer;
|
import net.tomp2p.p2p.Peer;
|
||||||
import net.tomp2p.p2p.PeerBuilder;
|
import net.tomp2p.p2p.PeerBuilder;
|
||||||
import net.tomp2p.peers.Number160;
|
import net.tomp2p.peers.Number160;
|
||||||
import net.tomp2p.peers.PeerAddress;
|
|
||||||
import net.tomp2p.peers.PeerMap;
|
import net.tomp2p.peers.PeerMap;
|
||||||
import net.tomp2p.peers.PeerMapConfiguration;
|
import net.tomp2p.peers.PeerMapConfiguration;
|
||||||
import net.tomp2p.peers.PeerSocketAddress;
|
|
||||||
|
|
||||||
public class UtilsDHT2 {
|
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 {
|
public static PeerDHT[] createNodes(int nrOfPeers, Random rnd, int port) throws Exception {
|
||||||
return createNodes(nrOfPeers, rnd, port, null);
|
return createNodes(nrOfPeers, rnd, port, null);
|
||||||
|
@ -177,34 +98,6 @@ public class UtilsDHT2 {
|
||||||
return peers;
|
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
|
* Perfect routing, where each neighbor has contacted each other. This means that for small number of peers, every
|
||||||
* peer knows every other peer.
|
* peer knows every other peer.
|
||||||
|
@ -219,14 +112,6 @@ public class UtilsDHT2 {
|
||||||
System.err.println("perfect routing done.");
|
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 {
|
public static void main(String[] args) throws IOException {
|
||||||
createTempDirectory();
|
createTempDirectory();
|
||||||
}
|
}
|
||||||
|
@ -246,121 +131,4 @@ public class UtilsDHT2 {
|
||||||
throw new IllegalStateException("Failed to create directory within " + TEMP_DIR_ATTEMPTS
|
throw new IllegalStateException("Failed to create directory within " + TEMP_DIR_ATTEMPTS
|
||||||
+ " attempts (tried " + baseName + "0 to " + baseName + (TEMP_DIR_ATTEMPTS - 1) + ')');
|
+ " 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue