(self)
| 98 | parser.add_argument("--skipreorg", action='store_true', dest="skip_reorg", help="Skip the large re-org test", default=False) |
| 99 | |
| 100 | def run_test(self): |
| 101 | node = self.nodes[0] # convenience reference to the node |
| 102 | |
| 103 | self.bootstrap_p2p() # Add one p2p connection to the node |
| 104 | |
| 105 | self.block_heights = {} |
| 106 | self.coinbase_key, self.coinbase_pubkey = generate_keypair() |
| 107 | self.tip = None |
| 108 | self.blocks = {} |
| 109 | self.genesis_hash = int(self.nodes[0].getbestblockhash(), 16) |
| 110 | self.block_heights[self.genesis_hash] = 0 |
| 111 | self.spendable_outputs = [] |
| 112 | |
| 113 | # Create a new block |
| 114 | b_dup_cb = self.next_block('dup_cb') |
| 115 | b_dup_cb.vtx[0].vin[0].scriptSig = DUPLICATE_COINBASE_SCRIPT_SIG |
| 116 | duplicate_tx = b_dup_cb.vtx[0] |
| 117 | b_dup_cb = self.update_block('dup_cb', []) |
| 118 | self.send_blocks([b_dup_cb]) |
| 119 | |
| 120 | # Add gigantic boundary scripts that respect all other limits |
| 121 | max_valid_script = CScript([b'\x01' * MAX_SCRIPT_ELEMENT_SIZE] * 19 + [b'\x01' * 62]) |
| 122 | assert_equal(len(max_valid_script), MAX_SCRIPT_SIZE) |
| 123 | min_invalid_script = CScript([b'\x01' * MAX_SCRIPT_ELEMENT_SIZE] * 19 + [b'\x01' * 63]) |
| 124 | assert_equal(len(min_invalid_script), MAX_SCRIPT_SIZE + 1) |
| 125 | |
| 126 | b0 = self.next_block(0, additional_output_scripts=[max_valid_script, min_invalid_script]) |
| 127 | self.save_spendable_output() |
| 128 | self.send_blocks([b0]) |
| 129 | |
| 130 | # Will test spending once possibly-mature |
| 131 | max_size_spendable_output = CTxIn(COutPoint(b0.vtx[0].txid_int, 1)) |
| 132 | min_size_unspendable_output = CTxIn(COutPoint(b0.vtx[0].txid_int, 2)) |
| 133 | |
| 134 | # These constants chosen specifically to trigger an immature coinbase spend |
| 135 | # at a certain time below. |
| 136 | NUM_BUFFER_BLOCKS_TO_GENERATE = 99 |
| 137 | NUM_OUTPUTS_TO_COLLECT = 33 |
| 138 | |
| 139 | # Allow the block to mature |
| 140 | blocks = [] |
| 141 | for i in range(NUM_BUFFER_BLOCKS_TO_GENERATE): |
| 142 | blocks.append(self.next_block(f"maturitybuffer.{i}")) |
| 143 | self.save_spendable_output() |
| 144 | self.send_blocks(blocks) |
| 145 | |
| 146 | # MAX_SCRIPT_SIZE testing now that coins are mature |
| 147 | tx = CTransaction() |
| 148 | tx.vin.append(max_size_spendable_output) |
| 149 | tx.vout.append(CTxOut(0, CScript([]))) |
| 150 | block = self.generateblock(self.nodes[0], output="raw(55)", transactions=[tx.serialize().hex()]) |
| 151 | assert_equal(block["hash"], self.nodes[0].getbestblockhash()) |
| 152 | self.nodes[0].invalidateblock(block["hash"]) |
| 153 | assert_equal(self.nodes[0].getrawmempool(), []) |
| 154 | |
| 155 | # MAX_SCRIPT_SIZE + 1 wasn't added to the utxo set |
| 156 | tx.vin[0] = min_size_unspendable_output |
| 157 | assert_raises_rpc_error(-25, f'TestBlockValidity failed: bad-txns-inputs-missingorspent, CheckTxInputs: inputs missing/spent in transaction {tx.txid_hex}', self.generateblock, self.nodes[0], output="raw(55)", transactions=[tx.serialize().hex()]) |
nothing calls this directly
no test coverage detected