aboutsummaryrefslogtreecommitdiff
path: root/qa
diff options
context:
space:
mode:
Diffstat (limited to 'qa')
-rwxr-xr-xqa/pull-tester/rpc-tests.sh1
-rwxr-xr-xqa/rpc-tests/mempool_spendcoinbase.py69
-rw-r--r--qa/rpc-tests/util.py12
3 files changed, 81 insertions, 1 deletions
diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh
index a064fb81e9..9587d90dfe 100755
--- a/qa/pull-tester/rpc-tests.sh
+++ b/qa/pull-tester/rpc-tests.sh
@@ -22,6 +22,7 @@ if [ "x${ENABLE_BITCOIND}${ENABLE_UTILS}${ENABLE_WALLET}" = "x111" ]; then
${BUILDDIR}/qa/rpc-tests/txn_doublespend.py --mineblock --srcdir "${BUILDDIR}/src"
${BUILDDIR}/qa/rpc-tests/getchaintips.py --srcdir "${BUILDDIR}/src"
${BUILDDIR}/qa/rpc-tests/rest.py --srcdir "${BUILDDIR}/src"
+ ${BUILDDIR}/qa/rpc-tests/mempool_spendcoinbase.py --srcdir "${BUILDDIR}/src"
#${BUILDDIR}/qa/rpc-tests/forknotify.py --srcdir "${BUILDDIR}/src"
else
echo "No rpc tests to run. Wallet, utils, and bitcoind must all be enabled"
diff --git a/qa/rpc-tests/mempool_spendcoinbase.py b/qa/rpc-tests/mempool_spendcoinbase.py
new file mode 100755
index 0000000000..0fc7c8577e
--- /dev/null
+++ b/qa/rpc-tests/mempool_spendcoinbase.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#
+# Test spending coinbase transactions.
+# The coinbase transaction in block N can appear in block
+# N+100... so is valid in the mempool when the best block
+# height is N+99.
+# This test makes sure coinbase spends that will be mature
+# in the next block are accepted into the memory pool,
+# but less mature coinbase spends are NOT.
+#
+
+from test_framework import BitcoinTestFramework
+from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
+from util import *
+import os
+import shutil
+
+# Create one-input, one-output, no-fee transaction:
+class MempoolSpendCoinbaseTest(BitcoinTestFramework):
+
+ def setup_network(self):
+ # Just need one node for this test
+ args = ["-checkmempool", "-debug=mempool"]
+ self.nodes = []
+ self.nodes.append(start_node(0, self.options.tmpdir, args))
+ self.is_network_split = False
+
+ def create_tx(self, from_txid, to_address, amount):
+ inputs = [{ "txid" : from_txid, "vout" : 0}]
+ outputs = { to_address : amount }
+ rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
+ signresult = self.nodes[0].signrawtransaction(rawtx)
+ assert_equal(signresult["complete"], True)
+ return signresult["hex"]
+
+ def run_test(self):
+ chain_height = self.nodes[0].getblockcount()
+ assert_equal(chain_height, 200)
+ node0_address = self.nodes[0].getnewaddress()
+
+ # Coinbase at height chain_height-100+1 ok in mempool, should
+ # get mined. Coinbase at height chain_height-100+2 is
+ # is too immature to spend.
+ b = [ self.nodes[0].getblockhash(n) for n in range(101, 103) ]
+ coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ]
+ spends_raw = [ self.create_tx(txid, node0_address, 50) for txid in coinbase_txids ]
+
+ spend_101_id = self.nodes[0].sendrawtransaction(spends_raw[0])
+
+ # coinbase at height 102 should be too immature to spend
+ assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, spends_raw[1])
+
+ # mempool should have just spend_101:
+ assert_equal(self.nodes[0].getrawmempool(), [ spend_101_id ])
+
+ # mine a block, spend_101 should get confirmed
+ self.nodes[0].setgenerate(True, 1)
+ assert_equal(set(self.nodes[0].getrawmempool()), set())
+
+ # ... and now height 102 can be spent:
+ spend_102_id = self.nodes[0].sendrawtransaction(spends_raw[1])
+ assert_equal(self.nodes[0].getrawmempool(), [ spend_102_id ])
+
+if __name__ == '__main__':
+ MempoolSpendCoinbaseTest().main()
diff --git a/qa/rpc-tests/util.py b/qa/rpc-tests/util.py
index 6b66bfd8f6..ec65f783e8 100644
--- a/qa/rpc-tests/util.py
+++ b/qa/rpc-tests/util.py
@@ -330,4 +330,14 @@ def assert_equal(thing1, thing2):
def assert_greater_than(thing1, thing2):
if thing1 <= thing2:
- raise AssertionError("%s <= %s"%(str(thing1),str(thing2))) \ No newline at end of file
+ raise AssertionError("%s <= %s"%(str(thing1),str(thing2)))
+
+def assert_raises(exc, fun, *args, **kwds):
+ try:
+ fun(*args, **kwds)
+ except exc:
+ pass
+ except Exception as e:
+ raise AssertionError("Unexpected exception raised: "+type(e).__name__)
+ else:
+ raise AssertionError("No exception raised")