mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2024-11-19 09:50:32 +01:00
Mark as spent the outputs used by pending transactions. Resolves issue 243.
This commit is contained in:
parent
c4304fe07d
commit
9f036bff84
3
AUTHORS
3
AUTHORS
@ -13,4 +13,5 @@ Steve Coughlan <shadders.del@gmail.com>
|
||||
Roman Mandeleil <roman.mandeleil@gmail.com>
|
||||
Chris Rico <chrisrico@gmail.com>
|
||||
Vasile Rotaru <vrotaru.md@gmail.com>
|
||||
Joseph Gleason <fireduck@gmail.com>
|
||||
Joseph Gleason <fireduck@gmail.com>
|
||||
Wilhelmus Petrus van Cuijk <phedny@gmail.com>
|
@ -866,8 +866,12 @@ public class Wallet implements Serializable {
|
||||
// Not found in the unspent map. Try again with the spent map.
|
||||
result = input.connect(spent, TransactionInput.ConnectMode.ABORT_ON_CONFLICT);
|
||||
if (result == TransactionInput.ConnectionResult.NO_SUCH_TX) {
|
||||
// Doesn't spend any of our outputs or is coinbase.
|
||||
continue;
|
||||
// Not found in the unspent and spent maps. Try again with the pending map.
|
||||
result = input.connect(pending, TransactionInput.ConnectMode.ABORT_ON_CONFLICT);
|
||||
if (result == TransactionInput.ConnectionResult.NO_SUCH_TX) {
|
||||
// Doesn't spend any of our outputs or is coinbase.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package com.google.bitcoin.core;
|
||||
|
||||
import com.google.bitcoin.core.Transaction.SigHash;
|
||||
import com.google.bitcoin.core.WalletTransaction.Pool;
|
||||
import com.google.bitcoin.store.BlockStore;
|
||||
import com.google.bitcoin.store.MemoryBlockStore;
|
||||
@ -789,6 +790,51 @@ public class WalletTest {
|
||||
assertNotNull(results[0]);
|
||||
assertEquals(f, results[1]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void spendOutputFromPendingTransaction() throws Exception {
|
||||
// We'll set up a wallet that receives a coin, then sends a coin of lesser value and keeps the change.
|
||||
BigInteger v1 = Utils.toNanoCoins(1, 0);
|
||||
Transaction t1 = createFakeTx(params, v1, myAddress);
|
||||
|
||||
wallet.receiveFromBlock(t1, null, BlockChain.NewBlockType.BEST_CHAIN);
|
||||
assertEquals(v1, wallet.getBalance());
|
||||
assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
|
||||
assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.ALL));
|
||||
|
||||
// First create our current transaction
|
||||
ECKey k2 = new ECKey();
|
||||
wallet.addKey(k2);
|
||||
BigInteger v2 = toNanoCoins(0, 50);
|
||||
Transaction t2 = new Transaction(params);
|
||||
TransactionOutput o2 = new TransactionOutput(params, t2, v2, k2.toAddress(params));
|
||||
t2.addOutput(o2);
|
||||
boolean complete = wallet.completeTx(t2);
|
||||
assertTrue(complete);
|
||||
|
||||
// Commit t2, so it is placed in the pending pool
|
||||
wallet.commitTx(t2);
|
||||
assertEquals(0, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
|
||||
assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.PENDING));
|
||||
assertEquals(2, wallet.getPoolSize(WalletTransaction.Pool.ALL));
|
||||
|
||||
// Now try the spend the output
|
||||
ECKey k3 = new ECKey();
|
||||
BigInteger v3 = toNanoCoins(0, 25);
|
||||
Transaction t3 = new Transaction(params);
|
||||
t3.addOutput(v3, k3.toAddress(params));
|
||||
t3.addInput(o2);
|
||||
t3.signInputs(SigHash.ALL, wallet);
|
||||
|
||||
// Commit t3, so the coins from the pending t2 are spent
|
||||
wallet.commitTx(t3);
|
||||
assertEquals(0, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
|
||||
assertEquals(2, wallet.getPoolSize(WalletTransaction.Pool.PENDING));
|
||||
assertEquals(3, wallet.getPoolSize(WalletTransaction.Pool.ALL));
|
||||
|
||||
// Now the output of t2 must not be available for spending
|
||||
assertFalse(o2.isAvailableForSpending());
|
||||
}
|
||||
|
||||
// There is a test for spending a coinbase transaction as it matures in BlockChainTest#coinbaseTransactionAvailability
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user