diff --git a/src/main/java/eu/hansolo/enzo/notification/Notification.java b/src/main/java/eu/hansolo/enzo/notification/Notification.java index 4b5901f7f0..68902668b3 100644 --- a/src/main/java/eu/hansolo/enzo/notification/Notification.java +++ b/src/main/java/eu/hansolo/enzo/notification/Notification.java @@ -460,7 +460,7 @@ public class Notification { return onNotificationPressedProperty().get(); } - private ObjectProperty> onNotificationPressed = new + private final ObjectProperty> onNotificationPressed = new ObjectPropertyBase>() { @Override public Object getBean() { @@ -485,7 +485,7 @@ public class Notification { return onShowNotificationProperty().get(); } - private ObjectProperty> onShowNotification = new + private final ObjectProperty> onShowNotification = new ObjectPropertyBase>() { @Override public Object getBean() { @@ -510,7 +510,7 @@ public class Notification { return onHideNotificationProperty().get(); } - private ObjectProperty> onHideNotification = new + private final ObjectProperty> onHideNotification = new ObjectPropertyBase>() { @Override public Object getBean() { diff --git a/src/main/java/io/bitsquare/AbstractBitsquareModule.java b/src/main/java/io/bitsquare/AbstractBitsquareModule.java index 72c51ef129..46a6f88c98 100644 --- a/src/main/java/io/bitsquare/AbstractBitsquareModule.java +++ b/src/main/java/io/bitsquare/AbstractBitsquareModule.java @@ -31,7 +31,7 @@ public abstract class AbstractBitsquareModule extends AbstractModule { private final Set modules = Sets.newHashSet(); - public AbstractBitsquareModule(Properties properties) { + protected AbstractBitsquareModule(Properties properties) { this.properties = properties; } diff --git a/src/main/java/io/bitsquare/app/ArgumentParser.java b/src/main/java/io/bitsquare/app/ArgumentParser.java index 2507017c4c..c2a59f7943 100644 --- a/src/main/java/io/bitsquare/app/ArgumentParser.java +++ b/src/main/java/io/bitsquare/app/ArgumentParser.java @@ -17,41 +17,37 @@ package io.bitsquare.app; +import io.bitsquare.network.BootstrapNodes; +import io.bitsquare.network.Node; + import net.sourceforge.argparse4j.ArgumentParsers; import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.inf.Namespace; -/* -optional arguments: - -h, --help show this help message and exit - -d PEERID, --peerid PEERID Seed peer ID. (default: digitalocean1.bitsquare.io) - -p PORT, --port PORT IP port to listen on. (default: 5000) - -i INTERFACE, --interface INTERFACE Network interface to listen on. - -n NAME, --name NAME Append name to application name. - */ public class ArgumentParser { - public static String PEER_ID_FLAG = "peerid"; - public static String PORT_FLAG = "port"; - public static Integer PORT_DEFAULT = 5000; - public static String INFHINT_FLAG = "interface"; - public static String NAME_FLAG = "name"; + public static final String PEER_ID_FLAG = "peerid"; + public static final String PORT_FLAG = "port"; + public static final String INTERFACE_HINT_FLAG = "interface"; + public static final String NAME_FLAG = "name"; + public static final String PEER_ID_DEFAULT = BootstrapNodes.DIGITAL_OCEAN_1.getId(); private final net.sourceforge.argparse4j.inf.ArgumentParser parser; public ArgumentParser() { parser = ArgumentParsers.newArgumentParser("Bitsquare") .defaultHelp(true) - .description("Bitsquare - The decentralized bitcoin exchange."); + .description("Bitsquare - The decentralized bitcoin exchange"); parser.addArgument("-d", "--" + PEER_ID_FLAG) - .help("Seed peer ID."); + .setDefault(PEER_ID_DEFAULT) + .help("Seed peer ID"); parser.addArgument("-p", "--" + PORT_FLAG) - .setDefault(PORT_DEFAULT) - .help("IP port to listen on."); - parser.addArgument("-i", "--" + INFHINT_FLAG) - .help("Network interface to listen on."); + .setDefault(Node.DEFAULT_PORT) + .help("Port to listen on"); + parser.addArgument("-i", "--" + INTERFACE_HINT_FLAG) + .help("Network interface to listen on"); parser.addArgument("-n", "--" + NAME_FLAG) - .help("Append name to application name."); + .help("Name to append name to default application name"); } public Namespace parseArgs(String... args) { diff --git a/src/main/java/io/bitsquare/app/cli/SeedNode.java b/src/main/java/io/bitsquare/app/cli/SeedNode.java index 01517108e6..735b986ca6 100644 --- a/src/main/java/io/bitsquare/app/cli/SeedNode.java +++ b/src/main/java/io/bitsquare/app/cli/SeedNode.java @@ -21,7 +21,7 @@ import io.bitsquare.app.ArgumentParser; import io.bitsquare.msg.actor.DHTManager; import io.bitsquare.msg.actor.command.InitializePeer; import io.bitsquare.msg.actor.event.PeerInitialized; -import io.bitsquare.network.BootstrapNode; +import io.bitsquare.network.BootstrapNodes; import io.bitsquare.network.Node; import java.net.UnknownHostException; @@ -52,19 +52,17 @@ public class SeedNode { ArgumentParser parser = new ArgumentParser(); Namespace namespace = parser.parseArgs(args); - if (namespace.getString(ArgumentParser.INFHINT_FLAG) != null) { - interfaceHint = namespace.getString(ArgumentParser.INFHINT_FLAG); - } + if (namespace.getString(ArgumentParser.INTERFACE_HINT_FLAG) != null) + interfaceHint = namespace.getString(ArgumentParser.INTERFACE_HINT_FLAG); int serverPort = Integer.valueOf(namespace.getString(ArgumentParser.PORT_FLAG)); - - String seedID = BootstrapNode.LOCAL_HOST.getId(); + String seedID = BootstrapNodes.LOCALHOST.getId(); if (namespace.getString(ArgumentParser.PEER_ID_FLAG) != null) { seedID = namespace.getString(ArgumentParser.PEER_ID_FLAG); } final Set peerAddresses = new HashSet<>(); - for (Node node : BootstrapNode.values()) { + for (Node node : BootstrapNodes.all()) { if (!node.getId().equals(seedID)) { try { peerAddresses.add(new PeerAddress(Number160.createHash(node.getId()), node.getIp(), @@ -81,14 +79,15 @@ public class SeedNode { inbox.send(seedNode, new InitializePeer(Number160.createHash(seedID), serverPort, interfaceHint, peerAddresses)); + final String _seedID = seedID; Thread seedNodeThread = new Thread(() -> { Boolean quit = false; while (!quit) { try { Object m = inbox.receive(FiniteDuration.create(5L, "seconds")); if (m instanceof PeerInitialized) { - log.debug("Seed Peer Initialized on port " + ((PeerInitialized) m).getPort - ()); + log.debug("Seed Peer with ID " + _seedID + + " initialized on port " + ((PeerInitialized) m).getPort()); } } catch (Exception e) { if (!(e instanceof TimeoutException)) { diff --git a/src/main/java/io/bitsquare/btc/BitcoinModule.java b/src/main/java/io/bitsquare/btc/BitcoinModule.java index a9601b4adc..c08f2eb562 100644 --- a/src/main/java/io/bitsquare/btc/BitcoinModule.java +++ b/src/main/java/io/bitsquare/btc/BitcoinModule.java @@ -30,15 +30,17 @@ import java.util.Properties; public class BitcoinModule extends AbstractBitsquareModule { - private final BitcoinNetwork defaultNetwork; + private static final BitcoinNetwork DEFAULT_NETWORK = BitcoinNetwork.REGTEST; + + private final BitcoinNetwork network; public BitcoinModule(Properties properties) { - this(properties, BitcoinNetwork.REGTEST); + this(properties, DEFAULT_NETWORK); } - public BitcoinModule(Properties properties, BitcoinNetwork defaultNetwork) { + public BitcoinModule(Properties properties, BitcoinNetwork network) { super(properties); - this.defaultNetwork = defaultNetwork; + this.network = network; } @Override @@ -55,7 +57,7 @@ public class BitcoinModule extends AbstractBitsquareModule { } private NetworkParameters network() { - String networkName = properties.getProperty("networkType", defaultNetwork.name()); + String networkName = properties.getProperty("networkType", network.name()); switch (BitcoinNetwork.valueOf(networkName.toUpperCase())) { case MAINNET: diff --git a/src/main/java/io/bitsquare/btc/BitcoinNetwork.java b/src/main/java/io/bitsquare/btc/BitcoinNetwork.java index d0a1fa2007..444b2a7bea 100644 --- a/src/main/java/io/bitsquare/btc/BitcoinNetwork.java +++ b/src/main/java/io/bitsquare/btc/BitcoinNetwork.java @@ -18,5 +18,5 @@ package io.bitsquare.btc; public enum BitcoinNetwork { - MAINNET, TESTNET, REGTEST; + MAINNET, TESTNET, REGTEST } diff --git a/src/main/java/io/bitsquare/btc/WalletFacade.java b/src/main/java/io/bitsquare/btc/WalletFacade.java index 7ee01fb165..2caff81328 100644 --- a/src/main/java/io/bitsquare/btc/WalletFacade.java +++ b/src/main/java/io/bitsquare/btc/WalletFacade.java @@ -77,6 +77,8 @@ import javax.inject.Named; import javafx.application.Platform; import javafx.util.Pair; +import org.jetbrains.annotations.NotNull; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -186,7 +188,7 @@ public class WalletFacade { walletAppKit.addListener(new Service.Listener() { @Override - public void failed(Service.State from, Throwable failure) { + public void failed(@NotNull Service.State from, @NotNull Throwable failure) { walletAppKit = null; // TODO show error popup //crashAlert(failure); diff --git a/src/main/java/io/bitsquare/gui/SystemTray.java b/src/main/java/io/bitsquare/gui/SystemTray.java index fc523eda6d..063139a146 100644 --- a/src/main/java/io/bitsquare/gui/SystemTray.java +++ b/src/main/java/io/bitsquare/gui/SystemTray.java @@ -38,8 +38,8 @@ public class SystemTray { private static final String ICON_HI_RES = "/images/system_tray_icon@2x.png"; private static final String ICON_LO_RES = "/images/system_tray_icon.png"; - public static final String SHOW_WINDOW_LABEL = "Show exchange window"; - public static final String HIDE_WINDOW_LABEL = "Hide exchange window"; + private static final String SHOW_WINDOW_LABEL = "Show exchange window"; + private static final String HIDE_WINDOW_LABEL = "Hide exchange window"; private final Stage stage; private final Runnable onExit; diff --git a/src/main/java/io/bitsquare/gui/main/MainModel.java b/src/main/java/io/bitsquare/gui/main/MainModel.java index de6a07ce78..2ccec1f9b2 100644 --- a/src/main/java/io/bitsquare/gui/main/MainModel.java +++ b/src/main/java/io/bitsquare/gui/main/MainModel.java @@ -23,6 +23,7 @@ import io.bitsquare.gui.UIModel; import io.bitsquare.gui.util.Profiler; import io.bitsquare.msg.MessageFacade; import io.bitsquare.msg.listeners.BootstrapListener; +import io.bitsquare.network.BootstrapState; import io.bitsquare.persistence.Persistence; import io.bitsquare.trade.Trade; import io.bitsquare.trade.TradeManager; @@ -44,6 +45,8 @@ import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.property.SimpleIntegerProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; import javafx.collections.MapChangeListener; import javafx.collections.ObservableList; @@ -62,11 +65,13 @@ class MainModel extends UIModel { private boolean messageFacadeInited; private boolean walletFacadeInited; + private boolean facadesInitialised; final BooleanProperty backendReady = new SimpleBooleanProperty(); final DoubleProperty networkSyncProgress = new SimpleDoubleProperty(-1); final IntegerProperty numPendingTrades = new SimpleIntegerProperty(0); - private boolean facadesInitialised; + final StringProperty bootstrapState = new SimpleStringProperty(); + /////////////////////////////////////////////////////////////////////////////////////////// // Constructor @@ -122,6 +127,11 @@ class MainModel extends UIModel { public void onFailed(Throwable throwable) { log.error(throwable.toString()); } + + @Override + public void onBootstrapStateChanged(BootstrapState bootstrapState) { + MainModel.this.bootstrapState.set(bootstrapState.getMessage()); + } }); Profiler.printMsgWithTime("MainModel.initFacades"); diff --git a/src/main/java/io/bitsquare/gui/main/MainPM.java b/src/main/java/io/bitsquare/gui/main/MainPM.java index b4ad8f0dae..f2059b6867 100644 --- a/src/main/java/io/bitsquare/gui/main/MainPM.java +++ b/src/main/java/io/bitsquare/gui/main/MainPM.java @@ -42,15 +42,17 @@ import org.slf4j.LoggerFactory; class MainPM extends PresentationModel { private static final Logger log = LoggerFactory.getLogger(MainPM.class); - private BSFormatter formatter; + private final BSFormatter formatter; final BooleanProperty backendReady = new SimpleBooleanProperty(); final StringProperty bankAccountsComboBoxPrompt = new SimpleStringProperty(); final BooleanProperty bankAccountsComboBoxDisable = new SimpleBooleanProperty(); - final StringProperty splashScreenInfoText = new SimpleStringProperty(); + final StringProperty bootstrapState = new SimpleStringProperty(); + final StringProperty bitcoinSyncState = new SimpleStringProperty("Initializing"); final IntegerProperty numPendingTrades = new SimpleIntegerProperty(); final DoubleProperty networkSyncProgress = new SimpleDoubleProperty(); + /////////////////////////////////////////////////////////////////////////////////////////// // Constructor /////////////////////////////////////////////////////////////////////////////////////////// @@ -61,11 +63,11 @@ class MainPM extends PresentationModel { this.formatter = formatter; } - /////////////////////////////////////////////////////////////////////////////////////////// // Lifecycle /////////////////////////////////////////////////////////////////////////////////////////// + @SuppressWarnings("EmptyMethod") @Override public void initialize() { @@ -75,16 +77,13 @@ class MainPM extends PresentationModel { networkSyncProgress.bind(model.networkSyncProgress); numPendingTrades.bind(model.numPendingTrades); - model.networkSyncProgress.addListener((ov, oldValue, newValue) -> { - if ((double) newValue > 0.0) - splashScreenInfoText.set("Synchronise with network " + formatter.formatToPercent((double) - newValue)); - else if ((double) newValue == 1) - splashScreenInfoText.set("Synchronise with network completed."); - else - splashScreenInfoText.set("Synchronise with network..."); - }); - splashScreenInfoText.set("Synchronise with network..."); + model.bootstrapState.addListener((ov, oldValue, newValue) -> + bootstrapState.set("Connection to P2P network: " + newValue)); + + bootstrapState.set(model.bootstrapState.get()); + + model.networkSyncProgress.addListener((ov, oldValue, newValue) -> updateBitcoinSyncState((double) newValue)); + updateBitcoinSyncState(model.networkSyncProgress.get()); model.getBankAccounts().addListener((ListChangeListener) change -> { bankAccountsComboBoxDisable.set(change.getList().isEmpty()); @@ -145,4 +144,19 @@ class MainPM extends PresentationModel { }; } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + + private void updateBitcoinSyncState(double value) { + if (value > 0.0) + bitcoinSyncState.set("Synchronizing with bitcoin network: " + + formatter.formatToPercent(value)); + else if (value == 1) + bitcoinSyncState.set("Synchronizing with bitcoin network completed."); + else + bitcoinSyncState.set("Synchronizing with bitcoin network..."); + } + } diff --git a/src/main/java/io/bitsquare/gui/main/MainViewCB.java b/src/main/java/io/bitsquare/gui/main/MainViewCB.java index c83dd71f05..5c359a1a60 100644 --- a/src/main/java/io/bitsquare/gui/main/MainViewCB.java +++ b/src/main/java/io/bitsquare/gui/main/MainViewCB.java @@ -47,6 +47,7 @@ import javafx.scene.effect.*; import javafx.scene.image.*; import javafx.scene.layout.*; import javafx.scene.paint.*; +import javafx.scene.text.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -167,7 +168,7 @@ public class MainViewCB extends ViewCB { ((StackPane) root).getChildren().addAll(baseApplicationContainer, splashScreen); baseApplicationContainer.setCenter(getApplicationContainer()); - Platform.runLater(() -> onSplashScreenAdded()); + Platform.runLater(this::onSplashScreenAdded); } private void onSplashScreenAdded() { @@ -285,16 +286,35 @@ public class MainViewCB extends ViewCB { ImageView logo = new ImageView(); logo.setId("image-splash-logo"); - Label loadingLabel = new Label(); - loadingLabel.setAlignment(Pos.CENTER); - loadingLabel.setPadding(new Insets(60, 0, 0, 0)); - loadingLabel.textProperty().bind(presentationModel.splashScreenInfoText); + Label bitcoinSyncStateLabel = new Label(); + bitcoinSyncStateLabel.textProperty().bind(presentationModel.bitcoinSyncState); - ProgressBar progressBar = new ProgressBar(); - progressBar.setPrefWidth(240); - progressBar.progressProperty().bind(presentationModel.networkSyncProgress); + ProgressBar btcProgressIndicator = new ProgressBar(-1); + btcProgressIndicator.setPrefWidth(120); + btcProgressIndicator.progressProperty().bind(presentationModel.networkSyncProgress); - vBox.getChildren().addAll(logo, loadingLabel, progressBar); + HBox btcBox = new HBox(); + btcBox.setSpacing(10); + btcBox.setAlignment(Pos.CENTER); + btcBox.setPadding(new Insets(60, 0, 0, 0)); + btcBox.getChildren().addAll(bitcoinSyncStateLabel, btcProgressIndicator); + + Label bootstrapStateLabel = new Label(); + bootstrapStateLabel.setWrapText(true); + bootstrapStateLabel.setMaxWidth(500); + bootstrapStateLabel.setTextAlignment(TextAlignment.CENTER); + bootstrapStateLabel.textProperty().bind(presentationModel.bootstrapState); + + ProgressIndicator p2pProgressIndicator = new ProgressIndicator(-1); + p2pProgressIndicator.setMaxSize(24, 24); + + HBox p2pBox = new HBox(); + p2pBox.setSpacing(10); + p2pBox.setAlignment(Pos.CENTER); + p2pBox.setPadding(new Insets(10, 0, 0, 0)); + p2pBox.getChildren().addAll(bootstrapStateLabel, p2pProgressIndicator); + + vBox.getChildren().addAll(logo, btcBox, p2pBox); return vBox; } diff --git a/src/main/java/io/bitsquare/gui/main/account/arbitrator/browser/ArbitratorBrowserViewCB.java b/src/main/java/io/bitsquare/gui/main/account/arbitrator/browser/ArbitratorBrowserViewCB.java index 1c19de23bd..6e629f9a8c 100644 --- a/src/main/java/io/bitsquare/gui/main/account/arbitrator/browser/ArbitratorBrowserViewCB.java +++ b/src/main/java/io/bitsquare/gui/main/account/arbitrator/browser/ArbitratorBrowserViewCB.java @@ -53,7 +53,7 @@ public class ArbitratorBrowserViewCB extends CachedViewCB implements ArbitratorL private final Settings settings; private final Persistence persistence; - private MessageFacade messageFacade; + private final MessageFacade messageFacade; private final List allArbitrators = new ArrayList<>(); private Arbitrator currentArbitrator; diff --git a/src/main/java/io/bitsquare/gui/main/account/arbitrator/profile/ArbitratorProfileViewCB.java b/src/main/java/io/bitsquare/gui/main/account/arbitrator/profile/ArbitratorProfileViewCB.java index 60b476861a..af9dec5bc3 100644 --- a/src/main/java/io/bitsquare/gui/main/account/arbitrator/profile/ArbitratorProfileViewCB.java +++ b/src/main/java/io/bitsquare/gui/main/account/arbitrator/profile/ArbitratorProfileViewCB.java @@ -38,13 +38,13 @@ public class ArbitratorProfileViewCB extends CachedViewCB { private final Settings settings; private final Persistence persistence; - private BSFormatter formatter; + private final BSFormatter formatter; @FXML Label nameLabel; @FXML TextField nameTextField, languagesTextField, reputationTextField, - feeTextField, methodsTextField, - idVerificationsTextField, webPageTextField; + feeTextField, methodsTextField, passiveServiceFeeTextField, + idVerificationsTextField, webPageTextField, maxTradeVolumeTextField; @FXML TextArea descriptionTextArea; diff --git a/src/main/java/io/bitsquare/gui/main/account/arbitrator/registration/ArbitratorRegistrationViewCB.java b/src/main/java/io/bitsquare/gui/main/account/arbitrator/registration/ArbitratorRegistrationViewCB.java index 02339c8eef..f1442a02be 100644 --- a/src/main/java/io/bitsquare/gui/main/account/arbitrator/registration/ArbitratorRegistrationViewCB.java +++ b/src/main/java/io/bitsquare/gui/main/account/arbitrator/registration/ArbitratorRegistrationViewCB.java @@ -68,7 +68,7 @@ public class ArbitratorRegistrationViewCB extends CachedViewCB { private final WalletFacade walletFacade; private final MessageFacade messageFacade; private final User user; - private BSFormatter formatter; + private final BSFormatter formatter; private Arbitrator arbitrator = new Arbitrator(); private boolean isEditMode; diff --git a/src/main/java/io/bitsquare/gui/main/account/content/fiat/FiatAccountViewCB.java b/src/main/java/io/bitsquare/gui/main/account/content/fiat/FiatAccountViewCB.java index 77e709f6e4..fcf01d6ada 100644 --- a/src/main/java/io/bitsquare/gui/main/account/content/fiat/FiatAccountViewCB.java +++ b/src/main/java/io/bitsquare/gui/main/account/content/fiat/FiatAccountViewCB.java @@ -68,7 +68,7 @@ public class FiatAccountViewCB extends CachedViewCB implements Co @FXML ComboBox selectionComboBox; @FXML ComboBox typesComboBox; @FXML ComboBox currencyComboBox; - private OverlayManager overlayManager; + private final OverlayManager overlayManager; /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/main/java/io/bitsquare/gui/main/account/content/irc/IrcAccountModel.java b/src/main/java/io/bitsquare/gui/main/account/content/irc/IrcAccountModel.java index 427ec916c9..231ff0f3f0 100644 --- a/src/main/java/io/bitsquare/gui/main/account/content/irc/IrcAccountModel.java +++ b/src/main/java/io/bitsquare/gui/main/account/content/irc/IrcAccountModel.java @@ -59,7 +59,7 @@ class IrcAccountModel extends UIModel { private final User user; private final Settings settings; - private MessageFacade messageFacade; + private final MessageFacade messageFacade; private final Persistence persistence; final StringProperty nickName = new SimpleStringProperty(); diff --git a/src/main/java/io/bitsquare/gui/main/account/content/irc/IrcAccountViewCB.java b/src/main/java/io/bitsquare/gui/main/account/content/irc/IrcAccountViewCB.java index a9f1e57bc8..22682240f7 100644 --- a/src/main/java/io/bitsquare/gui/main/account/content/irc/IrcAccountViewCB.java +++ b/src/main/java/io/bitsquare/gui/main/account/content/irc/IrcAccountViewCB.java @@ -123,17 +123,15 @@ public class IrcAccountViewCB extends CachedViewCB implements Cont setupListeners(); setupBindings(); - Platform.runLater(() -> { - Popups.openInfoPopup("Demo setup for simulating the banking transfer", - "For demo purposes we use a special setup so that users can simulate the banking transfer when " + - "meeting in an IRC chat room.\n" + - "You need to define your IRC nickname and later in the trade process you can find your " + - "trading partner with his IRC nickname in the chat room and simulate the bank transfer " + - "activities, which are:\n\n" + - "1. Bitcoin buyer indicates that he has started the bank transfer.\n\n" + - "2. Bitcoin seller confirms that he has received the national currency from the " + - "bank transfer."); - }); + Platform.runLater(() -> Popups.openInfoPopup("Demo setup for simulating the banking transfer", + "For demo purposes we use a special setup so that users can simulate the banking transfer when " + + "meeting in an IRC chat room.\n" + + "You need to define your IRC nickname and later in the trade process you can find your " + + "trading partner with his IRC nickname in the chat room and simulate the bank transfer " + + "activities, which are:\n\n" + + "1. Bitcoin buyer indicates that he has started the bank transfer.\n\n" + + "2. Bitcoin seller confirms that he has received the national currency from the " + + "bank transfer.")); } @SuppressWarnings("EmptyMethod") diff --git a/src/main/java/io/bitsquare/gui/main/account/content/registration/RegistrationPM.java b/src/main/java/io/bitsquare/gui/main/account/content/registration/RegistrationPM.java index 56968d9e09..449af1ee4c 100644 --- a/src/main/java/io/bitsquare/gui/main/account/content/registration/RegistrationPM.java +++ b/src/main/java/io/bitsquare/gui/main/account/content/registration/RegistrationPM.java @@ -47,7 +47,7 @@ class RegistrationPM extends PresentationModel { // That is needed for the addressTextField final ObjectProperty
address = new SimpleObjectProperty<>(); - private BSFormatter formatter; + private final BSFormatter formatter; /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/main/java/io/bitsquare/gui/main/account/content/seedwords/SeedWordsPM.java b/src/main/java/io/bitsquare/gui/main/account/content/seedwords/SeedWordsPM.java index 9cbf57a031..3ada05f144 100644 --- a/src/main/java/io/bitsquare/gui/main/account/content/seedwords/SeedWordsPM.java +++ b/src/main/java/io/bitsquare/gui/main/account/content/seedwords/SeedWordsPM.java @@ -32,7 +32,7 @@ class SeedWordsPM extends PresentationModel { private static final Logger log = LoggerFactory.getLogger(SeedWordsPM.class); final StringProperty seedWords = new SimpleStringProperty(); - private BSFormatter formatter; + private final BSFormatter formatter; /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/main/java/io/bitsquare/gui/main/account/settings/AccountSettingsViewCB.java b/src/main/java/io/bitsquare/gui/main/account/settings/AccountSettingsViewCB.java index 5058c9f345..71e3c4db39 100644 --- a/src/main/java/io/bitsquare/gui/main/account/settings/AccountSettingsViewCB.java +++ b/src/main/java/io/bitsquare/gui/main/account/settings/AccountSettingsViewCB.java @@ -52,8 +52,8 @@ public class AccountSettingsViewCB extends CachedViewCB { private final Navigation navigation; private Navigation.Listener listener; - @FXML VBox leftVBox; - @FXML AnchorPane content; + @FXML private VBox leftVBox; + @FXML private AnchorPane content; /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/main/java/io/bitsquare/gui/main/funds/transactions/TransactionsViewCB.java b/src/main/java/io/bitsquare/gui/main/funds/transactions/TransactionsViewCB.java index 1d8271c81d..f3039a414c 100644 --- a/src/main/java/io/bitsquare/gui/main/funds/transactions/TransactionsViewCB.java +++ b/src/main/java/io/bitsquare/gui/main/funds/transactions/TransactionsViewCB.java @@ -46,7 +46,7 @@ public class TransactionsViewCB extends CachedViewCB { private static final Logger log = LoggerFactory.getLogger(TransactionsViewCB.class); private final WalletFacade walletFacade; - private BSFormatter formatter; + private final BSFormatter formatter; private ObservableList transactionsListItems; @FXML TableView table; diff --git a/src/main/java/io/bitsquare/gui/main/funds/withdrawal/WithdrawalListItem.java b/src/main/java/io/bitsquare/gui/main/funds/withdrawal/WithdrawalListItem.java index 30f24c2381..c2aa8edc2f 100644 --- a/src/main/java/io/bitsquare/gui/main/funds/withdrawal/WithdrawalListItem.java +++ b/src/main/java/io/bitsquare/gui/main/funds/withdrawal/WithdrawalListItem.java @@ -43,7 +43,7 @@ public class WithdrawalListItem { private final AddressEntry addressEntry; private final WalletFacade walletFacade; - private BSFormatter formatter; + private final BSFormatter formatter; private final AddressConfidenceListener confidenceListener; private final ConfidenceProgressIndicator progressIndicator; diff --git a/src/main/java/io/bitsquare/gui/main/funds/withdrawal/WithdrawalViewCB.java b/src/main/java/io/bitsquare/gui/main/funds/withdrawal/WithdrawalViewCB.java index 2813dbacaf..9d07d2b513 100644 --- a/src/main/java/io/bitsquare/gui/main/funds/withdrawal/WithdrawalViewCB.java +++ b/src/main/java/io/bitsquare/gui/main/funds/withdrawal/WithdrawalViewCB.java @@ -64,7 +64,7 @@ public class WithdrawalViewCB extends CachedViewCB { private final WalletFacade walletFacade; - private BSFormatter formatter; + private final BSFormatter formatter; private final ObservableList addressList = FXCollections.observableArrayList(); @FXML TableView table; diff --git a/src/main/java/io/bitsquare/gui/main/portfolio/closed/ClosedTradesModel.java b/src/main/java/io/bitsquare/gui/main/portfolio/closed/ClosedTradesModel.java index 453884402b..db32851af5 100644 --- a/src/main/java/io/bitsquare/gui/main/portfolio/closed/ClosedTradesModel.java +++ b/src/main/java/io/bitsquare/gui/main/portfolio/closed/ClosedTradesModel.java @@ -37,7 +37,7 @@ class ClosedTradesModel extends UIModel { private static final Logger log = LoggerFactory.getLogger(ClosedTradesModel.class); private final TradeManager tradeManager; - private User user; + private final User user; private final ObservableList list = FXCollections.observableArrayList(); private MapChangeListener mapChangeListener; diff --git a/src/main/java/io/bitsquare/gui/main/portfolio/offer/OffersModel.java b/src/main/java/io/bitsquare/gui/main/portfolio/offer/OffersModel.java index 2e067cec85..450706e62c 100644 --- a/src/main/java/io/bitsquare/gui/main/portfolio/offer/OffersModel.java +++ b/src/main/java/io/bitsquare/gui/main/portfolio/offer/OffersModel.java @@ -38,7 +38,7 @@ class OffersModel extends UIModel { private static final Logger log = LoggerFactory.getLogger(OffersModel.class); private final TradeManager tradeManager; - private User user; + private final User user; private final ObservableList list = FXCollections.observableArrayList(); private MapChangeListener offerMapChangeListener; diff --git a/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesModel.java b/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesModel.java index d78a34e3e7..ea07d8f00b 100644 --- a/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesModel.java +++ b/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesModel.java @@ -226,10 +226,7 @@ class PendingTradesModel extends UIModel { String fromAddress = addressEntry.getAddressString(); try { walletFacade.sendFunds(fromAddress, toAddress, getAmountToWithdraw(), callback); - } catch (AddressFormatException e) { - e.printStackTrace(); - log.error(e.getMessage()); - } catch (InsufficientMoneyException e) { + } catch (AddressFormatException | InsufficientMoneyException e) { e.printStackTrace(); log.error(e.getMessage()); } diff --git a/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesPM.java b/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesPM.java index 32d8ff9a8c..5a9397fd9a 100644 --- a/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesPM.java +++ b/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesPM.java @@ -55,7 +55,7 @@ public class PendingTradesPM extends PresentationModel { private final BSFormatter formatter; private InvalidationListener stateChangeListener; - private BtcAddressValidator btcAddressValidator; + private final BtcAddressValidator btcAddressValidator; final StringProperty txId = new SimpleStringProperty(); final ObjectProperty state = new SimpleObjectProperty<>(); diff --git a/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesViewCB.java b/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesViewCB.java index a7a904f9d6..f3cf8ce05a 100644 --- a/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesViewCB.java +++ b/src/main/java/io/bitsquare/gui/main/portfolio/pending/PendingTradesViewCB.java @@ -61,7 +61,7 @@ public class PendingTradesViewCB extends CachedViewCB { private ChangeListener offererStateChangeListener; private ChangeListener takerStateChangeListener; private ChangeListener faultChangeListener; - private Navigation navigation; + private final Navigation navigation; @FXML ScrollPane scrollPane; @FXML GridPane gridPane; diff --git a/src/main/java/io/bitsquare/gui/main/trade/createoffer/CreateOfferModel.java b/src/main/java/io/bitsquare/gui/main/trade/createoffer/CreateOfferModel.java index b7bc9eb5d1..9eae9dc269 100644 --- a/src/main/java/io/bitsquare/gui/main/trade/createoffer/CreateOfferModel.java +++ b/src/main/java/io/bitsquare/gui/main/trade/createoffer/CreateOfferModel.java @@ -70,8 +70,8 @@ class CreateOfferModel extends UIModel { private final WalletFacade walletFacade; private final Settings settings; private final User user; - private Persistence persistence; - private BSFormatter formatter; + private final Persistence persistence; + private final BSFormatter formatter; private final String offerId; diff --git a/src/main/java/io/bitsquare/gui/main/trade/createoffer/CreateOfferPM.java b/src/main/java/io/bitsquare/gui/main/trade/createoffer/CreateOfferPM.java index c8dfecadab..6fed08d9c4 100644 --- a/src/main/java/io/bitsquare/gui/main/trade/createoffer/CreateOfferPM.java +++ b/src/main/java/io/bitsquare/gui/main/trade/createoffer/CreateOfferPM.java @@ -50,7 +50,7 @@ class CreateOfferPM extends PresentationModel { private static final Logger log = LoggerFactory.getLogger(CreateOfferPM.class); private final BtcValidator btcValidator; - private BSFormatter formatter; + private final BSFormatter formatter; private final FiatValidator fiatValidator; final StringProperty amount = new SimpleStringProperty(); diff --git a/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBook.java b/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBook.java index f9080354ff..0bbc0986c8 100644 --- a/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBook.java +++ b/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBook.java @@ -172,7 +172,7 @@ public class OfferBook { private void startPolling() { addListeners(); setBankAccount(user.getCurrentBankAccount()); - pollingTimer = Utilities.setInterval(1000, (animationTimer) -> { + pollingTimer = Utilities.setInterval(3000, (animationTimer) -> { offerRepository.requestInvalidationTimeStampFromDHT(fiatCode); return null; }); diff --git a/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookModel.java b/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookModel.java index f625a8a7c7..5d79bf4700 100644 --- a/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookModel.java +++ b/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookModel.java @@ -57,7 +57,7 @@ class OfferBookModel extends UIModel { private final User user; private final OfferBook offerBook; private final Settings settings; - private BSFormatter formatter; + private final BSFormatter formatter; private final TradeManager tradeManager; private final FilteredList filteredItems; diff --git a/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookPM.java b/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookPM.java index d15de26015..782fad8da2 100644 --- a/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookPM.java +++ b/src/main/java/io/bitsquare/gui/main/trade/offerbook/OfferBookPM.java @@ -42,7 +42,7 @@ class OfferBookPM extends PresentationModel { private static final Logger log = LoggerFactory.getLogger(OfferBookPM.class); private final OptionalBtcValidator optionalBtcValidator; - private BSFormatter formatter; + private final BSFormatter formatter; private final OptionalFiatValidator optionalFiatValidator; final StringProperty amount = new SimpleStringProperty(); diff --git a/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferModel.java b/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferModel.java index fc9196f9fa..cd7020b01f 100644 --- a/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferModel.java +++ b/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferModel.java @@ -57,7 +57,7 @@ class TakeOfferModel extends UIModel { private final TradeManager tradeManager; private final WalletFacade walletFacade; private final Settings settings; - private Persistence persistence; + private final Persistence persistence; private Offer offer; private AddressEntry addressEntry; diff --git a/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferPM.java b/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferPM.java index 931587ab89..0a8733adc8 100644 --- a/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferPM.java +++ b/src/main/java/io/bitsquare/gui/main/trade/takeoffer/TakeOfferPM.java @@ -65,7 +65,7 @@ class TakeOfferPM extends PresentationModel { final ObjectProperty
address = new SimpleObjectProperty<>(); private final BtcValidator btcValidator; - private BSFormatter formatter; + private final BSFormatter formatter; final StringProperty amount = new SimpleStringProperty(); final StringProperty volume = new SimpleStringProperty(); diff --git a/src/main/java/io/bitsquare/gui/util/validation/BtcAddressValidator.java b/src/main/java/io/bitsquare/gui/util/validation/BtcAddressValidator.java index 13e8055d6c..1a232a3e72 100644 --- a/src/main/java/io/bitsquare/gui/util/validation/BtcAddressValidator.java +++ b/src/main/java/io/bitsquare/gui/util/validation/BtcAddressValidator.java @@ -33,7 +33,7 @@ import org.slf4j.LoggerFactory; */ public final class BtcAddressValidator extends InputValidator { private static final Logger log = LoggerFactory.getLogger(BtcAddressValidator.class); - private NetworkParameters networkParameters; + private final NetworkParameters networkParameters; /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/main/java/io/bitsquare/msg/ActorService.java b/src/main/java/io/bitsquare/msg/ActorService.java index 46cdb686ca..e4f6ea4654 100644 --- a/src/main/java/io/bitsquare/msg/ActorService.java +++ b/src/main/java/io/bitsquare/msg/ActorService.java @@ -36,7 +36,7 @@ public abstract class ActorService extends Service { private final ActorSystem system; private final Inbox inbox; - private ActorSelection actor; + private final ActorSelection actor; private MessageHandler handler; @@ -71,12 +71,7 @@ public abstract class ActorService extends Service { if (result != null) { System.out.println(result.toString()); if (handler != null) { - Application.invokeLater(new Runnable() { - @Override - public void run() { - handler.handle(result); - } - }); + Application.invokeLater(() -> handler.handle(result)); } } } catch (Exception e) { diff --git a/src/main/java/io/bitsquare/msg/BootstrappedPeerFactory.java b/src/main/java/io/bitsquare/msg/BootstrappedPeerFactory.java index 0a3481fba0..df591d90b7 100644 --- a/src/main/java/io/bitsquare/msg/BootstrappedPeerFactory.java +++ b/src/main/java/io/bitsquare/msg/BootstrappedPeerFactory.java @@ -17,6 +17,7 @@ package io.bitsquare.msg; +import io.bitsquare.network.BootstrapState; import io.bitsquare.network.Node; import io.bitsquare.persistence.Persistence; @@ -32,13 +33,11 @@ import java.net.UnknownHostException; import java.security.KeyPair; -import javax.annotation.concurrent.Immutable; - import javax.inject.Inject; import javafx.application.Platform; -import javafx.beans.property.SimpleStringProperty; -import javafx.beans.property.StringProperty; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleObjectProperty; import net.tomp2p.dht.PeerBuilderDHT; import net.tomp2p.dht.PeerDHT; @@ -66,7 +65,6 @@ import org.slf4j.LoggerFactory; /** * Creates a DHT peer and bootstrap to the network via a seed node */ -@Immutable public class BootstrappedPeerFactory { private static final Logger log = LoggerFactory.getLogger(BootstrappedPeerFactory.class); @@ -76,7 +74,9 @@ public class BootstrappedPeerFactory { private final Persistence persistence; private final SettableFuture settableFuture = SettableFuture.create(); - public final StringProperty connectionState = new SimpleStringProperty(); + public final ObjectProperty bootstrapState = new SimpleObjectProperty<>(); + private Peer peer; + private PeerDHT peerDHT; /////////////////////////////////////////////////////////////////////////////////////////// @@ -109,8 +109,9 @@ public class BootstrappedPeerFactory { public ListenableFuture start(int port) { try { - Peer peer = new PeerBuilder(keyPair).ports(port).behindFirewall().start(); - PeerDHT peerDHT = new PeerBuilderDHT(peer).storageLayer(new StorageLayer(storage)).start(); + setState(BootstrapState.PEER_CREATION, "We create a P2P node."); + peer = new PeerBuilder(keyPair).ports(port).start(); + peerDHT = new PeerBuilderDHT(peer).storageLayer(new StorageLayer(storage)).start(); peer.peerBean().peerMap().addPeerMapChangeListener(new PeerMapChangeListener() { @Override @@ -147,29 +148,24 @@ public class BootstrappedPeerFactory { lastSuccessfulBootstrap = "default"; log.debug("lastSuccessfulBootstrap = " + lastSuccessfulBootstrap); - FutureDiscover futureDiscover; // just temporary while port forwarding is not working lastSuccessfulBootstrap = "default"; switch (lastSuccessfulBootstrap) { case "relay": - futureDiscover = peerDHT.peer().discover().peerAddress(getBootstrapAddress()).start(); - PeerNAT peerNAT = new PeerBuilderNAT(peerDHT.peer()).start(); - FutureNAT futureNAT = peerNAT.startSetupPortforwarding(futureDiscover); - bootstrapWithRelay(peerDHT, peerNAT, futureDiscover, futureNAT); + bootstrapWithRelay(); break; case "portForwarding": - futureDiscover = peerDHT.peer().discover().peerAddress(getBootstrapAddress()).start(); - tryPortForwarding(peerDHT, futureDiscover); + tryPortForwarding(); break; case "default": default: - discover(peerDHT); + discover(); break; } } catch (IOException e) { - setState("Cannot create peer with port: " + port + ". Exeption: " + e, false); + setState(BootstrapState.PEER_CREATION, "Cannot create peer with port: " + port + ". Exeption: " + e, false); settableFuture.setException(e); } @@ -177,28 +173,28 @@ public class BootstrappedPeerFactory { } // 1. Attempt: Try to discover our outside visible address - private void discover(PeerDHT peerDHT) { - FutureDiscover futureDiscover = peerDHT.peer().discover().peerAddress(getBootstrapAddress()).start(); + private void discover() { + setState(BootstrapState.DIRECT_INIT, "We are starting to bootstrap to a seed node."); + FutureDiscover futureDiscover = peer.discover().peerAddress(getBootstrapAddress()).start(); futureDiscover.addListener(new BaseFutureListener() { @Override public void operationComplete(BaseFuture future) throws Exception { if (future.isSuccess()) { - setState("We are visible to other peers: My address visible to " + - "the outside is " + futureDiscover.peerAddress()); + setState(BootstrapState.DIRECT_SUCCESS, "We are directly connected and visible to other peers."); persistence.write(BootstrappedPeerFactory.this, "lastSuccessfulBootstrap", "default"); settableFuture.set(peerDHT); } else { - setState("We are probably behind a NAT and not reachable to other peers. " + - "We try port forwarding as next step."); + setState(BootstrapState.DIRECT_NOT_SUCCEEDED, "We are probably behind a NAT and not reachable to " + + "other peers. We try to setup automatic port forwarding."); - tryPortForwarding(peerDHT, futureDiscover); + tryPortForwarding(); } } @Override public void exceptionCaught(Throwable t) throws Exception { - setState("Exception at discover: " + t.getMessage(), false); + setState(BootstrapState.DIRECT_FAILED, "Exception at discover: " + t.getMessage(), false); peerDHT.shutdown(); settableFuture.setException(t); } @@ -206,26 +202,30 @@ public class BootstrappedPeerFactory { } // 2. Attempt: Try to set up port forwarding with UPNP and NAT-PMP - private void tryPortForwarding(PeerDHT peerDHT, FutureDiscover futureDiscover) { - PeerNAT peerNAT = new PeerBuilderNAT(peerDHT.peer()).start(); + private void tryPortForwarding() { + setState(BootstrapState.NAT_INIT, "We are trying with automatic port forwarding."); + FutureDiscover futureDiscover = peer.discover().peerAddress(getBootstrapAddress()).start(); + PeerNAT peerNAT = new PeerBuilderNAT(peer).start(); FutureNAT futureNAT = peerNAT.startSetupPortforwarding(futureDiscover); futureNAT.addListener(new BaseFutureListener() { @Override public void operationComplete(BaseFuture future) throws Exception { if (future.isSuccess()) { - setState("Automatic port forwarding is setup. Address = " + futureNAT.peerAddress()); + setState(BootstrapState.NAT_SETUP_DONE, "Automatic port forwarding is setup. " + + "We need to do a discover process again."); // we need a second discover process - discoverAfterPortForwarding(peerDHT); + discoverAfterPortForwarding(); } else { - setState("Port forwarding has failed. We try to use a relay as next step."); - bootstrapWithRelay(peerDHT, peerNAT, futureDiscover, futureNAT); + setState(BootstrapState.NAT_NOT_SUCCEEDED, "Port forwarding has failed. " + + "We try to use a relay as next step."); + bootstrapWithRelay(); } } @Override public void exceptionCaught(Throwable t) throws Exception { - setState("Exception at port forwarding: " + t.getMessage(), false); + setState(BootstrapState.NAT_FAILED, "Exception at port forwarding: " + t.getMessage(), false); peerDHT.shutdown(); settableFuture.setException(t); } @@ -233,20 +233,19 @@ public class BootstrappedPeerFactory { } // Try to determine our outside visible address after port forwarding is setup - private void discoverAfterPortForwarding(PeerDHT peerDHT) { - FutureDiscover futureDiscover = peerDHT.peer().discover().peerAddress(getBootstrapAddress()).start(); + private void discoverAfterPortForwarding() { + FutureDiscover futureDiscover = peer.discover().peerAddress(getBootstrapAddress()).start(); futureDiscover.addListener(new BaseFutureListener() { @Override public void operationComplete(BaseFuture future) throws Exception { if (future.isSuccess()) { - setState("Discover with automatic port forwarding was successful. " + - "My address visible to the outside is = " + futureDiscover.peerAddress()); + setState(BootstrapState.NAT_SUCCESS, "Discover with automatic port forwarding was successful."); persistence.write(BootstrappedPeerFactory.this, "lastSuccessfulBootstrap", "portForwarding"); settableFuture.set(peerDHT); } else { - setState("Discover with automatic port forwarding has failed " + futureDiscover - .failedReason(), false); + setState(BootstrapState.NAT_FAILED, "Discover with automatic port forwarding has failed " + + futureDiscover.failedReason(), false); persistence.write(BootstrappedPeerFactory.this, "lastSuccessfulBootstrap", "default"); peerDHT.shutdown(); settableFuture.setException(new Exception("Discover with automatic port forwarding failed " + @@ -256,7 +255,7 @@ public class BootstrappedPeerFactory { @Override public void exceptionCaught(Throwable t) throws Exception { - setState("Exception at discover: " + t, false); + setState(BootstrapState.NAT_FAILED, "Exception at discover: " + t, false); persistence.write(BootstrappedPeerFactory.this, "lastSuccessfulBootstrap", "default"); peerDHT.shutdown(); settableFuture.setException(t); @@ -265,20 +264,23 @@ public class BootstrappedPeerFactory { } // 3. Attempt: We try to use another peer as relay - private void bootstrapWithRelay(PeerDHT peerDHT, PeerNAT peerNAT, FutureDiscover futureDiscover, - FutureNAT futureNAT) { + private void bootstrapWithRelay() { + setState(BootstrapState.RELAY_INIT, "We try to use another peer as relay."); + FutureDiscover futureDiscover = peer.discover().peerAddress(getBootstrapAddress()).start(); + PeerNAT peerNAT = new PeerBuilderNAT(peer).start(); + FutureNAT futureNAT = peerNAT.startSetupPortforwarding(futureDiscover); FutureRelayNAT futureRelayNAT = peerNAT.startRelay(futureDiscover, futureNAT); futureRelayNAT.addListener(new BaseFutureListener() { @Override public void operationComplete(BaseFuture future) throws Exception { if (future.isSuccess()) { - setState("Bootstrap using relay was successful. " + - "My address visible to the outside is = " + peerDHT.peerAddress()); + setState(BootstrapState.RELAY_SUCCESS, "Bootstrap using relay was successful."); persistence.write(BootstrappedPeerFactory.this, "lastSuccessfulBootstrap", "relay"); settableFuture.set(peerDHT); } else { - setState("Bootstrap using relay has failed " + futureRelayNAT.failedReason(), false); + setState(BootstrapState.RELAY_FAILED, "Bootstrap using relay has failed " + futureRelayNAT + .failedReason(), false); persistence.write(BootstrappedPeerFactory.this, "lastSuccessfulBootstrap", "default"); futureRelayNAT.shutdown(); peerDHT.shutdown(); @@ -289,14 +291,13 @@ public class BootstrappedPeerFactory { @Override public void exceptionCaught(Throwable t) throws Exception { - setState("Exception at bootstrapWithRelay: " + t, false); + setState(BootstrapState.RELAY_FAILED, "Exception at bootstrapWithRelay: " + t, false); persistence.write(BootstrappedPeerFactory.this, "lastSuccessfulBootstrap", "default"); futureRelayNAT.shutdown(); peerDHT.shutdown(); settableFuture.setException(t); } }); - } private PeerAddress getBootstrapAddress() { @@ -311,15 +312,17 @@ public class BootstrappedPeerFactory { } } - private void setState(String state) { - setState(state, true); + private void setState(BootstrapState bootstrapState, String message) { + setState(bootstrapState, message, true); } - private void setState(String state, boolean isSuccess) { + private void setState(BootstrapState bootstrapState, String message, boolean isSuccess) { if (isSuccess) - log.info(state); + log.info(message); else - log.error(state); - Platform.runLater(() -> connectionState.set(state)); + log.error(message); + + bootstrapState.setMessage(message); + Platform.runLater(() -> this.bootstrapState.set(bootstrapState)); } } diff --git a/src/main/java/io/bitsquare/msg/DefaultMessageModule.java b/src/main/java/io/bitsquare/msg/DefaultMessageModule.java index ddcad87bd3..4e1e75c2fe 100644 --- a/src/main/java/io/bitsquare/msg/DefaultMessageModule.java +++ b/src/main/java/io/bitsquare/msg/DefaultMessageModule.java @@ -18,7 +18,7 @@ package io.bitsquare.msg; import io.bitsquare.AbstractBitsquareModule; -import io.bitsquare.network.BootstrapNode; +import io.bitsquare.network.BootstrapNodes; import io.bitsquare.network.Node; import com.google.inject.Injector; @@ -44,7 +44,7 @@ public class DefaultMessageModule extends AbstractBitsquareModule implements Mes bind(Node.class) .annotatedWith(Names.named("bootstrapNode")) - .toInstance(BootstrapNode.LOCAL_HOST); + .toInstance(BootstrapNodes.LOCALHOST); } @Override diff --git a/src/main/java/io/bitsquare/msg/P2PNode.java b/src/main/java/io/bitsquare/msg/P2PNode.java index d7f42bb4ff..58ae953cec 100644 --- a/src/main/java/io/bitsquare/msg/P2PNode.java +++ b/src/main/java/io/bitsquare/msg/P2PNode.java @@ -17,6 +17,7 @@ package io.bitsquare.msg; +import io.bitsquare.msg.listeners.BootstrapListener; import io.bitsquare.network.tomp2p.TomP2PPeer; import com.google.common.util.concurrent.FutureCallback; @@ -38,6 +39,8 @@ import javax.annotation.Nullable; import javax.inject.Inject; +import javafx.application.Platform; + import net.tomp2p.connection.DSASignatureFactory; import net.tomp2p.connection.PeerConnection; import net.tomp2p.dht.FutureGet; @@ -117,14 +120,29 @@ public class P2PNode { bootstrappedPeerFactory.setKeyPair(keyPair); } - public void start(int port, FutureCallback callback) { + public void start(int port, BootstrapListener bootstrapListener) { useDiscStorage(useDiskStorage); bootstrappedPeerFactory.setStorage(storage); setupTimerForIPCheck(); ListenableFuture bootstrapComplete = bootstrap(port); - Futures.addCallback(bootstrapComplete, callback); + Futures.addCallback(bootstrapComplete, new FutureCallback() { + @Override + public void onSuccess(@Nullable PeerDHT result) { + log.debug("p2pNode.start success result = " + result); + Platform.runLater(bootstrapListener::onCompleted); + } + + @Override + public void onFailure(@NotNull Throwable t) { + log.error(t.toString()); + Platform.runLater(() -> bootstrapListener.onFailed(t)); + } + }); + + bootstrappedPeerFactory.bootstrapState.addListener((ov, oldValue, newValue) -> + bootstrapListener.onBootstrapStateChanged(newValue)); } @@ -187,7 +205,7 @@ public class P2PNode { futureDirect.addListener(new BaseFutureListener() { @Override public void operationComplete(BaseFuture future) throws Exception { - if (futureDirect.isSuccess()) { + if (isSuccess(futureDirect)) { log.debug("sendMessage completed"); } else { @@ -297,7 +315,7 @@ public class P2PNode { futurePut.addListener(new BaseFutureListener() { @Override public void operationComplete(BaseFuture future) throws Exception { - if (future.isSuccess()) { + if (isSuccess(futurePut)) { storedPeerAddress = peerDHT.peerAddress(); log.debug("storedPeerAddress = " + storedPeerAddress); } @@ -382,4 +400,10 @@ public class P2PNode { storage = new StorageMemory(); } } + + // Isolate the success handling as there is bug in port forwarding mode + private boolean isSuccess(BaseFuture baseFuture) { + // return baseFuture.isSuccess(); + return true; + } } diff --git a/src/main/java/io/bitsquare/msg/TomP2PMessageFacade.java b/src/main/java/io/bitsquare/msg/TomP2PMessageFacade.java index 9e48c886c7..0548e793c2 100644 --- a/src/main/java/io/bitsquare/msg/TomP2PMessageFacade.java +++ b/src/main/java/io/bitsquare/msg/TomP2PMessageFacade.java @@ -27,8 +27,6 @@ import io.bitsquare.network.Peer; import io.bitsquare.network.tomp2p.TomP2PPeer; import io.bitsquare.user.User; -import com.google.common.util.concurrent.FutureCallback; - import java.io.IOException; import java.security.PublicKey; @@ -37,8 +35,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; -import javax.annotation.Nullable; - import javax.inject.Inject; import javafx.application.Platform; @@ -46,7 +42,6 @@ import javafx.application.Platform; import net.tomp2p.dht.FutureGet; import net.tomp2p.dht.FuturePut; import net.tomp2p.dht.FutureRemove; -import net.tomp2p.dht.PeerDHT; import net.tomp2p.futures.BaseFuture; import net.tomp2p.futures.BaseFutureAdapter; import net.tomp2p.futures.BaseFutureListener; @@ -55,11 +50,10 @@ import net.tomp2p.peers.Number160; import net.tomp2p.storage.Data; import net.tomp2p.utils.Utils; -import org.jetbrains.annotations.NotNull; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; + /** * That facade delivers direct messaging and DHT functionality from the TomP2P library * It is the translating domain specific functionality to the messaging layer. @@ -98,19 +92,7 @@ class TomP2PMessageFacade implements MessageFacade { p2pNode.setMessageBroker(this); p2pNode.setKeyPair(user.getMessageKeyPair()); - p2pNode.start(port, new FutureCallback() { - @Override - public void onSuccess(@Nullable PeerDHT result) { - log.debug("p2pNode.start success result = " + result); - Platform.runLater(bootstrapListener::onCompleted); - } - - @Override - public void onFailure(@NotNull Throwable t) { - log.error(t.toString()); - Platform.runLater(() -> bootstrapListener.onFailed(t)); - } - }); + p2pNode.start(port, bootstrapListener); } public void shutDown() { @@ -131,7 +113,7 @@ class TomP2PMessageFacade implements MessageFacade { futureGet.addListener(new BaseFutureAdapter() { @Override public void operationComplete(BaseFuture baseFuture) throws Exception { - if (baseFuture.isSuccess() && futureGet.data() != null) { + if (isSuccess(baseFuture) && futureGet.data() != null) { final Peer peer = (Peer) futureGet.data().object(); Platform.runLater(() -> listener.onResult(peer)); } @@ -142,7 +124,6 @@ class TomP2PMessageFacade implements MessageFacade { }); } - /////////////////////////////////////////////////////////////////////////////////////////// // Trade process /////////////////////////////////////////////////////////////////////////////////////////// @@ -150,13 +131,13 @@ class TomP2PMessageFacade implements MessageFacade { public void sendMessage(Peer peer, Message message, OutgoingMessageListener listener) { if (!(peer instanceof TomP2PPeer)) { - throw new IllegalArgumentException("peer must be of type TomP2PPeer") ; + throw new IllegalArgumentException("peer must be of type TomP2PPeer"); } - FutureDirect futureDirect = p2pNode.sendData(((TomP2PPeer)peer).getPeerAddress(), message); + FutureDirect futureDirect = p2pNode.sendData(((TomP2PPeer) peer).getPeerAddress(), message); futureDirect.addListener(new BaseFutureListener() { @Override public void operationComplete(BaseFuture future) throws Exception { - if (futureDirect.isSuccess()) { + if (isSuccess(futureDirect)) { Platform.runLater(listener::onResult); } else { @@ -198,7 +179,7 @@ class TomP2PMessageFacade implements MessageFacade { } })); - if (addFuture.isSuccess()) { + if (isSuccess(addFuture)) { log.trace("Add arbitrator to DHT was successful. Stored data: [key: " + locationKey + ", " + "values: " + arbitratorData + "]"); } @@ -233,7 +214,7 @@ class TomP2PMessageFacade implements MessageFacade { } } })); - if (removeFuture.isSuccess()) { + if (isSuccess(removeFuture)) { log.trace("Remove arbitrator from DHT was successful. Stored data: [key: " + locationKey + ", " + "values: " + arbitratorData + "]"); } @@ -267,7 +248,7 @@ class TomP2PMessageFacade implements MessageFacade { listener.onArbitratorsReceived(arbitrators); })); - if (baseFuture.isSuccess()) { + if (isSuccess(baseFuture)) { log.trace("Get arbitrators from DHT was successful. Stored data: [key: " + locationKey + ", " + "values: " + futureGet.dataMap() + "]"); } @@ -299,6 +280,11 @@ class TomP2PMessageFacade implements MessageFacade { incomingMessageListeners.remove(listener); } + // Isolate the success handling as there is bug in port forwarding mode + private boolean isSuccess(BaseFuture baseFuture) { + // return baseFuture.isSuccess(); + return true; + } /////////////////////////////////////////////////////////////////////////////////////////// // Incoming message handler diff --git a/src/main/java/io/bitsquare/msg/actor/DHTManager.java b/src/main/java/io/bitsquare/msg/actor/DHTManager.java index dd26040666..be763753b1 100644 --- a/src/main/java/io/bitsquare/msg/actor/DHTManager.java +++ b/src/main/java/io/bitsquare/msg/actor/DHTManager.java @@ -52,14 +52,12 @@ public class DHTManager extends AbstractActor { return Props.create(DHTManager.class); } - private Bindings bindings; - private Peer peer; private PeerDHT peerDHT; private PeerNAT peerNAT; public DHTManager() { receive(ReceiveBuilder - .match(InitializePeer.class, initializePeer -> doInitializePeer(initializePeer)) + .match(InitializePeer.class, this::doInitializePeer) .matchAny(o -> log.info("received unknown message")).build() ); } @@ -68,7 +66,7 @@ public class DHTManager extends AbstractActor { log.debug("Received message: {}", initializePeer); try { - bindings = new Bindings(); + Bindings bindings = new Bindings(); // TODO: @Steve: Is that needed that we restrict to IP4? // bindings.addProtocol(StandardProtocolFamily.INET); @@ -77,8 +75,12 @@ public class DHTManager extends AbstractActor { bindings.addInterface(initializePeer.getInterfaceHint()); } - peer = new PeerBuilder(initializePeer.getPeerId()).ports(initializePeer.getPort()).bindings(bindings) + Peer peer = new PeerBuilder(initializePeer.getPeerId()).ports(initializePeer.getPort()).bindings(bindings) .start(); + peer.objectDataReply((sender, request) -> { + log.debug("received request: ", request.toString()); + return "pong"; + }); // For the moment we want not to bootstrap to other seed nodes to keep test scenarios // simple @@ -110,9 +112,7 @@ public class DHTManager extends AbstractActor { sender().tell(new PeerInitialized(peer.peerID(), initializePeer.getPort()), self()); } catch (Throwable t) { - log.info("The second instance has been started. If that happens at the first instance" + - " we are in trouble... " + t.getMessage()); - sender().tell(new PeerInitialized(null, null), self()); + log.error(t.getMessage()); } } diff --git a/src/main/java/io/bitsquare/msg/listeners/BootstrapListener.java b/src/main/java/io/bitsquare/msg/listeners/BootstrapListener.java index 9273c30bdf..c559226e34 100644 --- a/src/main/java/io/bitsquare/msg/listeners/BootstrapListener.java +++ b/src/main/java/io/bitsquare/msg/listeners/BootstrapListener.java @@ -17,9 +17,13 @@ package io.bitsquare.msg.listeners; +import io.bitsquare.network.BootstrapState; + public interface BootstrapListener { public void onCompleted(); public void onFailed(Throwable throwable); + public void onBootstrapStateChanged(BootstrapState state); + } diff --git a/src/main/java/io/bitsquare/network/BootstrapNode.java b/src/main/java/io/bitsquare/network/BootstrapNodes.java similarity index 56% rename from src/main/java/io/bitsquare/network/BootstrapNode.java rename to src/main/java/io/bitsquare/network/BootstrapNodes.java index e675f9af3d..5d8c4b5a75 100644 --- a/src/main/java/io/bitsquare/network/BootstrapNode.java +++ b/src/main/java/io/bitsquare/network/BootstrapNodes.java @@ -17,32 +17,16 @@ package io.bitsquare.network; -public enum BootstrapNode implements Node { - LOCAL_HOST("localhost", "127.0.0.1", 5000), - DIGITAL_OCEAN1("digitalocean1.bitsquare.io", "188.226.179.109", 5000); +import java.util.Arrays; +import java.util.List; - private final String id; - private final String ip; - private final int port; +public interface BootstrapNodes { + Node LOCALHOST = Node.at("localhost", "127.0.0.1"); + Node DIGITAL_OCEAN_1 = Node.at("digitalocean1.bitsquare.io", "188.226.179.109"); - BootstrapNode(String id, String ip, int port) { - this.id = id; - this.ip = ip; - this.port = port; - } - - @Override - public String getId() { - return id; - } - - @Override - public String getIp() { - return ip; - } - - @Override - public int getPort() { - return port; + static List all() { + return Arrays.asList( + LOCALHOST, DIGITAL_OCEAN_1 + ); } } diff --git a/src/main/java/io/bitsquare/network/BootstrapState.java b/src/main/java/io/bitsquare/network/BootstrapState.java new file mode 100644 index 0000000000..acba66b07e --- /dev/null +++ b/src/main/java/io/bitsquare/network/BootstrapState.java @@ -0,0 +1,51 @@ +/* + * This file is part of Bitsquare. + * + * Bitsquare is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bitsquare is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bitsquare. If not, see . + */ + +package io.bitsquare.network; + +/** + * NOT_SUCCEEDED means we will try the next step, FAILED is used for fatal failures which will terminate the bootstrap + */ +public enum BootstrapState { + PEER_CREATION, + PEER_CREATION_FAILED, + DIRECT_INIT, + DIRECT_SUCCESS, + DIRECT_NOT_SUCCEEDED, + DIRECT_FAILED, + NAT_INIT, + NAT_SETUP_DONE, + NAT_SUCCESS, + NAT_NOT_SUCCEEDED, + NAT_FAILED, + RELAY_INIT, + RELAY_SUCCESS, + RELAY_FAILED; + + private String message; + + BootstrapState() { + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/src/main/java/io/bitsquare/network/Node.java b/src/main/java/io/bitsquare/network/Node.java index e0f10b3b07..b975851ca6 100644 --- a/src/main/java/io/bitsquare/network/Node.java +++ b/src/main/java/io/bitsquare/network/Node.java @@ -17,13 +17,66 @@ package io.bitsquare.network; -public interface Node { +import com.google.common.base.Objects; - String getId(); +public final class Node { + public static final int DEFAULT_PORT = 5000; - String getIp(); + private final String id; + private final String ip; + private final int port; - int getPort(); + private Node(String id, String ip, int port) { + this.id = id; + this.ip = ip; + this.port = port; + } + public static Node at(String id, String ip) { + return Node.at(id, ip, DEFAULT_PORT); + } + + public static Node at(String id, String ip, int port) { + return new Node(id, ip, port); + } + + public String getId() { + return id; + } + + public String getIp() { + return ip; + } + + public int getPort() { + return port; + } + + @Override + public boolean equals(Object object) { + if (this == object) + return true; + + if (object == null || getClass() != object.getClass()) + return false; + + Node that = (Node) object; + return Objects.equal(this.id, that.id) && + Objects.equal(this.ip, that.ip) && + Objects.equal(this.port, that.port); + } + + @Override + public int hashCode() { + return Objects.hashCode(id, ip, port); + } + + @Override + public String toString() { + return Objects.toStringHelper(Node.class.getSimpleName()) + .add("id", id) + .add("ip", ip) + .add("port", port) + .toString(); + } } - diff --git a/src/main/java/io/bitsquare/offer/TomP2POfferRepository.java b/src/main/java/io/bitsquare/offer/TomP2POfferRepository.java index 8acce93bd9..6cd949b0d1 100644 --- a/src/main/java/io/bitsquare/offer/TomP2POfferRepository.java +++ b/src/main/java/io/bitsquare/offer/TomP2POfferRepository.java @@ -75,27 +75,27 @@ class TomP2POfferRepository implements OfferRepository { futurePut.addListener(new BaseFutureListener() { @Override public void operationComplete(BaseFuture future) throws Exception { - // deactivate it for the moment until the port forwarding bug is fixed - // if (future.isSuccess()) { - Platform.runLater(() -> { - resultHandler.handleResult(); - offerRepositoryListeners.stream().forEach(listener -> { - try { - Object offerDataObject = offerData.object(); - if (offerDataObject instanceof Offer) { - log.error("Added offer to DHT with ID: " + ((Offer) offerDataObject).getId()); - listener.onOfferAdded((Offer) offerDataObject); + if (isSuccess(future)) { + Platform.runLater(() -> { + resultHandler.handleResult(); + offerRepositoryListeners.stream().forEach(listener -> { + try { + Object offerDataObject = offerData.object(); + if (offerDataObject instanceof Offer) { + log.error("Added offer to DHT with ID: " + offerDataObject); + listener.onOfferAdded((Offer) offerDataObject); + } + } catch (ClassNotFoundException | IOException e) { + e.printStackTrace(); + log.error("Add offer to DHT failed: " + e.getMessage()); } - } catch (ClassNotFoundException | IOException e) { - e.printStackTrace(); - log.error("Add offer to DHT failed: " + e.getMessage()); - } - }); + }); - writeInvalidationTimestampToDHT(locationKey); - log.trace("Add offer to DHT was successful. Added data: [locationKey: " + locationKey + - ", value: " + offerData + "]"); - }); + writeInvalidationTimestampToDHT(locationKey); + log.trace("Add offer to DHT was successful. Added data: [locationKey: " + locationKey + + ", value: " + offerData + "]"); + }); + } } @Override @@ -124,25 +124,25 @@ class TomP2POfferRepository implements OfferRepository { futureRemove.addListener(new BaseFutureListener() { @Override public void operationComplete(BaseFuture future) throws Exception { - // deactivate it for the moment until the port forwarding bug is fixed - // if (future.isSuccess()) { - Platform.runLater(() -> { - offerRepositoryListeners.stream().forEach(listener -> { - try { - Object offerDataObject = offerData.object(); - if (offerDataObject instanceof Offer) { - log.trace("Remove offer from DHT was successful. Removed data: [key: " + - locationKey + ", " + - "offer: " + (Offer) offerDataObject + "]"); - listener.onOfferRemoved((Offer) offerDataObject); + if (isSuccess(future)) { + Platform.runLater(() -> { + offerRepositoryListeners.stream().forEach(listener -> { + try { + Object offerDataObject = offerData.object(); + if (offerDataObject instanceof Offer) { + log.trace("Remove offer from DHT was successful. Removed data: [key: " + + locationKey + ", " + + "offer: " + (Offer) offerDataObject + "]"); + listener.onOfferRemoved((Offer) offerDataObject); + } + } catch (ClassNotFoundException | IOException e) { + e.printStackTrace(); + log.error("Remove offer from DHT failed. Error: " + e.getMessage()); } - } catch (ClassNotFoundException | IOException e) { - e.printStackTrace(); - log.error("Remove offer from DHT failed. Error: " + e.getMessage()); - } + }); + writeInvalidationTimestampToDHT(locationKey); }); - writeInvalidationTimestampToDHT(locationKey); - }); + } } @Override @@ -163,7 +163,7 @@ class TomP2POfferRepository implements OfferRepository { futureGet.addListener(new BaseFutureAdapter() { @Override public void operationComplete(BaseFuture baseFuture) throws Exception { - if (baseFuture.isSuccess()) { + if (isSuccess(baseFuture)) { final Map dataMap = futureGet.dataMap(); final List offers = new ArrayList<>(); if (dataMap != null) { @@ -228,7 +228,7 @@ class TomP2POfferRepository implements OfferRepository { putFuture.addListener(new BaseFutureListener() { @Override public void operationComplete(BaseFuture future) throws Exception { - if (putFuture.isSuccess()) + if (isSuccess(putFuture)) log.trace("Update invalidationTimestamp to DHT was successful. TimeStamp=" + invalidationTimestamp.get()); else @@ -255,7 +255,7 @@ class TomP2POfferRepository implements OfferRepository { getFuture.addListener(new BaseFutureListener() { @Override public void operationComplete(BaseFuture future) throws Exception { - if (getFuture.isSuccess()) { + if (isSuccess(getFuture)) { Data data = getFuture.data(); if (data != null && data.object() instanceof Long) { final Object object = data.object(); @@ -265,8 +265,8 @@ class TomP2POfferRepository implements OfferRepository { invalidationTimestamp.set(timeStamp); }); } - else { - //log.error("Get invalidationTimestamp from DHT failed. Data = " + data); + else if (data != null) { + log.error("Get invalidationTimestamp from DHT failed. Data = " + data); } } else if (getFuture.data() == null) { @@ -290,4 +290,9 @@ class TomP2POfferRepository implements OfferRepository { return Number160.createHash(locationKey + "invalidated"); } + // Isolate the success handling as there is bug in port forwarding mode + private boolean isSuccess(BaseFuture baseFuture) { + // return baseFuture.isSuccess(); + return true; + } } diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index 6b4d2431bf..dcf292b153 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -26,7 +26,13 @@ - + + + + + + + @@ -37,8 +43,8 @@ - - + +