Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve startup info display #4850

Merged
merged 4 commits into from
Nov 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions core/src/main/java/bisq/core/app/WalletAppSetup.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,29 +111,38 @@ void init(@Nullable Consumer<String> chainFileLockedExceptionHandler,

ObjectProperty<Throwable> walletServiceException = new SimpleObjectProperty<>();
btcInfoBinding = EasyBind.combine(walletsSetup.downloadPercentageProperty(),
walletsSetup.chainHeightProperty(),
feeService.feeUpdateCounterProperty(),
walletServiceException,
(downloadPercentage, feeUpdate, exception) -> {
(downloadPercentage, chainHeight, feeUpdate, exception) -> {
String result;
if (exception == null) {
double percentage = (double) downloadPercentage;
btcSyncProgress.set(percentage);
int bestChainHeight = walletsSetup.getChain() != null ?
walletsSetup.getChain().getBestChainHeight() :
0;
String chainHeightAsString = bestChainHeight > 0 ?
String.valueOf(bestChainHeight) :
"";
if (percentage == 1) {
result = Res.get("mainView.footer.btcInfo",
Res.get("mainView.footer.btcInfo.synchronizedWith"),
getBtcNetworkAsString(),
feeService.getFeeTextForDisplay());
String synchronizedWith = Res.get("mainView.footer.btcInfo.synchronizedWith",
getBtcNetworkAsString(), chainHeightAsString);
String info = feeService.isFeeAvailable() ?
Res.get("mainView.footer.btcFeeRate", feeService.getTxFeePerVbyte().value) :
"";
result = Res.get("mainView.footer.btcInfo", synchronizedWith, info);
getBtcSplashSyncIconId().set("image-connection-synced");

downloadCompleteHandler.run();
} else if (percentage > 0.0) {
result = Res.get("mainView.footer.btcInfo",
Res.get("mainView.footer.btcInfo.synchronizingWith"),
getBtcNetworkAsString() + ": " + FormattingUtils.formatToPercentWithSymbol(percentage), "");
String synchronizingWith = Res.get("mainView.footer.btcInfo.synchronizingWith",
getBtcNetworkAsString(), chainHeightAsString,
FormattingUtils.formatToPercentWithSymbol(percentage));
result = Res.get("mainView.footer.btcInfo", synchronizingWith, "");
} else {
result = Res.get("mainView.footer.btcInfo",
Res.get("mainView.footer.btcInfo.connectingTo"),
getBtcNetworkAsString(), "");
getBtcNetworkAsString());
}
} else {
result = Res.get("mainView.footer.btcInfo",
Expand Down Expand Up @@ -259,6 +268,7 @@ void setRejectedTxErrorMessageHandler(Consumer<String> rejectedTxErrorMessageHan
}
});
}

private String getBtcNetworkAsString() {
String postFix;
if (config.ignoreLocalBtcNode)
Expand Down
72 changes: 55 additions & 17 deletions core/src/main/java/bisq/core/btc/setup/WalletConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,36 +24,66 @@
import bisq.common.config.Config;
import bisq.common.file.FileUtil;

import com.google.common.io.Closeables;
import com.google.common.util.concurrent.*;
import org.bitcoinj.core.listeners.*;
import org.bitcoinj.core.*;
import org.bitcoinj.core.BlockChain;
import org.bitcoinj.core.CheckpointManager;
import org.bitcoinj.core.Context;
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.core.PeerAddress;
import org.bitcoinj.core.PeerGroup;
import org.bitcoinj.core.listeners.DownloadProgressTracker;
import org.bitcoinj.crypto.KeyCrypter;
import org.bitcoinj.net.BlockingClientManager;
import org.bitcoinj.net.discovery.*;
import org.bitcoinj.net.discovery.DnsDiscovery;
import org.bitcoinj.net.discovery.PeerDiscovery;
import org.bitcoinj.script.Script;
import org.bitcoinj.store.*;
import org.bitcoinj.wallet.*;
import org.bitcoinj.store.BlockStore;
import org.bitcoinj.store.BlockStoreException;
import org.bitcoinj.store.SPVBlockStore;
import org.bitcoinj.wallet.DeterministicKeyChain;
import org.bitcoinj.wallet.DeterministicSeed;
import org.bitcoinj.wallet.KeyChainGroup;
import org.bitcoinj.wallet.KeyChainGroupStructure;
import org.bitcoinj.wallet.Protos;
import org.bitcoinj.wallet.Wallet;
import org.bitcoinj.wallet.WalletExtension;
import org.bitcoinj.wallet.WalletProtobufSerializer;

import com.runjva.sourceforge.jsocks.protocol.Socks5Proxy;

import com.google.common.io.Closeables;
import com.google.common.util.concurrent.AbstractIdleService;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;

import org.bouncycastle.crypto.params.KeyParameter;

import org.slf4j.*;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.annotation.*;
import java.io.*;
import java.net.*;
import java.util.concurrent.*;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import lombok.Getter;
import lombok.Setter;

import javax.annotation.Nullable;

import static bisq.common.util.Preconditions.checkDir;
import static com.google.common.base.Preconditions.*;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

/**
* <p>Utility class that wraps the boilerplate needed to set up a new SPV bitcoinj app. Instantiate it with a directory
Expand Down Expand Up @@ -98,8 +128,10 @@ public class WalletConfig extends AbstractIdleService {
protected DownloadProgressTracker downloadListener;
protected InputStream checkpoints;
protected String userAgent, version;
@Nullable protected DeterministicSeed restoreFromSeed;
@Nullable protected PeerDiscovery discovery;
@Nullable
protected DeterministicSeed restoreFromSeed;
@Nullable
protected PeerDiscovery discovery;

protected volatile Context context;

Expand Down Expand Up @@ -279,7 +311,7 @@ protected void startUp() throws Exception {
}
vChain = new BlockChain(params, vStore);
vPeerGroup = createPeerGroup();
if (minBroadcastConnections > 0 )
if (minBroadcastConnections > 0)
vPeerGroup.setMinBroadcastConnections(minBroadcastConnections);
if (this.userAgent != null)
vPeerGroup.setUserAgent(userAgent, version);
Expand Down Expand Up @@ -334,7 +366,9 @@ public void onFailure(Throwable t) {
}, MoreExecutors.directExecutor());
}

private Wallet createOrLoadWallet(boolean shouldReplayWallet, File walletFile, boolean isBsqWallet) throws Exception {
private Wallet createOrLoadWallet(boolean shouldReplayWallet,
File walletFile,
boolean isBsqWallet) throws Exception {
Wallet wallet;

maybeMoveOldWalletOutOfTheWay(walletFile);
Expand Down Expand Up @@ -546,4 +580,8 @@ public void maybeAddSegwitKeychain(Wallet wallet, KeyParameter aesKey) {
}
migratedWalletToSegwit.set(true);
}

public boolean stateStartingOrRunning() {
return state() == State.STARTING || state() == State.RUNNING;
}
}
2 changes: 1 addition & 1 deletion core/src/main/java/bisq/core/btc/setup/WalletsSetup.java
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ public NetworkParameters getParams() {

@Nullable
public BlockChain getChain() {
return walletConfig != null ? walletConfig.chain() : null;
return walletConfig != null && walletConfig.stateStartingOrRunning() ? walletConfig.chain() : null;
}

public PeerGroup getPeerGroup() {
Expand Down
8 changes: 2 additions & 6 deletions core/src/main/java/bisq/core/provider/fee/FeeService.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import bisq.core.dao.governance.param.Param;
import bisq.core.dao.governance.period.PeriodService;
import bisq.core.dao.state.DaoStateService;
import bisq.core.locale.Res;

import bisq.common.UserThread;
import bisq.common.config.Config;
Expand Down Expand Up @@ -192,10 +191,7 @@ public ReadOnlyIntegerProperty feeUpdateCounterProperty() {
return feeUpdateCounter;
}

public String getFeeTextForDisplay() {
// only show the fee rate if it has been initialized from the service (see feeUpdateCounter)
if (feeUpdateCounter.get() > 0)
return Res.get("mainView.footer.btcFeeRate", txFeePerVbyte);
return "";
public boolean isFeeAvailable() {
return feeUpdateCounter.get() > 0;
}
}
10 changes: 5 additions & 5 deletions core/src/main/resources/i18n/displayStrings.properties
Original file line number Diff line number Diff line change
Expand Up @@ -250,14 +250,14 @@ mainView.balance.locked=Locked in trades
mainView.balance.reserved.short=Reserved
mainView.balance.locked.short=Locked

mainView.footer.usingTor=(using Tor)
mainView.footer.usingTor=(via Tor)
mainView.footer.localhostBitcoinNode=(localhost)
mainView.footer.btcInfo={0} {1} {2}
mainView.footer.btcFeeRate=/ Current fee rate: {0} sat/vB
mainView.footer.btcInfo={0} {1}
mainView.footer.btcFeeRate=/ Fee rate: {0} sat/vB
mainView.footer.btcInfo.initializing=Connecting to Bitcoin network
mainView.footer.bsqInfo.synchronizing=/ Synchronizing DAO
mainView.footer.btcInfo.synchronizingWith=Synchronizing with
mainView.footer.btcInfo.synchronizedWith=Synced with
mainView.footer.btcInfo.synchronizingWith=Synchronizing with {0} at block: {1} / {2}
mainView.footer.btcInfo.synchronizedWith=Synced with {0} at block {1}
mainView.footer.btcInfo.connectingTo=Connecting to
mainView.footer.btcInfo.connectionFailed=Connection failed to
mainView.footer.p2pInfo=Bitcoin network peers: {0} / Bisq network peers: {1}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ public void onWalletTransactionsChange() {
// Private
///////////////////////////////////////////////////////////////////////////////////////////

// If chain height from wallet of from the BSQ blockchain parsing changed we update our state.
// If chain height from wallet or from the BSQ blockchain parsing changed we update our state.
private void onUpdateAnyChainHeight() {
int currentBlockHeight = daoFacade.getChainHeight();
if (walletChainHeight > 0) {
Expand All @@ -276,8 +276,7 @@ private void onUpdateAnyChainHeight() {
chainSyncIndicator.setVisible(!synced);
chainSyncIndicator.setManaged(!synced);
if (synced) {
chainHeightLabel.setText(Res.get("dao.wallet.chainHeightSynced",
currentBlockHeight));
chainHeightLabel.setText(Res.get("dao.wallet.chainHeightSynced", currentBlockHeight));
} else {
chainSyncIndicator.setProgress(progress);
if (walletChainHeight > currentBlockHeight) {
Expand All @@ -287,12 +286,13 @@ private void onUpdateAnyChainHeight() {
currentBlockHeight,
walletChainHeight));
} else {
// But when restoring from seed, we receive the latest block height
// from the seed nodes while BitcoinJ has not received all blocks yet and
// is still syncing
chainHeightLabel.setText(Res.get("dao.wallet.chainHeightSyncing",
walletChainHeight,
currentBlockHeight));
// Our wallet chain height is behind our BSQ chain height. That can be the case at SPV resync or if
// we updated manually our DaoStateStore with a newer version. We do not want to show sync state
// as we do not know at that moment if we are missing blocks. Once Btc wallet has synced we will
// trigger a check and request more blocks in case we are the lite node.
chainSyncIndicator.setVisible(false);
chainSyncIndicator.setManaged(false);
chainHeightLabel.setText(Res.get("dao.wallet.chainHeightSynced", currentBlockHeight));
}
}
} else {
Expand Down