From 289c3d19f0578fff71131d71ef2a1f3c572e4e5c Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sun, 23 Dec 2012 17:44:18 -0500 Subject: [PATCH] Add a Wallet.notifyTransactionIsInBlock(Sha256Hash txHash...) --- .../bitcoin/core/BlockChainListener.java | 11 ++++++++ .../java/com/google/bitcoin/core/Wallet.java | 26 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/core/src/main/java/com/google/bitcoin/core/BlockChainListener.java b/core/src/main/java/com/google/bitcoin/core/BlockChainListener.java index 95356d18..2ed69a89 100644 --- a/core/src/main/java/com/google/bitcoin/core/BlockChainListener.java +++ b/core/src/main/java/com/google/bitcoin/core/BlockChainListener.java @@ -61,4 +61,15 @@ public interface BlockChainListener { */ void receiveFromBlock(Transaction tx, StoredBlock block, BlockChain.NewBlockType blockType) throws VerificationException; + + /** + *

Called by the {@link BlockChain} when we receive a new filtered block that contains the given transaction + * hash in its merkle tree.

+ * + *

A transaction may be received multiple times if is included into blocks in parallel chains. The blockType + * parameter describes whether the containing block is on the main/best chain or whether it's on a presently + * inactive side chain.

+ */ + void notifyTransactionIsInBlock(Sha256Hash txHash, StoredBlock block, + BlockChain.NewBlockType blockType) throws VerificationException; } 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 b93df4e1..884ca793 100644 --- a/core/src/main/java/com/google/bitcoin/core/Wallet.java +++ b/core/src/main/java/com/google/bitcoin/core/Wallet.java @@ -613,6 +613,32 @@ public class Wallet implements Serializable, BlockChainListener { BlockChain.NewBlockType blockType) throws VerificationException { receive(tx, block, blockType, false); } + + /** + * Called by the {@link BlockChain} when we receive a new filtered block that contains a transactions previously + * received by a call to @{link receivePending}.

+ * + * This is necessary for the internal book-keeping Wallet does. When a transaction is received that sends us + * coins it is added to a pool so we can use it later to create spends. When a transaction is received that + * consumes outputs they are marked as spent so they won't be used in future.

+ * + * A transaction that spends our own coins can be received either because a spend we created was accepted by the + * network and thus made it into a block, or because our keys are being shared between multiple instances and + * some other node spent the coins instead. We still have to know about that to avoid accidentally trying to + * double spend.

+ * + * A transaction may be received multiple times if is included into blocks in parallel chains. The blockType + * parameter describes whether the containing block is on the main/best chain or whether it's on a presently + * inactive side chain. We must still record these transactions and the blocks they appear in because a future + * block might change which chain is best causing a reorganize. A re-org can totally change our balance! + */ + public synchronized void notifyTransactionIsInBlock(Sha256Hash txHash, StoredBlock block, + BlockChain.NewBlockType blockType) throws VerificationException { + Transaction tx = pending.get(txHash); + if (tx == null) + return; + receive(tx, block, blockType, false); + } /** * Called when we have found a transaction (via network broadcast or otherwise) that is relevant to this wallet