diff options
Diffstat (limited to 'test')
-rwxr-xr-x | test/functional/feature_minchainwork.py | 2 | ||||
-rwxr-xr-x | test/functional/feature_rbf.py | 16 | ||||
-rwxr-xr-x | test/functional/mempool_accept.py | 6 | ||||
-rwxr-xr-x | test/functional/mempool_persist.py | 14 | ||||
-rwxr-xr-x | test/functional/p2p_segwit.py | 4 | ||||
-rwxr-xr-x | test/functional/rpc_getblockfrompeer.py | 9 | ||||
-rwxr-xr-x | test/functional/rpc_packages.py | 4 | ||||
-rwxr-xr-x | test/functional/rpc_psbt.py | 4 | ||||
-rwxr-xr-x | test/functional/rpc_rawtransaction.py | 4 | ||||
-rwxr-xr-x | test/functional/rpc_signrawtransactionwithkey.py | 140 | ||||
-rwxr-xr-x | test/functional/test_framework/messages.py | 2 | ||||
-rwxr-xr-x | test/functional/test_runner.py | 5 | ||||
-rwxr-xr-x | test/functional/wallet_bumpfee.py | 8 | ||||
-rwxr-xr-x | test/functional/wallet_coinbase_category.py | 1 | ||||
-rwxr-xr-x | test/functional/wallet_listsinceblock.py | 4 | ||||
-rwxr-xr-x | test/functional/wallet_signrawtransactionwithwallet.py (renamed from test/functional/rpc_signrawtransaction.py) | 100 |
16 files changed, 191 insertions, 132 deletions
diff --git a/test/functional/feature_minchainwork.py b/test/functional/feature_minchainwork.py index 9d0ad5ef9d..fb4024b1b0 100755 --- a/test/functional/feature_minchainwork.py +++ b/test/functional/feature_minchainwork.py @@ -82,7 +82,7 @@ class MinimumChainWorkTest(BitcoinTestFramework): msg.hashstop = 0 peer.send_and_ping(msg) time.sleep(5) - assert ("headers" not in peer.last_message or len(peer.last_message["headers"].headers) == 0) + assert "headers" not in peer.last_message or len(peer.last_message["headers"].headers) == 0 self.log.info("Generating one more block") self.generate(self.nodes[0], 1) diff --git a/test/functional/feature_rbf.py b/test/functional/feature_rbf.py index 8e5cbba01a..2237a4171e 100755 --- a/test/functional/feature_rbf.py +++ b/test/functional/feature_rbf.py @@ -7,7 +7,7 @@ from decimal import Decimal from test_framework.messages import ( - BIP125_SEQUENCE_NUMBER, + MAX_BIP125_RBF_SEQUENCE, COIN, SEQUENCE_FINAL, ) @@ -428,7 +428,7 @@ class ReplaceByFeeTest(BitcoinTestFramework): optin_parent_tx = wallet.send_self_transfer_multi( from_node=normal_node, - sequence=BIP125_SEQUENCE_NUMBER, + sequence=MAX_BIP125_RBF_SEQUENCE, utxos_to_spend=[root_utxos[graph_num]], num_outputs=txs_per_graph, ) @@ -636,14 +636,14 @@ class ReplaceByFeeTest(BitcoinTestFramework): optin_parent_tx = self.wallet.send_self_transfer( from_node=self.nodes[0], utxo_to_spend=confirmed_utxo, - sequence=BIP125_SEQUENCE_NUMBER, + sequence=MAX_BIP125_RBF_SEQUENCE, fee_rate=Decimal('0.01'), ) assert_equal(True, self.nodes[0].getmempoolentry(optin_parent_tx['txid'])['bip125-replaceable']) replacement_parent_tx = self.wallet.create_self_transfer( utxo_to_spend=confirmed_utxo, - sequence=BIP125_SEQUENCE_NUMBER, + sequence=MAX_BIP125_RBF_SEQUENCE, fee_rate=Decimal('0.02'), ) @@ -702,17 +702,16 @@ class ReplaceByFeeTest(BitcoinTestFramework): assert_raises_rpc_error(-26, "insufficient fee", self.nodes[0].sendrawtransaction, tx.serialize().hex()) def test_fullrbf(self): - txid = self.wallet.send_self_transfer(from_node=self.nodes[0])['txid'] - self.generate(self.nodes[0], 1) - confirmed_utxo = self.wallet.get_utxo(txid=txid) + confirmed_utxo = self.make_utxo(self.nodes[0], int(2 * COIN)) self.restart_node(0, extra_args=["-mempoolfullrbf=1"]) + assert self.nodes[0].getmempoolinfo()["fullrbf"] # Create an explicitly opt-out transaction optout_tx = self.wallet.send_self_transfer( from_node=self.nodes[0], utxo_to_spend=confirmed_utxo, - sequence=SEQUENCE_FINAL, + sequence=MAX_BIP125_RBF_SEQUENCE + 1, fee_rate=Decimal('0.01'), ) assert_equal(False, self.nodes[0].getmempoolentry(optout_tx['txid'])['bip125-replaceable']) @@ -728,6 +727,7 @@ class ReplaceByFeeTest(BitcoinTestFramework): # Optout_tx is not anymore in the mempool. assert optout_tx['txid'] not in self.nodes[0].getrawmempool() + assert conflicting_tx['txid'] in self.nodes[0].getrawmempool() if __name__ == '__main__': ReplaceByFeeTest().main() diff --git a/test/functional/mempool_accept.py b/test/functional/mempool_accept.py index 85464b8d0d..65b37a4975 100755 --- a/test/functional/mempool_accept.py +++ b/test/functional/mempool_accept.py @@ -11,7 +11,7 @@ import math from test_framework.test_framework import BitcoinTestFramework from test_framework.key import ECKey from test_framework.messages import ( - BIP125_SEQUENCE_NUMBER, + MAX_BIP125_RBF_SEQUENCE, COIN, COutPoint, CTxIn, @@ -87,7 +87,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework): self.log.info('A transaction not in the mempool') fee = Decimal('0.000007') utxo_to_spend = self.wallet.get_utxo(txid=txid_in_block) # use 0.3 BTC UTXO - tx = self.wallet.create_self_transfer(utxo_to_spend=utxo_to_spend, sequence=BIP125_SEQUENCE_NUMBER)['tx'] + tx = self.wallet.create_self_transfer(utxo_to_spend=utxo_to_spend, sequence=MAX_BIP125_RBF_SEQUENCE)['tx'] tx.vout[0].nValue = int((Decimal('0.3') - fee) * COIN) raw_tx_0 = tx.serialize().hex() txid_0 = tx.rehash() @@ -125,7 +125,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework): self.log.info('A transaction that replaces a mempool transaction') 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 + tx.vin[0].nSequence = MAX_BIP125_RBF_SEQUENCE + 1 # Now, opt out of RBF raw_tx_0 = tx.serialize().hex() txid_0 = tx.rehash() self.check_mempool_result( diff --git a/test/functional/mempool_persist.py b/test/functional/mempool_persist.py index 8c9379b90b..58f4c91343 100755 --- a/test/functional/mempool_persist.py +++ b/test/functional/mempool_persist.py @@ -105,6 +105,11 @@ class MempoolPersistTest(BitcoinTestFramework): assert_equal(len(self.nodes[0].p2ps), 0) self.mini_wallet.send_self_transfer(from_node=self.nodes[0]) + # Test persistence of prioritisation for transactions not in the mempool. + # Create a tx and prioritise but don't submit until after the restart. + tx_prioritised_not_submitted = self.mini_wallet.create_self_transfer() + self.nodes[0].prioritisetransaction(txid=tx_prioritised_not_submitted['txid'], fee_delta=9999) + self.log.debug("Stop-start the nodes. Verify that node0 has the transactions in its mempool and node1 does not. Verify that node2 calculates its balance correctly after loading wallet transactions.") self.stop_nodes() # Give this node a head-start, so we can be "extra-sure" that it didn't load anything later @@ -125,6 +130,9 @@ class MempoolPersistTest(BitcoinTestFramework): self.log.debug('Verify all fields are loaded correctly') assert_equal(last_entry, self.nodes[0].getmempoolentry(txid=last_txid)) + self.nodes[0].sendrawtransaction(tx_prioritised_not_submitted['hex']) + entry_prioritised_before_restart = self.nodes[0].getmempoolentry(txid=tx_prioritised_not_submitted['txid']) + assert_equal(entry_prioritised_before_restart['fees']['base'] + Decimal('0.00009999'), entry_prioritised_before_restart['fees']['modified']) # Verify accounting of mempool transactions after restart is correct if self.is_sqlite_compiled(): @@ -143,7 +151,7 @@ class MempoolPersistTest(BitcoinTestFramework): self.stop_nodes() self.start_node(0) assert self.nodes[0].getmempoolinfo()["loaded"] - assert_equal(len(self.nodes[0].getrawmempool()), 6) + assert_equal(len(self.nodes[0].getrawmempool()), 7) mempooldat0 = os.path.join(self.nodes[0].datadir, self.chain, 'mempool.dat') mempooldat1 = os.path.join(self.nodes[1].datadir, self.chain, 'mempool.dat') @@ -153,12 +161,12 @@ class MempoolPersistTest(BitcoinTestFramework): assert os.path.isfile(mempooldat0) assert_equal(result0['filename'], mempooldat0) - self.log.debug("Stop nodes, make node1 use mempool.dat from node0. Verify it has 6 transactions") + self.log.debug("Stop nodes, make node1 use mempool.dat from node0. Verify it has 7 transactions") os.rename(mempooldat0, mempooldat1) self.stop_nodes() self.start_node(1, extra_args=["-persistmempool"]) assert self.nodes[1].getmempoolinfo()["loaded"] - assert_equal(len(self.nodes[1].getrawmempool()), 6) + assert_equal(len(self.nodes[1].getrawmempool()), 7) self.log.debug("Prevent bitcoind from writing mempool.dat to disk. Verify that `savemempool` fails") # to test the exception we are creating a tmp folder called mempool.dat.new diff --git a/test/functional/p2p_segwit.py b/test/functional/p2p_segwit.py index eedb7e6fa1..db6954ccf6 100755 --- a/test/functional/p2p_segwit.py +++ b/test/functional/p2p_segwit.py @@ -16,7 +16,7 @@ from test_framework.blocktools import ( ) from test_framework.key import ECKey from test_framework.messages import ( - BIP125_SEQUENCE_NUMBER, + MAX_BIP125_RBF_SEQUENCE, CBlockHeader, CInv, COutPoint, @@ -589,7 +589,7 @@ class SegWitTest(BitcoinTestFramework): tx.vin = [CTxIn(COutPoint(p2sh_tx.sha256, 0), CScript([witness_script]))] tx.vout = [CTxOut(p2sh_tx.vout[0].nValue - 10000, script_pubkey)] tx.vout.append(CTxOut(8000, script_pubkey)) # Might burn this later - tx.vin[0].nSequence = BIP125_SEQUENCE_NUMBER # Just to have the option to bump this tx from the mempool + tx.vin[0].nSequence = MAX_BIP125_RBF_SEQUENCE # Just to have the option to bump this tx from the mempool tx.rehash() # This is always accepted, since the mempool policy is to consider segwit as always active diff --git a/test/functional/rpc_getblockfrompeer.py b/test/functional/rpc_getblockfrompeer.py index a7628b5591..41e430d87e 100755 --- a/test/functional/rpc_getblockfrompeer.py +++ b/test/functional/rpc_getblockfrompeer.py @@ -54,14 +54,17 @@ class GetBlockFromPeerTest(BitcoinTestFramework): assert_equal(len(peers), 1) peer_0_peer_1_id = peers[0]["id"] - self.log.info("Arguments must be sensible") - assert_raises_rpc_error(-8, "hash must be of length 64 (not 4, for '1234')", self.nodes[0].getblockfrompeer, "1234", 0) + self.log.info("Arguments must be valid") + assert_raises_rpc_error(-8, "hash must be of length 64 (not 4, for '1234')", self.nodes[0].getblockfrompeer, "1234", peer_0_peer_1_id) + assert_raises_rpc_error(-3, "Expected type string, got number", self.nodes[0].getblockfrompeer, 1234, peer_0_peer_1_id) + assert_raises_rpc_error(-3, "Expected type number, got string", self.nodes[0].getblockfrompeer, short_tip, "0") self.log.info("We must already have the header") assert_raises_rpc_error(-1, "Block header missing", self.nodes[0].getblockfrompeer, "00" * 32, 0) self.log.info("Non-existent peer generates error") - assert_raises_rpc_error(-1, "Peer does not exist", self.nodes[0].getblockfrompeer, short_tip, peer_0_peer_1_id + 1) + for peer_id in [-1, peer_0_peer_1_id + 1]: + assert_raises_rpc_error(-1, "Peer does not exist", self.nodes[0].getblockfrompeer, short_tip, peer_id) self.log.info("Fetching from pre-segwit peer generates error") self.nodes[0].add_p2p_connection(P2PInterface(), services=P2P_SERVICES & ~NODE_WITNESS) diff --git a/test/functional/rpc_packages.py b/test/functional/rpc_packages.py index f687849287..9a563cbf5f 100755 --- a/test/functional/rpc_packages.py +++ b/test/functional/rpc_packages.py @@ -10,7 +10,7 @@ import random from test_framework.address import ADDRESS_BCRT1_P2WSH_OP_TRUE from test_framework.test_framework import BitcoinTestFramework from test_framework.messages import ( - BIP125_SEQUENCE_NUMBER, + MAX_BIP125_RBF_SEQUENCE, COIN, CTxInWitness, tx_from_hex, @@ -273,7 +273,7 @@ class RPCPackagesTest(BitcoinTestFramework): def test_rbf(self): node = self.nodes[0] coin = self.coins.pop() - inputs = [{"txid": coin["txid"], "vout": 0, "sequence": BIP125_SEQUENCE_NUMBER}] + inputs = [{"txid": coin["txid"], "vout": 0, "sequence": MAX_BIP125_RBF_SEQUENCE}] fee = Decimal('0.00125000') output = {node.get_deterministic_priv_key().address: 50 - fee} raw_replaceable_tx = node.createrawtransaction(inputs, output) diff --git a/test/functional/rpc_psbt.py b/test/functional/rpc_psbt.py index d2a888fd31..264b2ac32d 100755 --- a/test/functional/rpc_psbt.py +++ b/test/functional/rpc_psbt.py @@ -11,8 +11,9 @@ from itertools import product from test_framework.descriptors import descsum_create from test_framework.key import ECKey, H_POINT from test_framework.messages import ( - ser_compact_size, + MAX_BIP125_RBF_SEQUENCE, WITNESS_SCALE_FACTOR, + ser_compact_size, ) from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( @@ -27,7 +28,6 @@ from test_framework.wallet_util import bytes_to_wif import json import os -MAX_BIP125_RBF_SEQUENCE = 0xfffffffd # Create one-input, one-output, no-fee transaction: class PSBTTest(BitcoinTestFramework): diff --git a/test/functional/rpc_rawtransaction.py b/test/functional/rpc_rawtransaction.py index 26a5da85b7..bbf1f022d7 100755 --- a/test/functional/rpc_rawtransaction.py +++ b/test/functional/rpc_rawtransaction.py @@ -17,7 +17,7 @@ from decimal import Decimal from test_framework.blocktools import COINBASE_MATURITY from test_framework.messages import ( - BIP125_SEQUENCE_NUMBER, + MAX_BIP125_RBF_SEQUENCE, CTransaction, tx_from_hex, ) @@ -223,7 +223,7 @@ class RawTransactionsTest(BitcoinTestFramework): # Test `createrawtransaction` mismatch between sequence number(s) and `replaceable` option assert_raises_rpc_error(-8, "Invalid parameter combination: Sequence number(s) contradict replaceable option", - self.nodes[0].createrawtransaction, [{'txid': TXID, 'vout': 0, 'sequence': BIP125_SEQUENCE_NUMBER+1}], {}, 0, True) + self.nodes[0].createrawtransaction, [{'txid': TXID, 'vout': 0, 'sequence': MAX_BIP125_RBF_SEQUENCE+1}], {}, 0, True) # Test `createrawtransaction` invalid `locktime` assert_raises_rpc_error(-3, "Expected type number", self.nodes[0].createrawtransaction, [], {}, 'foo') diff --git a/test/functional/rpc_signrawtransactionwithkey.py b/test/functional/rpc_signrawtransactionwithkey.py new file mode 100755 index 0000000000..0da5a99fdb --- /dev/null +++ b/test/functional/rpc_signrawtransactionwithkey.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2022 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +"""Test transaction signing using the signrawtransactionwithkey RPC.""" + +from test_framework.blocktools import ( + COINBASE_MATURITY, +) +from test_framework.address import ( + script_to_p2sh, +) +from test_framework.key import ECKey +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + find_vout_for_address, +) +from test_framework.script_util import ( + key_to_p2pk_script, + key_to_p2pkh_script, + script_to_p2sh_p2wsh_script, + script_to_p2wsh_script, +) +from test_framework.wallet_util import ( + bytes_to_wif, +) + +from decimal import ( + Decimal, +) +from test_framework.wallet import ( + getnewdestination, +) + + +class SignRawTransactionWithKeyTest(BitcoinTestFramework): + def set_test_params(self): + self.setup_clean_chain = True + self.num_nodes = 2 + + def send_to_address(self, addr, amount): + input = {"txid": self.nodes[0].getblock(self.block_hash[self.blk_idx])["tx"][0], "vout": 0} + output = {addr: amount} + self.blk_idx += 1 + rawtx = self.nodes[0].createrawtransaction([input], output) + txid = self.nodes[0].sendrawtransaction(self.nodes[0].signrawtransactionwithkey(rawtx, [self.nodes[0].get_deterministic_priv_key().key])["hex"], 0) + return txid + + def successful_signing_test(self): + """Create and sign a valid raw transaction with one input. + + Expected results: + + 1) The transaction has a complete set of signatures + 2) No script verification error occurred""" + self.log.info("Test valid raw transaction with one input") + privKeys = ['cUeKHd5orzT3mz8P9pxyREHfsWtVfgsfDjiZZBcjUBAaGk1BTj7N', 'cVKpPfVKSJxKqVpE9awvXNWuLHCa5j5tiE7K6zbUSptFpTEtiFrA'] + + inputs = [ + # Valid pay-to-pubkey scripts + {'txid': '9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71', 'vout': 0, + 'scriptPubKey': '76a91460baa0f494b38ce3c940dea67f3804dc52d1fb9488ac'}, + {'txid': '83a4f6a6b73660e13ee6cb3c6063fa3759c50c9b7521d0536022961898f4fb02', 'vout': 0, + 'scriptPubKey': '76a914669b857c03a5ed269d5d85a1ffac9ed5d663072788ac'}, + ] + + outputs = {'mpLQjfK79b7CCV4VMJWEWAj5Mpx8Up5zxB': 0.1} + + rawTx = self.nodes[0].createrawtransaction(inputs, outputs) + rawTxSigned = self.nodes[0].signrawtransactionwithkey(rawTx, privKeys, inputs) + + # 1) The transaction has a complete set of signatures + assert rawTxSigned['complete'] + + # 2) No script verification error occurred + assert 'errors' not in rawTxSigned + + def witness_script_test(self): + self.log.info("Test signing transaction to P2SH-P2WSH addresses without wallet") + # Create a new P2SH-P2WSH 1-of-1 multisig address: + eckey = ECKey() + eckey.generate() + embedded_privkey = bytes_to_wif(eckey.get_bytes()) + embedded_pubkey = eckey.get_pubkey().get_bytes().hex() + p2sh_p2wsh_address = self.nodes[1].createmultisig(1, [embedded_pubkey], "p2sh-segwit") + # send transaction to P2SH-P2WSH 1-of-1 multisig address + self.block_hash = self.generate(self.nodes[0], COINBASE_MATURITY + 1) + self.blk_idx = 0 + self.send_to_address(p2sh_p2wsh_address["address"], 49.999) + self.generate(self.nodes[0], 1) + # Get the UTXO info from scantxoutset + unspent_output = self.nodes[1].scantxoutset('start', [p2sh_p2wsh_address['descriptor']])['unspents'][0] + spk = script_to_p2sh_p2wsh_script(p2sh_p2wsh_address['redeemScript']).hex() + unspent_output['witnessScript'] = p2sh_p2wsh_address['redeemScript'] + unspent_output['redeemScript'] = script_to_p2wsh_script(unspent_output['witnessScript']).hex() + assert_equal(spk, unspent_output['scriptPubKey']) + # Now create and sign a transaction spending that output on node[0], which doesn't know the scripts or keys + spending_tx = self.nodes[0].createrawtransaction([unspent_output], {getnewdestination()[2]: Decimal("49.998")}) + spending_tx_signed = self.nodes[0].signrawtransactionwithkey(spending_tx, [embedded_privkey], [unspent_output]) + # Check the signing completed successfully + assert 'complete' in spending_tx_signed + assert_equal(spending_tx_signed['complete'], True) + + # Now test with P2PKH and P2PK scripts as the witnessScript + for tx_type in ['P2PKH', 'P2PK']: # these tests are order-independent + self.verify_txn_with_witness_script(tx_type) + + def verify_txn_with_witness_script(self, tx_type): + self.log.info("Test with a {} script as the witnessScript".format(tx_type)) + eckey = ECKey() + eckey.generate() + embedded_privkey = bytes_to_wif(eckey.get_bytes()) + embedded_pubkey = eckey.get_pubkey().get_bytes().hex() + witness_script = { + 'P2PKH': key_to_p2pkh_script(embedded_pubkey).hex(), + 'P2PK': key_to_p2pk_script(embedded_pubkey).hex() + }.get(tx_type, "Invalid tx_type") + redeem_script = script_to_p2wsh_script(witness_script).hex() + addr = script_to_p2sh(redeem_script) + script_pub_key = self.nodes[1].validateaddress(addr)['scriptPubKey'] + # Fund that address + txid = self.send_to_address(addr, 10) + vout = find_vout_for_address(self.nodes[0], txid, addr) + self.generate(self.nodes[0], 1) + # Now create and sign a transaction spending that output on node[0], which doesn't know the scripts or keys + spending_tx = self.nodes[0].createrawtransaction([{'txid': txid, 'vout': vout}], {getnewdestination()[2]: Decimal("9.999")}) + spending_tx_signed = self.nodes[0].signrawtransactionwithkey(spending_tx, [embedded_privkey], [{'txid': txid, 'vout': vout, 'scriptPubKey': script_pub_key, 'redeemScript': redeem_script, 'witnessScript': witness_script, 'amount': 10}]) + # Check the signing completed successfully + assert 'complete' in spending_tx_signed + assert_equal(spending_tx_signed['complete'], True) + self.nodes[0].sendrawtransaction(spending_tx_signed['hex']) + + def run_test(self): + self.successful_signing_test() + self.witness_script_test() + + +if __name__ == '__main__': + SignRawTransactionWithKeyTest().main() diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py index aae44c0ac0..e6d9f9ae3a 100755 --- a/test/functional/test_framework/messages.py +++ b/test/functional/test_framework/messages.py @@ -39,7 +39,7 @@ MAX_BLOOM_HASH_FUNCS = 50 COIN = 100000000 # 1 btc in satoshis MAX_MONEY = 21000000 * COIN -BIP125_SEQUENCE_NUMBER = 0xfffffffd # Sequence number that is rbf-opt-in (BIP 125) and csv-opt-out (BIP 68) +MAX_BIP125_RBF_SEQUENCE = 0xfffffffd # Sequence number that is rbf-opt-in (BIP 125) and csv-opt-out (BIP 68) SEQUENCE_FINAL = 0xffffffff # Sequence number that disables nLockTime if set for every input of a tx MAX_PROTOCOL_MESSAGE_LENGTH = 4000000 # Maximum length of incoming protocol messages diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index 85dfa20a5a..c5a69afa6e 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -182,8 +182,9 @@ BASE_SCRIPTS = [ 'rpc_whitelist.py', 'feature_proxy.py', 'feature_syscall_sandbox.py', - 'rpc_signrawtransaction.py --legacy-wallet', - 'rpc_signrawtransaction.py --descriptors', + 'wallet_signrawtransactionwithwallet.py --legacy-wallet', + 'wallet_signrawtransactionwithwallet.py --descriptors', + 'rpc_signrawtransactionwithkey.py', 'rpc_rawtransaction.py --legacy-wallet', 'wallet_groups.py --legacy-wallet', 'wallet_transactiontime_rescan.py --descriptors', diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py index 3b23ee8e94..9a481b290b 100755 --- a/test/functional/wallet_bumpfee.py +++ b/test/functional/wallet_bumpfee.py @@ -23,7 +23,7 @@ from test_framework.blocktools import ( send_to_witness, ) from test_framework.messages import ( - BIP125_SEQUENCE_NUMBER, + MAX_BIP125_RBF_SEQUENCE, ) from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( @@ -212,7 +212,7 @@ def test_segwit_bumpfee_succeeds(self, rbf_node, dest_address): rbfraw = rbf_node.createrawtransaction([{ 'txid': segwitid, 'vout': 0, - "sequence": BIP125_SEQUENCE_NUMBER + "sequence": MAX_BIP125_RBF_SEQUENCE }], {dest_address: Decimal("0.0005"), rbf_node.getrawchangeaddress(): Decimal("0.0003")}) rbfsigned = rbf_node.signrawtransactionwithwallet(rbfraw) @@ -243,7 +243,7 @@ def test_notmine_bumpfee_fails(self, rbf_node, peer_node, dest_address): "txid": utxo["txid"], "vout": utxo["vout"], "address": utxo["address"], - "sequence": BIP125_SEQUENCE_NUMBER + "sequence": MAX_BIP125_RBF_SEQUENCE } for utxo in utxos] output_val = sum(utxo["amount"] for utxo in utxos) - fee rawtx = rbf_node.createrawtransaction(inputs, {dest_address: output_val}) @@ -578,7 +578,7 @@ def test_change_script_match(self, rbf_node, dest_address): def spend_one_input(node, dest_address, change_size=Decimal("0.00049000")): tx_input = dict( - sequence=BIP125_SEQUENCE_NUMBER, **next(u for u in node.listunspent() if u["amount"] == Decimal("0.00100000"))) + sequence=MAX_BIP125_RBF_SEQUENCE, **next(u for u in node.listunspent() if u["amount"] == Decimal("0.00100000"))) destinations = {dest_address: Decimal("0.00050000")} if change_size > 0: destinations[node.getrawchangeaddress()] = change_size diff --git a/test/functional/wallet_coinbase_category.py b/test/functional/wallet_coinbase_category.py index 5a6b6cee59..c2a8e612cf 100755 --- a/test/functional/wallet_coinbase_category.py +++ b/test/functional/wallet_coinbase_category.py @@ -15,6 +15,7 @@ from test_framework.util import ( class CoinbaseCategoryTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 + self.setup_clean_chain = True def skip_test_if_missing_module(self): self.skip_if_no_wallet() diff --git a/test/functional/wallet_listsinceblock.py b/test/functional/wallet_listsinceblock.py index fc06565983..1f3a276d9c 100755 --- a/test/functional/wallet_listsinceblock.py +++ b/test/functional/wallet_listsinceblock.py @@ -8,7 +8,7 @@ from test_framework.address import key_to_p2wpkh from test_framework.blocktools import COINBASE_MATURITY from test_framework.key import ECKey from test_framework.test_framework import BitcoinTestFramework -from test_framework.messages import BIP125_SEQUENCE_NUMBER +from test_framework.messages import MAX_BIP125_RBF_SEQUENCE from test_framework.util import ( assert_array_result, assert_equal, @@ -346,7 +346,7 @@ class ListSinceBlockTest(BitcoinTestFramework): dest_address = spending_node.getnewaddress() tx_input = dict( - sequence=BIP125_SEQUENCE_NUMBER, **next(u for u in spending_node.listunspent())) + sequence=MAX_BIP125_RBF_SEQUENCE, **next(u for u in spending_node.listunspent())) rawtx = spending_node.createrawtransaction( [tx_input], {dest_address: tx_input["amount"] - Decimal("0.00051000"), spending_node.getrawchangeaddress(): Decimal("0.00050000")}) diff --git a/test/functional/rpc_signrawtransaction.py b/test/functional/wallet_signrawtransactionwithwallet.py index 8da2cfa72b..6b30386b7e 100755 --- a/test/functional/rpc_signrawtransaction.py +++ b/test/functional/wallet_signrawtransactionwithwallet.py @@ -2,16 +2,14 @@ # Copyright (c) 2015-2021 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -"""Test transaction signing using the signrawtransaction* RPCs.""" +"""Test transaction signing using the signrawtransactionwithwallet RPC.""" from test_framework.blocktools import ( COINBASE_MATURITY, ) from test_framework.address import ( - script_to_p2sh, script_to_p2wsh, ) -from test_framework.key import ECKey from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, @@ -29,20 +27,13 @@ from test_framework.script import ( OP_DROP, OP_TRUE, ) -from test_framework.script_util import ( - key_to_p2pk_script, - key_to_p2pkh_script, - script_to_p2sh_p2wsh_script, - script_to_p2wsh_script, -) -from test_framework.wallet_util import bytes_to_wif from decimal import ( Decimal, getcontext, ) -class SignRawTransactionsTest(BitcoinTestFramework): +class SignRawTransactionWithWalletTest(BitcoinTestFramework): def set_test_params(self): self.setup_clean_chain = True self.num_nodes = 2 @@ -50,35 +41,6 @@ class SignRawTransactionsTest(BitcoinTestFramework): def skip_test_if_missing_module(self): self.skip_if_no_wallet() - def successful_signing_test(self): - """Create and sign a valid raw transaction with one input. - - Expected results: - - 1) The transaction has a complete set of signatures - 2) No script verification error occurred""" - self.log.info("Test valid raw transaction with one input") - privKeys = ['cUeKHd5orzT3mz8P9pxyREHfsWtVfgsfDjiZZBcjUBAaGk1BTj7N', 'cVKpPfVKSJxKqVpE9awvXNWuLHCa5j5tiE7K6zbUSptFpTEtiFrA'] - - inputs = [ - # Valid pay-to-pubkey scripts - {'txid': '9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71', 'vout': 0, - 'scriptPubKey': '76a91460baa0f494b38ce3c940dea67f3804dc52d1fb9488ac'}, - {'txid': '83a4f6a6b73660e13ee6cb3c6063fa3759c50c9b7521d0536022961898f4fb02', 'vout': 0, - 'scriptPubKey': '76a914669b857c03a5ed269d5d85a1ffac9ed5d663072788ac'}, - ] - - outputs = {'mpLQjfK79b7CCV4VMJWEWAj5Mpx8Up5zxB': 0.1} - - rawTx = self.nodes[0].createrawtransaction(inputs, outputs) - rawTxSigned = self.nodes[0].signrawtransactionwithkey(rawTx, privKeys, inputs) - - # 1) The transaction has a complete set of signatures - assert rawTxSigned['complete'] - - # 2) No script verification error occurred - assert 'errors' not in rawTxSigned - def test_with_lock_outputs(self): self.log.info("Test correct error reporting when trying to sign a locked output") self.nodes[0].encryptwallet("password") @@ -191,60 +153,6 @@ class SignRawTransactionsTest(BitcoinTestFramework): assert_equal(signedtx["hex"], signedtx2["hex"]) self.nodes[0].walletlock() - def witness_script_test(self): - self.log.info("Test signing transaction to P2SH-P2WSH addresses without wallet") - # Create a new P2SH-P2WSH 1-of-1 multisig address: - eckey = ECKey() - eckey.generate() - embedded_privkey = bytes_to_wif(eckey.get_bytes()) - embedded_pubkey = eckey.get_pubkey().get_bytes().hex() - p2sh_p2wsh_address = self.nodes[1].createmultisig(1, [embedded_pubkey], "p2sh-segwit") - # send transaction to P2SH-P2WSH 1-of-1 multisig address - self.generate(self.nodes[0], COINBASE_MATURITY + 1) - self.nodes[0].sendtoaddress(p2sh_p2wsh_address["address"], 49.999) - self.generate(self.nodes[0], 1) - # Get the UTXO info from scantxoutset - unspent_output = self.nodes[1].scantxoutset('start', [p2sh_p2wsh_address['descriptor']])['unspents'][0] - spk = script_to_p2sh_p2wsh_script(p2sh_p2wsh_address['redeemScript']).hex() - unspent_output['witnessScript'] = p2sh_p2wsh_address['redeemScript'] - unspent_output['redeemScript'] = script_to_p2wsh_script(unspent_output['witnessScript']).hex() - assert_equal(spk, unspent_output['scriptPubKey']) - # Now create and sign a transaction spending that output on node[0], which doesn't know the scripts or keys - spending_tx = self.nodes[0].createrawtransaction([unspent_output], {self.nodes[1].get_wallet_rpc(self.default_wallet_name).getnewaddress(): Decimal("49.998")}) - spending_tx_signed = self.nodes[0].signrawtransactionwithkey(spending_tx, [embedded_privkey], [unspent_output]) - # Check the signing completed successfully - assert 'complete' in spending_tx_signed - assert_equal(spending_tx_signed['complete'], True) - - # Now test with P2PKH and P2PK scripts as the witnessScript - for tx_type in ['P2PKH', 'P2PK']: # these tests are order-independent - self.verify_txn_with_witness_script(tx_type) - - def verify_txn_with_witness_script(self, tx_type): - self.log.info("Test with a {} script as the witnessScript".format(tx_type)) - eckey = ECKey() - eckey.generate() - embedded_privkey = bytes_to_wif(eckey.get_bytes()) - embedded_pubkey = eckey.get_pubkey().get_bytes().hex() - witness_script = { - 'P2PKH': key_to_p2pkh_script(embedded_pubkey).hex(), - 'P2PK': key_to_p2pk_script(embedded_pubkey).hex() - }.get(tx_type, "Invalid tx_type") - redeem_script = script_to_p2wsh_script(witness_script).hex() - addr = script_to_p2sh(redeem_script) - script_pub_key = self.nodes[1].validateaddress(addr)['scriptPubKey'] - # Fund that address - txid = self.nodes[0].sendtoaddress(addr, 10) - vout = find_vout_for_address(self.nodes[0], txid, addr) - self.generate(self.nodes[0], 1) - # Now create and sign a transaction spending that output on node[0], which doesn't know the scripts or keys - spending_tx = self.nodes[0].createrawtransaction([{'txid': txid, 'vout': vout}], {self.nodes[1].getnewaddress(): Decimal("9.999")}) - spending_tx_signed = self.nodes[0].signrawtransactionwithkey(spending_tx, [embedded_privkey], [{'txid': txid, 'vout': vout, 'scriptPubKey': script_pub_key, 'redeemScript': redeem_script, 'witnessScript': witness_script, 'amount': 10}]) - # Check the signing completed successfully - assert 'complete' in spending_tx_signed - assert_equal(spending_tx_signed['complete'], True) - self.nodes[0].sendrawtransaction(spending_tx_signed['hex']) - def OP_1NEGATE_test(self): self.log.info("Test OP_1NEGATE (0x4f) satisfies BIP62 minimal push standardness rule") hex_str = ( @@ -385,9 +293,7 @@ class SignRawTransactionsTest(BitcoinTestFramework): ]) def run_test(self): - self.successful_signing_test() self.script_verification_error_test() - self.witness_script_test() self.OP_1NEGATE_test() self.test_with_lock_outputs() self.test_fully_signed_tx() @@ -397,4 +303,4 @@ class SignRawTransactionsTest(BitcoinTestFramework): if __name__ == '__main__': - SignRawTransactionsTest().main() + SignRawTransactionWithWalletTest().main() |