cache the wallet nodes for provided addresses during transaction construction

This commit is contained in:
Craig Raw 2022-07-14 13:21:46 +02:00
parent fc52670b2d
commit e42fc9a033
2 changed files with 21 additions and 10 deletions

2
drongo

@ -1 +1 @@
Subproject commit bd01cb87309bcc4a4739b63a6d7548ca1b25910e Subproject commit 6d0d5b7f62781c15f16d4ce0b6e27d2298122d1e

View file

@ -10,10 +10,7 @@ import com.sparrowwallet.drongo.address.InvalidAddressException;
import com.sparrowwallet.drongo.bip47.PaymentCode; import com.sparrowwallet.drongo.bip47.PaymentCode;
import com.sparrowwallet.drongo.bip47.SecretPoint; import com.sparrowwallet.drongo.bip47.SecretPoint;
import com.sparrowwallet.drongo.crypto.ECKey; import com.sparrowwallet.drongo.crypto.ECKey;
import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.protocol.*;
import com.sparrowwallet.drongo.protocol.Sha256Hash;
import com.sparrowwallet.drongo.protocol.Transaction;
import com.sparrowwallet.drongo.protocol.TransactionOutPoint;
import com.sparrowwallet.drongo.psbt.PSBT; import com.sparrowwallet.drongo.psbt.PSBT;
import com.sparrowwallet.drongo.wallet.*; import com.sparrowwallet.drongo.wallet.*;
import com.sparrowwallet.sparrow.AppServices; import com.sparrowwallet.sparrow.AppServices;
@ -178,6 +175,8 @@ public class SendController extends WalletFormController implements Initializabl
private final Set<WalletNode> excludedChangeNodes = new HashSet<>(); private final Set<WalletNode> excludedChangeNodes = new HashSet<>();
private final Map<Wallet, Map<Address, WalletNode>> addressNodeMap = new HashMap<>();
private final ChangeListener<String> feeListener = new ChangeListener<>() { private final ChangeListener<String> feeListener = new ChangeListener<>() {
@Override @Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) { public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
@ -578,7 +577,9 @@ public class SendController extends WalletFormController implements Initializabl
boolean includeMempoolOutputs = Config.get().isIncludeMempoolOutputs(); boolean includeMempoolOutputs = Config.get().isIncludeMempoolOutputs();
boolean includeSpentMempoolOutputs = includeSpentMempoolOutputsProperty.get(); boolean includeSpentMempoolOutputs = includeSpentMempoolOutputsProperty.get();
walletTransactionService = new WalletTransactionService(wallet, getUtxoSelectors(payments), getUtxoFilters(), payments, opReturnsList, excludedChangeNodes, feeRate, getMinimumFeeRate(), userFee, currentBlockHeight, groupByAddress, includeMempoolOutputs, includeSpentMempoolOutputs); walletTransactionService = new WalletTransactionService(addressNodeMap, wallet, getUtxoSelectors(payments), getUtxoFilters(),
payments, opReturnsList, excludedChangeNodes,
feeRate, getMinimumFeeRate(), userFee, currentBlockHeight, groupByAddress, includeMempoolOutputs, includeSpentMempoolOutputs);
walletTransactionService.setOnSucceeded(event -> { walletTransactionService.setOnSucceeded(event -> {
if(!walletTransactionService.isIgnoreResult()) { if(!walletTransactionService.isIgnoreResult()) {
walletTransactionProperty.setValue(walletTransactionService.getValue()); walletTransactionProperty.setValue(walletTransactionService.getValue());
@ -636,6 +637,7 @@ public class SendController extends WalletFormController implements Initializabl
} }
private static class WalletTransactionService extends Service<WalletTransaction> { private static class WalletTransactionService extends Service<WalletTransaction> {
private final Map<Wallet, Map<Address, WalletNode>> addressNodeMap;
private final Wallet wallet; private final Wallet wallet;
private final List<UtxoSelector> utxoSelectors; private final List<UtxoSelector> utxoSelectors;
private final List<UtxoFilter> utxoFilters; private final List<UtxoFilter> utxoFilters;
@ -651,7 +653,11 @@ public class SendController extends WalletFormController implements Initializabl
private final boolean includeSpentMempoolOutputs; private final boolean includeSpentMempoolOutputs;
private boolean ignoreResult; private boolean ignoreResult;
public WalletTransactionService(Wallet wallet, List<UtxoSelector> utxoSelectors, List<UtxoFilter> utxoFilters, List<Payment> payments, List<byte[]> opReturns, Set<WalletNode> excludedChangeNodes, double feeRate, double longTermFeeRate, Long fee, Integer currentBlockHeight, boolean groupByAddress, boolean includeMempoolOutputs, boolean includeSpentMempoolOutputs) { public WalletTransactionService(Map<Wallet, Map<Address, WalletNode>> addressNodeMap,
Wallet wallet, List<UtxoSelector> utxoSelectors, List<UtxoFilter> utxoFilters,
List<Payment> payments, List<byte[]> opReturns, Set<WalletNode> excludedChangeNodes,
double feeRate, double longTermFeeRate, Long fee, Integer currentBlockHeight, boolean groupByAddress, boolean includeMempoolOutputs, boolean includeSpentMempoolOutputs) {
this.addressNodeMap = addressNodeMap;
this.wallet = wallet; this.wallet = wallet;
this.utxoSelectors = utxoSelectors; this.utxoSelectors = utxoSelectors;
this.utxoFilters = utxoFilters; this.utxoFilters = utxoFilters;
@ -671,7 +677,10 @@ public class SendController extends WalletFormController implements Initializabl
protected Task<WalletTransaction> createTask() { protected Task<WalletTransaction> createTask() {
return new Task<>() { return new Task<>() {
protected WalletTransaction call() throws InsufficientFundsException { protected WalletTransaction call() throws InsufficientFundsException {
return wallet.createWalletTransaction(utxoSelectors, utxoFilters, payments, opReturns, excludedChangeNodes, feeRate, longTermFeeRate, fee, currentBlockHeight, groupByAddress, includeMempoolOutputs, includeSpentMempoolOutputs); WalletTransaction walletTransaction = wallet.createWalletTransaction(utxoSelectors, utxoFilters, payments, opReturns, excludedChangeNodes,
feeRate, longTermFeeRate, fee, currentBlockHeight, groupByAddress, includeMempoolOutputs, includeSpentMempoolOutputs);
walletTransaction.updateAddressNodeMap(addressNodeMap, walletTransaction.getWallet());
return walletTransaction;
} }
}; };
} }
@ -1078,6 +1087,8 @@ public class SendController extends WalletFormController implements Initializabl
whirlpoolProperty.set(null); whirlpoolProperty.set(null);
paymentCodeProperty.set(null); paymentCodeProperty.set(null);
addressNodeMap.clear();
} }
public UtxoSelector getUtxoSelector() { public UtxoSelector getUtxoSelector() {
@ -1155,8 +1166,8 @@ public class SendController extends WalletFormController implements Initializabl
WalletTransaction walletTransaction = walletTransactionProperty.get(); WalletTransaction walletTransaction = walletTransactionProperty.get();
Set<WalletNode> nodes = new LinkedHashSet<>(walletTransaction.getSelectedUtxos().values()); Set<WalletNode> nodes = new LinkedHashSet<>(walletTransaction.getSelectedUtxos().values());
nodes.addAll(walletTransaction.getChangeMap().keySet()); nodes.addAll(walletTransaction.getChangeMap().keySet());
List<WalletNode> consolidationNodes = walletTransaction.getConsolidationSendNodes(); Map<Address, WalletNode> addressNodeMap = walletTransaction.getAddressNodeMap(walletTransaction.getWallet());
nodes.addAll(consolidationNodes); nodes.addAll(addressNodeMap.values().stream().filter(Objects::nonNull).collect(Collectors.toList()));
//All wallet nodes applicable to this transaction are stored so when the subscription status for one is updated, the history for all can be fetched in one atomic update //All wallet nodes applicable to this transaction are stored so when the subscription status for one is updated, the history for all can be fetched in one atomic update
walletForm.addWalletTransactionNodes(nodes); walletForm.addWalletTransactionNodes(nodes);