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