From 82e766e6b1ae4d355c7996409d421d8aaf393d27 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 18 Nov 2015 13:46:47 +0100 Subject: [PATCH] fix mailbox msg remove bug, add setup for release version --- .../src/main/java/io/bitsquare/app/Log.java | 18 +- .../bitsquare/common/crypto/PubKeyRing.java | 4 +- .../io/bitsquare/storage/FileManager.java | 2 +- .../messages/DisputeMailMessage.java | 2 +- .../messages/DisputeResultMessage.java | 2 +- .../messages/OpenNewDisputeMessage.java | 2 +- .../messages/PeerOpenedDisputeMessage.java | 2 +- .../PeerPublishedPayoutTxMessage.java | 2 +- .../java/io/bitsquare/trade/TradeManager.java | 5 +- .../messages/OfferAvailabilityRequest.java | 2 +- .../messages/OfferAvailabilityResponse.java | 2 +- .../messages/DepositTxPublishedMessage.java | 2 +- .../messages/FiatTransferStartedMessage.java | 2 +- .../messages/FinalizePayoutTxRequest.java | 2 +- .../trade/messages/PayDepositRequest.java | 2 +- .../messages/PayoutTxFinalizedMessage.java | 2 +- .../messages/PublishDepositTxRequest.java | 2 +- .../java/io/bitsquare/app/BitsquareApp.java | 59 +++-- .../java/io/bitsquare/gui/SystemTray.java | 6 +- .../main/offer/takeoffer/TakeOfferView.java | 6 +- .../resources/i18n/displayStrings.properties | 2 +- gui/src/main/resources/logback.xml | 59 ++--- .../toronionproxy/OnionProxyManager.java | 2 +- .../io/bitsquare/p2p/network/NetworkNode.java | 16 +- .../p2p/peers/AuthenticationHandshake.java | 213 +++++++++--------- .../io/bitsquare/p2p/peers/PeerGroup.java | 105 ++++++--- .../messages/auth/AuthenticationMessage.java | 7 + .../messages/auth/AuthenticationRequest.java | 3 +- .../messages/auth/AuthenticationResponse.java | 3 +- .../messages/auth/GetPeersAuthRequest.java | 3 +- .../messages/auth/GetPeersAuthResponse.java | 3 +- .../java/io/bitsquare/p2p/seed/SeedNode.java | 20 +- .../crypto/EncryptionServiceTests.java | 2 +- .../test/java/io/bitsquare/p2p/TestUtils.java | 2 +- .../p2p/mocks/MockMailboxMessage.java | 2 +- .../io/bitsquare/p2p/mocks/MockMessage.java | 2 +- .../bitsquare/p2p/routing/PeerGroupTest.java | 8 +- .../io/bitsquare/p2p/seed/SeedNodeMain.java | 32 +-- 38 files changed, 333 insertions(+), 277 deletions(-) diff --git a/common/src/main/java/io/bitsquare/app/Log.java b/common/src/main/java/io/bitsquare/app/Log.java index a95ee9c77a..e2ef885561 100644 --- a/common/src/main/java/io/bitsquare/app/Log.java +++ b/common/src/main/java/io/bitsquare/app/Log.java @@ -17,6 +17,8 @@ package io.bitsquare.app; +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.encoder.PatternLayoutEncoder; import ch.qos.logback.core.rolling.FixedWindowRollingPolicy; @@ -26,8 +28,11 @@ import org.slf4j.LoggerFactory; public class Log { public static boolean PRINT_TRACE_METHOD = true; + private static SizeBasedTriggeringPolicy triggeringPolicy; + private static Logger logbackLogger; - public static void setup(String fileName) { + public static void setup(String fileName, boolean releaseVersion) { + Log.PRINT_TRACE_METHOD = !releaseVersion; LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); RollingFileAppender appender = new RollingFileAppender(); @@ -42,13 +47,13 @@ public class Log { rollingPolicy.setMaxIndex(10); rollingPolicy.start(); - SizeBasedTriggeringPolicy triggeringPolicy = new ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy(); - triggeringPolicy.setMaxFileSize("1MB"); + triggeringPolicy = new SizeBasedTriggeringPolicy(); + triggeringPolicy.setMaxFileSize(releaseVersion ? "1MB" : "50MB"); triggeringPolicy.start(); PatternLayoutEncoder encoder = new PatternLayoutEncoder(); encoder.setContext(loggerContext); - encoder.setPattern("%highlight(%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg %xEx%n)"); + encoder.setPattern("%highlight(%d{MMM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{15} - %msg %xEx%n)"); encoder.start(); appender.setEncoder(encoder); @@ -56,7 +61,8 @@ public class Log { appender.setTriggeringPolicy(triggeringPolicy); appender.start(); - ch.qos.logback.classic.Logger logbackLogger = loggerContext.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME); + logbackLogger = loggerContext.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME); + logbackLogger.setLevel(releaseVersion ? Level.INFO : Level.TRACE); logbackLogger.addAppender(appender); } @@ -77,4 +83,6 @@ public class Log { String className = stackTraceElement.getClassName(); LoggerFactory.getLogger(className).trace("Called: {} [{}]", methodName, message); } + + } diff --git a/common/src/main/java/io/bitsquare/common/crypto/PubKeyRing.java b/common/src/main/java/io/bitsquare/common/crypto/PubKeyRing.java index 40529b40cc..762674e3c0 100644 --- a/common/src/main/java/io/bitsquare/common/crypto/PubKeyRing.java +++ b/common/src/main/java/io/bitsquare/common/crypto/PubKeyRing.java @@ -99,8 +99,8 @@ public class PubKeyRing implements Serializable { @Override public String toString() { return "PubKeyRing{" + - "\n\nsignaturePubKey.hashCode()=\n" + signaturePubKey.hashCode() + - "\n\nencryptionPubKey.hashCode()=\n" + encryptionPubKey.hashCode() + + "signaturePubKey.hashCode()=\n" + signaturePubKey.hashCode() + + "encryptionPubKey.hashCode()=\n" + encryptionPubKey.hashCode() + '}'; } diff --git a/common/src/main/java/io/bitsquare/storage/FileManager.java b/common/src/main/java/io/bitsquare/storage/FileManager.java index 7d8c218945..e54b95e737 100644 --- a/common/src/main/java/io/bitsquare/storage/FileManager.java +++ b/common/src/main/java/io/bitsquare/storage/FileManager.java @@ -218,7 +218,7 @@ public class FileManager { private void saveNowInternal(T serializable) { long now = System.currentTimeMillis(); saveToFile(serializable, dir, storageFile); - UserThread.execute(() -> log.info("Save {} completed in {}msec", storageFile, System.currentTimeMillis() - now)); + UserThread.execute(() -> log.trace("Save {} completed in {}msec", storageFile, System.currentTimeMillis() - now)); } private synchronized void saveToFile(T serializable, File dir, File storageFile) { diff --git a/core/src/main/java/io/bitsquare/arbitration/messages/DisputeMailMessage.java b/core/src/main/java/io/bitsquare/arbitration/messages/DisputeMailMessage.java index b5bceee55a..f8cce03b36 100644 --- a/core/src/main/java/io/bitsquare/arbitration/messages/DisputeMailMessage.java +++ b/core/src/main/java/io/bitsquare/arbitration/messages/DisputeMailMessage.java @@ -32,7 +32,7 @@ import java.util.Arrays; import java.util.Date; import java.util.List; -public class DisputeMailMessage extends DisputeMessage { +public final class DisputeMailMessage extends DisputeMessage { // 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; transient private static final Logger log = LoggerFactory.getLogger(DisputeMailMessage.class); diff --git a/core/src/main/java/io/bitsquare/arbitration/messages/DisputeResultMessage.java b/core/src/main/java/io/bitsquare/arbitration/messages/DisputeResultMessage.java index 3fa07e141f..37bae161b3 100644 --- a/core/src/main/java/io/bitsquare/arbitration/messages/DisputeResultMessage.java +++ b/core/src/main/java/io/bitsquare/arbitration/messages/DisputeResultMessage.java @@ -21,7 +21,7 @@ import io.bitsquare.app.Version; import io.bitsquare.arbitration.DisputeResult; import io.bitsquare.p2p.Address; -public class DisputeResultMessage extends DisputeMessage { +public final class DisputeResultMessage extends DisputeMessage { // 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; diff --git a/core/src/main/java/io/bitsquare/arbitration/messages/OpenNewDisputeMessage.java b/core/src/main/java/io/bitsquare/arbitration/messages/OpenNewDisputeMessage.java index a354c59cd6..2f817e424a 100644 --- a/core/src/main/java/io/bitsquare/arbitration/messages/OpenNewDisputeMessage.java +++ b/core/src/main/java/io/bitsquare/arbitration/messages/OpenNewDisputeMessage.java @@ -21,7 +21,7 @@ import io.bitsquare.app.Version; import io.bitsquare.arbitration.Dispute; import io.bitsquare.p2p.Address; -public class OpenNewDisputeMessage extends DisputeMessage { +public final class OpenNewDisputeMessage extends DisputeMessage { // 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; diff --git a/core/src/main/java/io/bitsquare/arbitration/messages/PeerOpenedDisputeMessage.java b/core/src/main/java/io/bitsquare/arbitration/messages/PeerOpenedDisputeMessage.java index bbc527010d..d7ed2de8a6 100644 --- a/core/src/main/java/io/bitsquare/arbitration/messages/PeerOpenedDisputeMessage.java +++ b/core/src/main/java/io/bitsquare/arbitration/messages/PeerOpenedDisputeMessage.java @@ -21,7 +21,7 @@ import io.bitsquare.app.Version; import io.bitsquare.arbitration.Dispute; import io.bitsquare.p2p.Address; -public class PeerOpenedDisputeMessage extends DisputeMessage { +public final class PeerOpenedDisputeMessage extends DisputeMessage { // 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; public final Dispute dispute; diff --git a/core/src/main/java/io/bitsquare/arbitration/messages/PeerPublishedPayoutTxMessage.java b/core/src/main/java/io/bitsquare/arbitration/messages/PeerPublishedPayoutTxMessage.java index b09459543c..cbd5bb69ff 100644 --- a/core/src/main/java/io/bitsquare/arbitration/messages/PeerPublishedPayoutTxMessage.java +++ b/core/src/main/java/io/bitsquare/arbitration/messages/PeerPublishedPayoutTxMessage.java @@ -22,7 +22,7 @@ import io.bitsquare.p2p.Address; import java.util.Arrays; -public class PeerPublishedPayoutTxMessage extends DisputeMessage { +public final class PeerPublishedPayoutTxMessage extends DisputeMessage { // 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; diff --git a/core/src/main/java/io/bitsquare/trade/TradeManager.java b/core/src/main/java/io/bitsquare/trade/TradeManager.java index f564300cca..fd47717079 100644 --- a/core/src/main/java/io/bitsquare/trade/TradeManager.java +++ b/core/src/main/java/io/bitsquare/trade/TradeManager.java @@ -22,6 +22,7 @@ import io.bitsquare.arbitration.ArbitratorManager; import io.bitsquare.btc.AddressEntry; import io.bitsquare.btc.TradeWalletService; import io.bitsquare.btc.WalletService; +import io.bitsquare.common.UserThread; import io.bitsquare.common.crypto.KeyRing; import io.bitsquare.common.handlers.FaultHandler; import io.bitsquare.common.handlers.ResultHandler; @@ -62,6 +63,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Optional; +import java.util.concurrent.TimeUnit; import static io.bitsquare.util.Validator.nonEmptyStringOf; @@ -151,7 +153,8 @@ public class TradeManager { p2PNetworkReadyListener = new P2PNetworkReadyListener() { @Override public void onFirstPeerAuthenticated() { - initPendingTrades(); + // give a bit delay to be sure other listeners has dont its jobs + UserThread.runAfter(() -> initPendingTrades(), 100, TimeUnit.MILLISECONDS); } }; p2PService.addP2PServiceListener(p2PNetworkReadyListener); diff --git a/core/src/main/java/io/bitsquare/trade/protocol/availability/messages/OfferAvailabilityRequest.java b/core/src/main/java/io/bitsquare/trade/protocol/availability/messages/OfferAvailabilityRequest.java index cbf90fd61b..80c6774fd9 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/availability/messages/OfferAvailabilityRequest.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/availability/messages/OfferAvailabilityRequest.java @@ -20,7 +20,7 @@ package io.bitsquare.trade.protocol.availability.messages; import io.bitsquare.app.Version; import io.bitsquare.common.crypto.PubKeyRing; -public class OfferAvailabilityRequest extends OfferMessage { +public final class OfferAvailabilityRequest extends OfferMessage { // 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; diff --git a/core/src/main/java/io/bitsquare/trade/protocol/availability/messages/OfferAvailabilityResponse.java b/core/src/main/java/io/bitsquare/trade/protocol/availability/messages/OfferAvailabilityResponse.java index 7a90bbd47a..f91c6aba9a 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/availability/messages/OfferAvailabilityResponse.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/availability/messages/OfferAvailabilityResponse.java @@ -19,7 +19,7 @@ package io.bitsquare.trade.protocol.availability.messages; import io.bitsquare.app.Version; -public class OfferAvailabilityResponse extends OfferMessage { +public final class OfferAvailabilityResponse extends OfferMessage { // 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; diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/DepositTxPublishedMessage.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/DepositTxPublishedMessage.java index 2ce022f833..c9f4aea4aa 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/DepositTxPublishedMessage.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/DepositTxPublishedMessage.java @@ -25,7 +25,7 @@ import javax.annotation.concurrent.Immutable; import java.util.Arrays; @Immutable -public class DepositTxPublishedMessage extends TradeMessage implements MailboxMessage { +public final class DepositTxPublishedMessage extends TradeMessage implements MailboxMessage { // 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; diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/FiatTransferStartedMessage.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/FiatTransferStartedMessage.java index 3591bd7a4c..f507fc087c 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/FiatTransferStartedMessage.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/FiatTransferStartedMessage.java @@ -24,7 +24,7 @@ import io.bitsquare.p2p.messaging.MailboxMessage; import javax.annotation.concurrent.Immutable; @Immutable -public class FiatTransferStartedMessage extends TradeMessage implements MailboxMessage { +public final class FiatTransferStartedMessage extends TradeMessage implements MailboxMessage { // 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; diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/FinalizePayoutTxRequest.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/FinalizePayoutTxRequest.java index 8553f4c386..979e2bb0f9 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/FinalizePayoutTxRequest.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/FinalizePayoutTxRequest.java @@ -25,7 +25,7 @@ import javax.annotation.concurrent.Immutable; import java.util.Arrays; @Immutable -public class FinalizePayoutTxRequest extends TradeMessage implements MailboxMessage { +public final class FinalizePayoutTxRequest extends TradeMessage implements MailboxMessage { // 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; diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/PayDepositRequest.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/PayDepositRequest.java index 35a00b62fa..427816e81f 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/PayDepositRequest.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/PayDepositRequest.java @@ -29,7 +29,7 @@ import java.util.Arrays; import java.util.List; @Immutable -public class PayDepositRequest extends TradeMessage implements MailboxMessage { +public final class PayDepositRequest extends TradeMessage implements MailboxMessage { // 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; diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/PayoutTxFinalizedMessage.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/PayoutTxFinalizedMessage.java index ced2b142d1..1cba186938 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/PayoutTxFinalizedMessage.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/PayoutTxFinalizedMessage.java @@ -25,7 +25,7 @@ import javax.annotation.concurrent.Immutable; import java.util.Arrays; @Immutable -public class PayoutTxFinalizedMessage extends TradeMessage implements MailboxMessage { +public final class PayoutTxFinalizedMessage extends TradeMessage implements MailboxMessage { // 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; diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/PublishDepositTxRequest.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/PublishDepositTxRequest.java index 5b8584dded..2b33335185 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/PublishDepositTxRequest.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/PublishDepositTxRequest.java @@ -29,7 +29,7 @@ import java.util.ArrayList; import java.util.List; @Immutable -public class PublishDepositTxRequest extends TradeMessage { +public final class PublishDepositTxRequest extends TradeMessage { // 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; diff --git a/gui/src/main/java/io/bitsquare/app/BitsquareApp.java b/gui/src/main/java/io/bitsquare/app/BitsquareApp.java index a2299ff42e..3435643dca 100644 --- a/gui/src/main/java/io/bitsquare/app/BitsquareApp.java +++ b/gui/src/main/java/io/bitsquare/app/BitsquareApp.java @@ -73,7 +73,8 @@ import static io.bitsquare.app.BitsquareEnvironment.APP_NAME_KEY; public class BitsquareApp extends Application { private static final Logger log = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(BitsquareApp.class); - public static final boolean DEV_MODE = false; + public static final boolean DEV_MODE = true; + public static final boolean IS_RELEASE_VERSION = !DEV_MODE && true; private static Environment env; @@ -90,7 +91,6 @@ public class BitsquareApp extends Application { private MainView mainView; public static Runnable shutDownHandler; - public static Runnable restartDownHandler; public static void setEnvironment(Environment env) { BitsquareApp.env = env; @@ -98,16 +98,12 @@ public class BitsquareApp extends Application { @Override public void start(Stage primaryStage) throws IOException { - BitsquareApp.primaryStage = primaryStage; - - Log.setup(Paths.get(env.getProperty(BitsquareEnvironment.APP_DATA_DIR_KEY), "bitsquare").toString()); - Log.PRINT_TRACE_METHOD = DEV_MODE; + String logPath = Paths.get(env.getProperty(BitsquareEnvironment.APP_DATA_DIR_KEY), "bitsquare").toString(); + Log.setup(logPath, IS_RELEASE_VERSION); + log.info("Log files under: " + logPath); UserThread.setExecutor(Platform::runLater); - shutDownHandler = this::stop; - restartDownHandler = this::restart; - // setup UncaughtExceptionHandler Thread.UncaughtExceptionHandler handler = (thread, throwable) -> { // Might come from another thread @@ -123,6 +119,11 @@ public class BitsquareApp extends Application { Security.addProvider(new BouncyCastleProvider()); + + BitsquareApp.primaryStage = primaryStage; + + shutDownHandler = this::stop; + try { // Guice bitsquareAppModule = new BitsquareAppModule(env, primaryStage); @@ -148,30 +149,33 @@ public class BitsquareApp extends Application { "/io/bitsquare/gui/images.css"); // configure the system tray - SystemTray.create(primaryStage, this::stop); + SystemTray systemTray = SystemTray.create(primaryStage, shutDownHandler); primaryStage.setOnCloseRequest(e -> { e.consume(); - stop(); + if (BitsquareApp.IS_RELEASE_VERSION) + systemTray.hideStage(); + else + stop(); }); scene.setOnKeyReleased(keyEvent -> { - // For now we exit when closing/quit the app. - // Later we will only hide the window (systemTray.hideStage()) and use the exit item in the system tray for - // shut down. if (new KeyCodeCombination(KeyCode.W, KeyCombination.SHORTCUT_DOWN).match(keyEvent) || - new KeyCodeCombination(KeyCode.Q, KeyCombination.SHORTCUT_DOWN).match(keyEvent)) - stop(); - else if (new KeyCodeCombination(KeyCode.D, KeyCombination.SHORTCUT_DOWN).match(keyEvent)) - //if (BitsquareApp.DEV_MODE) - showDebugWindow(); - else if (new KeyCodeCombination(KeyCode.F, KeyCombination.SHORTCUT_DOWN).match(keyEvent)) - showFPSWindow(); - else if (new KeyCodeCombination(KeyCode.E, KeyCombination.SHORTCUT_DOWN).match(keyEvent)) + new KeyCodeCombination(KeyCode.Q, KeyCombination.SHORTCUT_DOWN).match(keyEvent)) { + if (BitsquareApp.IS_RELEASE_VERSION) + systemTray.hideStage(); + else + stop(); + } else if (new KeyCodeCombination(KeyCode.E, KeyCombination.SHORTCUT_DOWN).match(keyEvent)) { showEmptyWalletPopup(); - else if (new KeyCodeCombination(KeyCode.M, KeyCombination.SHORTCUT_DOWN).match(keyEvent)) + } else if (new KeyCodeCombination(KeyCode.M, KeyCombination.SHORTCUT_DOWN).match(keyEvent)) { showSendAlertMessagePopup(); + } else if (BitsquareApp.DEV_MODE) { + if (new KeyCodeCombination(KeyCode.D, KeyCombination.SHORTCUT_DOWN).match(keyEvent)) + showDebugWindow(); + else if (new KeyCodeCombination(KeyCode.F, KeyCombination.SHORTCUT_DOWN).match(keyEvent)) + showFPSWindow(); + } }); - // configure the primary stage primaryStage.setTitle(env.getRequiredProperty(APP_NAME_KEY)); primaryStage.setScene(scene); @@ -285,7 +289,6 @@ public class BitsquareApp extends Application { stage.setWidth(200); stage.setHeight(100); stage.show(); - } @Override @@ -323,10 +326,4 @@ public class BitsquareApp extends Application { System.exit(1); } } - - private void restart() { - //TODO - stop(); - //gracefulShutDown(UpdateFX::restartApp); - } } diff --git a/gui/src/main/java/io/bitsquare/gui/SystemTray.java b/gui/src/main/java/io/bitsquare/gui/SystemTray.java index 5d4b6f4a96..b06d3122a9 100644 --- a/gui/src/main/java/io/bitsquare/gui/SystemTray.java +++ b/gui/src/main/java/io/bitsquare/gui/SystemTray.java @@ -51,8 +51,9 @@ public class SystemTray { private final Runnable onExit; private final MenuItem toggleShowHideItem = new MenuItem(HIDE_WINDOW_LABEL); - public static void create(Stage stage, Runnable onExit) { + public static SystemTray create(Stage stage, Runnable onExit) { systemTray = new SystemTray(stage, onExit); + return systemTray; } private SystemTray(Stage stage, Runnable onExit) { @@ -114,8 +115,7 @@ public class SystemTray { if (stage.isShowing()) { toggleShowHideItem.setLabel(SHOW_WINDOW_LABEL); UserThread.execute(stage::hide); - } - else { + } else { toggleShowHideItem.setLabel(HIDE_WINDOW_LABEL); UserThread.execute(stage::show); } diff --git a/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferView.java b/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferView.java index 3fe63652b1..d1b51cc70a 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferView.java @@ -356,10 +356,10 @@ public class TakeOfferView extends ActivatableViewAndModel--> - - - - - - - - - + - - - - - - - - - - - --> - - - - - - diff --git a/jtorproxy/src/main/java/com/msopentech/thali/toronionproxy/OnionProxyManager.java b/jtorproxy/src/main/java/com/msopentech/thali/toronionproxy/OnionProxyManager.java index ce2d91dba9..3451529ad6 100644 --- a/jtorproxy/src/main/java/com/msopentech/thali/toronionproxy/OnionProxyManager.java +++ b/jtorproxy/src/main/java/com/msopentech/thali/toronionproxy/OnionProxyManager.java @@ -129,6 +129,7 @@ public abstract class OnionProxyManager { if (isBootstrapped() == false) { Thread.sleep(1000, 0); } else { + LOG.info("Tor has bootstrapped"); return true; } } @@ -377,7 +378,6 @@ public abstract class OnionProxyManager { } if (phase != null && phase.contains("PROGRESS=100")) { - LOG.info("Tor has already bootstrapped"); return true; } diff --git a/network/src/main/java/io/bitsquare/p2p/network/NetworkNode.java b/network/src/main/java/io/bitsquare/p2p/network/NetworkNode.java index 1bdf293050..0629e8ae01 100644 --- a/network/src/main/java/io/bitsquare/p2p/network/NetworkNode.java +++ b/network/src/main/java/io/bitsquare/p2p/network/NetworkNode.java @@ -271,7 +271,11 @@ public abstract class NetworkNode implements MessageListener, ConnectionListener public void addConnectionListener(ConnectionListener connectionListener) { Log.traceCall(); - connectionListeners.add(connectionListener); + + boolean newEntry = connectionListeners.add(connectionListener); + if (!newEntry) + log.warn("Try to add a connectionListener which was already added.\nconnectionListener={}\nconnectionListeners={}" + , connectionListener, connectionListeners); } public void removeConnectionListener(ConnectionListener connectionListener) { @@ -281,12 +285,18 @@ public abstract class NetworkNode implements MessageListener, ConnectionListener public void addMessageListener(MessageListener messageListener) { Log.traceCall(); - messageListeners.add(messageListener); + boolean newEntry = messageListeners.add(messageListener); + if (!newEntry) + log.warn("Try to add a messageListener which was already added.\nmessageListener={}\nmessageListeners={}" + , messageListener, messageListeners); } public void removeMessageListener(MessageListener messageListener) { Log.traceCall(); - messageListeners.remove(messageListener); + boolean contained = messageListeners.remove(messageListener); + if (!contained) + log.warn("Try to remove a messageListener which was never added.\nmessageListener={}\nmessageListeners={}" + , messageListener, messageListeners); } diff --git a/network/src/main/java/io/bitsquare/p2p/peers/AuthenticationHandshake.java b/network/src/main/java/io/bitsquare/p2p/peers/AuthenticationHandshake.java index 042ed5e365..f798d10c4b 100644 --- a/network/src/main/java/io/bitsquare/p2p/peers/AuthenticationHandshake.java +++ b/network/src/main/java/io/bitsquare/p2p/peers/AuthenticationHandshake.java @@ -37,6 +37,7 @@ public class AuthenticationHandshake implements MessageListener { private final NetworkNode networkNode; private final PeerGroup peerGroup; private final Address myAddress; + private final Address peerAddress; private SettableFuture resultFuture; private long startAuthTs; @@ -48,13 +49,17 @@ public class AuthenticationHandshake implements MessageListener { // Constructor /////////////////////////////////////////////////////////////////////////////////////////// - public AuthenticationHandshake(NetworkNode networkNode, PeerGroup peerGroup, Address myAddress) { - Log.traceCall(); + public AuthenticationHandshake(NetworkNode networkNode, PeerGroup peerGroup, Address myAddress, Address peerAddress) { + Log.traceCall("peerAddress " + peerAddress); this.networkNode = networkNode; this.peerGroup = peerGroup; this.myAddress = myAddress; - } + this.peerAddress = peerAddress; + networkNode.addMessageListener(this); + resultFuture = SettableFuture.create(); + startAuthTs = System.currentTimeMillis(); + } /////////////////////////////////////////////////////////////////////////////////////////// // MessageListener implementation @@ -62,100 +67,98 @@ public class AuthenticationHandshake implements MessageListener { @Override public void onMessage(Message message, Connection connection) { - checkArgument(!stopped); - if (message instanceof AuthenticationMessage) { - Log.traceCall(message.toString()); - if (message instanceof AuthenticationResponse) { - // Requesting peer + // We are listening on all connections, so we need to filter out only our peer address + if (((AuthenticationMessage) message).address.equals(peerAddress)) { + Log.traceCall(message.toString()); + checkArgument(!stopped); + if (message instanceof AuthenticationResponse) { + // Requesting peer + // We use the active connectionType if we started the authentication request to another peer + // That is used for protecting eclipse attacks + connection.setConnectionPriority(ConnectionPriority.ACTIVE); - // We use the active connectionType if we started the authentication request to another peer - // That is used for protecting eclipse attacks - connection.setConnectionPriority(ConnectionPriority.ACTIVE); + AuthenticationResponse authenticationResponse = (AuthenticationResponse) message; + connection.setPeerAddress(peerAddress); + log.trace("Received authenticationResponse from " + peerAddress); + boolean verified = nonce != 0 && nonce == authenticationResponse.requesterNonce; + if (verified) { + GetPeersAuthRequest getPeersAuthRequest = new GetPeersAuthRequest(myAddress, + authenticationResponse.responderNonce, + new HashSet<>(peerGroup.getReportedPeers())); + SettableFuture future = networkNode.sendMessage(peerAddress, getPeersAuthRequest); + log.trace("Sent GetPeersAuthRequest {} to {}", getPeersAuthRequest, peerAddress); + Futures.addCallback(future, new FutureCallback() { + @Override + public void onSuccess(Connection connection) { + log.trace("Successfully sent GetPeersAuthRequest {} to {}", getPeersAuthRequest, peerAddress); + } - AuthenticationResponse authenticationResponse = (AuthenticationResponse) message; - Address peerAddress = authenticationResponse.address; - connection.setPeerAddress(peerAddress); - log.trace("Received authenticationResponse from " + peerAddress); - boolean verified = nonce != 0 && nonce == authenticationResponse.requesterNonce; - if (verified) { - GetPeersAuthRequest getPeersAuthRequest = new GetPeersAuthRequest(myAddress, - authenticationResponse.responderNonce, - new HashSet<>(peerGroup.getReportedPeers())); - SettableFuture future = networkNode.sendMessage(peerAddress, getPeersAuthRequest); - log.trace("Sent GetPeersAuthRequest {} to {}", getPeersAuthRequest, peerAddress); - Futures.addCallback(future, new FutureCallback() { - @Override - public void onSuccess(Connection connection) { - log.trace("Successfully sent GetPeersAuthRequest {} to {}", getPeersAuthRequest, peerAddress); - } + @Override + public void onFailure(@NotNull Throwable throwable) { + log.info("GetPeersAuthRequest sending failed " + throwable.getMessage()); + failed(throwable); + } + }); - @Override - public void onFailure(@NotNull Throwable throwable) { - log.info("GetPeersAuthRequest sending failed " + throwable.getMessage()); - failed(throwable); - } - }); + // We could set already the authenticated flag here already, but as we need the reported peers we need + // to wait for the GetPeersAuthResponse before we are completed. + } else { + log.warn("verify nonce failed. AuthenticationResponse=" + authenticationResponse + " / nonce=" + nonce); + failed(new Exception("Verify nonce failed. AuthenticationResponse=" + authenticationResponse + " / nonceMap=" + nonce)); + } + } else if (message instanceof GetPeersAuthRequest) { + // Responding peer + GetPeersAuthRequest getPeersAuthRequest = (GetPeersAuthRequest) message; + log.trace("GetPeersAuthRequest from " + peerAddress + " at " + myAddress); + boolean verified = nonce != 0 && nonce == getPeersAuthRequest.responderNonce; + if (verified) { + // we create the msg with our already collected peer addresses (before adding the new ones) + GetPeersAuthResponse getPeersAuthResponse = new GetPeersAuthResponse(myAddress, + new HashSet<>(peerGroup.getReportedPeers())); + SettableFuture future = networkNode.sendMessage(peerAddress, getPeersAuthResponse); + log.trace("Sent GetPeersAuthResponse {} to {}", getPeersAuthResponse, peerAddress); - // We could set already the authenticated flag here already, but as we need the reported peers we need - // to wait for the GetPeersAuthResponse before we are completed. - } else { - log.warn("verify nonce failed. AuthenticationResponse=" + authenticationResponse + " / nonce=" + nonce); - failed(new Exception("Verify nonce failed. AuthenticationResponse=" + authenticationResponse + " / nonceMap=" + nonce)); - } - } else if (message instanceof GetPeersAuthRequest) { - // Responding peer - GetPeersAuthRequest getPeersAuthRequest = (GetPeersAuthRequest) message; - Address peerAddress = getPeersAuthRequest.address; - log.trace("GetPeersAuthRequest from " + peerAddress + " at " + myAddress); - boolean verified = nonce != 0 && nonce == getPeersAuthRequest.responderNonce; - if (verified) { - // we create the msg with our already collected peer addresses (before adding the new ones) - GetPeersAuthResponse getPeersAuthResponse = new GetPeersAuthResponse(myAddress, - new HashSet<>(peerGroup.getReportedPeers())); - SettableFuture future = networkNode.sendMessage(peerAddress, getPeersAuthResponse); - log.trace("Sent GetPeersAuthResponse {} to {}", getPeersAuthResponse, peerAddress); + // now we add the reported peers to our own set + HashSet reportedPeers = getPeersAuthRequest.reportedPeers; + log.trace("Received reported peers: " + reportedPeers); + peerGroup.addToReportedPeers(reportedPeers, connection); - // now we add the reported peers to our own set - HashSet reportedPeers = getPeersAuthRequest.reportedPeers; + Futures.addCallback(future, new FutureCallback() { + @Override + public void onSuccess(Connection connection) { + log.trace("Successfully sent GetPeersAuthResponse {} to {}", getPeersAuthResponse, peerAddress); + log.info("AuthenticationComplete: Peer with address " + peerAddress + + " authenticated (" + connection.getUid() + "). Took " + + (System.currentTimeMillis() - startAuthTs) + " ms."); + + completed(connection); + } + + @Override + public void onFailure(@NotNull Throwable throwable) { + log.info("GetPeersAuthResponse sending failed " + throwable.getMessage()); + failed(throwable); + } + }); + } else { + log.warn("verify nonce failed. getPeersMessage=" + getPeersAuthRequest + " / nonce=" + nonce); + failed(new Exception("Verify nonce failed. getPeersMessage=" + getPeersAuthRequest + " / nonce=" + nonce)); + } + } else if (message instanceof GetPeersAuthResponse) { + // Requesting peer + GetPeersAuthResponse getPeersAuthResponse = (GetPeersAuthResponse) message; + log.trace("GetPeersAuthResponse from " + peerAddress + " at " + myAddress); + HashSet reportedPeers = getPeersAuthResponse.reportedPeers; log.trace("Received reported peers: " + reportedPeers); peerGroup.addToReportedPeers(reportedPeers, connection); - Futures.addCallback(future, new FutureCallback() { - @Override - public void onSuccess(Connection connection) { - log.trace("Successfully sent GetPeersAuthResponse {} to {}", getPeersAuthResponse, peerAddress); - log.info("AuthenticationComplete: Peer with address " + peerAddress - + " authenticated (" + connection.getUid() + "). Took " - + (System.currentTimeMillis() - startAuthTs) + " ms."); + log.info("AuthenticationComplete: Peer with address " + peerAddress + + " authenticated (" + connection.getUid() + "). Took " + + (System.currentTimeMillis() - startAuthTs) + " ms."); - completed(connection); - } - - @Override - public void onFailure(@NotNull Throwable throwable) { - log.info("GetPeersAuthResponse sending failed " + throwable.getMessage()); - failed(throwable); - } - }); - } else { - log.warn("verify nonce failed. getPeersMessage=" + getPeersAuthRequest + " / nonce=" + nonce); - failed(new Exception("Verify nonce failed. getPeersMessage=" + getPeersAuthRequest + " / nonce=" + nonce)); + completed(connection); } - } else if (message instanceof GetPeersAuthResponse) { - // Requesting peer - GetPeersAuthResponse getPeersAuthResponse = (GetPeersAuthResponse) message; - Address peerAddress = getPeersAuthResponse.address; - log.trace("GetPeersAuthResponse from " + peerAddress + " at " + myAddress); - HashSet reportedPeers = getPeersAuthResponse.reportedPeers; - log.trace("Received reported peers: " + reportedPeers); - peerGroup.addToReportedPeers(reportedPeers, connection); - - log.info("AuthenticationComplete: Peer with address " + peerAddress - + " authenticated (" + connection.getUid() + "). Took " - + (System.currentTimeMillis() - startAuthTs) + " ms."); - - completed(connection); } } } @@ -165,18 +168,17 @@ public class AuthenticationHandshake implements MessageListener { // Authentication initiated by requesting peer /////////////////////////////////////////////////////////////////////////////////////////// - public SettableFuture requestAuthentication(Address peerAddress) { - Log.traceCall(); + public SettableFuture requestAuthentication() { + Log.traceCall("peerAddress " + peerAddress); // Requesting peer - init(); - AuthenticationRequest authenticationRequest = new AuthenticationRequest(myAddress, getAndSetNonce()); SettableFuture future = networkNode.sendMessage(peerAddress, authenticationRequest); Futures.addCallback(future, new FutureCallback() { @Override public void onSuccess(Connection connection) { log.trace("send AuthenticationRequest to " + peerAddress + " succeeded."); + connection.setPeerAddress(peerAddress); // We protect that connection from getting closed by maintenance cleanup... connection.setConnectionPriority(ConnectionPriority.AUTH_REQUEST); @@ -198,13 +200,11 @@ public class AuthenticationHandshake implements MessageListener { // Responding to authentication request /////////////////////////////////////////////////////////////////////////////////////////// - public SettableFuture respondToAuthenticationRequest(AuthenticationRequest authenticationRequest, Connection connection) { - Log.traceCall(); + public SettableFuture respondToAuthenticationRequest(AuthenticationRequest + authenticationRequest, Connection connection) { + Log.traceCall("peerAddress " + peerAddress); // Responding peer - init(); - - Address peerAddress = authenticationRequest.address; log.trace("AuthenticationRequest from " + peerAddress + " at " + myAddress); log.info("We shut down inbound connection from peer {} to establish a new " + "connection with his reported address.", peerAddress); @@ -224,6 +224,7 @@ public class AuthenticationHandshake implements MessageListener { @Override public void onSuccess(Connection connection) { log.trace("onSuccess sending AuthenticationResponse"); + connection.setPeerAddress(peerAddress); // We use passive connectionType for connections created from received authentication requests from other peers // That is used for protecting eclipse attacks @@ -247,12 +248,6 @@ public class AuthenticationHandshake implements MessageListener { // Private /////////////////////////////////////////////////////////////////////////////////////////// - private void init() { - networkNode.addMessageListener(this); - resultFuture = SettableFuture.create(); - startAuthTs = System.currentTimeMillis(); - } - private long getAndSetNonce() { Log.traceCall(); nonce = new Random().nextLong(); @@ -279,4 +274,20 @@ public class AuthenticationHandshake implements MessageListener { networkNode.removeMessageListener(this); stopped = true; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof AuthenticationHandshake)) return false; + + AuthenticationHandshake that = (AuthenticationHandshake) o; + + return !(peerAddress != null ? !peerAddress.equals(that.peerAddress) : that.peerAddress != null); + + } + + @Override + public int hashCode() { + return peerAddress != null ? peerAddress.hashCode() : 0; + } } diff --git a/network/src/main/java/io/bitsquare/p2p/peers/PeerGroup.java b/network/src/main/java/io/bitsquare/p2p/peers/PeerGroup.java index 1a50ab2ed5..e7f5cb4038 100644 --- a/network/src/main/java/io/bitsquare/p2p/peers/PeerGroup.java +++ b/network/src/main/java/io/bitsquare/p2p/peers/PeerGroup.java @@ -143,8 +143,8 @@ public class PeerGroup implements MessageListener, ConnectionListener { }); }); } else { - log.trace("Message {} not broadcasted because we are not authenticated yet. " + - "That is expected at startup.", message); + log.trace("Message not broadcasted because we are not authenticated yet. " + + "That is expected at startup.\nmessage = {}", message); } } @@ -165,33 +165,43 @@ public class PeerGroup implements MessageListener, ConnectionListener { private void processAuthenticationRequest(NetworkNode networkNode, AuthenticationRequest message, final Connection connection) { Log.traceCall(message.toString()); Address peerAddress = message.address; + + checkArgument(!authenticatedPeers.containsKey(peerAddress), + "We have that peer already authenticated. That must never happen."); + + AuthenticationHandshake authenticationHandshake; if (!authenticationHandshakes.containsKey(peerAddress)) { // We protect that connection from getting closed by maintenance cleanup... connection.setConnectionPriority(ConnectionPriority.AUTH_REQUEST); - AuthenticationHandshake authenticationHandshake = new AuthenticationHandshake(networkNode, PeerGroup.this, getMyAddress()); + authenticationHandshake = new AuthenticationHandshake(networkNode, PeerGroup.this, getMyAddress(), message.address); authenticationHandshakes.put(peerAddress, authenticationHandshake); - SettableFuture future = authenticationHandshake.respondToAuthenticationRequest(message, connection); - Futures.addCallback(future, new FutureCallback() { - @Override - public void onSuccess(@Nullable Connection connection) { - if (connection != null && peerAddress.equals(connection.getPeerAddress())) { - setAuthenticated(connection, peerAddress); - purgeReportedPeersIfExceeds(); - } else { - log.error("Incorrect state at processAuthenticationRequest.onSuccess:\n" + - "peerAddress={}\nconnection=", peerAddress, connection); - } - } - @Override - public void onFailure(@NotNull Throwable throwable) { - log.info("AuthenticationHandshake failed. That is expected if peer went offline. " + throwable.getMessage()); - removePeer(connection.getPeerAddress()); - } - }); } else { - log.warn("An authentication handshake is already created for that peerAddress ({})", peerAddress); + authenticationHandshake = authenticationHandshakes.get(peerAddress); + log.debug("processAuthenticationRequest: An authentication handshake is already created for peerAddress ({})\n" + + "That can happen in race conditions. We might end up with 2 parallel connections as we " + + "got an request and sent an request ourselves.", peerAddress); } + + SettableFuture future = authenticationHandshake.respondToAuthenticationRequest(message, connection); + Futures.addCallback(future, new FutureCallback() { + @Override + public void onSuccess(@Nullable Connection connection) { + if (connection != null && peerAddress.equals(connection.getPeerAddress())) { + setAuthenticated(connection, peerAddress); + purgeReportedPeersIfExceeds(); + } else { + log.error("Incorrect state at processAuthenticationRequest.onSuccess:\n" + + "peerAddress={}\nconnection=", peerAddress, connection); + } + } + + @Override + public void onFailure(@NotNull Throwable throwable) { + log.info("AuthenticationHandshake failed. That is expected if peer went offline. " + throwable.getMessage()); + removePeer(connection.getPeerAddress()); + } + }); } @@ -217,9 +227,9 @@ public class PeerGroup implements MessageListener, ConnectionListener { checkArgument(!authenticatedPeers.containsKey(peerAddress), "We have that peer already authenticated. That must never happen."); if (!authenticationHandshakes.containsKey(peerAddress)) { - AuthenticationHandshake authenticationHandshake = new AuthenticationHandshake(networkNode, this, getMyAddress()); + AuthenticationHandshake authenticationHandshake = new AuthenticationHandshake(networkNode, this, getMyAddress(), peerAddress); authenticationHandshakes.put(peerAddress, authenticationHandshake); - SettableFuture future = authenticationHandshake.requestAuthentication(peerAddress); + SettableFuture future = authenticationHandshake.requestAuthentication(); Futures.addCallback(future, new FutureCallback() { @Override public void onSuccess(Connection connection) { @@ -267,7 +277,21 @@ public class PeerGroup implements MessageListener, ConnectionListener { } }); } else { - log.warn("An authentication handshake is already created for that peerAddress ({})", peerAddress); + log.info("An authentication handshake is already created for that peerAddress ({})", peerAddress); + + Optional>> tupleOptional = getRandomNotAuthPeerAndRemainingSet(remainingAddresses); + if (tupleOptional.isPresent()) { + log.info("We try to authenticate to a seed node. " + tupleOptional.get().first); + authenticateToSeedNode(tupleOptional.get().second, tupleOptional.get().first, true); + } else if (reportedPeers.size() > 0) { + log.info("We don't have any more seed nodes for connecting. Lets try the reported peers."); + authenticateToRemainingReportedPeers(true); + } else { + log.info("We don't have any more seed nodes nor reported nodes for connecting. " + + "We stop authentication attempts now, but will repeat after a few minutes."); + UserThread.runAfterRandomDelay(() -> authenticateToRemainingReportedPeers(true), + 1, 2, TimeUnit.MINUTES); + } } } @@ -315,9 +339,9 @@ public class PeerGroup implements MessageListener, ConnectionListener { checkArgument(!authenticatedPeers.containsKey(reportedPeerAddress), "We have that peer already authenticated. That must never happen."); if (!authenticationHandshakes.containsKey(reportedPeerAddress)) { - AuthenticationHandshake authenticationHandshake = new AuthenticationHandshake(networkNode, this, getMyAddress()); + AuthenticationHandshake authenticationHandshake = new AuthenticationHandshake(networkNode, this, getMyAddress(), reportedPeerAddress); authenticationHandshakes.put(reportedPeerAddress, authenticationHandshake); - SettableFuture future = authenticationHandshake.requestAuthentication(reportedPeerAddress); + SettableFuture future = authenticationHandshake.requestAuthentication(); Futures.addCallback(future, new FutureCallback() { @Override public void onSuccess(Connection connection) { @@ -342,7 +366,7 @@ public class PeerGroup implements MessageListener, ConnectionListener { public void onFailure(@NotNull Throwable throwable) { log.info("Send RequestAuthenticationMessage to a reported peer with address " + reportedPeer + " failed." + "\nThat is expected if the nodes was offline." + - "\nException:" + throwable.getMessage()); + "\nException:" + throwable.toString()); removeReportedPeer(reportedPeer); if (reportedPeers.size() > 0) { @@ -357,7 +381,17 @@ public class PeerGroup implements MessageListener, ConnectionListener { } }); } else { - log.warn("An authentication handshake is already created for that peerAddress ({})", reportedPeer); + log.info("An authentication handshake is already created for that peerAddress ({})", reportedPeer); + + if (reportedPeers.size() > 0) { + log.info("Authentication failed. Lets try again with the remaining reported peer addresses."); + authenticateToRemainingReportedPeers(false); + } else { + log.info("Authentication failed. " + + "Lets wait a bit and then try the remaining seed nodes."); + UserThread.runAfterRandomDelay(() -> authenticateToRemainingSeedNodes(), + 1, 2, TimeUnit.MINUTES); + } } } @@ -374,9 +408,9 @@ public class PeerGroup implements MessageListener, ConnectionListener { checkArgument(!authenticatedPeers.containsKey(peerAddress), "We have that seed node already authenticated. That must never happen."); if (!authenticationHandshakes.containsKey(peerAddress)) { - AuthenticationHandshake authenticationHandshake = new AuthenticationHandshake(networkNode, this, getMyAddress()); + AuthenticationHandshake authenticationHandshake = new AuthenticationHandshake(networkNode, this, getMyAddress(), peerAddress); authenticationHandshakes.put(peerAddress, authenticationHandshake); - SettableFuture future = authenticationHandshake.requestAuthentication(peerAddress); + SettableFuture future = authenticationHandshake.requestAuthentication(); Futures.addCallback(future, new FutureCallback() { @Override public void onSuccess(@Nullable Connection connection) { @@ -405,6 +439,7 @@ public class PeerGroup implements MessageListener, ConnectionListener { Log.traceCall(peerAddress.getFullAddress()); if (authenticationHandshakes.containsKey(peerAddress)) authenticationHandshakes.remove(peerAddress); + log.info("\n\n############################################################\n" + "We are authenticated to:" + "\nconnection=" + connection.getUid() @@ -412,9 +447,8 @@ public class PeerGroup implements MessageListener, ConnectionListener { + "\npeerAddress= " + peerAddress + "\n############################################################\n"); - connection.setAuthenticated(peerAddress, connection); - addAuthenticatedPeer(new Peer(connection)); + connection.setAuthenticated(peerAddress, connection); } private void addAuthenticatedPeer(Peer peer) { @@ -629,6 +663,7 @@ public class PeerGroup implements MessageListener, ConnectionListener { .map(e -> new ReportedPeer(e.address, new Date())) .collect(Collectors.toSet()); all.addAll(authenticated); + seedNodeAddresses.stream().forEach(e -> all.remove(e)); return all; } @@ -654,7 +689,7 @@ public class PeerGroup implements MessageListener, ConnectionListener { connection.shutDown(); } else { newReportedPeers.remove(new ReportedPeer(getMyAddress(), new Date())); - + seedNodeAddresses.stream().forEach(e -> newReportedPeers.remove(new ReportedPeer(e, new Date()))); // In case we have a peers already we adjust the lastActivityDate by adjusting the date to the mid // of the lastActivityDate of our already stored peer and the reported one Map reportedPeersMap = new HashMap<>(); @@ -750,6 +785,7 @@ public class PeerGroup implements MessageListener, ConnectionListener { private Optional>> getReportedPeerAndRemainingSet(Set remainingReportedPeers) { Log.traceCall(); List list = new ArrayList<>(remainingReportedPeers); + list.remove(new ReportedPeer(getMyAddress(), new Date())); authenticatedPeers.values().stream().forEach(e -> list.remove(new ReportedPeer(e.address, new Date()))); if (!list.isEmpty()) { ReportedPeer item = getAndRemoveRandomReportedPeer(list); @@ -762,6 +798,7 @@ public class PeerGroup implements MessageListener, ConnectionListener { private Optional>> getRandomNotAuthPeerAndRemainingSet(Set
remainingAddresses) { Log.traceCall(); List
list = new ArrayList<>(remainingAddresses); + list.remove(getMyAddress()); authenticatedPeers.values().stream().forEach(e -> list.remove(e.address)); if (!list.isEmpty()) { Address item = getAndRemoveRandomAddress(list); 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 476709736c..85a329423a 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 @@ -1,11 +1,18 @@ package io.bitsquare.p2p.peers.messages.auth; import io.bitsquare.app.Version; +import io.bitsquare.p2p.Address; import io.bitsquare.p2p.Message; public abstract class AuthenticationMessage implements Message { private final int networkId = Version.NETWORK_ID; + public final Address address; + + public AuthenticationMessage(Address address) { + this.address = address; + } + @Override public int networkId() { return networkId; diff --git a/network/src/main/java/io/bitsquare/p2p/peers/messages/auth/AuthenticationRequest.java b/network/src/main/java/io/bitsquare/p2p/peers/messages/auth/AuthenticationRequest.java index 7133d39eb5..cbcf8fc268 100644 --- a/network/src/main/java/io/bitsquare/p2p/peers/messages/auth/AuthenticationRequest.java +++ b/network/src/main/java/io/bitsquare/p2p/peers/messages/auth/AuthenticationRequest.java @@ -7,11 +7,10 @@ public final class AuthenticationRequest extends AuthenticationMessage { // 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; - public final Address address; public final long requesterNonce; public AuthenticationRequest(Address address, long requesterNonce) { - this.address = address; + super(address); this.requesterNonce = requesterNonce; } diff --git a/network/src/main/java/io/bitsquare/p2p/peers/messages/auth/AuthenticationResponse.java b/network/src/main/java/io/bitsquare/p2p/peers/messages/auth/AuthenticationResponse.java index 49d1557153..3872462b5f 100644 --- a/network/src/main/java/io/bitsquare/p2p/peers/messages/auth/AuthenticationResponse.java +++ b/network/src/main/java/io/bitsquare/p2p/peers/messages/auth/AuthenticationResponse.java @@ -7,12 +7,11 @@ public final class AuthenticationResponse extends AuthenticationMessage { // 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; - public final Address address; public final long requesterNonce; public final long responderNonce; public AuthenticationResponse(Address address, long requesterNonce, long responderNonce) { - this.address = address; + super(address); this.requesterNonce = requesterNonce; this.responderNonce = responderNonce; } diff --git a/network/src/main/java/io/bitsquare/p2p/peers/messages/auth/GetPeersAuthRequest.java b/network/src/main/java/io/bitsquare/p2p/peers/messages/auth/GetPeersAuthRequest.java index 26ca5f67cf..315cfddf19 100644 --- a/network/src/main/java/io/bitsquare/p2p/peers/messages/auth/GetPeersAuthRequest.java +++ b/network/src/main/java/io/bitsquare/p2p/peers/messages/auth/GetPeersAuthRequest.java @@ -10,12 +10,11 @@ public final class GetPeersAuthRequest extends AuthenticationMessage { // 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; - public final Address address; public final long responderNonce; public final HashSet reportedPeers; public GetPeersAuthRequest(Address address, long responderNonce, HashSet reportedPeers) { - this.address = address; + super(address); this.responderNonce = responderNonce; this.reportedPeers = reportedPeers; } diff --git a/network/src/main/java/io/bitsquare/p2p/peers/messages/auth/GetPeersAuthResponse.java b/network/src/main/java/io/bitsquare/p2p/peers/messages/auth/GetPeersAuthResponse.java index 0f030449ed..30ba688069 100644 --- a/network/src/main/java/io/bitsquare/p2p/peers/messages/auth/GetPeersAuthResponse.java +++ b/network/src/main/java/io/bitsquare/p2p/peers/messages/auth/GetPeersAuthResponse.java @@ -10,11 +10,10 @@ public final class GetPeersAuthResponse extends AuthenticationMessage { // 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; - public final Address address; public final HashSet reportedPeers; public GetPeersAuthResponse(Address address, HashSet reportedPeers) { - this.address = address; + super(address); this.reportedPeers = reportedPeers; } 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 c14a69c2fa..121c38175c 100644 --- a/network/src/main/java/io/bitsquare/p2p/seed/SeedNode.java +++ b/network/src/main/java/io/bitsquare/p2p/seed/SeedNode.java @@ -97,16 +97,25 @@ public class SeedNode { } } - public void createAndStartP2PService() { - createAndStartP2PService(mySeedNodeAddress, useLocalhost, Version.NETWORK_ID, progArgSeedNodes, null); + public void createAndStartP2PService(boolean releaseVersion) { + createAndStartP2PService(mySeedNodeAddress, useLocalhost, Version.NETWORK_ID, releaseVersion, progArgSeedNodes, null); } public void createAndStartP2PService(Address mySeedNodeAddress, boolean useLocalhost, int networkId, + boolean releaseVersion, @Nullable Set
progArgSeedNodes, @Nullable P2PServiceListener listener) { Log.traceCall(); + + Path appPath = Paths.get(defaultUserDataDir, + "Bitsquare_seed_node_" + String.valueOf(mySeedNodeAddress.getFullAddress().replace(":", "_"))); + + String logPath = Paths.get(appPath.toString(), "logs").toString(); + Log.setup(logPath, releaseVersion); + log.info("Log files under: " + logPath); + SeedNodesRepository seedNodesRepository = new SeedNodesRepository(); if (progArgSeedNodes != null && !progArgSeedNodes.isEmpty()) { if (useLocalhost) @@ -114,13 +123,12 @@ public class SeedNode { else seedNodesRepository.setTorSeedNodeAddresses(progArgSeedNodes); } - 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(); + File storageDir = Paths.get(appPath.toString(), "db").toFile(); if (storageDir.mkdirs()) log.info("Created storageDir at " + storageDir.getAbsolutePath()); + + File torDir = Paths.get(appPath.toString(), "tor").toFile(); if (torDir.mkdirs()) log.info("Created torDir at " + torDir.getAbsolutePath()); diff --git a/network/src/test/java/io/bitsquare/crypto/EncryptionServiceTests.java b/network/src/test/java/io/bitsquare/crypto/EncryptionServiceTests.java index 95a753f852..9e3acef9ec 100644 --- a/network/src/test/java/io/bitsquare/crypto/EncryptionServiceTests.java +++ b/network/src/test/java/io/bitsquare/crypto/EncryptionServiceTests.java @@ -79,7 +79,7 @@ public class EncryptionServiceTests { } -class TestMessage implements MailboxMessage { +final class TestMessage implements MailboxMessage { public String data = "test"; private final int networkId = Version.NETWORK_ID; diff --git a/network/src/test/java/io/bitsquare/p2p/TestUtils.java b/network/src/test/java/io/bitsquare/p2p/TestUtils.java index e219916113..eca5cf4785 100644 --- a/network/src/test/java/io/bitsquare/p2p/TestUtils.java +++ b/network/src/test/java/io/bitsquare/p2p/TestUtils.java @@ -80,7 +80,7 @@ public class TestUtils { } CountDownLatch latch = new CountDownLatch(1); - seedNode.createAndStartP2PService(new Address("localhost", port), useLocalhost, 2, + seedNode.createAndStartP2PService(new Address("localhost", port), useLocalhost, 2, false, seedNodes, 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 2e3847731c..fb2e41239c 100644 --- a/network/src/test/java/io/bitsquare/p2p/mocks/MockMailboxMessage.java +++ b/network/src/test/java/io/bitsquare/p2p/mocks/MockMailboxMessage.java @@ -5,7 +5,7 @@ import io.bitsquare.p2p.Address; import io.bitsquare.p2p.messaging.MailboxMessage; import io.bitsquare.p2p.storage.data.ExpirablePayload; -public class MockMailboxMessage implements MailboxMessage, ExpirablePayload { +public final class MockMailboxMessage implements MailboxMessage, ExpirablePayload { private final int networkId = Version.NETWORK_ID; public String msg; public Address senderAddress; 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 d92d84eea3..93fea2a2e6 100644 --- a/network/src/test/java/io/bitsquare/p2p/mocks/MockMessage.java +++ b/network/src/test/java/io/bitsquare/p2p/mocks/MockMessage.java @@ -4,7 +4,7 @@ import io.bitsquare.app.Version; import io.bitsquare.p2p.Message; import io.bitsquare.p2p.storage.data.ExpirablePayload; -public class MockMessage implements Message, ExpirablePayload { +public final class MockMessage implements Message, ExpirablePayload { public String msg; public long ttl; private final int networkId = Version.NETWORK_ID; 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 82122ab6e5..9d20388605 100644 --- a/network/src/test/java/io/bitsquare/p2p/routing/PeerGroupTest.java +++ b/network/src/test/java/io/bitsquare/p2p/routing/PeerGroupTest.java @@ -80,7 +80,7 @@ public class PeerGroupTest { seedNodes.add(address); seedNode1 = new SeedNode("test_dummy_dir"); latch = new CountDownLatch(2); - seedNode1.createAndStartP2PService(address, useLocalhost, 2, + seedNode1.createAndStartP2PService(address, useLocalhost, 2, false, seedNodes, new P2PServiceListener() { @Override public void onRequestingDataCompleted() { @@ -125,7 +125,7 @@ public class PeerGroupTest { latch = new CountDownLatch(6); seedNode1 = new SeedNode("test_dummy_dir"); - seedNode1.createAndStartP2PService(address1, useLocalhost, 2, seedNodes, new P2PServiceListener() { + seedNode1.createAndStartP2PService(address1, useLocalhost, 2, false, seedNodes, new P2PServiceListener() { @Override public void onRequestingDataCompleted() { latch.countDown(); @@ -156,7 +156,7 @@ public class PeerGroupTest { Thread.sleep(500); seedNode2 = new SeedNode("test_dummy_dir"); - seedNode2.createAndStartP2PService(address2, useLocalhost, 2, seedNodes, new P2PServiceListener() { + seedNode2.createAndStartP2PService(address2, useLocalhost, 2, false, seedNodes, new P2PServiceListener() { @Override public void onRequestingDataCompleted() { latch.countDown(); @@ -386,7 +386,7 @@ public class PeerGroupTest { SeedNode seedNode = new SeedNode("test_dummy_dir"); latch = new CountDownLatch(1); - seedNode.createAndStartP2PService(new Address("localhost", port), useLocalhost, 2, seedNodes, new P2PServiceListener() { + seedNode.createAndStartP2PService(new Address("localhost", port), useLocalhost, 2, false, 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 b5a3bd744d..6179d9ada7 100644 --- a/seednode/src/main/java/io/bitsquare/p2p/seed/SeedNodeMain.java +++ b/seednode/src/main/java/io/bitsquare/p2p/seed/SeedNodeMain.java @@ -2,15 +2,12 @@ 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; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.nio.file.Path; -import java.nio.file.Paths; import java.security.NoSuchAlgorithmException; import java.security.Security; import java.util.Scanner; @@ -20,6 +17,9 @@ import java.util.concurrent.ThreadFactory; public class SeedNodeMain { private static final Logger log = LoggerFactory.getLogger(SeedNodeMain.class); + + public static final boolean IS_RELEASE_VERSION = false; + private SeedNode seedNode; private boolean stopped; @@ -28,29 +28,35 @@ public class SeedNodeMain { // eg. lmvdenjkyvx2ovga.onion:8001 false eo5ay2lyzrfvx2nr.onion:8002|si3uu56adkyqkldl.onion:8003 // To stop enter: q public static void main(String[] args) throws NoSuchAlgorithmException { - Path path = Paths.get("seed_node_log"); - Log.setup(path.toString()); - Log.PRINT_TRACE_METHOD = true; - log.info("Log files under: " + path.toAbsolutePath().toString()); - - DRMWorkaround.maybeDisableExportControls(); - new SeedNodeMain(args); } public SeedNodeMain(String[] args) { - Security.addProvider(new BouncyCastleProvider()); - final ThreadFactory threadFactory = new ThreadFactoryBuilder() .setNameFormat("SeedNodeMain") .setDaemon(true) .build(); UserThread.setExecutor(Executors.newSingleThreadExecutor(threadFactory)); + + // setup UncaughtExceptionHandler + Thread.UncaughtExceptionHandler handler = (thread, throwable) -> { + // Might come from another thread + log.error("Uncaught Exception from thread " + Thread.currentThread().getName()); + log.error("Uncaught Exception throwableMessage= " + throwable.getMessage()); + throwable.printStackTrace(); + }; + Thread.setDefaultUncaughtExceptionHandler(handler); + Thread.currentThread().setUncaughtExceptionHandler(handler); + + DRMWorkaround.maybeDisableExportControls(); + + Security.addProvider(new BouncyCastleProvider()); + UserThread.execute(() -> { try { seedNode = new SeedNode(BitsquareEnvironment.defaultUserDataDir()); seedNode.processArgs(args); - seedNode.createAndStartP2PService(); + seedNode.createAndStartP2PService(IS_RELEASE_VERSION); } catch (Throwable t) { log.error("Executing task failed. " + t.getMessage()); t.printStackTrace();