Skip to content

Commit c2d7c61

Browse files
committed
Merge pull request #5407
9e56532 Coinbases-in-mempool regression test (Gavin Andresen)
2 parents 7eb0667 + 9e56532 commit c2d7c61

File tree

3 files changed

+81
-1
lines changed

3 files changed

+81
-1
lines changed

qa/pull-tester/rpc-tests.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ if [ "x${ENABLE_BITCOIND}${ENABLE_UTILS}${ENABLE_WALLET}" = "x111" ]; then
2323
${BUILDDIR}/qa/rpc-tests/txn_doublespend.py --mineblock --srcdir "${BUILDDIR}/src"
2424
${BUILDDIR}/qa/rpc-tests/getchaintips.py --srcdir "${BUILDDIR}/src"
2525
${BUILDDIR}/qa/rpc-tests/rest.py --srcdir "${BUILDDIR}/src"
26+
${BUILDDIR}/qa/rpc-tests/mempool_spendcoinbase.py --srcdir "${BUILDDIR}/src"
2627
#${BUILDDIR}/qa/rpc-tests/forknotify.py --srcdir "${BUILDDIR}/src"
2728
else
2829
echo "No rpc tests to run. Wallet, utils, and bitcoind must all be enabled"

qa/rpc-tests/mempool_spendcoinbase.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/usr/bin/env python
2+
# Copyright (c) 2014 The Bitcoin Core developers
3+
# Distributed under the MIT software license, see the accompanying
4+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
6+
#
7+
# Test spending coinbase transactions.
8+
# The coinbase transaction in block N can appear in block
9+
# N+100... so is valid in the mempool when the best block
10+
# height is N+99.
11+
# This test makes sure coinbase spends that will be mature
12+
# in the next block are accepted into the memory pool,
13+
# but less mature coinbase spends are NOT.
14+
#
15+
16+
from test_framework import BitcoinTestFramework
17+
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
18+
from util import *
19+
import os
20+
import shutil
21+
22+
# Create one-input, one-output, no-fee transaction:
23+
class MempoolSpendCoinbaseTest(BitcoinTestFramework):
24+
25+
def setup_network(self):
26+
# Just need one node for this test
27+
args = ["-checkmempool", "-debug=mempool"]
28+
self.nodes = []
29+
self.nodes.append(start_node(0, self.options.tmpdir, args))
30+
self.is_network_split = False
31+
32+
def create_tx(self, from_txid, to_address, amount):
33+
inputs = [{ "txid" : from_txid, "vout" : 0}]
34+
outputs = { to_address : amount }
35+
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
36+
signresult = self.nodes[0].signrawtransaction(rawtx)
37+
assert_equal(signresult["complete"], True)
38+
return signresult["hex"]
39+
40+
def run_test(self):
41+
chain_height = self.nodes[0].getblockcount()
42+
assert_equal(chain_height, 200)
43+
node0_address = self.nodes[0].getnewaddress()
44+
45+
# Coinbase at height chain_height-100+1 ok in mempool, should
46+
# get mined. Coinbase at height chain_height-100+2 is
47+
# is too immature to spend.
48+
b = [ self.nodes[0].getblockhash(n) for n in range(101, 103) ]
49+
coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ]
50+
spends_raw = [ self.create_tx(txid, node0_address, 50) for txid in coinbase_txids ]
51+
52+
spend_101_id = self.nodes[0].sendrawtransaction(spends_raw[0])
53+
54+
# coinbase at height 102 should be too immature to spend
55+
assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, spends_raw[1])
56+
57+
# mempool should have just spend_101:
58+
assert_equal(self.nodes[0].getrawmempool(), [ spend_101_id ])
59+
60+
# mine a block, spend_101 should get confirmed
61+
self.nodes[0].setgenerate(True, 1)
62+
assert_equal(set(self.nodes[0].getrawmempool()), set())
63+
64+
# ... and now height 102 can be spent:
65+
spend_102_id = self.nodes[0].sendrawtransaction(spends_raw[1])
66+
assert_equal(self.nodes[0].getrawmempool(), [ spend_102_id ])
67+
68+
if __name__ == '__main__':
69+
MempoolSpendCoinbaseTest().main()

qa/rpc-tests/util.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,4 +330,14 @@ def assert_equal(thing1, thing2):
330330

331331
def assert_greater_than(thing1, thing2):
332332
if thing1 <= thing2:
333-
raise AssertionError("%s <= %s"%(str(thing1),str(thing2)))
333+
raise AssertionError("%s <= %s"%(str(thing1),str(thing2)))
334+
335+
def assert_raises(exc, fun, *args, **kwds):
336+
try:
337+
fun(*args, **kwds)
338+
except exc:
339+
pass
340+
except Exception as e:
341+
raise AssertionError("Unexpected exception raised: "+type(e).__name__)
342+
else:
343+
raise AssertionError("No exception raised")

0 commit comments

Comments
 (0)