From 57b6fe732725356f035ddafb98f40b02c522421e Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Thu, 24 Jun 2021 12:47:04 +0200 Subject: [PATCH] Merge bitcoin/bitcoin#22257: test: refactor: various (de)serialization helpers cleanups/improvements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bdb8b9a347e68f80a2e8d44ce5590a2e8214b6bb test: doc: improve doc for `from_hex` helper (mention `to_hex` alternative) (Sebastian Falbesoner) 191405420815d49ab50184513717a303fc2744d6 scripted-diff: test: rename `FromHex` to `from_hex` (Sebastian Falbesoner) a79396fe5f8f81c78cf84117a87074c6ff6c9d95 test: remove `ToHex` helper, use .serialize().hex() instead (Sebastian Falbesoner) 2ce7b47958c4a10ba20dc86c011d71cda4b070a5 test: introduce `tx_from_hex` helper for tx deserialization (Sebastian Falbesoner) Pull request description: There are still many functional tests that perform conversions from a hex-string to a message object (deserialization) manually. This PR identifies all those instances and replaces them with a newly introduced helper `tx_from_hex`. Instances were found via * `git grep "deserialize.*BytesIO"` and some of them manually, when it were not one-liners. Further, the helper `ToHex` was removed and simply replaced by `.serialize().hex()`, since now both variants are in use (sometimes even within the same test) and using the helper doesn't really have an advantage in readability. (see discussion https://github.com/bitcoin/bitcoin/pull/22257#discussion_r652404782) ACKs for top commit: MarcoFalke: review re-ACK bdb8b9a347e68f80a2e8d44ce5590a2e8214b6bb 😁 Tree-SHA512: e25d7dc85918de1d6755a5cea65471b07a743204c20ad1c2f71ff07ef48cc1b9ad3fe5f515c1efaba2b2e3d89384e7980380c5d81895f9826e2046808cd3266e --- test/functional/feature_asset_locks.py | 6 +- test/functional/feature_bip68_sequence.py | 54 +++++++++------- test/functional/feature_cltv.py | 4 +- test/functional/feature_coinstatsindex.py | 5 +- test/functional/feature_csv_activation.py | 6 +- test/functional/feature_dbcrash.py | 3 +- test/functional/feature_dip0020_activation.py | 6 +- .../feature_dip3_deterministicmns.py | 6 +- test/functional/feature_dip3_v19.py | 4 +- .../feature_dip4_coinbasemerkleroots.py | 4 +- test/functional/feature_fee_estimation.py | 27 ++++++-- test/functional/feature_llmq_evo.py | 4 +- .../feature_llmq_is_cl_conflicts.py | 12 ++-- test/functional/feature_llmq_rotation.py | 4 +- test/functional/feature_pruning.py | 10 ++- test/functional/feature_utxo_set_hash.py | 6 +- test/functional/interface_zmq.py | 5 +- test/functional/interface_zmq_dash.py | 4 +- test/functional/mempool_accept.py | 59 ++++++++--------- test/functional/p2p_blocksonly.py | 6 +- test/functional/p2p_compactblocks.py | 64 ++++++++++++++++--- test/functional/p2p_eviction.py | 13 +++- test/functional/p2p_permissions.py | 6 +- test/functional/p2p_tx_download.py | 5 +- test/functional/rpc_blockchain.py | 4 +- test/functional/rpc_decodescript.py | 13 ++-- test/functional/rpc_packages.py | 24 ++++--- test/functional/rpc_rawtransaction.py | 18 +++--- test/functional/rpc_txoutproof.py | 16 +++-- test/functional/rpc_verifyislock.py | 4 +- test/functional/test_framework/blocktools.py | 9 +-- test/functional/test_framework/messages.py | 16 +++-- .../test_framework/test_framework.py | 7 +- test/functional/test_framework/util.py | 6 +- test/functional/wallet_groups.py | 8 ++- test/functional/wallet_listtransactions.py | 5 +- .../wallet_resendwallettransactions.py | 8 ++- test/functional/wallet_txn_clone.py | 9 +-- 38 files changed, 283 insertions(+), 187 deletions(-) diff --git a/test/functional/feature_asset_locks.py b/test/functional/feature_asset_locks.py index d02fbc5ba3..45a80fc152 100755 --- a/test/functional/feature_asset_locks.py +++ b/test/functional/feature_asset_locks.py @@ -23,7 +23,7 @@ from test_framework.messages import ( CTransaction, CTxIn, CTxOut, - FromHex, + tx_from_hex, hash256, ser_string, ) @@ -84,7 +84,7 @@ class AssetLocksTest(DashTestFramework): lock_tx.vExtraPayload = lockTx_payload.serialize() lock_tx = node_wallet.signrawtransactionwithwallet(lock_tx.serialize().hex()) - return FromHex(CTransaction(), lock_tx["hex"]) + return tx_from_hex(lock_tx["hex"]) def create_assetunlock(self, index, withdrawal, pubkey=None, fee=tiny_amount): @@ -175,7 +175,7 @@ class AssetLocksTest(DashTestFramework): block = create_block(tip, cbb, block_time, version=4) # Add quorum commitments from block template for tx_obj in gbt["transactions"]: - tx = FromHex(CTransaction(), tx_obj["data"]) + tx = tx_from_hex(tx_obj["data"]) if tx.nType == 6: block.vtx.append(tx) for tx in txes: diff --git a/test/functional/feature_bip68_sequence.py b/test/functional/feature_bip68_sequence.py index e78b8a3f38..b6d28afee4 100755 --- a/test/functional/feature_bip68_sequence.py +++ b/test/functional/feature_bip68_sequence.py @@ -4,8 +4,18 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test BIP68 implementation.""" -from test_framework.blocktools import create_block, NORMAL_GBT_REQUEST_PARAMS -from test_framework.messages import COIN, COutPoint, CTransaction, CTxIn, CTxOut, FromHex, ToHex +from test_framework.blocktools import ( + NORMAL_GBT_REQUEST_PARAMS, + create_block, +) +from test_framework.messages import ( + COIN, + COutPoint, + CTransaction, + CTxIn, + CTxOut, + tx_from_hex, +) from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, @@ -87,7 +97,7 @@ class BIP68Test(BitcoinTestFramework): tx1.vin = [CTxIn(COutPoint(int(utxo["txid"], 16), utxo["vout"]), nSequence=sequence_value)] tx1.vout = [CTxOut(value, DUMMY_P2SH_SCRIPT)] - tx1_signed = self.nodes[0].signrawtransactionwithwallet(ToHex(tx1))["hex"] + tx1_signed = self.nodes[0].signrawtransactionwithwallet(tx1.serialize().hex())["hex"] tx1_id = self.nodes[0].sendrawtransaction(tx1_signed) tx1_id = int(tx1_id, 16) @@ -100,13 +110,13 @@ class BIP68Test(BitcoinTestFramework): tx2.vout = [CTxOut(int(value - self.relayfee * COIN), DUMMY_P2SH_SCRIPT)] tx2.rehash() - assert_raises_rpc_error(-26, NOT_FINAL_ERROR, self.nodes[0].sendrawtransaction, ToHex(tx2)) + assert_raises_rpc_error(-26, NOT_FINAL_ERROR, self.nodes[0].sendrawtransaction, tx2.serialize().hex()) # Setting the version back down to 1 should disable the sequence lock, # so this should be accepted. tx2.nVersion = 1 - self.nodes[0].sendrawtransaction(ToHex(tx2)) + self.nodes[0].sendrawtransaction(tx2.serialize().hex()) # Calculate the median time past of a prior block ("confirmations" before # the current tip). @@ -191,9 +201,9 @@ class BIP68Test(BitcoinTestFramework): tx.vin.append(CTxIn(COutPoint(int(utxos[j]["txid"], 16), utxos[j]["vout"]), nSequence=sequence_value)) value += utxos[j]["amount"]*COIN # Overestimate the size of the tx - signatures should be less than 120 bytes, and leave 50 for the output - tx_size = len(ToHex(tx))//2 + 120*num_inputs + 50 + tx_size = len(tx.serialize().hex())//2 + 120*num_inputs + 50 tx.vout.append(CTxOut(int(value-self.relayfee*tx_size*COIN/1000), DUMMY_P2SH_SCRIPT)) - rawtx = self.nodes[0].signrawtransactionwithwallet(ToHex(tx))["hex"] + rawtx = self.nodes[0].signrawtransactionwithwallet(tx.serialize().hex())["hex"] if (using_sequence_locks and not should_pass): # This transaction should be rejected @@ -213,7 +223,7 @@ class BIP68Test(BitcoinTestFramework): # Create a mempool tx. txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 2) - tx1 = FromHex(CTransaction(), self.nodes[0].getrawtransaction(txid)) + tx1 = tx_from_hex(self.nodes[0].getrawtransaction(txid)) tx1.rehash() # Anyone-can-spend mempool tx. @@ -222,8 +232,8 @@ class BIP68Test(BitcoinTestFramework): tx2.nVersion = 2 tx2.vin = [CTxIn(COutPoint(tx1.sha256, 0), nSequence=0)] tx2.vout = [CTxOut(int(tx1.vout[0].nValue - self.relayfee*COIN), DUMMY_P2SH_SCRIPT)] - tx2_raw = self.nodes[0].signrawtransactionwithwallet(ToHex(tx2))["hex"] - tx2 = FromHex(tx2, tx2_raw) + tx2_raw = self.nodes[0].signrawtransactionwithwallet(tx2.serialize().hex())["hex"] + tx2 = tx_from_hex(tx2_raw) tx2.rehash() self.nodes[0].sendrawtransaction(tx2_raw) @@ -244,10 +254,10 @@ class BIP68Test(BitcoinTestFramework): if (orig_tx.hash in node.getrawmempool()): # sendrawtransaction should fail if the tx is in the mempool - assert_raises_rpc_error(-26, NOT_FINAL_ERROR, node.sendrawtransaction, ToHex(tx)) + assert_raises_rpc_error(-26, NOT_FINAL_ERROR, node.sendrawtransaction, tx.serialize().hex()) else: # sendrawtransaction should succeed if the tx is not in the mempool - node.sendrawtransaction(ToHex(tx)) + node.sendrawtransaction(tx.serialize().hex()) return tx @@ -297,7 +307,7 @@ class BIP68Test(BitcoinTestFramework): utxos = self.nodes[0].listunspent() tx5.vin.append(CTxIn(COutPoint(int(utxos[0]["txid"], 16), utxos[0]["vout"]), nSequence=1)) tx5.vout[0].nValue += int(utxos[0]["amount"]*COIN) - raw_tx5 = self.nodes[0].signrawtransactionwithwallet(ToHex(tx5))["hex"] + raw_tx5 = self.nodes[0].signrawtransactionwithwallet(tx5.serialize().hex())["hex"] assert_raises_rpc_error(-26, NOT_FINAL_ERROR, self.nodes[0].sendrawtransaction, raw_tx5) @@ -323,7 +333,7 @@ class BIP68Test(BitcoinTestFramework): block.rehash() block.solve() tip = block.sha256 - assert_equal(None if i == 1 else 'inconclusive', self.nodes[0].submitblock(ToHex(block))) + assert_equal(None if i == 1 else 'inconclusive', self.nodes[0].submitblock(block.serialize().hex())) tmpl = self.nodes[0].getblocktemplate(NORMAL_GBT_REQUEST_PARAMS) tmpl['previousblockhash'] = '%x' % tip tmpl['transactions'] = [] @@ -346,7 +356,7 @@ class BIP68Test(BitcoinTestFramework): assert not softfork_active(self.nodes[0], 'csv') txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 2) - tx1 = FromHex(CTransaction(), self.nodes[0].getrawtransaction(txid)) + tx1 = tx_from_hex(self.nodes[0].getrawtransaction(txid)) tx1.rehash() # Make an anyone-can-spend transaction @@ -356,11 +366,11 @@ class BIP68Test(BitcoinTestFramework): tx2.vout = [CTxOut(int(tx1.vout[0].nValue - self.relayfee*COIN), DUMMY_P2SH_SCRIPT)] # sign tx2 - tx2_raw = self.nodes[0].signrawtransactionwithwallet(ToHex(tx2))["hex"] - tx2 = FromHex(tx2, tx2_raw) + tx2_raw = self.nodes[0].signrawtransactionwithwallet(tx2.serialize().hex())["hex"] + tx2 = tx_from_hex(tx2_raw) tx2.rehash() - self.nodes[0].sendrawtransaction(ToHex(tx2)) + self.nodes[0].sendrawtransaction(tx2.serialize().hex()) # Now make an invalid spend of tx2 according to BIP68 sequence_value = 100 # 100 block relative locktime @@ -371,7 +381,7 @@ class BIP68Test(BitcoinTestFramework): tx3.vout = [CTxOut(int(tx2.vout[0].nValue - self.relayfee * COIN), DUMMY_P2SH_SCRIPT)] tx3.rehash() - assert_raises_rpc_error(-26, NOT_FINAL_ERROR, self.nodes[0].sendrawtransaction, ToHex(tx3)) + assert_raises_rpc_error(-26, NOT_FINAL_ERROR, self.nodes[0].sendrawtransaction, tx3.serialize().hex()) # make a block that violates bip68; ensure that the tip updates block = create_block(tmpl=self.nodes[0].getblocktemplate(NORMAL_GBT_REQUEST_PARAMS)) @@ -380,7 +390,7 @@ class BIP68Test(BitcoinTestFramework): block.rehash() block.solve() - assert_equal(None, self.nodes[0].submitblock(ToHex(block))) + assert_equal(None, self.nodes[0].submitblock(block.serialize().hex())) assert_equal(self.nodes[0].getbestblockhash(), block.hash) def activateCSV(self): @@ -401,9 +411,9 @@ class BIP68Test(BitcoinTestFramework): outputs = { self.nodes[1].getnewaddress() : 1.0 } rawtx = self.nodes[1].createrawtransaction(inputs, outputs) rawtxfund = self.nodes[1].fundrawtransaction(rawtx)['hex'] - tx = FromHex(CTransaction(), rawtxfund) + tx = tx_from_hex(rawtxfund) tx.nVersion = 2 - tx_signed = self.nodes[1].signrawtransactionwithwallet(ToHex(tx))["hex"] + tx_signed = self.nodes[1].signrawtransactionwithwallet(tx.serialize().hex())["hex"] self.nodes[1].sendrawtransaction(tx_signed) if __name__ == '__main__': diff --git a/test/functional/feature_cltv.py b/test/functional/feature_cltv.py index 6b51cd7069..0b677b653d 100755 --- a/test/functional/feature_cltv.py +++ b/test/functional/feature_cltv.py @@ -9,7 +9,7 @@ Test that the CHECKLOCKTIMEVERIFY soft-fork activates at (regtest) block height """ from test_framework.blocktools import create_coinbase, create_block, create_transaction -from test_framework.messages import CTransaction, msg_block, ToHex +from test_framework.messages import CTransaction, msg_block from test_framework.p2p import P2PInterface from test_framework.script import CScript, OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP, CScriptNum from test_framework.test_framework import BitcoinTestFramework @@ -43,7 +43,7 @@ def cltv_validate(node, tx, height): tx.nLockTime = height # Need to re-sign, since nSequence and nLockTime changed - signed_result = node.signrawtransactionwithwallet(ToHex(tx)) + signed_result = node.signrawtransactionwithwallet(tx.serialize().hex()) new_tx = CTransaction() new_tx.deserialize(BytesIO(hex_str_to_bytes(signed_result['hex']))) diff --git a/test/functional/feature_coinstatsindex.py b/test/functional/feature_coinstatsindex.py index 4930468910..5f88f23557 100755 --- a/test/functional/feature_coinstatsindex.py +++ b/test/functional/feature_coinstatsindex.py @@ -23,7 +23,6 @@ from test_framework.messages import ( CTransaction, CTxIn, CTxOut, - ToHex, ) from test_framework.script import ( CScript, @@ -180,7 +179,7 @@ class CoinStatsIndexTest(BitcoinTestFramework): tx2 = CTransaction() tx2.vin.append(CTxIn(COutPoint(int(tx1_txid, 16), n), b'')) tx2.vout.append(CTxOut(int(20.99 * COIN), CScript([OP_RETURN] + [OP_FALSE]*30))) - tx2_hex = self.nodes[0].signrawtransactionwithwallet(ToHex(tx2))['hex'] + tx2_hex = self.nodes[0].signrawtransactionwithwallet(tx2.serialize().hex())['hex'] self.nodes[0].sendrawtransaction(tx2_hex) # Include both txs in a block @@ -216,7 +215,7 @@ class CoinStatsIndexTest(BitcoinTestFramework): block_time = self.nodes[0].getblock(tip)['time'] + 1 block = create_block(int(tip, 16), cb, block_time) block.solve() - self.nodes[0].submitblock(ToHex(block)) + self.nodes[0].submitblock(block.serialize().hex()) self.sync_all() for hash_option in index_hash_options: diff --git a/test/functional/feature_csv_activation.py b/test/functional/feature_csv_activation.py index a0c4c9cf33..5fca60414c 100755 --- a/test/functional/feature_csv_activation.py +++ b/test/functional/feature_csv_activation.py @@ -42,7 +42,7 @@ from itertools import product from io import BytesIO from test_framework.blocktools import create_coinbase, create_block, create_transaction, TIME_GENESIS_BLOCK -from test_framework.messages import ToHex, CTransaction +from test_framework.messages import CTransaction from test_framework.p2p import P2PDataStore from test_framework.script import ( CScript, @@ -83,7 +83,7 @@ def all_rlt_txs(txs): return [tx['tx'] for tx in txs] def sign_transaction(node, unsignedtx): - rawtx = ToHex(unsignedtx) + rawtx = unsignedtx.serialize().hex() signresult = node.signrawtransactionwithwallet(rawtx) tx = CTransaction() f = BytesIO(hex_str_to_bytes(signresult['hex'])) @@ -105,7 +105,7 @@ def create_bip112emptystack(node, input, txversion, address): return signtx def send_generic_input_tx(node, coinbases, address): - return node.sendrawtransaction(ToHex(sign_transaction(node, create_transaction(node, node.getblock(coinbases.pop())['tx'][0], address, amount=Decimal("499.99"))))) + return node.sendrawtransaction(sign_transaction(node, create_transaction(node, node.getblock(coinbases.pop())['tx'][0], address, amount=Decimal("499.99"))).serialize().hex()) def create_bip68txs(node, bip68inputs, txversion, address, locktime_delta=0): """Returns a list of bip68 transactions with different bits set.""" diff --git a/test/functional/feature_dbcrash.py b/test/functional/feature_dbcrash.py index 59a72c063f..e41e16527f 100755 --- a/test/functional/feature_dbcrash.py +++ b/test/functional/feature_dbcrash.py @@ -36,7 +36,6 @@ from test_framework.messages import ( CTransaction, CTxIn, CTxOut, - ToHex, ) from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( @@ -208,7 +207,7 @@ class ChainstateWriteCrashTest(BitcoinTestFramework): tx.vout.append(CTxOut(output_amount, hex_str_to_bytes(utxo['scriptPubKey']))) # Sign and send the transaction to get into the mempool - tx_signed_hex = node.signrawtransactionwithwallet(ToHex(tx))['hex'] + tx_signed_hex = node.signrawtransactionwithwallet(tx.serialize().hex())['hex'] node.sendrawtransaction(tx_signed_hex) num_transactions += 1 diff --git a/test/functional/feature_dip0020_activation.py b/test/functional/feature_dip0020_activation.py index 2eaeff7b93..020616b7f3 100755 --- a/test/functional/feature_dip0020_activation.py +++ b/test/functional/feature_dip0020_activation.py @@ -2,7 +2,7 @@ # Copyright (c) 2015-2023 The Dash Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -from test_framework.messages import COIN, COutPoint, CTransaction, CTxIn, CTxOut, ToHex +from test_framework.messages import COIN, COutPoint, CTransaction, CTxIn, CTxOut from test_framework.script import CScript, OP_CAT, OP_DROP, OP_TRUE from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_raises_rpc_error, softfork_active, satoshi_round @@ -38,7 +38,7 @@ class DIP0020ActivationTest(BitcoinTestFramework): tx = CTransaction() tx.vin.append(CTxIn(COutPoint(int(utxo["txid"], 16), utxo["vout"]))) tx.vout.append(CTxOut(value, CScript([b'1', b'2', OP_CAT]))) - tx_signed_hex = self.node.signrawtransactionwithwallet(ToHex(tx))["hex"] + tx_signed_hex = self.node.signrawtransactionwithwallet(tx.serialize().hex())["hex"] txid = self.node.sendrawtransaction(tx_signed_hex) # This tx should be completely valid, should be included in mempool and mined in the next block @@ -52,7 +52,7 @@ class DIP0020ActivationTest(BitcoinTestFramework): tx0.vin.append(CTxIn(COutPoint(int(txid, 16), 0))) tx0.vout.append(CTxOut(value, CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE]))) tx0.rehash() - tx0_hex = ToHex(tx0) + tx0_hex = tx0.serialize().hex() # This tx isn't valid yet assert not softfork_active(self.nodes[0], 'dip0020') diff --git a/test/functional/feature_dip3_deterministicmns.py b/test/functional/feature_dip3_deterministicmns.py index 8b282fb55c..8deeb2a334 100755 --- a/test/functional/feature_dip3_deterministicmns.py +++ b/test/functional/feature_dip3_deterministicmns.py @@ -10,7 +10,7 @@ from decimal import Decimal from test_framework.blocktools import create_block_with_mnpayments -from test_framework.messages import CTransaction, FromHex, ToHex +from test_framework.messages import tx_from_hex from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_equal, force_finish_mnsync, p2p_port @@ -367,7 +367,7 @@ class DIP3Test(BitcoinTestFramework): def mine_block(self, mns, node, vtx=None, mn_payee=None, mn_amount=None, expected_error=None): block = create_block_with_mnpayments(mns, node, vtx, mn_payee, mn_amount) - result = node.submitblock(ToHex(block)) + result = node.submitblock(block.serialize().hex()) if expected_error is not None and result != expected_error: raise AssertionError('mining the block should have failed with error %s, but submitblock returned %s' % (expected_error, result)) elif expected_error is None and result is not None: @@ -382,7 +382,7 @@ class DIP3Test(BitcoinTestFramework): rawtx = node.createrawtransaction(txins, {target_address: amount}) rawtx = node.signrawtransactionwithwallet(rawtx)['hex'] - tx = FromHex(CTransaction(), rawtx) + tx = tx_from_hex(rawtx) self.mine_block(mns, node, [tx]) diff --git a/test/functional/feature_dip3_v19.py b/test/functional/feature_dip3_v19.py index 22e0524342..3ec14437d0 100755 --- a/test/functional/feature_dip3_v19.py +++ b/test/functional/feature_dip3_v19.py @@ -12,7 +12,7 @@ Checks DIP3 for v19 from io import BytesIO from test_framework.p2p import P2PInterface -from test_framework.messages import CBlock, CBlockHeader, CCbTx, CMerkleBlock, FromHex, hash256, msg_getmnlistd, \ +from test_framework.messages import CBlock, CBlockHeader, CCbTx, CMerkleBlock, from_hex, hash256, msg_getmnlistd, \ QuorumId, ser_uint256 from test_framework.test_framework import DashTestFramework from test_framework.util import ( @@ -176,7 +176,7 @@ class DIP3V19Test(DashTestFramework): def test_getmnlistdiff_base(self, base_block_hash, block_hash): hexstr = self.nodes[0].getblockheader(block_hash, False) - header = FromHex(CBlockHeader(), hexstr) + header = from_hex(CBlockHeader(), hexstr) d = self.test_node.getmnlistdiff(int(base_block_hash, 16), int(block_hash, 16)) assert_equal(d.baseBlockHash, int(base_block_hash, 16)) diff --git a/test/functional/feature_dip4_coinbasemerkleroots.py b/test/functional/feature_dip4_coinbasemerkleroots.py index 939691383e..40bcac3d0a 100755 --- a/test/functional/feature_dip4_coinbasemerkleroots.py +++ b/test/functional/feature_dip4_coinbasemerkleroots.py @@ -12,7 +12,7 @@ Checks DIP4 merkle roots in coinbases from io import BytesIO -from test_framework.messages import CBlock, CBlockHeader, CCbTx, CMerkleBlock, FromHex, hash256, msg_getmnlistd, QuorumId, ser_uint256 +from test_framework.messages import CBlock, CBlockHeader, CCbTx, CMerkleBlock, from_hex, hash256, msg_getmnlistd, QuorumId, ser_uint256 from test_framework.p2p import P2PInterface from test_framework.test_framework import DashTestFramework from test_framework.util import assert_equal @@ -216,7 +216,7 @@ class LLMQCoinbaseCommitmentsTest(DashTestFramework): def test_getmnlistdiff_base(self, baseBlockHash, blockHash): hexstr = self.nodes[0].getblockheader(blockHash, False) - header = FromHex(CBlockHeader(), hexstr) + header = from_hex(CBlockHeader(), hexstr) d = self.test_node.getmnlistdiff(int(baseBlockHash, 16), int(blockHash, 16)) assert_equal(d.baseBlockHash, int(baseBlockHash, 16)) diff --git a/test/functional/feature_fee_estimation.py b/test/functional/feature_fee_estimation.py index 9edb6e604e..6962a08cbf 100755 --- a/test/functional/feature_fee_estimation.py +++ b/test/functional/feature_fee_estimation.py @@ -6,8 +6,23 @@ from decimal import Decimal import random -from test_framework.messages import CTransaction, CTxIn, CTxOut, COutPoint, ToHex, COIN -from test_framework.script import CScript, OP_1, OP_DROP, OP_2, OP_HASH160, OP_EQUAL, hash160, OP_TRUE +from test_framework.messages import ( + COIN, + COutPoint, + CTransaction, + CTxIn, + CTxOut, +) +from test_framework.script import ( + CScript, + OP_1, + OP_2, + OP_DROP, + OP_EQUAL, + OP_HASH160, + OP_TRUE, + hash160, +) from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, @@ -64,11 +79,11 @@ def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee # the ScriptSig that will satisfy the ScriptPubKey. for inp in tx.vin: inp.scriptSig = SCRIPT_SIG[inp.prevout.n] - txid = from_node.sendrawtransaction(hexstring=ToHex(tx), maxfeerate=0) + txid = from_node.sendrawtransaction(hexstring=tx.serialize().hex(), maxfeerate=0) unconflist.append({"txid": txid, "vout": 0, "amount": total_in - amount - fee}) unconflist.append({"txid": txid, "vout": 1, "amount": amount}) - return (ToHex(tx), fee) + return (tx.serialize().hex(), fee) def split_inputs(from_node, txins, txouts, initial_split=False): @@ -91,10 +106,10 @@ def split_inputs(from_node, txins, txouts, initial_split=False): # If this is the initial split we actually need to sign the transaction # Otherwise we just need to insert the proper ScriptSig if (initial_split): - completetx = from_node.signrawtransactionwithwallet(ToHex(tx))["hex"] + completetx = from_node.signrawtransactionwithwallet(tx.serialize().hex())["hex"] else: tx.vin[0].scriptSig = SCRIPT_SIG[prevtxout["vout"]] - completetx = ToHex(tx) + completetx = tx.serialize().hex() txid = from_node.sendrawtransaction(hexstring=completetx, maxfeerate=0) txouts.append({"txid": txid, "vout": 0, "amount": half_change}) txouts.append({"txid": txid, "vout": 1, "amount": rem_change}) diff --git a/test/functional/feature_llmq_evo.py b/test/functional/feature_llmq_evo.py index 36c564ecbb..6543b9fa6a 100755 --- a/test/functional/feature_llmq_evo.py +++ b/test/functional/feature_llmq_evo.py @@ -13,7 +13,7 @@ from _decimal import Decimal from io import BytesIO from test_framework.p2p import P2PInterface -from test_framework.messages import CBlock, CBlockHeader, CCbTx, CMerkleBlock, FromHex, hash256, msg_getmnlistd, \ +from test_framework.messages import CBlock, CBlockHeader, CCbTx, CMerkleBlock, from_hex, hash256, msg_getmnlistd, \ QuorumId, ser_uint256 from test_framework.test_framework import DashTestFramework from test_framework.util import ( @@ -276,7 +276,7 @@ class LLMQEvoNodesTest(DashTestFramework): def test_getmnlistdiff_base(self, baseBlockHash, blockHash): hexstr = self.nodes[0].getblockheader(blockHash, False) - header = FromHex(CBlockHeader(), hexstr) + header = from_hex(CBlockHeader(), hexstr) d = self.test_node.getmnlistdiff(int(baseBlockHash, 16), int(blockHash, 16)) assert_equal(d.baseBlockHash, int(baseBlockHash, 16)) diff --git a/test/functional/feature_llmq_is_cl_conflicts.py b/test/functional/feature_llmq_is_cl_conflicts.py index 04d410acdb..3af1b35041 100755 --- a/test/functional/feature_llmq_is_cl_conflicts.py +++ b/test/functional/feature_llmq_is_cl_conflicts.py @@ -13,7 +13,7 @@ Checks conflict handling between ChainLocks and InstantSend import struct from test_framework.blocktools import create_block_with_mnpayments -from test_framework.messages import CInv, CTransaction, FromHex, hash256, msg_clsig, msg_inv, ser_string, ToHex, uint256_from_str +from test_framework.messages import CInv, hash256, msg_clsig, msg_inv, ser_string, tx_from_hex, uint256_from_str from test_framework.p2p import P2PInterface from test_framework.test_framework import DashTestFramework from test_framework.util import assert_equal, assert_raises_rpc_error, hex_str_to_bytes @@ -88,8 +88,8 @@ class LLMQ_IS_CL_Conflicts(DashTestFramework): # create three raw TXs, they will conflict with each other rawtx1 = self.create_raw_tx(self.nodes[0], self.nodes[0], 1, 1, 100)['hex'] rawtx2 = self.create_raw_tx(self.nodes[0], self.nodes[0], 1, 1, 100)['hex'] - rawtx1_obj = FromHex(CTransaction(), rawtx1) - rawtx2_obj = FromHex(CTransaction(), rawtx2) + rawtx1_obj = tx_from_hex(rawtx1) + rawtx2_obj = tx_from_hex(rawtx2) rawtx1_txid = self.nodes[0].sendrawtransaction(rawtx1) rawtx2_txid = hash256(hex_str_to_bytes(rawtx2))[::-1].hex() @@ -114,7 +114,7 @@ class LLMQ_IS_CL_Conflicts(DashTestFramework): block = create_block_with_mnpayments(self.mninfo, self.nodes[0], [rawtx2_obj]) if test_block_conflict: # The block shouldn't be accepted/connected but it should be known to node 0 now - submit_result = self.nodes[0].submitblock(ToHex(block)) + submit_result = self.nodes[0].submitblock(block.serialize().hex()) assert submit_result == "conflict-tx-lock" cl = self.create_chainlock(self.nodes[0].getblockcount() + 1, block) @@ -146,7 +146,7 @@ class LLMQ_IS_CL_Conflicts(DashTestFramework): # At this point all nodes should be in sync and have the same "best chainlock" - submit_result = self.nodes[1].submitblock(ToHex(block)) + submit_result = self.nodes[1].submitblock(block.serialize().hex()) if test_block_conflict: # Node 1 should receive the block from node 0 and should not accept it again via submitblock assert submit_result == "duplicate" @@ -235,7 +235,7 @@ class LLMQ_IS_CL_Conflicts(DashTestFramework): # Create the block and the corresponding clsig but do not relay clsig yet cl_block = create_block_with_mnpayments(self.mninfo, self.nodes[0]) cl = self.create_chainlock(self.nodes[0].getblockcount() + 1, cl_block) - self.nodes[0].submitblock(ToHex(cl_block)) + self.nodes[0].submitblock(cl_block.serialize().hex()) self.sync_all() assert self.nodes[0].getbestblockhash() == cl_block.hash diff --git a/test/functional/feature_llmq_rotation.py b/test/functional/feature_llmq_rotation.py index 2950620f50..827c46738c 100755 --- a/test/functional/feature_llmq_rotation.py +++ b/test/functional/feature_llmq_rotation.py @@ -13,7 +13,7 @@ import struct from io import BytesIO from test_framework.test_framework import DashTestFramework -from test_framework.messages import CBlock, CBlockHeader, CCbTx, CMerkleBlock, FromHex, hash256, msg_getmnlistd, QuorumId, ser_uint256, sha256 +from test_framework.messages import CBlock, CBlockHeader, CCbTx, CMerkleBlock, from_hex, hash256, msg_getmnlistd, QuorumId, ser_uint256, sha256 from test_framework.p2p import P2PInterface from test_framework.util import ( assert_equal, @@ -277,7 +277,7 @@ class LLMQQuorumRotationTest(DashTestFramework): def test_getmnlistdiff_base(self, baseBlockHash, blockHash, testQuorumsCLSigs): hexstr = self.nodes[0].getblockheader(blockHash, False) - header = FromHex(CBlockHeader(), hexstr) + header = from_hex(CBlockHeader(), hexstr) d = self.test_node.getmnlistdiff(int(baseBlockHash, 16), int(blockHash, 16)) assert_equal(d.baseBlockHash, int(baseBlockHash, 16)) diff --git a/test/functional/feature_pruning.py b/test/functional/feature_pruning.py index 81b7512526..ee3fb50daa 100755 --- a/test/functional/feature_pruning.py +++ b/test/functional/feature_pruning.py @@ -11,8 +11,12 @@ This test takes 30 mins or more (up to 2 hours) import os from test_framework.blocktools import create_coinbase -from test_framework.messages import CBlock, ToHex -from test_framework.script import CScript, OP_RETURN, OP_NOP +from test_framework.messages import CBlock +from test_framework.script import ( + CScript, + OP_NOP, + OP_RETURN, +) from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, @@ -65,7 +69,7 @@ def mine_large_blocks(node, n): block.solve() # Submit to the node - node.submitblock(ToHex(block)) + node.submitblock(block.serialize().hex()) previousblockhash = block.sha256 height += 1 diff --git a/test/functional/feature_utxo_set_hash.py b/test/functional/feature_utxo_set_hash.py index c8d7781e0d..b21b34b906 100755 --- a/test/functional/feature_utxo_set_hash.py +++ b/test/functional/feature_utxo_set_hash.py @@ -10,7 +10,7 @@ from test_framework.blocktools import create_transaction from test_framework.messages import ( CBlock, COutPoint, - FromHex, + from_hex, ) from test_framework.crypto.muhash import MuHash3072 from test_framework.test_framework import BitcoinTestFramework @@ -39,7 +39,7 @@ class UTXOSetHashTest(BitcoinTestFramework): # Generate 100 blocks and remove the first since we plan to spend its # coinbase block_hashes = node.generate(100) - blocks = list(map(lambda block: FromHex(CBlock(), node.getblock(block, False)), block_hashes)) + blocks = list(map(lambda block: from_hex(CBlock(), node.getblock(block, False)), block_hashes)) spending = blocks.pop(0) # Create a spending transaction and mine a block which includes it @@ -47,7 +47,7 @@ class UTXOSetHashTest(BitcoinTestFramework): txid = node.sendrawtransaction(hexstring=tx.serialize().hex(), maxfeerate=0) tx_block = node.generateblock(node.getnewaddress(), [txid])['hash'] - blocks.append(FromHex(CBlock(), node.getblock(tx_block, False))) + blocks.append(from_hex(CBlock(), node.getblock(tx_block, False))) # Serialize the outputs that should be in the UTXO set and add them to # a MuHash object diff --git a/test/functional/interface_zmq.py b/test/functional/interface_zmq.py index 4de114ab50..22ab5f8941 100755 --- a/test/functional/interface_zmq.py +++ b/test/functional/interface_zmq.py @@ -7,7 +7,10 @@ import struct from test_framework.address import ADDRESS_BCRT1_UNSPENDABLE from test_framework.test_framework import BitcoinTestFramework -from test_framework.messages import dashhash, hash256 +from test_framework.messages import ( + dashhash, + hash256, +) from test_framework.util import assert_equal from time import sleep diff --git a/test/functional/interface_zmq_dash.py b/test/functional/interface_zmq_dash.py index 70dc014a5f..ee8931d340 100755 --- a/test/functional/interface_zmq_dash.py +++ b/test/functional/interface_zmq_dash.py @@ -23,7 +23,7 @@ from test_framework.messages import ( COutPoint, CRecoveredSig, CTransaction, - FromHex, + from_hex, hash256, msg_clsig, msg_inv, @@ -341,7 +341,7 @@ class DashZMQTest (DashTestFramework): # this is expected pass # Now send the tx itself - self.test_node.send_tx(FromHex(msg_tx(), rpc_raw_tx_3['hex'])) + self.test_node.send_tx(from_hex(msg_tx(),rpc_raw_tx_3['hex'])) self.wait_for_instantlock(rpc_raw_tx_3['txid'], self.nodes[0]) # Validate hashtxlock zmq_tx_lock_hash = self.subscribers[ZMQPublisher.hash_tx_lock].receive().read(32).hex() diff --git a/test/functional/mempool_accept.py b/test/functional/mempool_accept.py index 941f9ecaa4..eb8749cf3c 100755 --- a/test/functional/mempool_accept.py +++ b/test/functional/mempool_accept.py @@ -6,7 +6,6 @@ from decimal import Decimal -from io import BytesIO import math from test_framework.test_framework import BitcoinTestFramework @@ -15,11 +14,11 @@ from test_framework.messages import ( BIP125_SEQUENCE_NUMBER, COIN, COutPoint, - CTransaction, CTxIn, CTxOut, MAX_BLOCK_SIZE, MAX_MONEY, + tx_from_hex, ) from test_framework.script import ( hash160, @@ -35,7 +34,6 @@ from test_framework.script import ( from test_framework.util import ( assert_equal, assert_raises_rpc_error, - hex_str_to_bytes, ) @@ -91,8 +89,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework): inputs=[{"txid": txid_in_block, "vout": 0, "sequence": BIP125_SEQUENCE_NUMBER}], # RBF is used later outputs=[{node.getnewaddress(): Decimal('0.3') - fee}], ))['hex'] - tx = CTransaction() - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_0))) + tx = tx_from_hex(raw_tx_0) txid_0 = tx.rehash() self.check_mempool_result( result_expected=[{'txid': txid_0, 'allowed': True, 'vsize': tx.get_vsize(), 'fees': {'base': Decimal(str(fee))}}], @@ -107,8 +104,8 @@ class MempoolAcceptanceTest(BitcoinTestFramework): outputs=[{node.getnewaddress(): output_amount}], locktime=node.getblockcount() + 2000, # Can be anything ))['hex'] - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_final))) fee_expected = int(coin['amount']) - output_amount + tx = tx_from_hex(raw_tx_final) self.check_mempool_result( result_expected=[{'txid': tx.rehash(), 'allowed': True, 'vsize': tx.get_vsize(), 'fees': {'base': Decimal(str(fee_expected))}}], rawtxs=[tx.serialize().hex()], @@ -126,11 +123,11 @@ class MempoolAcceptanceTest(BitcoinTestFramework): ) self.log.info('A transaction that replaces a mempool transaction') - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_0))) + tx = tx_from_hex(raw_tx_0) tx.vout[0].nValue -= int(fee * COIN) # Double the fee tx.vin[0].nSequence = BIP125_SEQUENCE_NUMBER + 1 # Now, opt out of RBF raw_tx_0_reject = node.signrawtransactionwithwallet(tx.serialize().hex())['hex'] - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_0_reject))) + tx = tx_from_hex(raw_tx_0_reject) txid_0_reject = tx.rehash() self.check_mempool_result( # No RBF in DASH @@ -142,7 +139,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework): # Send the transaction that replaces the mempool transaction and opts out of replaceability # node.sendrawtransaction(hexstring=tx.serialize().hex(), maxfeerate=0) # take original raw_tx_0 - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_0))) + tx = tx_from_hex(raw_tx_0) tx.vout[0].nValue -= int(4 * fee * COIN) # Set more fee # skip re-signing the tx self.check_mempool_result( @@ -152,7 +149,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework): ) self.log.info('A transaction with missing inputs, that never existed') - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_0))) + tx = tx_from_hex(raw_tx_0) tx.vin[0].prevout = COutPoint(hash=int('ff' * 32, 16), n=14) # skip re-signing the tx self.check_mempool_result( @@ -161,7 +158,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework): ) self.log.info('A transaction with missing inputs, that existed once in the past') - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_0))) + tx = tx_from_hex(raw_tx_0) tx.vin[0].prevout.n = 1 # Set vout to 1, to spend the other outpoint (49 coins) of the in-chain-tx we want to double spend raw_tx_1 = node.signrawtransactionwithwallet(tx.serialize().hex())['hex'] txid_1 = node.sendrawtransaction(hexstring=raw_tx_1, maxfeerate=0) @@ -191,7 +188,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework): inputs=[{'txid': txid_spend_both, 'vout': 0}], outputs=[{node.getnewaddress(): 0.05}], ))['hex'] - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_reference))) + tx = tx_from_hex(raw_tx_reference) # Reference tx should be valid on itself self.check_mempool_result( result_expected=[{'txid': tx.rehash(), 'allowed': True, 'vsize': tx.get_vsize(), 'fees': { 'base': Decimal(str(0.1 - 0.05))}}], @@ -200,17 +197,17 @@ class MempoolAcceptanceTest(BitcoinTestFramework): ) self.log.info('A transaction with no outputs') - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_reference))) + tx = tx_from_hex(raw_tx_reference) tx.vout = [] # Skip re-signing the transaction for context independent checks from now on - # tx.deserialize(BytesIO(hex_str_to_bytes(node.signrawtransactionwithwallet(tx.serialize().hex())['hex']))) + # tx = tx_from_hex(node.signrawtransactionwithwallet(tx.serialize().hex())['hex']) self.check_mempool_result( result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'bad-txns-vout-empty'}], rawtxs=[tx.serialize().hex()], ) self.log.info('A really large transaction') - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_reference))) + tx = tx_from_hex(raw_tx_reference) tx.vin = [tx.vin[0]] * math.ceil(MAX_BLOCK_SIZE / len(tx.vin[0].serialize())) self.check_mempool_result( result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'bad-txns-oversize'}], @@ -218,7 +215,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework): ) self.log.info('A transaction with negative output value') - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_reference))) + tx = tx_from_hex(raw_tx_reference) tx.vout[0].nValue *= -1 self.check_mempool_result( result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'bad-txns-vout-negative'}], @@ -227,7 +224,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework): # The following two validations prevent overflow of the output amounts (see CVE-2010-5139). self.log.info('A transaction with too large output value') - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_reference))) + tx = tx_from_hex(raw_tx_reference) tx.vout[0].nValue = MAX_MONEY + 1 self.check_mempool_result( result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'bad-txns-vout-toolarge'}], @@ -235,7 +232,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework): ) self.log.info('A transaction with too large sum of output values') - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_reference))) + tx = tx_from_hex(raw_tx_reference) tx.vout = [tx.vout[0]] * 2 tx.vout[0].nValue = MAX_MONEY self.check_mempool_result( @@ -244,7 +241,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework): ) self.log.info('A transaction with duplicate inputs') - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_reference))) + tx = tx_from_hex(raw_tx_reference) tx.vin = [tx.vin[0]] * 2 self.check_mempool_result( result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'bad-txns-inputs-duplicate'}], @@ -262,26 +259,26 @@ class MempoolAcceptanceTest(BitcoinTestFramework): self.log.info('A coinbase transaction') # Pick the input of the first tx we signed, so it has to be a coinbase tx raw_tx_coinbase_spent = node.getrawtransaction(txid=node.decoderawtransaction(hexstring=raw_tx_in_block)['vin'][0]['txid']) - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_coinbase_spent))) + tx = tx_from_hex(raw_tx_coinbase_spent) self.check_mempool_result( result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'coinbase'}], rawtxs=[tx.serialize().hex()], ) self.log.info('Some nonstandard transactions') - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_reference))) + tx = tx_from_hex(raw_tx_reference) tx.nVersion = 4 # A version currently non-standard self.check_mempool_result( result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'version'}], rawtxs=[tx.serialize().hex()], ) - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_reference))) + tx = tx_from_hex(raw_tx_reference) tx.vout[0].scriptPubKey = CScript([OP_0]) # Some non-standard script self.check_mempool_result( result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'scriptpubkey'}], rawtxs=[tx.serialize().hex()], ) - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_reference))) + tx = tx_from_hex(raw_tx_reference) key = ECKey() key.generate() pubkey = key.get_pubkey().get_bytes() @@ -290,25 +287,25 @@ class MempoolAcceptanceTest(BitcoinTestFramework): result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'bare-multisig'}], rawtxs=[tx.serialize().hex()], ) - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_reference))) + tx = tx_from_hex(raw_tx_reference) tx.vin[0].scriptSig = CScript([OP_HASH160]) # Some not-pushonly scriptSig self.check_mempool_result( result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'scriptsig-not-pushonly'}], rawtxs=[tx.serialize().hex()], ) - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_reference))) + tx = tx_from_hex(raw_tx_reference) tx.vin[0].scriptSig = CScript([b'a' * 1648]) # Some too large scriptSig (>1650 bytes) self.check_mempool_result( result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'scriptsig-size'}], rawtxs=[tx.serialize().hex()], ) - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_reference))) + tx = tx_from_hex(raw_tx_reference) tx.vin[0].scriptSig = CScript([b'a' * 1648]) # Some too large scriptSig (>1650 bytes) self.check_mempool_result( result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'scriptsig-size'}], rawtxs=[tx.serialize().hex()], ) - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_reference))) + tx = tx_from_hex(raw_tx_reference) output_p2sh_burn = CTxOut(nValue=540, scriptPubKey=CScript([OP_HASH160, hash160(b'burn'), OP_EQUAL])) num_scripts = 100000 // len(output_p2sh_burn.serialize()) # Use enough outputs to make the tx too large for our policy tx.vout = [output_p2sh_burn] * num_scripts @@ -316,14 +313,14 @@ class MempoolAcceptanceTest(BitcoinTestFramework): result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'tx-size'}], rawtxs=[tx.serialize().hex()], ) - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_reference))) + tx = tx_from_hex(raw_tx_reference) tx.vout[0] = output_p2sh_burn tx.vout[0].nValue -= 1 # Make output smaller, such that it is dust for our policy self.check_mempool_result( result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'dust'}], rawtxs=[tx.serialize().hex()], ) - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_reference))) + tx = tx_from_hex(raw_tx_reference) tx.vout[0].scriptPubKey = CScript([OP_RETURN, b'\xff']) tx.vout = [tx.vout[0]] * 2 self.check_mempool_result( @@ -332,7 +329,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework): ) self.log.info('A timelocked transaction') - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_reference))) + tx = tx_from_hex(raw_tx_reference) tx.vin[0].nSequence -= 1 # Should be non-max, so locktime is not ignored tx.nLockTime = node.getblockcount() + 1 self.check_mempool_result( @@ -341,7 +338,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework): ) self.log.info('A transaction that is locked by BIP68 sequence logic') - tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_reference))) + tx = tx_from_hex(raw_tx_reference) tx.vin[0].nSequence = 2 # We could include it in the second block mined from now, but not the very next one # Can skip re-signing the tx because of early rejection self.check_mempool_result( diff --git a/test/functional/p2p_blocksonly.py b/test/functional/p2p_blocksonly.py index 75ccc9fb58..da520aa349 100755 --- a/test/functional/p2p_blocksonly.py +++ b/test/functional/p2p_blocksonly.py @@ -4,7 +4,7 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test p2p blocksonly""" -from test_framework.messages import msg_tx, CTransaction, FromHex +from test_framework.messages import msg_tx, tx_from_hex from test_framework.p2p import P2PInterface from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_equal @@ -40,7 +40,7 @@ class P2PBlocksOnly(BitcoinTestFramework): )['hex'] assert_equal(self.nodes[0].getnetworkinfo()['localrelay'], False) with self.nodes[0].assert_debug_log(['tx sent in violation of protocol peer=0']): - block_relay_peer.send_message(msg_tx(FromHex(CTransaction(), sigtx))) + block_relay_peer.send_message(msg_tx(tx_from_hex(sigtx))) block_relay_peer.wait_for_disconnect() assert_equal(self.nodes[0].getmempoolinfo()['size'], 0) @@ -78,7 +78,7 @@ class P2PBlocksOnly(BitcoinTestFramework): # But if, for some reason, first_peer decides to relay transactions to us anyway, we should relay them to # second_peer since we gave relay permission to first_peer. # See https://github.com/bitcoin/bitcoin/issues/19943 for details. - first_peer.send_message(msg_tx(FromHex(CTransaction(), sigtx))) + first_peer.send_message(msg_tx(tx_from_hex(sigtx))) self.log.info('Check that the peer with relay-permission is still connected after sending the transaction') assert_equal(first_peer.is_connected, True) self.bump_mocktime(60) diff --git a/test/functional/p2p_compactblocks.py b/test/functional/p2p_compactblocks.py index 2f1becbb4f..c5e9f695be 100755 --- a/test/functional/p2p_compactblocks.py +++ b/test/functional/p2p_compactblocks.py @@ -7,12 +7,56 @@ import random -from test_framework.blocktools import COINBASE_MATURITY, create_block, NORMAL_GBT_REQUEST_PARAMS -from test_framework.messages import BlockTransactions, BlockTransactionsRequest, calculate_shortid, CBlock, CBlockHeader, CInv, COutPoint, CTransaction, CTxIn, CTxOut, FromHex, HeaderAndShortIDs, msg_block, msg_blocktxn, msg_cmpctblock, msg_getblocktxn, msg_getdata, msg_getheaders, msg_headers, msg_inv, msg_sendcmpct, msg_sendheaders, msg_tx, MSG_BLOCK, MSG_CMPCT_BLOCK, NODE_NETWORK, P2PHeaderAndShortIDs, PrefilledTransaction, ToHex, NODE_HEADERS_COMPRESSED -from test_framework.p2p import p2p_lock, P2PInterface -from test_framework.script import CScript, OP_TRUE, OP_DROP +from test_framework.blocktools import ( + COINBASE_MATURITY, + create_block, + NORMAL_GBT_REQUEST_PARAMS, +) +from test_framework.messages import ( + BlockTransactions, + BlockTransactionsRequest, + CBlock, + CBlockHeader, + CInv, + COutPoint, + CTransaction, + CTxIn, + CTxOut, + from_hex, + HeaderAndShortIDs, + MSG_BLOCK, + MSG_CMPCT_BLOCK, + NODE_HEADERS_COMPRESSED, + NODE_NETWORK, + P2PHeaderAndShortIDs, + PrefilledTransaction, + calculate_shortid, + msg_block, + msg_blocktxn, + msg_cmpctblock, + msg_getblocktxn, + msg_getdata, + msg_getheaders, + msg_headers, + msg_inv, + msg_sendcmpct, + msg_sendheaders, + msg_tx, + tx_from_hex, +) +from test_framework.p2p import ( + P2PInterface, + p2p_lock, +) +from test_framework.script import ( + CScript, + OP_DROP, + OP_TRUE, +) from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal +from test_framework.util import ( + assert_equal, +) # TestP2PConn: A peer we use to send messages to dashd, and store responses. class TestP2PConn(P2PInterface): @@ -249,7 +293,7 @@ class CompactBlocksTest(BitcoinTestFramework): for _ in range(num_transactions): txid = node.sendtoaddress(address, 0.1) hex_tx = node.gettransaction(txid)["hex"] - tx = FromHex(CTransaction(), hex_tx) + tx = tx_from_hex(hex_tx) # Wait until we've seen the block announcement for the resulting tip tip = int(node.getbestblockhash(), 16) @@ -263,7 +307,7 @@ class CompactBlocksTest(BitcoinTestFramework): block_hash = int(node.generate(1)[0], 16) # Store the raw block in our internal format. - block = FromHex(CBlock(), node.getblock("%064x" % block_hash, False)) + block = from_hex(CBlock(), node.getblock("%064x" % block_hash, False)) for tx in block.vtx: tx.calc_sha256() block.rehash() @@ -528,7 +572,7 @@ class CompactBlocksTest(BitcoinTestFramework): current_height = chain_height while (current_height >= chain_height - MAX_GETBLOCKTXN_DEPTH): block_hash = node.getblockhash(current_height) - block = FromHex(CBlock(), node.getblock(block_hash, False)) + block = from_hex(CBlock(), node.getblock(block_hash, False)) msg = msg_getblocktxn() msg.block_txn_request = BlockTransactionsRequest(int(block_hash, 16), []) @@ -564,7 +608,7 @@ class CompactBlocksTest(BitcoinTestFramework): # Request with out-of-bounds tx index results in disconnect bad_peer = self.nodes[0].add_p2p_connection(TestP2PConn(cmpct_version=1)) block_hash = node.getblockhash(chain_height) - block = FromHex(CBlock(), node.getblock(block_hash, False)) + block = from_hex(CBlock(), node.getblock(block_hash, False)) msg.block_txn_request = BlockTransactionsRequest(int(block_hash, 16), [len(block.vtx)]) with node.assert_debug_log(['getblocktxn with out-of-bounds tx indices']): bad_peer.send_message(msg) @@ -634,7 +678,7 @@ class CompactBlocksTest(BitcoinTestFramework): [l.clear_block_announcement() for l in listeners] - node.submitblock(ToHex(block)) + node.submitblock(block.serialize().hex()) for l in listeners: l.wait_until(lambda: "cmpctblock" in l.last_message, timeout=30) diff --git a/test/functional/p2p_eviction.py b/test/functional/p2p_eviction.py index 7ebfbc25dd..b3a877c86e 100755 --- a/test/functional/p2p_eviction.py +++ b/test/functional/p2p_eviction.py @@ -16,10 +16,17 @@ Therefore, this test is limited to the remaining protection criteria. import time from test_framework.blocktools import COINBASE_MATURITY, create_block, create_coinbase -from test_framework.messages import CTransaction, FromHex, msg_pong, msg_tx -from test_framework.p2p import P2PDataStore, P2PInterface +from test_framework.p2p import ( + P2PDataStore, + P2PInterface, +) from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_equal +from test_framework.messages import ( + msg_pong, + msg_tx, + tx_from_hex, +) class SlowP2PDataStore(P2PDataStore): @@ -85,7 +92,7 @@ class P2PEvict(BitcoinTestFramework): 'scriptPubKey': prevtx['vout'][0]['scriptPubKey']['hex'], }], )['hex'] - txpeer.send_message(msg_tx(FromHex(CTransaction(), sigtx))) + txpeer.send_message(msg_tx(tx_from_hex(sigtx))) protected_peers.add(current_peer) self.log.info("Create 8 peers and protect them from eviction by having faster pings") diff --git a/test/functional/p2p_permissions.py b/test/functional/p2p_permissions.py index f5bed070f7..38c18bbbd7 100755 --- a/test/functional/p2p_permissions.py +++ b/test/functional/p2p_permissions.py @@ -9,8 +9,7 @@ Test that permissions are correctly calculated and applied from test_framework.address import ADDRESS_BCRT1_P2SH_OP_TRUE from test_framework.messages import ( - CTransaction, - FromHex, + tx_from_hex, ) from test_framework.p2p import P2PDataStore from test_framework.script import ( @@ -114,8 +113,7 @@ class P2PPermissionsTests(BitcoinTestFramework): p2p_rebroadcast_wallet = self.nodes[1].add_p2p_connection(P2PDataStore()) self.log.debug("Send a tx from the wallet initially") - tx = FromHex( - CTransaction(), + tx = tx_from_hex( self.nodes[0].createrawtransaction( inputs=[{ 'txid': block_op_true['tx'][0], diff --git a/test/functional/p2p_tx_download.py b/test/functional/p2p_tx_download.py index dd5769d626..c0d077a941 100755 --- a/test/functional/p2p_tx_download.py +++ b/test/functional/p2p_tx_download.py @@ -8,12 +8,11 @@ Test transaction download behavior from test_framework.messages import ( CInv, - CTransaction, - FromHex, MSG_TX, MSG_TYPE_MASK, msg_inv, msg_notfound, + tx_from_hex, ) from test_framework.p2p import ( P2PInterface, @@ -92,7 +91,7 @@ class TxDownloadTest(BitcoinTestFramework): hexstring=tx, privkeys=[self.nodes[0].get_deterministic_priv_key().key], )['hex'] - ctx = FromHex(CTransaction(), tx) + ctx = tx_from_hex(tx) txid = int(ctx.rehash(), 16) self.log.info( diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py index 485bd6e52a..10a3c43516 100755 --- a/test/functional/rpc_blockchain.py +++ b/test/functional/rpc_blockchain.py @@ -29,7 +29,7 @@ from test_framework.blocktools import ( ) from test_framework.messages import ( CBlockHeader, - FromHex, + from_hex, msg_block, ) from test_framework.p2p import P2PInterface @@ -326,7 +326,7 @@ class BlockchainTest(BitcoinTestFramework): header_hex = node.getblockheader(blockhash=besthash, verbose=False) assert_is_hex_string(header_hex) - header = FromHex(CBlockHeader(), header_hex) + header = from_hex(CBlockHeader(), header_hex) header.calc_sha256() assert_equal(header.hash, besthash) diff --git a/test/functional/rpc_decodescript.py b/test/functional/rpc_decodescript.py index f0d84aae60..bf75825e92 100755 --- a/test/functional/rpc_decodescript.py +++ b/test/functional/rpc_decodescript.py @@ -4,11 +4,15 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test decoding scripts via decodescript RPC command.""" -from test_framework.messages import CTransaction +from test_framework.messages import ( + tx_from_hex, +) from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal, hex_str_to_bytes +from test_framework.util import ( + assert_equal, + hex_str_to_bytes, +) -from io import BytesIO class DecodeScriptTest(BitcoinTestFramework): def set_test_params(self): @@ -125,8 +129,7 @@ class DecodeScriptTest(BitcoinTestFramework): assert_equal('0 3045022100ae3b4e589dfc9d48cb82d41008dc5fa6a86f94d5c54f9935531924602730ab8002202f88cf464414c4ed9fa11b773c5ee944f66e9b05cc1e51d97abc22ce098937ea[ALL] 3045022100b44883be035600e9328a01b66c7d8439b74db64187e76b99a68f7893b701d5380220225bf286493e4c4adcf928c40f785422572eb232f84a0b83b0dea823c3a19c75[ALL] 5221020743d44be989540d27b1b4bbbcfd17721c337cb6bc9af20eb8a32520b393532f2102c0120a1dda9e51a938d39ddd9fe0ebc45ea97e1d27a7cbd671d5431416d3dd87210213820eb3d5f509d7438c9eeecb4157b2f595105e7cd564b3cdbb9ead3da41eed53ae', rpc_result['vin'][0]['scriptSig']['asm']) assert_equal('OP_DUP OP_HASH160 dc863734a218bfe83ef770ee9d41a27f824a6e56 OP_EQUALVERIFY OP_CHECKSIG', rpc_result['vout'][0]['scriptPubKey']['asm']) assert_equal('OP_HASH160 2a5edea39971049a540474c6a99edf0aa4074c58 OP_EQUAL', rpc_result['vout'][1]['scriptPubKey']['asm']) - txSave = CTransaction() - txSave.deserialize(BytesIO(hex_str_to_bytes(tx))) + txSave = tx_from_hex(tx) # make sure that a specifically crafted op_return value will not pass all the IsDERSignature checks and then get decoded as a sighash type tx = '01000000015ded05872fdbda629c7d3d02b194763ce3b9b1535ea884e3c8e765d42e316724020000006b48304502204c10d4064885c42638cbff3585915b322de33762598321145ba033fc796971e2022100bb153ad3baa8b757e30a2175bd32852d2e1cb9080f84d7e32fcdfd667934ef1b012103163c0ff73511ea1743fb5b98384a2ff09dd06949488028fd819f4d83f56264efffffffff0200000000000000000b6a0930060201000201000180380100000000001976a9141cabd296e753837c086da7a45a6c2fe0d49d7b7b88ac00000000' diff --git a/test/functional/rpc_packages.py b/test/functional/rpc_packages.py index 1727964bc0..c2e14ce8cd 100755 --- a/test/functional/rpc_packages.py +++ b/test/functional/rpc_packages.py @@ -10,9 +10,7 @@ import random from test_framework.address import ADDRESS_BCRT1_P2SH_OP_TRUE from test_framework.test_framework import BitcoinTestFramework from test_framework.messages import ( - CTransaction, - FromHex, - ToHex, + tx_from_hex, ) from test_framework.script import ( CScript, @@ -93,7 +91,7 @@ class RPCPackagesTest(BitcoinTestFramework): "amount": parent_value, }] if parent_locking_script else None signedtx = node.signrawtransactionwithkey(hexstring=rawtx, privkeys=self.privkeys, prevtxs=prevtxs) - tx = FromHex(CTransaction(), signedtx["hex"]) + tx = tx_from_hex(signedtx["hex"]) tx.rehash() assert signedtx["complete"] return (tx, signedtx["hex"], my_value, tx.vout[0].scriptPubKey.hex()) @@ -106,7 +104,7 @@ class RPCPackagesTest(BitcoinTestFramework): self.log.info("Test an otherwise valid package with an extra garbage tx appended") garbage_tx = node.createrawtransaction([{"txid": "00" * 32, "vout": 5}], {self.address: 1}) - tx = FromHex(CTransaction(), garbage_tx) + tx = tx_from_hex(garbage_tx) # Only the txid is returned because validation is incomplete for the independent txns. # Package validation is atomic: if the node cannot find a UTXO for any single tx in the package, # it terminates immediately to avoid unnecessary, expensive signature verification. @@ -118,8 +116,8 @@ class RPCPackagesTest(BitcoinTestFramework): coin = self.coins.pop() tx_bad_sig_hex = node.createrawtransaction([{"txid": coin["txid"], "vout": 0}], {self.address : coin["amount"] - Decimal("0.0001")}) - tx_bad_sig = FromHex(CTransaction(), tx_bad_sig_hex) - tx_bad_sig_hex = ToHex(tx_bad_sig) + tx_bad_sig = tx_from_hex(tx_bad_sig_hex) + tx_bad_sig_hex = tx_bad_sig.serialize().hex() testres_bad_sig = node.testmempoolaccept(self.independent_txns_hex + [tx_bad_sig_hex]) # By the time the signature for the last transaction is checked, all the other transactions # have been fully validated, which is why the node returns full validation results for all @@ -136,7 +134,7 @@ class RPCPackagesTest(BitcoinTestFramework): {self.address : coin["amount"] - Decimal("0.999")}) tx_high_fee_signed = node.signrawtransactionwithkey(hexstring=tx_high_fee_raw, privkeys=self.privkeys) assert tx_high_fee_signed["complete"] - tx_high_fee = FromHex(CTransaction(), tx_high_fee_signed["hex"]) + tx_high_fee = tx_from_hex(tx_high_fee_signed["hex"]) testres_high_fee = node.testmempoolaccept([tx_high_fee_signed["hex"]]) assert_equal(testres_high_fee, [ {"txid": tx_high_fee.rehash(), "allowed": False, "reject-reason": "max-fee-exceeded"} @@ -192,7 +190,7 @@ class RPCPackagesTest(BitcoinTestFramework): rawtx = node.createrawtransaction(inputs, outputs) parent_signed = node.signrawtransactionwithkey(hexstring=rawtx, privkeys=self.privkeys) - parent_tx = FromHex(CTransaction(), parent_signed["hex"]) + parent_tx = tx_from_hex(parent_signed["hex"]) assert parent_signed["complete"] parent_txid = parent_tx.rehash() assert node.testmempoolaccept([parent_signed["hex"]])[0]["allowed"] @@ -206,9 +204,9 @@ class RPCPackagesTest(BitcoinTestFramework): # Child B rawtx_b = node.createrawtransaction([{"txid": parent_txid, "vout": 1}], {self.address : child_value}) - tx_child_b = FromHex(CTransaction(), rawtx_b) + tx_child_b = tx_from_hex(rawtx_b) tx_child_b.vin[0].scriptSig = CScript([CScript([OP_TRUE])]) - tx_child_b_hex = ToHex(tx_child_b) + tx_child_b_hex = tx_child_b.serialize().hex() assert not node.testmempoolaccept([tx_child_b_hex])[0]["allowed"] self.log.info("Testmempoolaccept with entire package, should work with children in either order") @@ -284,8 +282,8 @@ class RPCPackagesTest(BitcoinTestFramework): rawtx2 = node.createrawtransaction(inputs, output2) signedtx1 = node.signrawtransactionwithkey(hexstring=rawtx1, privkeys=self.privkeys) signedtx2 = node.signrawtransactionwithkey(hexstring=rawtx2, privkeys=self.privkeys) - tx1 = FromHex(CTransaction(), signedtx1["hex"]) - tx2 = FromHex(CTransaction(), signedtx2["hex"]) + tx1 = tx_from_hex(signedtx1["hex"]) + tx2 = tx_from_hex(signedtx2["hex"]) assert signedtx1["complete"] assert signedtx2["complete"] diff --git a/test/functional/rpc_rawtransaction.py b/test/functional/rpc_rawtransaction.py index 2e3edf3b5e..813035119d 100755 --- a/test/functional/rpc_rawtransaction.py +++ b/test/functional/rpc_rawtransaction.py @@ -14,16 +14,17 @@ Test the following RPCs: from collections import OrderedDict from decimal import Decimal -from io import BytesIO from test_framework.blocktools import COINBASE_MATURITY -from test_framework.messages import CTransaction, ToHex +from test_framework.messages import ( + CTransaction, + tx_from_hex, +) from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, assert_raises_rpc_error, find_vout_for_address, - hex_str_to_bytes, ) @@ -124,23 +125,22 @@ class RawTransactionsTest(BitcoinTestFramework): assert_raises_rpc_error(-8, "Invalid parameter, locktime out of range", self.nodes[0].createrawtransaction, [], {}, 4294967296) self.log.info('Check that createrawtransaction accepts an array and object as outputs') - tx = CTransaction() # One output - tx.deserialize(BytesIO(hex_str_to_bytes(self.nodes[2].createrawtransaction(inputs=[{'txid': txid, 'vout': 9}], outputs={address: 99})))) + tx = tx_from_hex(self.nodes[2].createrawtransaction(inputs=[{'txid': txid, 'vout': 9}], outputs={address: 99})) assert_equal(len(tx.vout), 1) assert_equal( tx.serialize().hex(), self.nodes[2].createrawtransaction(inputs=[{'txid': txid, 'vout': 9}], outputs=[{address: 99}]), ) # Two outputs - tx.deserialize(BytesIO(hex_str_to_bytes(self.nodes[2].createrawtransaction(inputs=[{'txid': txid, 'vout': 9}], outputs=OrderedDict([(address, 99), (address2, 99)]))))) + tx = tx_from_hex(self.nodes[2].createrawtransaction(inputs=[{'txid': txid, 'vout': 9}], outputs=OrderedDict([(address, 99), (address2, 99)]))) assert_equal(len(tx.vout), 2) assert_equal( tx.serialize().hex(), self.nodes[2].createrawtransaction(inputs=[{'txid': txid, 'vout': 9}], outputs=[{address: 99}, {address2: 99}]), ) # Multiple mixed outputs - tx.deserialize(BytesIO(hex_str_to_bytes(self.nodes[2].createrawtransaction(inputs=[{'txid': txid, 'vout': 9}], outputs=multidict([(address, 99), (address2, 99), ('data', '99')]))))) + tx = tx_from_hex(self.nodes[2].createrawtransaction(inputs=[{'txid': txid, 'vout': 9}], outputs=multidict([(address, 99), (address2, 99), ('data', '99')]))) assert_equal(len(tx.vout), 3) assert_equal( tx.serialize().hex(), @@ -383,14 +383,14 @@ class RawTransactionsTest(BitcoinTestFramework): # As transaction version is unsigned, this should convert to its unsigned equivalent. tx = CTransaction() tx.nVersion = -0x8000 - rawtx = ToHex(tx) + rawtx = tx.serialize().hex() decrawtx = self.nodes[0].decoderawtransaction(rawtx) assert_equal(decrawtx['version'], 0x8000) # Test the maximum transaction version number that fits in a signed 32-bit integer. tx = CTransaction() tx.nVersion = 0x7fff - rawtx = ToHex(tx) + rawtx = tx.serialize().hex() decrawtx = self.nodes[0].decoderawtransaction(rawtx) assert_equal(decrawtx['version'], 0x7fff) diff --git a/test/functional/rpc_txoutproof.py b/test/functional/rpc_txoutproof.py index 4373cc7845..caa3ea37b6 100755 --- a/test/functional/rpc_txoutproof.py +++ b/test/functional/rpc_txoutproof.py @@ -5,11 +5,17 @@ """Test gettxoutproof and verifytxoutproof RPCs.""" from test_framework.blocktools import COINBASE_MATURITY -from test_framework.messages import CMerkleBlock, FromHex, ToHex +from test_framework.messages import ( + CMerkleBlock, + from_hex, +) from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal, assert_raises_rpc_error from test_framework.wallet import MiniWallet +from test_framework.util import ( + assert_equal, + assert_raises_rpc_error, +) class MerkleBlockTest(BitcoinTestFramework): def set_test_params(self): @@ -91,10 +97,10 @@ class MerkleBlockTest(BitcoinTestFramework): assert txid1 in self.nodes[0].verifytxoutproof(proof) assert txid2 in self.nodes[1].verifytxoutproof(proof) - tweaked_proof = FromHex(CMerkleBlock(), proof) + tweaked_proof = from_hex(CMerkleBlock(), proof) # Make sure that our serialization/deserialization is working - assert txid1 in self.nodes[0].verifytxoutproof(ToHex(tweaked_proof)) + assert txid1 in self.nodes[0].verifytxoutproof(tweaked_proof.serialize().hex()) # Check to see if we can go up the merkle tree and pass this off as a # single-transaction block @@ -103,7 +109,7 @@ class MerkleBlockTest(BitcoinTestFramework): tweaked_proof.txn.vBits = [True] + [False]*7 for n in self.nodes: - assert not n.verifytxoutproof(ToHex(tweaked_proof)) + assert not n.verifytxoutproof(tweaked_proof.serialize().hex()) # TODO: try more variants, eg transactions at different depths, and # verify that the proofs are invalid diff --git a/test/functional/rpc_verifyislock.py b/test/functional/rpc_verifyislock.py index 1eb91ae4bd..534bbe1c57 100755 --- a/test/functional/rpc_verifyislock.py +++ b/test/functional/rpc_verifyislock.py @@ -3,7 +3,7 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -from test_framework.messages import CTransaction, FromHex, hash256, ser_compact_size, ser_string +from test_framework.messages import CTransaction, from_hex, hash256, ser_compact_size, ser_string from test_framework.test_framework import DashTestFramework from test_framework.util import assert_raises_rpc_error, satoshi_round @@ -20,7 +20,7 @@ class RPCVerifyISLockTest(DashTestFramework): self.set_dash_test_params(6, 5, [["-whitelist=127.0.0.1"], [], [], [], [], []], fast_dip3_enforcement=True) def get_request_id(self, tx_hex): - tx = FromHex(CTransaction(), tx_hex) + tx = from_hex(CTransaction(), tx_hex) request_id_buf = ser_string(b"islock") + ser_compact_size(len(tx.vin)) for txin in tx.vin: diff --git a/test/functional/test_framework/blocktools.py b/test/functional/test_framework/blocktools.py index e8202f5e7d..d0eb93ec3b 100644 --- a/test/functional/test_framework/blocktools.py +++ b/test/functional/test_framework/blocktools.py @@ -19,7 +19,8 @@ from .messages import ( CTransaction, CTxIn, CTxOut, - FromHex, + tx_from_hex, + from_hex, uint256_to_string, ) from .script import CScript, CScriptNum, CScriptOp, OP_TRUE, OP_CHECKSIG @@ -123,13 +124,13 @@ def create_block_with_mnpayments(mninfo, node, vtx=None, mn_payee=None, mn_amoun if mn_operator_amount > 0: outputs[mn_operator_payee] = str(Decimal(mn_operator_amount) / COIN) - coinbase = FromHex(CTransaction(), node.createrawtransaction([], outputs)) + coinbase = tx_from_hex(node.createrawtransaction([], outputs)) coinbase.vin = create_coinbase(height).vin # We can't really use this one as it would result in invalid merkle roots for masternode lists if len(bt['coinbase_payload']) != 0: tip_block = node.getblock(tip_hash) - cbtx = FromHex(CCbTx(version=1), bt['coinbase_payload']) + cbtx = from_hex(CCbTx(version=1), bt['coinbase_payload']) if 'cbTx' in tip_block: cbtx.merkleRootMNList = int(tip_block['cbTx']['merkleRootMNList'], 16) else: @@ -145,7 +146,7 @@ def create_block_with_mnpayments(mninfo, node, vtx=None, mn_payee=None, mn_amoun # Add quorum commitments from template for tx in bt['transactions']: - tx2 = FromHex(CTransaction(), tx['data']) + tx2 = tx_from_hex(tx['data']) if tx2.nType == 6: block.vtx.append(tx2) diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py index d055226ca8..17164eb55a 100755 --- a/test/functional/test_framework/messages.py +++ b/test/functional/test_framework/messages.py @@ -208,14 +208,20 @@ def ser_dyn_bitset(l, bytes_based): return r -# Deserialize from a hex string representation (eg from RPC) -def FromHex(obj, hex_string): +def from_hex(obj, hex_string): + """Deserialize from a hex string representation (e.g. from RPC) + + Note that there is no complementary helper like e.g. `to_hex` for the + inverse operation. To serialize a message object to a hex string, simply + use obj.serialize().hex()""" obj.deserialize(BytesIO(hex_str_to_bytes(hex_string))) return obj -# Convert a binary-serializable object to hex (eg for submission via RPC) -def ToHex(obj): - return obj.serialize().hex() + +def tx_from_hex(hex_string): + """Deserialize from hex string to a transaction object""" + return from_hex(CTransaction(), hex_string) + # Objects that map to dashd objects, which can be serialized/deserialized diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index 8f5034e866..9f7aaa1d88 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -27,12 +27,13 @@ from .authproxy import JSONRPCException from test_framework.blocktools import TIME_GENESIS_BLOCK from . import coverage from .messages import ( - CTransaction, - FromHex, hash256, msg_isdlock, ser_compact_size, ser_string, + tx_from_hex, + + ) from .script import hash160 from .p2p import NetworkThread @@ -1564,7 +1565,7 @@ class DashTestFramework(BitcoinTestFramework): raise AssertionError("waiting unexpectedly succeeded") def create_isdlock(self, hextx): - tx = FromHex(CTransaction(), hextx) + tx = tx_from_hex(hextx) tx.rehash() request_id_buf = ser_string(b"islock") + ser_compact_size(len(tx.vin)) diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py index cf55814113..e009e0c7a6 100644 --- a/test/functional/test_framework/util.py +++ b/test/functional/test_framework/util.py @@ -19,7 +19,6 @@ import time from . import coverage from .authproxy import AuthServiceProxy, JSONRPCException -from io import BytesIO logger = logging.getLogger("TestFramework.utils") @@ -553,7 +552,7 @@ def gen_return_txouts(): def create_lots_of_big_transactions(node, txouts, utxos, num, fee): addr = node.getnewaddress() txids = [] - from .messages import CTransaction + from .messages import tx_from_hex for _ in range(num): t = utxos.pop() inputs = [{"txid": t["txid"], "vout": t["vout"]}] @@ -561,8 +560,7 @@ def create_lots_of_big_transactions(node, txouts, utxos, num, fee): change = t['amount'] - fee outputs[addr] = satoshi_round(change) rawtx = node.createrawtransaction(inputs, outputs) - tx = CTransaction() - tx.deserialize(BytesIO(hex_str_to_bytes(rawtx))) + tx = tx_from_hex(rawtx) for txout in txouts: tx.vout.append(txout) newtx = tx.serialize().hex() diff --git a/test/functional/wallet_groups.py b/test/functional/wallet_groups.py index f2c87583e8..9568326196 100755 --- a/test/functional/wallet_groups.py +++ b/test/functional/wallet_groups.py @@ -6,7 +6,9 @@ from test_framework.blocktools import COINBASE_MATURITY from test_framework.test_framework import BitcoinTestFramework -from test_framework.messages import CTransaction, FromHex, ToHex +from test_framework.messages import ( + tx_from_hex, +) from test_framework.util import ( assert_approx, assert_equal, @@ -152,10 +154,10 @@ class WalletGroupTest(BitcoinTestFramework): # scriptPubKey for _ in range(5): raw_tx = self.nodes[0].createrawtransaction([{"txid":"0"*64, "vout":0}], [{addr2[0]: 0.05}]) - tx = FromHex(CTransaction(), raw_tx) + tx = tx_from_hex(raw_tx) tx.vin = [] tx.vout = [tx.vout[0]] * 2000 - funded_tx = self.nodes[0].fundrawtransaction(ToHex(tx)) + funded_tx = self.nodes[0].fundrawtransaction(tx.serialize().hex()) signed_tx = self.nodes[0].signrawtransactionwithwallet(funded_tx['hex']) self.nodes[0].sendrawtransaction(signed_tx['hex']) self.nodes[0].generate(1) diff --git a/test/functional/wallet_listtransactions.py b/test/functional/wallet_listtransactions.py index 2e25d61df9..6f20635dce 100755 --- a/test/functional/wallet_listtransactions.py +++ b/test/functional/wallet_listtransactions.py @@ -6,7 +6,10 @@ from decimal import Decimal from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_array_result, assert_equal +from test_framework.util import ( + assert_array_result, + assert_equal, +) class ListTransactionsTest(BitcoinTestFramework): def set_test_params(self): diff --git a/test/functional/wallet_resendwallettransactions.py b/test/functional/wallet_resendwallettransactions.py index 592d0a6ea3..3a8615ac58 100755 --- a/test/functional/wallet_resendwallettransactions.py +++ b/test/functional/wallet_resendwallettransactions.py @@ -4,8 +4,10 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test that the wallet resends transactions periodically.""" -from test_framework.blocktools import create_block, create_coinbase -from test_framework.messages import ToHex +from test_framework.blocktools import ( + create_block, + create_coinbase, +) from test_framework.p2p import P2PTxInvStore from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_equal @@ -50,7 +52,7 @@ class ResendWalletTransactionsTest(BitcoinTestFramework): block = create_block(int(node.getbestblockhash(), 16), create_coinbase(node.getblockcount() + 1), block_time) block.rehash() block.solve() - node.submitblock(ToHex(block)) + node.submitblock(block.serialize().hex()) # Set correct m_best_block_time, which is used in ResendWalletTransactions node.syncwithvalidationinterfacequeue() diff --git a/test/functional/wallet_txn_clone.py b/test/functional/wallet_txn_clone.py index 1a88e1464d..3a865c05cf 100755 --- a/test/functional/wallet_txn_clone.py +++ b/test/functional/wallet_txn_clone.py @@ -4,12 +4,14 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the wallet accounts properly when there are cloned transactions with malleated scriptsigs.""" -import io from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, ) -from test_framework.messages import CTransaction, COIN +from test_framework.messages import ( + COIN, + tx_from_hex, +) class TxnMallTest(BitcoinTestFramework): def set_test_params(self): @@ -64,8 +66,7 @@ class TxnMallTest(BitcoinTestFramework): clone_raw = self.nodes[0].createrawtransaction(clone_inputs, clone_outputs, clone_locktime) # createrawtransaction randomizes the order of its outputs, so swap them if necessary. - clone_tx = CTransaction() - clone_tx.deserialize(io.BytesIO(bytes.fromhex(clone_raw))) + clone_tx = tx_from_hex(clone_raw) if (rawtx1["vout"][0]["value"] == 400 and clone_tx.vout[0].nValue != 400*COIN or rawtx1["vout"][0]["value"] != 400 and clone_tx.vout[0].nValue == 400*COIN): (clone_tx.vout[0], clone_tx.vout[1]) = (clone_tx.vout[1], clone_tx.vout[0])