[tests] Add logging to feature_block.py

This commit is contained in:
John Newbery 2017-11-22 14:07:26 -05:00
parent 3898c4f3d7
commit fc02c12ae9

View file

@ -145,6 +145,7 @@ class FullBlockTest(ComparisonTestFramework):
# \-> b3 (1)
#
# Nothing should happen at this point. We saw b2 first so it takes priority.
self.log.info("Don't reorg to a chain of the same length")
self.move_tip(1)
b3 = self.next_block(3, spend=out[1])
txout_b3 = PreviousSpendableOutput(b3.vtx[1], 0)
@ -154,6 +155,7 @@ class FullBlockTest(ComparisonTestFramework):
#
# genesis -> b1 (0) -> b2 (1)
# \-> b3 (1) -> b4 (2)
self.log.info("Reorg to a longer chain")
self.next_block(4, spend=out[2])
yield self.accepted()
@ -165,6 +167,7 @@ class FullBlockTest(ComparisonTestFramework):
self.save_spendable_output()
yield self.rejected()
self.log.info("Reorg back to the original chain")
self.next_block(6, spend=out[3])
yield self.accepted()
@ -172,6 +175,7 @@ class FullBlockTest(ComparisonTestFramework):
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
# \-> b7 (2) -> b8 (4)
# \-> b3 (1) -> b4 (2)
self.log.info("Reject a chain with a double spend, even if it is longer")
self.move_tip(5)
self.next_block(7, spend=out[2])
yield self.rejected()
@ -183,6 +187,7 @@ class FullBlockTest(ComparisonTestFramework):
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
# \-> b9 (4)
# \-> b3 (1) -> b4 (2)
self.log.info("Reject a block where the miner creates too much coinbase reward")
self.move_tip(6)
self.next_block(9, spend=out[4], additional_coinbase_value=1)
yield self.rejected(RejectResult(16, b'bad-cb-amount'))
@ -191,6 +196,7 @@ class FullBlockTest(ComparisonTestFramework):
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
# \-> b10 (3) -> b11 (4)
# \-> b3 (1) -> b4 (2)
self.log.info("Reject a chain where the miner creates too much coinbase reward, even if the chain is longer")
self.move_tip(5)
self.next_block(10, spend=out[3])
yield self.rejected()
@ -203,6 +209,7 @@ class FullBlockTest(ComparisonTestFramework):
# \-> b12 (3) -> b13 (4) -> b14 (5)
# (b12 added last)
# \-> b3 (1) -> b4 (2)
self.log.info("Reject a chain where the miner creates too much coinbase reward, even if the chain is longer (on a forked chain)")
self.move_tip(5)
b12 = self.next_block(12, spend=out[3])
self.save_spendable_output()
@ -223,15 +230,14 @@ class FullBlockTest(ComparisonTestFramework):
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
# \-> b12 (3) -> b13 (4) -> b15 (5) -> b16 (6)
# \-> b3 (1) -> b4 (2)
# Test that a block with a lot of checksigs is okay
self.log.info("Accept a block with lots of checksigs")
lots_of_checksigs = CScript([OP_CHECKSIG] * (MAX_BLOCK_SIGOPS - 1))
self.move_tip(13)
self.next_block(15, spend=out[5], script=lots_of_checksigs)
yield self.accepted()
self.save_spendable_output()
# Test that a block with too many checksigs is rejected
self.log.info("Reject a block with too many checksigs")
too_many_checksigs = CScript([OP_CHECKSIG] * (MAX_BLOCK_SIGOPS))
self.next_block(16, spend=out[6], script=too_many_checksigs)
yield self.rejected(RejectResult(16, b'bad-blk-sigops'))
@ -240,6 +246,7 @@ class FullBlockTest(ComparisonTestFramework):
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
# \-> b12 (3) -> b13 (4) -> b15 (5) -> b17 (b3.vtx[1])
# \-> b3 (1) -> b4 (2)
self.log.info("Reject a block with a spend from a re-org'ed out tx")
self.move_tip(15)
self.next_block(17, spend=txout_b3)
yield self.rejected(RejectResult(16, b'bad-txns-inputs-missingorspent'))
@ -249,6 +256,7 @@ class FullBlockTest(ComparisonTestFramework):
# \-> b12 (3) -> b13 (4) -> b15 (5)
# \-> b18 (b3.vtx[1]) -> b19 (6)
# \-> b3 (1) -> b4 (2)
self.log.info("Reject a block with a spend from a re-org'ed out tx (on a forked chain)")
self.move_tip(13)
self.next_block(18, spend=txout_b3)
yield self.rejected()
@ -260,6 +268,7 @@ class FullBlockTest(ComparisonTestFramework):
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
# \-> b12 (3) -> b13 (4) -> b15 (5) -> b20 (7)
# \-> b3 (1) -> b4 (2)
self.log.info("Reject a block spending an immature coinbase.")
self.move_tip(15)
self.next_block(20, spend=out[7])
yield self.rejected(RejectResult(16, b'bad-txns-premature-spend-of-coinbase'))
@ -269,6 +278,7 @@ class FullBlockTest(ComparisonTestFramework):
# \-> b12 (3) -> b13 (4) -> b15 (5)
# \-> b21 (6) -> b22 (5)
# \-> b3 (1) -> b4 (2)
self.log.info("Reject a block spending an immature coinbase (on a forked chain)")
self.move_tip(13)
self.next_block(21, spend=out[6])
yield self.rejected()
@ -281,6 +291,7 @@ class FullBlockTest(ComparisonTestFramework):
# \-> b12 (3) -> b13 (4) -> b15 (5) -> b23 (6)
# \-> b24 (6) -> b25 (7)
# \-> b3 (1) -> b4 (2)
self.log.info("Accept a block of size MAX_BLOCK_BASE_SIZE")
self.move_tip(15)
b23 = self.next_block(23, spend=out[6])
tx = CTransaction()
@ -294,7 +305,7 @@ class FullBlockTest(ComparisonTestFramework):
yield self.accepted()
self.save_spendable_output()
# Make the next block one byte bigger and check that it fails
self.log.info("Reject a block of size MAX_BLOCK_BASE_SIZE + 1")
self.move_tip(15)
b24 = self.next_block(24, spend=out[6])
script_length = MAX_BLOCK_BASE_SIZE - len(b24.serialize()) - 69
@ -312,6 +323,7 @@ class FullBlockTest(ComparisonTestFramework):
# \-> b12 (3) -> b13 (4) -> b15 (5) -> b23 (6) -> b30 (7)
# \-> ... (6) -> ... (7)
# \-> b3 (1) -> b4 (2)
self.log.info("Reject a block with coinbase input script size out of range")
self.move_tip(15)
b26 = self.next_block(26, spend=out[6])
b26.vtx[0].vin[0].scriptSig = b'\x00'
@ -355,6 +367,7 @@ class FullBlockTest(ComparisonTestFramework):
#
# MULTISIG: each op code counts as 20 sigops. To create the edge case, pack another 19 sigops at the end.
self.log.info("Accept a block with the max number of OP_CHECKMULTISIG sigops")
lots_of_multisigs = CScript([OP_CHECKMULTISIG] * ((MAX_BLOCK_SIGOPS - 1) // 20) + [OP_CHECKSIG] * 19)
b31 = self.next_block(31, spend=out[8], script=lots_of_multisigs)
assert_equal(get_legacy_sigopcount_block(b31), MAX_BLOCK_SIGOPS)
@ -362,29 +375,34 @@ class FullBlockTest(ComparisonTestFramework):
self.save_spendable_output()
# this goes over the limit because the coinbase has one sigop
self.log.info("Reject a block with too many OP_CHECKMULTISIG sigops")
too_many_multisigs = CScript([OP_CHECKMULTISIG] * (MAX_BLOCK_SIGOPS // 20))
b32 = self.next_block(32, spend=out[9], script=too_many_multisigs)
assert_equal(get_legacy_sigopcount_block(b32), MAX_BLOCK_SIGOPS + 1)
yield self.rejected(RejectResult(16, b'bad-blk-sigops'))
# CHECKMULTISIGVERIFY
self.log.info("Accept a block with the max number of OP_CHECKMULTISIGVERIFY sigops")
self.move_tip(31)
lots_of_multisigs = CScript([OP_CHECKMULTISIGVERIFY] * ((MAX_BLOCK_SIGOPS - 1) // 20) + [OP_CHECKSIG] * 19)
self.next_block(33, spend=out[9], script=lots_of_multisigs)
yield self.accepted()
self.save_spendable_output()
self.log.info("Reject a block with too many OP_CHECKMULTISIGVERIFY sigops")
too_many_multisigs = CScript([OP_CHECKMULTISIGVERIFY] * (MAX_BLOCK_SIGOPS // 20))
self.next_block(34, spend=out[10], script=too_many_multisigs)
yield self.rejected(RejectResult(16, b'bad-blk-sigops'))
# CHECKSIGVERIFY
self.log.info("Accept a block with the max number of OP_CHECKSIGVERIFY sigops")
self.move_tip(33)
lots_of_checksigs = CScript([OP_CHECKSIGVERIFY] * (MAX_BLOCK_SIGOPS - 1))
b35 = self.next_block(35, spend=out[10], script=lots_of_checksigs)
yield self.accepted()
self.save_spendable_output()
self.log.info("Reject a block with too many OP_CHECKSIGVERIFY sigops")
too_many_checksigs = CScript([OP_CHECKSIGVERIFY] * (MAX_BLOCK_SIGOPS))
self.next_block(36, spend=out[11], script=too_many_checksigs)
yield self.rejected(RejectResult(16, b'bad-blk-sigops'))
@ -398,6 +416,7 @@ class FullBlockTest(ComparisonTestFramework):
#
# save 37's spendable output, but then double-spend out11 to invalidate the block
self.log.info("Reject a block spending transaction from a block which failed to connect")
self.move_tip(35)
b37 = self.next_block(37, spend=out[11])
txout_b37 = PreviousSpendableOutput(b37.vtx[1], 0)
@ -421,6 +440,7 @@ class FullBlockTest(ComparisonTestFramework):
# redeem_script = COINBASE_PUBKEY, (OP_2DUP+OP_CHECKSIGVERIFY) * 5, OP_CHECKSIG
# p2sh_script = OP_HASH160, ripemd160(sha256(script)), OP_EQUAL
#
self.log.info("Check P2SH SIGOPS are correctly counted")
self.move_tip(35)
b39 = self.next_block(39)
b39_outputs = 0
@ -467,6 +487,7 @@ class FullBlockTest(ComparisonTestFramework):
#
# b41 does the same, less one, so it has the maximum sigops permitted.
#
self.log.info("Reject a block with too many P2SH sigops")
self.move_tip(39)
b40 = self.next_block(40, spend=out[12])
sigops = get_legacy_sigopcount_block(b40)
@ -501,6 +522,7 @@ class FullBlockTest(ComparisonTestFramework):
yield self.rejected(RejectResult(16, b'bad-blk-sigops'))
# same as b40, but one less sigop
self.log.info("Accept a block with the max number of P2SH sigops")
self.move_tip(39)
self.next_block(41, spend=None)
self.update_block(41, b40.vtx[1:-1])
@ -533,6 +555,7 @@ class FullBlockTest(ComparisonTestFramework):
# The next few blocks are going to be created "by hand" since they'll do funky things, such as having
# the first transaction be non-coinbase, etc. The purpose of b44 is to make sure this works.
self.log.info("Build block 44 manually")
height = self.block_heights[self.tip.sha256] + 1
coinbase = create_coinbase(height, self.coinbase_pubkey)
b44 = CBlock()
@ -547,7 +570,7 @@ class FullBlockTest(ComparisonTestFramework):
self.blocks[44] = b44
yield self.accepted()
# A block with a non-coinbase as the first tx
self.log.info("Reject a block with a non-coinbase as the first tx")
non_coinbase = self.create_tx(out[15].tx, out[15].n, 1)
b45 = CBlock()
b45.nTime = self.tip.nTime + 1
@ -562,7 +585,7 @@ class FullBlockTest(ComparisonTestFramework):
self.blocks[45] = b45
yield self.rejected(RejectResult(16, b'bad-cb-missing'))
# A block with no txns
self.log.info("Reject a block with no transactions")
self.move_tip(44)
b46 = CBlock()
b46.nTime = b44.nTime + 1
@ -577,7 +600,7 @@ class FullBlockTest(ComparisonTestFramework):
self.blocks[46] = b46
yield self.rejected(RejectResult(16, b'bad-blk-length'))
# A block with invalid work
self.log.info("Reject a block with invalid work")
self.move_tip(44)
b47 = self.next_block(47, solve=False)
target = uint256_from_compact(b47.nBits)
@ -586,35 +609,35 @@ class FullBlockTest(ComparisonTestFramework):
b47.rehash()
yield self.rejected(RejectResult(16, b'high-hash'))
# A block with timestamp > 2 hrs in the future
self.log.info("Reject a block with a timestamp >2 hours in the future")
self.move_tip(44)
b48 = self.next_block(48, solve=False)
b48.nTime = int(time.time()) + 60 * 60 * 3
b48.solve()
yield self.rejected(RejectResult(16, b'time-too-new'))
# A block with an invalid merkle hash
self.log.info("Reject a block with invalid merkle hash")
self.move_tip(44)
b49 = self.next_block(49)
b49.hashMerkleRoot += 1
b49.solve()
yield self.rejected(RejectResult(16, b'bad-txnmrklroot'))
# A block with an incorrect POW limit
self.log.info("Reject a block with incorrect POW limit")
self.move_tip(44)
b50 = self.next_block(50)
b50.nBits = b50.nBits - 1
b50.solve()
yield self.rejected(RejectResult(16, b'bad-diffbits'))
# A block with two coinbase txns
self.log.info("Reject a block with two coinbase transactions")
self.move_tip(44)
self.next_block(51)
cb2 = create_coinbase(51, self.coinbase_pubkey)
self.update_block(51, [cb2])
yield self.rejected(RejectResult(16, b'bad-cb-multiple'))
# A block w/ duplicate txns
self.log.info("Reject a block with duplicate transactions")
# Note: txns have to be in the right position in the merkle tree to trigger this error
self.move_tip(44)
b52 = self.next_block(52, spend=out[15])
@ -631,7 +654,7 @@ class FullBlockTest(ComparisonTestFramework):
yield self.rejected() # rejected since b44 is at same height
self.save_spendable_output()
# invalid timestamp (b35 is 5 blocks back, so its time is MedianTimePast)
self.log.info("Reject a block with timestamp before MedianTimePast")
b54 = self.next_block(54, spend=out[15])
b54.nTime = b35.nTime - 1
b54.solve()
@ -680,6 +703,7 @@ class FullBlockTest(ComparisonTestFramework):
b57 = self.update_block(57, [tx, tx1])
# b56 - copy b57, add a duplicate tx
self.log.info("Reject a block with a duplicate transaction in the Merkle Tree (but with a valid Merkle Root)")
self.move_tip(55)
b56 = copy.deepcopy(b57)
self.blocks[56] = b56
@ -699,6 +723,7 @@ class FullBlockTest(ComparisonTestFramework):
b57p2 = self.update_block("57p2", [tx, tx1, tx2, tx3, tx4])
# b56p2 - copy b57p2, duplicate two non-consecutive tx's
self.log.info("Reject a block with two duplicate transactions in the Merkle Tree (but with a valid Merkle Root)")
self.move_tip(55)
b56p2 = copy.deepcopy(b57p2)
self.blocks["b56p2"] = b56p2
@ -721,6 +746,7 @@ class FullBlockTest(ComparisonTestFramework):
#
# tx with prevout.n out of range
self.log.info("Reject a block with a transaction with prevout.n out of range")
self.move_tip(57)
self.next_block(58, spend=out[17])
tx = CTransaction()
@ -732,6 +758,7 @@ class FullBlockTest(ComparisonTestFramework):
yield self.rejected(RejectResult(16, b'bad-txns-inputs-missingorspent'))
# tx with output value > input value out of range
self.log.info("Reject a block with a transaction with outputs > inputs")
self.move_tip(57)
self.next_block(59)
tx = self.create_and_sign_transaction(out[17].tx, out[17].n, 51 * COIN)
@ -753,6 +780,7 @@ class FullBlockTest(ComparisonTestFramework):
# not-fully-spent transaction in the same chain. To test, make identical coinbases;
# the second one should be rejected.
#
self.log.info("Reject a block with a transaction with a duplicate hash of a previous transaction (BIP30)")
self.move_tip(60)
b61 = self.next_block(61, spend=out[18])
b61.vtx[0].vin[0].scriptSig = b60.vtx[0].vin[0].scriptSig # equalize the coinbases
@ -766,6 +794,7 @@ class FullBlockTest(ComparisonTestFramework):
# -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17)
# \-> b62 (18)
#
self.log.info("Reject a block with a transaction with a nonfinal locktime")
self.move_tip(60)
self.next_block(62)
tx = CTransaction()
@ -783,6 +812,7 @@ class FullBlockTest(ComparisonTestFramework):
# -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17)
# \-> b63 (-)
#
self.log.info("Reject a block with a coinbase transaction with a nonfinal locktime")
self.move_tip(60)
b63 = self.next_block(63)
b63.vtx[0].nLockTime = 0xffffffff
@ -805,6 +835,7 @@ class FullBlockTest(ComparisonTestFramework):
# b64a is a bloated block (non-canonical varint)
# b64 is a good block (same as b64 but w/ canonical varint)
#
self.log.info("Accept a valid block even if a bloated version of the block has previously been sent")
self.move_tip(60)
regular_block = self.next_block("64a", spend=out[18])
@ -841,6 +872,7 @@ class FullBlockTest(ComparisonTestFramework):
#
# -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19)
#
self.log.info("Accept a block with a transaction spending an output created in the same block")
self.move_tip(64)
self.next_block(65)
tx1 = self.create_and_sign_transaction(out[19].tx, out[19].n, out[19].tx.vout[0].nValue)
@ -853,6 +885,7 @@ class FullBlockTest(ComparisonTestFramework):
#
# -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19)
# \-> b66 (20)
self.log.info("Reject a block with a transaction spending an output created later in the same block")
self.move_tip(65)
self.next_block(66)
tx1 = self.create_and_sign_transaction(out[20].tx, out[20].n, out[20].tx.vout[0].nValue)
@ -866,6 +899,7 @@ class FullBlockTest(ComparisonTestFramework):
# \-> b67 (20)
#
#
self.log.info("Reject a block with a transaction double spending a transaction creted in the same block")
self.move_tip(65)
self.next_block(67)
tx1 = self.create_and_sign_transaction(out[20].tx, out[20].n, out[20].tx.vout[0].nValue)
@ -886,12 +920,14 @@ class FullBlockTest(ComparisonTestFramework):
# b69 - coinbase with extra 10 satoshis, and a tx that gives a 10 satoshi fee
# this succeeds
#
self.log.info("Reject a block trying to claim too much subsidy in the coinbase transaction")
self.move_tip(65)
self.next_block(68, additional_coinbase_value=10)
tx = self.create_and_sign_transaction(out[20].tx, out[20].n, out[20].tx.vout[0].nValue - 9)
self.update_block(68, [tx])
yield self.rejected(RejectResult(16, b'bad-cb-amount'))
self.log.info("Accept a block claiming the correct subsidy in the coinbase transaction")
self.move_tip(65)
b69 = self.next_block(69, additional_coinbase_value=10)
tx = self.create_and_sign_transaction(out[20].tx, out[20].n, out[20].tx.vout[0].nValue - 10)
@ -904,6 +940,7 @@ class FullBlockTest(ComparisonTestFramework):
# -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20)
# \-> b70 (21)
#
self.log.info("Reject a block containing a transaction spending from a non-existent input")
self.move_tip(69)
self.next_block(70, spend=out[21])
bogus_tx = CTransaction()
@ -921,7 +958,7 @@ class FullBlockTest(ComparisonTestFramework):
#
# b72 is a good block.
# b71 is a copy of 72, but re-adds one of its transactions. However, it has the same hash as b71.
#
self.log.info("Reject a block containing a duplicate transaction but with the same Merkle root (Merkle tree malleability")
self.move_tip(69)
b72 = self.next_block(72)
tx1 = self.create_and_sign_transaction(out[21].tx, out[21].n, 2)
@ -958,7 +995,7 @@ class FullBlockTest(ComparisonTestFramework):
# bytearray[20,000-20,003]: 521 (max_script_element_size+1, in little-endian format)
# bytearray[20,004-20,525]: unread data (script_element)
# bytearray[20,526] : OP_CHECKSIG (this puts us over the limit)
#
self.log.info("Reject a block containing too many sigops after a large script element")
self.move_tip(72)
b73 = self.next_block(73)
size = MAX_BLOCK_SIGOPS - 1 + MAX_SCRIPT_ELEMENT_SIZE + 1 + 5 + 1
@ -986,8 +1023,7 @@ class FullBlockTest(ComparisonTestFramework):
#
# b74 fails because we put MAX_BLOCK_SIGOPS+1 before the element
# b75 succeeds because we put MAX_BLOCK_SIGOPS before the element
#
#
self.log.info("Check sigops are counted correctly after an invalid script element")
self.move_tip(72)
self.next_block(74)
size = MAX_BLOCK_SIGOPS - 1 + MAX_SCRIPT_ELEMENT_SIZE + 42 # total = 20,561
@ -1043,7 +1079,7 @@ class FullBlockTest(ComparisonTestFramework):
# To get around this issue, we construct transactions which are not signed and which
# spend to OP_TRUE. If the standard-ness rules change, this test would need to be
# updated. (Perhaps to spend to a P2SH OP_TRUE script)
#
self.log.info("Test transaction resurrection during a re-org")
self.move_tip(76)
self.next_block(77)
tx77 = self.create_and_sign_transaction(out[24].tx, out[24].n, 10 * COIN)
@ -1087,6 +1123,7 @@ class FullBlockTest(ComparisonTestFramework):
#
# -> b81 (26) -> b82 (27) -> b83 (28)
#
self.log.info("Accept a block with invalid opcodes in dead execution paths")
self.next_block(83)
op_codes = [OP_IF, OP_INVALIDOPCODE, OP_ELSE, OP_TRUE, OP_ENDIF]
script = CScript(op_codes)
@ -1105,7 +1142,7 @@ class FullBlockTest(ComparisonTestFramework):
# -> b81 (26) -> b82 (27) -> b83 (28) -> b84 (29) -> b87 (30) -> b88 (31)
# \-> b85 (29) -> b86 (30) \-> b89a (32)
#
#
self.log.info("Test re-orging blocks with OP_RETURN in them")
self.next_block(84)
tx1 = self.create_tx(out[29].tx, out[29].n, 0, CScript([OP_RETURN]))
tx1.vout.append(CTxOut(0, CScript([OP_TRUE])))
@ -1149,6 +1186,8 @@ class FullBlockTest(ComparisonTestFramework):
self.update_block("89a", [tx])
yield self.rejected()
self.log.info("Test a re-org of one week's worth of blocks (1088 blocks)")
self.move_tip(88)
LARGE_REORG_SIZE = 1088
test1 = TestInstance(sync_every_block=False)