mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-07-26 08:25:23 -04:00
Use separate dirs for version and btc network, bootstrap to all bootstrap nodes, change config of bootstrap node
This commit is contained in:
parent
7a9de65e86
commit
fc3634af7b
29 changed files with 285 additions and 272 deletions
|
@ -18,14 +18,16 @@
|
||||||
package io.bitsquare.app.bootstrap;
|
package io.bitsquare.app.bootstrap;
|
||||||
|
|
||||||
import io.bitsquare.app.Logging;
|
import io.bitsquare.app.Logging;
|
||||||
|
import io.bitsquare.app.Version;
|
||||||
import io.bitsquare.p2p.BootstrapNodes;
|
import io.bitsquare.p2p.BootstrapNodes;
|
||||||
import io.bitsquare.p2p.Node;
|
import io.bitsquare.p2p.Node;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import net.tomp2p.connection.ChannelClientConfiguration;
|
||||||
|
import net.tomp2p.connection.ChannelServerConfiguration;
|
||||||
import net.tomp2p.dht.PeerBuilderDHT;
|
import net.tomp2p.dht.PeerBuilderDHT;
|
||||||
import net.tomp2p.dht.PeerDHT;
|
|
||||||
import net.tomp2p.nat.PeerBuilderNAT;
|
import net.tomp2p.nat.PeerBuilderNAT;
|
||||||
import net.tomp2p.p2p.Peer;
|
import net.tomp2p.p2p.Peer;
|
||||||
import net.tomp2p.p2p.PeerBuilder;
|
import net.tomp2p.p2p.PeerBuilder;
|
||||||
|
@ -37,13 +39,12 @@ import net.tomp2p.peers.PeerStatistic;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import io.netty.util.concurrent.DefaultEventExecutorGroup;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
|
|
||||||
public class BootstrapNode {
|
public class BootstrapNode {
|
||||||
private static final Logger log = LoggerFactory.getLogger(BootstrapNode.class);
|
private static final Logger log = LoggerFactory.getLogger(BootstrapNode.class);
|
||||||
|
|
||||||
private static final String VERSION = "0.1.3";
|
|
||||||
|
|
||||||
private static Peer peer = null;
|
private static Peer peer = null;
|
||||||
|
|
||||||
private final Environment env;
|
private final Environment env;
|
||||||
|
@ -53,29 +54,31 @@ public class BootstrapNode {
|
||||||
this.env = env;
|
this.env = env;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
String name = env.getProperty(Node.NAME_KEY, BootstrapNodes.getLocalhostNode().getName());
|
BootstrapNodes bootstrapNodes = new BootstrapNodes();
|
||||||
int p2pId = env.getProperty(Node.P2P_ID_KEY, Integer.class, BootstrapNodes.getLocalhostNode().getP2pId());
|
int p2pId = env.getProperty(Node.P2P_ID_KEY, Integer.class, Node.REG_TEST_P2P_ID); // use regtest as default
|
||||||
int port = env.getProperty(Node.PORT_KEY, Integer.class, BootstrapNodes.getLocalhostNode().getPort());
|
bootstrapNodes.initWithNetworkId(p2pId);
|
||||||
|
String name = env.getProperty(Node.NAME_KEY, bootstrapNodes.getLocalhostNode().getName());
|
||||||
|
int port = env.getProperty(Node.PORT_KEY, Integer.class, bootstrapNodes.getLocalhostNode().getPort());
|
||||||
|
|
||||||
Logging.setup(name + "_" + port);
|
Logging.setup(name + "_" + port);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Number160 peerId = Number160.createHash(name);
|
Number160 peerId = Number160.createHash(name);
|
||||||
/*
|
|
||||||
DefaultEventExecutorGroup eventExecutorGroup = new DefaultEventExecutorGroup(50);
|
DefaultEventExecutorGroup eventExecutorGroup = new DefaultEventExecutorGroup(50);
|
||||||
ChannelClientConfiguration clientConf = PeerBuilder.createDefaultChannelClientConfiguration();
|
ChannelClientConfiguration clientConf = PeerBuilder.createDefaultChannelClientConfiguration();
|
||||||
clientConf.pipelineFilter(new PeerBuilder.EventExecutorGroupFilter(eventExecutorGroup));
|
clientConf.pipelineFilter(new PeerBuilder.EventExecutorGroupFilter(eventExecutorGroup));
|
||||||
|
|
||||||
ChannelServerConfiguration serverConf = PeerBuilder.createDefaultChannelServerConfiguration();
|
ChannelServerConfiguration serverConf = PeerBuilder.createDefaultChannelServerConfiguration();
|
||||||
serverConf.pipelineFilter(new PeerBuilder.EventExecutorGroupFilter(eventExecutorGroup));
|
serverConf.pipelineFilter(new PeerBuilder.EventExecutorGroupFilter(eventExecutorGroup));
|
||||||
serverConf.connectionTimeoutTCPMillis(5000);*/
|
serverConf.connectionTimeoutTCPMillis(5000);
|
||||||
|
|
||||||
peer = new PeerBuilder(peerId)
|
peer = new PeerBuilder(peerId)
|
||||||
.ports(port)
|
.ports(port)
|
||||||
.p2pId(p2pId)
|
.p2pId(p2pId)
|
||||||
/* .channelClientConfiguration(clientConf)
|
.channelClientConfiguration(clientConf)
|
||||||
.channelServerConfiguration(serverConf)*/
|
.channelServerConfiguration(serverConf)
|
||||||
.start();
|
.start();
|
||||||
|
|
||||||
/*peer.objectDataReply((sender, request) -> {
|
/*peer.objectDataReply((sender, request) -> {
|
||||||
|
@ -83,70 +86,57 @@ public class BootstrapNode {
|
||||||
return "pong";
|
return "pong";
|
||||||
});*/
|
});*/
|
||||||
|
|
||||||
PeerDHT peerDHT = new PeerBuilderDHT(peer).start();
|
new PeerBuilderDHT(peer).start();
|
||||||
new PeerBuilderNAT(peer).start();
|
new PeerBuilderNAT(peer).start();
|
||||||
|
|
||||||
final int _port = port;
|
final int _port = port;
|
||||||
if (!name.equals(BootstrapNodes.getLocalhostNode().getName())) {
|
if (!name.equals(bootstrapNodes.getLocalhostNode().getName())) {
|
||||||
Collection<PeerAddress> bootstrapNodes = BootstrapNodes.getAllBootstrapNodes(p2pId).stream().filter(e -> !e.getName().equals(name))
|
List<Node> bootstrapNodesExcludingMyself = bootstrapNodes.getBootstrapNodes().stream().filter(e -> !e.getName().equals
|
||||||
|
(name)).collect(Collectors.toList());
|
||||||
|
log.info("Bootstrapping to bootstrapNodes " + bootstrapNodesExcludingMyself);
|
||||||
|
long ts = System.currentTimeMillis();
|
||||||
|
List<PeerAddress> bootstrapAddressesExcludingMyself = bootstrapNodesExcludingMyself.stream()
|
||||||
.map(e -> e.toPeerAddressWithPort(_port)).collect(Collectors.toList());
|
.map(e -> e.toPeerAddressWithPort(_port)).collect(Collectors.toList());
|
||||||
|
peer.bootstrap().bootstrapTo(bootstrapAddressesExcludingMyself).start().awaitUninterruptibly();
|
||||||
log.info("Bootstrapping to " + bootstrapNodes.size() + " bootstrapNode(s)");
|
log.info("Bootstrapping done after {} msec", System.currentTimeMillis() - ts);
|
||||||
log.info("Bootstrapping bootstrapNodes " + bootstrapNodes);
|
|
||||||
peer.bootstrap().bootstrapTo(bootstrapNodes).start().awaitUninterruptibly();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
log.info("We are localhost, we do not bootstrap to other nodes");
|
log.info("When using localhost we do not bootstrap to other nodes");
|
||||||
}
|
}
|
||||||
peer.peerBean().peerMap().addPeerMapChangeListener(new PeerMapChangeListener() {
|
peer.peerBean().peerMap().addPeerMapChangeListener(new PeerMapChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void peerInserted(PeerAddress peerAddress, boolean verified) {
|
public void peerInserted(PeerAddress peerAddress, boolean verified) {
|
||||||
try {
|
|
||||||
log.info("Peer inserted: peerAddress=" + peerAddress + ", verified=" + verified);
|
log.info("Peer inserted: peerAddress=" + peerAddress + ", verified=" + verified);
|
||||||
} catch (Throwable t) {
|
|
||||||
log.error("Exception at peerInserted " + t.getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void peerRemoved(PeerAddress peerAddress, PeerStatistic peerStatistics) {
|
public void peerRemoved(PeerAddress peerAddress, PeerStatistic peerStatistics) {
|
||||||
try {
|
|
||||||
log.info("Peer removed: peerAddress=" + peerAddress + ", peerStatistics=" + peerStatistics);
|
log.info("Peer removed: peerAddress=" + peerAddress + ", peerStatistics=" + peerStatistics);
|
||||||
} catch (Throwable t) {
|
|
||||||
log.error("Exception at peerRemoved " + t.getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void peerUpdated(PeerAddress peerAddress, PeerStatistic peerStatistics) {
|
public void peerUpdated(PeerAddress peerAddress, PeerStatistic peerStatistics) {
|
||||||
try {
|
|
||||||
//log.info("Peer updated: peerAddress=" + peerAddress + ", peerStatistics=" + peerStatistics);
|
//log.info("Peer updated: peerAddress=" + peerAddress + ", peerStatistics=" + peerStatistics);
|
||||||
} catch (Throwable t) {
|
|
||||||
log.error("Exception at peerUpdated " + t.getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
log.info("Bootstrap node started with name=" + name + " ,p2pId=" + p2pId + " ,port=" + port + " and version=" + VERSION);
|
log.info("Bootstrap node started with name=" + name + " ,p2pId=" + p2pId + " ,port=" + port +
|
||||||
|
" and network protocol version=" + Version.NETWORK_PROTOCOL_VERSION);
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (peer.peerBean().peerMap().all().size() > 0) {
|
if (peer.peerBean().peerMap().all().size() > 0) {
|
||||||
noPeersInfoPrinted = false;
|
noPeersInfoPrinted = false;
|
||||||
try {
|
|
||||||
log.info("Number of peers online = " + peer.peerBean().peerMap().all().size());
|
log.info("Number of peers online = " + peer.peerBean().peerMap().all().size());
|
||||||
for (PeerAddress peerAddress : peer.peerBean().peerMap().all()) {
|
for (PeerAddress peerAddress : peer.peerBean().peerMap().all()) {
|
||||||
log.info("Peer: " + peerAddress.toString());
|
log.info("Peer: " + peerAddress.toString());
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
|
||||||
log.error("Exception at run loop " + t.getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (noPeersInfoPrinted) {
|
else if (noPeersInfoPrinted) {
|
||||||
log.info("No peers online");
|
log.info("No peers online");
|
||||||
noPeersInfoPrinted = true;
|
noPeersInfoPrinted = true;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Thread.sleep(2000);
|
Thread.sleep(10000);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -32,14 +32,16 @@ public class BootstrapNodeMain extends BitsquareExecutable {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void customizeOptionParsing(OptionParser parser) {
|
protected void customizeOptionParsing(OptionParser parser) {
|
||||||
parser.accepts(Node.NAME_KEY, description("Name of this node", BootstrapNodes.getLocalhostNode().getName()))
|
BootstrapNodes bootstrapNodes = new BootstrapNodes();
|
||||||
|
bootstrapNodes.initWithNetworkId(Node.REG_TEST_P2P_ID); // use regtest as default
|
||||||
|
parser.accepts(Node.NAME_KEY, description("Name of this node", bootstrapNodes.getLocalhostNode().getName()))
|
||||||
.withRequiredArg()
|
.withRequiredArg()
|
||||||
.ofType(String.class);
|
.ofType(String.class);
|
||||||
parser.accepts(Node.P2P_ID_KEY, description("P2P network ID",
|
parser.accepts(Node.P2P_ID_KEY, description("P2P network ID",
|
||||||
BootstrapNodes.getLocalhostNode().getP2pId()))
|
bootstrapNodes.getLocalhostNode().getP2pId()))
|
||||||
.withRequiredArg()
|
.withRequiredArg()
|
||||||
.ofType(int.class);
|
.ofType(int.class);
|
||||||
parser.accepts(Node.PORT_KEY, description("Port to listen on", BootstrapNodes.getLocalhostNode().getPort()))
|
parser.accepts(Node.PORT_KEY, description("Port to listen on", bootstrapNodes.getLocalhostNode().getPort()))
|
||||||
.withRequiredArg()
|
.withRequiredArg()
|
||||||
.ofType(int.class);
|
.ofType(int.class);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
package io.bitsquare.app;
|
package io.bitsquare.app;
|
||||||
|
|
||||||
import io.bitsquare.BitsquareException;
|
import io.bitsquare.BitsquareException;
|
||||||
|
import io.bitsquare.btc.BitcoinNetwork;
|
||||||
import io.bitsquare.btc.UserAgent;
|
import io.bitsquare.btc.UserAgent;
|
||||||
import io.bitsquare.btc.WalletService;
|
import io.bitsquare.btc.WalletService;
|
||||||
import io.bitsquare.crypto.KeyStorage;
|
import io.bitsquare.crypto.KeyStorage;
|
||||||
|
@ -26,10 +27,19 @@ import io.bitsquare.storage.Storage;
|
||||||
import io.bitsquare.util.Utilities;
|
import io.bitsquare.util.Utilities;
|
||||||
import io.bitsquare.util.spring.JOptCommandLinePropertySource;
|
import io.bitsquare.util.spring.JOptCommandLinePropertySource;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import joptsimple.OptionSet;
|
import joptsimple.OptionSet;
|
||||||
import org.springframework.core.env.MutablePropertySources;
|
import org.springframework.core.env.MutablePropertySources;
|
||||||
import org.springframework.core.env.PropertiesPropertySource;
|
import org.springframework.core.env.PropertiesPropertySource;
|
||||||
|
@ -43,7 +53,9 @@ import org.springframework.core.io.support.ResourcePropertySource;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
public class BitsquareEnvironment extends StandardEnvironment {
|
public class BitsquareEnvironment extends StandardEnvironment {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(BitsquareEnvironment.class);
|
||||||
|
|
||||||
|
private static final String BITCOIN_NETWORK_PROP = "bitcoinNetwork.properties";
|
||||||
public static final String USER_DATA_DIR_KEY = "user.data.dir";
|
public static final String USER_DATA_DIR_KEY = "user.data.dir";
|
||||||
|
|
||||||
public static final String DEFAULT_USER_DATA_DIR = defaultUserDataDir();
|
public static final String DEFAULT_USER_DATA_DIR = defaultUserDataDir();
|
||||||
|
@ -52,7 +64,7 @@ public class BitsquareEnvironment extends StandardEnvironment {
|
||||||
public static final String DEFAULT_APP_NAME = "Bitsquare";
|
public static final String DEFAULT_APP_NAME = "Bitsquare";
|
||||||
|
|
||||||
public static final String APP_DATA_DIR_KEY = "app.data.dir";
|
public static final String APP_DATA_DIR_KEY = "app.data.dir";
|
||||||
public static final String DEFAULT_APP_DATA_DIR = appDataDir(DEFAULT_USER_DATA_DIR, DEFAULT_APP_NAME);
|
public static final String DEFAULT_APP_DATA_DIR = appDataDir(DEFAULT_USER_DATA_DIR, DEFAULT_APP_NAME, BitcoinNetwork.DEFAULT, Version.VERSION);
|
||||||
|
|
||||||
public static final String APP_DATA_DIR_CLEAN_KEY = "app.data.dir.clean";
|
public static final String APP_DATA_DIR_CLEAN_KEY = "app.data.dir.clean";
|
||||||
public static final String DEFAULT_APP_DATA_DIR_CLEAN = "false";
|
public static final String DEFAULT_APP_DATA_DIR_CLEAN = "false";
|
||||||
|
@ -60,12 +72,13 @@ public class BitsquareEnvironment extends StandardEnvironment {
|
||||||
static final String BITSQUARE_COMMANDLINE_PROPERTY_SOURCE_NAME = "bitsquareCommandLineProperties";
|
static final String BITSQUARE_COMMANDLINE_PROPERTY_SOURCE_NAME = "bitsquareCommandLineProperties";
|
||||||
static final String BITSQUARE_APP_DIR_PROPERTY_SOURCE_NAME = "bitsquareAppDirProperties";
|
static final String BITSQUARE_APP_DIR_PROPERTY_SOURCE_NAME = "bitsquareAppDirProperties";
|
||||||
static final String BITSQUARE_HOME_DIR_PROPERTY_SOURCE_NAME = "bitsquareHomeDirProperties";
|
static final String BITSQUARE_HOME_DIR_PROPERTY_SOURCE_NAME = "bitsquareHomeDirProperties";
|
||||||
static final String BITSQUARE_CLASSPATH_PROPERTY_SOURCE_NAME = "bitsquareClasspathProperties";
|
public static final String BITSQUARE_CLASSPATH_PROPERTY_SOURCE_NAME = "bitsquareClasspathProperties";
|
||||||
static final String BITSQUARE_DEFAULT_PROPERTY_SOURCE_NAME = "bitsquareDefaultProperties";
|
static final String BITSQUARE_DEFAULT_PROPERTY_SOURCE_NAME = "bitsquareDefaultProperties";
|
||||||
|
|
||||||
private final ResourceLoader resourceLoader = new DefaultResourceLoader();
|
private final ResourceLoader resourceLoader = new DefaultResourceLoader();
|
||||||
|
|
||||||
protected final String appName;
|
protected final String appName;
|
||||||
|
protected final String userDataDir;
|
||||||
protected final String appDataDir;
|
protected final String appDataDir;
|
||||||
protected final String bootstrapNodePort;
|
protected final String bootstrapNodePort;
|
||||||
|
|
||||||
|
@ -73,20 +86,60 @@ public class BitsquareEnvironment extends StandardEnvironment {
|
||||||
this(new JOptCommandLinePropertySource(BITSQUARE_COMMANDLINE_PROPERTY_SOURCE_NAME, checkNotNull(options)));
|
this(new JOptCommandLinePropertySource(BITSQUARE_COMMANDLINE_PROPERTY_SOURCE_NAME, checkNotNull(options)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BitcoinNetwork getBtcNetworkProperty() {
|
||||||
|
String dirString = Paths.get(userDataDir, appName, Version.VERSION).toString();
|
||||||
|
String fileString = Paths.get(dirString, BITCOIN_NETWORK_PROP).toString();
|
||||||
|
File dir = new File(dirString);
|
||||||
|
File file = new File(fileString);
|
||||||
|
if (!dir.exists())
|
||||||
|
dir.mkdirs();
|
||||||
|
|
||||||
|
if (!file.exists()) {
|
||||||
|
try {
|
||||||
|
file.createNewFile();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
log.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try (InputStream fileInputStream = new FileInputStream(file)) {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.load(fileInputStream);
|
||||||
|
String bitcoinNetwork = properties.getProperty("bitcoinNetwork", BitcoinNetwork.DEFAULT.name());
|
||||||
|
return BitcoinNetwork.valueOf(bitcoinNetwork);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
log.error(e.getMessage());
|
||||||
|
return BitcoinNetwork.DEFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBitcoinNetwork(BitcoinNetwork bitcoinNetwork) {
|
||||||
|
String path = Paths.get(userDataDir, appName, Version.VERSION, BITCOIN_NETWORK_PROP).toString();
|
||||||
|
File file = new File(path);
|
||||||
|
try (FileOutputStream fos = new FileOutputStream(file)) {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.setProperty("bitcoinNetwork", bitcoinNetwork.name());
|
||||||
|
properties.store(fos, null);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
log.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected BitsquareEnvironment(PropertySource commandLineProperties) {
|
protected BitsquareEnvironment(PropertySource commandLineProperties) {
|
||||||
String userDataDir = commandLineProperties.containsProperty(USER_DATA_DIR_KEY) ?
|
userDataDir = commandLineProperties.containsProperty(USER_DATA_DIR_KEY) ?
|
||||||
(String) commandLineProperties.getProperty(USER_DATA_DIR_KEY) :
|
(String) commandLineProperties.getProperty(USER_DATA_DIR_KEY) :
|
||||||
DEFAULT_USER_DATA_DIR;
|
DEFAULT_USER_DATA_DIR;
|
||||||
|
|
||||||
this.appName = commandLineProperties.containsProperty(APP_NAME_KEY) ?
|
appName = commandLineProperties.containsProperty(APP_NAME_KEY) ?
|
||||||
(String) commandLineProperties.getProperty(APP_NAME_KEY) :
|
(String) commandLineProperties.getProperty(APP_NAME_KEY) :
|
||||||
DEFAULT_APP_NAME;
|
DEFAULT_APP_NAME;
|
||||||
|
|
||||||
this.appDataDir = commandLineProperties.containsProperty(APP_DATA_DIR_KEY) ?
|
appDataDir = commandLineProperties.containsProperty(APP_DATA_DIR_KEY) ?
|
||||||
(String) commandLineProperties.getProperty(APP_DATA_DIR_KEY) :
|
(String) commandLineProperties.getProperty(APP_DATA_DIR_KEY) :
|
||||||
appDataDir(userDataDir, appName);
|
appDataDir(userDataDir, appName, getBtcNetworkProperty(), Version.VERSION);
|
||||||
|
|
||||||
this.bootstrapNodePort = commandLineProperties.containsProperty(TomP2PModule.BOOTSTRAP_NODE_PORT_KEY) ?
|
bootstrapNodePort = commandLineProperties.containsProperty(TomP2PModule.BOOTSTRAP_NODE_PORT_KEY) ?
|
||||||
(String) commandLineProperties.getProperty(TomP2PModule.BOOTSTRAP_NODE_PORT_KEY) : "-1";
|
(String) commandLineProperties.getProperty(TomP2PModule.BOOTSTRAP_NODE_PORT_KEY) : "-1";
|
||||||
|
|
||||||
MutablePropertySources propertySources = this.getPropertySources();
|
MutablePropertySources propertySources = this.getPropertySources();
|
||||||
|
@ -129,7 +182,6 @@ public class BitsquareEnvironment extends StandardEnvironment {
|
||||||
protected PropertySource<?> defaultProperties() {
|
protected PropertySource<?> defaultProperties() {
|
||||||
return new PropertiesPropertySource(BITSQUARE_DEFAULT_PROPERTY_SOURCE_NAME, new Properties() {
|
return new PropertiesPropertySource(BITSQUARE_DEFAULT_PROPERTY_SOURCE_NAME, new Properties() {
|
||||||
private static final long serialVersionUID = -8478089705207326165L;
|
private static final long serialVersionUID = -8478089705207326165L;
|
||||||
|
|
||||||
{
|
{
|
||||||
setProperty(APP_DATA_DIR_KEY, appDataDir);
|
setProperty(APP_DATA_DIR_KEY, appDataDir);
|
||||||
setProperty(APP_DATA_DIR_CLEAN_KEY, DEFAULT_APP_DATA_DIR_CLEAN);
|
setProperty(APP_DATA_DIR_CLEAN_KEY, DEFAULT_APP_DATA_DIR_CLEAN);
|
||||||
|
@ -149,7 +201,6 @@ public class BitsquareEnvironment extends StandardEnvironment {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static String defaultUserDataDir() {
|
private static String defaultUserDataDir() {
|
||||||
if (Utilities.isWindows())
|
if (Utilities.isWindows())
|
||||||
return System.getenv("APPDATA");
|
return System.getenv("APPDATA");
|
||||||
|
@ -159,7 +210,7 @@ public class BitsquareEnvironment extends StandardEnvironment {
|
||||||
return Paths.get(System.getProperty("user.home"), ".local", "share").toString();
|
return Paths.get(System.getProperty("user.home"), ".local", "share").toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String appDataDir(String userDataDir, String appName) {
|
private static String appDataDir(String userDataDir, String appName, BitcoinNetwork bitcoinNetwork, String version) {
|
||||||
return Paths.get(userDataDir, appName).toString();
|
return Paths.get(userDataDir, appName, version, bitcoinNetwork.name().toLowerCase()).toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,7 +136,7 @@ public class WalletService {
|
||||||
this.addressEntryList = addressEntryList;
|
this.addressEntryList = addressEntryList;
|
||||||
this.params = preferences.getBitcoinNetwork().getParameters();
|
this.params = preferences.getBitcoinNetwork().getParameters();
|
||||||
this.cryptoService = cryptoService;
|
this.cryptoService = cryptoService;
|
||||||
this.walletDir = new File(walletDir, preferences.getBitcoinNetwork().toString().toLowerCase());
|
this.walletDir = new File(walletDir, "bitcoin");
|
||||||
this.walletPrefix = walletPrefix;
|
this.walletPrefix = walletPrefix;
|
||||||
this.userAgent = userAgent;
|
this.userAgent = userAgent;
|
||||||
}
|
}
|
||||||
|
@ -176,6 +176,7 @@ public class WalletService {
|
||||||
// Now configure and start the appkit. This will take a second or two - we could show a temporary splash screen
|
// Now configure and start the appkit. This will take a second or two - we could show a temporary splash screen
|
||||||
// or progress widget to keep the user engaged whilst we initialise, but we don't.
|
// or progress widget to keep the user engaged whilst we initialise, but we don't.
|
||||||
if (params == RegTestParams.get()) {
|
if (params == RegTestParams.get()) {
|
||||||
|
log.debug("regTestHost " + regTestHost);
|
||||||
if (regTestHost == RegTestHost.REG_TEST_SERVER) {
|
if (regTestHost == RegTestHost.REG_TEST_SERVER) {
|
||||||
try {
|
try {
|
||||||
walletAppKit.setPeerNodes(new PeerAddress(InetAddress.getByName(RegTestHost.SERVER_IP), params.getPort()));
|
walletAppKit.setPeerNodes(new PeerAddress(InetAddress.getByName(RegTestHost.SERVER_IP), params.getPort()));
|
||||||
|
|
|
@ -19,83 +19,121 @@ package io.bitsquare.p2p;
|
||||||
|
|
||||||
import io.bitsquare.BitsquareException;
|
import io.bitsquare.BitsquareException;
|
||||||
|
|
||||||
|
import com.google.inject.name.Named;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import net.tomp2p.peers.Number160;
|
||||||
|
import net.tomp2p.peers.PeerAddress;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class BootstrapNodes {
|
public class BootstrapNodes {
|
||||||
private static final Logger log = LoggerFactory.getLogger(BootstrapNodes.class);
|
private static final Logger log = LoggerFactory.getLogger(BootstrapNodes.class);
|
||||||
|
public static final String BOOTSTRAP_NODE_KEY = "bootstrapNode";
|
||||||
|
|
||||||
private static final List<Node> bootstrapNodes = Arrays.asList(
|
private final List<Node> rawBootstrapNodes = Arrays.asList(
|
||||||
Node.at("digitalocean1.bitsquare.io", "188.226.179.109"),
|
Node.rawNodeAt("digitalocean1.bitsquare.io", "188.226.179.109"),
|
||||||
Node.at("aws1.bitsquare.io", "52.24.144.42"),
|
Node.rawNodeAt("aws1.bitsquare.io", "52.24.144.42"),
|
||||||
Node.at("aws2.bitsquare.io", "52.11.125.194")
|
Node.rawNodeAt("aws2.bitsquare.io", "52.11.125.194")
|
||||||
);
|
);
|
||||||
private static Node selectedNode;
|
private Node rawLocalhostNode = Node.rawNodeAt("localhost", "127.0.0.1");
|
||||||
|
|
||||||
public static List<Node> getAllBootstrapNodes(int p2pId) {
|
|
||||||
|
private Node preferredBootstrapNode;
|
||||||
|
private List<Node> bootstrapNodes;
|
||||||
|
private Node localhostNode;
|
||||||
|
private int p2pId;
|
||||||
|
private boolean inited;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public BootstrapNodes(@Named(BOOTSTRAP_NODE_KEY) Node preferredBootstrapNode) {
|
||||||
|
// preferredBootstrapNode need to be fully defined to get accepted (name, IP, p2pId, port)
|
||||||
|
if (preferredBootstrapNode.getName() != null
|
||||||
|
&& preferredBootstrapNode.getIp() != null
|
||||||
|
&& preferredBootstrapNode.getP2pId() != -1
|
||||||
|
&& preferredBootstrapNode.getPort() != -1) {
|
||||||
|
this.preferredBootstrapNode = preferredBootstrapNode;
|
||||||
|
}
|
||||||
|
else if (preferredBootstrapNode.getName() != null
|
||||||
|
|| preferredBootstrapNode.getIp() != null
|
||||||
|
|| preferredBootstrapNode.getP2pId() != -1
|
||||||
|
|| preferredBootstrapNode.getPort() != -1) {
|
||||||
|
log.debug("preferredBootstrapNode not fully defined (name, IP, p2pId, port). preferredBootstrapNode=" + preferredBootstrapNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BootstrapNodes() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initWithNetworkId(int p2pId) {
|
||||||
|
if (!inited) {
|
||||||
|
inited = true;
|
||||||
|
this.p2pId = p2pId;
|
||||||
|
if (preferredBootstrapNode != null) {
|
||||||
|
bootstrapNodes = Arrays.asList(preferredBootstrapNode);
|
||||||
|
}
|
||||||
|
else {
|
||||||
switch (p2pId) {
|
switch (p2pId) {
|
||||||
case Node.MAIN_NET_P2P_ID:
|
case Node.MAIN_NET_P2P_ID:
|
||||||
return bootstrapNodes.stream().map(e -> e.withP2pIdAndPort(Node.MAIN_NET_P2P_ID, Node.MAIN_NET_PORT)).collect(Collectors.toList());
|
bootstrapNodes = rawBootstrapNodes.stream()
|
||||||
|
.map(e -> e.withP2pIdAndPort(Node.MAIN_NET_P2P_ID, Node.MAIN_NET_PORT)).collect(Collectors.toList());
|
||||||
|
localhostNode = rawLocalhostNode.withP2pIdAndPort(Node.MAIN_NET_P2P_ID, Node.MAIN_NET_PORT);
|
||||||
|
break;
|
||||||
case Node.TEST_NET_P2P_ID:
|
case Node.TEST_NET_P2P_ID:
|
||||||
return bootstrapNodes.stream().map(e -> e.withP2pIdAndPort(Node.TEST_NET_P2P_ID, Node.TEST_NET_PORT)).collect(Collectors.toList());
|
bootstrapNodes = rawBootstrapNodes.stream()
|
||||||
|
.map(e -> e.withP2pIdAndPort(Node.TEST_NET_P2P_ID, Node.TEST_NET_PORT)).collect(Collectors.toList());
|
||||||
|
localhostNode = rawLocalhostNode.withP2pIdAndPort(Node.TEST_NET_P2P_ID, Node.TEST_NET_PORT);
|
||||||
|
break;
|
||||||
case Node.REG_TEST_P2P_ID:
|
case Node.REG_TEST_P2P_ID:
|
||||||
return bootstrapNodes.stream().map(e -> e.withP2pIdAndPort(Node.REG_TEST_P2P_ID, Node.REG_TEST_PORT)).collect(Collectors.toList());
|
bootstrapNodes = rawBootstrapNodes.stream()
|
||||||
|
.map(e -> e.withP2pIdAndPort(Node.REG_TEST_P2P_ID, Node.REG_TEST_PORT)).collect(Collectors.toList());
|
||||||
|
localhostNode = rawLocalhostNode.withP2pIdAndPort(Node.REG_TEST_P2P_ID, Node.REG_TEST_PORT);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new BitsquareException("Unsupported P2pId. p2pId=" + p2pId);
|
throw new BitsquareException("Unsupported P2pId. p2pId=" + p2pId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
public static Node selectNode(int p2pId) {
|
else {
|
||||||
if (selectedNode == null)
|
throw new BitsquareException("initWithNetworkId called twice");
|
||||||
selectedNode = getAllBootstrapNodes(p2pId).get(new Random().nextInt(bootstrapNodes.size()));
|
}
|
||||||
else
|
|
||||||
throw new BitsquareException("selectNode must be called only once.");
|
|
||||||
|
|
||||||
return selectedNode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Node getSelectedNode() {
|
public Node getRandomDiscoverNode() {
|
||||||
if (selectedNode == null)
|
return bootstrapNodes.get(new Random().nextInt(rawBootstrapNodes.size()));
|
||||||
throw new BitsquareException("selectNode must be called first.");
|
|
||||||
|
|
||||||
return selectedNode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Node getFallbackNode() {
|
public List<Node> getBootstrapNodes() {
|
||||||
if (bootstrapNodes.size() > 1)
|
return bootstrapNodes;
|
||||||
return BootstrapNodes.getAllBootstrapNodes(selectedNode.getP2pId()).stream().filter(e -> !e.equals(selectedNode)).findAny().get();
|
}
|
||||||
else
|
|
||||||
|
public List<PeerAddress> getBootstrapPeerAddresses() {
|
||||||
|
return bootstrapNodes.stream().map(e -> {
|
||||||
|
try {
|
||||||
|
return new PeerAddress(Number160.createHash(e.getName()), InetAddress.getByName(e.getIp()), e.getPort(), e.getPort());
|
||||||
|
} catch (UnknownHostException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
log.error(e1.getMessage());
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
}).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Localhost default use regtest
|
public Node getLocalhostNode() {
|
||||||
private static Node localhostNode = selectLocalhostNode(Node.REG_TEST_P2P_ID);
|
|
||||||
|
|
||||||
public static Node selectLocalhostNode(int p2pId) {
|
|
||||||
final Node localhostNode = Node.at("localhost", "127.0.0.1");
|
|
||||||
switch (p2pId) {
|
|
||||||
case Node.MAIN_NET_P2P_ID:
|
|
||||||
BootstrapNodes.localhostNode = localhostNode.withP2pIdAndPort(Node.MAIN_NET_P2P_ID, Node.MAIN_NET_PORT);
|
|
||||||
break;
|
|
||||||
case Node.TEST_NET_P2P_ID:
|
|
||||||
BootstrapNodes.localhostNode = localhostNode.withP2pIdAndPort(Node.TEST_NET_P2P_ID, Node.TEST_NET_PORT);
|
|
||||||
break;
|
|
||||||
case Node.REG_TEST_P2P_ID:
|
|
||||||
BootstrapNodes.localhostNode = localhostNode.withP2pIdAndPort(Node.REG_TEST_P2P_ID, Node.REG_TEST_PORT);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new BitsquareException("Unsupported P2pId. p2pId=" + p2pId);
|
|
||||||
}
|
|
||||||
return BootstrapNodes.localhostNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Node getLocalhostNode() {
|
|
||||||
return localhostNode;
|
return localhostNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getP2pId() {
|
||||||
|
return p2pId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,9 +32,7 @@ public interface ClientNode {
|
||||||
|
|
||||||
String getClientNodeInfo();
|
String getClientNodeInfo();
|
||||||
|
|
||||||
Node getBootstrapNode();
|
Observable<BootstrappedPeerBuilder.State> bootstrap(KeyPair keyPair);
|
||||||
|
|
||||||
Observable<BootstrappedPeerBuilder.State> bootstrap(int networkId, KeyPair keyPair);
|
|
||||||
|
|
||||||
ReadOnlyIntegerProperty numPeersProperty();
|
ReadOnlyIntegerProperty numPeersProperty();
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ public final class Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not fully defined node
|
// Not fully defined node
|
||||||
public static Node at(String name, String ip) {
|
public static Node rawNodeAt(String name, String ip) {
|
||||||
return Node.at(name, ip, -1, -1);
|
return Node.at(name, ip, -1, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,10 +76,6 @@ public final class Node {
|
||||||
return Node.at(this.name, this.ip, p2pId, port);
|
return Node.at(this.name, this.ip, p2pId, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* public static Node at(String name, int p2pId, String ip) {
|
|
||||||
return Node.at(name, ip, p2pId, DEFAULT_PORT);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
public static final int CLIENT_PORT = findFreeSystemPort();
|
public static final int CLIENT_PORT = findFreeSystemPort();
|
||||||
|
|
||||||
public static int findFreeSystemPort() {
|
public static int findFreeSystemPort() {
|
||||||
|
@ -98,8 +94,20 @@ public final class Node {
|
||||||
|
|
||||||
public PeerAddress toPeerAddressWithPort(int port) {
|
public PeerAddress toPeerAddressWithPort(int port) {
|
||||||
try {
|
try {
|
||||||
return new PeerAddress(Number160.createHash(getName()),
|
return new PeerAddress(Number160.createHash(name),
|
||||||
InetAddress.getByName(getIp()),
|
InetAddress.getByName(ip),
|
||||||
|
port,
|
||||||
|
port);
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
log.error(e.getMessage());
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public PeerAddress toPeerAddress() {
|
||||||
|
try {
|
||||||
|
return new PeerAddress(Number160.createHash(name),
|
||||||
|
InetAddress.getByName(ip),
|
||||||
port,
|
port,
|
||||||
port);
|
port);
|
||||||
} catch (UnknownHostException e) {
|
} catch (UnknownHostException e) {
|
||||||
|
|
|
@ -27,9 +27,6 @@ import com.google.inject.name.Named;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
|
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
|
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
@ -55,7 +52,6 @@ import net.tomp2p.nat.PeerBuilderNAT;
|
||||||
import net.tomp2p.nat.PeerNAT;
|
import net.tomp2p.nat.PeerNAT;
|
||||||
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.PeerAddress;
|
import net.tomp2p.peers.PeerAddress;
|
||||||
import net.tomp2p.peers.PeerMapChangeListener;
|
import net.tomp2p.peers.PeerMapChangeListener;
|
||||||
import net.tomp2p.peers.PeerStatistic;
|
import net.tomp2p.peers.PeerStatistic;
|
||||||
|
@ -75,7 +71,6 @@ import io.netty.util.concurrent.DefaultEventExecutorGroup;
|
||||||
public class BootstrappedPeerBuilder {
|
public class BootstrappedPeerBuilder {
|
||||||
private static final Logger log = LoggerFactory.getLogger(BootstrappedPeerBuilder.class);
|
private static final Logger log = LoggerFactory.getLogger(BootstrappedPeerBuilder.class);
|
||||||
|
|
||||||
static final String BOOTSTRAP_NODE_KEY = "bootstrapNode";
|
|
||||||
static final String NETWORK_INTERFACE_KEY = "interface";
|
static final String NETWORK_INTERFACE_KEY = "interface";
|
||||||
static final String NETWORK_INTERFACE_UNSPECIFIED = "<unspecified>";
|
static final String NETWORK_INTERFACE_UNSPECIFIED = "<unspecified>";
|
||||||
static final String USE_MANUAL_PORT_FORWARDING_KEY = "node.useManualPortForwarding";
|
static final String USE_MANUAL_PORT_FORWARDING_KEY = "node.useManualPortForwarding";
|
||||||
|
@ -117,17 +112,16 @@ public class BootstrappedPeerBuilder {
|
||||||
private final int port;
|
private final int port;
|
||||||
private final boolean useManualPortForwarding;
|
private final boolean useManualPortForwarding;
|
||||||
private final String networkInterface;
|
private final String networkInterface;
|
||||||
|
private BootstrapNodes bootstrapNodes;
|
||||||
private final Preferences preferences;
|
private final Preferences preferences;
|
||||||
|
|
||||||
private final SettableFuture<PeerDHT> settableFuture = SettableFuture.create();
|
private final SettableFuture<PeerDHT> settableFuture = SettableFuture.create();
|
||||||
private final ObjectProperty<State> state = new SimpleObjectProperty<>(State.UNDEFINED);
|
private final ObjectProperty<State> state = new SimpleObjectProperty<>(State.UNDEFINED);
|
||||||
private final ObjectProperty<ConnectionType> connectionType = new SimpleObjectProperty<>(ConnectionType.UNDEFINED);
|
private final ObjectProperty<ConnectionType> connectionType = new SimpleObjectProperty<>(ConnectionType.UNDEFINED);
|
||||||
|
|
||||||
private Node bootstrapNode;
|
|
||||||
private KeyPair keyPair;
|
private KeyPair keyPair;
|
||||||
private Peer peer;
|
private Peer peer;
|
||||||
private PeerDHT peerDHT;
|
private PeerDHT peerDHT;
|
||||||
private boolean retriedOtherBootstrapNode;
|
|
||||||
private Executor executor;
|
private Executor executor;
|
||||||
|
|
||||||
|
|
||||||
|
@ -138,13 +132,13 @@ public class BootstrappedPeerBuilder {
|
||||||
@Inject
|
@Inject
|
||||||
public BootstrappedPeerBuilder(@Named(Node.PORT_KEY) int port,
|
public BootstrappedPeerBuilder(@Named(Node.PORT_KEY) int port,
|
||||||
@Named(USE_MANUAL_PORT_FORWARDING_KEY) boolean useManualPortForwarding,
|
@Named(USE_MANUAL_PORT_FORWARDING_KEY) boolean useManualPortForwarding,
|
||||||
@Named(BOOTSTRAP_NODE_KEY) Node bootstrapNode,
|
|
||||||
@Named(NETWORK_INTERFACE_KEY) String networkInterface,
|
@Named(NETWORK_INTERFACE_KEY) String networkInterface,
|
||||||
|
BootstrapNodes bootstrapNodes,
|
||||||
Preferences preferences) {
|
Preferences preferences) {
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.useManualPortForwarding = useManualPortForwarding;
|
this.useManualPortForwarding = useManualPortForwarding;
|
||||||
this.bootstrapNode = bootstrapNode;
|
|
||||||
this.networkInterface = networkInterface;
|
this.networkInterface = networkInterface;
|
||||||
|
this.bootstrapNodes = bootstrapNodes;
|
||||||
this.preferences = preferences;
|
this.preferences = preferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,28 +160,8 @@ public class BootstrappedPeerBuilder {
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SettableFuture<PeerDHT> start(int p2pId) {
|
public SettableFuture<PeerDHT> start() {
|
||||||
try {
|
try {
|
||||||
Node selectedNode = BootstrapNodes.selectNode(p2pId);
|
|
||||||
String bootstrapNodeName = bootstrapNode.getName();
|
|
||||||
if (bootstrapNodeName == null)
|
|
||||||
bootstrapNodeName = selectedNode.getName();
|
|
||||||
|
|
||||||
String bootstrapNodeIp = bootstrapNode.getIp();
|
|
||||||
if (bootstrapNodeIp == null)
|
|
||||||
bootstrapNodeIp = selectedNode.getIp();
|
|
||||||
|
|
||||||
int bootstrapNodeP2pId = bootstrapNode.getP2pId();
|
|
||||||
if (bootstrapNodeP2pId == -1)
|
|
||||||
bootstrapNodeP2pId = selectedNode.getP2pId();
|
|
||||||
|
|
||||||
int bootstrapNodePort = bootstrapNode.getPort();
|
|
||||||
if (bootstrapNodePort == -1)
|
|
||||||
bootstrapNodePort = selectedNode.getPort();
|
|
||||||
|
|
||||||
bootstrapNode = Node.at(bootstrapNodeName, bootstrapNodeIp, bootstrapNodeP2pId, bootstrapNodePort);
|
|
||||||
log.debug("Bootstrap to {}", bootstrapNode.toString());
|
|
||||||
|
|
||||||
DefaultEventExecutorGroup eventExecutorGroup = new DefaultEventExecutorGroup(20);
|
DefaultEventExecutorGroup eventExecutorGroup = new DefaultEventExecutorGroup(20);
|
||||||
ChannelClientConfiguration clientConf = PeerBuilder.createDefaultChannelClientConfiguration();
|
ChannelClientConfiguration clientConf = PeerBuilder.createDefaultChannelClientConfiguration();
|
||||||
clientConf.pipelineFilter(new PeerBuilder.EventExecutorGroupFilter(eventExecutorGroup));
|
clientConf.pipelineFilter(new PeerBuilder.EventExecutorGroupFilter(eventExecutorGroup));
|
||||||
|
@ -202,7 +176,7 @@ public class BootstrappedPeerBuilder {
|
||||||
|
|
||||||
if (useManualPortForwarding) {
|
if (useManualPortForwarding) {
|
||||||
peer = new PeerBuilder(keyPair)
|
peer = new PeerBuilder(keyPair)
|
||||||
.p2pId(p2pId)
|
.p2pId(bootstrapNodes.getP2pId())
|
||||||
.channelClientConfiguration(clientConf)
|
.channelClientConfiguration(clientConf)
|
||||||
.channelServerConfiguration(serverConf)
|
.channelServerConfiguration(serverConf)
|
||||||
.ports(port)
|
.ports(port)
|
||||||
|
@ -213,7 +187,7 @@ public class BootstrappedPeerBuilder {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
peer = new PeerBuilder(keyPair)
|
peer = new PeerBuilder(keyPair)
|
||||||
.p2pId(p2pId)
|
.p2pId(bootstrapNodes.getP2pId())
|
||||||
.channelClientConfiguration(clientConf)
|
.channelClientConfiguration(clientConf)
|
||||||
.channelServerConfiguration(serverConf)
|
.channelServerConfiguration(serverConf)
|
||||||
.ports(port)
|
.ports(port)
|
||||||
|
@ -270,13 +244,13 @@ public class BootstrappedPeerBuilder {
|
||||||
// bootstrap node and use that peer as relay
|
// bootstrap node and use that peer as relay
|
||||||
|
|
||||||
private void discoverExternalAddressUsingUPnP() {
|
private void discoverExternalAddressUsingUPnP() {
|
||||||
FutureDiscover futureDiscover = peer.discover().peerAddress(getBootstrapAddress()).start();
|
Node randomNode = bootstrapNodes.getRandomDiscoverNode();
|
||||||
|
log.info("Random Node for discovering own address visible form outside: " + randomNode);
|
||||||
|
FutureDiscover futureDiscover = peer.discover().peerAddress(randomNode.toPeerAddress()).start();
|
||||||
setState(State.DISCOVERY_STARTED);
|
setState(State.DISCOVERY_STARTED);
|
||||||
PeerNAT peerNAT = new PeerBuilderNAT(peer).start();
|
PeerNAT peerNAT = new PeerBuilderNAT(peer).start();
|
||||||
|
|
||||||
FutureNAT futureNAT = peerNAT.startSetupPortforwarding(futureDiscover);
|
FutureNAT futureNAT = peerNAT.startSetupPortforwarding(futureDiscover);
|
||||||
FutureRelayNAT futureRelayNAT = peerNAT.startRelay(new TCPRelayClientConfig(), futureDiscover, futureNAT);
|
FutureRelayNAT futureRelayNAT = peerNAT.startRelay(new TCPRelayClientConfig(), futureDiscover, futureNAT);
|
||||||
|
|
||||||
futureRelayNAT.addListener(new BaseFutureListener<BaseFuture>() {
|
futureRelayNAT.addListener(new BaseFutureListener<BaseFuture>() {
|
||||||
@Override
|
@Override
|
||||||
public void operationComplete(BaseFuture futureRelayNAT) throws Exception {
|
public void operationComplete(BaseFuture futureRelayNAT) throws Exception {
|
||||||
|
@ -308,14 +282,6 @@ public class BootstrappedPeerBuilder {
|
||||||
setConnectionType(ConnectionType.RELAY);
|
setConnectionType(ConnectionType.RELAY);
|
||||||
bootstrap();
|
bootstrap();
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
Node fallbackNode = BootstrapNodes.getFallbackNode();
|
|
||||||
if (!retriedOtherBootstrapNode && fallbackNode != null) {
|
|
||||||
retriedOtherBootstrapNode = true;
|
|
||||||
bootstrapNode = fallbackNode;
|
|
||||||
log.warn("Bootstrap failed with bootstrapNode: " + bootstrapNode + ". We try again with another node.");
|
|
||||||
executor.execute(() -> discoverExternalAddress());
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
// All attempts failed. Give up...
|
// All attempts failed. Give up...
|
||||||
handleError(State.RELAY_FAILED, "NAT traversal using relay mode failed " + futureRelayNAT.failedReason());
|
handleError(State.RELAY_FAILED, "NAT traversal using relay mode failed " + futureRelayNAT.failedReason());
|
||||||
|
@ -323,7 +289,6 @@ public class BootstrappedPeerBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exceptionCaught(Throwable t) throws Exception {
|
public void exceptionCaught(Throwable t) throws Exception {
|
||||||
|
@ -333,12 +298,12 @@ public class BootstrappedPeerBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void discoverExternalAddress() {
|
private void discoverExternalAddress() {
|
||||||
FutureDiscover futureDiscover = peer.discover().peerAddress(getBootstrapAddress()).start();
|
Node randomNode = bootstrapNodes.getRandomDiscoverNode();
|
||||||
|
log.info("Random Node for discovering own address visible form outside: " + randomNode);
|
||||||
|
FutureDiscover futureDiscover = peer.discover().peerAddress(randomNode.toPeerAddress()).start();
|
||||||
setState(State.DISCOVERY_STARTED);
|
setState(State.DISCOVERY_STARTED);
|
||||||
PeerNAT peerNAT = new PeerBuilderNAT(peer).start();
|
PeerNAT peerNAT = new PeerBuilderNAT(peer).start();
|
||||||
|
|
||||||
FutureRelayNAT futureRelayNAT = peerNAT.startRelay(new TCPRelayClientConfig(), futureDiscover);
|
FutureRelayNAT futureRelayNAT = peerNAT.startRelay(new TCPRelayClientConfig(), futureDiscover);
|
||||||
|
|
||||||
futureRelayNAT.addListener(new BaseFutureListener<BaseFuture>() {
|
futureRelayNAT.addListener(new BaseFutureListener<BaseFuture>() {
|
||||||
@Override
|
@Override
|
||||||
public void operationComplete(BaseFuture futureRelayNAT) throws Exception {
|
public void operationComplete(BaseFuture futureRelayNAT) throws Exception {
|
||||||
|
@ -362,21 +327,12 @@ public class BootstrappedPeerBuilder {
|
||||||
setConnectionType(ConnectionType.RELAY);
|
setConnectionType(ConnectionType.RELAY);
|
||||||
bootstrap();
|
bootstrap();
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
Node fallbackNode = BootstrapNodes.getFallbackNode();
|
|
||||||
if (!retriedOtherBootstrapNode && fallbackNode != null) {
|
|
||||||
retriedOtherBootstrapNode = true;
|
|
||||||
bootstrapNode = fallbackNode;
|
|
||||||
log.warn("Bootstrap failed with bootstrapNode: " + bootstrapNode + ". We try again with another node.");
|
|
||||||
executor.execute(() -> discoverExternalAddress());
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
// All attempts failed. Give up...
|
// All attempts failed. Give up...
|
||||||
handleError(State.RELAY_FAILED, "NAT traversal using relay mode failed " + futureRelayNAT.failedReason());
|
handleError(State.RELAY_FAILED, "NAT traversal using relay mode failed " + futureRelayNAT.failedReason());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exceptionCaught(Throwable t) throws Exception {
|
public void exceptionCaught(Throwable t) throws Exception {
|
||||||
|
@ -389,9 +345,7 @@ public class BootstrappedPeerBuilder {
|
||||||
log.trace("start bootstrap");
|
log.trace("start bootstrap");
|
||||||
|
|
||||||
// We don't wait until bootstrap is done for speeding up startup process
|
// We don't wait until bootstrap is done for speeding up startup process
|
||||||
// settableFuture.set(peerDHT);
|
FutureBootstrap futureBootstrap = peer.bootstrap().bootstrapTo(bootstrapNodes.getBootstrapPeerAddresses()).start();
|
||||||
|
|
||||||
FutureBootstrap futureBootstrap = peer.bootstrap().peerAddress(getBootstrapAddress()).start();
|
|
||||||
futureBootstrap.addListener(new BaseFutureListener<BaseFuture>() {
|
futureBootstrap.addListener(new BaseFutureListener<BaseFuture>() {
|
||||||
@Override
|
@Override
|
||||||
public void operationComplete(BaseFuture future) throws Exception {
|
public void operationComplete(BaseFuture future) throws Exception {
|
||||||
|
@ -413,22 +367,6 @@ public class BootstrappedPeerBuilder {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private PeerAddress getBootstrapAddress() {
|
|
||||||
try {
|
|
||||||
return new PeerAddress(Number160.createHash(bootstrapNode.getName()),
|
|
||||||
InetAddress.getByName(bootstrapNode.getIp()),
|
|
||||||
bootstrapNode.getPort(),
|
|
||||||
bootstrapNode.getPort());
|
|
||||||
} catch (UnknownHostException e) {
|
|
||||||
log.error("getBootstrapAddress failed: " + e.getMessage());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Node getBootstrapNode() {
|
|
||||||
return bootstrapNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConnectionType getConnectionType() {
|
public ConnectionType getConnectionType() {
|
||||||
return connectionType.get();
|
return connectionType.get();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
package io.bitsquare.p2p.tomp2p;
|
package io.bitsquare.p2p.tomp2p;
|
||||||
|
|
||||||
import io.bitsquare.p2p.AddressService;
|
import io.bitsquare.p2p.AddressService;
|
||||||
|
import io.bitsquare.p2p.BootstrapNodes;
|
||||||
import io.bitsquare.p2p.ClientNode;
|
import io.bitsquare.p2p.ClientNode;
|
||||||
import io.bitsquare.p2p.MailboxService;
|
import io.bitsquare.p2p.MailboxService;
|
||||||
import io.bitsquare.p2p.MessageService;
|
import io.bitsquare.p2p.MessageService;
|
||||||
|
@ -33,7 +34,7 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
|
|
||||||
import static io.bitsquare.p2p.tomp2p.BootstrappedPeerBuilder.*;
|
import static io.bitsquare.p2p.tomp2p.BootstrappedPeerBuilder.NETWORK_INTERFACE_UNSPECIFIED;
|
||||||
|
|
||||||
public class TomP2PModule extends P2PModule {
|
public class TomP2PModule extends P2PModule {
|
||||||
private static final Logger log = LoggerFactory.getLogger(TomP2PModule.class);
|
private static final Logger log = LoggerFactory.getLogger(TomP2PModule.class);
|
||||||
|
@ -51,6 +52,7 @@ public class TomP2PModule extends P2PModule {
|
||||||
@Override
|
@Override
|
||||||
protected void doConfigure() {
|
protected void doConfigure() {
|
||||||
// Used both ClientNode and TomP2PNode for injection
|
// Used both ClientNode and TomP2PNode for injection
|
||||||
|
bind(BootstrapNodes.class).in(Singleton.class);
|
||||||
bind(ClientNode.class).to(TomP2PNode.class).in(Singleton.class);
|
bind(ClientNode.class).to(TomP2PNode.class).in(Singleton.class);
|
||||||
bind(TomP2PNode.class).in(Singleton.class);
|
bind(TomP2PNode.class).in(Singleton.class);
|
||||||
|
|
||||||
|
@ -64,7 +66,7 @@ public class TomP2PModule extends P2PModule {
|
||||||
bind(boolean.class).annotatedWith(Names.named(USE_MANUAL_PORT_FORWARDING_KEY)).toInstance(
|
bind(boolean.class).annotatedWith(Names.named(USE_MANUAL_PORT_FORWARDING_KEY)).toInstance(
|
||||||
env.getProperty(USE_MANUAL_PORT_FORWARDING_KEY, boolean.class, false));
|
env.getProperty(USE_MANUAL_PORT_FORWARDING_KEY, boolean.class, false));
|
||||||
|
|
||||||
bind(Node.class).annotatedWith(Names.named(BOOTSTRAP_NODE_KEY)).toInstance(
|
bind(Node.class).annotatedWith(Names.named(BootstrapNodes.BOOTSTRAP_NODE_KEY)).toInstance(
|
||||||
Node.at(env.getProperty(BOOTSTRAP_NODE_NAME_KEY, ""),
|
Node.at(env.getProperty(BOOTSTRAP_NODE_NAME_KEY, ""),
|
||||||
env.getProperty(BOOTSTRAP_NODE_IP_KEY, ""),
|
env.getProperty(BOOTSTRAP_NODE_IP_KEY, ""),
|
||||||
Integer.valueOf(env.getProperty(BOOTSTRAP_NODE_P2P_ID_KEY, "-1")),
|
Integer.valueOf(env.getProperty(BOOTSTRAP_NODE_P2P_ID_KEY, "-1")),
|
||||||
|
|
|
@ -21,7 +21,6 @@ import io.bitsquare.BitsquareException;
|
||||||
import io.bitsquare.common.handlers.ResultHandler;
|
import io.bitsquare.common.handlers.ResultHandler;
|
||||||
import io.bitsquare.p2p.BaseP2PService;
|
import io.bitsquare.p2p.BaseP2PService;
|
||||||
import io.bitsquare.p2p.ClientNode;
|
import io.bitsquare.p2p.ClientNode;
|
||||||
import io.bitsquare.p2p.Node;
|
|
||||||
|
|
||||||
import com.google.common.util.concurrent.FutureCallback;
|
import com.google.common.util.concurrent.FutureCallback;
|
||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
|
@ -91,7 +90,7 @@ public class TomP2PNode implements ClientNode {
|
||||||
bootstrappedPeerBuilder.setExecutor(executor);
|
bootstrappedPeerBuilder.setExecutor(executor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Observable<BootstrappedPeerBuilder.State> bootstrap(int p2pId, KeyPair keyPair) {
|
public Observable<BootstrappedPeerBuilder.State> bootstrap(KeyPair keyPair) {
|
||||||
bootstrappedPeerBuilder.setKeyPair(keyPair);
|
bootstrappedPeerBuilder.setKeyPair(keyPair);
|
||||||
|
|
||||||
bootstrappedPeerBuilder.getState().addListener((ov, oldValue, newValue) -> {
|
bootstrappedPeerBuilder.getState().addListener((ov, oldValue, newValue) -> {
|
||||||
|
@ -99,7 +98,7 @@ public class TomP2PNode implements ClientNode {
|
||||||
bootstrapStateSubject.onNext(newValue);
|
bootstrapStateSubject.onNext(newValue);
|
||||||
});
|
});
|
||||||
|
|
||||||
SettableFuture<PeerDHT> bootstrapFuture = bootstrappedPeerBuilder.start(p2pId);
|
SettableFuture<PeerDHT> bootstrapFuture = bootstrappedPeerBuilder.start();
|
||||||
Futures.addCallback(bootstrapFuture, new FutureCallback<PeerDHT>() {
|
Futures.addCallback(bootstrapFuture, new FutureCallback<PeerDHT>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(@Nullable PeerDHT peerDHT) {
|
public void onSuccess(@Nullable PeerDHT peerDHT) {
|
||||||
|
@ -179,11 +178,6 @@ public class TomP2PNode implements ClientNode {
|
||||||
"; port=" + peerAddress.peerSocketAddress().tcpPort();
|
"; port=" + peerAddress.peerSocketAddress().tcpPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Node getBootstrapNode() {
|
|
||||||
return bootstrappedPeerBuilder.getBootstrapNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addResultHandler(ResultHandler resultHandler) {
|
public void addResultHandler(ResultHandler resultHandler) {
|
||||||
resultHandlers.add(resultHandler);
|
resultHandlers.add(resultHandler);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,12 +47,10 @@ public class BuyerAsOffererTrade extends BuyerTrade implements OffererTrade, Ser
|
||||||
|
|
||||||
public BuyerAsOffererTrade(Offer offer, Storage<? extends TradableList> storage) {
|
public BuyerAsOffererTrade(Offer offer, Storage<? extends TradableList> storage) {
|
||||||
super(offer, storage);
|
super(offer, storage);
|
||||||
log.trace("Created by constructor");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||||
in.defaultReadObject();
|
in.defaultReadObject();
|
||||||
log.trace("Created from serialized form.");
|
|
||||||
|
|
||||||
initStateProperties();
|
initStateProperties();
|
||||||
initAmountProperty();
|
initAmountProperty();
|
||||||
|
|
|
@ -46,12 +46,10 @@ public class BuyerAsTakerTrade extends BuyerTrade implements TakerTrade, Seriali
|
||||||
|
|
||||||
public BuyerAsTakerTrade(Offer offer, Coin tradeAmount, Peer tradingPeer, Storage<? extends TradableList> storage) {
|
public BuyerAsTakerTrade(Offer offer, Coin tradeAmount, Peer tradingPeer, Storage<? extends TradableList> storage) {
|
||||||
super(offer, tradeAmount, tradingPeer, storage);
|
super(offer, tradeAmount, tradingPeer, storage);
|
||||||
log.trace("Created by constructor");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||||
in.defaultReadObject();
|
in.defaultReadObject();
|
||||||
log.trace("Created from serialized form.");
|
|
||||||
|
|
||||||
initStateProperties();
|
initStateProperties();
|
||||||
initAmountProperty();
|
initAmountProperty();
|
||||||
|
|
|
@ -40,12 +40,10 @@ public abstract class BuyerTrade extends Trade implements Serializable {
|
||||||
|
|
||||||
public BuyerTrade(Offer offer, Coin tradeAmount, Peer tradingPeer, Storage<? extends TradableList> storage) {
|
public BuyerTrade(Offer offer, Coin tradeAmount, Peer tradingPeer, Storage<? extends TradableList> storage) {
|
||||||
super(offer, tradeAmount, tradingPeer, storage);
|
super(offer, tradeAmount, tradingPeer, storage);
|
||||||
log.trace("Created by constructor");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BuyerTrade(Offer offer, Storage<? extends TradableList> storage) {
|
public BuyerTrade(Offer offer, Storage<? extends TradableList> storage) {
|
||||||
super(offer, storage);
|
super(offer, storage);
|
||||||
log.trace("Created by constructor");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -45,12 +45,10 @@ public class SellerAsOffererTrade extends SellerTrade implements OffererTrade, S
|
||||||
|
|
||||||
public SellerAsOffererTrade(Offer offer, Storage<? extends TradableList> storage) {
|
public SellerAsOffererTrade(Offer offer, Storage<? extends TradableList> storage) {
|
||||||
super(offer, storage);
|
super(offer, storage);
|
||||||
log.trace("Created by constructor");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||||
in.defaultReadObject();
|
in.defaultReadObject();
|
||||||
log.trace("Created from serialized form.");
|
|
||||||
|
|
||||||
initStateProperties();
|
initStateProperties();
|
||||||
initAmountProperty();
|
initAmountProperty();
|
||||||
|
|
|
@ -45,12 +45,10 @@ public class SellerAsTakerTrade extends SellerTrade implements TakerTrade, Seria
|
||||||
|
|
||||||
public SellerAsTakerTrade(Offer offer, Coin tradeAmount, Peer tradingPeer, Storage<? extends TradableList> storage) {
|
public SellerAsTakerTrade(Offer offer, Coin tradeAmount, Peer tradingPeer, Storage<? extends TradableList> storage) {
|
||||||
super(offer, tradeAmount, tradingPeer, storage);
|
super(offer, tradeAmount, tradingPeer, storage);
|
||||||
log.trace("Created by constructor");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
|
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||||
in.defaultReadObject();
|
in.defaultReadObject();
|
||||||
log.trace("Created from serialized form.");
|
|
||||||
|
|
||||||
initStateProperties();
|
initStateProperties();
|
||||||
initAmountProperty();
|
initAmountProperty();
|
||||||
|
|
|
@ -40,12 +40,10 @@ public abstract class SellerTrade extends Trade implements Serializable {
|
||||||
|
|
||||||
public SellerTrade(Offer offer, Coin tradeAmount, Peer tradingPeer, Storage<? extends TradableList> storage) {
|
public SellerTrade(Offer offer, Coin tradeAmount, Peer tradingPeer, Storage<? extends TradableList> storage) {
|
||||||
super(offer, tradeAmount, tradingPeer, storage);
|
super(offer, tradeAmount, tradingPeer, storage);
|
||||||
log.trace("Created by constructor");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SellerTrade(Offer offer, Storage<? extends TradableList> storage) {
|
public SellerTrade(Offer offer, Storage<? extends TradableList> storage) {
|
||||||
super(offer, storage);
|
super(offer, storage);
|
||||||
log.trace("Created by constructor");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -49,8 +49,6 @@ public class TradableList<T extends Tradable> extends ArrayList<T> implements Se
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public TradableList(Storage<TradableList<T>> storage, String fileName) {
|
public TradableList(Storage<TradableList<T>> storage, String fileName) {
|
||||||
log.trace("Created by constructor");
|
|
||||||
|
|
||||||
this.storage = storage;
|
this.storage = storage;
|
||||||
|
|
||||||
TradableList persisted = storage.initAndGetPersisted(this, fileName);
|
TradableList persisted = storage.initAndGetPersisted(this, fileName);
|
||||||
|
@ -62,7 +60,6 @@ public class TradableList<T extends Tradable> extends ArrayList<T> implements Se
|
||||||
|
|
||||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||||
in.defaultReadObject();
|
in.defaultReadObject();
|
||||||
log.trace("Created from serialized form.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -128,7 +128,6 @@ abstract public class Trade implements Tradable, Model, Serializable {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
protected Trade(Offer offer, Storage<? extends TradableList> storage) {
|
protected Trade(Offer offer, Storage<? extends TradableList> storage) {
|
||||||
log.trace("Created by constructor");
|
|
||||||
this.offer = offer;
|
this.offer = offer;
|
||||||
this.storage = storage;
|
this.storage = storage;
|
||||||
|
|
||||||
|
@ -156,7 +155,6 @@ abstract public class Trade implements Tradable, Model, Serializable {
|
||||||
|
|
||||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||||
in.defaultReadObject();
|
in.defaultReadObject();
|
||||||
log.trace("Created from serialized form.");
|
|
||||||
|
|
||||||
initStateProperties();
|
initStateProperties();
|
||||||
initAmountProperty();
|
initAmountProperty();
|
||||||
|
|
|
@ -80,13 +80,11 @@ public class ProcessModel implements Model, Serializable {
|
||||||
|
|
||||||
|
|
||||||
public ProcessModel() {
|
public ProcessModel() {
|
||||||
log.trace("Created by constructor");
|
|
||||||
tradingPeer = new TradingPeer();
|
tradingPeer = new TradingPeer();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||||
in.defaultReadObject();
|
in.defaultReadObject();
|
||||||
log.trace("Created from serialized form.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onAllServicesInitialized(Offer offer,
|
public void onAllServicesInitialized(Offer offer,
|
||||||
|
|
|
@ -60,12 +60,10 @@ public class TradingPeer implements Serializable {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public TradingPeer() {
|
public TradingPeer() {
|
||||||
log.trace("Created by constructor");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||||
in.defaultReadObject();
|
in.defaultReadObject();
|
||||||
log.trace("Created from serialized form.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
package io.bitsquare.user;
|
package io.bitsquare.user;
|
||||||
|
|
||||||
|
import io.bitsquare.app.BitsquareEnvironment;
|
||||||
import io.bitsquare.app.Version;
|
import io.bitsquare.app.Version;
|
||||||
import io.bitsquare.btc.BitcoinNetwork;
|
import io.bitsquare.btc.BitcoinNetwork;
|
||||||
import io.bitsquare.storage.Storage;
|
import io.bitsquare.storage.Storage;
|
||||||
|
@ -38,8 +39,6 @@ import javafx.beans.property.StringProperty;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
|
|
||||||
public class Preferences implements Serializable {
|
public class Preferences implements Serializable {
|
||||||
// That object is saved to disc. We need to take care of changes to not break deserialization.
|
// That object is saved to disc. We need to take care of changes to not break deserialization.
|
||||||
private static final long serialVersionUID = Version.LOCAL_DB_VERSION;
|
private static final long serialVersionUID = Version.LOCAL_DB_VERSION;
|
||||||
|
@ -48,11 +47,13 @@ public class Preferences implements Serializable {
|
||||||
|
|
||||||
// Deactivate mBit for now as most screens are not supporting it yet
|
// Deactivate mBit for now as most screens are not supporting it yet
|
||||||
transient private static final List<String> BTC_DENOMINATIONS = Arrays.asList(MonetaryFormat.CODE_BTC/*, MonetaryFormat.CODE_MBTC*/);
|
transient private static final List<String> BTC_DENOMINATIONS = Arrays.asList(MonetaryFormat.CODE_BTC/*, MonetaryFormat.CODE_MBTC*/);
|
||||||
|
|
||||||
public static List<String> getBtcDenominations() {
|
public static List<String> getBtcDenominations() {
|
||||||
return BTC_DENOMINATIONS;
|
return BTC_DENOMINATIONS;
|
||||||
}
|
}
|
||||||
|
|
||||||
transient private final Storage<Preferences> storage;
|
transient private final Storage<Preferences> storage;
|
||||||
|
transient private BitsquareEnvironment bitsquareEnvironment;
|
||||||
|
|
||||||
// Persisted fields
|
// Persisted fields
|
||||||
private String btcDenomination = MonetaryFormat.CODE_BTC;
|
private String btcDenomination = MonetaryFormat.CODE_BTC;
|
||||||
|
@ -61,7 +62,7 @@ public class Preferences implements Serializable {
|
||||||
private boolean useEffects = true;
|
private boolean useEffects = true;
|
||||||
private boolean displaySecurityDepositInfo = true;
|
private boolean displaySecurityDepositInfo = true;
|
||||||
private boolean useUPnP = true;
|
private boolean useUPnP = true;
|
||||||
private BitcoinNetwork bitcoinNetwork;
|
transient private BitcoinNetwork bitcoinNetwork;
|
||||||
|
|
||||||
// Observable wrappers
|
// Observable wrappers
|
||||||
transient private final StringProperty btcDenominationProperty = new SimpleStringProperty(btcDenomination);
|
transient private final StringProperty btcDenominationProperty = new SimpleStringProperty(btcDenomination);
|
||||||
|
@ -74,8 +75,9 @@ public class Preferences implements Serializable {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public Preferences(Storage<Preferences> storage, Environment environment) {
|
public Preferences(Storage<Preferences> storage, BitsquareEnvironment bitsquareEnvironment) {
|
||||||
this.storage = storage;
|
this.storage = storage;
|
||||||
|
this.bitsquareEnvironment = bitsquareEnvironment;
|
||||||
|
|
||||||
Preferences persisted = storage.initAndGetPersisted(this);
|
Preferences persisted = storage.initAndGetPersisted(this);
|
||||||
if (persisted != null) {
|
if (persisted != null) {
|
||||||
|
@ -83,12 +85,10 @@ public class Preferences implements Serializable {
|
||||||
setUseAnimations(persisted.useAnimations);
|
setUseAnimations(persisted.useAnimations);
|
||||||
setUseEffects(persisted.useEffects);
|
setUseEffects(persisted.useEffects);
|
||||||
setUseUPnP(persisted.useUPnP);
|
setUseUPnP(persisted.useUPnP);
|
||||||
setBitcoinNetwork(persisted.bitcoinNetwork);
|
|
||||||
displaySecurityDepositInfo = persisted.getDisplaySecurityDepositInfo();
|
displaySecurityDepositInfo = persisted.getDisplaySecurityDepositInfo();
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
setBitcoinNetwork(environment.getProperty(BitcoinNetwork.KEY, BitcoinNetwork.class, BitcoinNetwork.DEFAULT));
|
setBitcoinNetwork(bitsquareEnvironment.getBtcNetworkProperty());
|
||||||
}
|
|
||||||
|
|
||||||
// Use that to guarantee update of the serializable field and to make a storage update in case of a change
|
// Use that to guarantee update of the serializable field and to make a storage update in case of a change
|
||||||
btcDenominationProperty.addListener((ov) -> {
|
btcDenominationProperty.addListener((ov) -> {
|
||||||
|
@ -133,8 +133,10 @@ public class Preferences implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBitcoinNetwork(BitcoinNetwork bitcoinNetwork) {
|
public void setBitcoinNetwork(BitcoinNetwork bitcoinNetwork) {
|
||||||
|
if (this.bitcoinNetwork != bitcoinNetwork)
|
||||||
|
bitsquareEnvironment.setBitcoinNetwork(bitcoinNetwork);
|
||||||
|
|
||||||
this.bitcoinNetwork = bitcoinNetwork;
|
this.bitcoinNetwork = bitcoinNetwork;
|
||||||
storage.queueUpForSave();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,8 @@ public class NodeTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEqualsAndHashCode() {
|
public void testEqualsAndHashCode() {
|
||||||
Node node1a = Node.at("bitsquare1.example.com", "203.0.113.1");
|
Node node1a = Node.rawNodeAt("bitsquare1.example.com", "203.0.113.1");
|
||||||
Node node1b = Node.at("bitsquare1.example.com", "203.0.113.1");
|
Node node1b = Node.rawNodeAt("bitsquare1.example.com", "203.0.113.1");
|
||||||
|
|
||||||
assertThat(node1a, equalTo(node1a));
|
assertThat(node1a, equalTo(node1a));
|
||||||
|
|
||||||
|
@ -37,10 +37,10 @@ public class NodeTests {
|
||||||
assertThat(node1a, not((Object) equalTo(null)));
|
assertThat(node1a, not((Object) equalTo(null)));
|
||||||
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.rawNodeAt("bitsquare2.example.com", node1a.getIp()))));
|
||||||
assertThat(node1a, not(equalTo(Node.at(node1a.getName(), "203.0.113.2"))));
|
assertThat(node1a, not(equalTo(Node.rawNodeAt(node1a.getName(), "203.0.113.2"))));
|
||||||
|
|
||||||
Node node2 = Node.at("bitsquare2.example.com", "203.0.113.2");
|
Node node2 = Node.rawNodeAt("bitsquare2.example.com", "203.0.113.2");
|
||||||
assertThat(node1a.hashCode(), equalTo(node1b.hashCode()));
|
assertThat(node1a.hashCode(), equalTo(node1b.hashCode()));
|
||||||
assertThat(node1a.hashCode(), not(equalTo(node2.hashCode())));
|
assertThat(node1a.hashCode(), not(equalTo(node2.hashCode())));
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,11 +90,14 @@ public class TomP2PTests {
|
||||||
|
|
||||||
private static final PeerAddress BOOTSTRAP_NODE_ADDRESS;
|
private static final PeerAddress BOOTSTRAP_NODE_ADDRESS;
|
||||||
|
|
||||||
|
private static final BootstrapNodes bootstrapNodes;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
int p2pId = 1;
|
int p2pId = 1;
|
||||||
|
bootstrapNodes = new BootstrapNodes();
|
||||||
if (FORCED_CONNECTION_TYPE == BootstrappedPeerBuilder.ConnectionType.DIRECT) {
|
if (FORCED_CONNECTION_TYPE == BootstrappedPeerBuilder.ConnectionType.DIRECT) {
|
||||||
BootstrapNodes.selectLocalhostNode(p2pId);
|
bootstrapNodes.initWithNetworkId(p2pId);
|
||||||
BOOTSTRAP_NODE = BootstrapNodes.getLocalhostNode();
|
BOOTSTRAP_NODE = bootstrapNodes.getLocalhostNode();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BOOTSTRAP_NODE = Node.at("digitalocean1.dev.bitsquare.io", "188.226.179.109", p2pId, 7367);
|
BOOTSTRAP_NODE = Node.at("digitalocean1.dev.bitsquare.io", "188.226.179.109", p2pId, 7367);
|
||||||
|
@ -318,9 +321,7 @@ public class TomP2PTests {
|
||||||
PeerDHT peer1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash("peer1")).ports(3006).start()).start();
|
PeerDHT peer1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash("peer1")).ports(3006).start()).start();
|
||||||
PeerDHT peer2 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash("peer2")).ports(3007).start()).start();
|
PeerDHT peer2 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash("peer2")).ports(3007).start()).start();
|
||||||
*/
|
*/
|
||||||
PeerAddress masterPeerAddress = new PeerAddress(Number160.createHash(BootstrapNodes.getLocalhostNode().getName()),
|
PeerAddress masterPeerAddress = bootstrapNodes.getLocalhostNode().toPeerAddress();
|
||||||
BootstrapNodes.getLocalhostNode().getIp(), BootstrapNodes.getLocalhostNode().getPort(),
|
|
||||||
BootstrapNodes.getLocalhostNode().getPort());
|
|
||||||
|
|
||||||
// start both at the same time
|
// start both at the same time
|
||||||
BaseFuture fb1 = peer1.peer().bootstrap().peerAddress(masterPeerAddress).start();
|
BaseFuture fb1 = peer1.peer().bootstrap().peerAddress(masterPeerAddress).start();
|
||||||
|
|
|
@ -123,7 +123,7 @@ public class BitsquareAppMain extends BitsquareExecutable {
|
||||||
parser.accepts(USE_MANUAL_PORT_FORWARDING_KEY, description("Use manual port forwarding", false))
|
parser.accepts(USE_MANUAL_PORT_FORWARDING_KEY, description("Use manual port forwarding", false))
|
||||||
.withRequiredArg()
|
.withRequiredArg()
|
||||||
.ofType(boolean.class);
|
.ofType(boolean.class);
|
||||||
parser.accepts(BitcoinNetwork.KEY, description("", BitcoinNetwork.DEFAULT))
|
parser.accepts(BitcoinNetwork.KEY, description("Bitcoin network", BitcoinNetwork.DEFAULT))
|
||||||
.withRequiredArg()
|
.withRequiredArg()
|
||||||
.ofType(BitcoinNetwork.class)
|
.ofType(BitcoinNetwork.class)
|
||||||
.withValuesConvertedBy(new EnumValueConverter(BitcoinNetwork.class));
|
.withValuesConvertedBy(new EnumValueConverter(BitcoinNetwork.class));
|
||||||
|
@ -133,15 +133,16 @@ public class BitsquareAppMain extends BitsquareExecutable {
|
||||||
.ofType(RegTestHost.class)
|
.ofType(RegTestHost.class)
|
||||||
.withValuesConvertedBy(new EnumValueConverter(RegTestHost.class));
|
.withValuesConvertedBy(new EnumValueConverter(RegTestHost.class));
|
||||||
|
|
||||||
|
BootstrapNodes bootstrapNodes = new BootstrapNodes();
|
||||||
parser.accepts(BOOTSTRAP_NODE_NAME_KEY, description("Bootstrap node name", BootstrapNodes.getLocalhostNode().getName()))
|
bootstrapNodes.initWithNetworkId(Node.REG_TEST_P2P_ID); // use regtest as default
|
||||||
|
parser.accepts(BOOTSTRAP_NODE_NAME_KEY, description("Bootstrap node name", bootstrapNodes.getLocalhostNode().getName()))
|
||||||
.withRequiredArg();
|
.withRequiredArg();
|
||||||
parser.accepts(BOOTSTRAP_NODE_IP_KEY, description("Bootstrap node IP", BootstrapNodes.getLocalhostNode().getIp()))
|
parser.accepts(BOOTSTRAP_NODE_IP_KEY, description("Bootstrap node IP", bootstrapNodes.getLocalhostNode().getIp()))
|
||||||
.withRequiredArg();
|
.withRequiredArg();
|
||||||
parser.accepts(BOOTSTRAP_NODE_P2P_ID_KEY, description("Bootstrap node p2p network ID", BootstrapNodes.getLocalhostNode().getPort()))
|
parser.accepts(BOOTSTRAP_NODE_P2P_ID_KEY, description("Bootstrap node p2p network ID", bootstrapNodes.getLocalhostNode().getPort()))
|
||||||
.withRequiredArg()
|
.withRequiredArg()
|
||||||
.ofType(int.class);
|
.ofType(int.class);
|
||||||
parser.accepts(BOOTSTRAP_NODE_PORT_KEY, description("Bootstrap node port", BootstrapNodes.getLocalhostNode().getPort()))
|
parser.accepts(BOOTSTRAP_NODE_PORT_KEY, description("Bootstrap node port", bootstrapNodes.getLocalhostNode().getPort()))
|
||||||
.withRequiredArg()
|
.withRequiredArg()
|
||||||
.ofType(int.class);
|
.ofType(int.class);
|
||||||
parser.accepts(NETWORK_INTERFACE_KEY, description("Network interface", null))
|
parser.accepts(NETWORK_INTERFACE_KEY, description("Network interface", null))
|
||||||
|
|
|
@ -73,7 +73,7 @@ class BitsquareAppModule extends BitsquareModule {
|
||||||
File keyStorageDir = new File(env.getRequiredProperty(KeyStorage.DIR_KEY));
|
File keyStorageDir = new File(env.getRequiredProperty(KeyStorage.DIR_KEY));
|
||||||
bind(File.class).annotatedWith(named(KeyStorage.DIR_KEY)).toInstance(keyStorageDir);
|
bind(File.class).annotatedWith(named(KeyStorage.DIR_KEY)).toInstance(keyStorageDir);
|
||||||
|
|
||||||
bind(Environment.class).toInstance(env);
|
bind(BitsquareEnvironment.class).toInstance((BitsquareEnvironment) env);
|
||||||
bind(UpdateProcess.class).in(Singleton.class);
|
bind(UpdateProcess.class).in(Singleton.class);
|
||||||
|
|
||||||
// ordering is used for shut down sequence
|
// ordering is used for shut down sequence
|
||||||
|
|
|
@ -68,7 +68,7 @@ public class UpdateProcess {
|
||||||
protected Timer timeoutTimer;
|
protected Timer timeoutTimer;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public UpdateProcess(Environment environment) {
|
public UpdateProcess(BitsquareEnvironment environment) {
|
||||||
this.environment = environment;
|
this.environment = environment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ import io.bitsquare.gui.common.model.ViewModel;
|
||||||
import io.bitsquare.gui.util.BSFormatter;
|
import io.bitsquare.gui.util.BSFormatter;
|
||||||
import io.bitsquare.locale.CountryUtil;
|
import io.bitsquare.locale.CountryUtil;
|
||||||
import io.bitsquare.p2p.BaseP2PService;
|
import io.bitsquare.p2p.BaseP2PService;
|
||||||
|
import io.bitsquare.p2p.BootstrapNodes;
|
||||||
import io.bitsquare.p2p.ClientNode;
|
import io.bitsquare.p2p.ClientNode;
|
||||||
import io.bitsquare.p2p.tomp2p.BootstrappedPeerBuilder;
|
import io.bitsquare.p2p.tomp2p.BootstrappedPeerBuilder;
|
||||||
import io.bitsquare.trade.Trade;
|
import io.bitsquare.trade.Trade;
|
||||||
|
@ -77,7 +78,6 @@ class MainViewModel implements ViewModel {
|
||||||
private final OpenOfferManager openOfferManager;
|
private final OpenOfferManager openOfferManager;
|
||||||
private final UpdateProcess updateProcess;
|
private final UpdateProcess updateProcess;
|
||||||
private final BSFormatter formatter;
|
private final BSFormatter formatter;
|
||||||
private final int p2pId;
|
|
||||||
|
|
||||||
// BTC network
|
// BTC network
|
||||||
final StringProperty blockchainSyncInfo = new SimpleStringProperty("Initializing");
|
final StringProperty blockchainSyncInfo = new SimpleStringProperty("Initializing");
|
||||||
|
@ -120,7 +120,7 @@ class MainViewModel implements ViewModel {
|
||||||
@Inject
|
@Inject
|
||||||
public MainViewModel(User user, KeyRing keyRing, WalletService walletService, ArbitrationRepository arbitrationRepository, ClientNode clientNode,
|
public MainViewModel(User user, KeyRing keyRing, WalletService walletService, ArbitrationRepository arbitrationRepository, ClientNode clientNode,
|
||||||
TradeManager tradeManager, OpenOfferManager openOfferManager, Preferences preferences, UpdateProcess updateProcess,
|
TradeManager tradeManager, OpenOfferManager openOfferManager, Preferences preferences, UpdateProcess updateProcess,
|
||||||
BSFormatter formatter) {
|
BootstrapNodes bootstrapNodes, BSFormatter formatter) {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
this.keyRing = keyRing;
|
this.keyRing = keyRing;
|
||||||
this.walletService = walletService;
|
this.walletService = walletService;
|
||||||
|
@ -132,7 +132,7 @@ class MainViewModel implements ViewModel {
|
||||||
this.formatter = formatter;
|
this.formatter = formatter;
|
||||||
|
|
||||||
bitcoinNetworkAsString = formatter.formatBitcoinNetwork(preferences.getBitcoinNetwork());
|
bitcoinNetworkAsString = formatter.formatBitcoinNetwork(preferences.getBitcoinNetwork());
|
||||||
p2pId = preferences.getBitcoinNetwork().ordinal() + 10; // p2pId: Mainnet 10, testnet 11, regtest 12
|
bootstrapNodes.initWithNetworkId(preferences.getBitcoinNetwork().ordinal() + 10);
|
||||||
|
|
||||||
updateProcess.state.addListener((observableValue, oldValue, newValue) -> applyUpdateState(newValue));
|
updateProcess.state.addListener((observableValue, oldValue, newValue) -> applyUpdateState(newValue));
|
||||||
applyUpdateState(updateProcess.state.get());
|
applyUpdateState(updateProcess.state.get());
|
||||||
|
@ -206,7 +206,7 @@ class MainViewModel implements ViewModel {
|
||||||
});
|
});
|
||||||
|
|
||||||
clientNode.setExecutor(Platform::runLater);
|
clientNode.setExecutor(Platform::runLater);
|
||||||
Observable<BootstrappedPeerBuilder.State> bootstrapStateAsObservable = clientNode.bootstrap(p2pId, keyRing.getDhtSignatureKeyPair());
|
Observable<BootstrappedPeerBuilder.State> bootstrapStateAsObservable = clientNode.bootstrap(keyRing.getDhtSignatureKeyPair());
|
||||||
bootstrapStateAsObservable.publish();
|
bootstrapStateAsObservable.publish();
|
||||||
bootstrapStateAsObservable.subscribe(
|
bootstrapStateAsObservable.subscribe(
|
||||||
state -> Platform.runLater(() -> setBootstrapState(state)),
|
state -> Platform.runLater(() -> setBootstrapState(state)),
|
||||||
|
|
|
@ -85,8 +85,8 @@
|
||||||
<TextField fx:id="nodeAddress" GridPane.rowIndex="6" GridPane.columnIndex="1"
|
<TextField fx:id="nodeAddress" GridPane.rowIndex="6" GridPane.columnIndex="1"
|
||||||
mouseTransparent="true" focusTraversable="false"/>
|
mouseTransparent="true" focusTraversable="false"/>
|
||||||
|
|
||||||
<Label text="P2P bootstrap node address:" GridPane.rowIndex="7"/>
|
<Label text="P2P bootstrap node addresses:" GridPane.rowIndex="7" GridPane.valignment="TOP"/>
|
||||||
<TextField fx:id="bootstrapNodeAddress" GridPane.rowIndex="7" GridPane.columnIndex="1"
|
<TextArea fx:id="bootstrapNodeAddress" GridPane.rowIndex="7" GridPane.columnIndex="1"
|
||||||
mouseTransparent="true" focusTraversable="false"/>
|
mouseTransparent="true" focusTraversable="false"/>
|
||||||
|
|
||||||
<columnConstraints>
|
<columnConstraints>
|
||||||
|
|
|
@ -25,11 +25,13 @@ import io.bitsquare.gui.common.view.InitializableView;
|
||||||
import io.bitsquare.gui.components.Popups;
|
import io.bitsquare.gui.components.Popups;
|
||||||
import io.bitsquare.gui.util.BSFormatter;
|
import io.bitsquare.gui.util.BSFormatter;
|
||||||
import io.bitsquare.locale.BSResources;
|
import io.bitsquare.locale.BSResources;
|
||||||
|
import io.bitsquare.p2p.BootstrapNodes;
|
||||||
import io.bitsquare.p2p.ClientNode;
|
import io.bitsquare.p2p.ClientNode;
|
||||||
import io.bitsquare.user.Preferences;
|
import io.bitsquare.user.Preferences;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
@ -48,17 +50,20 @@ public class NetworkSettingsView extends InitializableView {
|
||||||
|
|
||||||
private final String bitcoinNetworkString;
|
private final String bitcoinNetworkString;
|
||||||
private final WalletService walletService;
|
private final WalletService walletService;
|
||||||
|
private BootstrapNodes bootstrapNodes;
|
||||||
private final Preferences preferences;
|
private final Preferences preferences;
|
||||||
private final ClientNode clientNode;
|
private final ClientNode clientNode;
|
||||||
|
|
||||||
@FXML TextField bitcoinNetwork, connectionType, nodeAddress, bootstrapNodeAddress, connectedPeersBTC, connectedPeersP2P;
|
@FXML TextField bitcoinNetwork, connectionType, nodeAddress, connectedPeersBTC, connectedPeersP2P;
|
||||||
@FXML CheckBox useUPnP;
|
@FXML CheckBox useUPnP;
|
||||||
@FXML ComboBox<BitcoinNetwork> netWorkComboBox;
|
@FXML ComboBox<BitcoinNetwork> netWorkComboBox;
|
||||||
|
@FXML TextArea bootstrapNodeAddress;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public NetworkSettingsView(WalletService walletService, ClientNode clientNode, Preferences preferences, BSFormatter
|
public NetworkSettingsView(WalletService walletService, ClientNode clientNode, BootstrapNodes bootstrapNodes, Preferences preferences, BSFormatter
|
||||||
formatter) {
|
formatter) {
|
||||||
this.walletService = walletService;
|
this.walletService = walletService;
|
||||||
|
this.bootstrapNodes = bootstrapNodes;
|
||||||
this.preferences = preferences;
|
this.preferences = preferences;
|
||||||
this.bitcoinNetworkString = formatter.formatBitcoinNetwork(preferences.getBitcoinNetwork());
|
this.bitcoinNetworkString = formatter.formatBitcoinNetwork(preferences.getBitcoinNetwork());
|
||||||
this.clientNode = clientNode;
|
this.clientNode = clientNode;
|
||||||
|
@ -72,7 +77,10 @@ public class NetworkSettingsView extends InitializableView {
|
||||||
connectionType.setText(clientNode.getConnectionType().toString());
|
connectionType.setText(clientNode.getConnectionType().toString());
|
||||||
connectedPeersP2P.textProperty().bind(createStringBinding(() -> String.valueOf(clientNode.numPeersProperty().get()), clientNode.numPeersProperty()));
|
connectedPeersP2P.textProperty().bind(createStringBinding(() -> String.valueOf(clientNode.numPeersProperty().get()), clientNode.numPeersProperty()));
|
||||||
nodeAddress.setText(clientNode.getClientNodeInfo());
|
nodeAddress.setText(clientNode.getClientNodeInfo());
|
||||||
bootstrapNodeAddress.setText(clientNode.getBootstrapNode().toString());
|
String bootstrapNodesText = bootstrapNodes.getBootstrapNodes().stream().map(e -> e.toString() + "\n").collect(Collectors.toList()).toString()
|
||||||
|
.replace(", ", "").replace("[", "").replace("\n]", "");
|
||||||
|
bootstrapNodeAddress.setPrefRowCount(bootstrapNodes.getBootstrapNodes().size());
|
||||||
|
bootstrapNodeAddress.setText(bootstrapNodesText);
|
||||||
|
|
||||||
useUPnP.setSelected(preferences.getUseUPnP());
|
useUPnP.setSelected(preferences.getUseUPnP());
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue