diff --git a/AUTHORS b/AUTHORS index 4ade96d4..92cfd7a4 100644 --- a/AUTHORS +++ b/AUTHORS @@ -5,4 +5,5 @@ Thilo Planz Micheal Swiggs Gary Rowe Noa Resare -John Sample \ No newline at end of file +John Sample +Jan Møller \ No newline at end of file diff --git a/src/com/google/bitcoin/core/Transaction.java b/src/com/google/bitcoin/core/Transaction.java index 38e33ef5..154d1f4b 100644 --- a/src/com/google/bitcoin/core/Transaction.java +++ b/src/com/google/bitcoin/core/Transaction.java @@ -170,6 +170,10 @@ public class Transaction extends Message implements Serializable { connected = input.getConnectedOutput(wallet.pending); if (connected == null) continue; + // The connected output may be the change to the sender of a previous input sent to this wallet. In this + // case we ignore it. + if (!connected.isMine(wallet)) + continue; v = v.add(connected.getValue()); } return v; diff --git a/tests/com/google/bitcoin/core/WalletTest.java b/tests/com/google/bitcoin/core/WalletTest.java index 2710658a..911fd3cc 100644 --- a/tests/com/google/bitcoin/core/WalletTest.java +++ b/tests/com/google/bitcoin/core/WalletTest.java @@ -35,10 +35,11 @@ public class WalletTest { private Address myAddress; private Wallet wallet; private BlockStore blockStore; + private ECKey myKey; @Before public void setUp() throws Exception { - ECKey myKey = new ECKey(); + myKey = new ECKey(); myAddress = myKey.toAddress(params); wallet = new Wallet(params); wallet.addKey(myKey); @@ -212,6 +213,23 @@ public class WalletTest { assertEquals(nanos, send2.getValueSentFromMe(wallet)); } + @Test + public void transactions() throws Exception { + // This test covers a bug in which Transaction.getValueSentFromMe was calculating incorrectly. + Transaction tx = createFakeTx(Utils.toNanoCoins(1, 0), myAddress); + // Now add another output (ie, change) that goes to some other address. + Address someOtherGuy = new ECKey().toAddress(params); + TransactionOutput output = new TransactionOutput(params, tx, Utils.toNanoCoins(0, 5), someOtherGuy); + tx.addOutput(output); + wallet.receive(tx, null, BlockChain.NewBlockType.BEST_CHAIN); + // Now the other guy creates a transaction which spends that change. + Transaction tx2 = new Transaction(params); + tx2.addInput(output); + tx2.addOutput(new TransactionOutput(params, tx2, Utils.toNanoCoins(0, 5), myAddress)); + // tx2 doesn't send any coins from us, even though the output is in the wallet. + assertEquals(Utils.toNanoCoins(0, 0), tx2.getValueSentFromMe(wallet)); + } + @Test public void finneyAttack() throws Exception { // A Finney attack is where a miner includes a transaction spending coins to themselves but does not