diff --git a/test/functional/abc-mempool-accept-txn.py b/test/functional/abc-mempool-accept-txn.py --- a/test/functional/abc-mempool-accept-txn.py +++ b/test/functional/abc-mempool-accept-txn.py @@ -13,7 +13,7 @@ from test_framework.blocktools import ( create_block, create_coinbase, - create_transaction, + create_tx_with_script, ) from test_framework.cdefs import MAX_STANDARD_TX_SIGOPS from test_framework.key import CECKey @@ -80,7 +80,7 @@ # 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])): - tx = create_transaction(spend_tx, n, b"", value, script) + tx = create_tx_with_script(spend_tx, n, b"", value, script) return tx # sign a transaction, using the key we know about @@ -123,7 +123,7 @@ coinbase.rehash() block = create_block(base_block_hash, coinbase, block_time) # spend 1 satoshi - tx = create_transaction(spend.tx, spend.n, b"", 1, script) + tx = create_tx_with_script(spend.tx, spend.n, b"", 1, script) 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/abc-mempool-coherence-on-activations.py b/test/functional/abc-mempool-coherence-on-activations.py --- a/test/functional/abc-mempool-coherence-on-activations.py +++ b/test/functional/abc-mempool-coherence-on-activations.py @@ -22,7 +22,7 @@ from test_framework.blocktools import ( create_block, create_coinbase, - create_transaction, + create_tx_with_script, make_conform_to_ctor, ) from test_framework.key import CECKey @@ -78,7 +78,7 @@ # Fund transaction script = CScript([public_key, OP_CHECKSIG]) - txfund = create_transaction( + txfund = create_tx_with_script( spend.tx, spend.n, b'', 50 * COIN, script) txfund.rehash() @@ -203,7 +203,7 @@ # scriptPub=OP_TRUE coin into another. Returns the transaction and its # spendable output for further chaining. def create_always_valid_chained_tx(spend): - tx = create_transaction( + tx = create_tx_with_script( spend.tx, spend.n, b'', spend.tx.vout[0].nValue - 1000, CScript([OP_TRUE])) tx.rehash() return tx, PreviousSpendableOutput(tx, 0) diff --git a/test/functional/abc-minimaldata.py b/test/functional/abc-minimaldata.py --- a/test/functional/abc-minimaldata.py +++ b/test/functional/abc-minimaldata.py @@ -15,7 +15,7 @@ from test_framework.blocktools import ( create_block, create_coinbase, - create_transaction, + create_tx_with_script, make_conform_to_ctor, ) from test_framework.messages import ( @@ -140,7 +140,7 @@ value = spendfrom.vout[0].nValue # Fund transaction - txfund = create_transaction(spendfrom, 0, b'', value, script) + txfund = create_tx_with_script(spendfrom, 0, b'', value, script) txfund.rehash() fundings.append(txfund) diff --git a/test/functional/abc-replay-protection.py b/test/functional/abc-replay-protection.py --- a/test/functional/abc-replay-protection.py +++ b/test/functional/abc-replay-protection.py @@ -14,7 +14,7 @@ from test_framework.blocktools import ( create_block, create_coinbase, - create_transaction, + create_tx_with_script, make_conform_to_ctor, ) from test_framework.key import CECKey @@ -152,7 +152,7 @@ def create_fund_and_spend_tx(spend, forkvalue=0): # Fund transaction script = CScript([public_key, OP_CHECKSIG]) - txfund = create_transaction( + txfund = create_tx_with_script( spend.tx, spend.n, b'', 50 * COIN - 1000, script) txfund.rehash() diff --git a/test/functional/abc-schnorr.py b/test/functional/abc-schnorr.py --- a/test/functional/abc-schnorr.py +++ b/test/functional/abc-schnorr.py @@ -13,7 +13,7 @@ from test_framework.blocktools import ( create_block, create_coinbase, - create_transaction, + create_tx_with_script, make_conform_to_ctor, ) from test_framework.key import CECKey @@ -163,7 +163,7 @@ value = spendfrom.vout[0].nValue # Fund transaction - txfund = create_transaction(spendfrom, 0, b'', value, script) + txfund = create_tx_with_script(spendfrom, 0, b'', value, script) txfund.rehash() fundings.append(txfund) diff --git a/test/functional/abc-schnorrmultisig.py b/test/functional/abc-schnorrmultisig.py --- a/test/functional/abc-schnorrmultisig.py +++ b/test/functional/abc-schnorrmultisig.py @@ -16,7 +16,7 @@ from test_framework.blocktools import ( create_block, create_coinbase, - create_transaction, + create_tx_with_script, make_conform_to_ctor, ) from test_framework.key import CECKey @@ -166,7 +166,7 @@ value = spendfrom.vout[0].nValue # Fund transaction - txfund = create_transaction(spendfrom, 0, b'', value, script) + txfund = create_tx_with_script(spendfrom, 0, b'', value, script) txfund.rehash() fundings.append(txfund) diff --git a/test/functional/feature_block.py b/test/functional/feature_block.py --- a/test/functional/feature_block.py +++ b/test/functional/feature_block.py @@ -11,7 +11,7 @@ from test_framework.blocktools import ( create_block, create_coinbase, - create_transaction, + create_tx_with_script, get_legacy_sigopcount_block, make_conform_to_ctor, ) @@ -1310,7 +1310,7 @@ # 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])): - 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 @@ -1350,7 +1350,7 @@ coinbase.rehash() block = create_block(base_block_hash, coinbase, block_time) # spend 1 satoshi - tx = create_transaction(spend.tx, spend.n, b"", 1, script) + tx = create_tx_with_script(spend.tx, spend.n, b"", 1, script) 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 --- a/test/functional/feature_cltv.py +++ b/test/functional/feature_cltv.py @@ -8,7 +8,7 @@ 1351. """ -from test_framework.blocktools import create_block, create_coinbase, make_conform_to_ctor +from test_framework.blocktools import create_block, create_coinbase, create_transaction, make_conform_to_ctor from test_framework.messages import ( CTransaction, FromHex, @@ -81,16 +81,6 @@ return fundtx, spendtx -def spend_from_coinbase(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 = FromHex(CTransaction(), signresult['hex']) - return tx - - class BIP65Test(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 @@ -101,14 +91,15 @@ self.nodes[0].add_p2p_connection(P2PInterface()) self.log.info("Mining {} blocks".format(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") - fundtx = spend_from_coinbase(self.nodes[0], self.coinbase_blocks[0], - self.nodeaddress, 49.99) + fundtx = create_transaction(self.nodes[0], self.coinbase_txids[0], + self.nodeaddress, 49.99) fundtx, spendtx = cltv_lock_to_height( self.nodes[0], fundtx, self.nodeaddress, 49.98) @@ -144,8 +135,8 @@ "Test that invalid-according-to-cltv transactions cannot appear in a block") block.nVersion = 4 - fundtx = spend_from_coinbase(self.nodes[0], self.coinbase_blocks[1], - self.nodeaddress, 49.99) + fundtx = create_transaction(self.nodes[0], self.coinbase_txids[1], + self.nodeaddress, 49.99) fundtx, spendtx = cltv_lock_to_height( self.nodes[0], fundtx, self.nodeaddress, 49.98) @@ -193,8 +184,8 @@ self.log.info( "Test that a version 4 block with a valid-according-to-CLTV transaction is accepted") - fundtx = spend_from_coinbase(self.nodes[0], self.coinbase_blocks[2], - self.nodeaddress, 49.99) + fundtx = create_transaction(self.nodes[0], self.coinbase_txids[2], + self.nodeaddress, 49.99) fundtx, spendtx = cltv_lock_to_height( self.nodes[0], fundtx, self.nodeaddress, 49.98, CLTV_HEIGHT) diff --git a/test/functional/feature_dersig.py b/test/functional/feature_dersig.py --- a/test/functional/feature_dersig.py +++ b/test/functional/feature_dersig.py @@ -7,8 +7,8 @@ Test that the DERSIG soft-fork activates at (regtest) height 1251. """ -from test_framework.blocktools import create_block, create_coinbase -from test_framework.messages import CTransaction, FromHex, msg_block, ToHex +from test_framework.blocktools import create_block, create_coinbase, create_transaction +from test_framework.messages import msg_block, ToHex from test_framework.mininode import ( mininode_lock, P2PInterface, @@ -43,15 +43,6 @@ 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) - return FromHex(CTransaction(), signresult['hex']) - - class BIP66Test(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 @@ -62,7 +53,8 @@ self.nodes[0].add_p2p_connection(P2PInterface()) self.log.info("Mining {} blocks".format(DERSIG_HEIGHT - 1)) - self.coinbase_blocks = self.nodes[0].generate(DERSIG_HEIGHT - 1) + self.coinbase_txids = [self.nodes[0].getblock( + b)['tx'][0] for b in self.nodes[0].generate(DERSIG_HEIGHT - 1)] self.nodeaddress = self.nodes[0].getnewaddress() self.log.info("Test that blocks must now be at least version 3") @@ -83,7 +75,7 @@ "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() @@ -120,7 +112,7 @@ 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/p2p_invalid_block.py b/test/functional/p2p_invalid_block.py --- a/test/functional/p2p_invalid_block.py +++ b/test/functional/p2p_invalid_block.py @@ -16,7 +16,7 @@ from test_framework.blocktools import ( create_block, create_coinbase, - create_transaction, + create_tx_with_script, ) from test_framework.messages import COIN from test_framework.mininode import P2PDataStore @@ -69,8 +69,10 @@ block_time += 1 # b'0x51' is OP_TRUE - tx1 = create_transaction(block1.vtx[0], 0, b'', 50 * COIN) - tx2 = create_transaction(tx1, 0, b'\x51', 50 * COIN) + tx1 = create_tx_with_script( + block1.vtx[0], 0, script_sig=b'', amount=50 * COIN) + tx2 = create_tx_with_script( + tx1, 0, script_sig=b'\x51', amount=50 * COIN) block2.vtx.extend([tx1, tx2]) block2.vtx = [block2.vtx[0]] + \ diff --git a/test/functional/p2p_invalid_tx.py b/test/functional/p2p_invalid_tx.py --- a/test/functional/p2p_invalid_tx.py +++ b/test/functional/p2p_invalid_tx.py @@ -10,7 +10,7 @@ from test_framework.blocktools import ( create_block, create_coinbase, - create_transaction, + create_tx_with_script, ) from test_framework.txtools import pad_tx from test_framework.messages import ( @@ -75,8 +75,8 @@ # 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) diff --git a/test/functional/p2p_unrequested_blocks.py b/test/functional/p2p_unrequested_blocks.py --- a/test/functional/p2p_unrequested_blocks.py +++ b/test/functional/p2p_unrequested_blocks.py @@ -56,7 +56,7 @@ from test_framework.blocktools import ( create_block, create_coinbase, - create_transaction, + create_tx_with_script, ) from test_framework.messages import ( CBlockHeader, @@ -279,8 +279,8 @@ 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( diff --git a/test/functional/test_framework/blocktools.py b/test/functional/test_framework/blocktools.py --- a/test/functional/test_framework/blocktools.py +++ b/test/functional/test_framework/blocktools.py @@ -92,20 +92,33 @@ coinbase.calc_sha256() return coinbase -# Create a transaction. -# If the scriptPubKey is not specified, make it anyone-can-spend. +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. -def create_transaction(prevtx, n, sig, value, scriptPubKey=CScript()): + Can optionally pass scriptPubKey and scriptSig, default is anyone-can-spend output. + """ tx = CTransaction() - assert n < len(prevtx.vout) - tx.vin.append(CTxIn(COutPoint(prevtx.sha256, n), sig, 0xffffffff)) - tx.vout.append(CTxOut(value, scriptPubKey)) + assert(n < len(prevtx.vout)) + tx.vin.append(CTxIn(COutPoint(prevtx.sha256, n), script_sig, 0xffffffff)) + tx.vout.append(CTxOut(amount, script_pub_key)) pad_tx(tx) 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 = FromHex(CTransaction(), 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