From 201f9a0fbc84fe036f3527c8fe6930aa1ab1ecf3 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 30 Jan 2019 11:38:43 +0100 Subject: [PATCH] Delete tor files at startup We get sometimes Tor startup problems which is related to some tor files in the tor directory. It happens more often if the application got killed (not graceful shutdown). Creating all tor files newly takes about 3-4 sec. longer and it does not benefit from cache files. TODO: We should fix those startup problems in the netlayer library, once fixed there we can remove that call at the Bisq startup again. --- core/src/main/java/bisq/core/CoreModule.java | 2 + .../main/java/bisq/core/app/BisqSetup.java | 4 ++ .../src/main/java/bisq/core/app/TorSetup.java | 69 +++++++++++++++++++ .../bisq/core/app/misc/AppSetupWithP2P.java | 9 ++- .../core/app/misc/AppSetupWithP2PAndDAO.java | 5 +- .../core/app/misc/ModuleForAppWithP2p.java | 2 + .../windows/TorNetworkSettingsWindow.java | 26 ++----- 7 files changed, 94 insertions(+), 23 deletions(-) create mode 100644 core/src/main/java/bisq/core/app/TorSetup.java diff --git a/core/src/main/java/bisq/core/CoreModule.java b/core/src/main/java/bisq/core/CoreModule.java index db41abc2211..6058ba71f33 100644 --- a/core/src/main/java/bisq/core/CoreModule.java +++ b/core/src/main/java/bisq/core/CoreModule.java @@ -23,6 +23,7 @@ import bisq.core.app.BisqEnvironment; import bisq.core.app.BisqSetup; import bisq.core.app.P2PNetworkSetup; +import bisq.core.app.TorSetup; import bisq.core.app.WalletAppSetup; import bisq.core.arbitration.ArbitratorModule; import bisq.core.btc.BitcoinModule; @@ -80,6 +81,7 @@ public CoreModule(Environment environment) { @Override protected void configure() { bind(BisqSetup.class).in(Singleton.class); + bind(TorSetup.class).in(Singleton.class); bind(P2PNetworkSetup.class).in(Singleton.class); bind(WalletAppSetup.class).in(Singleton.class); diff --git a/core/src/main/java/bisq/core/app/BisqSetup.java b/core/src/main/java/bisq/core/app/BisqSetup.java index cb8e6aa997e..cbc70acad20 100644 --- a/core/src/main/java/bisq/core/app/BisqSetup.java +++ b/core/src/main/java/bisq/core/app/BisqSetup.java @@ -150,6 +150,7 @@ public interface BisqSetupCompleteListener { private final VoteResultService voteResultService; private final AssetTradeActivityCheck tradeActivityCheck; private final AssetService assetService; + private final TorSetup torSetup; private final BSFormatter formatter; @Setter @Nullable @@ -226,6 +227,7 @@ public BisqSetup(P2PNetworkSetup p2PNetworkSetup, VoteResultService voteResultService, AssetTradeActivityCheck tradeActivityCheck, AssetService assetService, + TorSetup torSetup, BSFormatter formatter) { @@ -264,6 +266,7 @@ public BisqSetup(P2PNetworkSetup p2PNetworkSetup, this.voteResultService = voteResultService; this.tradeActivityCheck = tradeActivityCheck; this.assetService = assetService; + this.torSetup = torSetup; this.formatter = formatter; } @@ -286,6 +289,7 @@ private void step2() { } private void step3() { + torSetup.cleanupTorFiles(); readMapsFromResources(); checkCryptoSetup(); checkForCorrectOSArchitecture(); diff --git a/core/src/main/java/bisq/core/app/TorSetup.java b/core/src/main/java/bisq/core/app/TorSetup.java new file mode 100644 index 00000000000..238e23e97a4 --- /dev/null +++ b/core/src/main/java/bisq/core/app/TorSetup.java @@ -0,0 +1,69 @@ +/* + * This file is part of Bisq. + * + * Bisq 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. + * + * Bisq 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 Bisq. If not, see . + */ + +package bisq.core.app; + +import bisq.network.NetworkOptionKeys; + +import bisq.common.handlers.ErrorMessageHandler; +import bisq.common.storage.FileUtil; + +import com.google.inject.name.Named; + +import javax.inject.Inject; + +import java.nio.file.Paths; + +import java.io.File; +import java.io.IOException; + +import lombok.extern.slf4j.Slf4j; + +import javax.annotation.Nullable; + +@Slf4j +public class TorSetup { + private File torDir; + + @Inject + public TorSetup(@Named(NetworkOptionKeys.TOR_DIR) File torDir) { + this.torDir = torDir; + } + + public void cleanupTorFiles() { + cleanupTorFiles(null, null); + } + + // We get sometimes Tor startup problems which is related to some tor files in the tor directory. It happens + // more often if the application got killed (not graceful shutdown). + // Creating all tor files newly takes about 3-4 sec. longer and it does not benefit from cache files. + // TODO: We should fix those startup problems in the netlayer library, once fixed there we can remove that call at the + // Bisq startup again. + public void cleanupTorFiles(@Nullable Runnable resultHandler, @Nullable ErrorMessageHandler errorMessageHandler) { + File hiddenservice = new File(Paths.get(torDir.getAbsolutePath(), "hiddenservice").toString()); + try { + FileUtil.deleteDirectory(torDir, hiddenservice, true); + if (resultHandler != null) + resultHandler.run(); + } catch (IOException e) { + e.printStackTrace(); + log.error(e.toString()); + if (errorMessageHandler != null) + errorMessageHandler.handleErrorMessage(e.toString()); + } + } +} diff --git a/core/src/main/java/bisq/core/app/misc/AppSetupWithP2P.java b/core/src/main/java/bisq/core/app/misc/AppSetupWithP2P.java index 89adeacab21..1cb08ab7f80 100644 --- a/core/src/main/java/bisq/core/app/misc/AppSetupWithP2P.java +++ b/core/src/main/java/bisq/core/app/misc/AppSetupWithP2P.java @@ -18,6 +18,7 @@ package bisq.core.app.misc; import bisq.core.app.SetupUtils; +import bisq.core.app.TorSetup; import bisq.core.filter.FilterManager; import bisq.core.payment.AccountAgeWitnessService; import bisq.core.trade.statistics.TradeStatisticsManager; @@ -46,6 +47,7 @@ public class AppSetupWithP2P extends AppSetup { protected final P2PService p2PService; protected final AccountAgeWitnessService accountAgeWitnessService; protected final FilterManager filterManager; + private final TorSetup torSetup; protected BooleanProperty p2pNetWorkReady; protected final TradeStatisticsManager tradeStatisticsManager; protected ArrayList persistedDataHosts; @@ -56,21 +58,24 @@ public AppSetupWithP2P(EncryptionService encryptionService, P2PService p2PService, TradeStatisticsManager tradeStatisticsManager, AccountAgeWitnessService accountAgeWitnessService, - FilterManager filterManager) { + FilterManager filterManager, + TorSetup torSetup) { super(encryptionService, keyRing); this.p2PService = p2PService; this.tradeStatisticsManager = tradeStatisticsManager; this.accountAgeWitnessService = accountAgeWitnessService; this.filterManager = filterManager; + this.torSetup = torSetup; this.persistedDataHosts = new ArrayList<>(); } @Override public void initPersistedDataHosts() { + torSetup.cleanupTorFiles(); persistedDataHosts.add(p2PService); // we apply at startup the reading of persisted data but don't want to get it triggered in the constructor - persistedDataHosts.stream().forEach(e -> { + persistedDataHosts.forEach(e -> { try { log.info("call readPersisted at " + e.getClass().getSimpleName()); e.readPersisted(); diff --git a/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java b/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java index 50628e336e2..4a2a89c2953 100644 --- a/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java +++ b/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java @@ -17,6 +17,7 @@ package bisq.core.app.misc; +import bisq.core.app.TorSetup; import bisq.core.dao.DaoOptionKeys; import bisq.core.dao.DaoSetup; import bisq.core.dao.governance.ballot.BallotListService; @@ -57,13 +58,15 @@ public AppSetupWithP2PAndDAO(EncryptionService encryptionService, MyProposalListService myProposalListService, MyReputationListService myReputationListService, MyProofOfBurnListService myProofOfBurnListService, + TorSetup torSetup, @Named(DaoOptionKeys.DAO_ACTIVATED) boolean daoActivated) { super(encryptionService, keyRing, p2PService, tradeStatisticsManager, accountAgeWitnessService, - filterManager); + filterManager, + torSetup); this.daoSetup = daoSetup; diff --git a/core/src/main/java/bisq/core/app/misc/ModuleForAppWithP2p.java b/core/src/main/java/bisq/core/app/misc/ModuleForAppWithP2p.java index 64cfcb465e3..16d1c87ea70 100644 --- a/core/src/main/java/bisq/core/app/misc/ModuleForAppWithP2p.java +++ b/core/src/main/java/bisq/core/app/misc/ModuleForAppWithP2p.java @@ -20,6 +20,7 @@ import bisq.core.alert.AlertModule; import bisq.core.app.AppOptionKeys; import bisq.core.app.BisqEnvironment; +import bisq.core.app.TorSetup; import bisq.core.arbitration.ArbitratorModule; import bisq.core.btc.BitcoinModule; import bisq.core.dao.DaoModule; @@ -74,6 +75,7 @@ protected void configure() { bind(PersistenceProtoResolver.class).to(CorePersistenceProtoResolver.class).in(Singleton.class); bind(Preferences.class).in(Singleton.class); bind(BridgeAddressProvider.class).to(Preferences.class).in(Singleton.class); + bind(TorSetup.class).in(Singleton.class); bind(SeedNodeAddressLookup.class).in(Singleton.class); bind(SeedNodeRepository.class).to(DefaultSeedNodeRepository.class).in(Singleton.class); diff --git a/desktop/src/main/java/bisq/desktop/main/overlays/windows/TorNetworkSettingsWindow.java b/desktop/src/main/java/bisq/desktop/main/overlays/windows/TorNetworkSettingsWindow.java index 6fb693d22cc..5fd771c9248 100644 --- a/desktop/src/main/java/bisq/desktop/main/overlays/windows/TorNetworkSettingsWindow.java +++ b/desktop/src/main/java/bisq/desktop/main/overlays/windows/TorNetworkSettingsWindow.java @@ -25,21 +25,18 @@ import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.util.Layout; +import bisq.core.app.TorSetup; import bisq.core.locale.Res; import bisq.core.user.Preferences; -import bisq.network.NetworkOptionKeys; import bisq.network.p2p.network.DefaultPluggableTransports; import bisq.network.p2p.network.NetworkNode; import bisq.common.UserThread; -import bisq.common.storage.FileUtil; import bisq.common.util.Tuple2; import bisq.common.util.Tuple4; import bisq.common.util.Utilities; -import com.google.inject.name.Named; - import javax.inject.Inject; import javafx.scene.Scene; @@ -65,9 +62,6 @@ import java.net.URI; -import java.nio.file.Paths; - -import java.io.File; import java.io.IOException; import java.util.Arrays; @@ -94,8 +88,8 @@ public enum Transport { } private final Preferences preferences; - private NetworkNode networkNode; - private final File torDir; + private final NetworkNode networkNode; + private final TorSetup torSetup; private Label enterBridgeLabel; private ComboBox transportTypeComboBox; private TextArea bridgeEntriesTextArea; @@ -106,10 +100,10 @@ public enum Transport { @Inject public TorNetworkSettingsWindow(Preferences preferences, NetworkNode networkNode, - @Named(NetworkOptionKeys.TOR_DIR) File torDir) { + TorSetup torSetup) { this.preferences = preferences; this.networkNode = networkNode; - this.torDir = torDir; + this.torSetup = torSetup; type = Type.Attention; @@ -342,15 +336,7 @@ private void cleanTorDir(Runnable resultHandler) { networkNode.shutDown(() -> { // We give it a bit extra time to be sure that OS locks are removed UserThread.runAfter(() -> { - final File hiddenservice = new File(Paths.get(torDir.getAbsolutePath(), "hiddenservice").toString()); - try { - FileUtil.deleteDirectory(torDir, hiddenservice, true); - resultHandler.run(); - } catch (IOException e) { - e.printStackTrace(); - log.error(e.toString()); - new Popup<>().error(e.toString()).show(); - } + torSetup.cleanupTorFiles(resultHandler, errorMessage -> new Popup<>().error(errorMessage).show()); }, 3); }); }