From fe9cbf8b7bc5e3c3b5dcb0b4696adbb5874d9abd Mon Sep 17 00:00:00 2001 From: Miron Cuperman Date: Tue, 10 Apr 2012 13:25:39 -0700 Subject: [PATCH] Wallet.isConsistent tests Resolves issue 184. --- .../java/com/google/bitcoin/core/Wallet.java | 2 +- .../com/google/bitcoin/core/WalletTest.java | 50 +++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) 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 8a0a5479..397277e9 100644 --- a/core/src/main/java/com/google/bitcoin/core/Wallet.java +++ b/core/src/main/java/com/google/bitcoin/core/Wallet.java @@ -232,7 +232,7 @@ public class Wallet implements Serializable { int size2 = unspent.size() + spent.size() + pendingInactive.size() + dead.size(); if (size1 != size2) { log.error("Inconsistent wallet sizes: {} {}", size1, size2); - success = true; + success = false; } for (Transaction tx : unspent.values()) { 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 f1566fa7..826ffc8f 100644 --- a/core/src/test/java/com/google/bitcoin/core/WalletTest.java +++ b/core/src/test/java/com/google/bitcoin/core/WalletTest.java @@ -16,6 +16,7 @@ package com.google.bitcoin.core; +import com.google.bitcoin.core.WalletTransaction.Pool; import com.google.bitcoin.store.BlockStore; import com.google.bitcoin.store.MemoryBlockStore; import com.google.bitcoin.store.WalletProtobufSerializer; @@ -263,6 +264,55 @@ public class WalletTest { assertEquals(BigInteger.ZERO.subtract(toNanoCoins(0, 10)), send2.getValue(wallet)); } + @Test + public void isConsistent_duplicates() throws Exception { + // This test ensures that isConsistent catches duplicate transactions. + Transaction tx = createFakeTx(params, Utils.toNanoCoins(1, 0), myAddress); + Address someOtherGuy = new ECKey().toAddress(params); + TransactionOutput output = new TransactionOutput(params, tx, Utils.toNanoCoins(0, 5), someOtherGuy); + tx.addOutput(output); + wallet.receiveFromBlock(tx, null, BlockChain.NewBlockType.BEST_CHAIN); + + assertTrue(wallet.isConsistent()); + + Transaction txClone = new Transaction(params, tx.bitcoinSerialize()); + try { + wallet.receiveFromBlock(txClone, null, BlockChain.NewBlockType.SIDE_CHAIN); + fail(); + } catch (IllegalStateException ex) { + // expected + } + } + + @Test + public void isConsistent_pools() throws Exception { + // This test ensures that isConsistent catches transactions that are in incompatible pools. + Transaction tx = createFakeTx(params, Utils.toNanoCoins(1, 0), myAddress); + Address someOtherGuy = new ECKey().toAddress(params); + TransactionOutput output = new TransactionOutput(params, tx, Utils.toNanoCoins(0, 5), someOtherGuy); + tx.addOutput(output); + wallet.receiveFromBlock(tx, null, BlockChain.NewBlockType.BEST_CHAIN); + + assertTrue(wallet.isConsistent()); + + wallet.addWalletTransaction(new WalletTransaction(Pool.PENDING, tx)); + assertFalse(wallet.isConsistent()); + } + + @Test + public void isConsistent_spent() throws Exception { + // This test ensures that isConsistent catches transactions that are marked spent when + // they aren't. + Transaction tx = createFakeTx(params, Utils.toNanoCoins(1, 0), myAddress); + Address someOtherGuy = new ECKey().toAddress(params); + TransactionOutput output = new TransactionOutput(params, tx, Utils.toNanoCoins(0, 5), someOtherGuy); + tx.addOutput(output); + assertTrue(wallet.isConsistent()); + + wallet.addWalletTransaction(new WalletTransaction(Pool.SPENT, tx)); + assertFalse(wallet.isConsistent()); + } + @Test public void transactions() throws Exception { // This test covers a bug in which Transaction.getValueSentFromMe was calculating incorrectly.