rpc_generate.py
1 #!/usr/bin/env python3 2 # Copyright (c) 2020-2022 The Bitcoin Core developers 3 # Distributed under the MIT software license, see the accompanying 4 # file COPYING or http://www.opensource.org/licenses/mit-license.php. 5 """Test generate* RPCs.""" 6 7 from test_framework.test_framework import BitcoinTestFramework 8 from test_framework.wallet import MiniWallet 9 from test_framework.util import ( 10 assert_equal, 11 assert_raises_rpc_error, 12 ) 13 14 15 class RPCGenerateTest(BitcoinTestFramework): 16 def set_test_params(self): 17 self.num_nodes = 1 18 19 def run_test(self): 20 self.test_generatetoaddress() 21 self.test_generate() 22 self.test_generateblock() 23 24 def test_generatetoaddress(self): 25 self.generatetoaddress(self.nodes[0], 1, 'mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ') 26 assert_raises_rpc_error(-5, "Invalid address", self.generatetoaddress, self.nodes[0], 1, '3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy') 27 28 def test_generateblock(self): 29 node = self.nodes[0] 30 miniwallet = MiniWallet(node) 31 32 self.log.info('Mine an empty block to address and return the hex') 33 address = miniwallet.get_address() 34 generated_block = self.generateblock(node, output=address, transactions=[], submit=False) 35 node.submitblock(hexdata=generated_block['hex']) 36 assert_equal(generated_block['hash'], node.getbestblockhash()) 37 38 self.log.info('Generate an empty block to address') 39 hash = self.generateblock(node, output=address, transactions=[])['hash'] 40 block = node.getblock(blockhash=hash, verbose=2) 41 assert_equal(len(block['tx']), 1) 42 assert_equal(block['tx'][0]['vout'][0]['scriptPubKey']['address'], address) 43 44 self.log.info('Generate an empty block to a descriptor') 45 hash = self.generateblock(node, 'addr(' + address + ')', [])['hash'] 46 block = node.getblock(blockhash=hash, verbosity=2) 47 assert_equal(len(block['tx']), 1) 48 assert_equal(block['tx'][0]['vout'][0]['scriptPubKey']['address'], address) 49 50 self.log.info('Generate an empty block to a combo descriptor with compressed pubkey') 51 combo_key = '0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798' 52 combo_address = 'bcrt1qw508d6qejxtdg4y5r3zarvary0c5xw7kygt080' 53 hash = self.generateblock(node, 'combo(' + combo_key + ')', [])['hash'] 54 block = node.getblock(hash, 2) 55 assert_equal(len(block['tx']), 1) 56 assert_equal(block['tx'][0]['vout'][0]['scriptPubKey']['address'], combo_address) 57 58 self.log.info('Generate an empty block to a combo descriptor with uncompressed pubkey') 59 combo_key = '0408ef68c46d20596cc3f6ddf7c8794f71913add807f1dc55949fa805d764d191c0b7ce6894c126fce0babc6663042f3dde9b0cf76467ea315514e5a6731149c67' 60 combo_address = 'mkc9STceoCcjoXEXe6cm66iJbmjM6zR9B2' 61 hash = self.generateblock(node, 'combo(' + combo_key + ')', [])['hash'] 62 block = node.getblock(hash, 2) 63 assert_equal(len(block['tx']), 1) 64 assert_equal(block['tx'][0]['vout'][0]['scriptPubKey']['address'], combo_address) 65 66 # Generate some extra mempool transactions to verify they don't get mined 67 for _ in range(10): 68 miniwallet.send_self_transfer(from_node=node) 69 70 self.log.info('Generate block with txid') 71 txid = miniwallet.send_self_transfer(from_node=node)['txid'] 72 hash = self.generateblock(node, address, [txid])['hash'] 73 block = node.getblock(hash, 1) 74 assert_equal(len(block['tx']), 2) 75 assert_equal(block['tx'][1], txid) 76 77 self.log.info('Generate block with raw tx') 78 rawtx = miniwallet.create_self_transfer()['hex'] 79 hash = self.generateblock(node, address, [rawtx])['hash'] 80 81 block = node.getblock(hash, 1) 82 assert_equal(len(block['tx']), 2) 83 txid = block['tx'][1] 84 assert_equal(node.getrawtransaction(txid=txid, verbose=False, blockhash=hash), rawtx) 85 86 self.log.info('Fail to generate block with out of order txs') 87 txid1 = miniwallet.send_self_transfer(from_node=node)['txid'] 88 utxo1 = miniwallet.get_utxo(txid=txid1) 89 rawtx2 = miniwallet.create_self_transfer(utxo_to_spend=utxo1)['hex'] 90 assert_raises_rpc_error(-25, 'TestBlockValidity failed: bad-txns-inputs-missingorspent', self.generateblock, node, address, [rawtx2, txid1]) 91 92 self.log.info('Fail to generate block with txid not in mempool') 93 missing_txid = '0000000000000000000000000000000000000000000000000000000000000000' 94 assert_raises_rpc_error(-5, 'Transaction ' + missing_txid + ' not in mempool.', self.generateblock, node, address, [missing_txid]) 95 96 self.log.info('Fail to generate block with invalid raw tx') 97 invalid_raw_tx = '0000' 98 assert_raises_rpc_error(-22, 'Transaction decode failed for ' + invalid_raw_tx, self.generateblock, node, address, [invalid_raw_tx]) 99 100 self.log.info('Fail to generate block with invalid address/descriptor') 101 assert_raises_rpc_error(-5, 'Invalid address or descriptor', self.generateblock, node, '1234', []) 102 103 self.log.info('Fail to generate block with a ranged descriptor') 104 ranged_descriptor = 'pkh(tpubD6NzVbkrYhZ4XgiXtGrdW5XDAPFCL9h7we1vwNCpn8tGbBcgfVYjXyhWo4E1xkh56hjod1RhGjxbaTLV3X4FyWuejifB9jusQ46QzG87VKp/0/*)' 105 assert_raises_rpc_error(-8, 'Ranged descriptor not accepted. Maybe pass through deriveaddresses first?', self.generateblock, node, ranged_descriptor, []) 106 107 self.log.info('Fail to generate block with a descriptor missing a private key') 108 child_descriptor = 'pkh(tpubD6NzVbkrYhZ4XgiXtGrdW5XDAPFCL9h7we1vwNCpn8tGbBcgfVYjXyhWo4E1xkh56hjod1RhGjxbaTLV3X4FyWuejifB9jusQ46QzG87VKp/0\'/0)' 109 assert_raises_rpc_error(-5, 'Cannot derive script without private keys', self.generateblock, node, child_descriptor, []) 110 111 def test_generate(self): 112 message = ( 113 "generate\n\n" 114 "has been replaced by the -generate " 115 "cli option. Refer to -help for more information.\n" 116 ) 117 118 self.log.info("Test rpc generate raises with message to use cli option") 119 assert_raises_rpc_error(-32601, message, self.nodes[0].rpc.generate) 120 121 self.log.info("Test rpc generate help prints message to use cli option") 122 assert_equal(message, self.nodes[0].help("generate")) 123 124 self.log.info("Test rpc generate is a hidden command not discoverable in general help") 125 assert message not in self.nodes[0].help() 126 127 128 if __name__ == "__main__": 129 RPCGenerateTest().main()