mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 18:03:12 +01:00
Merge branch 'master_upstream' into reenable-chat-on-dispute-reopen
This commit is contained in:
commit
a148850685
@ -497,6 +497,14 @@ configure(project(':pricenode')) {
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
|
||||
// Disabled by default, since spot provider tests include connections to external API endpoints
|
||||
// Can be enabled by adding -Dtest.pricenode.includeSpotProviderTests=true to the gradle command:
|
||||
// ./gradlew test -Dtest.pricenode.includeSpotProviderTests=true
|
||||
if (System.properties['test.pricenode.includeSpotProviderTests'] != 'true') {
|
||||
project.logger.lifecycle('Pricenode: Skipping spot provider tests')
|
||||
exclude 'bisq/price/spot/providers/**'
|
||||
}
|
||||
}
|
||||
|
||||
task stage {
|
||||
|
@ -67,7 +67,7 @@ public abstract class BisqExecutable implements GracefulShutDownHandler, BisqSet
|
||||
protected Injector injector;
|
||||
protected AppModule module;
|
||||
protected Config config;
|
||||
private boolean isShutdown = false;
|
||||
private boolean isShutdownInProgress;
|
||||
|
||||
public BisqExecutable(String fullName, String scriptName, String appName, String version) {
|
||||
this.fullName = fullName;
|
||||
@ -204,47 +204,56 @@ public abstract class BisqExecutable implements GracefulShutDownHandler, BisqSet
|
||||
// This might need to be overwritten in case the application is not using all modules
|
||||
@Override
|
||||
public void gracefulShutDown(ResultHandler resultHandler) {
|
||||
if (isShutdown) // prevent double cleanup
|
||||
log.info("Start graceful shutDown");
|
||||
if (isShutdownInProgress) {
|
||||
return;
|
||||
}
|
||||
|
||||
isShutdownInProgress = true;
|
||||
|
||||
if (injector == null) {
|
||||
log.warn("Shut down called before injector was created");
|
||||
resultHandler.handleResult();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
isShutdown = true;
|
||||
try {
|
||||
if (injector != null) {
|
||||
injector.getInstance(ArbitratorManager.class).shutDown();
|
||||
injector.getInstance(TradeManager.class).shutDown();
|
||||
injector.getInstance(DaoSetup.class).shutDown();
|
||||
injector.getInstance(OpenOfferManager.class).shutDown(() -> {
|
||||
log.info("OpenOfferManager shutdown completed");
|
||||
injector.getInstance(ArbitratorManager.class).shutDown();
|
||||
injector.getInstance(TradeManager.class).shutDown();
|
||||
injector.getInstance(DaoSetup.class).shutDown();
|
||||
injector.getInstance(AvoidStandbyModeService.class).shutDown();
|
||||
injector.getInstance(OpenOfferManager.class).shutDown(() -> {
|
||||
log.info("OpenOfferManager shutdown completed");
|
||||
|
||||
injector.getInstance(BtcWalletService.class).shutDown();
|
||||
injector.getInstance(BsqWalletService.class).shutDown();
|
||||
|
||||
// We need to shutdown BitcoinJ before the P2PService as it uses Tor.
|
||||
WalletsSetup walletsSetup = injector.getInstance(WalletsSetup.class);
|
||||
walletsSetup.shutDownComplete.addListener((ov, o, n) -> {
|
||||
log.info("WalletsSetup shutdown completed");
|
||||
|
||||
injector.getInstance(P2PService.class).shutDown(() -> {
|
||||
log.info("P2PService shutdown completed");
|
||||
injector.getInstance(WalletsSetup.class).shutDownComplete.addListener((ov, o, n) -> {
|
||||
log.info("WalletsSetup shutdown completed");
|
||||
module.close(injector);
|
||||
resultHandler.handleResult();
|
||||
log.info("Graceful shutdown completed. Exiting now.");
|
||||
System.exit(0);
|
||||
});
|
||||
injector.getInstance(WalletsSetup.class).shutDown();
|
||||
injector.getInstance(BtcWalletService.class).shutDown();
|
||||
injector.getInstance(BsqWalletService.class).shutDown();
|
||||
|
||||
module.close(injector);
|
||||
resultHandler.handleResult();
|
||||
log.info("Graceful shutdown completed. Exiting now.");
|
||||
System.exit(0);
|
||||
});
|
||||
});
|
||||
injector.getInstance(AvoidStandbyModeService.class).shutDown();
|
||||
// we wait max 20 sec.
|
||||
UserThread.runAfter(() -> {
|
||||
log.warn("Timeout triggered resultHandler");
|
||||
resultHandler.handleResult();
|
||||
System.exit(0);
|
||||
}, 20);
|
||||
} else {
|
||||
log.warn("injector == null triggered resultHandler");
|
||||
UserThread.runAfter(() -> {
|
||||
resultHandler.handleResult();
|
||||
System.exit(0);
|
||||
}, 1);
|
||||
}
|
||||
walletsSetup.shutDown();
|
||||
|
||||
});
|
||||
|
||||
// Wait max 20 sec.
|
||||
UserThread.runAfter(() -> {
|
||||
log.warn("Timeout triggered resultHandler");
|
||||
resultHandler.handleResult();
|
||||
System.exit(0);
|
||||
}, 20);
|
||||
} catch (Throwable t) {
|
||||
log.error("App shutdown failed with exception");
|
||||
log.error("App shutdown failed with exception {}", t.toString());
|
||||
t.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
|
@ -492,8 +492,11 @@ public class WalletConfig extends AbstractIdleService {
|
||||
}
|
||||
}
|
||||
|
||||
private Wallet createOrLoadWallet(File walletFile, boolean shouldReplayWallet,
|
||||
BisqKeyChainGroup keyChainGroup, boolean isBsqWallet, DeterministicSeed restoreFromSeed)
|
||||
private Wallet createOrLoadWallet(File walletFile,
|
||||
boolean shouldReplayWallet,
|
||||
BisqKeyChainGroup keyChainGroup,
|
||||
boolean isBsqWallet,
|
||||
DeterministicSeed restoreFromSeed)
|
||||
throws Exception {
|
||||
|
||||
if (restoreFromSeed != null)
|
||||
@ -530,7 +533,9 @@ public class WalletConfig extends AbstractIdleService {
|
||||
}
|
||||
}
|
||||
|
||||
private Wallet loadWallet(File walletFile, boolean shouldReplayWallet, boolean useBitcoinDeterministicKeyChain) throws Exception {
|
||||
private Wallet loadWallet(File walletFile,
|
||||
boolean shouldReplayWallet,
|
||||
boolean useBitcoinDeterministicKeyChain) throws Exception {
|
||||
Wallet wallet;
|
||||
try (FileInputStream walletStream = new FileInputStream(walletFile)) {
|
||||
List<WalletExtension> extensions = provideWalletExtensions();
|
||||
@ -570,21 +575,30 @@ public class WalletConfig extends AbstractIdleService {
|
||||
// Runs in a separate thread.
|
||||
try {
|
||||
Context.propagate(context);
|
||||
vPeerGroup.stop();
|
||||
vBtcWallet.saveToFile(vBtcWalletFile);
|
||||
if (vBsqWallet != null && vBsqWalletFile != null)
|
||||
//noinspection ConstantConditions,ConstantConditions
|
||||
vBsqWallet.saveToFile(vBsqWalletFile);
|
||||
vStore.close();
|
||||
|
||||
vPeerGroup = null;
|
||||
vBtcWallet.saveToFile(vBtcWalletFile);
|
||||
vBtcWallet = null;
|
||||
vBsqWallet = null;
|
||||
log.info("BtcWallet saved to file");
|
||||
|
||||
if (vBsqWallet != null && vBsqWalletFile != null) {
|
||||
vBsqWallet.saveToFile(vBsqWalletFile);
|
||||
vBsqWallet = null;
|
||||
log.info("BsqWallet saved to file");
|
||||
}
|
||||
|
||||
vStore.close();
|
||||
vStore = null;
|
||||
log.info("SPV file closed");
|
||||
|
||||
vChain = null;
|
||||
|
||||
// vPeerGroup.stop has no timeout and can take very long (10 sec. in my test). So we call it at the end.
|
||||
// We might get likely interrupted by the parent call timeout.
|
||||
vPeerGroup.stop();
|
||||
vPeerGroup = null;
|
||||
log.info("PeerGroup stopped");
|
||||
} catch (BlockStoreException e) {
|
||||
throw new IOException(e);
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,6 @@
|
||||
package bisq.core.btc.setup;
|
||||
|
||||
import bisq.core.btc.exceptions.InvalidHostException;
|
||||
import bisq.core.btc.nodes.LocalBitcoinNode;
|
||||
import bisq.core.btc.exceptions.RejectedTxException;
|
||||
import bisq.core.btc.model.AddressEntry;
|
||||
import bisq.core.btc.model.AddressEntryList;
|
||||
@ -27,6 +26,7 @@ import bisq.core.btc.nodes.BtcNodes;
|
||||
import bisq.core.btc.nodes.BtcNodes.BtcNode;
|
||||
import bisq.core.btc.nodes.BtcNodesRepository;
|
||||
import bisq.core.btc.nodes.BtcNodesSetupPreferences;
|
||||
import bisq.core.btc.nodes.LocalBitcoinNode;
|
||||
import bisq.core.user.Preferences;
|
||||
|
||||
import bisq.network.Socks5MultiDiscovery;
|
||||
@ -314,14 +314,16 @@ public class WalletsSetup {
|
||||
public void shutDown() {
|
||||
if (walletConfig != null) {
|
||||
try {
|
||||
log.info("walletConfig shutDown started");
|
||||
walletConfig.stopAsync();
|
||||
walletConfig.awaitTerminated(5, TimeUnit.SECONDS);
|
||||
walletConfig.awaitTerminated(1, TimeUnit.SECONDS);
|
||||
log.info("walletConfig shutDown completed");
|
||||
} catch (Throwable ignore) {
|
||||
log.info("walletConfig shutDown interrupted by timeout");
|
||||
}
|
||||
shutDownComplete.set(true);
|
||||
} else {
|
||||
shutDownComplete.set(true);
|
||||
}
|
||||
|
||||
shutDownComplete.set(true);
|
||||
}
|
||||
|
||||
public void reSyncSPVChain() throws IOException {
|
||||
|
@ -82,6 +82,8 @@ public final class Preferences implements PersistedDataHost, BridgeAddressProvid
|
||||
new BlockChainExplorer("mempool.space Tor V3", "http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/tx/", "http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/address/"),
|
||||
new BlockChainExplorer("mempool.emzy.de (@emzy)", "https://mempool.emzy.de/tx/", "https://mempool.emzy.de/address/"),
|
||||
new BlockChainExplorer("mempool.emzy.de Tor V3", "http://mempool4t6mypeemozyterviq3i5de4kpoua65r3qkn5i3kknu5l2cad.onion/tx/", "http://mempool4t6mypeemozyterviq3i5de4kpoua65r3qkn5i3kknu5l2cad.onion/address/"),
|
||||
new BlockChainExplorer("mempool.bisq.services (@devinbileck)", "https://mempool.bisq.services/tx/", "https://mempool.bisq.services/address/"),
|
||||
new BlockChainExplorer("mempool.bisq.services Tor V3", "http://mempoolusb2f67qi7mz2it7n5e77a6komdzx6wftobcduxszkdfun2yd.onion/tx/", "http://mempoolusb2f67qi7mz2it7n5e77a6komdzx6wftobcduxszkdfun2yd.onion/address/"),
|
||||
new BlockChainExplorer("Blockstream.info", "https://blockstream.info/tx/", "https://blockstream.info/address/"),
|
||||
new BlockChainExplorer("Blockstream.info Tor V3", "http://explorerzydxu5ecjrkwceayqybizmpjjznk5izmitf2modhcusuqlid.onion/tx/", "http://explorerzydxu5ecjrkwceayqybizmpjjznk5izmitf2modhcusuqlid.onion/address/"),
|
||||
new BlockChainExplorer("OXT", "https://oxt.me/transaction/", "https://oxt.me/address/"),
|
||||
|
@ -123,6 +123,7 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||
private final IntegerProperty numConnectedPeers = new SimpleIntegerProperty(0);
|
||||
|
||||
private volatile boolean shutDownInProgress;
|
||||
@Getter
|
||||
private boolean shutDownComplete;
|
||||
private final Subscription networkReadySubscription;
|
||||
private boolean isBootstrapped;
|
||||
@ -446,7 +447,9 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoved(Collection<ProtectedStorageEntry> protectedStorageEntries) { }
|
||||
public void onRemoved(Collection<ProtectedStorageEntry> protectedStorageEntries) {
|
||||
// not handled
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// DirectMessages
|
||||
@ -463,7 +466,9 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||
}
|
||||
}
|
||||
|
||||
private void doSendEncryptedDirectMessage(@NotNull NodeAddress peersNodeAddress, PubKeyRing pubKeyRing, NetworkEnvelope message,
|
||||
private void doSendEncryptedDirectMessage(@NotNull NodeAddress peersNodeAddress,
|
||||
PubKeyRing pubKeyRing,
|
||||
NetworkEnvelope message,
|
||||
SendDirectMessageListener sendDirectMessageListener) {
|
||||
log.debug("Send encrypted direct message {} to peer {}",
|
||||
message.getClass().getSimpleName(), peersNodeAddress);
|
||||
@ -691,7 +696,9 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBroadcastCompleted(BroadcastMessage message, int numOfCompletedBroadcasts, int numOfFailedBroadcasts) {
|
||||
public void onBroadcastCompleted(BroadcastMessage message,
|
||||
int numOfCompletedBroadcasts,
|
||||
int numOfFailedBroadcasts) {
|
||||
log.info("Broadcast completed: Sent to {} peers (failed: {}). Message = {}",
|
||||
numOfCompletedBroadcasts, numOfFailedBroadcasts, Utilities.toTruncatedString(message));
|
||||
if (numOfCompletedBroadcasts == 0)
|
||||
|
@ -332,7 +332,17 @@ public abstract class NetworkNode implements MessageListener {
|
||||
|
||||
Set<Connection> allConnections = getAllConnections();
|
||||
int numConnections = allConnections.size();
|
||||
|
||||
if (numConnections == 0) {
|
||||
log.info("Shutdown immediately because no connections are open.");
|
||||
if (shutDownCompleteHandler != null) {
|
||||
shutDownCompleteHandler.run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("Shutdown {} connections", numConnections);
|
||||
|
||||
AtomicInteger shutdownCompleted = new AtomicInteger();
|
||||
Timer timeoutHandler = UserThread.runAfter(() -> {
|
||||
if (shutDownCompleteHandler != null) {
|
||||
@ -340,6 +350,7 @@ public abstract class NetworkNode implements MessageListener {
|
||||
shutDownCompleteHandler.run();
|
||||
}
|
||||
}, 3);
|
||||
|
||||
allConnections.forEach(c -> c.shutDown(CloseConnectionReason.APP_SHUT_DOWN,
|
||||
() -> {
|
||||
shutdownCompleted.getAndIncrement();
|
||||
|
@ -5,5 +5,5 @@ spring.jackson.serialization.indent_output=true
|
||||
bisq.price.mining.providers.mempoolHostname.1=mempool.space
|
||||
bisq.price.mining.providers.mempoolHostname.2=mempool.emzy.de
|
||||
bisq.price.mining.providers.mempoolHostname.3=mempool.ninja
|
||||
# bisq.price.mining.providers.mempoolHostname.4=someHostOrIP
|
||||
bisq.price.mining.providers.mempoolHostname.4=mempool.bisq.services
|
||||
# bisq.price.mining.providers.mempoolHostname.5=someHostOrIP
|
||||
|
Loading…
Reference in New Issue
Block a user