diff --git a/common/src/main/java/io/bitsquare/app/ProgramArguments.java b/common/src/main/java/io/bitsquare/app/ProgramArguments.java index c2a12dd6b0..ce50a240c0 100644 --- a/common/src/main/java/io/bitsquare/app/ProgramArguments.java +++ b/common/src/main/java/io/bitsquare/app/ProgramArguments.java @@ -14,6 +14,7 @@ public class ProgramArguments { public static final String NAME_KEY = "node.name"; public static final String PORT_KEY = "node.port"; + public static final String NETWORK_ID = "network.id"; private static final Logger log = LoggerFactory.getLogger(ProgramArguments.class); } diff --git a/core/src/main/java/io/bitsquare/app/BitsquareEnvironment.java b/core/src/main/java/io/bitsquare/app/BitsquareEnvironment.java index 643637087c..81bca7d2f2 100644 --- a/core/src/main/java/io/bitsquare/app/BitsquareEnvironment.java +++ b/core/src/main/java/io/bitsquare/app/BitsquareEnvironment.java @@ -192,11 +192,13 @@ public class BitsquareEnvironment extends StandardEnvironment { setProperty(Storage.DIR_KEY, Paths.get(btcNetworkDir, "db").toString()); setProperty(KeyStorage.DIR_KEY, Paths.get(btcNetworkDir, "keys").toString()); setProperty(ProgramArguments.TOR_DIR, Paths.get(btcNetworkDir, "tor").toString()); + + setProperty(ProgramArguments.NETWORK_ID, String.valueOf(bitcoinNetwork.ordinal())); } }); } - private static String defaultUserDataDir() { + public static String defaultUserDataDir() { if (Utilities.isWindows()) return System.getenv("APPDATA"); else if (Utilities.isOSX()) diff --git a/core/src/main/java/io/bitsquare/arbitration/messages/DisputeMessage.java b/core/src/main/java/io/bitsquare/arbitration/messages/DisputeMessage.java index 3c3f324274..41a53585e0 100644 --- a/core/src/main/java/io/bitsquare/arbitration/messages/DisputeMessage.java +++ b/core/src/main/java/io/bitsquare/arbitration/messages/DisputeMessage.java @@ -21,8 +21,10 @@ import io.bitsquare.app.Version; import io.bitsquare.p2p.messaging.MailboxMessage; public abstract class DisputeMessage implements MailboxMessage { + private final int networkId = Version.NETWORK_ID; + @Override public int networkId() { - return Version.NETWORK_ID; + return networkId; } } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/availability/messages/OfferMessage.java b/core/src/main/java/io/bitsquare/trade/protocol/availability/messages/OfferMessage.java index 3dc7afbcab..1e03ca7cd9 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/availability/messages/OfferMessage.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/availability/messages/OfferMessage.java @@ -27,6 +27,7 @@ public abstract class OfferMessage implements MailMessage { // That object is sent over the wire, so we need to take care of version compatibility. private static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION; + private final int networkId = Version.NETWORK_ID; public final String offerId; protected OfferMessage(String offerId) { @@ -35,6 +36,6 @@ public abstract class OfferMessage implements MailMessage { @Override public int networkId() { - return Version.NETWORK_ID; + return networkId; } } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/TradeMessage.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/TradeMessage.java index 093b1be7e9..dff389c102 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/TradeMessage.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/TradeMessage.java @@ -27,6 +27,7 @@ public abstract class TradeMessage implements MailMessage { // That object is sent over the wire, so we need to take care of version compatibility. private static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION; + private final int networkId = Version.NETWORK_ID; public final String tradeId; @Override @@ -51,6 +52,6 @@ public abstract class TradeMessage implements MailMessage { @Override public int networkId() { - return Version.NETWORK_ID; + return networkId; } } diff --git a/gui/src/main/java/io/bitsquare/gui/main/MainViewModel.java b/gui/src/main/java/io/bitsquare/gui/main/MainViewModel.java index 33679a5224..2b8cdb5632 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/MainViewModel.java +++ b/gui/src/main/java/io/bitsquare/gui/main/MainViewModel.java @@ -29,7 +29,6 @@ import io.bitsquare.btc.AddressEntry; import io.bitsquare.btc.TradeWalletService; import io.bitsquare.btc.WalletService; import io.bitsquare.btc.listeners.BalanceListener; -import io.bitsquare.common.crypto.KeyRing; import io.bitsquare.gui.common.model.ViewModel; import io.bitsquare.gui.components.BalanceTextField; import io.bitsquare.gui.components.BalanceWithConfirmationTextField; @@ -126,9 +125,8 @@ class MainViewModel implements ViewModel { public MainViewModel(WalletService walletService, TradeWalletService tradeWalletService, ArbitratorManager arbitratorManager, P2PService p2PService, TradeManager tradeManager, OpenOfferManager openOfferManager, DisputeManager disputeManager, Preferences preferences, - KeyRing keyRing, User user, - AlertManager alertManager, - WalletPasswordPopup walletPasswordPopup, BSFormatter formatter) { + User user, AlertManager alertManager, WalletPasswordPopup walletPasswordPopup, + BSFormatter formatter) { this.user = user; log.debug("in"); this.walletService = walletService; diff --git a/gui/src/main/java/io/bitsquare/gui/main/settings/network/NetworkSettingsView.java b/gui/src/main/java/io/bitsquare/gui/main/settings/network/NetworkSettingsView.java index c2d800b95a..b3bc4dab70 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/settings/network/NetworkSettingsView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/settings/network/NetworkSettingsView.java @@ -29,7 +29,7 @@ import io.bitsquare.gui.util.BSFormatter; import io.bitsquare.p2p.Address; import io.bitsquare.p2p.P2PService; import io.bitsquare.p2p.P2PServiceListener; -import io.bitsquare.p2p.network.TorNetworkNode; +import io.bitsquare.p2p.network.LocalhostNetworkNode; import io.bitsquare.p2p.seed.SeedNodesRepository; import io.bitsquare.user.Preferences; import javafx.beans.value.ChangeListener; @@ -68,13 +68,12 @@ public class NetworkSettingsView extends ActivatableViewAndModel decryptedMailListeners = new CopyOnWriteArraySet<>(); private final CopyOnWriteArraySet decryptedMailboxListeners = new CopyOnWriteArraySet<>(); private final CopyOnWriteArraySet p2pServiceListeners = new CopyOnWriteArraySet<>(); - private final Map mailboxMap = new ConcurrentHashMap<>(); + private final Map mailboxMap = new HashMap<>(); private volatile boolean shutDownInProgress; private Address connectedSeedNode; private final Set
authenticatedPeerAddresses = new HashSet<>(); @@ -91,6 +90,7 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis @Named(ProgramArguments.PORT_KEY) int port, @Named(ProgramArguments.TOR_DIR) File torDir, @Named(ProgramArguments.USE_LOCALHOST) boolean useLocalhost, + @Named(ProgramArguments.NETWORK_ID) int networkId, @Nullable EncryptionService encryptionService, KeyRing keyRing, @Named("storage.dir") File storageDir) { @@ -103,20 +103,14 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis this.keyRing = keyRing; this.storageDir = storageDir; - init(); + init(networkId); } - private void init() { + private void init(int networkId) { Log.traceCall(); // network - Set
seedNodeAddresses; - if (useLocalhost) { - networkNode = new LocalhostNetworkNode(port); - seedNodeAddresses = seedNodesRepository.getLocalhostSeedNodeAddresses(); - } else { - networkNode = new TorNetworkNode(port, torDir); - seedNodeAddresses = seedNodesRepository.getTorSeedNodeAddresses(); - } + networkNode = useLocalhost ? new LocalhostNetworkNode(port) : new TorNetworkNode(port, torDir); + Set
seedNodeAddresses = seedNodesRepository.geSeedNodeAddresses(useLocalhost, networkId); // peer group peerGroup = new PeerGroup(networkNode, seedNodeAddresses); @@ -564,13 +558,19 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis Log.traceCall(); checkAuthentication(); - ProtectedMailboxData mailboxData = mailboxMap.get(decryptedMsgWithPubKey); - if (mailboxData != null && mailboxData.expirablePayload instanceof ExpirableMailboxPayload) { - checkArgument(mailboxData.receiversPubKey.equals(keyRing.getSignatureKeyPair().getPublic()), - "mailboxData.receiversPubKey is not matching with our key. That must not happen."); - removeMailboxData((ExpirableMailboxPayload) mailboxData.expirablePayload, mailboxData.receiversPubKey); - mailboxMap.remove(decryptedMsgWithPubKey); - log.trace("Removed successfully protectedExpirableData."); + if (mailboxMap.containsKey(decryptedMsgWithPubKey)) { + ProtectedMailboxData mailboxData = mailboxMap.get(decryptedMsgWithPubKey); + if (mailboxData != null && mailboxData.expirablePayload instanceof ExpirableMailboxPayload) { + checkArgument(mailboxData.receiversPubKey.equals(keyRing.getSignatureKeyPair().getPublic()), + "mailboxData.receiversPubKey is not matching with our key. That must not happen."); + removeMailboxData((ExpirableMailboxPayload) mailboxData.expirablePayload, mailboxData.receiversPubKey); + mailboxMap.remove(decryptedMsgWithPubKey); + log.trace("Removed successfully protectedExpirableData."); + + } + } else { + log.warn("decryptedMsgWithPubKey not found in mailboxMap. That should never happen." + + "\ndecryptedMsgWithPubKey={}\nmailboxMap={}", decryptedMsgWithPubKey, mailboxMap); } } diff --git a/network/src/main/java/io/bitsquare/p2p/messaging/DecryptedMsgWithPubKey.java b/network/src/main/java/io/bitsquare/p2p/messaging/DecryptedMsgWithPubKey.java index 217b9729d9..0859d4c701 100644 --- a/network/src/main/java/io/bitsquare/p2p/messaging/DecryptedMsgWithPubKey.java +++ b/network/src/main/java/io/bitsquare/p2p/messaging/DecryptedMsgWithPubKey.java @@ -26,6 +26,7 @@ public final class DecryptedMsgWithPubKey implements MailMessage { // That object is sent over the wire, so we need to take care of version compatibility. private static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION; + private final int networkId = Version.NETWORK_ID; public final Message message; public final PublicKey signaturePubKey; @@ -36,7 +37,7 @@ public final class DecryptedMsgWithPubKey implements MailMessage { @Override public int networkId() { - return Version.NETWORK_ID; + return networkId; } @Override diff --git a/network/src/main/java/io/bitsquare/p2p/network/Connection.java b/network/src/main/java/io/bitsquare/p2p/network/Connection.java index f1586b5663..9b8bcf1a24 100644 --- a/network/src/main/java/io/bitsquare/p2p/network/Connection.java +++ b/network/src/main/java/io/bitsquare/p2p/network/Connection.java @@ -35,7 +35,6 @@ public class Connection implements MessageListener { private static final int SOCKET_TIMEOUT = 30 * 60 * 1000; // 30 min. private InputHandler inputHandler; private volatile boolean isAuthenticated; - private String connectionId; public static int getMaxMsgSize() { return MAX_MSG_SIZE; @@ -48,7 +47,7 @@ public class Connection implements MessageListener { private final String portInfo; private final String uid; private final ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); - public final String objectId = super.toString().split("@")[1]; + public final String objectId; // set in init private ObjectOutputStream objectOutputStream; @@ -76,6 +75,8 @@ public class Connection implements MessageListener { this.messageListener = messageListener; this.connectionListener = connectionListener; + objectId = super.toString().split("@")[1]; + Log.traceCall(); uid = UUID.randomUUID().toString(); if (socket.getLocalPort() == 0) @@ -335,10 +336,6 @@ public class Connection implements MessageListener { '}'; } - public String getConnectionId() { - return connectionId; - } - /////////////////////////////////////////////////////////////////////////////////////////// // SharedSpace @@ -379,12 +376,23 @@ public class Connection implements MessageListener { public void reportIllegalRequest(IllegalRequest illegalRequest) { Log.traceCall(); log.warn("We got reported an illegal request " + illegalRequest); - int prevCounter = illegalRequests.get(illegalRequest); - if (prevCounter > illegalRequest.maxTolerance) { - log.warn("We close connection as we received too many illegal requests.\n" + illegalRequests.toString()); - connection.shutDown(false); + int violations; + if (illegalRequests.contains(illegalRequest)) + violations = illegalRequests.get(illegalRequest); + else + violations = 0; + + violations++; + illegalRequests.put(illegalRequest, violations); + + if (violations >= illegalRequest.maxTolerance) { + log.warn("We close connection as we received too many invalid requests.\n" + + "violations={}\n" + + "illegalRequest={}\n" + + "illegalRequests={}", violations, illegalRequest, illegalRequests.toString()); + shutDown(false); } else { - illegalRequests.put(illegalRequest, ++prevCounter); + illegalRequests.put(illegalRequest, ++violations); } } @@ -406,15 +414,15 @@ public class Connection implements MessageListener { e.printStackTrace(); } - if (!stopped) { - stopped = true; - connection.shutDown(false); - } + shutDown(false); } public void shutDown(boolean sendCloseConnectionMessage) { Log.traceCall(); - connection.shutDown(sendCloseConnectionMessage); + if (!stopped) { + stopped = true; + connection.shutDown(sendCloseConnectionMessage); + } } @@ -422,8 +430,8 @@ public class Connection implements MessageListener { return socket; } - public String getConnectionId() { - return connection.getConnectionId(); + public String getConnectionInfo() { + return connection.toString(); } public void stop() { @@ -483,9 +491,9 @@ public class Connection implements MessageListener { Thread.currentThread().setName("InputHandler-" + portInfo); while (!stopped && !Thread.currentThread().isInterrupted()) { try { - log.trace("InputHandler waiting for incoming messages connection=" + sharedSpace.getConnectionId()); + log.trace("InputHandler waiting for incoming messages connection=" + sharedSpace.getConnectionInfo()); Object rawInputObject = objectInputStream.readObject(); - log.info("New data arrived at inputHandler of connection=" + sharedSpace.getConnectionId() + log.info("New data arrived at inputHandler of connection=" + sharedSpace.getConnectionInfo() + " rawInputObject " + rawInputObject); int size = ByteArrayUtils.objectToByteArray(rawInputObject).length; diff --git a/network/src/main/java/io/bitsquare/p2p/network/IllegalRequest.java b/network/src/main/java/io/bitsquare/p2p/network/IllegalRequest.java index dc0fb84c5e..f5637c90fb 100644 --- a/network/src/main/java/io/bitsquare/p2p/network/IllegalRequest.java +++ b/network/src/main/java/io/bitsquare/p2p/network/IllegalRequest.java @@ -1,10 +1,11 @@ package io.bitsquare.p2p.network; public enum IllegalRequest { + // TODO check for needed allowed tolerance MaxSizeExceeded(1), - NotAuthenticated(2), - InvalidDataType(2), - WrongNetworkId(2); + NotAuthenticated(1), + InvalidDataType(1), + WrongNetworkId(1); public final int maxTolerance; diff --git a/network/src/main/java/io/bitsquare/p2p/network/messages/CloseConnectionMessage.java b/network/src/main/java/io/bitsquare/p2p/network/messages/CloseConnectionMessage.java index 01ed87b87a..63332ac408 100644 --- a/network/src/main/java/io/bitsquare/p2p/network/messages/CloseConnectionMessage.java +++ b/network/src/main/java/io/bitsquare/p2p/network/messages/CloseConnectionMessage.java @@ -7,8 +7,10 @@ public final class CloseConnectionMessage implements Message { // That object is sent over the wire, so we need to take care of version compatibility. private static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION; + private final int networkId = Version.NETWORK_ID; + @Override public int networkId() { - return Version.NETWORK_ID; + return networkId; } } diff --git a/network/src/main/java/io/bitsquare/p2p/peers/messages/auth/AuthenticationMessage.java b/network/src/main/java/io/bitsquare/p2p/peers/messages/auth/AuthenticationMessage.java index 08875eaed8..2fe9c5ba5b 100644 --- a/network/src/main/java/io/bitsquare/p2p/peers/messages/auth/AuthenticationMessage.java +++ b/network/src/main/java/io/bitsquare/p2p/peers/messages/auth/AuthenticationMessage.java @@ -4,8 +4,10 @@ import io.bitsquare.app.Version; import io.bitsquare.p2p.Message; public abstract class AuthenticationMessage implements Message { + private final int networkId = Version.NETWORK_ID; + @Override public int networkId() { - return Version.NETWORK_ID; + return networkId; } } diff --git a/network/src/main/java/io/bitsquare/p2p/peers/messages/maintenance/MaintenanceMessage.java b/network/src/main/java/io/bitsquare/p2p/peers/messages/maintenance/MaintenanceMessage.java index 4aa975e82d..7265f0072f 100644 --- a/network/src/main/java/io/bitsquare/p2p/peers/messages/maintenance/MaintenanceMessage.java +++ b/network/src/main/java/io/bitsquare/p2p/peers/messages/maintenance/MaintenanceMessage.java @@ -4,8 +4,10 @@ import io.bitsquare.app.Version; import io.bitsquare.p2p.Message; public abstract class MaintenanceMessage implements Message { + private final int networkId = Version.NETWORK_ID; + @Override public int networkId() { - return Version.NETWORK_ID; + return networkId; } } diff --git a/network/src/main/java/io/bitsquare/p2p/seed/SeedNode.java b/network/src/main/java/io/bitsquare/p2p/seed/SeedNode.java index 0474cf1a63..da5c8b3a57 100644 --- a/network/src/main/java/io/bitsquare/p2p/seed/SeedNode.java +++ b/network/src/main/java/io/bitsquare/p2p/seed/SeedNode.java @@ -14,6 +14,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Arrays; import java.util.HashSet; import java.util.List; @@ -29,8 +31,10 @@ public class SeedNode { private Set
seedNodes; private P2PService p2PService; private boolean stopped; + private final String defaultUserDataDir; - public SeedNode() { + public SeedNode(String defaultUserDataDir) { + this.defaultUserDataDir = defaultUserDataDir; Log.traceCall(); } @@ -39,59 +43,73 @@ public class SeedNode { // API /////////////////////////////////////////////////////////////////////////////////////////// - // args: myAddress (incl. port) BitcoinNetworkId maxConnections useLocalhost seedNodes (separated with |) + // args: myAddress (incl. port) bitcoinNetworkId maxConnections useLocalhost seedNodes (separated with |) // 2. and 3. args are optional // eg. lmvdenjkyvx2ovga.onion:8001 0 20 false eo5ay2lyzrfvx2nr.onion:8002|si3uu56adkyqkldl.onion:8003 // or when using localhost: localhost:8001 2 20 true localhost:8002|localhost:8003 // BitcoinNetworkId: The id for the bitcoin network (Mainnet = 0, TestNet = 1, Regtest = 2) public void processArgs(String[] args) { Log.traceCall(); - if (args.length > 0) { - String arg0 = args[0]; - checkArgument(arg0.contains(":") && arg0.split(":").length == 2 && arg0.split(":")[1].length() == 4, "Wrong program argument"); - mySeedNodeAddress = new Address(arg0); - if (args.length > 1) { - String arg1 = args[1]; - int networkId = Integer.parseInt(arg1); - checkArgument(networkId > -1 && networkId < 3, "networkId out of scope (Mainnet = 0, TestNet = 1, Regtest = 2)"); - Version.NETWORK_ID = networkId; - if (args.length > 2) { - String arg2 = args[2]; - int maxConnections = Integer.parseInt(arg2); - checkArgument(maxConnections < 1000, "maxConnections seems to be a bit too high..."); - PeerGroup.setMaxConnections(maxConnections); - } else { - // we keep default a higher connection size for seed nodes - PeerGroup.setMaxConnections(50); - } - if (args.length > 3) { - String arg3 = args[3]; - checkArgument(arg3.equals("true") || arg3.equals("false")); - useLocalhost = ("true").equals(arg3); - } - if (args.length > 4) { - String arg4 = args[4]; - checkArgument(arg4.contains(":") && arg4.split(":").length > 1 && arg4.split(":")[1].length() > 3, "Wrong program argument"); - List list = Arrays.asList(arg4.split("|")); - seedNodes = new HashSet<>(); - list.forEach(e -> { - checkArgument(e.contains(":") && e.split(":").length == 2 && e.split(":")[1].length() == 4, "Wrong program argument"); - seedNodes.add(new Address(e)); - }); - seedNodes.remove(mySeedNodeAddress); - } else if (args.length > 5) { - log.error("Too many program arguments." + - "\nProgram arguments: myAddress (incl. port) BitcoinNetworkId maxConnections useLocalhost seedNodes (separated with |)"); + try { + if (args.length > 0) { + String arg0 = args[0]; + checkArgument(arg0.contains(":") && arg0.split(":").length == 2 && arg0.split(":")[1].length() > 3, "Wrong program argument: " + arg0); + mySeedNodeAddress = new Address(arg0); + if (args.length > 1) { + String arg1 = args[1]; + int networkId = Integer.parseInt(arg1); + checkArgument(networkId > -1 && networkId < 3, + "networkId out of scope (Mainnet = 0, TestNet = 1, Regtest = 2)"); + Version.NETWORK_ID = networkId; + if (args.length > 2) { + String arg2 = args[2]; + int maxConnections = Integer.parseInt(arg2); + checkArgument(maxConnections < 1000, "maxConnections seems to be a bit too high..."); + PeerGroup.setMaxConnections(maxConnections); + } else { + // we keep default a higher connection size for seed nodes + PeerGroup.setMaxConnections(50); + } + if (args.length > 3) { + String arg3 = args[3]; + checkArgument(arg3.equals("true") || arg3.equals("false")); + useLocalhost = ("true").equals(arg3); + } + if (args.length > 4) { + String arg4 = args[4]; + checkArgument(arg4.contains(":") && arg4.split(":").length > 1 && arg4.split(":")[1].length() > 3, + "Wrong program argument"); + List list = Arrays.asList(arg4.split("|")); + seedNodes = new HashSet<>(); + list.forEach(e -> { + checkArgument(e.contains(":") && e.split(":").length == 2 && e.split(":")[1].length() == 4, + "Wrong program argument"); + seedNodes.add(new Address(e)); + }); + seedNodes.remove(mySeedNodeAddress); + } else if (args.length > 5) { + log.error("Too many program arguments." + + "\nProgram arguments: myAddress (incl. port) bitcoinNetworkId " + + "maxConnections useLocalhost seedNodes (separated with |)"); + } } } + } catch (Throwable t) { + shutDown(); } } public void createAndStartP2PService() { - createAndStartP2PService(null, null, mySeedNodeAddress, useLocalhost, seedNodes, null); + createAndStartP2PService(null, null, mySeedNodeAddress, useLocalhost, Version.NETWORK_ID, seedNodes, null); } - public void createAndStartP2PService(EncryptionService encryptionService, KeyRing keyRing, Address mySeedNodeAddress, boolean useLocalhost, @Nullable Set
seedNodes, @Nullable P2PServiceListener listener) { + public void createAndStartP2PService(EncryptionService encryptionService, + KeyRing keyRing, + Address mySeedNodeAddress, + boolean useLocalhost, + int networkId, + @Nullable Set
seedNodes, + @Nullable P2PServiceListener listener) { Log.traceCall(); SeedNodesRepository seedNodesRepository = new SeedNodesRepository(); if (seedNodes != null && !seedNodes.isEmpty()) { @@ -100,8 +118,18 @@ public class SeedNode { else seedNodesRepository.setTorSeedNodeAddresses(seedNodes); } + Path seedNodePath = Paths.get(defaultUserDataDir, + "Bitsquare_seed_node_" + String.valueOf(mySeedNodeAddress.getFullAddress().replace(":", "_"))); + File storageDir = Paths.get(seedNodePath.toString(), "db").toFile(); + File torDir = Paths.get(seedNodePath.toString(), "tor").toFile(); - p2PService = new P2PService(seedNodesRepository, mySeedNodeAddress.port, new File("bitsquare_seed_node_" + mySeedNodeAddress.port), useLocalhost, encryptionService, keyRing, new File("dummy")); + if (storageDir.mkdirs()) + log.info("Created storageDir at " + storageDir.getAbsolutePath()); + if (torDir.mkdirs()) + log.info("Created torDir at " + torDir.getAbsolutePath()); + + p2PService = new P2PService(seedNodesRepository, mySeedNodeAddress.port, torDir, + useLocalhost, networkId, encryptionService, keyRing, storageDir); p2PService.removeMySeedNodeAddressFromList(mySeedNodeAddress); p2PService.start(listener); } diff --git a/network/src/main/java/io/bitsquare/p2p/seed/SeedNodesRepository.java b/network/src/main/java/io/bitsquare/p2p/seed/SeedNodesRepository.java index 4493c77736..35574f7b1d 100644 --- a/network/src/main/java/io/bitsquare/p2p/seed/SeedNodesRepository.java +++ b/network/src/main/java/io/bitsquare/p2p/seed/SeedNodesRepository.java @@ -4,33 +4,53 @@ import com.google.common.collect.Sets; import io.bitsquare.p2p.Address; import java.util.Set; +import java.util.stream.Collectors; public class SeedNodesRepository { - + // mainnet use port 8000 + // testnet use port 8001 + // regtest use port 8002 private Set
torSeedNodeAddresses = Sets.newHashSet( + // mainnet + new Address("lmvdenjkyvx2ovga.onion:8000"), + new Address("eo5ay2lyzrfvx2nr.onion:8000"), + new Address("si3uu56adkyqkldl.onion:8000"), + + // testnet new Address("lmvdenjkyvx2ovga.onion:8001"), + new Address("eo5ay2lyzrfvx2nr.onion:8001"), + new Address("si3uu56adkyqkldl.onion:8001"), + + // regtest + new Address("lmvdenjkyvx2ovga.onion:8002"), new Address("eo5ay2lyzrfvx2nr.onion:8002"), - new Address("si3uu56adkyqkldl.onion:8003") + new Address("si3uu56adkyqkldl.onion:8002") ); private Set
localhostSeedNodeAddresses = Sets.newHashSet( - new Address("localhost:8001"), - new Address("localhost:8002"), - new Address("localhost:8003") + // mainnet + new Address("localhost:2000"), + new Address("localhost:3000"), + new Address("localhost:4000"), + + // testnet + new Address("localhost:2001"), + new Address("localhost:3001"), + new Address("localhost:4001"), + + // regtest + new Address("localhost:2002"), + new Address("localhost:3002"), + new Address("localhost:4002") ); - public Set
getTorSeedNodeAddresses() { - return torSeedNodeAddresses; - } - - public Set
geSeedNodeAddresses(boolean useLocalhost) { - return useLocalhost ? localhostSeedNodeAddresses : torSeedNodeAddresses; - } - - public Set
getLocalhostSeedNodeAddresses() { - return localhostSeedNodeAddresses; + public Set
geSeedNodeAddresses(boolean useLocalhost, int networkId) { + String networkIdAsString = String.valueOf(networkId); + Set
addresses = useLocalhost ? localhostSeedNodeAddresses : torSeedNodeAddresses; + return addresses.stream() + .filter(e -> String.valueOf(e.port).endsWith(networkIdAsString)).collect(Collectors.toSet()); } public void setTorSeedNodeAddresses(Set
torSeedNodeAddresses) { diff --git a/network/src/main/java/io/bitsquare/p2p/storage/ProtectedExpirableDataStorage.java b/network/src/main/java/io/bitsquare/p2p/storage/ProtectedExpirableDataStorage.java index a7023519ae..525e513501 100644 --- a/network/src/main/java/io/bitsquare/p2p/storage/ProtectedExpirableDataStorage.java +++ b/network/src/main/java/io/bitsquare/p2p/storage/ProtectedExpirableDataStorage.java @@ -28,10 +28,10 @@ import java.io.File; import java.math.BigInteger; import java.security.KeyPair; import java.security.PublicKey; +import java.util.HashMap; import java.util.Map; import java.util.Timer; import java.util.TimerTask; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; // Run in UserThread @@ -42,10 +42,10 @@ public class ProtectedExpirableDataStorage implements MessageListener { public static int CHECK_TTL_INTERVAL = 10 * 60 * 1000; private final PeerGroup peerGroup; - private final Map map = new ConcurrentHashMap<>(); + private final Map map = new HashMap<>(); private final CopyOnWriteArraySet hashMapChangedListeners = new CopyOnWriteArraySet<>(); - private ConcurrentHashMap sequenceNumberMap = new ConcurrentHashMap<>(); - private final Storage storage; + private HashMap sequenceNumberMap = new HashMap<>(); + private final Storage storage; private final Timer timer = new Timer(); private volatile boolean shutDownInProgress; @@ -65,7 +65,7 @@ public class ProtectedExpirableDataStorage implements MessageListener { private void init() { Log.traceCall(); - ConcurrentHashMap persisted = storage.initAndGetPersisted(sequenceNumberMap, "sequenceNumberMap"); + HashMap persisted = storage.initAndGetPersisted(sequenceNumberMap, "sequenceNumberMap"); if (persisted != null) { sequenceNumberMap = persisted; } diff --git a/network/src/main/java/io/bitsquare/p2p/storage/messages/DataBroadcastMessage.java b/network/src/main/java/io/bitsquare/p2p/storage/messages/DataBroadcastMessage.java index 9bd121b1b8..6311364c8c 100644 --- a/network/src/main/java/io/bitsquare/p2p/storage/messages/DataBroadcastMessage.java +++ b/network/src/main/java/io/bitsquare/p2p/storage/messages/DataBroadcastMessage.java @@ -4,8 +4,10 @@ import io.bitsquare.app.Version; import io.bitsquare.p2p.Message; public abstract class DataBroadcastMessage implements Message { + private final int networkId = Version.NETWORK_ID; + @Override public int networkId() { - return Version.NETWORK_ID; + return networkId; } } \ No newline at end of file diff --git a/network/src/main/java/io/bitsquare/p2p/storage/messages/GetDataRequest.java b/network/src/main/java/io/bitsquare/p2p/storage/messages/GetDataRequest.java index 96b74740e9..c84521a9ef 100644 --- a/network/src/main/java/io/bitsquare/p2p/storage/messages/GetDataRequest.java +++ b/network/src/main/java/io/bitsquare/p2p/storage/messages/GetDataRequest.java @@ -7,11 +7,13 @@ public final class GetDataRequest implements Message { // That object is sent over the wire, so we need to take care of version compatibility. private static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION; + private final int networkId = Version.NETWORK_ID; + public GetDataRequest() { } @Override public int networkId() { - return Version.NETWORK_ID; + return networkId; } } diff --git a/network/src/main/java/io/bitsquare/p2p/storage/messages/GetDataResponse.java b/network/src/main/java/io/bitsquare/p2p/storage/messages/GetDataResponse.java index b9e151e9f4..dfe67d44c2 100644 --- a/network/src/main/java/io/bitsquare/p2p/storage/messages/GetDataResponse.java +++ b/network/src/main/java/io/bitsquare/p2p/storage/messages/GetDataResponse.java @@ -9,7 +9,8 @@ import java.util.HashSet; public final class GetDataResponse implements Message { // That object is sent over the wire, so we need to take care of version compatibility. private static final long serialVersionUID = Version.NETWORK_PROTOCOL_VERSION; - + private final int networkId = Version.NETWORK_ID; + public final HashSet set; public GetDataResponse(HashSet set) { @@ -18,7 +19,7 @@ public final class GetDataResponse implements Message { @Override public int networkId() { - return Version.NETWORK_ID; + return networkId; } @Override diff --git a/network/src/test/java/io/bitsquare/crypto/EncryptionServiceTests.java b/network/src/test/java/io/bitsquare/crypto/EncryptionServiceTests.java index 229f6bd744..92340a3659 100644 --- a/network/src/test/java/io/bitsquare/crypto/EncryptionServiceTests.java +++ b/network/src/test/java/io/bitsquare/crypto/EncryptionServiceTests.java @@ -84,6 +84,7 @@ public class EncryptionServiceTests { class TestMessage implements MailboxMessage { public String data = "test"; + private final int networkId = Version.NETWORK_ID; public TestMessage(String data) { this.data = data; @@ -96,6 +97,6 @@ class TestMessage implements MailboxMessage { @Override public int networkId() { - return Version.NETWORK_ID; + return networkId; } } diff --git a/network/src/test/java/io/bitsquare/p2p/TestUtils.java b/network/src/test/java/io/bitsquare/p2p/TestUtils.java index 832ee2f65c..c353e25d15 100644 --- a/network/src/test/java/io/bitsquare/p2p/TestUtils.java +++ b/network/src/test/java/io/bitsquare/p2p/TestUtils.java @@ -70,44 +70,47 @@ public class TestUtils { seedNodes.add(new Address("localhost:8002")); seedNodes.add(new Address("localhost:8003")); sleepTime = 100; - seedNode = new SeedNode(); + seedNode = new SeedNode("test_dummy_dir"); } else { seedNodes.add(new Address("3omjuxn7z73pxoee.onion:8001")); seedNodes.add(new Address("j24fxqyghjetgpdx.onion:8002")); seedNodes.add(new Address("45367tl6unwec6kw.onion:8003")); sleepTime = 10000; - seedNode = new SeedNode(); + seedNode = new SeedNode("test_dummy_dir"); } CountDownLatch latch = new CountDownLatch(1); - seedNode.createAndStartP2PService(encryptionService, keyRing, new Address("localhost", port), useLocalhost, seedNodes, new P2PServiceListener() { - @Override - public void onRequestingDataCompleted() { - } + seedNode.createAndStartP2PService(encryptionService, keyRing, new Address("localhost", port), useLocalhost, 2, + seedNodes, new P2PServiceListener() { + @Override + public void onRequestingDataCompleted() { + } - @Override - public void onFirstPeerAuthenticated() { - } + @Override + public void onFirstPeerAuthenticated() { + } - @Override - public void onTorNodeReady() { - } + @Override + public void onTorNodeReady() { + } - @Override - public void onHiddenServicePublished() { - latch.countDown(); - } + @Override + public void onHiddenServicePublished() { + latch.countDown(); + } - @Override - public void onSetupFailed(Throwable throwable) { - } - }); + @Override + public void onSetupFailed(Throwable throwable) { + } + }); latch.await(); Thread.sleep(sleepTime); return seedNode; } - public static P2PService getAndAuthenticateP2PService(int port, EncryptionService encryptionService, KeyRing keyRing, boolean useLocalhost, Set
seedNodes) throws InterruptedException { + public static P2PService getAndAuthenticateP2PService(int port, EncryptionService encryptionService, KeyRing keyRing, + boolean useLocalhost, Set
seedNodes) + throws InterruptedException { CountDownLatch latch = new CountDownLatch(1); SeedNodesRepository seedNodesRepository = new SeedNodesRepository(); if (seedNodes != null && !seedNodes.isEmpty()) { @@ -117,7 +120,8 @@ public class TestUtils { seedNodesRepository.setTorSeedNodeAddresses(seedNodes); } - P2PService p2PService = new P2PService(seedNodesRepository, port, new File("seed_node_" + port), useLocalhost, encryptionService, keyRing, new File("dummy")); + P2PService p2PService = new P2PService(seedNodesRepository, port, new File("seed_node_" + port), useLocalhost, 2, + encryptionService, keyRing, new File("dummy")); p2PService.start(new P2PServiceListener() { @Override public void onRequestingDataCompleted() { diff --git a/network/src/test/java/io/bitsquare/p2p/mocks/MockMailboxMessage.java b/network/src/test/java/io/bitsquare/p2p/mocks/MockMailboxMessage.java index 5b8d590ac1..2e3847731c 100644 --- a/network/src/test/java/io/bitsquare/p2p/mocks/MockMailboxMessage.java +++ b/network/src/test/java/io/bitsquare/p2p/mocks/MockMailboxMessage.java @@ -6,6 +6,7 @@ import io.bitsquare.p2p.messaging.MailboxMessage; import io.bitsquare.p2p.storage.data.ExpirablePayload; public class MockMailboxMessage implements MailboxMessage, ExpirablePayload { + private final int networkId = Version.NETWORK_ID; public String msg; public Address senderAddress; public long ttl; @@ -17,7 +18,7 @@ public class MockMailboxMessage implements MailboxMessage, ExpirablePayload { @Override public int networkId() { - return Version.NETWORK_ID; + return networkId; } @Override diff --git a/network/src/test/java/io/bitsquare/p2p/mocks/MockMessage.java b/network/src/test/java/io/bitsquare/p2p/mocks/MockMessage.java index d299a447bc..d92d84eea3 100644 --- a/network/src/test/java/io/bitsquare/p2p/mocks/MockMessage.java +++ b/network/src/test/java/io/bitsquare/p2p/mocks/MockMessage.java @@ -7,6 +7,7 @@ import io.bitsquare.p2p.storage.data.ExpirablePayload; public class MockMessage implements Message, ExpirablePayload { public String msg; public long ttl; + private final int networkId = Version.NETWORK_ID; public MockMessage(String msg) { this.msg = msg; @@ -14,7 +15,7 @@ public class MockMessage implements Message, ExpirablePayload { @Override public int networkId() { - return Version.NETWORK_ID; + return networkId; } @Override diff --git a/network/src/test/java/io/bitsquare/p2p/routing/PeerGroupTest.java b/network/src/test/java/io/bitsquare/p2p/routing/PeerGroupTest.java index 1e99bb7000..435cfb007f 100644 --- a/network/src/test/java/io/bitsquare/p2p/routing/PeerGroupTest.java +++ b/network/src/test/java/io/bitsquare/p2p/routing/PeerGroupTest.java @@ -81,33 +81,34 @@ public class PeerGroupTest { seedNodes = new HashSet<>(); Address address = new Address("localhost:8001"); seedNodes.add(address); - seedNode1 = new SeedNode(); + seedNode1 = new SeedNode("test_dummy_dir"); latch = new CountDownLatch(2); - seedNode1.createAndStartP2PService(null, null, address, useLocalhost, seedNodes, new P2PServiceListener() { - @Override - public void onRequestingDataCompleted() { - latch.countDown(); - } + seedNode1.createAndStartP2PService(null, null, address, useLocalhost, 2, + seedNodes, new P2PServiceListener() { + @Override + public void onRequestingDataCompleted() { + latch.countDown(); + } - @Override - public void onTorNodeReady() { + @Override + public void onTorNodeReady() { - } + } - @Override - public void onFirstPeerAuthenticated() { - } + @Override + public void onFirstPeerAuthenticated() { + } - @Override - public void onHiddenServicePublished() { - latch.countDown(); - } + @Override + public void onHiddenServicePublished() { + latch.countDown(); + } - @Override - public void onSetupFailed(Throwable throwable) { + @Override + public void onSetupFailed(Throwable throwable) { - } - }); + } + }); P2PService p2PService1 = seedNode1.getP2PService(); latch.await(); Thread.sleep(500); @@ -126,8 +127,8 @@ public class PeerGroupTest { latch = new CountDownLatch(6); - seedNode1 = new SeedNode(); - seedNode1.createAndStartP2PService(null, null, address1, useLocalhost, seedNodes, new P2PServiceListener() { + seedNode1 = new SeedNode("test_dummy_dir"); + seedNode1.createAndStartP2PService(null, null, address1, useLocalhost, 2, seedNodes, new P2PServiceListener() { @Override public void onRequestingDataCompleted() { latch.countDown(); @@ -157,8 +158,8 @@ public class PeerGroupTest { Thread.sleep(500); - seedNode2 = new SeedNode(); - seedNode2.createAndStartP2PService(null, null, address2, useLocalhost, seedNodes, new P2PServiceListener() { + seedNode2 = new SeedNode("test_dummy_dir"); + seedNode2.createAndStartP2PService(null, null, address2, useLocalhost, 2, seedNodes, new P2PServiceListener() { @Override public void onRequestingDataCompleted() { latch.countDown(); @@ -382,10 +383,10 @@ public class PeerGroupTest { } private SeedNode getAndStartSeedNode(int port) throws InterruptedException { - SeedNode seedNode = new SeedNode(); + SeedNode seedNode = new SeedNode("test_dummy_dir"); latch = new CountDownLatch(1); - seedNode.createAndStartP2PService(null, null, new Address("localhost", port), useLocalhost, seedNodes, new P2PServiceListener() { + seedNode.createAndStartP2PService(null, null, new Address("localhost", port), useLocalhost, 2, seedNodes, new P2PServiceListener() { @Override public void onRequestingDataCompleted() { latch.countDown(); diff --git a/seednode/src/main/java/io/bitsquare/p2p/seed/SeedNodeMain.java b/seednode/src/main/java/io/bitsquare/p2p/seed/SeedNodeMain.java index 24ffb9c90f..b5a3bd744d 100644 --- a/seednode/src/main/java/io/bitsquare/p2p/seed/SeedNodeMain.java +++ b/seednode/src/main/java/io/bitsquare/p2p/seed/SeedNodeMain.java @@ -1,6 +1,7 @@ package io.bitsquare.p2p.seed; import com.google.common.util.concurrent.ThreadFactoryBuilder; +import io.bitsquare.app.BitsquareEnvironment; import io.bitsquare.app.Log; import io.bitsquare.common.UserThread; import org.bitcoinj.crypto.DRMWorkaround; @@ -47,7 +48,7 @@ public class SeedNodeMain { UserThread.setExecutor(Executors.newSingleThreadExecutor(threadFactory)); UserThread.execute(() -> { try { - seedNode = new SeedNode(); + seedNode = new SeedNode(BitsquareEnvironment.defaultUserDataDir()); seedNode.processArgs(args); seedNode.createAndStartP2PService(); } catch (Throwable t) {