FilteringCoinSelector: make immutable

This is an API-breaking change because it requires a list of
`TransactionOutPoint` to be passed to the constructor and remove the
`excludesOutputsSpentBy(tx)` method.

`Wallet` is updated to use the new constructor.
This commit is contained in:
Sean Gilligan 2023-09-05 19:42:31 -07:00 committed by Andreas Schildbach
parent 82feb7b831
commit 9eaff37897
2 changed files with 11 additions and 14 deletions

View File

@ -17,30 +17,25 @@
package org.bitcoinj.wallet;
import org.bitcoinj.base.Coin;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.TransactionInput;
import org.bitcoinj.core.TransactionOutPoint;
import org.bitcoinj.core.TransactionOutput;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
* A filtering coin selector delegates to another coin selector, but won't select outputs spent by the given transactions.
*/
public class FilteringCoinSelector implements CoinSelector {
protected CoinSelector delegate;
protected HashSet<TransactionOutPoint> spent = new HashSet<>();
protected final CoinSelector delegate;
protected final Set<TransactionOutPoint> spent;
public FilteringCoinSelector(CoinSelector delegate) {
public FilteringCoinSelector(CoinSelector delegate, List<TransactionOutPoint> excludedOutPoints) {
this.delegate = delegate;
}
public void excludeOutputsSpentBy(Transaction tx) {
for (TransactionInput input : tx.getInputs()) {
spent.add(input.getOutpoint());
}
this.spent = Collections.unmodifiableSet(new HashSet<>(excludedOutPoints));
}
@Override

View File

@ -5870,10 +5870,12 @@ public class Wallet extends BaseTaggableObject
// have already got stuck double spends in their wallet due to the Bloom-filtering block reordering
// bug that was fixed in 0.10, thus, making a re-key transaction depend on those would cause it to
// never confirm at all.
List<TransactionOutPoint> excluded = others.stream()
.flatMap(tx -> tx.getInputs().stream())
.map(TransactionInput::getOutpoint)
.collect(StreamUtils.toUnmodifiableList());
CoinSelector keyTimeSelector = new KeyTimeCoinSelector(this, time, true);
FilteringCoinSelector selector = new FilteringCoinSelector(keyTimeSelector);
for (Transaction other : others)
selector.excludeOutputsSpentBy(other);
FilteringCoinSelector selector = new FilteringCoinSelector(keyTimeSelector, excluded);
// TODO: Make this use the standard SendRequest.
CoinSelection toMove = selector.select(Coin.ZERO, calculateAllSpendCandidates());
if (toMove.totalValue().equals(Coin.ZERO)) return null; // Nothing to do.