From d4cfad59cf720ec2331971de71220804cdf6e0bb Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Thu, 14 Feb 2013 19:04:57 +0100 Subject: [PATCH] Fix a bug where pending transactions with spent outputs would be considered unspent, triggering consistency assertions. Resolves issue 313. --- core/src/main/java/com/google/bitcoin/core/Wallet.java | 7 ++++--- .../test/java/com/google/bitcoin/core/WalletTest.java | 10 +++++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/google/bitcoin/core/Wallet.java b/core/src/main/java/com/google/bitcoin/core/Wallet.java index a6d3a96e..f9f07b0f 100644 --- a/core/src/main/java/com/google/bitcoin/core/Wallet.java +++ b/core/src/main/java/com/google/bitcoin/core/Wallet.java @@ -933,8 +933,9 @@ public class Wallet implements Serializable, BlockChainListener { // A transaction we created appeared in a block. Probably this is a spend we broadcast that has been // accepted by the network. if (bestChain) { - if (valueSentToMe.equals(BigInteger.ZERO)) { - // There were no change transactions so this tx is fully spent. + // Was confirmed. + if (tx.isEveryOwnedOutputSpent(this)) { + // There were no change transactions so this tx is fully spent log.info(" ->spent"); addWalletTransaction(Pool.SPENT, tx); } else { @@ -1091,7 +1092,7 @@ public class Wallet implements Serializable, BlockChainListener { updateForSpends(tx, true); - if (!tx.getValueSentToMe(this).equals(BigInteger.ZERO)) { + if (!tx.isEveryOwnedOutputSpent(this)) { // It's sending us coins. log.info(" new tx {} ->unspent", tx.getHashAsString()); addWalletTransaction(Pool.UNSPENT, tx); diff --git a/core/src/test/java/com/google/bitcoin/core/WalletTest.java b/core/src/test/java/com/google/bitcoin/core/WalletTest.java index 72b1782d..24fe44d9 100644 --- a/core/src/test/java/com/google/bitcoin/core/WalletTest.java +++ b/core/src/test/java/com/google/bitcoin/core/WalletTest.java @@ -142,6 +142,14 @@ public class WalletTest { assertEquals(v3, wallet.getBalance()); Transaction t3 = wallet.createSend(new ECKey().toAddress(params), v3); assertNotNull(t3); + wallet.commitTx(t3); + assertTrue(wallet.isConsistent()); + // t2 and t3 gets confirmed in the same block. + BlockPair bp = createFakeBlock(blockStore, t2, t3); + wallet.receiveFromBlock(t2, bp.storedBlock, AbstractBlockChain.NewBlockType.BEST_CHAIN); + wallet.receiveFromBlock(t3, bp.storedBlock, AbstractBlockChain.NewBlockType.BEST_CHAIN); + wallet.notifyNewBestBlock(bp.block); + assertTrue(wallet.isConsistent()); } @Test @@ -848,7 +856,7 @@ public class WalletTest { assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.PENDING)); assertEquals(2, wallet.getPoolSize(WalletTransaction.Pool.ALL)); - // Now try the spend the output + // Now try to the spend the output. ECKey k3 = new ECKey(); BigInteger v3 = toNanoCoins(0, 25); Transaction t3 = new Transaction(params);