spend change from notification transactions only if necessary

This commit is contained in:
Craig Raw 2022-07-21 12:29:21 +02:00
parent 40dab59337
commit b2f5f5ffeb
3 changed files with 35 additions and 8 deletions

View file

@ -174,6 +174,10 @@ public class PaymentCode {
if(scriptChunks.get(1).getData() != null && scriptChunks.get(1).getData().length != 80) {
return null;
}
byte[] data = scriptChunks.get(1).getData();
if(data[0] != 0x01 || (data[2] != 0x02 && data[2] != 0x03)) {
return null;
}
return scriptChunks;
}

View file

@ -20,6 +20,7 @@ public class OutputGroup {
private long longTermFee = 0;
private int depth = Integer.MAX_VALUE;
private boolean allInputsFromWallet = true;
private boolean spendLast;
public OutputGroup(ScriptType scriptType, int walletBlockHeight, long inputWeightUnits, double feeRate, double longTermFeeRate) {
this.scriptType = scriptType;
@ -29,7 +30,7 @@ public class OutputGroup {
this.longTermFeeRate = longTermFeeRate;
}
public void add(BlockTransactionHashIndex utxo, boolean allInputsFromWallet) {
public void add(BlockTransactionHashIndex utxo, boolean allInputsFromWallet, boolean spendLast) {
utxos.add(utxo);
value += utxo.getValue();
effectiveValue += utxo.getValue() - (long)(inputWeightUnits * feeRate / WITNESS_SCALE_FACTOR);
@ -37,6 +38,7 @@ public class OutputGroup {
longTermFee += (long)(inputWeightUnits * longTermFeeRate / WITNESS_SCALE_FACTOR);
depth = utxo.getHeight() <= 0 ? 0 : Math.min(depth, walletBlockHeight - utxo.getHeight() + 1);
this.allInputsFromWallet &= allInputsFromWallet;
this.spendLast |= spendLast;
}
public void remove(BlockTransactionHashIndex utxo) {
@ -80,21 +82,27 @@ public class OutputGroup {
return allInputsFromWallet;
}
public boolean isSpendLast() {
return spendLast;
}
public static class Filter {
private final int minWalletConfirmations;
private final int minExternalConfirmations;
private final boolean includeSpendLast;
public Filter(int minWalletConfirmations, int minExternalConfirmations) {
public Filter(int minWalletConfirmations, int minExternalConfirmations, boolean includeSpendLast) {
this.minWalletConfirmations = minWalletConfirmations;
this.minExternalConfirmations = minExternalConfirmations;
this.includeSpendLast = includeSpendLast;
}
public boolean isEligible(OutputGroup outputGroup) {
if(outputGroup.isAllInputsFromWallet()) {
return outputGroup.getDepth() >= minWalletConfirmations;
return outputGroup.getDepth() >= minWalletConfirmations && (includeSpendLast || !outputGroup.isSpendLast());
}
return outputGroup.getDepth() >= minExternalConfirmations;
return outputGroup.getDepth() >= minExternalConfirmations && (includeSpendLast || !outputGroup.isSpendLast());
}
}
}

View file

@ -1163,10 +1163,13 @@ public class Wallet extends Persistable implements Comparable<Wallet> {
List<OutputGroup> utxoPool = getGroupedUtxos(utxoFilters, feeRate, longTermFeeRate, groupByAddress, includeSpentMempoolOutputs);
List<OutputGroup.Filter> filters = new ArrayList<>();
filters.add(new OutputGroup.Filter(1, 6));
filters.add(new OutputGroup.Filter(1, 1));
filters.add(new OutputGroup.Filter(1, 6, false));
filters.add(new OutputGroup.Filter(1, 1, false));
if(includeMempoolOutputs) {
filters.add(new OutputGroup.Filter(0, 0));
filters.add(new OutputGroup.Filter(0, 0, false));
filters.add(new OutputGroup.Filter(0, 0, true));
} else {
filters.add(new OutputGroup.Filter(1, 1, true));
}
if(sendMax) {
@ -1237,7 +1240,7 @@ public class Wallet extends Persistable implements Comparable<Wallet> {
outputGroups.add(outputGroup);
}
outputGroup.add(utxo, allInputsFromWallet(walletTransactions, walletTxos, utxo.getHash()));
outputGroup.add(utxo, allInputsFromWallet(walletTransactions, walletTxos, utxo.getHash()), isNotificationChange(walletTransactions, utxo.getHash()));
}
}
}
@ -1280,6 +1283,18 @@ public class Wallet extends Persistable implements Comparable<Wallet> {
return true;
}
private boolean isNotificationChange(Map<Sha256Hash, BlockTransaction> walletTransactions, Sha256Hash txId) {
BlockTransaction utxoBlkTx = walletTransactions.get(txId);
try {
PaymentCode.getOpReturnData(utxoBlkTx.getTransaction());
return true;
} catch(IllegalArgumentException e) {
//ignore, not a notification tx
}
return false;
}
/**
* Determines the maximum total amount this wallet can send for the number and type of addresses at the given fee rate
*