mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-08-14 09:25:37 -04:00
remove dependency on local BTC node
Co-authored-by: premek <1145361+premek@users.noreply.github.com>
This commit is contained in:
parent
1b78be689a
commit
9059974725
13 changed files with 143 additions and 161 deletions
|
@ -85,6 +85,7 @@ public class AppStartupState {
|
|||
p2pNetworkAndWalletInitialized.subscribe((observable, oldValue, newValue) -> {
|
||||
if (newValue) {
|
||||
applicationFullyInitialized.set(true);
|
||||
log.info("Application fully initialized");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
25
core/src/main/java/bisq/core/btc/setup/DownloadListener.java
Normal file
25
core/src/main/java/bisq/core/btc/setup/DownloadListener.java
Normal file
|
@ -0,0 +1,25 @@
|
|||
package bisq.core.btc.setup;
|
||||
|
||||
import bisq.common.UserThread;
|
||||
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
import javafx.beans.property.ReadOnlyDoubleProperty;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
class DownloadListener {
|
||||
private final DoubleProperty percentage = new SimpleDoubleProperty(-1);
|
||||
|
||||
protected void progress(double percentage, int blocksLeft, Date date) {
|
||||
UserThread.execute(() -> this.percentage.set(percentage / 100d));
|
||||
}
|
||||
|
||||
protected void doneDownload() {
|
||||
UserThread.execute(() -> this.percentage.set(1d));
|
||||
}
|
||||
|
||||
public ReadOnlyDoubleProperty percentageProperty() {
|
||||
return percentage;
|
||||
}
|
||||
}
|
|
@ -151,7 +151,7 @@ public class WalletConfig extends AbstractIdleService {
|
|||
protected volatile File vBtcWalletFile;
|
||||
|
||||
protected PeerAddress[] peerAddresses;
|
||||
protected DownloadProgressTracker downloadListener;
|
||||
protected DownloadListener downloadListener;
|
||||
protected InputStream checkpoints;
|
||||
protected String userAgent, version;
|
||||
@Nullable
|
||||
|
@ -234,7 +234,7 @@ public class WalletConfig extends AbstractIdleService {
|
|||
* If you want to learn about the sync process, you can provide a listener here. For instance, a
|
||||
* {@link DownloadProgressTracker} is a good choice.
|
||||
*/
|
||||
public WalletConfig setDownloadListener(DownloadProgressTracker listener) {
|
||||
public WalletConfig setDownloadListener(DownloadListener listener) {
|
||||
this.downloadListener = listener;
|
||||
return this;
|
||||
}
|
||||
|
@ -388,7 +388,8 @@ public class WalletConfig extends AbstractIdleService {
|
|||
System.out.println("Monero wallet uri: " + vXmrWallet.getRpcConnection().getUri());
|
||||
// vXmrWallet.rescanSpent();
|
||||
// vXmrWallet.rescanBlockchain();
|
||||
vXmrWallet.sync();
|
||||
vXmrWallet.sync(); // blocking
|
||||
downloadListener.doneDownload();
|
||||
vXmrWallet.save();
|
||||
System.out.println("Loaded wallet balance: " + vXmrWallet.getBalance(0));
|
||||
System.out.println("Loaded wallet unlocked balance: " + vXmrWallet.getUnlockedBalance(0));
|
||||
|
@ -471,7 +472,7 @@ public class WalletConfig extends AbstractIdleService {
|
|||
@Override
|
||||
public void onSuccess(@Nullable Object result) {
|
||||
//completeExtensionInitiations(vPeerGroup);
|
||||
DownloadProgressTracker tracker = downloadListener == null ? new DownloadProgressTracker() : downloadListener;
|
||||
DownloadProgressTracker tracker = new DownloadProgressTracker();
|
||||
vPeerGroup.startBlockChainDownload(tracker);
|
||||
}
|
||||
|
||||
|
|
|
@ -45,11 +45,9 @@ import org.bitcoinj.core.Address;
|
|||
import org.bitcoinj.core.BlockChain;
|
||||
import org.bitcoinj.core.Context;
|
||||
import org.bitcoinj.core.NetworkParameters;
|
||||
import org.bitcoinj.core.Peer;
|
||||
import org.bitcoinj.core.PeerAddress;
|
||||
import org.bitcoinj.core.PeerGroup;
|
||||
import org.bitcoinj.core.RejectMessage;
|
||||
import org.bitcoinj.core.listeners.DownloadProgressTracker;
|
||||
import org.bitcoinj.utils.Threading;
|
||||
import org.bitcoinj.wallet.DeterministicSeed;
|
||||
import org.bitcoinj.wallet.Wallet;
|
||||
|
@ -65,15 +63,15 @@ import com.google.common.util.concurrent.Service;
|
|||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.LongProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.ReadOnlyDoubleProperty;
|
||||
import javafx.beans.property.ReadOnlyIntegerProperty;
|
||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.property.SimpleLongProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
@ -85,7 +83,6 @@ import java.io.File;
|
|||
import java.io.IOException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -103,6 +100,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
|
||||
|
||||
import monero.daemon.MoneroDaemon;
|
||||
import monero.daemon.model.MoneroDaemonConnection;
|
||||
import monero.wallet.MoneroWallet;
|
||||
|
||||
// Setup wallets and use WalletConfig for BitcoinJ wiring.
|
||||
|
@ -112,6 +110,8 @@ import monero.wallet.MoneroWallet;
|
|||
public class WalletsSetup {
|
||||
|
||||
public static final String PRE_SEGWIT_WALLET_BACKUP = "pre_segwit_haveno_BTC.wallet.backup";
|
||||
private static final int MIN_BROADCAST_CONNECTIONS = 2;
|
||||
private static final long DAEMON_POLL_INTERVAL_SECONDS = 20;
|
||||
|
||||
@Getter
|
||||
public final BooleanProperty walletsSetupFailed = new SimpleBooleanProperty();
|
||||
|
@ -135,9 +135,8 @@ public class WalletsSetup {
|
|||
private final int walletRpcBindPort;
|
||||
private final int socks5DiscoverMode;
|
||||
private final IntegerProperty numPeers = new SimpleIntegerProperty(0);
|
||||
private final IntegerProperty chainHeight = new SimpleIntegerProperty(0);
|
||||
private final ObjectProperty<Peer> blocksDownloadedFromPeer = new SimpleObjectProperty<>();
|
||||
private final ObjectProperty<List<Peer>> connectedPeers = new SimpleObjectProperty<>();
|
||||
private final LongProperty chainHeight = new SimpleLongProperty(0);
|
||||
private final ObjectProperty<List<MoneroDaemonConnection>> peerConnections = new SimpleObjectProperty<>();
|
||||
private final DownloadListener downloadListener = new DownloadListener();
|
||||
private final List<Runnable> setupCompletedHandlers = new ArrayList<>();
|
||||
public final BooleanProperty shutDownComplete = new SimpleBooleanProperty();
|
||||
|
@ -220,19 +219,11 @@ public class WalletsSetup {
|
|||
if (preferences.getBitcoinNodes() != null && !preferences.getBitcoinNodes().isEmpty())
|
||||
peerGroup.setAddPeersFromAddressMessage(false);
|
||||
|
||||
peerGroup.addConnectedEventListener((peer, peerCount) -> {
|
||||
// We get called here on our user thread
|
||||
numPeers.set(peerCount);
|
||||
connectedPeers.set(peerGroup.getConnectedPeers());
|
||||
});
|
||||
peerGroup.addDisconnectedEventListener((peer, peerCount) -> {
|
||||
// We get called here on our user thread
|
||||
numPeers.set(peerCount);
|
||||
connectedPeers.set(peerGroup.getConnectedPeers());
|
||||
});
|
||||
peerGroup.addBlocksDownloadedEventListener((peer, block, filteredBlock, blocksLeft) -> {
|
||||
blocksDownloadedFromPeer.set(peer);
|
||||
});
|
||||
UserThread.runPeriodically(() -> {
|
||||
peerConnections.set(getPeerConnections());
|
||||
numPeers.set(peerConnections.get().size());
|
||||
chainHeight.set(vXmrDaemon.getHeight());
|
||||
}, DAEMON_POLL_INTERVAL_SECONDS);
|
||||
|
||||
// Need to be Threading.SAME_THREAD executor otherwise BitcoinJ will skip that listener
|
||||
peerGroup.addPreMessageReceivedEventListener(Threading.SAME_THREAD, (peer, message) -> {
|
||||
|
@ -247,16 +238,11 @@ public class WalletsSetup {
|
|||
return message;
|
||||
});
|
||||
|
||||
chain.addNewBestBlockListener(block -> {
|
||||
UserThread.execute(() -> {
|
||||
connectedPeers.set(peerGroup.getConnectedPeers());
|
||||
chainHeight.set(block.getHeight());
|
||||
});
|
||||
});
|
||||
|
||||
// Map to user thread
|
||||
UserThread.execute(() -> {
|
||||
chainHeight.set(chain.getBestChainHeight());
|
||||
peerConnections.set(getPeerConnections());
|
||||
numPeers.set(peerConnections.get().size());
|
||||
chainHeight.set(vXmrDaemon.getHeight());
|
||||
addressEntryList.onWalletReady(walletConfig.btcWallet());
|
||||
xmrAddressEntryList.onWalletReady(walletConfig.getXmrWallet());
|
||||
timeoutTimer.stop();
|
||||
|
@ -266,6 +252,12 @@ public class WalletsSetup {
|
|||
// onSetupCompleted in walletAppKit is not the called on the last invocations, so we add a bit of delay
|
||||
UserThread.runAfter(resultHandler::handleResult, 100, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private List<MoneroDaemonConnection> getPeerConnections() {
|
||||
return vXmrDaemon.getConnections().stream()
|
||||
.filter(peerConnection -> peerConnection.getPeer().isOnline())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
};
|
||||
walletConfig.setSocks5Proxy(socks5Proxy);
|
||||
walletConfig.setConfig(config);
|
||||
|
@ -401,11 +393,10 @@ public class WalletsSetup {
|
|||
}
|
||||
|
||||
private void configPeerNodes(@Nullable Socks5Proxy proxy) {
|
||||
BtcNodesSetupPreferences btcNodesSetupPreferences = new BtcNodesSetupPreferences(preferences);
|
||||
walletConfig.setMinBroadcastConnections(MIN_BROADCAST_CONNECTIONS);
|
||||
|
||||
BtcNodesSetupPreferences btcNodesSetupPreferences = new BtcNodesSetupPreferences(preferences);
|
||||
List<BtcNode> nodes = btcNodesSetupPreferences.selectPreferredNodes(btcNodes);
|
||||
int minBroadcastConnections = btcNodesSetupPreferences.calculateMinBroadcastConnections(nodes);
|
||||
walletConfig.setMinBroadcastConnections(minBroadcastConnections);
|
||||
|
||||
BtcNodesRepository repository = new BtcNodesRepository(nodes);
|
||||
boolean isUseClearNodesWithProxies = (useAllProvidedNodes || btcNodesSetupPreferences.isUseCustomNodes());
|
||||
|
@ -515,18 +506,14 @@ public class WalletsSetup {
|
|||
return numPeers;
|
||||
}
|
||||
|
||||
public ReadOnlyObjectProperty<List<Peer>> connectedPeersProperty() {
|
||||
return connectedPeers;
|
||||
public ReadOnlyObjectProperty<List<MoneroDaemonConnection>> peerConnectionsProperty() {
|
||||
return peerConnections;
|
||||
}
|
||||
|
||||
public ReadOnlyIntegerProperty chainHeightProperty() {
|
||||
public LongProperty chainHeightProperty() {
|
||||
return chainHeight;
|
||||
}
|
||||
|
||||
public ReadOnlyObjectProperty<Peer> blocksDownloadedFromPeerProperty() {
|
||||
return blocksDownloadedFromPeer;
|
||||
}
|
||||
|
||||
public ReadOnlyDoubleProperty downloadPercentageProperty() {
|
||||
return downloadListener.percentageProperty();
|
||||
}
|
||||
|
@ -536,8 +523,9 @@ public class WalletsSetup {
|
|||
}
|
||||
|
||||
public boolean isChainHeightSyncedWithinTolerance() {
|
||||
int peersChainHeight = PeerGroup.getMostCommonChainHeight(connectedPeers.get());
|
||||
int bestChainHeight = walletConfig.chain().getBestChainHeight();
|
||||
Long peersChainHeight = walletConfig.vXmrDaemon.getSyncInfo().getTargetHeight();
|
||||
if (peersChainHeight == 0) return true; // monero-daemon-rpc sync_info's target_height returns 0 when node is fully synced
|
||||
long bestChainHeight = chainHeight.get();
|
||||
if (Math.abs(peersChainHeight - bestChainHeight) <= 3) {
|
||||
return true;
|
||||
}
|
||||
|
@ -566,28 +554,4 @@ public class WalletsSetup {
|
|||
return walletConfig.getMinBroadcastConnections();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Inner classes
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private static class DownloadListener extends DownloadProgressTracker {
|
||||
private final DoubleProperty percentage = new SimpleDoubleProperty(-1);
|
||||
|
||||
@Override
|
||||
protected void progress(double percentage, int blocksLeft, Date date) {
|
||||
super.progress(percentage, blocksLeft, date);
|
||||
UserThread.execute(() -> this.percentage.set(percentage / 100d));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doneDownload() {
|
||||
super.doneDownload();
|
||||
UserThread.execute(() -> this.percentage.set(1d));
|
||||
}
|
||||
|
||||
public ReadOnlyDoubleProperty percentageProperty() {
|
||||
return percentage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ public class XmrTxProofService implements AssetTxProofService {
|
|||
private final Map<String, XmrTxProofRequestsPerTrade> servicesByTradeId = new HashMap<>();
|
||||
private AutoConfirmSettings autoConfirmSettings;
|
||||
private final Map<String, ChangeListener<Trade.State>> tradeStateListenerMap = new HashMap<>();
|
||||
private ChangeListener<Number> btcPeersListener, btcBlockListener;
|
||||
private ChangeListener<Number> xmrPeersListener, xmrBlockListener;
|
||||
private BootstrapListener bootstrapListener;
|
||||
private MonadicBinding<Boolean> p2pNetworkAndWalletReady;
|
||||
private ChangeListener<Boolean> p2pNetworkAndWalletReadyListener;
|
||||
|
@ -126,12 +126,12 @@ public class XmrTxProofService implements AssetTxProofService {
|
|||
// onAllServicesInitialized is called once we have received the initial data but we want to have our
|
||||
// hidden service published and upDatedDataResponse received before we start.
|
||||
BooleanProperty isP2pBootstrapped = isP2pBootstrapped();
|
||||
BooleanProperty hasSufficientBtcPeers = hasSufficientBtcPeers();
|
||||
BooleanProperty isBtcBlockDownloadComplete = isBtcBlockDownloadComplete();
|
||||
if (isP2pBootstrapped.get() && hasSufficientBtcPeers.get() && isBtcBlockDownloadComplete.get()) {
|
||||
BooleanProperty hasSufficientXmrPeers = hasSufficientXmrPeers();
|
||||
BooleanProperty isXmrBlockDownloadComplete = isXmrBlockDownloadComplete();
|
||||
if (isP2pBootstrapped.get() && hasSufficientXmrPeers.get() && isXmrBlockDownloadComplete.get()) {
|
||||
onP2pNetworkAndWalletReady();
|
||||
} else {
|
||||
p2pNetworkAndWalletReady = EasyBind.combine(isP2pBootstrapped, hasSufficientBtcPeers, isBtcBlockDownloadComplete,
|
||||
p2pNetworkAndWalletReady = EasyBind.combine(isP2pBootstrapped, hasSufficientXmrPeers, isXmrBlockDownloadComplete,
|
||||
(bootstrapped, sufficientPeers, downloadComplete) ->
|
||||
bootstrapped && sufficientPeers && downloadComplete);
|
||||
|
||||
|
@ -287,34 +287,34 @@ public class XmrTxProofService implements AssetTxProofService {
|
|||
// Startup checks
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private BooleanProperty isBtcBlockDownloadComplete() {
|
||||
private BooleanProperty isXmrBlockDownloadComplete() {
|
||||
BooleanProperty result = new SimpleBooleanProperty();
|
||||
if (walletsSetup.isDownloadComplete()) {
|
||||
result.set(true);
|
||||
} else {
|
||||
btcBlockListener = (observable, oldValue, newValue) -> {
|
||||
xmrBlockListener = (observable, oldValue, newValue) -> {
|
||||
if (walletsSetup.isDownloadComplete()) {
|
||||
walletsSetup.downloadPercentageProperty().removeListener(btcBlockListener);
|
||||
walletsSetup.downloadPercentageProperty().removeListener(xmrBlockListener);
|
||||
result.set(true);
|
||||
}
|
||||
};
|
||||
walletsSetup.downloadPercentageProperty().addListener(btcBlockListener);
|
||||
walletsSetup.downloadPercentageProperty().addListener(xmrBlockListener);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private BooleanProperty hasSufficientBtcPeers() {
|
||||
private BooleanProperty hasSufficientXmrPeers() {
|
||||
BooleanProperty result = new SimpleBooleanProperty();
|
||||
if (walletsSetup.hasSufficientPeersForBroadcast()) {
|
||||
result.set(true);
|
||||
} else {
|
||||
btcPeersListener = (observable, oldValue, newValue) -> {
|
||||
xmrPeersListener = (observable, oldValue, newValue) -> {
|
||||
if (walletsSetup.hasSufficientPeersForBroadcast()) {
|
||||
walletsSetup.numPeersProperty().removeListener(btcPeersListener);
|
||||
walletsSetup.numPeersProperty().removeListener(xmrPeersListener);
|
||||
result.set(true);
|
||||
}
|
||||
};
|
||||
walletsSetup.numPeersProperty().addListener(btcPeersListener);
|
||||
walletsSetup.numPeersProperty().addListener(xmrPeersListener);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue