mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2024-11-19 09:50:32 +01:00
DefaultCoinSelector: require network for constructor
This is so that the special handling for regtest network can work in future.
This commit is contained in:
parent
472af481cc
commit
c60c612107
@ -19,6 +19,7 @@ package org.bitcoinj.wallet;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.bitcoinj.base.BitcoinNetwork;
|
||||
import org.bitcoinj.base.Coin;
|
||||
import org.bitcoinj.base.Network;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
import org.bitcoinj.core.TransactionConfidence;
|
||||
import org.bitcoinj.core.TransactionOutput;
|
||||
@ -34,7 +35,14 @@ import java.util.List;
|
||||
* "spending" more priority than would be required to get the transaction we are creating confirmed.
|
||||
*/
|
||||
public class DefaultCoinSelector implements CoinSelector {
|
||||
private final Network network;
|
||||
|
||||
protected DefaultCoinSelector() {
|
||||
this.network = null;
|
||||
}
|
||||
|
||||
private DefaultCoinSelector(Network network) {
|
||||
this.network = network;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -45,7 +53,6 @@ public class DefaultCoinSelector implements CoinSelector {
|
||||
ArrayList<TransactionOutput> sortedOutputs = new ArrayList<>(candidates);
|
||||
// When calculating the wallet balance, we may be asked to select all possible coins, if so, avoid sorting
|
||||
// them in order to improve performance.
|
||||
// TODO: Take in network parameters when instantiated, and then test against the current network. Or just have a boolean parameter for "give me everything"
|
||||
if (!target.equals(BitcoinNetwork.MAX_MONEY)) {
|
||||
sortOutputs(sortedOutputs);
|
||||
}
|
||||
@ -87,12 +94,20 @@ public class DefaultCoinSelector implements CoinSelector {
|
||||
/** Sub-classes can override this to just customize whether transactions are usable, but keep age sorting. */
|
||||
protected boolean shouldSelect(Transaction tx) {
|
||||
if (tx != null) {
|
||||
return isSelectable(tx);
|
||||
return isSelectable(tx, network);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isSelectable(Transaction tx) {
|
||||
/**
|
||||
* Helper to determine if this selector would select a given transaction. Note that in a regtest network outgoing
|
||||
* payments will likely not see propagation, so there is a special exception.
|
||||
*
|
||||
* @param tx transaction to determine if it would be selected
|
||||
* @param network network the transaction is on
|
||||
* @return true if it would be selected, false otherwise
|
||||
*/
|
||||
public static boolean isSelectable(Transaction tx, Network network) {
|
||||
// Only pick chain-included transactions, or transactions that are ours and pending.
|
||||
TransactionConfidence confidence = tx.getConfidence();
|
||||
TransactionConfidence.ConfidenceType type = confidence.getConfidenceType();
|
||||
@ -101,10 +116,10 @@ public class DefaultCoinSelector implements CoinSelector {
|
||||
type.equals(TransactionConfidence.ConfidenceType.PENDING) &&
|
||||
confidence.getSource().equals(TransactionConfidence.Source.SELF) &&
|
||||
// In regtest mode we expect to have only one peer, so we won't see transactions propagate.
|
||||
(confidence.numBroadcastPeers() > 0 || tx.getParams().network() == BitcoinNetwork.REGTEST);
|
||||
(confidence.numBroadcastPeers() > 0 || network == BitcoinNetwork.REGTEST);
|
||||
}
|
||||
|
||||
public static CoinSelector get() {
|
||||
return new DefaultCoinSelector();
|
||||
public static CoinSelector get(Network network) {
|
||||
return new DefaultCoinSelector(network);
|
||||
}
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ public class Wallet extends BaseTaggableObject
|
||||
@Nullable
|
||||
private volatile Instant vKeyRotationTime = null;
|
||||
|
||||
protected final CoinSelector coinSelector = DefaultCoinSelector.get();
|
||||
protected final CoinSelector coinSelector;
|
||||
|
||||
// The wallet version. This is an int that can be used to track breaking changes in the wallet format.
|
||||
// You can also use it to detect wallets that come from the future (ie they contain features you
|
||||
@ -511,6 +511,7 @@ public class Wallet extends BaseTaggableObject
|
||||
*/
|
||||
public Wallet(NetworkParameters params, KeyChainGroup keyChainGroup) {
|
||||
this.params = Objects.requireNonNull(params);
|
||||
this.coinSelector = DefaultCoinSelector.get(params.network());
|
||||
this.keyChainGroup = Objects.requireNonNull(keyChainGroup);
|
||||
watchedScripts = new HashSet<>();
|
||||
unspent = new HashMap<>();
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package org.bitcoinj.wallet;
|
||||
|
||||
import org.bitcoinj.base.BitcoinNetwork;
|
||||
import org.bitcoinj.base.internal.TimeUtils;
|
||||
import org.bitcoinj.core.AbstractBlockChain;
|
||||
import org.bitcoinj.core.Block;
|
||||
@ -65,20 +66,20 @@ public class DefaultCoinSelectorTest extends TestWithWallet {
|
||||
Transaction t;
|
||||
t = new Transaction(TESTNET);
|
||||
t.getConfidence().setConfidenceType(TransactionConfidence.ConfidenceType.PENDING);
|
||||
assertFalse(DefaultCoinSelector.isSelectable(t));
|
||||
assertFalse(DefaultCoinSelector.isSelectable(t, BitcoinNetwork.TESTNET));
|
||||
t.getConfidence().setSource(TransactionConfidence.Source.SELF);
|
||||
assertFalse(DefaultCoinSelector.isSelectable(t));
|
||||
assertFalse(DefaultCoinSelector.isSelectable(t, BitcoinNetwork.TESTNET));
|
||||
t.getConfidence().markBroadcastBy(new PeerAddress(InetAddress.getByName("1.2.3.4"), TESTNET.getPort()));
|
||||
assertTrue(DefaultCoinSelector.isSelectable(t));
|
||||
assertTrue(DefaultCoinSelector.isSelectable(t, BitcoinNetwork.TESTNET));
|
||||
t.getConfidence().markBroadcastBy(new PeerAddress(InetAddress.getByName("5.6.7.8"), TESTNET.getPort()));
|
||||
assertTrue(DefaultCoinSelector.isSelectable(t));
|
||||
assertTrue(DefaultCoinSelector.isSelectable(t, BitcoinNetwork.TESTNET));
|
||||
t = new Transaction(TESTNET);
|
||||
t.getConfidence().setConfidenceType(TransactionConfidence.ConfidenceType.BUILDING);
|
||||
assertTrue(DefaultCoinSelector.isSelectable(t));
|
||||
assertTrue(DefaultCoinSelector.isSelectable(t, BitcoinNetwork.TESTNET));
|
||||
t = new Transaction(REGTEST);
|
||||
t.getConfidence().setConfidenceType(TransactionConfidence.ConfidenceType.PENDING);
|
||||
t.getConfidence().setSource(TransactionConfidence.Source.SELF);
|
||||
assertTrue(DefaultCoinSelector.isSelectable(t));
|
||||
assertTrue(DefaultCoinSelector.isSelectable(t, BitcoinNetwork.REGTEST));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -88,7 +89,7 @@ public class DefaultCoinSelectorTest extends TestWithWallet {
|
||||
Transaction t2 = Objects.requireNonNull(sendMoneyToWallet(AbstractBlockChain.NewBlockType.BEST_CHAIN, COIN));
|
||||
|
||||
// Check we selected just the oldest one.
|
||||
CoinSelector selector = DefaultCoinSelector.get();
|
||||
CoinSelector selector = wallet.getCoinSelector();
|
||||
CoinSelection selection = selector.select(COIN, wallet.calculateAllSpendCandidates());
|
||||
assertTrue(selection.outputs().contains(t1.getOutputs().get(0)));
|
||||
assertEquals(COIN, selection.totalValue());
|
||||
@ -136,7 +137,7 @@ public class DefaultCoinSelectorTest extends TestWithWallet {
|
||||
);
|
||||
t.getConfidence().setConfidenceType(TransactionConfidence.ConfidenceType.BUILDING);
|
||||
|
||||
CoinSelector selector = DefaultCoinSelector.get();
|
||||
CoinSelector selector = DefaultCoinSelector.get(BitcoinNetwork.TESTNET);
|
||||
CoinSelection selection = selector.select(COIN.multiply(2), outputs);
|
||||
|
||||
assertTrue(selection.outputs().size() == 4);
|
||||
|
Loading…
Reference in New Issue
Block a user