From b8009996149fee5a678a4e6e0d1f48611afd117f Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 15 Nov 2016 01:13:24 +0100 Subject: [PATCH] Add popup for adding a full btc node ip address at first startup as well in settings --- .../java/io/bitsquare/alert/AlertManager.java | 4 +- .../java/io/bitsquare/alert/AlertModule.java | 4 +- .../alert/PrivateNotificationManager.java | 4 +- ...CoreOptionKeys.java => AppOptionKeys.java} | 5 +- .../bitsquare/app/BitsquareEnvironment.java | 54 ++++---- .../io/bitsquare/app/BitsquareExecutable.java | 18 +-- .../java/io/bitsquare/btc/BitcoinModule.java | 8 +- .../java/io/bitsquare/btc/BtcOptionKeys.java | 2 - .../java/io/bitsquare/btc/WalletService.java | 18 +-- .../btc/pricefeed/PriceFeedService.java | 4 +- .../io/bitsquare/filter/FilterManager.java | 4 +- .../io/bitsquare/filter/FilterModule.java | 4 +- .../java/io/bitsquare/trade/TradeModule.java | 4 +- .../trade/offer/OfferBookService.java | 4 +- .../statistics/TradeStatisticsManager.java | 4 +- .../java/io/bitsquare/user/Preferences.java | 34 ++++- .../java/io/bitsquare/app/BitsquareApp.java | 4 +- .../io/bitsquare/app/BitsquareAppMain.java | 6 +- .../main/java/io/bitsquare/gui/GuiModule.java | 4 +- .../java/io/bitsquare/gui/main/MainView.java | 2 +- .../io/bitsquare/gui/main/MainViewModel.java | 26 +++- .../account/content/backup/BackupView.java | 4 +- .../windows/AddBitcoinNodesWindow.java | 129 ++++++++++++++++++ .../settings/network/NetworkSettingsView.fxml | 20 +-- .../settings/network/NetworkSettingsView.java | 50 +++++-- .../java/io/bitsquare/headless/Headless.java | 4 +- .../io/bitsquare/headless/HeadlessMain.java | 8 +- .../java/io/bitsquare/monitor/Monitor.java | 4 +- .../io/bitsquare/monitor/MonitorMain.java | 8 +- .../java/io/bitsquare/seednode/SeedNode.java | 4 +- .../io/bitsquare/seednode/SeedNodeMain.java | 10 +- .../io/bitsquare/statistics/Statistics.java | 4 +- .../bitsquare/statistics/StatisticsMain.java | 10 +- 33 files changed, 336 insertions(+), 136 deletions(-) rename core/src/main/java/io/bitsquare/app/{CoreOptionKeys.java => AppOptionKeys.java} (76%) create mode 100644 gui/src/main/java/io/bitsquare/gui/main/overlays/windows/AddBitcoinNodesWindow.java diff --git a/core/src/main/java/io/bitsquare/alert/AlertManager.java b/core/src/main/java/io/bitsquare/alert/AlertManager.java index dc0d55bdca..b6641414ab 100644 --- a/core/src/main/java/io/bitsquare/alert/AlertManager.java +++ b/core/src/main/java/io/bitsquare/alert/AlertManager.java @@ -19,7 +19,7 @@ package io.bitsquare.alert; import com.google.inject.Inject; import com.google.inject.name.Named; -import io.bitsquare.app.CoreOptionKeys; +import io.bitsquare.app.AppOptionKeys; import io.bitsquare.common.crypto.KeyRing; import io.bitsquare.p2p.P2PService; import io.bitsquare.p2p.storage.HashMapChangedListener; @@ -56,7 +56,7 @@ public class AlertManager { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public AlertManager(P2PService p2PService, KeyRing keyRing, User user, @Named(CoreOptionKeys.IGNORE_DEV_MSG_KEY) boolean ignoreDevMsg) { + public AlertManager(P2PService p2PService, KeyRing keyRing, User user, @Named(AppOptionKeys.IGNORE_DEV_MSG_KEY) boolean ignoreDevMsg) { this.p2PService = p2PService; this.keyRing = keyRing; this.user = user; diff --git a/core/src/main/java/io/bitsquare/alert/AlertModule.java b/core/src/main/java/io/bitsquare/alert/AlertModule.java index 18ad9c03e6..6956c3fe92 100644 --- a/core/src/main/java/io/bitsquare/alert/AlertModule.java +++ b/core/src/main/java/io/bitsquare/alert/AlertModule.java @@ -19,7 +19,7 @@ package io.bitsquare.alert; import com.google.inject.Singleton; import io.bitsquare.app.AppModule; -import io.bitsquare.app.CoreOptionKeys; +import io.bitsquare.app.AppOptionKeys; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.env.Environment; @@ -37,6 +37,6 @@ public class AlertModule extends AppModule { protected final void configure() { bind(AlertManager.class).in(Singleton.class); bind(PrivateNotificationManager.class).in(Singleton.class); - bindConstant().annotatedWith(named(CoreOptionKeys.IGNORE_DEV_MSG_KEY)).to(env.getRequiredProperty(CoreOptionKeys.IGNORE_DEV_MSG_KEY)); + bindConstant().annotatedWith(named(AppOptionKeys.IGNORE_DEV_MSG_KEY)).to(env.getRequiredProperty(AppOptionKeys.IGNORE_DEV_MSG_KEY)); } } diff --git a/core/src/main/java/io/bitsquare/alert/PrivateNotificationManager.java b/core/src/main/java/io/bitsquare/alert/PrivateNotificationManager.java index 505ca4f83e..d8cd111e0a 100644 --- a/core/src/main/java/io/bitsquare/alert/PrivateNotificationManager.java +++ b/core/src/main/java/io/bitsquare/alert/PrivateNotificationManager.java @@ -19,7 +19,7 @@ package io.bitsquare.alert; import com.google.inject.Inject; import com.google.inject.name.Named; -import io.bitsquare.app.CoreOptionKeys; +import io.bitsquare.app.AppOptionKeys; import io.bitsquare.common.crypto.KeyRing; import io.bitsquare.common.crypto.PubKeyRing; import io.bitsquare.crypto.DecryptedMsgWithPubKey; @@ -58,7 +58,7 @@ public class PrivateNotificationManager { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public PrivateNotificationManager(P2PService p2PService, KeyRing keyRing, @Named(CoreOptionKeys.IGNORE_DEV_MSG_KEY) boolean ignoreDevMsg) { + public PrivateNotificationManager(P2PService p2PService, KeyRing keyRing, @Named(AppOptionKeys.IGNORE_DEV_MSG_KEY) boolean ignoreDevMsg) { this.p2PService = p2PService; this.keyRing = keyRing; diff --git a/core/src/main/java/io/bitsquare/app/CoreOptionKeys.java b/core/src/main/java/io/bitsquare/app/AppOptionKeys.java similarity index 76% rename from core/src/main/java/io/bitsquare/app/CoreOptionKeys.java rename to core/src/main/java/io/bitsquare/app/AppOptionKeys.java index e631be4570..ed6157c353 100644 --- a/core/src/main/java/io/bitsquare/app/CoreOptionKeys.java +++ b/core/src/main/java/io/bitsquare/app/AppOptionKeys.java @@ -1,6 +1,6 @@ package io.bitsquare.app; -public class CoreOptionKeys { +public class AppOptionKeys { public static final String IGNORE_DEV_MSG_KEY = "ignoreDevMsg"; public static final String DUMP_STATISTICS = "dumpStatistics"; public static final String USER_DATA_DIR_KEY = "userDataDir"; @@ -8,5 +8,6 @@ public class CoreOptionKeys { public static final String APP_DATA_DIR_KEY = "appDataDir"; public static final String MAX_MEMORY = "maxMemory"; public static final String PRICE_FEED_PROVIDERS = "priceFeedProviders"; - + public static final String BTC_NODES = "btcNodes"; + public static final String USE_TOR_FOR_BTC = "useTorForBtc"; } diff --git a/core/src/main/java/io/bitsquare/app/BitsquareEnvironment.java b/core/src/main/java/io/bitsquare/app/BitsquareEnvironment.java index 2713bfce11..a6ba8abdf5 100644 --- a/core/src/main/java/io/bitsquare/app/BitsquareEnvironment.java +++ b/core/src/main/java/io/bitsquare/app/BitsquareEnvironment.java @@ -124,28 +124,28 @@ public class BitsquareEnvironment extends StandardEnvironment { (String) commandLineProperties.getProperty(CommonOptionKeys.LOG_LEVEL_KEY) : LOG_LEVEL_DEFAULT; - userDataDir = commandLineProperties.containsProperty(CoreOptionKeys.USER_DATA_DIR_KEY) ? - (String) commandLineProperties.getProperty(CoreOptionKeys.USER_DATA_DIR_KEY) : + userDataDir = commandLineProperties.containsProperty(AppOptionKeys.USER_DATA_DIR_KEY) ? + (String) commandLineProperties.getProperty(AppOptionKeys.USER_DATA_DIR_KEY) : DEFAULT_USER_DATA_DIR; - appName = commandLineProperties.containsProperty(CoreOptionKeys.APP_NAME_KEY) ? - (String) commandLineProperties.getProperty(CoreOptionKeys.APP_NAME_KEY) : + appName = commandLineProperties.containsProperty(AppOptionKeys.APP_NAME_KEY) ? + (String) commandLineProperties.getProperty(AppOptionKeys.APP_NAME_KEY) : DEFAULT_APP_NAME; - appDataDir = commandLineProperties.containsProperty(CoreOptionKeys.APP_DATA_DIR_KEY) ? - (String) commandLineProperties.getProperty(CoreOptionKeys.APP_DATA_DIR_KEY) : + appDataDir = commandLineProperties.containsProperty(AppOptionKeys.APP_DATA_DIR_KEY) ? + (String) commandLineProperties.getProperty(AppOptionKeys.APP_DATA_DIR_KEY) : appDataDir(userDataDir, appName); - ignoreDevMsg = commandLineProperties.containsProperty(CoreOptionKeys.IGNORE_DEV_MSG_KEY) ? - (String) commandLineProperties.getProperty(CoreOptionKeys.IGNORE_DEV_MSG_KEY) : + ignoreDevMsg = commandLineProperties.containsProperty(AppOptionKeys.IGNORE_DEV_MSG_KEY) ? + (String) commandLineProperties.getProperty(AppOptionKeys.IGNORE_DEV_MSG_KEY) : ""; - dumpStatistics = commandLineProperties.containsProperty(CoreOptionKeys.DUMP_STATISTICS) ? - (String) commandLineProperties.getProperty(CoreOptionKeys.DUMP_STATISTICS) : + dumpStatistics = commandLineProperties.containsProperty(AppOptionKeys.DUMP_STATISTICS) ? + (String) commandLineProperties.getProperty(AppOptionKeys.DUMP_STATISTICS) : ""; - maxMemory = commandLineProperties.containsProperty(CoreOptionKeys.MAX_MEMORY) ? - (String) commandLineProperties.getProperty(CoreOptionKeys.MAX_MEMORY) : + maxMemory = commandLineProperties.containsProperty(AppOptionKeys.MAX_MEMORY) ? + (String) commandLineProperties.getProperty(AppOptionKeys.MAX_MEMORY) : ""; - priceFeedProviders = commandLineProperties.containsProperty(CoreOptionKeys.PRICE_FEED_PROVIDERS) ? - (String) commandLineProperties.getProperty(CoreOptionKeys.PRICE_FEED_PROVIDERS) : + priceFeedProviders = commandLineProperties.containsProperty(AppOptionKeys.PRICE_FEED_PROVIDERS) ? + (String) commandLineProperties.getProperty(AppOptionKeys.PRICE_FEED_PROVIDERS) : ""; seedNodes = commandLineProperties.containsProperty(NetworkOptionKeys.SEED_NODES_KEY) ? @@ -165,12 +165,12 @@ public class BitsquareEnvironment extends StandardEnvironment { (String) commandLineProperties.getProperty(NetworkOptionKeys.SOCKS_5_PROXY_HTTP_ADDRESS) : ""; - btcNodes = commandLineProperties.containsProperty(BtcOptionKeys.BTC_NODES) ? - (String) commandLineProperties.getProperty(BtcOptionKeys.BTC_NODES) : + btcNodes = commandLineProperties.containsProperty(AppOptionKeys.BTC_NODES) ? + (String) commandLineProperties.getProperty(AppOptionKeys.BTC_NODES) : ""; - useTorForBtc = commandLineProperties.containsProperty(BtcOptionKeys.USE_TOR_FOR_BTC) ? - (String) commandLineProperties.getProperty(BtcOptionKeys.USE_TOR_FOR_BTC) : + useTorForBtc = commandLineProperties.containsProperty(AppOptionKeys.USE_TOR_FOR_BTC) ? + (String) commandLineProperties.getProperty(AppOptionKeys.USE_TOR_FOR_BTC) : ""; MutablePropertySources propertySources = this.getPropertySources(); @@ -237,16 +237,16 @@ public class BitsquareEnvironment extends StandardEnvironment { setProperty(NetworkOptionKeys.SOCKS_5_PROXY_BTC_ADDRESS, socks5ProxyBtcAddress); setProperty(NetworkOptionKeys.SOCKS_5_PROXY_HTTP_ADDRESS, socks5ProxyHttpAddress); - setProperty(CoreOptionKeys.APP_DATA_DIR_KEY, appDataDir); - setProperty(CoreOptionKeys.IGNORE_DEV_MSG_KEY, ignoreDevMsg); - setProperty(CoreOptionKeys.DUMP_STATISTICS, dumpStatistics); - setProperty(CoreOptionKeys.APP_NAME_KEY, appName); - setProperty(CoreOptionKeys.MAX_MEMORY, maxMemory); - setProperty(CoreOptionKeys.USER_DATA_DIR_KEY, userDataDir); - setProperty(CoreOptionKeys.PRICE_FEED_PROVIDERS, priceFeedProviders); + setProperty(AppOptionKeys.APP_DATA_DIR_KEY, appDataDir); + setProperty(AppOptionKeys.IGNORE_DEV_MSG_KEY, ignoreDevMsg); + setProperty(AppOptionKeys.DUMP_STATISTICS, dumpStatistics); + setProperty(AppOptionKeys.APP_NAME_KEY, appName); + setProperty(AppOptionKeys.MAX_MEMORY, maxMemory); + setProperty(AppOptionKeys.USER_DATA_DIR_KEY, userDataDir); + setProperty(AppOptionKeys.PRICE_FEED_PROVIDERS, priceFeedProviders); - setProperty(BtcOptionKeys.BTC_NODES, btcNodes); - setProperty(BtcOptionKeys.USE_TOR_FOR_BTC, useTorForBtc); + setProperty(AppOptionKeys.BTC_NODES, btcNodes); + setProperty(AppOptionKeys.USE_TOR_FOR_BTC, useTorForBtc); setProperty(UserAgent.NAME_KEY, appName); setProperty(UserAgent.VERSION_KEY, Version.VERSION); diff --git a/core/src/main/java/io/bitsquare/app/BitsquareExecutable.java b/core/src/main/java/io/bitsquare/app/BitsquareExecutable.java index a1aa6f5fb6..2d608c82f3 100644 --- a/core/src/main/java/io/bitsquare/app/BitsquareExecutable.java +++ b/core/src/main/java/io/bitsquare/app/BitsquareExecutable.java @@ -94,22 +94,22 @@ public abstract class BitsquareExecutable { parser.accepts(NetworkOptionKeys.SOCKS_5_PROXY_HTTP_ADDRESS, description("A proxy address to be used for Http requests (should be non-Tor). [host:port]", "")) .withRequiredArg(); - parser.accepts(CoreOptionKeys.USER_DATA_DIR_KEY, description("User data directory", DEFAULT_USER_DATA_DIR)) + parser.accepts(AppOptionKeys.USER_DATA_DIR_KEY, description("User data directory", DEFAULT_USER_DATA_DIR)) .withRequiredArg(); - parser.accepts(CoreOptionKeys.APP_NAME_KEY, description("Application name", DEFAULT_APP_NAME)) + parser.accepts(AppOptionKeys.APP_NAME_KEY, description("Application name", DEFAULT_APP_NAME)) .withRequiredArg(); - parser.accepts(CoreOptionKeys.MAX_MEMORY, description("Max. permitted memory (used only at headless versions)", 600)) + parser.accepts(AppOptionKeys.MAX_MEMORY, description("Max. permitted memory (used only at headless versions)", 600)) .withRequiredArg(); - parser.accepts(CoreOptionKeys.APP_DATA_DIR_KEY, description("Application data directory", DEFAULT_APP_DATA_DIR)) + parser.accepts(AppOptionKeys.APP_DATA_DIR_KEY, description("Application data directory", DEFAULT_APP_DATA_DIR)) .withRequiredArg(); - parser.accepts(CoreOptionKeys.IGNORE_DEV_MSG_KEY, description("If set to true all signed messages from Bitsquare developers are ignored " + + parser.accepts(AppOptionKeys.IGNORE_DEV_MSG_KEY, description("If set to true all signed messages from Bitsquare developers are ignored " + "(Global alert, Version update alert, Filters for offers, nodes or trading account data)", false)) .withRequiredArg() .ofType(boolean.class); - parser.accepts(CoreOptionKeys.DUMP_STATISTICS, description("If set to true the trade statistics are stored as json file in the data dir.", false)) + parser.accepts(AppOptionKeys.DUMP_STATISTICS, description("If set to true the trade statistics are stored as json file in the data dir.", false)) .withRequiredArg() .ofType(boolean.class); - parser.accepts(CoreOptionKeys.PRICE_FEED_PROVIDERS, description("Custom price feed providers (comma separated)", false)) + parser.accepts(AppOptionKeys.PRICE_FEED_PROVIDERS, description("Custom price feed providers (comma separated)", false)) .withRequiredArg(); parser.accepts(BtcOptionKeys.BTC_NETWORK, description("Bitcoin network", BitcoinNetwork.DEFAULT)) @@ -120,9 +120,9 @@ public abstract class BitsquareExecutable { .withRequiredArg() .ofType(RegTestHost.class) .withValuesConvertedBy(new EnumValueConverter(RegTestHost.class)); - parser.accepts(BtcOptionKeys.BTC_NODES, description("Custom nodes used for BitcoinJ as comma separated IP addresses.", "")) + parser.accepts(AppOptionKeys.BTC_NODES, description("Custom nodes used for BitcoinJ as comma separated IP addresses.", "")) .withRequiredArg(); - parser.accepts(BtcOptionKeys.USE_TOR_FOR_BTC, description("If set to true BitcoinJ is routed over tor (socks 5 proxy).", "")) + parser.accepts(AppOptionKeys.USE_TOR_FOR_BTC, description("If set to true BitcoinJ is routed over tor (socks 5 proxy).", "")) .withRequiredArg(); } diff --git a/core/src/main/java/io/bitsquare/btc/BitcoinModule.java b/core/src/main/java/io/bitsquare/btc/BitcoinModule.java index 81d2697c7c..b84d5a8ef4 100644 --- a/core/src/main/java/io/bitsquare/btc/BitcoinModule.java +++ b/core/src/main/java/io/bitsquare/btc/BitcoinModule.java @@ -19,7 +19,7 @@ package io.bitsquare.btc; import com.google.inject.Singleton; import io.bitsquare.app.AppModule; -import io.bitsquare.app.CoreOptionKeys; +import io.bitsquare.app.AppOptionKeys; import io.bitsquare.btc.blockchain.BlockchainService; import io.bitsquare.btc.blockchain.providers.BlockTrailProvider; import io.bitsquare.btc.blockchain.providers.BlockrIOProvider; @@ -52,9 +52,9 @@ public class BitcoinModule extends AppModule { File walletDir = new File(env.getRequiredProperty(BtcOptionKeys.WALLET_DIR)); bind(File.class).annotatedWith(named(BtcOptionKeys.WALLET_DIR)).toInstance(walletDir); - bindConstant().annotatedWith(named(BtcOptionKeys.BTC_NODES)).to(env.getRequiredProperty(BtcOptionKeys.BTC_NODES)); - bindConstant().annotatedWith(named(BtcOptionKeys.USE_TOR_FOR_BTC)).to(env.getRequiredProperty(BtcOptionKeys.USE_TOR_FOR_BTC)); - bindConstant().annotatedWith(named(CoreOptionKeys.PRICE_FEED_PROVIDERS)).to(env.getRequiredProperty(CoreOptionKeys.PRICE_FEED_PROVIDERS)); + bindConstant().annotatedWith(named(AppOptionKeys.BTC_NODES)).to(env.getRequiredProperty(AppOptionKeys.BTC_NODES)); + bindConstant().annotatedWith(named(AppOptionKeys.USE_TOR_FOR_BTC)).to(env.getRequiredProperty(AppOptionKeys.USE_TOR_FOR_BTC)); + bindConstant().annotatedWith(named(AppOptionKeys.PRICE_FEED_PROVIDERS)).to(env.getRequiredProperty(AppOptionKeys.PRICE_FEED_PROVIDERS)); bind(AddressEntryList.class).in(Singleton.class); bind(TradeWalletService.class).in(Singleton.class); diff --git a/core/src/main/java/io/bitsquare/btc/BtcOptionKeys.java b/core/src/main/java/io/bitsquare/btc/BtcOptionKeys.java index e6521fdafa..9b9ff4e00a 100644 --- a/core/src/main/java/io/bitsquare/btc/BtcOptionKeys.java +++ b/core/src/main/java/io/bitsquare/btc/BtcOptionKeys.java @@ -3,7 +3,5 @@ package io.bitsquare.btc; public class BtcOptionKeys { public static final String BTC_NETWORK = "bitcoinNetwork"; public static final String REG_TEST_HOST = "bitcoinRegtestHost"; - public static final String BTC_NODES = "btcNodes"; - public static final String USE_TOR_FOR_BTC = "useTorForBtc"; public static final String WALLET_DIR = "walletDir"; } diff --git a/core/src/main/java/io/bitsquare/btc/WalletService.java b/core/src/main/java/io/bitsquare/btc/WalletService.java index e4efdb09cf..4ec02324e5 100644 --- a/core/src/main/java/io/bitsquare/btc/WalletService.java +++ b/core/src/main/java/io/bitsquare/btc/WalletService.java @@ -89,11 +89,9 @@ public class WalletService { private final AddressEntryList addressEntryList; private final Preferences preferences; private final Socks5ProxyProvider socks5ProxyProvider; - private final String btcNodes; private final NetworkParameters params; private final File walletDir; private final UserAgent userAgent; - private final boolean useTor; private WalletAppKitBitSquare walletAppKit; private Wallet wallet; @@ -116,29 +114,16 @@ public class WalletService { UserAgent userAgent, Preferences preferences, Socks5ProxyProvider socks5ProxyProvider, - @Named(BtcOptionKeys.WALLET_DIR) File appDir, - @Named(BtcOptionKeys.BTC_NODES) String btcNodes, - @Named(BtcOptionKeys.USE_TOR_FOR_BTC) String useTorFlagFromOptions) { + @Named(BtcOptionKeys.WALLET_DIR) File appDir) { this.regTestHost = regTestHost; this.tradeWalletService = tradeWalletService; this.addressEntryList = addressEntryList; this.preferences = preferences; this.socks5ProxyProvider = socks5ProxyProvider; - this.btcNodes = btcNodes; this.params = preferences.getBitcoinNetwork().getParameters(); this.walletDir = new File(appDir, "bitcoin"); this.userAgent = userAgent; - // We support a checkbox in the settings to set the use tor flag. - // If we get the options set we override that setting. - if (useTorFlagFromOptions != null && !useTorFlagFromOptions.isEmpty()) { - if (useTorFlagFromOptions.equals("false")) - preferences.setUseTorForBitcoinJ(false); - else if (useTorFlagFromOptions.equals("true")) - preferences.setUseTorForBitcoinJ(true); - } - useTor = preferences.getUseTorForBitcoinJ(); - storage = new Storage<>(walletDir); Long persisted = storage.initAndGetPersistedWithFileName("BloomFilterNonce"); if (persisted != null) { @@ -273,6 +258,7 @@ public class WalletService { // 1333 / (2800 + 1333) = 0.32 -> 32 % probability that a pub key is in our wallet walletAppKit.setBloomFilterFalsePositiveRate(0.00005); + String btcNodes = preferences.getBitcoinNodes(); log.debug("btcNodes: " + btcNodes); boolean usePeerNodes = false; diff --git a/core/src/main/java/io/bitsquare/btc/pricefeed/PriceFeedService.java b/core/src/main/java/io/bitsquare/btc/pricefeed/PriceFeedService.java index 05ecd754c4..2b6a8ae957 100644 --- a/core/src/main/java/io/bitsquare/btc/pricefeed/PriceFeedService.java +++ b/core/src/main/java/io/bitsquare/btc/pricefeed/PriceFeedService.java @@ -4,7 +4,7 @@ import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.SettableFuture; import com.google.inject.Inject; -import io.bitsquare.app.CoreOptionKeys; +import io.bitsquare.app.AppOptionKeys; import io.bitsquare.app.Log; import io.bitsquare.common.UserThread; import io.bitsquare.common.handlers.FaultHandler; @@ -70,7 +70,7 @@ public class PriceFeedService { @Inject public PriceFeedService(HttpClient httpClient, - @Named(CoreOptionKeys.PRICE_FEED_PROVIDERS) String priceFeedProviders, + @Named(AppOptionKeys.PRICE_FEED_PROVIDERS) String priceFeedProviders, @Named(NetworkOptionKeys.USE_LOCALHOST) boolean useLocalhost) { this.httpClient = httpClient; if (priceFeedProviders.isEmpty()) { diff --git a/core/src/main/java/io/bitsquare/filter/FilterManager.java b/core/src/main/java/io/bitsquare/filter/FilterManager.java index 579a0c4f48..6649fda6de 100644 --- a/core/src/main/java/io/bitsquare/filter/FilterManager.java +++ b/core/src/main/java/io/bitsquare/filter/FilterManager.java @@ -19,7 +19,7 @@ package io.bitsquare.filter; import com.google.inject.Inject; import com.google.inject.name.Named; -import io.bitsquare.app.CoreOptionKeys; +import io.bitsquare.app.AppOptionKeys; import io.bitsquare.common.crypto.KeyRing; import io.bitsquare.common.util.Tuple3; import io.bitsquare.common.util.Utilities; @@ -59,7 +59,7 @@ public class FilterManager { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public FilterManager(P2PService p2PService, KeyRing keyRing, User user, @Named(CoreOptionKeys.IGNORE_DEV_MSG_KEY) boolean ignoreDevMsg) { + public FilterManager(P2PService p2PService, KeyRing keyRing, User user, @Named(AppOptionKeys.IGNORE_DEV_MSG_KEY) boolean ignoreDevMsg) { this.p2PService = p2PService; this.keyRing = keyRing; this.user = user; diff --git a/core/src/main/java/io/bitsquare/filter/FilterModule.java b/core/src/main/java/io/bitsquare/filter/FilterModule.java index 8c6759238c..5b0a6ac7e3 100644 --- a/core/src/main/java/io/bitsquare/filter/FilterModule.java +++ b/core/src/main/java/io/bitsquare/filter/FilterModule.java @@ -19,7 +19,7 @@ package io.bitsquare.filter; import com.google.inject.Singleton; import io.bitsquare.app.AppModule; -import io.bitsquare.app.CoreOptionKeys; +import io.bitsquare.app.AppOptionKeys; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.env.Environment; @@ -36,6 +36,6 @@ public class FilterModule extends AppModule { @Override protected final void configure() { bind(FilterManager.class).in(Singleton.class); - bindConstant().annotatedWith(named(CoreOptionKeys.IGNORE_DEV_MSG_KEY)).to(env.getRequiredProperty(CoreOptionKeys.IGNORE_DEV_MSG_KEY)); + bindConstant().annotatedWith(named(AppOptionKeys.IGNORE_DEV_MSG_KEY)).to(env.getRequiredProperty(AppOptionKeys.IGNORE_DEV_MSG_KEY)); } } diff --git a/core/src/main/java/io/bitsquare/trade/TradeModule.java b/core/src/main/java/io/bitsquare/trade/TradeModule.java index d4afb74741..6a699d7a57 100644 --- a/core/src/main/java/io/bitsquare/trade/TradeModule.java +++ b/core/src/main/java/io/bitsquare/trade/TradeModule.java @@ -19,7 +19,7 @@ package io.bitsquare.trade; import com.google.inject.Singleton; import io.bitsquare.app.AppModule; -import io.bitsquare.app.CoreOptionKeys; +import io.bitsquare.app.AppOptionKeys; import io.bitsquare.trade.closed.ClosedTradableManager; import io.bitsquare.trade.failed.FailedTradesManager; import io.bitsquare.trade.statistics.TradeStatisticsManager; @@ -42,6 +42,6 @@ public class TradeModule extends AppModule { bind(TradeStatisticsManager.class).in(Singleton.class); bind(ClosedTradableManager.class).in(Singleton.class); bind(FailedTradesManager.class).in(Singleton.class); - bindConstant().annotatedWith(named(CoreOptionKeys.DUMP_STATISTICS)).to(env.getRequiredProperty(CoreOptionKeys.DUMP_STATISTICS)); + bindConstant().annotatedWith(named(AppOptionKeys.DUMP_STATISTICS)).to(env.getRequiredProperty(AppOptionKeys.DUMP_STATISTICS)); } } diff --git a/core/src/main/java/io/bitsquare/trade/offer/OfferBookService.java b/core/src/main/java/io/bitsquare/trade/offer/OfferBookService.java index 308c74a012..907be75df9 100644 --- a/core/src/main/java/io/bitsquare/trade/offer/OfferBookService.java +++ b/core/src/main/java/io/bitsquare/trade/offer/OfferBookService.java @@ -18,7 +18,7 @@ package io.bitsquare.trade.offer; import com.google.inject.name.Named; -import io.bitsquare.app.CoreOptionKeys; +import io.bitsquare.app.AppOptionKeys; import io.bitsquare.btc.pricefeed.PriceFeedService; import io.bitsquare.common.UserThread; import io.bitsquare.common.handlers.ErrorMessageHandler; @@ -66,7 +66,7 @@ public class OfferBookService { public OfferBookService(P2PService p2PService, PriceFeedService priceFeedService, Storage offersJsonStorage, - @Named(CoreOptionKeys.DUMP_STATISTICS) boolean dumpStatistics) { + @Named(AppOptionKeys.DUMP_STATISTICS) boolean dumpStatistics) { this.p2PService = p2PService; this.priceFeedService = priceFeedService; this.offersJsonStorage = offersJsonStorage; diff --git a/core/src/main/java/io/bitsquare/trade/statistics/TradeStatisticsManager.java b/core/src/main/java/io/bitsquare/trade/statistics/TradeStatisticsManager.java index d918087262..b7507205ab 100644 --- a/core/src/main/java/io/bitsquare/trade/statistics/TradeStatisticsManager.java +++ b/core/src/main/java/io/bitsquare/trade/statistics/TradeStatisticsManager.java @@ -2,7 +2,7 @@ package io.bitsquare.trade.statistics; import com.google.inject.Inject; import com.google.inject.name.Named; -import io.bitsquare.app.CoreOptionKeys; +import io.bitsquare.app.AppOptionKeys; import io.bitsquare.common.util.Utilities; import io.bitsquare.locale.CurrencyTuple; import io.bitsquare.locale.CurrencyUtil; @@ -39,7 +39,7 @@ public class TradeStatisticsManager { Storage cryptoCurrencyListJsonStorage, Storage statisticsJsonStorage, P2PService p2PService, - @Named(CoreOptionKeys.DUMP_STATISTICS) boolean dumpStatistics) { + @Named(AppOptionKeys.DUMP_STATISTICS) boolean dumpStatistics) { this.statisticsStorage = statisticsStorage; this.fiatCurrencyListJsonStorage = fiatCurrencyListJsonStorage; this.cryptoCurrencyListJsonStorage = cryptoCurrencyListJsonStorage; diff --git a/core/src/main/java/io/bitsquare/user/Preferences.java b/core/src/main/java/io/bitsquare/user/Preferences.java index 880d69c5ef..19132c53fd 100644 --- a/core/src/main/java/io/bitsquare/user/Preferences.java +++ b/core/src/main/java/io/bitsquare/user/Preferences.java @@ -17,6 +17,7 @@ package io.bitsquare.user; +import io.bitsquare.app.AppOptionKeys; import io.bitsquare.app.BitsquareEnvironment; import io.bitsquare.app.DevFlags; import io.bitsquare.app.Version; @@ -40,6 +41,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.inject.Inject; +import javax.inject.Named; import java.util.*; public final class Preferences implements Persistable { @@ -131,6 +133,7 @@ public final class Preferences implements Persistable { private boolean sortMarketCurrenciesNumerically = true; private boolean usePercentageBasedPrice = false; private Map peerTagMap = new HashMap<>(); + private String bitcoinNodes = ""; private List ignoreTradersList = new ArrayList<>(); private String defaultPath; @@ -156,8 +159,9 @@ public final class Preferences implements Persistable { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public Preferences(Storage storage, BitsquareEnvironment bitsquareEnvironment) { - log.debug("Preferences " + this); + public Preferences(Storage storage, BitsquareEnvironment bitsquareEnvironment, + @Named(AppOptionKeys.BTC_NODES) String btcNodesFromOptions, + @Named(AppOptionKeys.USE_TOR_FOR_BTC) String useTorFlagFromOptions) { INSTANCE = this; this.storage = storage; this.bitsquareEnvironment = bitsquareEnvironment; @@ -226,6 +230,10 @@ public final class Preferences implements Persistable { showOwnOffersInOfferBook = persisted.getShowOwnOffersInOfferBook(); maxPriceDistanceInPercent = persisted.getMaxPriceDistanceInPercent(); + bitcoinNodes = persisted.getBitcoinNodes(); + if (bitcoinNodes == null) + bitcoinNodes = ""; + try { setNonTradeTxFeePerKB(persisted.getNonTradeTxFeePerKB()); } catch (Exception e) { @@ -267,6 +275,20 @@ public final class Preferences implements Persistable { cryptoCurrenciesAsObservable.addListener(this::updateTradeCurrencies); tradeCurrenciesAsObservable.addAll(fiatCurrencies); tradeCurrenciesAsObservable.addAll(cryptoCurrencies); + + // Override settings with options if set + if (useTorFlagFromOptions != null && !useTorFlagFromOptions.isEmpty()) { + if (useTorFlagFromOptions.equals("false")) + setUseTorForBitcoinJ(false); + else if (useTorFlagFromOptions.equals("true")) + setUseTorForBitcoinJ(true); + } + + if (btcNodesFromOptions != null && !btcNodesFromOptions.isEmpty()) + setBitcoinNodes(btcNodesFromOptions); + + if (bitcoinNodes.equals("127.0.0.1") || bitcoinNodes.equals("localhost")) + setUseTorForBitcoinJ(false); } public void dontShowAgain(String key, boolean dontShowAgain) { @@ -453,6 +475,11 @@ public final class Preferences implements Persistable { storage.queueUpForSave(); } + public void setBitcoinNodes(String bitcoinNodes) { + this.bitcoinNodes = bitcoinNodes; + storage.queueUpForSave(50); + } + /////////////////////////////////////////////////////////////////////////////////////////// // Getter @@ -605,6 +632,9 @@ public final class Preferences implements Persistable { return sortMarketCurrenciesNumerically; } + public String getBitcoinNodes() { + return bitcoinNodes; + } /////////////////////////////////////////////////////////////////////////////////////////// // Private diff --git a/gui/src/main/java/io/bitsquare/app/BitsquareApp.java b/gui/src/main/java/io/bitsquare/app/BitsquareApp.java index 8816ee29f4..59375f3572 100644 --- a/gui/src/main/java/io/bitsquare/app/BitsquareApp.java +++ b/gui/src/main/java/io/bitsquare/app/BitsquareApp.java @@ -81,7 +81,7 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; -import static io.bitsquare.app.CoreOptionKeys.APP_NAME_KEY; +import static io.bitsquare.app.AppOptionKeys.APP_NAME_KEY; public class BitsquareApp extends Application { private static final Logger log = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(BitsquareApp.class); @@ -110,7 +110,7 @@ public class BitsquareApp extends Application { public void start(Stage stage) throws IOException { BitsquareApp.primaryStage = stage; - String logPath = Paths.get(env.getProperty(CoreOptionKeys.APP_DATA_DIR_KEY), "bitsquare").toString(); + String logPath = Paths.get(env.getProperty(AppOptionKeys.APP_DATA_DIR_KEY), "bitsquare").toString(); Log.setup(logPath); log.info("Log files under: " + logPath); Version.printVersion(); diff --git a/gui/src/main/java/io/bitsquare/app/BitsquareAppMain.java b/gui/src/main/java/io/bitsquare/app/BitsquareAppMain.java index cc901765a8..6c97c025b1 100644 --- a/gui/src/main/java/io/bitsquare/app/BitsquareAppMain.java +++ b/gui/src/main/java/io/bitsquare/app/BitsquareAppMain.java @@ -34,9 +34,9 @@ public class BitsquareAppMain extends BitsquareExecutable { // So we only handle the absolute minimum which is APP_NAME, APP_DATA_DIR_KEY and USER_DATA_DIR OptionParser parser = new OptionParser(); parser.allowsUnrecognizedOptions(); - parser.accepts(CoreOptionKeys.USER_DATA_DIR_KEY, description("User data directory", DEFAULT_USER_DATA_DIR)) + parser.accepts(AppOptionKeys.USER_DATA_DIR_KEY, description("User data directory", DEFAULT_USER_DATA_DIR)) .withRequiredArg(); - parser.accepts(CoreOptionKeys.APP_NAME_KEY, description("Application name", DEFAULT_APP_NAME)) + parser.accepts(AppOptionKeys.APP_NAME_KEY, description("Application name", DEFAULT_APP_NAME)) .withRequiredArg(); OptionSet options; @@ -52,7 +52,7 @@ public class BitsquareAppMain extends BitsquareExecutable { BitsquareEnvironment bitsquareEnvironment = new BitsquareEnvironment(options); // need to call that before BitsquareAppMain().execute(args) - BitsquareExecutable.initAppDir(bitsquareEnvironment.getProperty(CoreOptionKeys.APP_DATA_DIR_KEY)); + BitsquareExecutable.initAppDir(bitsquareEnvironment.getProperty(AppOptionKeys.APP_DATA_DIR_KEY)); // For some reason the JavaFX launch process results in us losing the thread context class loader: reset it. // In order to work around a bug in JavaFX 8u25 and below, you must include the following code as the first line of your realMain method: diff --git a/gui/src/main/java/io/bitsquare/gui/GuiModule.java b/gui/src/main/java/io/bitsquare/gui/GuiModule.java index 286e7b60c4..55b1b2ec67 100644 --- a/gui/src/main/java/io/bitsquare/gui/GuiModule.java +++ b/gui/src/main/java/io/bitsquare/gui/GuiModule.java @@ -20,7 +20,7 @@ package io.bitsquare.gui; import com.google.inject.Singleton; import com.google.inject.name.Names; import io.bitsquare.app.AppModule; -import io.bitsquare.app.CoreOptionKeys; +import io.bitsquare.app.AppOptionKeys; import io.bitsquare.gui.common.fxml.FxmlViewLoader; import io.bitsquare.gui.common.view.CachingViewLoader; import io.bitsquare.gui.common.view.ViewFactory; @@ -69,6 +69,6 @@ public class GuiModule extends AppModule { bind(Stage.class).toInstance(primaryStage); - bindConstant().annotatedWith(Names.named(MainView.TITLE_KEY)).to(env.getRequiredProperty(CoreOptionKeys.APP_NAME_KEY)); + bindConstant().annotatedWith(Names.named(MainView.TITLE_KEY)).to(env.getRequiredProperty(AppOptionKeys.APP_NAME_KEY)); } } diff --git a/gui/src/main/java/io/bitsquare/gui/main/MainView.java b/gui/src/main/java/io/bitsquare/gui/main/MainView.java index a8e3a18a3a..f0b542e2ae 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/MainView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/MainView.java @@ -259,7 +259,7 @@ public class MainView extends InitializableView { }); // Delay a bit to give time for rendering the splash screen - UserThread.execute(model::initializeAllServices); + UserThread.execute(model::start); } private Tuple2 getBalanceBox(String text) { diff --git a/gui/src/main/java/io/bitsquare/gui/main/MainViewModel.java b/gui/src/main/java/io/bitsquare/gui/main/MainViewModel.java index 5b75089cd5..2365ce993e 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/MainViewModel.java +++ b/gui/src/main/java/io/bitsquare/gui/main/MainViewModel.java @@ -47,6 +47,7 @@ import io.bitsquare.gui.components.BalanceWithConfirmationTextField; import io.bitsquare.gui.components.TxIdTextField; import io.bitsquare.gui.main.overlays.notifications.NotificationCenter; import io.bitsquare.gui.main.overlays.popups.Popup; +import io.bitsquare.gui.main.overlays.windows.AddBitcoinNodesWindow; import io.bitsquare.gui.main.overlays.windows.DisplayAlertMessageWindow; import io.bitsquare.gui.main.overlays.windows.TacWindow; import io.bitsquare.gui.main.overlays.windows.WalletPasswordWindow; @@ -108,6 +109,7 @@ public class MainViewModel implements ViewModel { private PrivateNotificationManager privateNotificationManager; private FilterManager filterManager; private final WalletPasswordWindow walletPasswordWindow; + private AddBitcoinNodesWindow addBitcoinNodesWindow; private final NotificationCenter notificationCenter; private final TacWindow tacWindow; private Clock clock; @@ -177,7 +179,7 @@ public class MainViewModel implements ViewModel { ArbitratorManager arbitratorManager, P2PService p2PService, TradeManager tradeManager, OpenOfferManager openOfferManager, DisputeManager disputeManager, Preferences preferences, User user, AlertManager alertManager, PrivateNotificationManager privateNotificationManager, - FilterManager filterManager, WalletPasswordWindow walletPasswordWindow, + FilterManager filterManager, WalletPasswordWindow walletPasswordWindow, AddBitcoinNodesWindow addBitcoinNodesWindow, NotificationCenter notificationCenter, TacWindow tacWindow, Clock clock, KeyRing keyRing, Navigation navigation, BSFormatter formatter) { this.priceFeedService = priceFeedService; @@ -194,6 +196,7 @@ public class MainViewModel implements ViewModel { this.privateNotificationManager = privateNotificationManager; this.filterManager = filterManager; // Reference so it's initialized and eventlistener gets registered this.walletPasswordWindow = walletPasswordWindow; + this.addBitcoinNodesWindow = addBitcoinNodesWindow; this.notificationCenter = notificationCenter; this.tacWindow = tacWindow; this.clock = clock; @@ -215,11 +218,30 @@ public class MainViewModel implements ViewModel { // API /////////////////////////////////////////////////////////////////////////////////////////// - public void initializeAllServices() { + public void start() { + String key = "showAddBitcoinNodesWindowKey"; + if (preferences.showAgain(key)) + addBitcoinNodesWindow.dontShowAgainId(key, preferences) + .onClose(() -> { + preferences.dontShowAgain(key, true); + initializeAllServices(); + }) + .onAction(() -> { + preferences.dontShowAgain(key, true); + initializeAllServices(); + }) + .show(); + else + initializeAllServices(); + } + + private void initializeAllServices() { + log.error("initializeAllServices"); Log.traceCall(); UserThread.runAfter(tacWindow::showIfNeeded, 2); + ChangeListener walletInitializedListener = (observable, oldValue, newValue) -> { if (newValue && !p2pNetWorkReady.get()) showStartupTimeoutPopup(); diff --git a/gui/src/main/java/io/bitsquare/gui/main/account/content/backup/BackupView.java b/gui/src/main/java/io/bitsquare/gui/main/account/content/backup/BackupView.java index 95ec90910e..f448620eb3 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/account/content/backup/BackupView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/account/content/backup/BackupView.java @@ -17,8 +17,8 @@ package io.bitsquare.gui.main.account.content.backup; +import io.bitsquare.app.AppOptionKeys; import io.bitsquare.app.BitsquareEnvironment; -import io.bitsquare.app.CoreOptionKeys; import io.bitsquare.common.util.Tuple3; import io.bitsquare.common.util.Utilities; import io.bitsquare.gui.common.view.ActivatableView; @@ -63,7 +63,7 @@ public class BackupView extends ActivatableView { super(); this.stage = stage; this.preferences = preferences; - dataDir = new File(environment.getProperty(CoreOptionKeys.APP_DATA_DIR_KEY)); + dataDir = new File(environment.getProperty(AppOptionKeys.APP_DATA_DIR_KEY)); } @Override diff --git a/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/AddBitcoinNodesWindow.java b/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/AddBitcoinNodesWindow.java new file mode 100644 index 0000000000..287614eb67 --- /dev/null +++ b/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/AddBitcoinNodesWindow.java @@ -0,0 +1,129 @@ +/* + * 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.gui.main.overlays.windows; + +import de.jensd.fx.fontawesome.AwesomeIcon; +import io.bitsquare.common.util.Tuple2; +import io.bitsquare.gui.components.HyperlinkWithIcon; +import io.bitsquare.gui.components.InputTextField; +import io.bitsquare.gui.main.overlays.Overlay; +import io.bitsquare.gui.util.GUIUtil; +import io.bitsquare.user.Preferences; +import javafx.geometry.HPos; +import javafx.geometry.Insets; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.input.KeyCode; +import javafx.scene.layout.GridPane; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.inject.Inject; + +import static io.bitsquare.gui.util.FormBuilder.*; + +public class AddBitcoinNodesWindow extends Overlay { + private static final Logger log = LoggerFactory.getLogger(AddBitcoinNodesWindow.class); + private Button saveButton; + private Preferences preferences; + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Public API + /////////////////////////////////////////////////////////////////////////////////////////// + + @Inject + public AddBitcoinNodesWindow(Preferences preferences) { + this.preferences = preferences; + type = Type.Attention; + } + + public void show() { + if (headLine == null) + headLine = "Protect your privacy"; + + width = 900; + createGridPane(); + addHeadLine(); + addSeparator(); + addContent(); + applyStyles(); + display(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Protected + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + protected void setupKeyHandler(Scene scene) { + if (!hideCloseButton) { + scene.setOnKeyPressed(e -> { + if (e.getCode() == KeyCode.ESCAPE) { + e.consume(); + doClose(); + } + }); + } + } + + private void addContent() { + Label label = addLabel(gridPane, ++rowIndex, "For the best protection of your privacy is it recommended that you run your own Bitcoin core node.\n" + + "You can run it locally (127.0.0.1) or hosted on a VPS.\n" + + "You can edit that settings in \"Settings/Network info\".\n\n" + + "If you prefer to use the public Bitcoin network your Bitcoin transactions might get de-anonymized by chain analysis companies operating full nodes to spy on Bitcoin users.\n\n" + + "To learn more about that topic please read our FAQ on Bitsquare.io."); + label.setWrapText(true); + GridPane.setColumnSpan(label, 2); + GridPane.setHalignment(label, HPos.LEFT); + + HyperlinkWithIcon hyperlinkWithIcon = new HyperlinkWithIcon("Open Bitsquare FAQ", AwesomeIcon.EXTERNAL_LINK); + hyperlinkWithIcon.setOnAction(e -> GUIUtil.openWebPage("https://bitsquare.io/faq/#privacy_btc")); + GridPane.setRowIndex(hyperlinkWithIcon, ++rowIndex); + GridPane.setColumnIndex(hyperlinkWithIcon, 0); + GridPane.setMargin(hyperlinkWithIcon, new Insets(0, 0, 0, -4)); + GridPane.setHalignment(hyperlinkWithIcon, HPos.LEFT); + gridPane.getChildren().add(hyperlinkWithIcon); + + Tuple2 labelInputTextFieldTuple2 = addLabelInputTextField(gridPane, ++rowIndex, "Add custom Bitcoin nodes:", 20); + InputTextField input = labelInputTextFieldTuple2.second; + input.setPromptText("Add comma separated IP addresses"); + if (!preferences.getBitcoinNodes().isEmpty()) + input.setText(preferences.getBitcoinNodes()); + + Tuple2 tuple = add2Buttons(gridPane, ++rowIndex, "Save", "Ignore and use public Bitcoin network nodes"); + saveButton = tuple.first; + saveButton.setOnAction(e -> { + preferences.setBitcoinNodes(input.getText()); + hide(); + closeHandlerOptional.ifPresent(Runnable::run); + }); + + closeButton = tuple.second; + closeButton.setOnAction(e -> { + preferences.setBitcoinNodes(""); + hide(); + closeHandlerOptional.ifPresent(Runnable::run); + }); + + // Add some space + ++rowIndex; + } +} diff --git a/gui/src/main/java/io/bitsquare/gui/main/settings/network/NetworkSettingsView.fxml b/gui/src/main/java/io/bitsquare/gui/main/settings/network/NetworkSettingsView.fxml index 1a9b56c5ef..ccfa015452 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/settings/network/NetworkSettingsView.fxml +++ b/gui/src/main/java/io/bitsquare/gui/main/settings/network/NetworkSettingsView.fxml @@ -17,6 +17,7 @@ ~ along with Bitsquare. If not, see . --> + @@ -32,7 +33,7 @@ - +