diff --git a/core/src/main/java/bisq/core/app/BisqSetup.java b/core/src/main/java/bisq/core/app/BisqSetup.java index cbc70acad20..4c9c132d264 100644 --- a/core/src/main/java/bisq/core/app/BisqSetup.java +++ b/core/src/main/java/bisq/core/app/BisqSetup.java @@ -355,6 +355,16 @@ public StringProperty getBtcSplashSyncIconId() { return walletAppSetup.getBtcSplashSyncIconId(); } + + // DAO Wallet + public StringProperty getBsqInfo() { + return daoSetup.getBsqInfo(); + } + + public DoubleProperty getBsqSyncProgress() { + return daoSetup.getBsqSyncProgress(); + } + // P2P public StringProperty getP2PNetworkInfo() { return p2PNetworkSetup.getP2PNetworkInfo(); diff --git a/core/src/main/java/bisq/core/dao/DaoSetup.java b/core/src/main/java/bisq/core/dao/DaoSetup.java index 591f65af26f..846ed815032 100644 --- a/core/src/main/java/bisq/core/dao/DaoSetup.java +++ b/core/src/main/java/bisq/core/dao/DaoSetup.java @@ -17,6 +17,8 @@ package bisq.core.dao; +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.governance.asset.AssetService; import bisq.core.dao.governance.ballot.BallotListService; import bisq.core.dao.governance.blindvote.BlindVoteListService; @@ -34,22 +36,44 @@ import bisq.core.dao.node.BsqNode; import bisq.core.dao.node.BsqNodeProvider; import bisq.core.dao.node.explorer.ExportJsonFilesService; +import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.locale.Res; import com.google.inject.Inject; +import javafx.beans.property.DoubleProperty; +import javafx.beans.property.SimpleDoubleProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import javafx.beans.value.ChangeListener; + import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; +import lombok.Getter; + /** * High level entry point for Dao domain. * We initialize all main service classes here to be sure they are started. */ -public class DaoSetup { +public class DaoSetup implements DaoStateListener { private final BsqNode bsqNode; private final List daoSetupServices = new ArrayList<>(); + @Getter + private final DoubleProperty bsqSyncProgress = new SimpleDoubleProperty(-1); + @Getter + private final StringProperty bsqInfo = new SimpleStringProperty(Res.get("mainView.footer.bsqInfo.initializing")); + private final ChangeListener walletChainHeightListener; + + private final BtcWalletService btcWalletService; + private final DaoFacade daoFacade; + private final BsqWalletService bsqWalletService; + private final DaoStateService daoStateService; + @Inject public DaoSetup(BsqNodeProvider bsqNodeProvider, DaoStateService daoStateService, @@ -69,7 +93,9 @@ public DaoSetup(BsqNodeProvider bsqNodeProvider, ProofOfBurnService proofOfBurnService, DaoFacade daoFacade, ExportJsonFilesService exportJsonFilesService, - DaoKillSwitch daoKillSwitch) { + DaoKillSwitch daoKillSwitch, + BtcWalletService btcWalletService, + BsqWalletService bsqWalletService) { bsqNode = bsqNodeProvider.getBsqNode(); @@ -93,6 +119,13 @@ public DaoSetup(BsqNodeProvider bsqNodeProvider, daoSetupServices.add(exportJsonFilesService); daoSetupServices.add(daoKillSwitch); daoSetupServices.add(bsqNodeProvider.getBsqNode()); + + this.btcWalletService = btcWalletService; + this.daoFacade = daoFacade; + this.bsqWalletService = bsqWalletService; + this.daoStateService = daoStateService; + + walletChainHeightListener = (observable, oldValue, newValue) -> onUpdateAnyChainHeight(); } public void onAllServicesInitialized(Consumer errorMessageHandler, @@ -106,9 +139,63 @@ public void onAllServicesInitialized(Consumer errorMessageHandler, // which triggers listeners. daoSetupServices.forEach(DaoSetupService::addListeners); daoSetupServices.forEach(DaoSetupService::start); + + addListeners(); + + onUpdateAnyChainHeight(); } public void shutDown() { bsqNode.shutDown(); } + + private void onUpdateAnyChainHeight() { + final int bsqBlockChainHeight = daoFacade.getChainHeight(); + final int bsqWalletChainHeight = bsqWalletService.getBestChainHeight(); + if (bsqWalletChainHeight > 0) { + final boolean synced = bsqWalletChainHeight == bsqBlockChainHeight; + if (bsqBlockChainHeight != bsqWalletChainHeight) { + bsqSyncProgress.set(-1); + } else { + bsqSyncProgress.set(0); + } + + if (synced) { + bsqInfo.set(""); + } else { + bsqInfo.set(Res.get("mainView.footer.bsqInfo.synchronizing")); + } + } else { + bsqInfo.set(Res.get("mainView.footer.bsqInfo.synchronizing")); + } + } + + private void addListeners() { + btcWalletService.getChainHeightProperty().addListener(walletChainHeightListener); + daoStateService.addBsqStateListener(this); + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // DaoStateListener + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void onNewBlockHeight(int blockHeight) { + + } + + @Override + public void onParseBlockChainComplete() { + + } + + @Override + public void onParseTxsCompleteAfterBatchProcessing(Block block) { + onUpdateAnyChainHeight(); + } + + @Override + public void onParseTxsComplete(Block block) { + + } } diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index 895b45be37f..bf7bd5a13cb 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -233,6 +233,8 @@ mainView.footer.usingTor=(using Tor) mainView.footer.localhostBitcoinNode=(localhost) mainView.footer.btcInfo=Bitcoin network peers: {0} / {1} {2} mainView.footer.btcInfo.initializing=Initializing +mainView.footer.bsqInfo.initializing=/ Initializing DAO +mainView.footer.bsqInfo.synchronizing=/ Synchronizing DAO mainView.footer.btcInfo.synchronizedWith=synchronized with mainView.footer.btcInfo.connectingTo=connecting to mainView.footer.btcInfo.connectionFailed=connection failed diff --git a/desktop/src/main/java/bisq/desktop/main/MainView.java b/desktop/src/main/java/bisq/desktop/main/MainView.java index 82f30d010ee..91574cafff6 100644 --- a/desktop/src/main/java/bisq/desktop/main/MainView.java +++ b/desktop/src/main/java/bisq/desktop/main/MainView.java @@ -588,8 +588,8 @@ private AnchorPane createFooter() { btcInfoLabel.setId("footer-pane"); btcInfoLabel.textProperty().bind(model.getBtcInfo()); - ProgressBar blockchainSyncIndicator = new ProgressBar(-1); - blockchainSyncIndicator.setPrefWidth(120); + ProgressBar blockchainSyncIndicator = new JFXProgressBar(-1); + blockchainSyncIndicator.setPrefWidth(80); blockchainSyncIndicator.setMaxHeight(10); blockchainSyncIndicator.progressProperty().bind(model.getBtcSyncProgress()); diff --git a/desktop/src/main/java/bisq/desktop/main/MainViewModel.java b/desktop/src/main/java/bisq/desktop/main/MainViewModel.java index 39a143b35cb..12d560b4550 100644 --- a/desktop/src/main/java/bisq/desktop/main/MainViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/MainViewModel.java @@ -65,11 +65,14 @@ import org.fxmisc.easybind.EasyBind; import org.fxmisc.easybind.monadic.MonadicBinding; +import javafx.beans.binding.Bindings; import javafx.beans.property.BooleanProperty; import javafx.beans.property.DoubleProperty; import javafx.beans.property.IntegerProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleDoubleProperty; +import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import javafx.collections.ObservableList; @@ -107,6 +110,7 @@ public class MainViewModel implements ViewModel, BisqSetup.BisqSetupCompleteList @Getter private BooleanProperty showAppScreen = new SimpleBooleanProperty(); + private DoubleProperty combinedSyncProgress = new SimpleDoubleProperty(); private final BooleanProperty isSplashScreenRemoved = new SimpleBooleanProperty(); private Timer checkNumberOfBtcPeersTimer; private Timer checkNumberOfP2pNetworkPeersTimer; @@ -349,6 +353,10 @@ private void setupHandlers() { tradeManager.setTakeOfferRequestErrorMessageHandler(errorMessage -> new Popup<>() .warning(Res.get("popup.error.takeOfferRequestFailed", errorMessage)) .show()); + + bisqSetup.getBtcSyncProgress().addListener((observable, oldValue, newValue) -> updateBtcSyncProgress()); + bisqSetup.getBsqSyncProgress().addListener((observable, oldValue, newValue) -> updateBtcSyncProgress()); + } private void setupP2PNumPeersWatcher() { @@ -455,6 +463,16 @@ public void onUpdatedDataReceived() { } } + private void updateBtcSyncProgress() { + final DoubleProperty btcSyncProgress = bisqSetup.getBtcSyncProgress(); + + if (btcSyncProgress.doubleValue() < 1) { + combinedSyncProgress.set(btcSyncProgress.doubleValue()); + } else { + combinedSyncProgress.set(bisqSetup.getBsqSyncProgress().doubleValue()); + } + } + /////////////////////////////////////////////////////////////////////////////////////////// // MainView delegate getters @@ -495,11 +513,13 @@ StringProperty getLockedBalance() { // Wallet StringProperty getBtcInfo() { - return bisqSetup.getBtcInfo(); + final StringProperty combinedInfo = new SimpleStringProperty(); + combinedInfo.bind(Bindings.concat(bisqSetup.getBtcInfo(), " ", bisqSetup.getBsqInfo())); + return combinedInfo; } DoubleProperty getBtcSyncProgress() { - return bisqSetup.getBtcSyncProgress(); + return combinedSyncProgress; } StringProperty getWalletServiceErrorMsg() {