From a71da1b859f12bd15db4eba6c77fa55a57d9e151 Mon Sep 17 00:00:00 2001 From: Andreas Schildbach Date: Wed, 25 May 2016 14:19:13 +0200 Subject: [PATCH] Fix wrong balance calculation if identical (apart from the index) outputs are involved. This regression was triggered by a53b508049d0febf59dfd3f7e5d75776a0b3f7a8, though before that change it only worked by luck. --- .../main/java/org/bitcoinj/core/TransactionOutput.java | 4 ++-- core/src/test/java/org/bitcoinj/wallet/WalletTest.java | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/bitcoinj/core/TransactionOutput.java b/core/src/main/java/org/bitcoinj/core/TransactionOutput.java index 0a9facf0..357cdc2c 100644 --- a/core/src/main/java/org/bitcoinj/core/TransactionOutput.java +++ b/core/src/main/java/org/bitcoinj/core/TransactionOutput.java @@ -419,8 +419,8 @@ public class TransactionOutput extends ChildMessage { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; TransactionOutput other = (TransactionOutput) o; - return value == other.value && (parent == null || parent == other.parent) - && Arrays.equals(scriptBytes, other.scriptBytes); + return value == other.value && (parent == null || (parent == other.parent && getIndex() == other.getIndex())) + && Arrays.equals(scriptBytes, other.scriptBytes); } @Override diff --git a/core/src/test/java/org/bitcoinj/wallet/WalletTest.java b/core/src/test/java/org/bitcoinj/wallet/WalletTest.java index e164f622..acd2d8d7 100644 --- a/core/src/test/java/org/bitcoinj/wallet/WalletTest.java +++ b/core/src/test/java/org/bitcoinj/wallet/WalletTest.java @@ -545,6 +545,16 @@ public class WalletTest extends TestWithWallet { assertEquals(v4, wallet.getBalance(Wallet.BalanceType.AVAILABLE)); } + @Test + public void balanceWithIdenticalOutputs() { + assertEquals(Coin.ZERO, wallet.getBalance(BalanceType.ESTIMATED)); + Transaction tx = new Transaction(PARAMS); + tx.addOutput(Coin.COIN, myAddress); + tx.addOutput(Coin.COIN, myAddress); // identical to the above + wallet.addWalletTransaction(new WalletTransaction(Pool.UNSPENT, tx)); + assertEquals(Coin.COIN.plus(Coin.COIN), wallet.getBalance(BalanceType.ESTIMATED)); + } + // Intuitively you'd expect to be able to create a transaction with identical inputs and outputs and get an // identical result to Bitcoin Core. However the signatures are not deterministic - signing the same data // with the same key twice gives two different outputs. So we cannot prove bit-for-bit compatibility in this test