From 2c74beb9f50a231cbbb7ae578cfa0084c8770f0d Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Wed, 6 Jul 2011 12:12:18 +0000 Subject: [PATCH] =?UTF-8?q?Fix=20a=20bug=20in=20Transaction.getValueSentFr?= =?UTF-8?q?omMe()=20in=20which=20inputs=20connected=20to=20outputs=20that?= =?UTF-8?q?=20existed=20in=20the=20wallet=20but=20were=20not=20actually=20?= =?UTF-8?q?owned=20by=20us=20were=20counted.=20Resolves=20issue=2036.=20Pa?= =?UTF-8?q?tch=20from=20Jan=20M=C3=B8ller.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AUTHORS | 3 ++- src/com/google/bitcoin/core/Transaction.java | 4 ++++ tests/com/google/bitcoin/core/WalletTest.java | 20 ++++++++++++++++++- 3 files changed, 25 insertions(+), 2 deletions(-) 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