CoinSelection: add a new constructor that doesn't require valueGathered

We'll add the output values up ourselves.

This also deprecates the old constructor.
This commit is contained in:
Andreas Schildbach 2022-07-19 01:28:17 +02:00
parent fb6add760b
commit f6cb6c15d1
4 changed files with 23 additions and 16 deletions

View file

@ -33,8 +33,23 @@ public class CoinSelection {
public final Coin valueGathered;
public final Collection<TransactionOutput> gathered;
public CoinSelection(Coin valueGathered, Collection<TransactionOutput> gathered) {
this.valueGathered = valueGathered;
public CoinSelection(Collection<TransactionOutput> gathered) {
this.valueGathered = sumOutputValues(gathered);
this.gathered = gathered;
}
/**
* @deprecated use {@link #CoinSelection(Collection<TransactionOutput>)}
*/
@Deprecated
public CoinSelection(Coin valueGathered, Collection<TransactionOutput> gathered) {
// ignore valueGathered
this(gathered);
}
private static Coin sumOutputValues(Collection<TransactionOutput> outputs) {
return outputs.stream()
.map(TransactionOutput::getValue)
.reduce(Coin.ZERO, Coin::add);
}
}

View file

@ -61,7 +61,7 @@ public class DefaultCoinSelector implements CoinSelector {
}
// Total may be lower than target here, if the given candidates were insufficient to create to requested
// transaction.
return new CoinSelection(Coin.valueOf(total), selected);
return new CoinSelection(selected);
}
@VisibleForTesting static void sortOutputs(ArrayList<TransactionOutput> outputs) {

View file

@ -58,7 +58,6 @@ public class KeyTimeCoinSelector implements CoinSelector {
public CoinSelection select(Coin target, List<TransactionOutput> candidates) {
try {
LinkedList<TransactionOutput> gathered = new LinkedList<>();
Coin valueGathered = Coin.ZERO;
for (TransactionOutput output : candidates) {
if (ignorePending && !isConfirmed(output))
continue;
@ -79,14 +78,13 @@ public class KeyTimeCoinSelector implements CoinSelector {
checkNotNull(controllingKey, "Coin selector given output as candidate for which we lack the key");
if (controllingKey.getCreationTimeSeconds() >= unixTimeSeconds) continue;
// It's older than the cutoff time so select.
valueGathered = valueGathered.add(output.getValue());
gathered.push(output);
if (gathered.size() >= MAX_SIMULTANEOUS_INPUTS) {
log.warn("Reached {} inputs, going further would yield a tx that is too large, stopping here.", gathered.size());
break;
}
}
return new CoinSelection(valueGathered, gathered);
return new CoinSelection(gathered);
} catch (ScriptException e) {
throw new RuntimeException(e); // We should never have problems understanding scripts in our wallet.
}

View file

@ -453,20 +453,17 @@ public class WalletTool implements Callable<Integer> {
}
final Address validSelectAddr = selectAddr;
coinSelector = (target, candidates) -> {
Coin valueGathered = Coin.ZERO;
List<TransactionOutput> gathered = new LinkedList<TransactionOutput>();
for (TransactionOutput candidate : candidates) {
try {
Address candidateAddr = candidate.getScriptPubKey().getToAddress(params);
if (validSelectAddr.equals(candidateAddr)) {
if (validSelectAddr.equals(candidateAddr))
gathered.add(candidate);
valueGathered = valueGathered.add(candidate.getValue());
}
} catch (ScriptException x) {
// swallow
}
}
return new CoinSelection(valueGathered, gathered);
return new CoinSelection(gathered);
};
}
if (selectOutputStr != null) {
@ -474,17 +471,14 @@ public class WalletTool implements Callable<Integer> {
Sha256Hash selectTransactionHash = Sha256Hash.wrap(parts[0]);
int selectIndex = Integer.parseInt(parts[1]);
coinSelector = (target, candidates) -> {
Coin valueGathered = Coin.ZERO;
List<TransactionOutput> gathered = new LinkedList<TransactionOutput>();
for (TransactionOutput candidate : candidates) {
int candicateIndex = candidate.getIndex();
final Sha256Hash candidateTransactionHash = candidate.getParentTransactionHash();
if (selectIndex == candicateIndex && selectTransactionHash.equals(candidateTransactionHash)) {
if (selectIndex == candicateIndex && selectTransactionHash.equals(candidateTransactionHash))
gathered.add(candidate);
valueGathered = valueGathered.add(candidate.getValue());
}
}
return new CoinSelection(valueGathered, gathered);
return new CoinSelection(gathered);
};
}
send(coinSelector, outputsStr, feePerVkb, lockTimeStr, allowUnconfirmed);