3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-13 10:45:51 +00:00

Wallet: Make transaction pools private again, but add a poolContainsTxHash() method that is visible for testing.

This commit is contained in:
Andreas Schildbach 2016-01-16 16:16:43 +01:00
parent 697bb9fd60
commit 7e98f9f792
3 changed files with 46 additions and 25 deletions

View File

@ -120,10 +120,10 @@ public class Wallet extends BaseTaggableObject
// to the user in the UI, etc). A transaction can leave dead and move into spent/unspent if there is a // to the user in the UI, etc). A transaction can leave dead and move into spent/unspent if there is a
// re-org to a chain that doesn't include the double spend. // re-org to a chain that doesn't include the double spend.
@VisibleForTesting final Map<Sha256Hash, Transaction> pending; private final Map<Sha256Hash, Transaction> pending;
@VisibleForTesting final Map<Sha256Hash, Transaction> unspent; private final Map<Sha256Hash, Transaction> unspent;
@VisibleForTesting final Map<Sha256Hash, Transaction> spent; private final Map<Sha256Hash, Transaction> spent;
@VisibleForTesting final Map<Sha256Hash, Transaction> dead; private final Map<Sha256Hash, Transaction> dead;
// All transactions together. // All transactions together.
protected final Map<Sha256Hash, Transaction> transactions; protected final Map<Sha256Hash, Transaction> transactions;
@ -2909,6 +2909,26 @@ public class Wallet extends BaseTaggableObject
} }
} }
@VisibleForTesting
public boolean poolContainsTxHash(final WalletTransaction.Pool pool, final Sha256Hash txHash) {
lock.lock();
try {
switch (pool) {
case UNSPENT:
return unspent.containsKey(txHash);
case SPENT:
return spent.containsKey(txHash);
case PENDING:
return pending.containsKey(txHash);
case DEAD:
return dead.containsKey(txHash);
}
throw new RuntimeException("Unreachable");
} finally {
lock.unlock();
}
}
/** Returns a copy of the internal unspent outputs list */ /** Returns a copy of the internal unspent outputs list */
public List<TransactionOutput> getUnspents() { public List<TransactionOutput> getUnspents() {
lock.lock(); lock.lock();

View File

@ -25,6 +25,7 @@ import org.bitcoinj.testing.FakeTxBuilder;
import org.bitcoinj.utils.BriefLogFormatter; import org.bitcoinj.utils.BriefLogFormatter;
import org.bitcoinj.utils.Threading; import org.bitcoinj.utils.Threading;
import org.bitcoinj.wallet.WalletTransaction;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -586,10 +587,10 @@ public class ChainSplitTest {
// Check the coinbase transaction is building and in the unspent pool only. // Check the coinbase transaction is building and in the unspent pool only.
final Transaction coinbase = txns.get(0); final Transaction coinbase = txns.get(0);
assertEquals(ConfidenceType.BUILDING, coinbase.getConfidence().getConfidenceType()); assertEquals(ConfidenceType.BUILDING, coinbase.getConfidence().getConfidenceType());
assertTrue(!wallet.pending.containsKey(coinbase.getHash())); assertTrue(!wallet.poolContainsTxHash(WalletTransaction.Pool.PENDING, coinbase.getHash()));
assertTrue(wallet.unspent.containsKey(coinbase.getHash())); assertTrue(wallet.poolContainsTxHash(WalletTransaction.Pool.UNSPENT, coinbase.getHash()));
assertTrue(!wallet.spent.containsKey(coinbase.getHash())); assertTrue(!wallet.poolContainsTxHash(WalletTransaction.Pool.SPENT, coinbase.getHash()));
assertTrue(!wallet.dead.containsKey(coinbase.getHash())); assertTrue(!wallet.poolContainsTxHash(WalletTransaction.Pool.DEAD, coinbase.getHash()));
// Add blocks to b3 until we can spend the coinbase. // Add blocks to b3 until we can spend the coinbase.
Block firstTip = b3; Block firstTip = b3;
@ -634,10 +635,10 @@ public class ChainSplitTest {
// Transaction 1 (in block b2) is now on a side chain and should have confidence type of dead and be in // Transaction 1 (in block b2) is now on a side chain and should have confidence type of dead and be in
// the dead pool only. // the dead pool only.
assertEquals(TransactionConfidence.ConfidenceType.DEAD, coinbase.getConfidence().getConfidenceType()); assertEquals(TransactionConfidence.ConfidenceType.DEAD, coinbase.getConfidence().getConfidenceType());
assertTrue(!wallet.pending.containsKey(coinbase.getHash())); assertTrue(!wallet.poolContainsTxHash(WalletTransaction.Pool.PENDING, coinbase.getHash()));
assertTrue(!wallet.unspent.containsKey(coinbase.getHash())); assertTrue(!wallet.poolContainsTxHash(WalletTransaction.Pool.UNSPENT, coinbase.getHash()));
assertTrue(!wallet.spent.containsKey(coinbase.getHash())); assertTrue(!wallet.poolContainsTxHash(WalletTransaction.Pool.SPENT, coinbase.getHash()));
assertTrue(wallet.dead.containsKey(coinbase.getHash())); assertTrue(wallet.poolContainsTxHash(WalletTransaction.Pool.DEAD, coinbase.getHash()));
assertTrue(fodderIsDead.get()); assertTrue(fodderIsDead.get());
// ... and back to the first chain. // ... and back to the first chain.
@ -656,10 +657,10 @@ public class ChainSplitTest {
// The coinbase transaction should now have confidence type of building once more and in the unspent pool only. // The coinbase transaction should now have confidence type of building once more and in the unspent pool only.
assertEquals(TransactionConfidence.ConfidenceType.BUILDING, coinbase.getConfidence().getConfidenceType()); assertEquals(TransactionConfidence.ConfidenceType.BUILDING, coinbase.getConfidence().getConfidenceType());
assertTrue(!wallet.pending.containsKey(coinbase.getHash())); assertTrue(!wallet.poolContainsTxHash(WalletTransaction.Pool.PENDING, coinbase.getHash()));
assertTrue(wallet.unspent.containsKey(coinbase.getHash())); assertTrue(wallet.poolContainsTxHash(WalletTransaction.Pool.UNSPENT, coinbase.getHash()));
assertTrue(!wallet.spent.containsKey(coinbase.getHash())); assertTrue(!wallet.poolContainsTxHash(WalletTransaction.Pool.SPENT, coinbase.getHash()));
assertTrue(!wallet.dead.containsKey(coinbase.getHash())); assertTrue(!wallet.poolContainsTxHash(WalletTransaction.Pool.DEAD, coinbase.getHash()));
// However, fodder is still dead. Bitcoin Core doesn't keep killed transactions around in case they become // However, fodder is still dead. Bitcoin Core doesn't keep killed transactions around in case they become
// valid again later. They are just deleted from the mempool for good. // valid again later. They are just deleted from the mempool for good.
@ -679,9 +680,9 @@ public class ChainSplitTest {
// The coinbase transaction should now have the confidence type of dead and be in the dead pool only. // The coinbase transaction should now have the confidence type of dead and be in the dead pool only.
assertEquals(TransactionConfidence.ConfidenceType.DEAD, coinbase.getConfidence().getConfidenceType()); assertEquals(TransactionConfidence.ConfidenceType.DEAD, coinbase.getConfidence().getConfidenceType());
assertTrue(!wallet.pending.containsKey(coinbase.getHash())); assertTrue(!wallet.poolContainsTxHash(WalletTransaction.Pool.PENDING, coinbase.getHash()));
assertTrue(!wallet.unspent.containsKey(coinbase.getHash())); assertTrue(!wallet.poolContainsTxHash(WalletTransaction.Pool.UNSPENT, coinbase.getHash()));
assertTrue(!wallet.spent.containsKey(coinbase.getHash())); assertTrue(!wallet.poolContainsTxHash(WalletTransaction.Pool.SPENT, coinbase.getHash()));
assertTrue(wallet.dead.containsKey(coinbase.getHash())); assertTrue(wallet.poolContainsTxHash(WalletTransaction.Pool.DEAD, coinbase.getHash()));
} }
} }

View File

@ -1156,27 +1156,27 @@ public class WalletTest extends TestWithWallet {
private void assertInConflict(Transaction tx) { private void assertInConflict(Transaction tx) {
assertEquals(ConfidenceType.IN_CONFLICT, tx.getConfidence().getConfidenceType()); assertEquals(ConfidenceType.IN_CONFLICT, tx.getConfidence().getConfidenceType());
assertTrue(wallet.pending.containsKey(tx.getHash())); assertTrue(wallet.poolContainsTxHash(WalletTransaction.Pool.PENDING, tx.getHash()));
} }
private void assertPending(Transaction tx) { private void assertPending(Transaction tx) {
assertEquals(ConfidenceType.PENDING, tx.getConfidence().getConfidenceType()); assertEquals(ConfidenceType.PENDING, tx.getConfidence().getConfidenceType());
assertTrue(wallet.pending.containsKey(tx.getHash())); assertTrue(wallet.poolContainsTxHash(WalletTransaction.Pool.PENDING, tx.getHash()));
} }
private void assertSpent(Transaction tx) { private void assertSpent(Transaction tx) {
assertEquals(ConfidenceType.BUILDING, tx.getConfidence().getConfidenceType()); assertEquals(ConfidenceType.BUILDING, tx.getConfidence().getConfidenceType());
assertTrue(wallet.spent.containsKey(tx.getHash())); assertTrue(wallet.poolContainsTxHash(WalletTransaction.Pool.SPENT, tx.getHash()));
} }
private void assertUnspent(Transaction tx) { private void assertUnspent(Transaction tx) {
assertEquals(ConfidenceType.BUILDING, tx.getConfidence().getConfidenceType()); assertEquals(ConfidenceType.BUILDING, tx.getConfidence().getConfidenceType());
assertTrue(wallet.unspent.containsKey(tx.getHash())); assertTrue(wallet.poolContainsTxHash(WalletTransaction.Pool.UNSPENT, tx.getHash()));
} }
private void assertDead(Transaction tx) { private void assertDead(Transaction tx) {
assertEquals(ConfidenceType.DEAD, tx.getConfidence().getConfidenceType()); assertEquals(ConfidenceType.DEAD, tx.getConfidence().getConfidenceType());
assertTrue(wallet.dead.containsKey(tx.getHash())); assertTrue(wallet.poolContainsTxHash(WalletTransaction.Pool.DEAD, tx.getHash()));
} }
@Test @Test