Merge #14119: qa: Read reject reasons from debug log, not p2p messages
fac3e22b18
qa: Read reject reasons from debug log, not p2p messages (MarcoFalke)
Pull request description:
For local testing we don't need to rely on p2p messages just to assert a reject reason.
Replace reading p2p messages with reading from the debug log file.
Tree-SHA512: fa59598ecf5e00cfb420ef1892d90aa415501fd882e1c608894dc577b0d00e93a442326d3a9167fef77d26aafbe345b730b49109982ccad68a5942384564a90b
This commit is contained in:
commit
cb25cd6aa1
8 changed files with 138 additions and 191 deletions
|
@ -169,7 +169,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
self.log.info("Reject a block where the miner creates too much coinbase reward")
|
||||
self.move_tip(6)
|
||||
b9 = self.next_block(9, spend=out[4], additional_coinbase_value=1)
|
||||
self.sync_blocks([b9], success=False, reject_code=16, reject_reason=b'bad-cb-amount', reconnect=True)
|
||||
self.sync_blocks([b9], success=False, reject_reason='bad-cb-amount', reconnect=True)
|
||||
|
||||
# Create a fork that ends in a block with too much fee (the one that causes the reorg)
|
||||
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
|
||||
|
@ -181,7 +181,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
self.sync_blocks([b10], False)
|
||||
|
||||
b11 = self.next_block(11, spend=out[4], additional_coinbase_value=1)
|
||||
self.sync_blocks([b11], success=False, reject_code=16, reject_reason=b'bad-cb-amount', reconnect=True)
|
||||
self.sync_blocks([b11], success=False, reject_reason='bad-cb-amount', reconnect=True)
|
||||
|
||||
# Try again, but with a valid fork first
|
||||
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
|
||||
|
@ -194,7 +194,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
b13 = self.next_block(13, spend=out[4])
|
||||
self.save_spendable_output()
|
||||
b14 = self.next_block(14, spend=out[5], additional_coinbase_value=1)
|
||||
self.sync_blocks([b12, b13, b14], success=False, reject_code=16, reject_reason=b'bad-cb-amount', reconnect=True)
|
||||
self.sync_blocks([b12, b13, b14], success=False, reject_reason='bad-cb-amount', reconnect=True)
|
||||
|
||||
# New tip should be b13.
|
||||
assert_equal(node.getbestblockhash(), b13.hash)
|
||||
|
@ -213,7 +213,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
self.log.info("Reject a block with too many checksigs")
|
||||
too_many_checksigs = CScript([OP_CHECKSIG] * (MAX_BLOCK_SIGOPS))
|
||||
b16 = self.next_block(16, spend=out[6], script=too_many_checksigs)
|
||||
self.sync_blocks([b16], success=False, reject_code=16, reject_reason=b'bad-blk-sigops', reconnect=True)
|
||||
self.sync_blocks([b16], success=False, reject_reason='bad-blk-sigops', reconnect=True)
|
||||
|
||||
# Attempt to spend a transaction created on a different fork
|
||||
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
|
||||
|
@ -222,7 +222,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
self.log.info("Reject a block with a spend from a re-org'ed out tx")
|
||||
self.move_tip(15)
|
||||
b17 = self.next_block(17, spend=txout_b3)
|
||||
self.sync_blocks([b17], success=False, reject_code=16, reject_reason=b'bad-txns-inputs-missingorspent', reconnect=True)
|
||||
self.sync_blocks([b17], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True)
|
||||
|
||||
# Attempt to spend a transaction created on a different fork (on a fork this time)
|
||||
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
|
||||
|
@ -235,7 +235,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
self.sync_blocks([b18], False)
|
||||
|
||||
b19 = self.next_block(19, spend=out[6])
|
||||
self.sync_blocks([b19], success=False, reject_code=16, reject_reason=b'bad-txns-inputs-missingorspent', reconnect=True)
|
||||
self.sync_blocks([b19], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True)
|
||||
|
||||
# Attempt to spend a coinbase at depth too low
|
||||
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
|
||||
|
@ -244,7 +244,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
self.log.info("Reject a block spending an immature coinbase.")
|
||||
self.move_tip(15)
|
||||
b20 = self.next_block(20, spend=out[7])
|
||||
self.sync_blocks([b20], success=False, reject_code=16, reject_reason=b'bad-txns-premature-spend-of-coinbase')
|
||||
self.sync_blocks([b20], success=False, reject_reason='bad-txns-premature-spend-of-coinbase')
|
||||
|
||||
# Attempt to spend a coinbase at depth too low (on a fork this time)
|
||||
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
|
||||
|
@ -257,7 +257,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
self.sync_blocks([b21], False)
|
||||
|
||||
b22 = self.next_block(22, spend=out[5])
|
||||
self.sync_blocks([b22], success=False, reject_code=16, reject_reason=b'bad-txns-premature-spend-of-coinbase')
|
||||
self.sync_blocks([b22], success=False, reject_reason='bad-txns-premature-spend-of-coinbase')
|
||||
|
||||
# Create a block on either side of MAX_BLOCK_BASE_SIZE and make sure its accepted/rejected
|
||||
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
|
||||
|
@ -286,7 +286,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
tx.vout = [CTxOut(0, script_output)]
|
||||
b24 = self.update_block(24, [tx])
|
||||
assert_equal(len(b24.serialize()), MAX_BLOCK_BASE_SIZE + 1)
|
||||
self.sync_blocks([b24], success=False, reject_code=16, reject_reason=b'bad-blk-length', reconnect=True)
|
||||
self.sync_blocks([b24], success=False, reject_reason='bad-blk-length', reconnect=True)
|
||||
|
||||
b25 = self.next_block(25, spend=out[7])
|
||||
self.sync_blocks([b25], False)
|
||||
|
@ -304,7 +304,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
# update_block causes the merkle root to get updated, even with no new
|
||||
# transactions, and updates the required state.
|
||||
b26 = self.update_block(26, [])
|
||||
self.sync_blocks([b26], success=False, reject_code=16, reject_reason=b'bad-cb-length', reconnect=True)
|
||||
self.sync_blocks([b26], success=False, reject_reason='bad-cb-length', reconnect=True)
|
||||
|
||||
# Extend the b26 chain to make sure bitcoind isn't accepting b26
|
||||
b27 = self.next_block(27, spend=out[7])
|
||||
|
@ -316,7 +316,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
b28.vtx[0].vin[0].scriptSig = b'\x00' * 101
|
||||
b28.vtx[0].rehash()
|
||||
b28 = self.update_block(28, [])
|
||||
self.sync_blocks([b28], success=False, reject_code=16, reject_reason=b'bad-cb-length', reconnect=True)
|
||||
self.sync_blocks([b28], success=False, reject_reason='bad-cb-length', reconnect=True)
|
||||
|
||||
# Extend the b28 chain to make sure bitcoind isn't accepting b28
|
||||
b29 = self.next_block(29, spend=out[7])
|
||||
|
@ -352,7 +352,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
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)
|
||||
self.sync_blocks([b32], success=False, reject_code=16, reject_reason=b'bad-blk-sigops', reconnect=True)
|
||||
self.sync_blocks([b32], success=False, reject_reason='bad-blk-sigops', reconnect=True)
|
||||
|
||||
# CHECKMULTISIGVERIFY
|
||||
self.log.info("Accept a block with the max number of OP_CHECKMULTISIGVERIFY sigops")
|
||||
|
@ -365,7 +365,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
self.log.info("Reject a block with too many OP_CHECKMULTISIGVERIFY sigops")
|
||||
too_many_multisigs = CScript([OP_CHECKMULTISIGVERIFY] * (MAX_BLOCK_SIGOPS // 20))
|
||||
b34 = self.next_block(34, spend=out[10], script=too_many_multisigs)
|
||||
self.sync_blocks([b34], success=False, reject_code=16, reject_reason=b'bad-blk-sigops', reconnect=True)
|
||||
self.sync_blocks([b34], success=False, reject_reason='bad-blk-sigops', reconnect=True)
|
||||
|
||||
# CHECKSIGVERIFY
|
||||
self.log.info("Accept a block with the max number of OP_CHECKSIGVERIFY sigops")
|
||||
|
@ -378,7 +378,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
self.log.info("Reject a block with too many OP_CHECKSIGVERIFY sigops")
|
||||
too_many_checksigs = CScript([OP_CHECKSIGVERIFY] * (MAX_BLOCK_SIGOPS))
|
||||
b36 = self.next_block(36, spend=out[11], script=too_many_checksigs)
|
||||
self.sync_blocks([b36], success=False, reject_code=16, reject_reason=b'bad-blk-sigops', reconnect=True)
|
||||
self.sync_blocks([b36], success=False, reject_reason='bad-blk-sigops', reconnect=True)
|
||||
|
||||
# Check spending of a transaction in a block which failed to connect
|
||||
#
|
||||
|
@ -395,12 +395,12 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
txout_b37 = b37.vtx[1]
|
||||
tx = self.create_and_sign_transaction(out[11], 0)
|
||||
b37 = self.update_block(37, [tx])
|
||||
self.sync_blocks([b37], success=False, reject_code=16, reject_reason=b'bad-txns-inputs-missingorspent', reconnect=True)
|
||||
self.sync_blocks([b37], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True)
|
||||
|
||||
# attempt to spend b37's first non-coinbase tx, at which point b37 was still considered valid
|
||||
self.move_tip(35)
|
||||
b38 = self.next_block(38, spend=txout_b37)
|
||||
self.sync_blocks([b38], success=False, reject_code=16, reject_reason=b'bad-txns-inputs-missingorspent', reconnect=True)
|
||||
self.sync_blocks([b38], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True)
|
||||
|
||||
# Check P2SH SigOp counting
|
||||
#
|
||||
|
@ -492,7 +492,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
tx.rehash()
|
||||
new_txs.append(tx)
|
||||
self.update_block(40, new_txs)
|
||||
self.sync_blocks([b40], success=False, reject_code=16, reject_reason=b'bad-blk-sigops', reconnect=True)
|
||||
self.sync_blocks([b40], success=False, reject_reason='bad-blk-sigops', reconnect=True)
|
||||
|
||||
# same as b40, but one less sigop
|
||||
self.log.info("Accept a block with the max number of P2SH sigops")
|
||||
|
@ -555,7 +555,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
self.block_heights[b45.sha256] = self.block_heights[self.tip.sha256] + 1
|
||||
self.tip = b45
|
||||
self.blocks[45] = b45
|
||||
self.sync_blocks([b45], success=False, reject_code=16, reject_reason=b'bad-cb-missing', reconnect=True)
|
||||
self.sync_blocks([b45], success=False, reject_reason='bad-cb-missing', reconnect=True)
|
||||
|
||||
self.log.info("Reject a block with no transactions")
|
||||
self.move_tip(44)
|
||||
|
@ -570,7 +570,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
self.tip = b46
|
||||
assert 46 not in self.blocks
|
||||
self.blocks[46] = b46
|
||||
self.sync_blocks([b46], success=False, reject_code=16, reject_reason=b'bad-blk-length', reconnect=True)
|
||||
self.sync_blocks([b46], success=False, reject_reason='bad-blk-length', reconnect=True)
|
||||
|
||||
self.log.info("Reject a block with invalid work")
|
||||
self.move_tip(44)
|
||||
|
@ -593,7 +593,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
b49 = self.next_block(49)
|
||||
b49.hashMerkleRoot += 1
|
||||
b49.solve()
|
||||
self.sync_blocks([b49], success=False, reject_code=16, reject_reason=b'bad-txnmrklroot', reconnect=True)
|
||||
self.sync_blocks([b49], success=False, reject_reason='bad-txnmrklroot', reconnect=True)
|
||||
|
||||
self.log.info("Reject a block with incorrect POW limit")
|
||||
self.move_tip(44)
|
||||
|
@ -607,7 +607,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
b51 = self.next_block(51)
|
||||
cb2 = create_coinbase(51, self.coinbase_pubkey)
|
||||
b51 = self.update_block(51, [cb2])
|
||||
self.sync_blocks([b51], success=False, reject_code=16, reject_reason=b'bad-cb-multiple', reconnect=True)
|
||||
self.sync_blocks([b51], success=False, reject_reason='bad-cb-multiple', reconnect=True)
|
||||
|
||||
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
|
||||
|
@ -615,7 +615,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
b52 = self.next_block(52, spend=out[15])
|
||||
tx = self.create_tx(b52.vtx[1], 0, 1)
|
||||
b52 = self.update_block(52, [tx, tx])
|
||||
self.sync_blocks([b52], success=False, reject_code=16, reject_reason=b'bad-txns-duplicate', reconnect=True)
|
||||
self.sync_blocks([b52], success=False, reject_reason='bad-txns-duplicate', reconnect=True)
|
||||
|
||||
# Test block timestamps
|
||||
# -> b31 (8) -> b33 (9) -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15)
|
||||
|
@ -682,7 +682,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
assert_equal(len(b56.vtx), 3)
|
||||
b56 = self.update_block(56, [tx1])
|
||||
assert_equal(b56.hash, b57.hash)
|
||||
self.sync_blocks([b56], success=False, reject_code=16, reject_reason=b'bad-txns-duplicate', reconnect=True)
|
||||
self.sync_blocks([b56], success=False, reject_reason='bad-txns-duplicate', reconnect=True)
|
||||
|
||||
# b57p2 - a good block with 6 tx'es, don't submit until end
|
||||
self.move_tip(55)
|
||||
|
@ -702,7 +702,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
assert_equal(b56p2.hash, b57p2.hash)
|
||||
assert_equal(len(b56p2.vtx), 6)
|
||||
b56p2 = self.update_block("b56p2", [tx3, tx4])
|
||||
self.sync_blocks([b56p2], success=False, reject_code=16, reject_reason=b'bad-txns-duplicate', reconnect=True)
|
||||
self.sync_blocks([b56p2], success=False, reject_reason='bad-txns-duplicate', reconnect=True)
|
||||
|
||||
self.move_tip("57p2")
|
||||
self.sync_blocks([b57p2], True)
|
||||
|
@ -727,7 +727,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
tx.vout.append(CTxOut(0, b""))
|
||||
tx.calc_sha256()
|
||||
b58 = self.update_block(58, [tx])
|
||||
self.sync_blocks([b58], success=False, reject_code=16, reject_reason=b'bad-txns-inputs-missingorspent', reconnect=True)
|
||||
self.sync_blocks([b58], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True)
|
||||
|
||||
# tx with output value > input value
|
||||
self.log.info("Reject a block with a transaction with outputs > inputs")
|
||||
|
@ -735,7 +735,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
b59 = self.next_block(59)
|
||||
tx = self.create_and_sign_transaction(out[17], 51 * COIN)
|
||||
b59 = self.update_block(59, [tx])
|
||||
self.sync_blocks([b59], success=False, reject_code=16, reject_reason=b'bad-txns-in-belowout', reconnect=True)
|
||||
self.sync_blocks([b59], success=False, reject_reason='bad-txns-in-belowout', reconnect=True)
|
||||
|
||||
# reset to good chain
|
||||
self.move_tip(57)
|
||||
|
@ -759,7 +759,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
b61.vtx[0].rehash()
|
||||
b61 = self.update_block(61, [])
|
||||
assert_equal(b60.vtx[0].serialize(), b61.vtx[0].serialize())
|
||||
self.sync_blocks([b61], success=False, reject_code=16, reject_reason=b'bad-txns-BIP30', reconnect=True)
|
||||
self.sync_blocks([b61], success=False, reject_reason='bad-txns-BIP30', reconnect=True)
|
||||
|
||||
# Test tx.isFinal is properly rejected (not an exhaustive tx.isFinal test, that should be in data-driven transaction tests)
|
||||
#
|
||||
|
@ -776,7 +776,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
assert(tx.vin[0].nSequence < 0xffffffff)
|
||||
tx.calc_sha256()
|
||||
b62 = self.update_block(62, [tx])
|
||||
self.sync_blocks([b62], success=False, reject_code=16, reject_reason=b'bad-txns-nonfinal')
|
||||
self.sync_blocks([b62], success=False, reject_reason='bad-txns-nonfinal')
|
||||
|
||||
# Test a non-final coinbase is also rejected
|
||||
#
|
||||
|
@ -790,7 +790,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
b63.vtx[0].vin[0].nSequence = 0xDEADBEEF
|
||||
b63.vtx[0].rehash()
|
||||
b63 = self.update_block(63, [])
|
||||
self.sync_blocks([b63], success=False, reject_code=16, reject_reason=b'bad-txns-nonfinal')
|
||||
self.sync_blocks([b63], success=False, reject_reason='bad-txns-nonfinal')
|
||||
|
||||
# This checks that a block with a bloated VARINT between the block_header and the array of tx such that
|
||||
# the block is > MAX_BLOCK_BASE_SIZE with the bloated varint, but <= MAX_BLOCK_BASE_SIZE without the bloated varint,
|
||||
|
@ -824,7 +824,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
tx.vin.append(CTxIn(COutPoint(b64a.vtx[1].sha256, 0)))
|
||||
b64a = self.update_block("64a", [tx])
|
||||
assert_equal(len(b64a.serialize()), MAX_BLOCK_BASE_SIZE + 8)
|
||||
self.sync_blocks([b64a], success=False, reject_code=1, reject_reason=b'error parsing message')
|
||||
self.sync_blocks([b64a], success=False, reject_reason='non-canonical ReadCompactSize(): iostream error')
|
||||
|
||||
# bitcoind doesn't disconnect us for sending a bloated block, but if we subsequently
|
||||
# resend the header message, it won't send us the getdata message again. Just
|
||||
|
@ -866,7 +866,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
tx1 = self.create_and_sign_transaction(out[20], out[20].vout[0].nValue)
|
||||
tx2 = self.create_and_sign_transaction(tx1, 1)
|
||||
b66 = self.update_block(66, [tx2, tx1])
|
||||
self.sync_blocks([b66], success=False, reject_code=16, reject_reason=b'bad-txns-inputs-missingorspent', reconnect=True)
|
||||
self.sync_blocks([b66], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True)
|
||||
|
||||
# Attempt to double-spend a transaction created in a block
|
||||
#
|
||||
|
@ -881,7 +881,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
tx2 = self.create_and_sign_transaction(tx1, 1)
|
||||
tx3 = self.create_and_sign_transaction(tx1, 2)
|
||||
b67 = self.update_block(67, [tx1, tx2, tx3])
|
||||
self.sync_blocks([b67], success=False, reject_code=16, reject_reason=b'bad-txns-inputs-missingorspent', reconnect=True)
|
||||
self.sync_blocks([b67], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True)
|
||||
|
||||
# More tests of block subsidy
|
||||
#
|
||||
|
@ -900,7 +900,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
b68 = self.next_block(68, additional_coinbase_value=10)
|
||||
tx = self.create_and_sign_transaction(out[20], out[20].vout[0].nValue - 9)
|
||||
b68 = self.update_block(68, [tx])
|
||||
self.sync_blocks([b68], success=False, reject_code=16, reject_reason=b'bad-cb-amount', reconnect=True)
|
||||
self.sync_blocks([b68], success=False, reject_reason='bad-cb-amount', reconnect=True)
|
||||
|
||||
self.log.info("Accept a block claiming the correct subsidy in the coinbase transaction")
|
||||
self.move_tip(65)
|
||||
|
@ -924,7 +924,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
tx.vin.append(CTxIn(COutPoint(bogus_tx.sha256, 0), b"", 0xffffffff))
|
||||
tx.vout.append(CTxOut(1, b""))
|
||||
b70 = self.update_block(70, [tx])
|
||||
self.sync_blocks([b70], success=False, reject_code=16, reject_reason=b'bad-txns-inputs-missingorspent', reconnect=True)
|
||||
self.sync_blocks([b70], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True)
|
||||
|
||||
# Test accepting an invalid block which has the same hash as a valid one (via merkle tree tricks)
|
||||
#
|
||||
|
@ -949,7 +949,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
assert_equal(b72.sha256, b71.sha256)
|
||||
|
||||
self.move_tip(71)
|
||||
self.sync_blocks([b71], success=False, reject_code=16, reject_reason=b'bad-txns-duplicate', reconnect=True)
|
||||
self.sync_blocks([b71], success=False, reject_reason='bad-txns-duplicate', reconnect=True)
|
||||
|
||||
self.move_tip(72)
|
||||
self.sync_blocks([b72], True)
|
||||
|
@ -987,7 +987,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
tx = self.create_and_sign_transaction(out[22], 1, CScript(a))
|
||||
b73 = self.update_block(73, [tx])
|
||||
assert_equal(get_legacy_sigopcount_block(b73), MAX_BLOCK_SIGOPS + 1)
|
||||
self.sync_blocks([b73], success=False, reject_code=16, reject_reason=b'bad-blk-sigops', reconnect=True)
|
||||
self.sync_blocks([b73], success=False, reject_reason='bad-blk-sigops', reconnect=True)
|
||||
|
||||
# b74/75 - if we push an invalid script element, all previous sigops are counted,
|
||||
# but sigops after the element are not counted.
|
||||
|
@ -1011,7 +1011,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
a[MAX_BLOCK_SIGOPS + 4] = 0xff
|
||||
tx = self.create_and_sign_transaction(out[22], 1, CScript(a))
|
||||
b74 = self.update_block(74, [tx])
|
||||
self.sync_blocks([b74], success=False, reject_code=16, reject_reason=b'bad-blk-sigops', reconnect=True)
|
||||
self.sync_blocks([b74], success=False, reject_reason='bad-blk-sigops', reconnect=True)
|
||||
|
||||
self.move_tip(72)
|
||||
b75 = self.next_block(75)
|
||||
|
@ -1160,7 +1160,7 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
b89a = self.next_block("89a", spend=out[32])
|
||||
tx = self.create_tx(tx1, 0, 0, CScript([OP_TRUE]))
|
||||
b89a = self.update_block("89a", [tx])
|
||||
self.sync_blocks([b89a], success=False, reject_code=16, reject_reason=b'bad-txns-inputs-missingorspent', reconnect=True)
|
||||
self.sync_blocks([b89a], success=False, reject_reason='bad-txns-inputs-missingorspent', reconnect=True)
|
||||
|
||||
self.log.info("Test a re-org of one week's worth of blocks (1088 blocks)")
|
||||
|
||||
|
@ -1309,11 +1309,11 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
self.nodes[0].disconnect_p2ps()
|
||||
self.bootstrap_p2p()
|
||||
|
||||
def sync_blocks(self, blocks, success=True, reject_code=None, reject_reason=None, request_block=True, reconnect=False, timeout=60):
|
||||
def sync_blocks(self, blocks, success=True, reject_reason=None, request_block=True, reconnect=False, timeout=60):
|
||||
"""Sends blocks to test node. Syncs and verifies that tip has advanced to most recent block.
|
||||
|
||||
Call with success = False if the tip shouldn't advance to the most recent block."""
|
||||
self.nodes[0].p2p.send_blocks_and_test(blocks, self.nodes[0], success=success, reject_code=reject_code, reject_reason=reject_reason, request_block=request_block, timeout=timeout)
|
||||
self.nodes[0].p2p.send_blocks_and_test(blocks, self.nodes[0], success=success, reject_reason=reject_reason, request_block=request_block, timeout=timeout, expect_disconnect=reconnect)
|
||||
|
||||
if reconnect:
|
||||
self.reconnect_p2p()
|
||||
|
|
|
@ -10,10 +10,14 @@ Test that the CHECKLOCKTIMEVERIFY soft-fork activates at (regtest) block height
|
|||
|
||||
from test_framework.blocktools import create_coinbase, create_block, create_transaction
|
||||
from test_framework.messages import CTransaction, msg_block, ToHex
|
||||
from test_framework.mininode import mininode_lock, P2PInterface
|
||||
from test_framework.mininode import P2PInterface
|
||||
from test_framework.script import CScript, OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP, CScriptNum
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import assert_equal, bytes_to_hex_str, hex_str_to_bytes, wait_until
|
||||
from test_framework.util import (
|
||||
assert_equal,
|
||||
bytes_to_hex_str,
|
||||
hex_str_to_bytes,
|
||||
)
|
||||
|
||||
from io import BytesIO
|
||||
|
||||
|
@ -51,10 +55,11 @@ def cltv_validate(node, tx, height):
|
|||
list(CScript(new_tx.vin[0].scriptSig)))
|
||||
return new_tx
|
||||
|
||||
|
||||
class BIP65Test(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 1
|
||||
self.extra_args = [['-whitelist=127.0.0.1']]
|
||||
self.extra_args = [['-whitelist=127.0.0.1', '-par=1']] # Use only one script thread to get the exact reject reason for testing
|
||||
self.setup_clean_chain = True
|
||||
|
||||
def run_test(self):
|
||||
|
@ -88,15 +93,11 @@ class BIP65Test(BitcoinTestFramework):
|
|||
block = create_block(tip, create_coinbase(CLTV_HEIGHT), block_time)
|
||||
block.nVersion = 3
|
||||
block.solve()
|
||||
self.nodes[0].p2p.send_and_ping(msg_block(block))
|
||||
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
|
||||
|
||||
wait_until(lambda: "reject" in self.nodes[0].p2p.last_message.keys(), lock=mininode_lock)
|
||||
with mininode_lock:
|
||||
assert_equal(self.nodes[0].p2p.last_message["reject"].code, REJECT_OBSOLETE)
|
||||
assert_equal(self.nodes[0].p2p.last_message["reject"].reason, b'bad-version(0x00000003)')
|
||||
assert_equal(self.nodes[0].p2p.last_message["reject"].data, block.sha256)
|
||||
del self.nodes[0].p2p.last_message["reject"]
|
||||
with self.nodes[0].assert_debug_log(expected_msgs=['{}, bad-version(0x00000003)'.format(block.hash)]):
|
||||
self.nodes[0].p2p.send_and_ping(msg_block(block))
|
||||
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
|
||||
self.nodes[0].p2p.sync_with_ping()
|
||||
|
||||
self.log.info("Test that invalid-according-to-cltv transactions cannot appear in a block")
|
||||
block.nVersion = 4
|
||||
|
@ -118,18 +119,10 @@ class BIP65Test(BitcoinTestFramework):
|
|||
block.hashMerkleRoot = block.calc_merkle_root()
|
||||
block.solve()
|
||||
|
||||
self.nodes[0].p2p.send_and_ping(msg_block(block))
|
||||
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
|
||||
|
||||
wait_until(lambda: "reject" in self.nodes[0].p2p.last_message.keys(), lock=mininode_lock)
|
||||
with mininode_lock:
|
||||
assert self.nodes[0].p2p.last_message["reject"].code in [REJECT_INVALID, REJECT_NONSTANDARD]
|
||||
assert_equal(self.nodes[0].p2p.last_message["reject"].data, block.sha256)
|
||||
if self.nodes[0].p2p.last_message["reject"].code == REJECT_INVALID:
|
||||
# Generic rejection when a block is invalid
|
||||
assert_equal(self.nodes[0].p2p.last_message["reject"].reason, b'block-validation-failed')
|
||||
else:
|
||||
assert b'Negative locktime' in self.nodes[0].p2p.last_message["reject"].reason
|
||||
with self.nodes[0].assert_debug_log(expected_msgs=['CheckInputs on {} failed with non-mandatory-script-verify-flag (Negative locktime)'.format(block.vtx[-1].hash)]):
|
||||
self.nodes[0].p2p.send_and_ping(msg_block(block))
|
||||
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
|
||||
self.nodes[0].p2p.sync_with_ping()
|
||||
|
||||
self.log.info("Test that a version 4 block with a valid-according-to-CLTV transaction is accepted")
|
||||
spendtx = cltv_validate(self.nodes[0], spendtx, CLTV_HEIGHT - 1)
|
||||
|
|
|
@ -165,11 +165,11 @@ class BIP68_112_113Test(BitcoinTestFramework):
|
|||
block.solve()
|
||||
return block
|
||||
|
||||
def sync_blocks(self, blocks, success=True, reject_code=None, reject_reason=None, request_block=True):
|
||||
def sync_blocks(self, blocks, success=True):
|
||||
"""Sends blocks to test node. Syncs and verifies that tip has advanced to most recent block.
|
||||
|
||||
Call with success = False if the tip shouldn't advance to the most recent block."""
|
||||
self.nodes[0].p2p.send_blocks_and_test(blocks, self.nodes[0], success=success, reject_code=reject_code, reject_reason=reject_reason, request_block=request_block)
|
||||
self.nodes[0].p2p.send_blocks_and_test(blocks, self.nodes[0], success=success)
|
||||
|
||||
def run_test(self):
|
||||
self.nodes[0].add_p2p_connection(P2PDataStore())
|
||||
|
|
|
@ -12,7 +12,11 @@ from test_framework.messages import msg_block
|
|||
from test_framework.mininode import mininode_lock, P2PInterface
|
||||
from test_framework.script import CScript
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import assert_equal, bytes_to_hex_str, wait_until
|
||||
from test_framework.util import (
|
||||
assert_equal,
|
||||
bytes_to_hex_str,
|
||||
wait_until,
|
||||
)
|
||||
|
||||
DERSIG_HEIGHT = 1251
|
||||
|
||||
|
@ -42,7 +46,7 @@ def unDERify(tx):
|
|||
class BIP66Test(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 1
|
||||
self.extra_args = [['-whitelist=127.0.0.1']]
|
||||
self.extra_args = [['-whitelist=127.0.0.1', '-par=1', '-enablebip61']] # Use only one script thread to get the exact reject reason for testing
|
||||
self.setup_clean_chain = True
|
||||
|
||||
def run_test(self):
|
||||
|
@ -78,15 +82,11 @@ class BIP66Test(BitcoinTestFramework):
|
|||
block.nVersion = 2
|
||||
block.rehash()
|
||||
block.solve()
|
||||
self.nodes[0].p2p.send_and_ping(msg_block(block))
|
||||
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
|
||||
|
||||
wait_until(lambda: "reject" in self.nodes[0].p2p.last_message.keys(), lock=mininode_lock)
|
||||
with mininode_lock:
|
||||
assert_equal(self.nodes[0].p2p.last_message["reject"].code, REJECT_OBSOLETE)
|
||||
assert_equal(self.nodes[0].p2p.last_message["reject"].reason, b'bad-version(0x00000002)')
|
||||
assert_equal(self.nodes[0].p2p.last_message["reject"].data, block.sha256)
|
||||
del self.nodes[0].p2p.last_message["reject"]
|
||||
with self.nodes[0].assert_debug_log(expected_msgs=['{}, bad-version(0x00000002)'.format(block.hash)]):
|
||||
self.nodes[0].p2p.send_and_ping(msg_block(block))
|
||||
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
|
||||
self.nodes[0].p2p.sync_with_ping()
|
||||
|
||||
self.log.info("Test that transactions with non-DER signatures cannot appear in a block")
|
||||
block.nVersion = 3
|
||||
|
@ -109,23 +109,16 @@ class BIP66Test(BitcoinTestFramework):
|
|||
block.rehash()
|
||||
block.solve()
|
||||
|
||||
self.nodes[0].p2p.send_and_ping(msg_block(block))
|
||||
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
|
||||
with self.nodes[0].assert_debug_log(expected_msgs=['CheckInputs on {} failed with non-mandatory-script-verify-flag (Non-canonical DER signature)'.format(block.vtx[-1].hash)]):
|
||||
self.nodes[0].p2p.send_and_ping(msg_block(block))
|
||||
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
|
||||
self.nodes[0].p2p.sync_with_ping()
|
||||
|
||||
wait_until(lambda: "reject" in self.nodes[0].p2p.last_message.keys(), lock=mininode_lock)
|
||||
with mininode_lock:
|
||||
# We can receive different reject messages depending on whether
|
||||
# bitcoind is running with multiple script check threads. If script
|
||||
# check threads are not in use, then transaction script validation
|
||||
# happens sequentially, and bitcoind produces more specific reject
|
||||
# reasons.
|
||||
assert self.nodes[0].p2p.last_message["reject"].code in [REJECT_INVALID, REJECT_NONSTANDARD]
|
||||
assert_equal(self.nodes[0].p2p.last_message["reject"].data, block.sha256)
|
||||
if self.nodes[0].p2p.last_message["reject"].code == REJECT_INVALID:
|
||||
# Generic rejection when a block is invalid
|
||||
assert_equal(self.nodes[0].p2p.last_message["reject"].reason, b'block-validation-failed')
|
||||
else:
|
||||
assert b'Non-canonical DER signature' in self.nodes[0].p2p.last_message["reject"].reason
|
||||
assert b'Non-canonical DER signature' in self.nodes[0].p2p.last_message["reject"].reason
|
||||
|
||||
self.log.info("Test that a version 3 block with a DERSIG-compliant transaction is accepted")
|
||||
block.vtx[1] = create_transaction(self.nodes[0], self.coinbase_txids[1], self.nodeaddress, amount=1.0)
|
||||
|
|
|
@ -79,7 +79,7 @@ class InvalidBlockRequestTest(BitcoinTestFramework):
|
|||
assert_equal(orig_hash, block2.rehash())
|
||||
assert(block2_orig.vtx != block2.vtx)
|
||||
|
||||
node.p2p.send_blocks_and_test([block2], node, success=False, request_block=False, reject_code=16, reject_reason=b'bad-txns-duplicate')
|
||||
node.p2p.send_blocks_and_test([block2], node, success=False, request_block=False, reject_reason='bad-txns-duplicate')
|
||||
|
||||
self.log.info("Test very broken block.")
|
||||
|
||||
|
@ -92,7 +92,7 @@ class InvalidBlockRequestTest(BitcoinTestFramework):
|
|||
block3.rehash()
|
||||
block3.solve()
|
||||
|
||||
node.p2p.send_blocks_and_test([block3], node, success=False, request_block=False, reject_code=16, reject_reason=b'bad-cb-amount')
|
||||
node.p2p.send_blocks_and_test([block3], node, success=False, request_block=False, reject_reason='bad-cb-amount')
|
||||
|
||||
if __name__ == '__main__':
|
||||
InvalidBlockRequestTest().main()
|
||||
|
|
|
@ -116,7 +116,8 @@ class InvalidTxRequestTest(BitcoinTestFramework):
|
|||
assert_equal(2, len(node.getpeerinfo())) # p2ps[1] is still connected
|
||||
|
||||
self.log.info('Send the withhold tx ... ')
|
||||
node.p2p.send_txs_and_test([tx_withhold], node, success=True)
|
||||
with node.assert_debug_log(expected_msgs=["bad-txns-in-belowout"]):
|
||||
node.p2p.send_txs_and_test([tx_withhold], node, success=True)
|
||||
|
||||
# Transactions that should end up in the mempool
|
||||
expected_mempool = {
|
||||
|
@ -134,18 +135,6 @@ class InvalidTxRequestTest(BitcoinTestFramework):
|
|||
wait_until(lambda: 1 == len(node.getpeerinfo()), timeout=12) # p2ps[1] is no longer connected
|
||||
assert_equal(expected_mempool, set(node.getrawmempool()))
|
||||
|
||||
# restart node with sending BIP61 messages disabled, check that it disconnects without sending the reject message
|
||||
self.log.info('Test a transaction that is rejected, with BIP61 disabled')
|
||||
self.restart_node(0, ['-enablebip61=0', '-persistmempool=0'])
|
||||
self.reconnect_p2p(num_connections=1)
|
||||
with node.assert_debug_log(expected_msgs=[
|
||||
"{} from peer=0 was not accepted: mandatory-script-verify-flag-failed (Invalid OP_IF construction) (code 16)".format(tx1.hash),
|
||||
"disconnecting peer=0",
|
||||
]):
|
||||
node.p2p.send_txs_and_test([tx1], node, success=False, expect_disconnect=True)
|
||||
# send_txs_and_test will have waited for disconnect, so we can safely check that no reject has been received
|
||||
assert_equal(node.p2p.reject_code_received, None)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
InvalidTxRequestTest().main()
|
||||
|
|
|
@ -41,7 +41,6 @@ from test_framework.messages import (
|
|||
from test_framework.mininode import (
|
||||
P2PInterface,
|
||||
mininode_lock,
|
||||
wait_until,
|
||||
)
|
||||
from test_framework.script import (
|
||||
CScript,
|
||||
|
@ -124,32 +123,23 @@ def test_transaction_acceptance(node, p2p, tx, with_witness, accepted, reason=No
|
|||
|
||||
- Submit the transaction over the p2p interface
|
||||
- use the getrawmempool rpc to check for acceptance."""
|
||||
tx_message = msg_tx(tx)
|
||||
if with_witness:
|
||||
tx_message = msg_witness_tx(tx)
|
||||
p2p.send_message(tx_message)
|
||||
p2p.sync_with_ping()
|
||||
assert_equal(tx.hash in node.getrawmempool(), accepted)
|
||||
if (reason is not None and not accepted):
|
||||
# Check the rejection reason as well.
|
||||
with mininode_lock:
|
||||
assert_equal(p2p.last_message["reject"].reason, reason)
|
||||
reason = [reason] if reason else []
|
||||
with node.assert_debug_log(expected_msgs=reason):
|
||||
p2p.send_message(msg_witness_tx(tx) if with_witness else msg_tx(tx))
|
||||
p2p.sync_with_ping()
|
||||
assert_equal(tx.hash in node.getrawmempool(), accepted)
|
||||
|
||||
def test_witness_block(node, p2p, block, accepted, with_witness=True, reason=None):
|
||||
"""Send a block to the node and check that it's accepted
|
||||
|
||||
- Submit the block over the p2p interface
|
||||
- use the getbestblockhash rpc to check for acceptance."""
|
||||
if with_witness:
|
||||
p2p.send_message(msg_witness_block(block))
|
||||
else:
|
||||
p2p.send_message(msg_block(block))
|
||||
p2p.sync_with_ping()
|
||||
assert_equal(node.getbestblockhash() == block.hash, accepted)
|
||||
if (reason is not None and not accepted):
|
||||
# Check the rejection reason as well.
|
||||
with mininode_lock:
|
||||
assert_equal(p2p.last_message["reject"].reason, reason)
|
||||
reason = [reason] if reason else []
|
||||
with node.assert_debug_log(expected_msgs=reason):
|
||||
p2p.send_message(msg_witness_block(block) if with_witness else msg_block(block))
|
||||
p2p.sync_with_ping()
|
||||
assert_equal(node.getbestblockhash() == block.hash, accepted)
|
||||
|
||||
|
||||
class TestP2PConn(P2PInterface):
|
||||
def __init__(self):
|
||||
|
@ -349,8 +339,7 @@ class SegWitTest(BitcoinTestFramework):
|
|||
self.update_witness_block_with_transactions(block, [tx])
|
||||
# Sending witness data before activation is not allowed (anti-spam
|
||||
# rule).
|
||||
test_witness_block(self.nodes[0], self.test_node, block, accepted=False)
|
||||
wait_until(lambda: 'reject' in self.test_node.last_message and self.test_node.last_message["reject"].reason == b"unexpected-witness")
|
||||
test_witness_block(self.nodes[0], self.test_node, block, accepted=False, reason='unexpected-witness')
|
||||
|
||||
# But it should not be permanently marked bad...
|
||||
# Resend without witness information.
|
||||
|
@ -497,7 +486,7 @@ class SegWitTest(BitcoinTestFramework):
|
|||
self.update_witness_block_with_transactions(block, [tx])
|
||||
# Verify that segwit isn't activated. A block serialized with witness
|
||||
# should be rejected prior to activation.
|
||||
test_witness_block(self.nodes[0], self.test_node, block, accepted=False, with_witness=True, reason=b'unexpected-witness')
|
||||
test_witness_block(self.nodes[0], self.test_node, block, accepted=False, with_witness=True, reason='unexpected-witness')
|
||||
# Now send the block without witness. It should be accepted
|
||||
test_witness_block(self.nodes[0], self.test_node, block, accepted=True, with_witness=False)
|
||||
|
||||
|
@ -523,7 +512,7 @@ class SegWitTest(BitcoinTestFramework):
|
|||
|
||||
# When the block is serialized with a witness, the block will be rejected because witness
|
||||
# data isn't allowed in blocks that don't commit to witness data.
|
||||
test_witness_block(self.nodes[0], self.test_node, block, accepted=False, with_witness=True, reason=b'unexpected-witness')
|
||||
test_witness_block(self.nodes[0], self.test_node, block, accepted=False, with_witness=True, reason='unexpected-witness')
|
||||
|
||||
# When the block is serialized without witness, validation fails because the transaction is
|
||||
# invalid (transactions are always validated with SCRIPT_VERIFY_WITNESS so a segwit v0 transaction
|
||||
|
@ -1343,9 +1332,9 @@ class SegWitTest(BitcoinTestFramework):
|
|||
|
||||
# Node will not be blinded to the transaction
|
||||
self.std_node.announce_tx_and_wait_for_getdata(tx3)
|
||||
test_transaction_acceptance(self.nodes[1], self.std_node, tx3, True, False, b'tx-size')
|
||||
test_transaction_acceptance(self.nodes[1], self.std_node, tx3, True, False, 'tx-size')
|
||||
self.std_node.announce_tx_and_wait_for_getdata(tx3)
|
||||
test_transaction_acceptance(self.nodes[1], self.std_node, tx3, True, False, b'tx-size')
|
||||
test_transaction_acceptance(self.nodes[1], self.std_node, tx3, True, False, 'tx-size')
|
||||
|
||||
# Remove witness stuffing, instead add extra witness push on stack
|
||||
tx3.vout[0] = CTxOut(tx2.vout[0].nValue - 1000, CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE]))
|
||||
|
@ -1454,10 +1443,7 @@ class SegWitTest(BitcoinTestFramework):
|
|||
tx3.rehash()
|
||||
# Spending a higher version witness output is not allowed by policy,
|
||||
# even with fRequireStandard=false.
|
||||
test_transaction_acceptance(self.nodes[0], self.test_node, tx3, with_witness=True, accepted=False)
|
||||
self.test_node.sync_with_ping()
|
||||
with mininode_lock:
|
||||
assert(b"reserved for soft-fork upgrades" in self.test_node.last_message["reject"].reason)
|
||||
test_transaction_acceptance(self.nodes[0], self.test_node, tx3, with_witness=True, accepted=False, reason="reserved for soft-fork upgrades")
|
||||
|
||||
# Building a block with the transaction must be valid, however.
|
||||
block = self.build_next_block()
|
||||
|
@ -1551,7 +1537,7 @@ class SegWitTest(BitcoinTestFramework):
|
|||
tx2.rehash()
|
||||
|
||||
# Should fail policy test.
|
||||
test_transaction_acceptance(self.nodes[0], self.test_node, tx2, True, False, b'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)')
|
||||
test_transaction_acceptance(self.nodes[0], self.test_node, tx2, True, False, 'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)')
|
||||
# But passes consensus.
|
||||
block = self.build_next_block()
|
||||
self.update_witness_block_with_transactions(block, [tx2])
|
||||
|
@ -1571,7 +1557,7 @@ class SegWitTest(BitcoinTestFramework):
|
|||
sign_p2pk_witness_input(witness_program, tx3, 0, SIGHASH_ALL, tx2.vout[0].nValue, key)
|
||||
|
||||
# Should fail policy test.
|
||||
test_transaction_acceptance(self.nodes[0], self.test_node, tx3, True, False, b'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)')
|
||||
test_transaction_acceptance(self.nodes[0], self.test_node, tx3, True, False, 'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)')
|
||||
# But passes consensus.
|
||||
block = self.build_next_block()
|
||||
self.update_witness_block_with_transactions(block, [tx3])
|
||||
|
@ -1588,7 +1574,7 @@ class SegWitTest(BitcoinTestFramework):
|
|||
sign_p2pk_witness_input(witness_program, tx4, 0, SIGHASH_ALL, tx3.vout[0].nValue, key)
|
||||
|
||||
# Should fail policy test.
|
||||
test_transaction_acceptance(self.nodes[0], self.test_node, tx4, True, False, b'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)')
|
||||
test_transaction_acceptance(self.nodes[0], self.test_node, tx4, True, False, 'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)')
|
||||
block = self.build_next_block()
|
||||
self.update_witness_block_with_transactions(block, [tx4])
|
||||
test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
|
||||
|
@ -1825,7 +1811,7 @@ class SegWitTest(BitcoinTestFramework):
|
|||
tx2.rehash()
|
||||
# This will be rejected due to a policy check:
|
||||
# No witness is allowed, since it is not a witness program but a p2sh program
|
||||
test_transaction_acceptance(self.nodes[1], self.std_node, tx2, True, False, b'bad-witness-nonstandard')
|
||||
test_transaction_acceptance(self.nodes[1], self.std_node, tx2, True, False, 'bad-witness-nonstandard')
|
||||
|
||||
# If we send without witness, it should be accepted.
|
||||
test_transaction_acceptance(self.nodes[1], self.std_node, tx2, False, True)
|
||||
|
@ -1897,13 +1883,13 @@ class SegWitTest(BitcoinTestFramework):
|
|||
# Testing native P2WSH
|
||||
# Witness stack size, excluding witnessScript, over 100 is non-standard
|
||||
p2wsh_txs[0].wit.vtxinwit[0].scriptWitness.stack = [pad] * 101 + [scripts[0]]
|
||||
test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[0], True, False, b'bad-witness-nonstandard')
|
||||
test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[0], True, False, 'bad-witness-nonstandard')
|
||||
# Non-standard nodes should accept
|
||||
test_transaction_acceptance(self.nodes[0], self.test_node, p2wsh_txs[0], True, True)
|
||||
|
||||
# Stack element size over 80 bytes is non-standard
|
||||
p2wsh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 81] * 100 + [scripts[1]]
|
||||
test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[1], True, False, b'bad-witness-nonstandard')
|
||||
test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[1], True, False, 'bad-witness-nonstandard')
|
||||
# Non-standard nodes should accept
|
||||
test_transaction_acceptance(self.nodes[0], self.test_node, p2wsh_txs[1], True, True)
|
||||
# Standard nodes should accept if element size is not over 80 bytes
|
||||
|
@ -1917,16 +1903,16 @@ class SegWitTest(BitcoinTestFramework):
|
|||
|
||||
# witnessScript size at 3601 bytes is non-standard
|
||||
p2wsh_txs[3].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, pad, scripts[3]]
|
||||
test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[3], True, False, b'bad-witness-nonstandard')
|
||||
test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[3], True, False, 'bad-witness-nonstandard')
|
||||
# Non-standard nodes should accept
|
||||
test_transaction_acceptance(self.nodes[0], self.test_node, p2wsh_txs[3], True, True)
|
||||
|
||||
# Repeating the same tests with P2SH-P2WSH
|
||||
p2sh_txs[0].wit.vtxinwit[0].scriptWitness.stack = [pad] * 101 + [scripts[0]]
|
||||
test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[0], True, False, b'bad-witness-nonstandard')
|
||||
test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[0], True, False, 'bad-witness-nonstandard')
|
||||
test_transaction_acceptance(self.nodes[0], self.test_node, p2sh_txs[0], True, True)
|
||||
p2sh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 81] * 100 + [scripts[1]]
|
||||
test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[1], True, False, b'bad-witness-nonstandard')
|
||||
test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[1], True, False, 'bad-witness-nonstandard')
|
||||
test_transaction_acceptance(self.nodes[0], self.test_node, p2sh_txs[1], True, True)
|
||||
p2sh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 80] * 100 + [scripts[1]]
|
||||
test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[1], True, True)
|
||||
|
@ -1934,7 +1920,7 @@ class SegWitTest(BitcoinTestFramework):
|
|||
test_transaction_acceptance(self.nodes[0], self.test_node, p2sh_txs[2], True, True)
|
||||
test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[2], True, True)
|
||||
p2sh_txs[3].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, pad, scripts[3]]
|
||||
test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[3], True, False, b'bad-witness-nonstandard')
|
||||
test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[3], True, False, 'bad-witness-nonstandard')
|
||||
test_transaction_acceptance(self.nodes[0], self.test_node, p2sh_txs[3], True, True)
|
||||
|
||||
self.nodes[0].generate(1) # Mine and clean up the mempool of non-standard node
|
||||
|
|
|
@ -425,8 +425,6 @@ class P2PDataStore(P2PInterface):
|
|||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.reject_code_received = None
|
||||
self.reject_reason_received = None
|
||||
# store of blocks. key is block hash, value is a CBlock object
|
||||
self.block_store = {}
|
||||
self.last_block_hash = ''
|
||||
|
@ -477,12 +475,7 @@ class P2PDataStore(P2PInterface):
|
|||
if response is not None:
|
||||
self.send_message(response)
|
||||
|
||||
def on_reject(self, message):
|
||||
"""Store reject reason and code for testing."""
|
||||
self.reject_code_received = message.code
|
||||
self.reject_reason_received = message.reason
|
||||
|
||||
def send_blocks_and_test(self, blocks, node, *, success=True, request_block=True, reject_code=None, reject_reason=None, timeout=60):
|
||||
def send_blocks_and_test(self, blocks, node, *, success=True, request_block=True, reject_reason=None, expect_disconnect=False, timeout=60):
|
||||
"""Send blocks to test node and test whether the tip advances.
|
||||
|
||||
- add all blocks to our block_store
|
||||
|
@ -492,66 +485,59 @@ class P2PDataStore(P2PInterface):
|
|||
ensure that any getdata messages are responded to
|
||||
- if success is True: assert that the node's tip advances to the most recent block
|
||||
- if success is False: assert that the node's tip doesn't advance
|
||||
- if reject_code and reject_reason are set: assert that the correct reject message is received"""
|
||||
- if reject_reason is set: assert that the correct reject message is logged"""
|
||||
|
||||
with mininode_lock:
|
||||
self.reject_code_received = None
|
||||
self.reject_reason_received = None
|
||||
|
||||
for block in blocks:
|
||||
self.block_store[block.sha256] = block
|
||||
self.last_block_hash = block.sha256
|
||||
|
||||
self.send_message(msg_headers([CBlockHeader(blocks[-1])]))
|
||||
reject_reason = [reject_reason] if reject_reason else []
|
||||
with node.assert_debug_log(expected_msgs=reject_reason):
|
||||
self.send_message(msg_headers([CBlockHeader(blocks[-1])]))
|
||||
|
||||
if request_block:
|
||||
wait_until(lambda: blocks[-1].sha256 in self.getdata_requests, timeout=timeout, lock=mininode_lock)
|
||||
if request_block:
|
||||
wait_until(lambda: blocks[-1].sha256 in self.getdata_requests, timeout=timeout, lock=mininode_lock)
|
||||
|
||||
if success:
|
||||
wait_until(lambda: node.getbestblockhash() == blocks[-1].hash, timeout=timeout)
|
||||
else:
|
||||
assert node.getbestblockhash() != blocks[-1].hash
|
||||
if expect_disconnect:
|
||||
self.wait_for_disconnect()
|
||||
else:
|
||||
self.sync_with_ping()
|
||||
|
||||
if reject_code is not None:
|
||||
wait_until(lambda: self.reject_code_received == reject_code, lock=mininode_lock)
|
||||
if reject_reason is not None:
|
||||
wait_until(lambda: self.reject_reason_received == reject_reason, lock=mininode_lock)
|
||||
if success:
|
||||
wait_until(lambda: node.getbestblockhash() == blocks[-1].hash, timeout=timeout)
|
||||
else:
|
||||
assert node.getbestblockhash() != blocks[-1].hash
|
||||
|
||||
def send_txs_and_test(self, txs, node, *, success=True, expect_disconnect=False, reject_code=None, reject_reason=None):
|
||||
def send_txs_and_test(self, txs, node, *, success=True, expect_disconnect=False, reject_reason=None):
|
||||
"""Send txs to test node and test whether they're accepted to the mempool.
|
||||
|
||||
- add all txs to our tx_store
|
||||
- send tx messages for all txs
|
||||
- if success is True/False: assert that the txs are/are not accepted to the mempool
|
||||
- if expect_disconnect is True: Skip the sync with ping
|
||||
- if reject_code and reject_reason are set: assert that the correct reject message is received."""
|
||||
- if reject_reason is set: assert that the correct reject message is logged."""
|
||||
|
||||
with mininode_lock:
|
||||
self.reject_code_received = None
|
||||
self.reject_reason_received = None
|
||||
|
||||
for tx in txs:
|
||||
self.tx_store[tx.sha256] = tx
|
||||
|
||||
for tx in txs:
|
||||
self.send_message(msg_tx(tx))
|
||||
|
||||
if expect_disconnect:
|
||||
self.wait_for_disconnect()
|
||||
else:
|
||||
self.sync_with_ping()
|
||||
|
||||
raw_mempool = node.getrawmempool()
|
||||
if success:
|
||||
# Check that all txs are now in the mempool
|
||||
reject_reason = [reject_reason] if reject_reason else []
|
||||
with node.assert_debug_log(expected_msgs=reject_reason):
|
||||
for tx in txs:
|
||||
assert tx.hash in raw_mempool, "{} not found in mempool".format(tx.hash)
|
||||
else:
|
||||
# Check that none of the txs are now in the mempool
|
||||
for tx in txs:
|
||||
assert tx.hash not in raw_mempool, "{} tx found in mempool".format(tx.hash)
|
||||
self.send_message(msg_tx(tx))
|
||||
|
||||
if reject_code is not None:
|
||||
wait_until(lambda: self.reject_code_received == reject_code, lock=mininode_lock)
|
||||
if reject_reason is not None:
|
||||
wait_until(lambda: self.reject_reason_received == reject_reason, lock=mininode_lock)
|
||||
if expect_disconnect:
|
||||
self.wait_for_disconnect()
|
||||
else:
|
||||
self.sync_with_ping()
|
||||
|
||||
raw_mempool = node.getrawmempool()
|
||||
if success:
|
||||
# Check that all txs are now in the mempool
|
||||
for tx in txs:
|
||||
assert tx.hash in raw_mempool, "{} not found in mempool".format(tx.hash)
|
||||
else:
|
||||
# Check that none of the txs are now in the mempool
|
||||
for tx in txs:
|
||||
assert tx.hash not in raw_mempool, "{} tx found in mempool".format(tx.hash)
|
||||
|
|
Loading…
Reference in a new issue