Skip to content

Commit

Permalink
Merge pull request #6600 from stejbac/speed-up-bsq-tx-view-load
Browse files Browse the repository at this point in the history
Speed up BSQ tx view load
  • Loading branch information
alejandrogarcia83 authored Mar 11, 2023
2 parents cfeb597 + fcbf96c commit 4e4321e
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,55 +26,82 @@
import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.TransactionConfidence;

import com.google.common.base.Suppliers;

import javafx.scene.control.Tooltip;

import lombok.Data;
import java.util.function.Supplier;

import lombok.Getter;

@Data
public class TxConfidenceListItem {
@Getter
protected final BsqWalletService bsqWalletService;
@Getter
protected final String txId;
protected int confirmations = 0;
protected TxConfidenceIndicator txConfidenceIndicator;
protected TxConfidenceListener txConfidenceListener;
private final TxConfidenceListener txConfidenceListener;
private final Supplier<LazyFields> lazyFieldsSupplier;
private volatile LazyFields lazyFields;

private static class LazyFields {
int confirmations;
TxConfidenceIndicator txConfidenceIndicator;
Tooltip tooltip;
}

private LazyFields lazy() {
return lazyFieldsSupplier.get();
}

protected TxConfidenceListItem(Transaction transaction,
BsqWalletService bsqWalletService) {
this.bsqWalletService = bsqWalletService;

txId = transaction.getTxId().toString();
txConfidenceIndicator = new TxConfidenceIndicator();
txConfidenceIndicator.setId("funds-confidence");
Tooltip tooltip = new Tooltip();
txConfidenceIndicator.setProgress(0);
txConfidenceIndicator.setPrefSize(24, 24);
txConfidenceIndicator.setTooltip(tooltip);
lazyFieldsSupplier = Suppliers.memoize(() -> new LazyFields() {{
txConfidenceIndicator = new TxConfidenceIndicator();
txConfidenceIndicator.setId("funds-confidence");
tooltip = new Tooltip();
txConfidenceIndicator.setProgress(0);
txConfidenceIndicator.setPrefSize(24, 24);
txConfidenceIndicator.setTooltip(tooltip);

lazyFields = this;
updateConfidence(bsqWalletService.getConfidenceForTxId(txId));
}});

txConfidenceListener = new TxConfidenceListener(txId) {
@Override
public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
updateConfidence(confidence, tooltip);
updateConfidence(confidence);
}
};
bsqWalletService.addTxConfidenceListener(txConfidenceListener);
updateConfidence(bsqWalletService.getConfidenceForTxId(txId), tooltip);
}

protected TxConfidenceListItem() {
this.bsqWalletService = null;
this.txId = null;
bsqWalletService = null;
txId = null;
txConfidenceListener = null;
lazyFieldsSupplier = null;
}

private void updateConfidence(TransactionConfidence confidence, Tooltip tooltip) {
if (confidence != null) {
GUIUtil.updateConfidence(confidence, tooltip, txConfidenceIndicator);
confirmations = confidence.getDepthInBlocks();
public int getNumConfirmations() {
return lazy().confirmations;
}

public TxConfidenceIndicator getTxConfidenceIndicator() {
return lazy().txConfidenceIndicator;
}

private void updateConfidence(TransactionConfidence confidence) {
if (confidence != null && lazyFields != null) {
GUIUtil.updateConfidence(confidence, lazyFields.tooltip, lazyFields.txConfidenceIndicator);
lazyFields.confirmations = confidence.getDepthInBlocks();
}
}

public void cleanup() {
bsqWalletService.removeTxConfidenceListener(txConfidenceListener);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
package bisq.desktop.main.dao.wallet.tx;

import bisq.desktop.components.TxConfidenceListItem;
import bisq.desktop.main.funds.transactions.TradableRepository;
import bisq.desktop.util.DisplayUtils;

import bisq.core.btc.wallet.BsqWalletService;
Expand All @@ -36,6 +35,7 @@
import org.bitcoinj.core.TransactionOutput;

import java.util.Date;
import java.util.Map;
import java.util.Optional;

import lombok.EqualsAndHashCode;
Expand Down Expand Up @@ -66,7 +66,7 @@ class BsqTxListItem extends TxConfidenceListItem {
DaoFacade daoFacade,
Date date,
BsqFormatter bsqFormatter,
TradableRepository tradableRepository) {
Map<String, BsqSwapTrade> swapTradeByTxIdMap) {
super(transaction, bsqWalletService);

this.daoFacade = daoFacade;
Expand Down Expand Up @@ -133,12 +133,7 @@ class BsqTxListItem extends TxConfidenceListItem {
else
address = "";


optionalBsqTrade = tradableRepository.getAll().stream()
.filter(tradable -> tradable instanceof BsqSwapTrade)
.map(tradable -> (BsqSwapTrade) tradable)
.filter(tradable -> txId.equals(tradable.getTxId()))
.findFirst();
optionalBsqTrade = Optional.ofNullable(swapTradeByTxIdMap.get(txId));
}

BsqTxListItem() {
Expand All @@ -156,7 +151,7 @@ class BsqTxListItem extends TxConfidenceListItem {
TxType getTxType() {
return daoFacade.getTx(txId)
.flatMap(tx -> daoFacade.getOptionalTxType(tx.getId()))
.orElse(confirmations == 0 ? TxType.UNVERIFIED : TxType.UNDEFINED_TX_TYPE);
.orElse(getNumConfirmations() == 0 ? TxType.UNVERIFIED : TxType.UNDEFINED_TX_TYPE);
}

boolean isWithdrawalToBTCWallet() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -202,14 +203,13 @@ protected void activate() {

daoFacade.addBsqStateListener(this);

updateList();

walletChainHeight = bsqWalletService.getBestChainHeight();
blockHeightBeforeProcessing = daoFacade.getChainHeight();
missingBlocks = walletChainHeight - blockHeightBeforeProcessing;
if (!daoStateService.isParseBlockChainComplete()) {
updateAnyChainHeightTimer = UserThread.runPeriodically(this::onUpdateAnyChainHeight, 100, TimeUnit.MILLISECONDS);
}
// This indirectly calls updateList(), as required:
onUpdateAnyChainHeight();

exportButton.setOnAction(event -> {
Expand All @@ -235,7 +235,7 @@ protected void activate() {
columns[3] = item.getAddress();
columns[4] = String.valueOf(item.isReceived());
columns[5] = item.getAmountAsString();
columns[6] = String.valueOf(item.getConfirmations());
columns[6] = String.valueOf(item.getNumConfirmations());
columns[7] = item.getTxType().name();
return columns;
};
Expand Down Expand Up @@ -352,17 +352,21 @@ private void updateList() {
observableList.forEach(BsqTxListItem::cleanup);

List<Transaction> walletTransactions = bsqWalletService.getClonedWalletTransactions();
Map<String, BsqSwapTrade> swapTradeByTxIdMap = tradableRepository.getAll().stream()
.filter(tradable -> tradable instanceof BsqSwapTrade)
.map(t -> (BsqSwapTrade) t)
.collect(Collectors.toMap(BsqSwapTrade::getTxId, t -> t));

List<BsqTxListItem> items = walletTransactions.stream()
.map(transaction -> {
return new BsqTxListItem(transaction,
bsqWalletService,
btcWalletService,
daoFacade,
// Use tx.getIncludedInBestChainAt() when available, otherwise use tx.getUpdateTime()
transaction.getIncludedInBestChainAt() != null ? transaction.getIncludedInBestChainAt() : transaction.getUpdateTime(),
bsqFormatter,
tradableRepository);
})
.map(transaction -> new BsqTxListItem(transaction,
bsqWalletService,
btcWalletService,
daoFacade,
// Use tx.getIncludedInBestChainAt() when available, otherwise use tx.getUpdateTime()
transaction.getIncludedInBestChainAt() != null ? transaction.getIncludedInBestChainAt() : transaction.getUpdateTime(),
bsqFormatter,
swapTradeByTxIdMap)
)
.collect(Collectors.toList());
observableList.setAll(items);
}
Expand Down Expand Up @@ -486,7 +490,7 @@ public void updateItem(final BsqTxListItem item, boolean empty) {
TxType txType = item.getTxType();
String labelString = Res.get("dao.tx.type.enum." + txType.name());
Label label;
if (item.getConfirmations() > 0 && isValidType(txType)) {
if (item.getNumConfirmations() > 0 && isValidType(txType)) {
if (item.getOptionalBsqTrade().isPresent()) {
if (field != null)
field.setOnAction(null);
Expand Down Expand Up @@ -574,7 +578,7 @@ public void updateItem(final BsqTxListItem item, boolean empty) {

String bsqAmount = Res.get("shared.na");

if (item.getConfirmations() > 0) {
if (item.getNumConfirmations() > 0) {
if (isValidType(txType))
bsqAmount = item.getAmountAsString();
else if (item.isWithdrawalToBTCWallet())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,11 @@ class DepositListItem implements FilterableListItem {
private Coin balanceAsCoin;
private final String addressString;
private String usage = "-";
private TxConfidenceListener txConfidenceListener;
private BalanceListener balanceListener;
private final TxConfidenceListener txConfidenceListener;
private final BalanceListener balanceListener;
private int numTxOutputs = 0;
private final Supplier<LazyFields> lazyFieldsSupplier;
private volatile LazyFields lazyFields;

private static class LazyFields {
TxConfidenceIndicator txConfidenceIndicator;
Expand All @@ -82,28 +83,29 @@ private LazyFields lazy() {
tooltip = new Tooltip(Res.get("shared.notUsedYet"));
txConfidenceIndicator.setProgress(0);
txConfidenceIndicator.setTooltip(tooltip);
if (confidence != null) {
GUIUtil.updateConfidence(confidence, tooltip, txConfidenceIndicator);
}

lazyFields = this;
updateConfidence(confidence);
}});

if (confidence != null) {
txConfidenceListener = new TxConfidenceListener(confidence.getTransactionHash().toString()) {
@Override
public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
GUIUtil.updateConfidence(confidence, lazy().tooltip, lazy().txConfidenceIndicator);
updateConfidence(confidence);
}
};
walletService.addTxConfidenceListener(txConfidenceListener);
} else {
txConfidenceListener = null;
}

balanceListener = new BalanceListener(address) {
@Override
public void onBalanceChanged(Coin balanceAsCoin, Transaction tx) {
DepositListItem.this.balanceAsCoin = balanceAsCoin;
DepositListItem.this.balance.set(formatter.formatCoin(balanceAsCoin));
var confidence = walletService.getConfidenceForTxId(tx.getTxId().toString());
GUIUtil.updateConfidence(confidence, lazy().tooltip, lazy().txConfidenceIndicator);
updateConfidence(walletService.getConfidenceForTxId(tx.getTxId().toString()));
updateUsage(address);
}
};
Expand All @@ -115,6 +117,12 @@ public void onBalanceChanged(Coin balanceAsCoin, Transaction tx) {
updateUsage(address);
}

private void updateConfidence(TransactionConfidence confidence) {
if (confidence != null && lazyFields != null) {
GUIUtil.updateConfidence(confidence, lazyFields.tooltip, lazyFields.txConfidenceIndicator);
}
}

private void updateUsage(Address address) {
numTxOutputs = walletService.getNumTxOutputsForAddress(address);
usage = numTxOutputs == 0 ? Res.get("funds.deposit.unused") : Res.get("funds.deposit.usedInTx", numTxOutputs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,13 @@ class TransactionsListItem implements FilterableListItem {
private boolean received;
private Coin amountAsCoin = Coin.ZERO;
private String memo = "";
private int confirmations = 0;
@Getter
private final boolean isDustAttackTx;
private boolean initialTxConfidenceVisibility = true;
private final Supplier<LazyFields> lazyFieldsSupplier;

private static class LazyFields {
int confirmations;
TxConfidenceIndicator txConfidenceIndicator;
Tooltip tooltip;
}
Expand Down Expand Up @@ -349,7 +349,7 @@ public Tradable getTradable() {
}

public String getNumConfirmations() {
return String.valueOf(confirmations);
return String.valueOf(lazy().confirmations);
}

public String getMemo() {
Expand Down

0 comments on commit 4e4321e

Please sign in to comment.