From 736f9414246f2a855e7b6fc57c8f903e60530540 Mon Sep 17 00:00:00 2001 From: Conor Scott Date: Mon, 30 Jul 2018 10:16:40 +0200 Subject: [Tests] Cleanup extra instances of create_transaction --- test/functional/feature_block.py | 6 +++--- test/functional/feature_cltv.py | 18 ++++-------------- test/functional/feature_csv_activation.py | 11 +---------- test/functional/feature_dersig.py | 20 +++++--------------- test/functional/feature_nulldummy.py | 26 +++++++------------------- test/functional/p2p_invalid_block.py | 6 +++--- test/functional/p2p_invalid_tx.py | 4 ++-- test/functional/p2p_unrequested_blocks.py | 4 ++-- test/functional/test_framework/blocktools.py | 24 +++++++++++++++++++----- 9 files changed, 46 insertions(+), 73 deletions(-) diff --git a/test/functional/feature_block.py b/test/functional/feature_block.py index b230f1c9c2..6d1ec8f09a 100755 --- a/test/functional/feature_block.py +++ b/test/functional/feature_block.py @@ -7,7 +7,7 @@ import copy import struct import time -from test_framework.blocktools import create_block, create_coinbase, create_transaction, get_legacy_sigopcount_block +from test_framework.blocktools import create_block, create_coinbase, create_tx_with_script, get_legacy_sigopcount_block from test_framework.key import CECKey from test_framework.messages import ( CBlock, @@ -1217,7 +1217,7 @@ class FullBlockTest(BitcoinTestFramework): # this is a little handier to use than the version in blocktools.py def create_tx(self, spend_tx, n, value, script=CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE])): - return create_transaction(spend_tx, n, b"", value, script) + return create_tx_with_script(spend_tx, n, b"", value, script) # sign a transaction, using the key we know about # this signs input 0 in tx, which is assumed to be spending output n in spend_tx @@ -1253,7 +1253,7 @@ class FullBlockTest(BitcoinTestFramework): coinbase.vout[0].nValue += spend.tx.vout[spend.n].nValue - 1 # all but one satoshi to fees coinbase.rehash() block = create_block(base_block_hash, coinbase, block_time) - tx = create_transaction(spend.tx, spend.n, b"", 1, script) # spend 1 satoshi + tx = create_tx_with_script(spend.tx, spend.n, b"", 1, script) # spend 1 satoshi self.sign_tx(tx, spend.tx, spend.n) self.add_transactions_to_block(block, [tx]) block.hashMerkleRoot = block.calc_merkle_root() diff --git a/test/functional/feature_cltv.py b/test/functional/feature_cltv.py index 7a106ea3d0..0ba261a97b 100755 --- a/test/functional/feature_cltv.py +++ b/test/functional/feature_cltv.py @@ -11,7 +11,7 @@ Test that the CHECKLOCKTIMEVERIFY soft-fork activates at (regtest) block height from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * from test_framework.mininode import * -from test_framework.blocktools import create_coinbase, create_block +from test_framework.blocktools import create_coinbase, create_block, create_transaction from test_framework.script import CScript, OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP, CScriptNum from io import BytesIO @@ -49,16 +49,6 @@ def cltv_validate(node, tx, height): list(CScript(new_tx.vin[0].scriptSig))) return new_tx -def create_transaction(node, coinbase, to_address, amount): - from_txid = node.getblock(coinbase)['tx'][0] - inputs = [{ "txid" : from_txid, "vout" : 0}] - outputs = { to_address : amount } - rawtx = node.createrawtransaction(inputs, outputs) - signresult = node.signrawtransactionwithwallet(rawtx) - tx = CTransaction() - tx.deserialize(BytesIO(hex_str_to_bytes(signresult['hex']))) - return tx - class BIP65Test(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 @@ -70,12 +60,12 @@ class BIP65Test(BitcoinTestFramework): self.nodes[0].p2p.wait_for_verack() self.log.info("Mining %d blocks", CLTV_HEIGHT - 2) - self.coinbase_blocks = self.nodes[0].generate(CLTV_HEIGHT - 2) + self.coinbase_txids = [self.nodes[0].getblock(b)['tx'][0] for b in self.nodes[0].generate(CLTV_HEIGHT - 2)] self.nodeaddress = self.nodes[0].getnewaddress() self.log.info("Test that an invalid-according-to-CLTV transaction can still appear in a block") - spendtx = create_transaction(self.nodes[0], self.coinbase_blocks[0], + spendtx = create_transaction(self.nodes[0], self.coinbase_txids[0], self.nodeaddress, 1.0) cltv_invalidate(spendtx) spendtx.rehash() @@ -110,7 +100,7 @@ class BIP65Test(BitcoinTestFramework): self.log.info("Test that invalid-according-to-cltv transactions cannot appear in a block") block.nVersion = 4 - spendtx = create_transaction(self.nodes[0], self.coinbase_blocks[1], + spendtx = create_transaction(self.nodes[0], self.coinbase_txids[1], self.nodeaddress, 1.0) cltv_invalidate(spendtx) spendtx.rehash() diff --git a/test/functional/feature_csv_activation.py b/test/functional/feature_csv_activation.py index 6199b753be..a74471aae5 100755 --- a/test/functional/feature_csv_activation.py +++ b/test/functional/feature_csv_activation.py @@ -47,7 +47,7 @@ from itertools import product from io import BytesIO import time -from test_framework.blocktools import create_coinbase, create_block +from test_framework.blocktools import create_coinbase, create_block, create_transaction from test_framework.messages import ToHex, CTransaction from test_framework.mininode import P2PDataStore from test_framework.script import ( @@ -85,15 +85,6 @@ def relative_locktime(sdf, srhb, stf, srlb): def all_rlt_txs(txs): return [tx['tx'] for tx in txs] -def create_transaction(node, txid, to_address, amount): - inputs = [{"txid": txid, "vout": 0}] - outputs = {to_address: amount} - rawtx = node.createrawtransaction(inputs, outputs) - tx = CTransaction() - f = BytesIO(hex_str_to_bytes(rawtx)) - tx.deserialize(f) - return tx - def sign_transaction(node, unsignedtx): rawtx = ToHex(unsignedtx) signresult = node.signrawtransactionwithwallet(rawtx) diff --git a/test/functional/feature_dersig.py b/test/functional/feature_dersig.py index 1848ea99c0..bdd1eaaccc 100755 --- a/test/functional/feature_dersig.py +++ b/test/functional/feature_dersig.py @@ -10,9 +10,8 @@ Test that the DERSIG soft-fork activates at (regtest) height 1251. from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * from test_framework.mininode import * -from test_framework.blocktools import create_coinbase, create_block +from test_framework.blocktools import create_coinbase, create_block, create_transaction from test_framework.script import CScript -from io import BytesIO DERSIG_HEIGHT = 1251 @@ -37,15 +36,6 @@ def unDERify(tx): newscript.append(i) tx.vin[0].scriptSig = CScript(newscript) -def create_transaction(node, coinbase, to_address, amount): - from_txid = node.getblock(coinbase)['tx'][0] - inputs = [{ "txid" : from_txid, "vout" : 0}] - outputs = { to_address : amount } - rawtx = node.createrawtransaction(inputs, outputs) - signresult = node.signrawtransactionwithwallet(rawtx) - tx = CTransaction() - tx.deserialize(BytesIO(hex_str_to_bytes(signresult['hex']))) - return tx class BIP66Test(BitcoinTestFramework): @@ -61,12 +51,12 @@ class BIP66Test(BitcoinTestFramework): self.nodes[0].p2p.wait_for_verack() self.log.info("Mining %d blocks", DERSIG_HEIGHT - 2) - self.coinbase_blocks = self.nodes[0].generate(DERSIG_HEIGHT - 2) + self.coinbase_txids = [self.nodes[0].getblock(b)['tx'][0] for b in self.nodes[0].generate(DERSIG_HEIGHT - 2)] self.nodeaddress = self.nodes[0].getnewaddress() self.log.info("Test that a transaction with non-DER signature can still appear in a block") - spendtx = create_transaction(self.nodes[0], self.coinbase_blocks[0], + spendtx = create_transaction(self.nodes[0], self.coinbase_txids[0], self.nodeaddress, 1.0) unDERify(spendtx) spendtx.rehash() @@ -103,7 +93,7 @@ class BIP66Test(BitcoinTestFramework): self.log.info("Test that transactions with non-DER signatures cannot appear in a block") block.nVersion = 3 - spendtx = create_transaction(self.nodes[0], self.coinbase_blocks[1], + spendtx = create_transaction(self.nodes[0], self.coinbase_txids[1], self.nodeaddress, 1.0) unDERify(spendtx) spendtx.rehash() @@ -141,7 +131,7 @@ class BIP66Test(BitcoinTestFramework): self.log.info("Test that a version 3 block with a DERSIG-compliant transaction is accepted") block.vtx[1] = create_transaction(self.nodes[0], - self.coinbase_blocks[1], self.nodeaddress, 1.0) + self.coinbase_txids[1], self.nodeaddress, 1.0) block.hashMerkleRoot = block.calc_merkle_root() block.rehash() block.solve() diff --git a/test/functional/feature_nulldummy.py b/test/functional/feature_nulldummy.py index bd41913e0d..21255c89c8 100755 --- a/test/functional/feature_nulldummy.py +++ b/test/functional/feature_nulldummy.py @@ -16,9 +16,8 @@ Generate 427 more blocks. from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * from test_framework.messages import CTransaction -from test_framework.blocktools import create_coinbase, create_block, add_witness_commitment +from test_framework.blocktools import create_coinbase, create_block, create_transaction, add_witness_commitment from test_framework.script import CScript -from io import BytesIO import time NULLDUMMY_ERROR = "non-mandatory-script-verify-flag (Dummy CHECKMULTISIG argument must be zero) (code 64)" @@ -61,16 +60,16 @@ class NULLDUMMYTest(BitcoinTestFramework): self.lastblocktime = int(time.time()) + 429 self.log.info("Test 1: NULLDUMMY compliant base transactions should be accepted to mempool and mined before activation [430]") - test1txs = [self.create_transaction(self.nodes[0], coinbase_txid[0], self.ms_address, 49)] + test1txs = [create_transaction(self.nodes[0], coinbase_txid[0], self.ms_address, 49)] txid1 = self.nodes[0].sendrawtransaction(bytes_to_hex_str(test1txs[0].serialize_with_witness()), True) - test1txs.append(self.create_transaction(self.nodes[0], txid1, self.ms_address, 48)) + test1txs.append(create_transaction(self.nodes[0], txid1, self.ms_address, 48)) txid2 = self.nodes[0].sendrawtransaction(bytes_to_hex_str(test1txs[1].serialize_with_witness()), True) - test1txs.append(self.create_transaction(self.nodes[0], coinbase_txid[1], self.wit_ms_address, 49)) + test1txs.append(create_transaction(self.nodes[0], coinbase_txid[1], self.wit_ms_address, 49)) txid3 = self.nodes[0].sendrawtransaction(bytes_to_hex_str(test1txs[2].serialize_with_witness()), True) self.block_submit(self.nodes[0], test1txs, False, True) self.log.info("Test 2: Non-NULLDUMMY base multisig transaction should not be accepted to mempool before activation") - test2tx = self.create_transaction(self.nodes[0], txid2, self.ms_address, 47) + test2tx = create_transaction(self.nodes[0], txid2, self.ms_address, 47) trueDummy(test2tx) assert_raises_rpc_error(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, bytes_to_hex_str(test2tx.serialize_with_witness()), True) @@ -78,14 +77,14 @@ class NULLDUMMYTest(BitcoinTestFramework): self.block_submit(self.nodes[0], [test2tx], False, True) self.log.info("Test 4: Non-NULLDUMMY base multisig transaction is invalid after activation") - test4tx = self.create_transaction(self.nodes[0], test2tx.hash, self.address, 46) + test4tx = create_transaction(self.nodes[0], test2tx.hash, self.address, 46) test6txs=[CTransaction(test4tx)] trueDummy(test4tx) assert_raises_rpc_error(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, bytes_to_hex_str(test4tx.serialize_with_witness()), True) self.block_submit(self.nodes[0], [test4tx]) self.log.info("Test 5: Non-NULLDUMMY P2WSH multisig transaction invalid after activation") - test5tx = self.create_transaction(self.nodes[0], txid3, self.wit_address, 48) + test5tx = create_transaction(self.nodes[0], txid3, self.wit_address, 48) test6txs.append(CTransaction(test5tx)) test5tx.wit.vtxinwit[0].scriptWitness.stack[0] = b'\x01' assert_raises_rpc_error(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, bytes_to_hex_str(test5tx.serialize_with_witness()), True) @@ -97,17 +96,6 @@ class NULLDUMMYTest(BitcoinTestFramework): self.block_submit(self.nodes[0], test6txs, True, True) - def create_transaction(self, node, txid, to_address, amount): - inputs = [{ "txid" : txid, "vout" : 0}] - outputs = { to_address : amount } - rawtx = node.createrawtransaction(inputs, outputs) - signresult = node.signrawtransactionwithwallet(rawtx) - tx = CTransaction() - f = BytesIO(hex_str_to_bytes(signresult['hex'])) - tx.deserialize(f) - return tx - - def block_submit(self, node, txs, witness = False, accept = False): block = create_block(self.tip, create_coinbase(self.lastblockheight + 1), self.lastblocktime + 1) block.nVersion = 4 diff --git a/test/functional/p2p_invalid_block.py b/test/functional/p2p_invalid_block.py index 7c02abffec..b455791657 100755 --- a/test/functional/p2p_invalid_block.py +++ b/test/functional/p2p_invalid_block.py @@ -12,7 +12,7 @@ re-requested. """ import copy -from test_framework.blocktools import create_block, create_coinbase, create_transaction +from test_framework.blocktools import create_block, create_coinbase, create_tx_with_script from test_framework.messages import COIN from test_framework.mininode import P2PDataStore from test_framework.test_framework import BitcoinTestFramework @@ -64,8 +64,8 @@ class InvalidBlockRequestTest(BitcoinTestFramework): block_time += 1 # b'0x51' is OP_TRUE - tx1 = create_transaction(block1.vtx[0], 0, b'\x51', 50 * COIN) - tx2 = create_transaction(tx1, 0, b'\x51', 50 * COIN) + tx1 = create_tx_with_script(block1.vtx[0], 0, script_sig=b'\x51', amount=50 * COIN) + tx2 = create_tx_with_script(tx1, 0, script_sig=b'\x51', amount=50 * COIN) block2.vtx.extend([tx1, tx2]) block2.hashMerkleRoot = block2.calc_merkle_root() diff --git a/test/functional/p2p_invalid_tx.py b/test/functional/p2p_invalid_tx.py index 16c4b1b407..ab647526ee 100755 --- a/test/functional/p2p_invalid_tx.py +++ b/test/functional/p2p_invalid_tx.py @@ -5,7 +5,7 @@ """Test node responses to invalid transactions. In this test we connect to one node over p2p, and test tx requests.""" -from test_framework.blocktools import create_block, create_coinbase, create_transaction +from test_framework.blocktools import create_block, create_coinbase, create_tx_with_script from test_framework.messages import ( COIN, COutPoint, @@ -68,7 +68,7 @@ class InvalidTxRequestTest(BitcoinTestFramework): # Transaction will be rejected with code 16 (REJECT_INVALID) # and we get disconnected immediately self.log.info('Test a transaction that is rejected') - tx1 = create_transaction(block1.vtx[0], 0, b'\x64' * 35, 50 * COIN - 12000) + tx1 = create_tx_with_script(block1.vtx[0], 0, script_sig=b'\x64' * 35, amount=50 * COIN - 12000) node.p2p.send_txs_and_test([tx1], node, success=False, expect_disconnect=True) # Make two p2p connections to provide the node with orphans diff --git a/test/functional/p2p_unrequested_blocks.py b/test/functional/p2p_unrequested_blocks.py index 0c5d8f3a3f..b15e2774c4 100755 --- a/test/functional/p2p_unrequested_blocks.py +++ b/test/functional/p2p_unrequested_blocks.py @@ -55,7 +55,7 @@ from test_framework.mininode import * from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * import time -from test_framework.blocktools import create_block, create_coinbase, create_transaction +from test_framework.blocktools import create_block, create_coinbase, create_tx_with_script class AcceptBlockTest(BitcoinTestFramework): @@ -244,7 +244,7 @@ class AcceptBlockTest(BitcoinTestFramework): block_290f.solve() block_291 = create_block(block_290f.sha256, create_coinbase(291), block_290f.nTime+1) # block_291 spends a coinbase below maturity! - block_291.vtx.append(create_transaction(block_290f.vtx[0], 0, b"42", 1)) + block_291.vtx.append(create_tx_with_script(block_290f.vtx[0], 0, script_sig=b"42", amount=1)) block_291.hashMerkleRoot = block_291.calc_merkle_root() block_291.solve() block_292 = create_block(block_291.sha256, create_coinbase(292), block_291.nTime+1) diff --git a/test/functional/test_framework/blocktools.py b/test/functional/test_framework/blocktools.py index c2d20d27b5..56f70d9833 100644 --- a/test/functional/test_framework/blocktools.py +++ b/test/functional/test_framework/blocktools.py @@ -39,6 +39,7 @@ from .script import ( hash160, ) from .util import assert_equal +from io import BytesIO # From BIP141 WITNESS_COMMITMENT_HEADER = b"\xaa\x21\xa9\xed" @@ -117,17 +118,30 @@ def create_coinbase(height, pubkey=None): coinbase.calc_sha256() return coinbase -def create_transaction(prevtx, n, sig, value, script_pub_key=CScript()): - """Create a transaction. +def create_tx_with_script(prevtx, n, script_sig=b"", amount=1, script_pub_key=CScript()): + """Return one-input, one-output transaction object + spending the prevtx's n-th output with the given amount. - If the script_pub_key is not specified, make it anyone-can-spend.""" + Can optionally pass scriptPubKey and scriptSig, default is anyone-can-spend ouput. + """ tx = CTransaction() assert(n < len(prevtx.vout)) - tx.vin.append(CTxIn(COutPoint(prevtx.sha256, n), sig, 0xffffffff)) - tx.vout.append(CTxOut(value, script_pub_key)) + tx.vin.append(CTxIn(COutPoint(prevtx.sha256, n), script_sig, 0xffffffff)) + tx.vout.append(CTxOut(amount, script_pub_key)) tx.calc_sha256() return tx +def create_transaction(node, txid, to_address, amount): + """ Return signed transaction spending the first output of the + input txid. Note that the node must be able to sign for the + output that is being spent, and the node must not be running + multiple wallets. + """ + raw_tx = create_raw_transaction(node, txid, to_address, amount) + tx = CTransaction() + tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx))) + return tx + def create_raw_transaction(node, txid, to_address, amount): """ Return raw signed transaction spending the first output of the input txid. Note that the node must be able to sign for the -- cgit v1.2.3