mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-04-20 23:56:30 -04:00
fix mailbox msg remove bug, add setup for release version
This commit is contained in:
parent
9b1108aa0a
commit
82e766e6b1
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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() +
|
||||
'}';
|
||||
}
|
||||
|
||||
|
@ -218,7 +218,7 @@ public class FileManager<T> {
|
||||
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) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -356,10 +356,10 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||
}
|
||||
});
|
||||
new Popup().information("To ensure that both traders follow the trade protocol they need to pay a security deposit.\n\n" +
|
||||
"The deposit will stay in your local trading wallet until the offer gets accepted by another trader.\n" +
|
||||
"It will be refunded to you after the trade has successfully completed.\n\n" +
|
||||
"The security deposit will be refunded to you after the trade has successfully completed.\n\n" +
|
||||
"You need to pay in the exact amount displayed to you from your external Bitcoin wallet into the " +
|
||||
"Bitsquare trade wallet. The amount is the sum of the trade amount, the security deposit, " +
|
||||
"Bitsquare trade wallet. In case you over pay, you will get it refunded after the trade.\n\n" +
|
||||
"The amount needed for funding is the sum of the trade amount, the security deposit, " +
|
||||
"the trading fee and the Bitcoin mining fee.\n" +
|
||||
"You can see the details when you move the mouse over the question mark.").show();
|
||||
|
||||
|
@ -75,7 +75,7 @@ createOffer.advancedBox.currency=Currency:
|
||||
createOffer.advancedBox.county=Payments account country:
|
||||
createOffer.advancedBox.info=Your trading partners must fulfill your offer restrictions. You can edit the accepted countries, languages and arbitrators in the settings. The payments account details are used from your current selected payments account (if you have multiple payments accounts).
|
||||
|
||||
createOffer.success.headline=Your offer has been published to the offerbook.
|
||||
createOffer.success.headline=Your offer has been published to the P2P network.
|
||||
createOffer.success.info=You can manage your open offers in the \"Portfolio\" screen under \"Open offers\".
|
||||
|
||||
createOffer.error.message=An error occurred when placing the offer.\n\n{0}
|
||||
|
@ -18,50 +18,23 @@
|
||||
<logger name="io.bitsquare.p2p.network.NetworkNode" level="TRACE"/>-->
|
||||
|
||||
|
||||
<logger name="com.msopentech.thali.toronionproxy.OnionProxyManagerEventHandler" level="WARN"/>
|
||||
|
||||
<logger name="io.bitsquare.btc.AddressBasedCoinSelector" level="WARN"/>
|
||||
<logger name="io.bitsquare.storage.Storage" level="WARN"/>
|
||||
|
||||
<logger name="io.bitsquare.gui.util.Profiler" level="ERROR"/>
|
||||
<logger name="io.bitsquare.locale.BSResources" level="ERROR"/>
|
||||
<logger name="io.bitsquare.temp.storage.RemoteStorage" level="WARN"/>
|
||||
<logger name="io.bitsquare.storage.FileManager" level="WARN"/>
|
||||
<!-- <logger name="com.msopentech.thali.toronionproxy.OnionProxyManagerEventHandler" level="WARN"/>
|
||||
|
||||
<logger name="io.bitsquare.btc.AddressBasedCoinSelector" level="WARN"/>
|
||||
<logger name="io.bitsquare.storage.Storage" level="WARN"/>
|
||||
|
||||
<logger name="io.bitsquare.gui.util.Profiler" level="ERROR"/>
|
||||
<logger name="io.bitsquare.locale.BSResources" level="ERROR"/>
|
||||
<logger name="io.bitsquare.temp.storage.RemoteStorage" level="WARN"/>
|
||||
<logger name="io.bitsquare.storage.FileManager" level="WARN"/>
|
||||
|
||||
<logger name="org.bitcoinj" level="WARN"/>
|
||||
|
||||
<logger name="org.bitcoinj.core.BitcoinSerializer" level="WARN"/>
|
||||
<logger name="org.bitcoinj.core.Peer" level="WARN"/>
|
||||
<logger name="org.bitcoinj.core.HeadersMessage" level="WARN"/>
|
||||
<logger name="org.bitcoinj.core.AbstractBlockChain" level="ERROR"/>-->
|
||||
|
||||
<logger name="org.bitcoinj" level="WARN"/>
|
||||
|
||||
<logger name="org.bitcoinj.core.BitcoinSerializer" level="WARN"/>
|
||||
<logger name="org.bitcoinj.core.Peer" level="WARN"/>
|
||||
<logger name="org.bitcoinj.core.HeadersMessage" level="WARN"/>
|
||||
<logger name="org.bitcoinj.core.AbstractBlockChain" level="ERROR"/>
|
||||
|
||||
<!--
|
||||
<logger name="io.netty" level="OFF"/>
|
||||
<logger name="org.bitcoinj.core.BitcoinSerializer" level="ERROR"/>
|
||||
<logger name="org.bitcoinj.core.Peer" level="ERROR"/>-->
|
||||
|
||||
|
||||
<logger name="io.netty.util" level="WARN"/>
|
||||
<logger name="io.netty.channel" level="WARN"/>
|
||||
<logger name="io.netty.buffer" level="WARN"/>-->
|
||||
|
||||
|
||||
<!-- <logger name="org.bitcoinj.core.BitcoinSerializer" level="WARN"/>
|
||||
<logger name="org.bitcoinj.core.AbstractBlockChain" level="WARN"/>
|
||||
<logger name="org.bitcoinj.wallet.DeterministicKeyChain" level="WARN"/>-->
|
||||
<!-- <logger name="io.bitsquare.btc.WalletService" level="WARN"/>-->
|
||||
|
||||
<!--
|
||||
<logger name="org.bitcoinj.core.Wallet" level="OFF"/>
|
||||
<logger name="org.bitcoinj.core.MemoryPool" level="OFF"/>
|
||||
<logger name="org.bitcoinj.net.discovery.DnsDiscovery" level="OFF"/>
|
||||
<logger name="org.bitcoinj.core.DownloadListener" level="OFF"/>
|
||||
<logger name="org.bitcoinj.core.TransactionOutput" level="OFF"/>
|
||||
<logger name="org.bitcoinj.core.BitcoinSerializer" level="OFF"/>
|
||||
<logger name="org.bitcoinj.core.Peer" level="OFF"/>
|
||||
<logger name="org.bitcoinj.core.PeerGroup" level="OFF"/>
|
||||
<logger name="org.bitcoinj.core.PeerSocketHandler" level="OFF"/>
|
||||
<logger name="org.bitcoinj.net.NioClientManager" level="OFF"/>
|
||||
<logger name="org.bitcoinj.net.ConnectionHandler" level="OFF"/>
|
||||
-->
|
||||
</configuration>
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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<Connection> 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<Connection> future = networkNode.sendMessage(peerAddress, getPeersAuthRequest);
|
||||
log.trace("Sent GetPeersAuthRequest {} to {}", getPeersAuthRequest, peerAddress);
|
||||
Futures.addCallback(future, new FutureCallback<Connection>() {
|
||||
@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<Connection> future = networkNode.sendMessage(peerAddress, getPeersAuthRequest);
|
||||
log.trace("Sent GetPeersAuthRequest {} to {}", getPeersAuthRequest, peerAddress);
|
||||
Futures.addCallback(future, new FutureCallback<Connection>() {
|
||||
@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<Connection> 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<Connection> future = networkNode.sendMessage(peerAddress, getPeersAuthResponse);
|
||||
log.trace("Sent GetPeersAuthResponse {} to {}", getPeersAuthResponse, peerAddress);
|
||||
// now we add the reported peers to our own set
|
||||
HashSet<ReportedPeer> reportedPeers = getPeersAuthRequest.reportedPeers;
|
||||
log.trace("Received reported peers: " + reportedPeers);
|
||||
peerGroup.addToReportedPeers(reportedPeers, connection);
|
||||
|
||||
// now we add the reported peers to our own set
|
||||
HashSet<ReportedPeer> reportedPeers = getPeersAuthRequest.reportedPeers;
|
||||
Futures.addCallback(future, new FutureCallback<Connection>() {
|
||||
@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<ReportedPeer> reportedPeers = getPeersAuthResponse.reportedPeers;
|
||||
log.trace("Received reported peers: " + reportedPeers);
|
||||
peerGroup.addToReportedPeers(reportedPeers, connection);
|
||||
|
||||
Futures.addCallback(future, new FutureCallback<Connection>() {
|
||||
@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<ReportedPeer> 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<Connection> requestAuthentication(Address peerAddress) {
|
||||
Log.traceCall();
|
||||
public SettableFuture<Connection> requestAuthentication() {
|
||||
Log.traceCall("peerAddress " + peerAddress);
|
||||
// Requesting peer
|
||||
|
||||
init();
|
||||
|
||||
AuthenticationRequest authenticationRequest = new AuthenticationRequest(myAddress, getAndSetNonce());
|
||||
SettableFuture<Connection> future = networkNode.sendMessage(peerAddress, authenticationRequest);
|
||||
Futures.addCallback(future, new FutureCallback<Connection>() {
|
||||
@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<Connection> respondToAuthenticationRequest(AuthenticationRequest authenticationRequest, Connection connection) {
|
||||
Log.traceCall();
|
||||
public SettableFuture<Connection> 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;
|
||||
}
|
||||
}
|
||||
|
@ -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<Connection> future = authenticationHandshake.respondToAuthenticationRequest(message, connection);
|
||||
Futures.addCallback(future, new FutureCallback<Connection>() {
|
||||
@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<Connection> future = authenticationHandshake.respondToAuthenticationRequest(message, connection);
|
||||
Futures.addCallback(future, new FutureCallback<Connection>() {
|
||||
@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<Connection> future = authenticationHandshake.requestAuthentication(peerAddress);
|
||||
SettableFuture<Connection> future = authenticationHandshake.requestAuthentication();
|
||||
Futures.addCallback(future, new FutureCallback<Connection>() {
|
||||
@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<Tuple2<Address, Set<Address>>> 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<Connection> future = authenticationHandshake.requestAuthentication(reportedPeerAddress);
|
||||
SettableFuture<Connection> future = authenticationHandshake.requestAuthentication();
|
||||
Futures.addCallback(future, new FutureCallback<Connection>() {
|
||||
@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<Connection> future = authenticationHandshake.requestAuthentication(peerAddress);
|
||||
SettableFuture<Connection> future = authenticationHandshake.requestAuthentication();
|
||||
Futures.addCallback(future, new FutureCallback<Connection>() {
|
||||
@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<Address, ReportedPeer> reportedPeersMap = new HashMap<>();
|
||||
@ -750,6 +785,7 @@ public class PeerGroup implements MessageListener, ConnectionListener {
|
||||
private Optional<Tuple2<ReportedPeer, Set<ReportedPeer>>> getReportedPeerAndRemainingSet(Set<ReportedPeer> remainingReportedPeers) {
|
||||
Log.traceCall();
|
||||
List<ReportedPeer> 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<Tuple2<Address, Set<Address>>> getRandomNotAuthPeerAndRemainingSet(Set<Address> remainingAddresses) {
|
||||
Log.traceCall();
|
||||
List<Address> list = new ArrayList<>(remainingAddresses);
|
||||
list.remove(getMyAddress());
|
||||
authenticatedPeers.values().stream().forEach(e -> list.remove(e.address));
|
||||
if (!list.isEmpty()) {
|
||||
Address item = getAndRemoveRandomAddress(list);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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<ReportedPeer> reportedPeers;
|
||||
|
||||
public GetPeersAuthRequest(Address address, long responderNonce, HashSet<ReportedPeer> reportedPeers) {
|
||||
this.address = address;
|
||||
super(address);
|
||||
this.responderNonce = responderNonce;
|
||||
this.reportedPeers = reportedPeers;
|
||||
}
|
||||
|
@ -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<ReportedPeer> reportedPeers;
|
||||
|
||||
public GetPeersAuthResponse(Address address, HashSet<ReportedPeer> reportedPeers) {
|
||||
this.address = address;
|
||||
super(address);
|
||||
this.reportedPeers = reportedPeers;
|
||||
}
|
||||
|
||||
|
@ -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<Address> 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());
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user