feature_block.py
1 #!/usr/bin/env python3 2 # Copyright (c) 2015-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 block processing.""" 6 import copy 7 import struct 8 import time 9 10 from test_framework.blocktools import ( 11 create_block, 12 create_coinbase, 13 create_tx_with_script, 14 get_legacy_sigopcount_block, 15 MAX_BLOCK_SIGOPS, 16 ) 17 from test_framework.messages import ( 18 CBlock, 19 COIN, 20 COutPoint, 21 CTransaction, 22 CTxIn, 23 CTxOut, 24 MAX_BLOCK_WEIGHT, 25 SEQUENCE_FINAL, 26 uint256_from_compact, 27 uint256_from_str, 28 ) 29 from test_framework.p2p import P2PDataStore 30 from test_framework.script import ( 31 CScript, 32 MAX_SCRIPT_ELEMENT_SIZE, 33 OP_2DUP, 34 OP_CHECKMULTISIG, 35 OP_CHECKMULTISIGVERIFY, 36 OP_CHECKSIG, 37 OP_CHECKSIGVERIFY, 38 OP_ELSE, 39 OP_ENDIF, 40 OP_DROP, 41 OP_FALSE, 42 OP_IF, 43 OP_INVALIDOPCODE, 44 OP_RETURN, 45 OP_TRUE, 46 sign_input_legacy, 47 ) 48 from test_framework.script_util import ( 49 script_to_p2sh_script, 50 ) 51 from test_framework.test_framework import BitcoinTestFramework 52 from test_framework.util import ( 53 assert_equal, 54 assert_greater_than, 55 ) 56 from test_framework.wallet_util import generate_keypair 57 from data import invalid_txs 58 59 60 # Use this class for tests that require behavior other than normal p2p behavior. 61 # For now, it is used to serialize a bloated varint (b64). 62 class CBrokenBlock(CBlock): 63 def initialize(self, base_block): 64 self.vtx = copy.deepcopy(base_block.vtx) 65 self.hashMerkleRoot = self.calc_merkle_root() 66 67 def serialize(self, with_witness=False): 68 r = b"" 69 r += super(CBlock, self).serialize() 70 r += struct.pack("<BQ", 255, len(self.vtx)) 71 for tx in self.vtx: 72 if with_witness: 73 r += tx.serialize_with_witness() 74 else: 75 r += tx.serialize_without_witness() 76 return r 77 78 def normal_serialize(self): 79 return super().serialize() 80 81 82 DUPLICATE_COINBASE_SCRIPT_SIG = b'\x01\x78' # Valid for block at height 120 83 84 85 class FullBlockTest(BitcoinTestFramework): 86 def set_test_params(self): 87 self.num_nodes = 1 88 self.setup_clean_chain = True 89 self.extra_args = [[ 90 '-acceptnonstdtxn=1', # This is a consensus block test, we don't care about tx policy 91 '-testactivationheight=bip34@2', 92 ]] 93 94 def run_test(self): 95 node = self.nodes[0] # convenience reference to the node 96 97 self.bootstrap_p2p() # Add one p2p connection to the node 98 99 self.block_heights = {} 100 self.coinbase_key, self.coinbase_pubkey = generate_keypair() 101 self.tip = None 102 self.blocks = {} 103 self.genesis_hash = int(self.nodes[0].getbestblockhash(), 16) 104 self.block_heights[self.genesis_hash] = 0 105 self.spendable_outputs = [] 106 107 # Create a new block 108 b_dup_cb = self.next_block('dup_cb') 109 b_dup_cb.vtx[0].vin[0].scriptSig = DUPLICATE_COINBASE_SCRIPT_SIG 110 b_dup_cb.vtx[0].rehash() 111 duplicate_tx = b_dup_cb.vtx[0] 112 b_dup_cb = self.update_block('dup_cb', []) 113 self.send_blocks([b_dup_cb]) 114 115 b0 = self.next_block(0) 116 self.save_spendable_output() 117 self.send_blocks([b0]) 118 119 # These constants chosen specifically to trigger an immature coinbase spend 120 # at a certain time below. 121 NUM_BUFFER_BLOCKS_TO_GENERATE = 99 122 NUM_OUTPUTS_TO_COLLECT = 33 123 124 # Allow the block to mature 125 blocks = [] 126 for i in range(NUM_BUFFER_BLOCKS_TO_GENERATE): 127 blocks.append(self.next_block(f"maturitybuffer.{i}")) 128 self.save_spendable_output() 129 self.send_blocks(blocks) 130 131 # collect spendable outputs now to avoid cluttering the code later on 132 out = [] 133 for _ in range(NUM_OUTPUTS_TO_COLLECT): 134 out.append(self.get_spendable_output()) 135 136 # Start by building a couple of blocks on top (which output is spent is 137 # in parentheses): 138 # genesis -> b1 (0) -> b2 (1) 139 b1 = self.next_block(1, spend=out[0]) 140 self.save_spendable_output() 141 142 b2 = self.next_block(2, spend=out[1]) 143 self.save_spendable_output() 144 145 self.send_blocks([b1, b2], timeout=4) 146 147 # Select a txn with an output eligible for spending. This won't actually be spent, 148 # since we're testing submission of a series of blocks with invalid txns. 149 attempt_spend_tx = out[2] 150 151 # Submit blocks for rejection, each of which contains a single transaction 152 # (aside from coinbase) which should be considered invalid. 153 for TxTemplate in invalid_txs.iter_all_templates(): 154 template = TxTemplate(spend_tx=attempt_spend_tx) 155 156 if template.valid_in_block: 157 continue 158 159 self.log.info(f"Reject block with invalid tx: {TxTemplate.__name__}") 160 blockname = f"for_invalid.{TxTemplate.__name__}" 161 self.next_block(blockname) 162 badtx = template.get_tx() 163 if TxTemplate != invalid_txs.InputMissing: 164 self.sign_tx(badtx, attempt_spend_tx) 165 badtx.rehash() 166 badblock = self.update_block(blockname, [badtx]) 167 self.send_blocks( 168 [badblock], success=False, 169 reject_reason=(template.block_reject_reason or template.reject_reason), 170 reconnect=True, timeout=2) 171 172 self.move_tip(2) 173 174 # Fork like this: 175 # 176 # genesis -> b1 (0) -> b2 (1) 177 # \-> b3 (1) 178 # 179 # Nothing should happen at this point. We saw b2 first so it takes priority. 180 self.log.info("Don't reorg to a chain of the same length") 181 self.move_tip(1) 182 b3 = self.next_block(3, spend=out[1]) 183 txout_b3 = b3.vtx[1] 184 self.send_blocks([b3], False) 185 186 # Now we add another block to make the alternative chain longer. 187 # 188 # genesis -> b1 (0) -> b2 (1) 189 # \-> b3 (1) -> b4 (2) 190 self.log.info("Reorg to a longer chain") 191 b4 = self.next_block(4, spend=out[2]) 192 self.send_blocks([b4]) 193 194 # ... and back to the first chain. 195 # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) 196 # \-> b3 (1) -> b4 (2) 197 self.move_tip(2) 198 b5 = self.next_block(5, spend=out[2]) 199 self.save_spendable_output() 200 self.send_blocks([b5], False) 201 202 self.log.info("Reorg back to the original chain") 203 b6 = self.next_block(6, spend=out[3]) 204 self.send_blocks([b6], True) 205 206 # Try to create a fork that double-spends 207 # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) 208 # \-> b7 (2) -> b8 (4) 209 # \-> b3 (1) -> b4 (2) 210 self.log.info("Reject a chain with a double spend, even if it is longer") 211 self.move_tip(5) 212 b7 = self.next_block(7, spend=out[2]) 213 self.send_blocks([b7], False) 214 215 b8 = self.next_block(8, spend=out[4]) 216 self.send_blocks([b8], False, reconnect=True) 217 218 # Try to create a block that has too much fee 219 # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) 220 # \-> b9 (4) 221 # \-> b3 (1) -> b4 (2) 222 self.log.info("Reject a block where the miner creates too much coinbase reward") 223 self.move_tip(6) 224 b9 = self.next_block(9, spend=out[4], additional_coinbase_value=1) 225 self.send_blocks([b9], success=False, reject_reason='bad-cb-amount', reconnect=True) 226 227 # Create a fork that ends in a block with too much fee (the one that causes the reorg) 228 # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) 229 # \-> b10 (3) -> b11 (4) 230 # \-> b3 (1) -> b4 (2) 231 self.log.info("Reject a chain where the miner creates too much coinbase reward, even if the chain is longer") 232 self.move_tip(5) 233 b10 = self.next_block(10, spend=out[3]) 234 self.send_blocks([b10], False) 235 236 b11 = self.next_block(11, spend=out[4], additional_coinbase_value=1) 237 self.send_blocks([b11], success=False, reject_reason='bad-cb-amount', reconnect=True) 238 239 # Try again, but with a valid fork first 240 # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) 241 # \-> b12 (3) -> b13 (4) -> b14 (5) 242 # \-> b3 (1) -> b4 (2) 243 self.log.info("Reject a chain where the miner creates too much coinbase reward, even if the chain is longer (on a forked chain)") 244 self.move_tip(5) 245 b12 = self.next_block(12, spend=out[3]) 246 self.save_spendable_output() 247 b13 = self.next_block(13, spend=out[4]) 248 self.save_spendable_output() 249 b14 = self.next_block(14, spend=out[5], additional_coinbase_value=1) 250 self.send_blocks([b12, b13, b14], success=False, reject_reason='bad-cb-amount', reconnect=True) 251 252 # New tip should be b13. 253 assert_equal(node.getbestblockhash(), b13.hash) 254 255 # Add a block with MAX_BLOCK_SIGOPS and one with one more sigop 256 # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) 257 # \-> b12 (3) -> b13 (4) -> b15 (5) -> b16 (6) 258 # \-> b3 (1) -> b4 (2) 259 self.log.info("Accept a block with lots of checksigs") 260 lots_of_checksigs = CScript([OP_CHECKSIG] * (MAX_BLOCK_SIGOPS - 1)) 261 self.move_tip(13) 262 b15 = self.next_block(15, spend=out[5], script=lots_of_checksigs) 263 self.save_spendable_output() 264 self.send_blocks([b15], True) 265 266 self.log.info("Reject a block with too many checksigs") 267 too_many_checksigs = CScript([OP_CHECKSIG] * (MAX_BLOCK_SIGOPS)) 268 b16 = self.next_block(16, spend=out[6], script=too_many_checksigs) 269 self.send_blocks([b16], success=False, reject_reason='bad-blk-sigops', reconnect=True) 270 271 # Attempt to spend a transaction created on a different fork 272 # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) 273 # \-> b12 (3) -> b13 (4) -> b15 (5) -> b17 (b3.vtx[1]) 274 # \-> b3 (1) -> b4 (2) 275 self.log.info("Reject a block with a spend from a re-org'ed out tx") 276 self.move_tip(15) 277 b17 = self.next_block(17, spend=txout_b3) 278 self.send_blocks([b17], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True) 279 280 # Attempt to spend a transaction created on a different fork (on a fork this time) 281 # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) 282 # \-> b12 (3) -> b13 (4) -> b15 (5) 283 # \-> b18 (b3.vtx[1]) -> b19 (6) 284 # \-> b3 (1) -> b4 (2) 285 self.log.info("Reject a block with a spend from a re-org'ed out tx (on a forked chain)") 286 self.move_tip(13) 287 b18 = self.next_block(18, spend=txout_b3) 288 self.send_blocks([b18], False) 289 290 b19 = self.next_block(19, spend=out[6]) 291 self.send_blocks([b19], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True) 292 293 # Attempt to spend a coinbase at depth too low 294 # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) 295 # \-> b12 (3) -> b13 (4) -> b15 (5) -> b20 (7) 296 # \-> b3 (1) -> b4 (2) 297 self.log.info("Reject a block spending an immature coinbase.") 298 self.move_tip(15) 299 b20 = self.next_block(20, spend=out[7]) 300 self.send_blocks([b20], success=False, reject_reason='bad-txns-premature-spend-of-coinbase', reconnect=True) 301 302 # Attempt to spend a coinbase at depth too low (on a fork this time) 303 # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) 304 # \-> b12 (3) -> b13 (4) -> b15 (5) 305 # \-> b21 (6) -> b22 (5) 306 # \-> b3 (1) -> b4 (2) 307 self.log.info("Reject a block spending an immature coinbase (on a forked chain)") 308 self.move_tip(13) 309 b21 = self.next_block(21, spend=out[6]) 310 self.send_blocks([b21], False) 311 312 b22 = self.next_block(22, spend=out[5]) 313 self.send_blocks([b22], success=False, reject_reason='bad-txns-premature-spend-of-coinbase', reconnect=True) 314 315 # Create a block on either side of MAX_BLOCK_WEIGHT and make sure its accepted/rejected 316 # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) 317 # \-> b12 (3) -> b13 (4) -> b15 (5) -> b23 (6) 318 # \-> b24 (6) -> b25 (7) 319 # \-> b3 (1) -> b4 (2) 320 self.log.info("Accept a block of weight MAX_BLOCK_WEIGHT") 321 self.move_tip(15) 322 b23 = self.next_block(23, spend=out[6]) 323 tx = CTransaction() 324 script_length = (MAX_BLOCK_WEIGHT - b23.get_weight() - 276) // 4 325 script_output = CScript([b'\x00' * script_length]) 326 tx.vout.append(CTxOut(0, script_output)) 327 tx.vin.append(CTxIn(COutPoint(b23.vtx[1].sha256, 0))) 328 b23 = self.update_block(23, [tx]) 329 # Make sure the math above worked out to produce a max-weighted block 330 assert_equal(b23.get_weight(), MAX_BLOCK_WEIGHT) 331 self.send_blocks([b23], True) 332 self.save_spendable_output() 333 334 self.log.info("Reject a block of weight MAX_BLOCK_WEIGHT + 4") 335 self.move_tip(15) 336 b24 = self.next_block(24, spend=out[6]) 337 script_length = (MAX_BLOCK_WEIGHT - b24.get_weight() - 276) // 4 338 script_output = CScript([b'\x00' * (script_length + 1)]) 339 tx.vout = [CTxOut(0, script_output)] 340 b24 = self.update_block(24, [tx]) 341 assert_equal(b24.get_weight(), MAX_BLOCK_WEIGHT + 1 * 4) 342 self.send_blocks([b24], success=False, reject_reason='bad-blk-length', reconnect=True) 343 344 b25 = self.next_block(25, spend=out[7]) 345 self.send_blocks([b25], False) 346 347 # Create blocks with a coinbase input script size out of range 348 # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) 349 # \-> b12 (3) -> b13 (4) -> b15 (5) -> b23 (6) -> b30 (7) 350 # \-> ... (6) -> ... (7) 351 # \-> b3 (1) -> b4 (2) 352 self.log.info("Reject a block with coinbase input script size out of range") 353 self.move_tip(15) 354 b26 = self.next_block(26, spend=out[6]) 355 b26.vtx[0].vin[0].scriptSig = b'\x00' 356 b26.vtx[0].rehash() 357 # update_block causes the merkle root to get updated, even with no new 358 # transactions, and updates the required state. 359 b26 = self.update_block(26, []) 360 self.send_blocks([b26], success=False, reject_reason='bad-cb-length', reconnect=True) 361 362 # Extend the b26 chain to make sure bitcoind isn't accepting b26 363 b27 = self.next_block(27, spend=out[7]) 364 self.send_blocks([b27], False) 365 366 # Now try a too-large-coinbase script 367 self.move_tip(15) 368 b28 = self.next_block(28, spend=out[6]) 369 b28.vtx[0].vin[0].scriptSig = b'\x00' * 101 370 b28.vtx[0].rehash() 371 b28 = self.update_block(28, []) 372 self.send_blocks([b28], success=False, reject_reason='bad-cb-length', reconnect=True) 373 374 # Extend the b28 chain to make sure bitcoind isn't accepting b28 375 b29 = self.next_block(29, spend=out[7]) 376 self.send_blocks([b29], False) 377 378 # b30 has a max-sized coinbase scriptSig. 379 self.move_tip(23) 380 b30 = self.next_block(30) 381 b30.vtx[0].vin[0].scriptSig = bytes(b30.vtx[0].vin[0].scriptSig) # Convert CScript to raw bytes 382 b30.vtx[0].vin[0].scriptSig += b'\x00' * (100 - len(b30.vtx[0].vin[0].scriptSig)) # Fill with 0s 383 assert_equal(len(b30.vtx[0].vin[0].scriptSig), 100) 384 b30.vtx[0].rehash() 385 b30 = self.update_block(30, []) 386 self.send_blocks([b30], True) 387 self.save_spendable_output() 388 389 # b31 - b35 - check sigops of OP_CHECKMULTISIG / OP_CHECKMULTISIGVERIFY / OP_CHECKSIGVERIFY 390 # 391 # genesis -> ... -> b30 (7) -> b31 (8) -> b33 (9) -> b35 (10) 392 # \-> b36 (11) 393 # \-> b34 (10) 394 # \-> b32 (9) 395 # 396 397 # MULTISIG: each op code counts as 20 sigops. To create the edge case, pack another 19 sigops at the end. 398 self.log.info("Accept a block with the max number of OP_CHECKMULTISIG sigops") 399 lots_of_multisigs = CScript([OP_CHECKMULTISIG] * ((MAX_BLOCK_SIGOPS - 1) // 20) + [OP_CHECKSIG] * 19) 400 b31 = self.next_block(31, spend=out[8], script=lots_of_multisigs) 401 assert_equal(get_legacy_sigopcount_block(b31), MAX_BLOCK_SIGOPS) 402 self.send_blocks([b31], True) 403 self.save_spendable_output() 404 405 # this goes over the limit because the coinbase has one sigop 406 self.log.info("Reject a block with too many OP_CHECKMULTISIG sigops") 407 too_many_multisigs = CScript([OP_CHECKMULTISIG] * (MAX_BLOCK_SIGOPS // 20)) 408 b32 = self.next_block(32, spend=out[9], script=too_many_multisigs) 409 assert_equal(get_legacy_sigopcount_block(b32), MAX_BLOCK_SIGOPS + 1) 410 self.send_blocks([b32], success=False, reject_reason='bad-blk-sigops', reconnect=True) 411 412 # CHECKMULTISIGVERIFY 413 self.log.info("Accept a block with the max number of OP_CHECKMULTISIGVERIFY sigops") 414 self.move_tip(31) 415 lots_of_multisigs = CScript([OP_CHECKMULTISIGVERIFY] * ((MAX_BLOCK_SIGOPS - 1) // 20) + [OP_CHECKSIG] * 19) 416 b33 = self.next_block(33, spend=out[9], script=lots_of_multisigs) 417 self.send_blocks([b33], True) 418 self.save_spendable_output() 419 420 self.log.info("Reject a block with too many OP_CHECKMULTISIGVERIFY sigops") 421 too_many_multisigs = CScript([OP_CHECKMULTISIGVERIFY] * (MAX_BLOCK_SIGOPS // 20)) 422 b34 = self.next_block(34, spend=out[10], script=too_many_multisigs) 423 self.send_blocks([b34], success=False, reject_reason='bad-blk-sigops', reconnect=True) 424 425 # CHECKSIGVERIFY 426 self.log.info("Accept a block with the max number of OP_CHECKSIGVERIFY sigops") 427 self.move_tip(33) 428 lots_of_checksigs = CScript([OP_CHECKSIGVERIFY] * (MAX_BLOCK_SIGOPS - 1)) 429 b35 = self.next_block(35, spend=out[10], script=lots_of_checksigs) 430 self.send_blocks([b35], True) 431 self.save_spendable_output() 432 433 self.log.info("Reject a block with too many OP_CHECKSIGVERIFY sigops") 434 too_many_checksigs = CScript([OP_CHECKSIGVERIFY] * (MAX_BLOCK_SIGOPS)) 435 b36 = self.next_block(36, spend=out[11], script=too_many_checksigs) 436 self.send_blocks([b36], success=False, reject_reason='bad-blk-sigops', reconnect=True) 437 438 # Check spending of a transaction in a block which failed to connect 439 # 440 # b6 (3) 441 # b12 (3) -> b13 (4) -> b15 (5) -> b23 (6) -> b30 (7) -> b31 (8) -> b33 (9) -> b35 (10) 442 # \-> b37 (11) 443 # \-> b38 (11/37) 444 # 445 446 # save 37's spendable output, but then double-spend out11 to invalidate the block 447 self.log.info("Reject a block spending transaction from a block which failed to connect") 448 self.move_tip(35) 449 b37 = self.next_block(37, spend=out[11]) 450 txout_b37 = b37.vtx[1] 451 tx = self.create_and_sign_transaction(out[11], 0) 452 b37 = self.update_block(37, [tx]) 453 self.send_blocks([b37], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True) 454 455 # attempt to spend b37's first non-coinbase tx, at which point b37 was still considered valid 456 self.move_tip(35) 457 b38 = self.next_block(38, spend=txout_b37) 458 self.send_blocks([b38], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True) 459 460 # Check P2SH SigOp counting 461 # 462 # 463 # 13 (4) -> b15 (5) -> b23 (6) -> b30 (7) -> b31 (8) -> b33 (9) -> b35 (10) -> b39 (11) -> b41 (12) 464 # \-> b40 (12) 465 # 466 # b39 - create some P2SH outputs that will require 6 sigops to spend: 467 # 468 # redeem_script = COINBASE_PUBKEY, (OP_2DUP+OP_CHECKSIGVERIFY) * 5, OP_CHECKSIG 469 # p2sh_script = OP_HASH160, ripemd160(sha256(script)), OP_EQUAL 470 # 471 self.log.info("Check P2SH SIGOPS are correctly counted") 472 self.move_tip(35) 473 self.next_block(39) 474 b39_outputs = 0 475 b39_sigops_per_output = 6 476 477 # Build the redeem script, hash it, use hash to create the p2sh script 478 redeem_script = CScript([self.coinbase_pubkey] + [OP_2DUP, OP_CHECKSIGVERIFY] * 5 + [OP_CHECKSIG]) 479 p2sh_script = script_to_p2sh_script(redeem_script) 480 481 # Create a transaction that spends one satoshi to the p2sh_script, the rest to OP_TRUE 482 # This must be signed because it is spending a coinbase 483 spend = out[11] 484 tx = self.create_tx(spend, 0, 1, p2sh_script) 485 tx.vout.append(CTxOut(spend.vout[0].nValue - 1, CScript([OP_TRUE]))) 486 self.sign_tx(tx, spend) 487 tx.rehash() 488 b39 = self.update_block(39, [tx]) 489 b39_outputs += 1 490 491 # Until block is full, add tx's with 1 satoshi to p2sh_script, the rest to OP_TRUE 492 tx_new = None 493 tx_last = tx 494 total_weight = b39.get_weight() 495 while total_weight < MAX_BLOCK_WEIGHT: 496 tx_new = self.create_tx(tx_last, 1, 1, p2sh_script) 497 tx_new.vout.append(CTxOut(tx_last.vout[1].nValue - 1, CScript([OP_TRUE]))) 498 tx_new.rehash() 499 total_weight += tx_new.get_weight() 500 if total_weight >= MAX_BLOCK_WEIGHT: 501 break 502 b39.vtx.append(tx_new) # add tx to block 503 tx_last = tx_new 504 b39_outputs += 1 505 506 # The accounting in the loop above can be off, because it misses the 507 # compact size encoding of the number of transactions in the block. 508 # Make sure we didn't accidentally make too big a block. Note that the 509 # size of the block has non-determinism due to the ECDSA signature in 510 # the first transaction. 511 while b39.get_weight() >= MAX_BLOCK_WEIGHT: 512 del b39.vtx[-1] 513 514 b39 = self.update_block(39, []) 515 self.send_blocks([b39], True) 516 self.save_spendable_output() 517 518 # Test sigops in P2SH redeem scripts 519 # 520 # b40 creates 3333 tx's spending the 6-sigop P2SH outputs from b39 for a total of 19998 sigops. 521 # The first tx has one sigop and then at the end we add 2 more to put us just over the max. 522 # 523 # b41 does the same, less one, so it has the maximum sigops permitted. 524 # 525 self.log.info("Reject a block with too many P2SH sigops") 526 self.move_tip(39) 527 b40 = self.next_block(40, spend=out[12]) 528 sigops = get_legacy_sigopcount_block(b40) 529 numTxes = (MAX_BLOCK_SIGOPS - sigops) // b39_sigops_per_output 530 assert_equal(numTxes <= b39_outputs, True) 531 532 lastOutpoint = COutPoint(b40.vtx[1].sha256, 0) 533 new_txs = [] 534 for i in range(1, numTxes + 1): 535 tx = CTransaction() 536 tx.vout.append(CTxOut(1, CScript([OP_TRUE]))) 537 tx.vin.append(CTxIn(lastOutpoint, b'')) 538 # second input is corresponding P2SH output from b39 539 tx.vin.append(CTxIn(COutPoint(b39.vtx[i].sha256, 0), b'')) 540 # Note: must pass the redeem_script (not p2sh_script) to the signature hash function 541 tx.vin[1].scriptSig = CScript([redeem_script]) 542 sign_input_legacy(tx, 1, redeem_script, self.coinbase_key) 543 new_txs.append(tx) 544 lastOutpoint = COutPoint(tx.sha256, 0) 545 546 b40_sigops_to_fill = MAX_BLOCK_SIGOPS - (numTxes * b39_sigops_per_output + sigops) + 1 547 tx = CTransaction() 548 tx.vin.append(CTxIn(lastOutpoint, b'')) 549 tx.vout.append(CTxOut(1, CScript([OP_CHECKSIG] * b40_sigops_to_fill))) 550 tx.rehash() 551 new_txs.append(tx) 552 self.update_block(40, new_txs) 553 self.send_blocks([b40], success=False, reject_reason='bad-blk-sigops', reconnect=True) 554 555 # same as b40, but one less sigop 556 self.log.info("Accept a block with the max number of P2SH sigops") 557 self.move_tip(39) 558 b41 = self.next_block(41, spend=None) 559 self.update_block(41, b40.vtx[1:-1]) 560 b41_sigops_to_fill = b40_sigops_to_fill - 1 561 tx = CTransaction() 562 tx.vin.append(CTxIn(lastOutpoint, b'')) 563 tx.vout.append(CTxOut(1, CScript([OP_CHECKSIG] * b41_sigops_to_fill))) 564 tx.rehash() 565 self.update_block(41, [tx]) 566 self.send_blocks([b41], True) 567 568 # Fork off of b39 to create a constant base again 569 # 570 # b23 (6) -> b30 (7) -> b31 (8) -> b33 (9) -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) 571 # \-> b41 (12) 572 # 573 self.move_tip(39) 574 b42 = self.next_block(42, spend=out[12]) 575 self.save_spendable_output() 576 577 b43 = self.next_block(43, spend=out[13]) 578 self.save_spendable_output() 579 self.send_blocks([b42, b43], True) 580 581 # Test a number of really invalid scenarios 582 # 583 # -> b31 (8) -> b33 (9) -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) -> b44 (14) 584 # \-> ??? (15) 585 586 # The next few blocks are going to be created "by hand" since they'll do funky things, such as having 587 # the first transaction be non-coinbase, etc. The purpose of b44 is to make sure this works. 588 self.log.info("Build block 44 manually") 589 height = self.block_heights[self.tip.sha256] + 1 590 coinbase = create_coinbase(height, self.coinbase_pubkey) 591 b44 = CBlock() 592 b44.nTime = self.tip.nTime + 1 593 b44.hashPrevBlock = self.tip.sha256 594 b44.nBits = 0x207fffff 595 b44.vtx.append(coinbase) 596 tx = self.create_and_sign_transaction(out[14], 1) 597 b44.vtx.append(tx) 598 b44.hashMerkleRoot = b44.calc_merkle_root() 599 b44.solve() 600 self.tip = b44 601 self.block_heights[b44.sha256] = height 602 self.blocks[44] = b44 603 self.send_blocks([b44], True) 604 605 self.log.info("Reject a block with a non-coinbase as the first tx") 606 non_coinbase = self.create_tx(out[15], 0, 1) 607 b45 = CBlock() 608 b45.nTime = self.tip.nTime + 1 609 b45.hashPrevBlock = self.tip.sha256 610 b45.nBits = 0x207fffff 611 b45.vtx.append(non_coinbase) 612 b45.hashMerkleRoot = b45.calc_merkle_root() 613 b45.solve() 614 self.block_heights[b45.sha256] = self.block_heights[self.tip.sha256] + 1 615 self.tip = b45 616 self.blocks[45] = b45 617 self.send_blocks([b45], success=False, reject_reason='bad-cb-missing', reconnect=True) 618 619 self.log.info("Reject a block with no transactions") 620 self.move_tip(44) 621 b46 = CBlock() 622 b46.nTime = b44.nTime + 1 623 b46.hashPrevBlock = b44.sha256 624 b46.nBits = 0x207fffff 625 b46.vtx = [] 626 b46.hashMerkleRoot = 0 627 b46.solve() 628 self.block_heights[b46.sha256] = self.block_heights[b44.sha256] + 1 629 self.tip = b46 630 assert 46 not in self.blocks 631 self.blocks[46] = b46 632 self.send_blocks([b46], success=False, reject_reason='bad-blk-length', reconnect=True) 633 634 self.log.info("Reject a block with invalid work") 635 self.move_tip(44) 636 b47 = self.next_block(47) 637 target = uint256_from_compact(b47.nBits) 638 while b47.sha256 <= target: 639 # Rehash nonces until an invalid too-high-hash block is found. 640 b47.nNonce += 1 641 b47.rehash() 642 self.send_blocks([b47], False, force_send=True, reject_reason='high-hash', reconnect=True) 643 644 self.log.info("Reject a block with a timestamp >2 hours in the future") 645 self.move_tip(44) 646 b48 = self.next_block(48) 647 b48.nTime = int(time.time()) + 60 * 60 * 3 648 # Header timestamp has changed. Re-solve the block. 649 b48.solve() 650 self.send_blocks([b48], False, force_send=True, reject_reason='time-too-new') 651 652 self.log.info("Reject a block with invalid merkle hash") 653 self.move_tip(44) 654 b49 = self.next_block(49) 655 b49.hashMerkleRoot += 1 656 b49.solve() 657 self.send_blocks([b49], success=False, reject_reason='bad-txnmrklroot', reconnect=True) 658 659 self.log.info("Reject a block with incorrect POW limit") 660 self.move_tip(44) 661 b50 = self.next_block(50) 662 b50.nBits = b50.nBits - 1 663 b50.solve() 664 self.send_blocks([b50], False, force_send=True, reject_reason='bad-diffbits', reconnect=True) 665 666 self.log.info("Reject a block with two coinbase transactions") 667 self.move_tip(44) 668 self.next_block(51) 669 cb2 = create_coinbase(51, self.coinbase_pubkey) 670 b51 = self.update_block(51, [cb2]) 671 self.send_blocks([b51], success=False, reject_reason='bad-cb-multiple', reconnect=True) 672 673 self.log.info("Reject a block with duplicate transactions") 674 # Note: txns have to be in the right position in the merkle tree to trigger this error 675 self.move_tip(44) 676 b52 = self.next_block(52, spend=out[15]) 677 tx = self.create_tx(b52.vtx[1], 0, 1) 678 b52 = self.update_block(52, [tx, tx]) 679 self.send_blocks([b52], success=False, reject_reason='bad-txns-duplicate', reconnect=True) 680 681 # Test block timestamps 682 # -> b31 (8) -> b33 (9) -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) 683 # \-> b54 (15) 684 # -> b44 (14)\-> b48 () 685 self.move_tip(43) 686 b53 = self.next_block(53, spend=out[14]) 687 self.send_blocks([b53], False) 688 self.save_spendable_output() 689 690 self.log.info("Reject a block with timestamp before MedianTimePast") 691 b54 = self.next_block(54, spend=out[15]) 692 b54.nTime = b35.nTime - 1 693 b54.solve() 694 self.send_blocks([b54], False, force_send=True, reject_reason='time-too-old', reconnect=True) 695 696 # valid timestamp 697 self.move_tip(53) 698 b55 = self.next_block(55, spend=out[15]) 699 b55.nTime = b35.nTime 700 self.update_block(55, []) 701 self.send_blocks([b55], True) 702 self.save_spendable_output() 703 704 # The block which was previously rejected because of being "too far(3 hours)" must be accepted 2 hours later. 705 # The new block is only 1 hour into future now and we must reorg onto to the new longer chain. 706 # The new bestblock b48p is invalidated manually. 707 # -> b31 (8) -> b33 (9) -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) 708 # \-> b54 (15) 709 # -> b44 (14)\-> b48 () -> b48p () 710 self.log.info("Accept a previously rejected future block at a later time") 711 node.setmocktime(int(time.time()) + 2*60*60) 712 self.move_tip(48) 713 self.block_heights[b48.sha256] = self.block_heights[b44.sha256] + 1 # b48 is a parent of b44 714 b48p = self.next_block("48p") 715 self.send_blocks([b48, b48p], success=True) # Reorg to the longer chain 716 node.invalidateblock(b48p.hash) # mark b48p as invalid 717 node.setmocktime(0) 718 719 # Test Merkle tree malleability 720 # 721 # -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57p2 (16) 722 # \-> b57 (16) 723 # \-> b56p2 (16) 724 # \-> b56 (16) 725 # 726 # Merkle tree malleability (CVE-2012-2459): repeating sequences of transactions in a block without 727 # affecting the merkle root of a block, while still invalidating it. 728 # See: src/consensus/merkle.h 729 # 730 # b57 has three txns: coinbase, tx, tx1. The merkle root computation will duplicate tx. 731 # Result: OK 732 # 733 # b56 copies b57 but duplicates tx1 and does not recalculate the block hash. So it has a valid merkle 734 # root but duplicate transactions. 735 # Result: Fails 736 # 737 # b57p2 has six transactions in its merkle tree: 738 # - coinbase, tx, tx1, tx2, tx3, tx4 739 # Merkle root calculation will duplicate as necessary. 740 # Result: OK. 741 # 742 # b56p2 copies b57p2 but adds both tx3 and tx4. The purpose of the test is to make sure the code catches 743 # duplicate txns that are not next to one another with the "bad-txns-duplicate" error (which indicates 744 # that the error was caught early, avoiding a DOS vulnerability.) 745 746 # b57 - a good block with 2 txs, don't submit until end 747 self.move_tip(55) 748 self.next_block(57) 749 tx = self.create_and_sign_transaction(out[16], 1) 750 tx1 = self.create_tx(tx, 0, 1) 751 b57 = self.update_block(57, [tx, tx1]) 752 753 # b56 - copy b57, add a duplicate tx 754 self.log.info("Reject a block with a duplicate transaction in the Merkle Tree (but with a valid Merkle Root)") 755 self.move_tip(55) 756 b56 = copy.deepcopy(b57) 757 self.blocks[56] = b56 758 assert_equal(len(b56.vtx), 3) 759 b56 = self.update_block(56, [tx1]) 760 assert_equal(b56.hash, b57.hash) 761 self.send_blocks([b56], success=False, reject_reason='bad-txns-duplicate', reconnect=True) 762 763 # b57p2 - a good block with 6 tx'es, don't submit until end 764 self.move_tip(55) 765 self.next_block("57p2") 766 tx = self.create_and_sign_transaction(out[16], 1) 767 tx1 = self.create_tx(tx, 0, 1) 768 tx2 = self.create_tx(tx1, 0, 1) 769 tx3 = self.create_tx(tx2, 0, 1) 770 tx4 = self.create_tx(tx3, 0, 1) 771 b57p2 = self.update_block("57p2", [tx, tx1, tx2, tx3, tx4]) 772 773 # b56p2 - copy b57p2, duplicate two non-consecutive tx's 774 self.log.info("Reject a block with two duplicate transactions in the Merkle Tree (but with a valid Merkle Root)") 775 self.move_tip(55) 776 b56p2 = copy.deepcopy(b57p2) 777 self.blocks["b56p2"] = b56p2 778 assert_equal(b56p2.hash, b57p2.hash) 779 assert_equal(len(b56p2.vtx), 6) 780 b56p2 = self.update_block("b56p2", [tx3, tx4]) 781 self.send_blocks([b56p2], success=False, reject_reason='bad-txns-duplicate', reconnect=True) 782 783 self.move_tip("57p2") 784 self.send_blocks([b57p2], True) 785 786 self.move_tip(57) 787 self.send_blocks([b57], False) # The tip is not updated because 57p2 seen first 788 self.save_spendable_output() 789 790 # Test a few invalid tx types 791 # 792 # -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 () 793 # \-> ??? (17) 794 # 795 796 # tx with prevout.n out of range 797 self.log.info("Reject a block with a transaction with prevout.n out of range") 798 self.move_tip(57) 799 self.next_block(58, spend=out[17]) 800 tx = CTransaction() 801 assert len(out[17].vout) < 42 802 tx.vin.append(CTxIn(COutPoint(out[17].sha256, 42), CScript([OP_TRUE]), SEQUENCE_FINAL)) 803 tx.vout.append(CTxOut(0, b"")) 804 tx.calc_sha256() 805 b58 = self.update_block(58, [tx]) 806 self.send_blocks([b58], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True) 807 808 # tx with output value > input value 809 self.log.info("Reject a block with a transaction with outputs > inputs") 810 self.move_tip(57) 811 self.next_block(59) 812 tx = self.create_and_sign_transaction(out[17], 51 * COIN) 813 b59 = self.update_block(59, [tx]) 814 self.send_blocks([b59], success=False, reject_reason='bad-txns-in-belowout', reconnect=True) 815 816 # reset to good chain 817 self.move_tip(57) 818 b60 = self.next_block(60) 819 self.send_blocks([b60], True) 820 self.save_spendable_output() 821 822 # Test BIP30 (reject duplicate) 823 # 824 # -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 () 825 # \-> b61 () 826 # 827 # Blocks are not allowed to contain a transaction whose id matches that of an earlier, 828 # not-fully-spent transaction in the same chain. To test, make identical coinbases; 829 # the second one should be rejected. See also CVE-2012-1909. 830 # 831 self.log.info("Reject a block with a transaction with a duplicate hash of a previous transaction (BIP30)") 832 self.move_tip(60) 833 b61 = self.next_block(61) 834 b61.vtx[0].vin[0].scriptSig = DUPLICATE_COINBASE_SCRIPT_SIG 835 b61.vtx[0].rehash() 836 b61 = self.update_block(61, []) 837 assert_equal(duplicate_tx.serialize(), b61.vtx[0].serialize()) 838 # BIP30 is always checked on regtest, regardless of the BIP34 activation height 839 self.send_blocks([b61], success=False, reject_reason='bad-txns-BIP30', reconnect=True) 840 841 # Test BIP30 (allow duplicate if spent) 842 # 843 # -> b57 (16) -> b60 () 844 # \-> b_spend_dup_cb (b_dup_cb) -> b_dup_2 () 845 # 846 self.move_tip(57) 847 self.next_block('spend_dup_cb') 848 tx = CTransaction() 849 tx.vin.append(CTxIn(COutPoint(duplicate_tx.sha256, 0))) 850 tx.vout.append(CTxOut(0, CScript([OP_TRUE]))) 851 self.sign_tx(tx, duplicate_tx) 852 tx.rehash() 853 b_spend_dup_cb = self.update_block('spend_dup_cb', [tx]) 854 855 b_dup_2 = self.next_block('dup_2') 856 b_dup_2.vtx[0].vin[0].scriptSig = DUPLICATE_COINBASE_SCRIPT_SIG 857 b_dup_2.vtx[0].rehash() 858 b_dup_2 = self.update_block('dup_2', []) 859 assert_equal(duplicate_tx.serialize(), b_dup_2.vtx[0].serialize()) 860 assert_equal(self.nodes[0].gettxout(txid=duplicate_tx.hash, n=0)['confirmations'], 119) 861 self.send_blocks([b_spend_dup_cb, b_dup_2], success=True) 862 # The duplicate has less confirmations 863 assert_equal(self.nodes[0].gettxout(txid=duplicate_tx.hash, n=0)['confirmations'], 1) 864 865 # Test tx.isFinal is properly rejected (not an exhaustive tx.isFinal test, that should be in data-driven transaction tests) 866 # 867 # -> b_spend_dup_cb (b_dup_cb) -> b_dup_2 () 868 # \-> b62 (18) 869 # 870 self.log.info("Reject a block with a transaction with a nonfinal locktime") 871 self.move_tip('dup_2') 872 self.next_block(62) 873 tx = CTransaction() 874 tx.nLockTime = 0xffffffff # this locktime is non-final 875 tx.vin.append(CTxIn(COutPoint(out[18].sha256, 0))) # don't set nSequence 876 tx.vout.append(CTxOut(0, CScript([OP_TRUE]))) 877 assert_greater_than(SEQUENCE_FINAL, tx.vin[0].nSequence) 878 tx.calc_sha256() 879 b62 = self.update_block(62, [tx]) 880 self.send_blocks([b62], success=False, reject_reason='bad-txns-nonfinal', reconnect=True) 881 882 # Test a non-final coinbase is also rejected 883 # 884 # -> b_spend_dup_cb (b_dup_cb) -> b_dup_2 () 885 # \-> b63 (-) 886 # 887 self.log.info("Reject a block with a coinbase transaction with a nonfinal locktime") 888 self.move_tip('dup_2') 889 b63 = self.next_block(63) 890 b63.vtx[0].nLockTime = 0xffffffff 891 b63.vtx[0].vin[0].nSequence = 0xDEADBEEF 892 b63.vtx[0].rehash() 893 b63 = self.update_block(63, []) 894 self.send_blocks([b63], success=False, reject_reason='bad-txns-nonfinal', reconnect=True) 895 896 # This checks that a block with a bloated VARINT between the block_header and the array of tx such that 897 # the block is > MAX_BLOCK_WEIGHT with the bloated varint, but <= MAX_BLOCK_WEIGHT without the bloated varint, 898 # does not cause a subsequent, identical block with canonical encoding to be rejected. The test does not 899 # care whether the bloated block is accepted or rejected; it only cares that the second block is accepted. 900 # 901 # What matters is that the receiving node should not reject the bloated block, and then reject the canonical 902 # block on the basis that it's the same as an already-rejected block (which would be a consensus failure.) 903 # 904 # -> b_spend_dup_cb (b_dup_cb) -> b_dup_2 () -> b64 (18) 905 # \ 906 # b64a (18) 907 # b64a is a bloated block (non-canonical varint) 908 # b64 is a good block (same as b64 but w/ canonical varint) 909 # 910 self.log.info("Accept a valid block even if a bloated version of the block has previously been sent") 911 self.move_tip('dup_2') 912 regular_block = self.next_block("64a", spend=out[18]) 913 914 # make it a "broken_block," with non-canonical serialization 915 b64a = CBrokenBlock(regular_block) 916 b64a.initialize(regular_block) 917 self.blocks["64a"] = b64a 918 self.tip = b64a 919 tx = CTransaction() 920 921 # use canonical serialization to calculate size 922 script_length = (MAX_BLOCK_WEIGHT - 4 * len(b64a.normal_serialize()) - 276) // 4 923 script_output = CScript([b'\x00' * script_length]) 924 tx.vout.append(CTxOut(0, script_output)) 925 tx.vin.append(CTxIn(COutPoint(b64a.vtx[1].sha256, 0))) 926 b64a = self.update_block("64a", [tx]) 927 assert_equal(b64a.get_weight(), MAX_BLOCK_WEIGHT + 8 * 4) 928 self.send_blocks([b64a], success=False, reject_reason='non-canonical ReadCompactSize()') 929 930 # bitcoind doesn't disconnect us for sending a bloated block, but if we subsequently 931 # resend the header message, it won't send us the getdata message again. Just 932 # disconnect and reconnect and then call sync_blocks. 933 # TODO: improve this test to be less dependent on P2P DOS behaviour. 934 node.disconnect_p2ps() 935 self.reconnect_p2p() 936 937 self.move_tip('dup_2') 938 b64 = CBlock(b64a) 939 b64.vtx = copy.deepcopy(b64a.vtx) 940 assert_equal(b64.hash, b64a.hash) 941 assert_equal(b64.get_weight(), MAX_BLOCK_WEIGHT) 942 self.blocks[64] = b64 943 b64 = self.update_block(64, []) 944 self.send_blocks([b64], True) 945 self.save_spendable_output() 946 947 # Spend an output created in the block itself 948 # 949 # -> b_dup_2 () -> b64 (18) -> b65 (19) 950 # 951 self.log.info("Accept a block with a transaction spending an output created in the same block") 952 self.move_tip(64) 953 self.next_block(65) 954 tx1 = self.create_and_sign_transaction(out[19], out[19].vout[0].nValue) 955 tx2 = self.create_and_sign_transaction(tx1, 0) 956 b65 = self.update_block(65, [tx1, tx2]) 957 self.send_blocks([b65], True) 958 self.save_spendable_output() 959 960 # Attempt to spend an output created later in the same block 961 # 962 # -> b64 (18) -> b65 (19) 963 # \-> b66 (20) 964 self.log.info("Reject a block with a transaction spending an output created later in the same block") 965 self.move_tip(65) 966 self.next_block(66) 967 tx1 = self.create_and_sign_transaction(out[20], out[20].vout[0].nValue) 968 tx2 = self.create_and_sign_transaction(tx1, 1) 969 b66 = self.update_block(66, [tx2, tx1]) 970 self.send_blocks([b66], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True) 971 972 # Attempt to double-spend a transaction created in a block 973 # 974 # -> b64 (18) -> b65 (19) 975 # \-> b67 (20) 976 # 977 # 978 self.log.info("Reject a block with a transaction double spending a transaction created in the same block") 979 self.move_tip(65) 980 self.next_block(67) 981 tx1 = self.create_and_sign_transaction(out[20], out[20].vout[0].nValue) 982 tx2 = self.create_and_sign_transaction(tx1, 1) 983 tx3 = self.create_and_sign_transaction(tx1, 2) 984 b67 = self.update_block(67, [tx1, tx2, tx3]) 985 self.send_blocks([b67], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True) 986 987 # More tests of block subsidy 988 # 989 # -> b64 (18) -> b65 (19) -> b69 (20) 990 # \-> b68 (20) 991 # 992 # b68 - coinbase with an extra 10 satoshis, 993 # creates a tx that has 9 satoshis from out[20] go to fees 994 # this fails because the coinbase is trying to claim 1 satoshi too much in fees 995 # 996 # b69 - coinbase with extra 10 satoshis, and a tx that gives a 10 satoshi fee 997 # this succeeds 998 # 999 self.log.info("Reject a block trying to claim too much subsidy in the coinbase transaction") 1000 self.move_tip(65) 1001 self.next_block(68, additional_coinbase_value=10) 1002 tx = self.create_and_sign_transaction(out[20], out[20].vout[0].nValue - 9) 1003 b68 = self.update_block(68, [tx]) 1004 self.send_blocks([b68], success=False, reject_reason='bad-cb-amount', reconnect=True) 1005 1006 self.log.info("Accept a block claiming the correct subsidy in the coinbase transaction") 1007 self.move_tip(65) 1008 b69 = self.next_block(69, additional_coinbase_value=10) 1009 tx = self.create_and_sign_transaction(out[20], out[20].vout[0].nValue - 10) 1010 self.update_block(69, [tx]) 1011 self.send_blocks([b69], True) 1012 self.save_spendable_output() 1013 1014 # Test spending the outpoint of a non-existent transaction 1015 # 1016 # -> b65 (19) -> b69 (20) 1017 # \-> b70 (21) 1018 # 1019 self.log.info("Reject a block containing a transaction spending from a non-existent input") 1020 self.move_tip(69) 1021 self.next_block(70, spend=out[21]) 1022 bogus_tx = CTransaction() 1023 bogus_tx.sha256 = uint256_from_str(b"23c70ed7c0506e9178fc1a987f40a33946d4ad4c962b5ae3a52546da53af0c5c") 1024 tx = CTransaction() 1025 tx.vin.append(CTxIn(COutPoint(bogus_tx.sha256, 0), b"", SEQUENCE_FINAL)) 1026 tx.vout.append(CTxOut(1, b"")) 1027 b70 = self.update_block(70, [tx]) 1028 self.send_blocks([b70], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True) 1029 1030 # Test accepting an invalid block which has the same hash as a valid one (via merkle tree tricks) 1031 # 1032 # -> b65 (19) -> b69 (20) -> b72 (21) 1033 # \-> b71 (21) 1034 # 1035 # b72 is a good block. 1036 # b71 is a copy of 72, but re-adds one of its transactions. However, it has the same hash as b72. 1037 self.log.info("Reject a block containing a duplicate transaction but with the same Merkle root (Merkle tree malleability") 1038 self.move_tip(69) 1039 self.next_block(72) 1040 tx1 = self.create_and_sign_transaction(out[21], 2) 1041 tx2 = self.create_and_sign_transaction(tx1, 1) 1042 b72 = self.update_block(72, [tx1, tx2]) # now tip is 72 1043 b71 = copy.deepcopy(b72) 1044 b71.vtx.append(tx2) # add duplicate tx2 1045 self.block_heights[b71.sha256] = self.block_heights[b69.sha256] + 1 # b71 builds off b69 1046 self.blocks[71] = b71 1047 1048 assert_equal(len(b71.vtx), 4) 1049 assert_equal(len(b72.vtx), 3) 1050 assert_equal(b72.sha256, b71.sha256) 1051 1052 self.move_tip(71) 1053 self.send_blocks([b71], success=False, reject_reason='bad-txns-duplicate', reconnect=True) 1054 1055 self.move_tip(72) 1056 self.send_blocks([b72], True) 1057 self.save_spendable_output() 1058 1059 # Test some invalid scripts and MAX_BLOCK_SIGOPS 1060 # 1061 # -> b69 (20) -> b72 (21) 1062 # \-> b** (22) 1063 # 1064 1065 # b73 - tx with excessive sigops that are placed after an excessively large script element. 1066 # The purpose of the test is to make sure those sigops are counted. 1067 # 1068 # script is a bytearray of size 20,526 1069 # 1070 # bytearray[0-19,998] : OP_CHECKSIG 1071 # bytearray[19,999] : OP_PUSHDATA4 1072 # bytearray[20,000-20,003]: 521 (max_script_element_size+1, in little-endian format) 1073 # bytearray[20,004-20,525]: unread data (script_element) 1074 # bytearray[20,526] : OP_CHECKSIG (this puts us over the limit) 1075 self.log.info("Reject a block containing too many sigops after a large script element") 1076 self.move_tip(72) 1077 self.next_block(73) 1078 size = MAX_BLOCK_SIGOPS - 1 + MAX_SCRIPT_ELEMENT_SIZE + 1 + 5 + 1 1079 a = bytearray([OP_CHECKSIG] * size) 1080 a[MAX_BLOCK_SIGOPS - 1] = int("4e", 16) # OP_PUSHDATA4 1081 1082 element_size = MAX_SCRIPT_ELEMENT_SIZE + 1 1083 a[MAX_BLOCK_SIGOPS] = element_size % 256 1084 a[MAX_BLOCK_SIGOPS + 1] = element_size // 256 1085 a[MAX_BLOCK_SIGOPS + 2] = 0 1086 a[MAX_BLOCK_SIGOPS + 3] = 0 1087 1088 tx = self.create_and_sign_transaction(out[22], 1, CScript(a)) 1089 b73 = self.update_block(73, [tx]) 1090 assert_equal(get_legacy_sigopcount_block(b73), MAX_BLOCK_SIGOPS + 1) 1091 self.send_blocks([b73], success=False, reject_reason='bad-blk-sigops', reconnect=True) 1092 1093 # b74/75 - if we push an invalid script element, all previous sigops are counted, 1094 # but sigops after the element are not counted. 1095 # 1096 # The invalid script element is that the push_data indicates that 1097 # there will be a large amount of data (0xffffff bytes), but we only 1098 # provide a much smaller number. These bytes are CHECKSIGS so they would 1099 # cause b75 to fail for excessive sigops, if those bytes were counted. 1100 # 1101 # b74 fails because we put MAX_BLOCK_SIGOPS+1 before the element 1102 # b75 succeeds because we put MAX_BLOCK_SIGOPS before the element 1103 self.log.info("Check sigops are counted correctly after an invalid script element") 1104 self.move_tip(72) 1105 self.next_block(74) 1106 size = MAX_BLOCK_SIGOPS - 1 + MAX_SCRIPT_ELEMENT_SIZE + 42 # total = 20,561 1107 a = bytearray([OP_CHECKSIG] * size) 1108 a[MAX_BLOCK_SIGOPS] = 0x4e 1109 a[MAX_BLOCK_SIGOPS + 1] = 0xfe 1110 a[MAX_BLOCK_SIGOPS + 2] = 0xff 1111 a[MAX_BLOCK_SIGOPS + 3] = 0xff 1112 a[MAX_BLOCK_SIGOPS + 4] = 0xff 1113 tx = self.create_and_sign_transaction(out[22], 1, CScript(a)) 1114 b74 = self.update_block(74, [tx]) 1115 self.send_blocks([b74], success=False, reject_reason='bad-blk-sigops', reconnect=True) 1116 1117 self.move_tip(72) 1118 self.next_block(75) 1119 size = MAX_BLOCK_SIGOPS - 1 + MAX_SCRIPT_ELEMENT_SIZE + 42 1120 a = bytearray([OP_CHECKSIG] * size) 1121 a[MAX_BLOCK_SIGOPS - 1] = 0x4e 1122 a[MAX_BLOCK_SIGOPS] = 0xff 1123 a[MAX_BLOCK_SIGOPS + 1] = 0xff 1124 a[MAX_BLOCK_SIGOPS + 2] = 0xff 1125 a[MAX_BLOCK_SIGOPS + 3] = 0xff 1126 tx = self.create_and_sign_transaction(out[22], 1, CScript(a)) 1127 b75 = self.update_block(75, [tx]) 1128 self.send_blocks([b75], True) 1129 self.save_spendable_output() 1130 1131 # Check that if we push an element filled with CHECKSIGs, they are not counted 1132 self.move_tip(75) 1133 self.next_block(76) 1134 size = MAX_BLOCK_SIGOPS - 1 + MAX_SCRIPT_ELEMENT_SIZE + 1 + 5 1135 a = bytearray([OP_CHECKSIG] * size) 1136 a[MAX_BLOCK_SIGOPS - 1] = 0x4e # PUSHDATA4, but leave the following bytes as just checksigs 1137 tx = self.create_and_sign_transaction(out[23], 1, CScript(a)) 1138 b76 = self.update_block(76, [tx]) 1139 self.send_blocks([b76], True) 1140 self.save_spendable_output() 1141 1142 # Test transaction resurrection 1143 # 1144 # -> b77 (24) -> b78 (25) -> b79 (26) 1145 # \-> b80 (25) -> b81 (26) -> b82 (27) 1146 # 1147 # b78 creates a tx, which is spent in b79. After b82, both should be in mempool 1148 # 1149 # The tx'es must be unsigned and pass the node's mempool policy. It is unsigned for the 1150 # rather obscure reason that the Python signature code does not distinguish between 1151 # Low-S and High-S values (whereas the bitcoin code has custom code which does so); 1152 # as a result of which, the odds are 50% that the python code will use the right 1153 # value and the transaction will be accepted into the mempool. Until we modify the 1154 # test framework to support low-S signing, we are out of luck. 1155 # 1156 # To get around this issue, we construct transactions which are not signed and which 1157 # spend to OP_TRUE. If the standard-ness rules change, this test would need to be 1158 # updated. (Perhaps to spend to a P2SH OP_TRUE script) 1159 self.log.info("Test transaction resurrection during a re-org") 1160 self.move_tip(76) 1161 self.next_block(77) 1162 tx77 = self.create_and_sign_transaction(out[24], 10 * COIN) 1163 b77 = self.update_block(77, [tx77]) 1164 self.send_blocks([b77], True) 1165 self.save_spendable_output() 1166 1167 self.next_block(78) 1168 tx78 = self.create_tx(tx77, 0, 9 * COIN) 1169 b78 = self.update_block(78, [tx78]) 1170 self.send_blocks([b78], True) 1171 1172 self.next_block(79) 1173 tx79 = self.create_tx(tx78, 0, 8 * COIN) 1174 b79 = self.update_block(79, [tx79]) 1175 self.send_blocks([b79], True) 1176 1177 # mempool should be empty 1178 assert_equal(len(self.nodes[0].getrawmempool()), 0) 1179 1180 self.move_tip(77) 1181 b80 = self.next_block(80, spend=out[25]) 1182 self.send_blocks([b80], False, force_send=True) 1183 self.save_spendable_output() 1184 1185 b81 = self.next_block(81, spend=out[26]) 1186 self.send_blocks([b81], False, force_send=True) # other chain is same length 1187 self.save_spendable_output() 1188 1189 b82 = self.next_block(82, spend=out[27]) 1190 self.send_blocks([b82], True) # now this chain is longer, triggers re-org 1191 self.save_spendable_output() 1192 1193 # now check that tx78 and tx79 have been put back into the peer's mempool 1194 mempool = self.nodes[0].getrawmempool() 1195 assert_equal(len(mempool), 2) 1196 assert tx78.hash in mempool 1197 assert tx79.hash in mempool 1198 1199 # Test invalid opcodes in dead execution paths. 1200 # 1201 # -> b81 (26) -> b82 (27) -> b83 (28) 1202 # 1203 self.log.info("Accept a block with invalid opcodes in dead execution paths") 1204 self.next_block(83) 1205 op_codes = [OP_IF, OP_INVALIDOPCODE, OP_ELSE, OP_TRUE, OP_ENDIF] 1206 script = CScript(op_codes) 1207 tx1 = self.create_and_sign_transaction(out[28], out[28].vout[0].nValue, script) 1208 1209 tx2 = self.create_and_sign_transaction(tx1, 0, CScript([OP_TRUE])) 1210 tx2.vin[0].scriptSig = CScript([OP_FALSE]) 1211 tx2.rehash() 1212 1213 b83 = self.update_block(83, [tx1, tx2]) 1214 self.send_blocks([b83], True) 1215 self.save_spendable_output() 1216 1217 # Reorg on/off blocks that have OP_RETURN in them (and try to spend them) 1218 # 1219 # -> b81 (26) -> b82 (27) -> b83 (28) -> b84 (29) -> b87 (30) -> b88 (31) 1220 # \-> b85 (29) -> b86 (30) \-> b89a (32) 1221 # 1222 self.log.info("Test re-orging blocks with OP_RETURN in them") 1223 self.next_block(84) 1224 tx1 = self.create_tx(out[29], 0, 0, CScript([OP_RETURN])) 1225 tx1.vout.append(CTxOut(0, CScript([OP_TRUE]))) 1226 tx1.vout.append(CTxOut(0, CScript([OP_TRUE]))) 1227 tx1.vout.append(CTxOut(0, CScript([OP_TRUE]))) 1228 tx1.vout.append(CTxOut(0, CScript([OP_TRUE]))) 1229 tx1.calc_sha256() 1230 self.sign_tx(tx1, out[29]) 1231 tx1.rehash() 1232 tx2 = self.create_tx(tx1, 1, 0, CScript([OP_RETURN])) 1233 tx2.vout.append(CTxOut(0, CScript([OP_RETURN]))) 1234 tx3 = self.create_tx(tx1, 2, 0, CScript([OP_RETURN])) 1235 tx3.vout.append(CTxOut(0, CScript([OP_TRUE]))) 1236 tx4 = self.create_tx(tx1, 3, 0, CScript([OP_TRUE])) 1237 tx4.vout.append(CTxOut(0, CScript([OP_RETURN]))) 1238 tx5 = self.create_tx(tx1, 4, 0, CScript([OP_RETURN])) 1239 1240 b84 = self.update_block(84, [tx1, tx2, tx3, tx4, tx5]) 1241 self.send_blocks([b84], True) 1242 self.save_spendable_output() 1243 1244 self.move_tip(83) 1245 b85 = self.next_block(85, spend=out[29]) 1246 self.send_blocks([b85], False) # other chain is same length 1247 1248 b86 = self.next_block(86, spend=out[30]) 1249 self.send_blocks([b86], True) 1250 1251 self.move_tip(84) 1252 b87 = self.next_block(87, spend=out[30]) 1253 self.send_blocks([b87], False) # other chain is same length 1254 self.save_spendable_output() 1255 1256 b88 = self.next_block(88, spend=out[31]) 1257 self.send_blocks([b88], True) 1258 self.save_spendable_output() 1259 1260 # trying to spend the OP_RETURN output is rejected 1261 self.next_block("89a", spend=out[32]) 1262 tx = self.create_tx(tx1, 0, 0, CScript([OP_TRUE])) 1263 b89a = self.update_block("89a", [tx]) 1264 self.send_blocks([b89a], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True) 1265 1266 # Don't use v2transport for the large reorg, which is too slow with the unoptimized python ChaCha20 implementation 1267 if self.options.v2transport: 1268 self.nodes[0].disconnect_p2ps() 1269 self.helper_peer = self.nodes[0].add_p2p_connection(P2PDataStore(), supports_v2_p2p=False) 1270 self.log.info("Test a re-org of one week's worth of blocks (1088 blocks)") 1271 1272 self.move_tip(88) 1273 LARGE_REORG_SIZE = 1088 1274 blocks = [] 1275 spend = out[32] 1276 for i in range(89, LARGE_REORG_SIZE + 89): 1277 b = self.next_block(i, spend) 1278 tx = CTransaction() 1279 script_length = (MAX_BLOCK_WEIGHT - b.get_weight() - 276) // 4 1280 script_output = CScript([b'\x00' * script_length]) 1281 tx.vout.append(CTxOut(0, script_output)) 1282 tx.vin.append(CTxIn(COutPoint(b.vtx[1].sha256, 0))) 1283 b = self.update_block(i, [tx]) 1284 assert_equal(b.get_weight(), MAX_BLOCK_WEIGHT) 1285 blocks.append(b) 1286 self.save_spendable_output() 1287 spend = self.get_spendable_output() 1288 1289 self.send_blocks(blocks, True, timeout=2440) 1290 chain1_tip = i 1291 1292 # now create alt chain of same length 1293 self.move_tip(88) 1294 blocks2 = [] 1295 for i in range(89, LARGE_REORG_SIZE + 89): 1296 blocks2.append(self.next_block("alt" + str(i))) 1297 self.send_blocks(blocks2, False, force_send=False) 1298 1299 # extend alt chain to trigger re-org 1300 block = self.next_block("alt" + str(chain1_tip + 1)) 1301 self.send_blocks([block], True, timeout=2440) 1302 1303 # ... and re-org back to the first chain 1304 self.move_tip(chain1_tip) 1305 block = self.next_block(chain1_tip + 1) 1306 self.send_blocks([block], False, force_send=True) 1307 block = self.next_block(chain1_tip + 2) 1308 self.send_blocks([block], True, timeout=2440) 1309 1310 self.log.info("Reject a block with an invalid block header version") 1311 b_v1 = self.next_block('b_v1', version=1) 1312 self.send_blocks([b_v1], success=False, force_send=True, reject_reason='bad-version(0x00000001)', reconnect=True) 1313 1314 self.move_tip(chain1_tip + 2) 1315 b_cb34 = self.next_block('b_cb34') 1316 b_cb34.vtx[0].vin[0].scriptSig = b_cb34.vtx[0].vin[0].scriptSig[:-1] 1317 b_cb34.vtx[0].rehash() 1318 b_cb34.hashMerkleRoot = b_cb34.calc_merkle_root() 1319 b_cb34.solve() 1320 self.send_blocks([b_cb34], success=False, reject_reason='bad-cb-height', reconnect=True) 1321 1322 # Helper methods 1323 ################ 1324 1325 def add_transactions_to_block(self, block, tx_list): 1326 [tx.rehash() for tx in tx_list] 1327 block.vtx.extend(tx_list) 1328 1329 # this is a little handier to use than the version in blocktools.py 1330 def create_tx(self, spend_tx, n, value, script=CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE])): 1331 return create_tx_with_script(spend_tx, n, amount=value, script_pub_key=script) 1332 1333 # sign a transaction, using the key we know about 1334 # this signs input 0 in tx, which is assumed to be spending output 0 in spend_tx 1335 def sign_tx(self, tx, spend_tx): 1336 scriptPubKey = bytearray(spend_tx.vout[0].scriptPubKey) 1337 if (scriptPubKey[0] == OP_TRUE): # an anyone-can-spend 1338 tx.vin[0].scriptSig = CScript() 1339 return 1340 sign_input_legacy(tx, 0, spend_tx.vout[0].scriptPubKey, self.coinbase_key) 1341 1342 def create_and_sign_transaction(self, spend_tx, value, script=CScript([OP_TRUE])): 1343 tx = self.create_tx(spend_tx, 0, value, script) 1344 self.sign_tx(tx, spend_tx) 1345 tx.rehash() 1346 return tx 1347 1348 def next_block(self, number, spend=None, additional_coinbase_value=0, script=CScript([OP_TRUE]), *, version=4): 1349 if self.tip is None: 1350 base_block_hash = self.genesis_hash 1351 block_time = int(time.time()) + 1 1352 else: 1353 base_block_hash = self.tip.sha256 1354 block_time = self.tip.nTime + 1 1355 # First create the coinbase 1356 height = self.block_heights[base_block_hash] + 1 1357 coinbase = create_coinbase(height, self.coinbase_pubkey) 1358 coinbase.vout[0].nValue += additional_coinbase_value 1359 coinbase.rehash() 1360 if spend is None: 1361 block = create_block(base_block_hash, coinbase, block_time, version=version) 1362 else: 1363 coinbase.vout[0].nValue += spend.vout[0].nValue - 1 # all but one satoshi to fees 1364 coinbase.rehash() 1365 tx = self.create_tx(spend, 0, 1, script) # spend 1 satoshi 1366 self.sign_tx(tx, spend) 1367 tx.rehash() 1368 block = create_block(base_block_hash, coinbase, block_time, version=version, txlist=[tx]) 1369 # Block is created. Find a valid nonce. 1370 block.solve() 1371 self.tip = block 1372 self.block_heights[block.sha256] = height 1373 assert number not in self.blocks 1374 self.blocks[number] = block 1375 return block 1376 1377 # save the current tip so it can be spent by a later block 1378 def save_spendable_output(self): 1379 self.log.debug(f"saving spendable output {self.tip.vtx[0]}") 1380 self.spendable_outputs.append(self.tip) 1381 1382 # get an output that we previously marked as spendable 1383 def get_spendable_output(self): 1384 self.log.debug(f"getting spendable output {self.spendable_outputs[0].vtx[0]}") 1385 return self.spendable_outputs.pop(0).vtx[0] 1386 1387 # move the tip back to a previous block 1388 def move_tip(self, number): 1389 self.tip = self.blocks[number] 1390 1391 # adds transactions to the block and updates state 1392 def update_block(self, block_number, new_transactions): 1393 block = self.blocks[block_number] 1394 self.add_transactions_to_block(block, new_transactions) 1395 old_sha256 = block.sha256 1396 block.hashMerkleRoot = block.calc_merkle_root() 1397 block.solve() 1398 # Update the internal state just like in next_block 1399 self.tip = block 1400 if block.sha256 != old_sha256: 1401 self.block_heights[block.sha256] = self.block_heights[old_sha256] 1402 del self.block_heights[old_sha256] 1403 self.blocks[block_number] = block 1404 return block 1405 1406 def bootstrap_p2p(self, timeout=10): 1407 """Add a P2P connection to the node. 1408 1409 Helper to connect and wait for version handshake.""" 1410 self.helper_peer = self.nodes[0].add_p2p_connection(P2PDataStore()) 1411 # We need to wait for the initial getheaders from the peer before we 1412 # start populating our blockstore. If we don't, then we may run ahead 1413 # to the next subtest before we receive the getheaders. We'd then send 1414 # an INV for the next block and receive two getheaders - one for the 1415 # IBD and one for the INV. We'd respond to both and could get 1416 # unexpectedly disconnected if the DoS score for that error is 50. 1417 self.helper_peer.wait_for_getheaders(timeout=timeout) 1418 1419 def reconnect_p2p(self, timeout=60): 1420 """Tear down and bootstrap the P2P connection to the node. 1421 1422 The node gets disconnected several times in this test. This helper 1423 method reconnects the p2p and restarts the network thread.""" 1424 self.nodes[0].disconnect_p2ps() 1425 self.bootstrap_p2p(timeout=timeout) 1426 1427 def send_blocks(self, blocks, success=True, reject_reason=None, force_send=False, reconnect=False, timeout=960): 1428 """Sends blocks to test node. Syncs and verifies that tip has advanced to most recent block. 1429 1430 Call with success = False if the tip shouldn't advance to the most recent block.""" 1431 self.helper_peer.send_blocks_and_test(blocks, self.nodes[0], success=success, reject_reason=reject_reason, force_send=force_send, timeout=timeout, expect_disconnect=reconnect) 1432 1433 if reconnect: 1434 self.reconnect_p2p(timeout=timeout) 1435 1436 1437 if __name__ == '__main__': 1438 FullBlockTest().main()