mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-05-31 12:34: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
|
@ -13,13 +13,10 @@
|
|||
|
||||
# Mac OSX:
|
||||
# $HOME/Library/Application Support/Bitcoin/
|
||||
# /Users/username/Library/Application Support/Bitcoin/bitcoin.conf
|
||||
# /Users/username/Library/Application Support/Bitcoin/bitcoin.conf
|
||||
|
||||
|
||||
# Supported properties:
|
||||
# networkType=regtest | testnet | mainnet
|
||||
# bitcoin.network=regtest | testnet | mainnet
|
||||
|
||||
# defaultSeedNode=localhost | server
|
||||
|
||||
networkType=regtest
|
||||
defaultSeedNode=localhost
|
||||
bitcoin.network=regtest
|
||||
|
|
|
@ -36,8 +36,6 @@ import com.google.inject.name.Names;
|
|||
|
||||
import java.util.Properties;
|
||||
|
||||
import net.tomp2p.connection.Ports;
|
||||
|
||||
/**
|
||||
* 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");
|
||||
|
||||
bindConstant().annotatedWith(Names.named("appName")).to(appName);
|
||||
|
||||
int randomPort = new Ports().tcpPort();
|
||||
bindConstant().annotatedWith(Names.named("clientPort")).to(randomPort);
|
||||
}
|
||||
|
||||
protected MessageModule messageModule() {
|
||||
|
|
|
@ -17,12 +17,15 @@
|
|||
|
||||
package io.bitsquare.app;
|
||||
|
||||
import io.bitsquare.btc.BitcoinModule;
|
||||
import io.bitsquare.network.Node;
|
||||
|
||||
import net.sourceforge.argparse4j.ArgumentParsers;
|
||||
import net.sourceforge.argparse4j.inf.ArgumentParserException;
|
||||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
|
||||
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 {
|
||||
|
||||
|
@ -33,18 +36,28 @@ public class ArgumentParser {
|
|||
.defaultHelp(true)
|
||||
.description("Bitsquare - The decentralized bitcoin exchange");
|
||||
|
||||
// Args for seed node config
|
||||
parser.addArgument("-d", "--" + BOOTSTRAP_NODE_ID_KEY)
|
||||
.help("Seed node ID");
|
||||
parser.addArgument("-s", "--" + BOOTSTRAP_NODE_IP_KEY)
|
||||
.help("Seed node IP");
|
||||
parser.addArgument("-p", "--" + BOOTSTRAP_NODE_PORT_KEY)
|
||||
.help("Seed node port");
|
||||
// Args for local node config
|
||||
parser.addArgument("--" + Node.NAME_KEY)
|
||||
.help("Local node name");
|
||||
parser.addArgument("--" + Node.PORT_KEY)
|
||||
.help("Local 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)
|
||||
parser.addArgument("-i", "--" + NETWORK_INTERFACE_KEY)
|
||||
parser.addArgument("--" + NETWORK_INTERFACE_KEY)
|
||||
.help("Network interface");
|
||||
|
||||
parser.addArgument("--" + BitcoinModule.BITCOIN_NETWORK_KEY)
|
||||
.setDefault(BitcoinModule.DEFAULT_BITCOIN_NETWORK.toString())
|
||||
.help("Bitcoin network to use");
|
||||
|
||||
// Args for app config
|
||||
parser.addArgument("-n", "--" + APP_NAME_KEY)
|
||||
.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 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 {
|
||||
private static final Logger log = LoggerFactory.getLogger(Main.class);
|
||||
|
@ -70,8 +72,14 @@ public class Main extends Application {
|
|||
|
||||
properties.setProperty(APP_NAME_KEY, appName);
|
||||
|
||||
if (argumentsNamespace.getString(BOOTSTRAP_NODE_ID_KEY) != null)
|
||||
properties.setProperty(BOOTSTRAP_NODE_ID_KEY, argumentsNamespace.getString(BOOTSTRAP_NODE_ID_KEY));
|
||||
if (argumentsNamespace.getString(NAME_KEY) != null)
|
||||
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)
|
||||
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)
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,17 +30,11 @@ import java.util.Properties;
|
|||
|
||||
public class BitcoinModule extends BitsquareModule {
|
||||
|
||||
private static final BitcoinNetwork DEFAULT_NETWORK = BitcoinNetwork.TESTNET;
|
||||
|
||||
private final BitcoinNetwork network;
|
||||
public static final String BITCOIN_NETWORK_KEY = "bitcoin.network";
|
||||
public static final String DEFAULT_BITCOIN_NETWORK = BitcoinNetwork.TESTNET.toString();
|
||||
|
||||
public BitcoinModule(Properties properties) {
|
||||
this(properties, DEFAULT_NETWORK);
|
||||
}
|
||||
|
||||
public BitcoinModule(Properties properties, BitcoinNetwork network) {
|
||||
super(properties);
|
||||
this.network = network;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -57,9 +51,10 @@ public class BitcoinModule extends BitsquareModule {
|
|||
}
|
||||
|
||||
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:
|
||||
return MainNetParams.get();
|
||||
case TESTNET:
|
||||
|
@ -67,7 +62,7 @@ public class BitcoinModule extends BitsquareModule {
|
|||
case REGTEST:
|
||||
return RegTestParams.get();
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown bitcoin network name: " + networkName);
|
||||
throw new IllegalArgumentException("Unknown bitcoin network: " + network);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,5 +18,5 @@
|
|||
package io.bitsquare.btc;
|
||||
|
||||
public enum BitcoinNetwork {
|
||||
MAINNET, TESTNET, REGTEST
|
||||
MAINNET, TESTNET, REGTEST;
|
||||
}
|
||||
|
|
|
@ -31,8 +31,6 @@ import io.bitsquare.user.User;
|
|||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import javax.inject.Named;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
|
@ -56,7 +54,6 @@ class MainModel extends UIModel {
|
|||
private final MessageFacade messageFacade;
|
||||
private final TradeManager tradeManager;
|
||||
private final Persistence persistence;
|
||||
private final int clientPort;
|
||||
|
||||
private boolean messageFacadeInited;
|
||||
private boolean walletFacadeInited;
|
||||
|
@ -75,14 +72,12 @@ class MainModel extends UIModel {
|
|||
|
||||
@Inject
|
||||
private MainModel(User user, WalletFacade walletFacade, MessageFacade messageFacade,
|
||||
TradeManager tradeManager, Persistence persistence,
|
||||
@Named("clientPort") int clientPort) {
|
||||
TradeManager tradeManager, Persistence persistence) {
|
||||
this.user = user;
|
||||
this.walletFacade = walletFacade;
|
||||
this.messageFacade = messageFacade;
|
||||
this.tradeManager = tradeManager;
|
||||
this.persistence = persistence;
|
||||
this.clientPort = clientPort;
|
||||
}
|
||||
|
||||
|
||||
|
@ -109,10 +104,10 @@ class MainModel extends UIModel {
|
|||
|
||||
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(clientPort, new BootstrapListener() {
|
||||
messageFacade.init(new BootstrapListener() {
|
||||
@Override
|
||||
public void onCompleted() {
|
||||
messageFacadeInited = true;
|
||||
|
|
|
@ -45,7 +45,7 @@ public interface MessageFacade extends MessageBroker {
|
|||
|
||||
void getArbitrators(Locale defaultLanguageLocale);
|
||||
|
||||
void init(int clientPort, BootstrapListener bootstrapListener);
|
||||
void init(BootstrapListener bootstrapListener);
|
||||
|
||||
void getPeerAddress(PublicKey messagePublicKey, GetPeerAddressListener getPeerAddressListener);
|
||||
}
|
||||
|
|
|
@ -18,22 +18,13 @@
|
|||
package io.bitsquare.msg;
|
||||
|
||||
import io.bitsquare.BitsquareModule;
|
||||
import io.bitsquare.network.Node;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.name.Names;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import static io.bitsquare.network.BootstrapNodes.DEFAULT_BOOTSTRAP_NODE;
|
||||
|
||||
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) {
|
||||
super(properties);
|
||||
}
|
||||
|
@ -42,23 +33,6 @@ public abstract class MessageModule extends BitsquareModule {
|
|||
protected final void configure() {
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -68,12 +68,17 @@ import org.jetbrains.annotations.NotNull;
|
|||
import org.slf4j.Logger;
|
||||
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 {
|
||||
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 Storage storage;
|
||||
private final Node bootstrapNode;
|
||||
|
@ -91,8 +96,9 @@ class BootstrappedPeerFactory {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public BootstrappedPeerFactory(Persistence persistence, @Named("bootstrapNode") Node bootstrapNode,
|
||||
@Named("networkInterface") String networkInterface) {
|
||||
public BootstrappedPeerFactory(Persistence persistence,
|
||||
@Named(BOOTSTRAP_NODE_KEY) Node bootstrapNode,
|
||||
@Named(NETWORK_INTERFACE_KEY) String networkInterface) {
|
||||
this.persistence = persistence;
|
||||
this.bootstrapNode = bootstrapNode;
|
||||
this.networkInterface = networkInterface;
|
||||
|
@ -127,7 +133,7 @@ class BootstrappedPeerFactory {
|
|||
cc.maxPermitsTCP(100);
|
||||
cc.maxPermitsUDP(100);
|
||||
Bindings bindings = new Bindings();
|
||||
if (!networkInterface.equals(""))
|
||||
if (!NETWORK_INTERFACE_UNSPECIFIED.equals(networkInterface))
|
||||
bindings.addInterface(networkInterface);
|
||||
|
||||
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
|
||||
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.addListener(new BaseFutureListener<BaseFuture>() {
|
||||
@Override
|
||||
|
@ -324,7 +330,7 @@ class BootstrappedPeerFactory {
|
|||
|
||||
private PeerAddress getBootstrapAddress() {
|
||||
try {
|
||||
return new PeerAddress(Number160.createHash(bootstrapNode.getId()),
|
||||
return new PeerAddress(Number160.createHash(bootstrapNode.getName()),
|
||||
InetAddress.getByName(bootstrapNode.getIp()),
|
||||
bootstrapNode.getPort(),
|
||||
bootstrapNode.getPort());
|
||||
|
|
|
@ -92,11 +92,10 @@ class TomP2PMessageFacade implements MessageFacade {
|
|||
// Public Methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void init(int port, BootstrapListener bootstrapListener) {
|
||||
public void init(BootstrapListener bootstrapListener) {
|
||||
p2pNode.setMessageBroker(this);
|
||||
p2pNode.setKeyPair(user.getMessageKeyPair());
|
||||
|
||||
p2pNode.start(port, bootstrapListener);
|
||||
p2pNode.start(bootstrapListener);
|
||||
}
|
||||
|
||||
public void shutDown() {
|
||||
|
@ -219,7 +218,7 @@ class TomP2PMessageFacade implements MessageFacade {
|
|||
}
|
||||
}));
|
||||
|
||||
// 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
|
||||
|
||||
|
|
|
@ -19,18 +19,41 @@ package io.bitsquare.msg.tomp2p;
|
|||
|
||||
import io.bitsquare.msg.MessageFacade;
|
||||
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 static io.bitsquare.msg.tomp2p.BootstrappedPeerFactory.*;
|
||||
|
||||
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) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
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(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();
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ package io.bitsquare.msg.tomp2p;
|
|||
|
||||
import io.bitsquare.msg.MessageBroker;
|
||||
import io.bitsquare.msg.listeners.BootstrapListener;
|
||||
import io.bitsquare.network.Node;
|
||||
import io.bitsquare.network.tomp2p.TomP2PPeer;
|
||||
|
||||
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 java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.security.KeyPair;
|
||||
|
@ -42,13 +42,11 @@ import javax.inject.Inject;
|
|||
|
||||
import javafx.application.Platform;
|
||||
|
||||
import net.tomp2p.connection.DSASignatureFactory;
|
||||
import net.tomp2p.connection.PeerConnection;
|
||||
import net.tomp2p.dht.FutureGet;
|
||||
import net.tomp2p.dht.FuturePut;
|
||||
import net.tomp2p.dht.FutureRemove;
|
||||
import net.tomp2p.dht.PeerDHT;
|
||||
import net.tomp2p.dht.StorageMemory;
|
||||
import net.tomp2p.futures.BaseFuture;
|
||||
import net.tomp2p.futures.BaseFutureListener;
|
||||
import net.tomp2p.futures.FutureDirect;
|
||||
|
@ -57,7 +55,6 @@ import net.tomp2p.peers.Number160;
|
|||
import net.tomp2p.peers.PeerAddress;
|
||||
import net.tomp2p.storage.Data;
|
||||
import net.tomp2p.storage.Storage;
|
||||
import net.tomp2p.storage.StorageDisk;
|
||||
import net.tomp2p.utils.Utils;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -65,8 +62,6 @@ import org.jetbrains.annotations.NotNull;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import lighthouse.files.AppDirectory;
|
||||
|
||||
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 KeyPair keyPair;
|
||||
private String appName;
|
||||
private final Boolean useDiskStorage;
|
||||
private final int port;
|
||||
private MessageBroker messageBroker;
|
||||
|
||||
private PeerAddress storedPeerAddress;
|
||||
|
@ -94,12 +88,9 @@ public class TomP2PNode {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public TomP2PNode(BootstrappedPeerFactory bootstrappedPeerFactory,
|
||||
@Named("appName") String appName,
|
||||
@Named("useDiskStorage") Boolean useDiskStorage) {
|
||||
public TomP2PNode(BootstrappedPeerFactory bootstrappedPeerFactory, @Named(Node.PORT_KEY) int port) {
|
||||
this.bootstrappedPeerFactory = bootstrappedPeerFactory;
|
||||
this.appName = appName;
|
||||
this.useDiskStorage = useDiskStorage;
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
// for unit testing
|
||||
|
@ -109,7 +100,7 @@ public class TomP2PNode {
|
|||
peerDHT.peerBean().keyPair(keyPair);
|
||||
messageBroker = (message, peerAddress) -> {
|
||||
};
|
||||
useDiskStorage = false;
|
||||
port = Node.DEFAULT_PORT;
|
||||
}
|
||||
|
||||
|
||||
|
@ -126,9 +117,7 @@ public class TomP2PNode {
|
|||
bootstrappedPeerFactory.setKeyPair(keyPair);
|
||||
}
|
||||
|
||||
public void start(int port, BootstrapListener bootstrapListener) {
|
||||
useDiscStorage(useDiskStorage);
|
||||
|
||||
public void start(BootstrapListener bootstrapListener) {
|
||||
bootstrappedPeerFactory.setStorage(storage);
|
||||
setupTimerForIPCheck();
|
||||
|
||||
|
@ -391,19 +380,4 @@ public class TomP2PNode {
|
|||
log.debug("storePeerAddress " + peerDHT.peerAddress().toString());
|
||||
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.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 {
|
||||
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_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() {
|
||||
return Arrays.asList(
|
||||
LOCALHOST, DIGITAL_OCEAN_1
|
||||
DIGITAL_OCEAN_1
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,32 +20,40 @@ package io.bitsquare.network;
|
|||
import com.google.common.base.Objects;
|
||||
|
||||
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;
|
||||
|
||||
private final String id;
|
||||
private final String name;
|
||||
private final String ip;
|
||||
private final int port;
|
||||
|
||||
private Node(String id, String ip, int port) {
|
||||
this.id = id;
|
||||
private Node(String name, String ip, int port) {
|
||||
this.name = name;
|
||||
this.ip = ip;
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public static Node at(String id, String ip) {
|
||||
return Node.at(id, ip, DEFAULT_PORT);
|
||||
public static Node at(String name, String ip) {
|
||||
return Node.at(name, ip, DEFAULT_PORT);
|
||||
}
|
||||
|
||||
public static Node at(String id, String ip, int port) {
|
||||
return new Node(id, ip, port);
|
||||
public static Node at(String name, String ip, int port) {
|
||||
return new Node(name, ip, port);
|
||||
}
|
||||
|
||||
public static Node at(String id, String ip, String port) {
|
||||
return new Node(id, ip, Integer.valueOf(port));
|
||||
public static Node at(String name, String ip, String port) {
|
||||
return new Node(name, ip, Integer.valueOf(port));
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getIp() {
|
||||
|
@ -60,6 +68,13 @@ public final class Node {
|
|||
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
|
||||
public boolean equals(Object object) {
|
||||
if (this == object)
|
||||
|
@ -69,20 +84,20 @@ public final class Node {
|
|||
return false;
|
||||
|
||||
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.port, that.port);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(id, ip, port);
|
||||
return Objects.hashCode(name, ip, port);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Objects.toStringHelper(Node.class.getSimpleName())
|
||||
.add("id", id)
|
||||
.add("name", name)
|
||||
.add("ip", ip)
|
||||
.add("port", port)
|
||||
.toString();
|
||||
|
|
|
@ -1,11 +1 @@
|
|||
seed.0.id=digitalocean1.bitsquare.io
|
||||
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
|
||||
# Empty for now; see ConfigLoader
|
|
@ -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 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)
|
||||
|
|
|
@ -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}"));
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue