[tests] Fix flake8 warnings in feature_block.py

This commit is contained in:
John Newbery 2017-11-22 12:57:58 -05:00
parent 00d1680498
commit 5cd01d235a

View file

@ -2,15 +2,48 @@
# Copyright (c) 2015-2017 The Bitcoin Core developers # Copyright (c) 2015-2017 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying # Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php. # file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test block processing. """Test block processing."""
import copy
This reimplements tests from the bitcoinj/FullBlockTestGenerator used import struct
by the pull-tester. import time
We use the testing framework in which we expect a particular answer from
each test.
"""
from test_framework.blocktools import create_block, create_coinbase, create_transaction, get_legacy_sigopcount_block
from test_framework.comptool import RejectResult, TestInstance, TestManager
from test_framework.key import CECKey
from test_framework.messages import (
CBlock,
CBlockHeader,
COIN,
COutPoint,
CTransaction,
CTxIn,
CTxOut,
MAX_BLOCK_BASE_SIZE,
uint256_from_compact,
uint256_from_str,
)
from test_framework.mininode import network_thread_start
from test_framework.script import (
CScript,
MAX_SCRIPT_ELEMENT_SIZE,
OP_2DUP,
OP_CHECKMULTISIG,
OP_CHECKMULTISIGVERIFY,
OP_CHECKSIG,
OP_CHECKSIGVERIFY,
OP_ELSE,
OP_ENDIF,
OP_EQUAL,
OP_FALSE,
OP_HASH160,
OP_IF,
OP_INVALIDOPCODE,
OP_RETURN,
OP_TRUE,
SIGHASH_ALL,
SignatureHash,
hash160,
)
from test_framework.test_framework import ComparisonTestFramework from test_framework.test_framework import ComparisonTestFramework
from test_framework.util import * from test_framework.util import *
from test_framework.comptool import TestManager, TestInstance, RejectResult from test_framework.comptool import TestManager, TestInstance, RejectResult
@ -18,11 +51,10 @@ from test_framework.blocktools import *
import time import time
from test_framework.key import CECKey from test_framework.key import CECKey
from test_framework.script import * from test_framework.script import *
from test_framework.mininode import network_thread_start
import struct import struct
class PreviousSpendableOutput(): class PreviousSpendableOutput():
def __init__(self, tx = CTransaction(), n = -1): def __init__(self, tx=CTransaction(), n=-1):
self.tx = tx self.tx = tx
self.n = n # the output we're spending self.n = n # the output we're spending
@ -76,7 +108,7 @@ class FullBlockTest(ComparisonTestFramework):
self.test.run() self.test.run()
def add_transactions_to_block(self, block, tx_list): def add_transactions_to_block(self, block, tx_list):
[ tx.rehash() for tx in tx_list ] [tx.rehash() for tx in tx_list]
block.vtx.extend(tx_list) block.vtx.extend(tx_list)
# this is a little handier to use than the version in blocktools.py # this is a little handier to use than the version in blocktools.py
@ -101,9 +133,9 @@ class FullBlockTest(ComparisonTestFramework):
return tx return tx
def next_block(self, number, spend=None, additional_coinbase_value=0, script=CScript([OP_TRUE]), solve=True): def next_block(self, number, spend=None, additional_coinbase_value=0, script=CScript([OP_TRUE]), solve=True):
if self.tip == None: if self.tip is None:
base_block_hash = self.genesis_hash base_block_hash = self.genesis_hash
block_time = int(time.time())+1 block_time = int(time.time()) + 1
else: else:
base_block_hash = self.tip.sha256 base_block_hash = self.tip.sha256
block_time = self.tip.nTime + 1 block_time = self.tip.nTime + 1
@ -112,10 +144,10 @@ class FullBlockTest(ComparisonTestFramework):
coinbase = create_coinbase(height, self.coinbase_pubkey) coinbase = create_coinbase(height, self.coinbase_pubkey)
coinbase.vout[0].nValue += additional_coinbase_value coinbase.vout[0].nValue += additional_coinbase_value
coinbase.rehash() coinbase.rehash()
if spend == None: if spend is None:
block = create_block(base_block_hash, coinbase, block_time) block = create_block(base_block_hash, coinbase, block_time)
else: else:
coinbase.vout[0].nValue += spend.tx.vout[spend.n].nValue - 1 # all but one satoshi to fees coinbase.vout[0].nValue += spend.tx.vout[spend.n].nValue - 1 # all but one satoshi to fees
coinbase.rehash() coinbase.rehash()
block = create_block(base_block_hash, coinbase, block_time) block = create_block(base_block_hash, coinbase, block_time)
tx = create_transaction(spend.tx, spend.n, b"", 1, script) # spend 1 satoshi tx = create_transaction(spend.tx, spend.n, b"", 1, script) # spend 1 satoshi
@ -148,7 +180,7 @@ class FullBlockTest(ComparisonTestFramework):
return TestInstance([[self.tip, True]]) return TestInstance([[self.tip, True]])
# returns a test case that asserts that the current tip was rejected # returns a test case that asserts that the current tip was rejected
def rejected(reject = None): def rejected(reject=None):
if reject is None: if reject is None:
return TestInstance([[self.tip, False]]) return TestInstance([[self.tip, False]])
else: else:
@ -181,14 +213,12 @@ class FullBlockTest(ComparisonTestFramework):
# these must be updated if consensus changes # these must be updated if consensus changes
MAX_BLOCK_SIGOPS = 20000 MAX_BLOCK_SIGOPS = 20000
# Create a new block # Create a new block
block(0) block(0)
save_spendable_output() save_spendable_output()
yield accepted() yield accepted()
# Now we need that block to mature so we can spend the coinbase.
# Now we need that block to mature so we can spend the coinbase.
test = TestInstance(sync_every_block=False) test = TestInstance(sync_every_block=False)
for i in range(99): for i in range(99):
block(5000 + i) block(5000 + i)
@ -223,7 +253,6 @@ class FullBlockTest(ComparisonTestFramework):
txout_b3 = PreviousSpendableOutput(b3.vtx[1], 0) txout_b3 = PreviousSpendableOutput(b3.vtx[1], 0)
yield rejected() yield rejected()
# Now we add another block to make the alternative chain longer. # Now we add another block to make the alternative chain longer.
# #
# genesis -> b1 (0) -> b2 (1) # genesis -> b1 (0) -> b2 (1)
@ -231,7 +260,6 @@ class FullBlockTest(ComparisonTestFramework):
block(4, spend=out[2]) block(4, spend=out[2])
yield accepted() yield accepted()
# ... and back to the first chain. # ... and back to the first chain.
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
# \-> b3 (1) -> b4 (2) # \-> b3 (1) -> b4 (2)
@ -273,7 +301,6 @@ class FullBlockTest(ComparisonTestFramework):
block(11, spend=out[4], additional_coinbase_value=1) block(11, spend=out[4], additional_coinbase_value=1)
yield rejected(RejectResult(16, b'bad-cb-amount')) yield rejected(RejectResult(16, b'bad-cb-amount'))
# Try again, but with a valid fork first # Try again, but with a valid fork first
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
# \-> b12 (3) -> b13 (4) -> b14 (5) # \-> b12 (3) -> b13 (4) -> b14 (5)
@ -293,7 +320,7 @@ class FullBlockTest(ComparisonTestFramework):
block(14, spend=out[5], additional_coinbase_value=1) block(14, spend=out[5], additional_coinbase_value=1)
yield rejected() yield rejected()
yield TestInstance([[b12, True, b13.sha256]]) # New tip should be b13. yield TestInstance([[b12, True, b13.sha256]]) # New tip should be b13.
# Add a block with MAX_BLOCK_SIGOPS and one with one more sigop # Add a block with MAX_BLOCK_SIGOPS and one with one more sigop
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
@ -307,13 +334,11 @@ class FullBlockTest(ComparisonTestFramework):
yield accepted() yield accepted()
save_spendable_output() save_spendable_output()
# Test that a block with too many checksigs is rejected # Test that a block with too many checksigs is rejected
too_many_checksigs = CScript([OP_CHECKSIG] * (MAX_BLOCK_SIGOPS)) too_many_checksigs = CScript([OP_CHECKSIG] * (MAX_BLOCK_SIGOPS))
block(16, spend=out[6], script=too_many_checksigs) block(16, spend=out[6], script=too_many_checksigs)
yield rejected(RejectResult(16, b'bad-blk-sigops')) yield rejected(RejectResult(16, b'bad-blk-sigops'))
# Attempt to spend a transaction created on a different fork # Attempt to spend a transaction created on a different fork
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
# \-> b12 (3) -> b13 (4) -> b15 (5) -> b17 (b3.vtx[1]) # \-> b12 (3) -> b13 (4) -> b15 (5) -> b17 (b3.vtx[1])
@ -376,10 +401,10 @@ class FullBlockTest(ComparisonTestFramework):
tip(15) tip(15)
b24 = block(24, spend=out[6]) b24 = block(24, spend=out[6])
script_length = MAX_BLOCK_BASE_SIZE - len(b24.serialize()) - 69 script_length = MAX_BLOCK_BASE_SIZE - len(b24.serialize()) - 69
script_output = CScript([b'\x00' * (script_length+1)]) script_output = CScript([b'\x00' * (script_length + 1)])
tx.vout = [CTxOut(0, script_output)] tx.vout = [CTxOut(0, script_output)]
b24 = update_block(24, [tx]) b24 = update_block(24, [tx])
assert_equal(len(b24.serialize()), MAX_BLOCK_BASE_SIZE+1) assert_equal(len(b24.serialize()), MAX_BLOCK_BASE_SIZE + 1)
yield rejected(RejectResult(16, b'bad-blk-length')) yield rejected(RejectResult(16, b'bad-blk-length'))
block(25, spend=out[7]) block(25, spend=out[7])
@ -433,7 +458,7 @@ class FullBlockTest(ComparisonTestFramework):
# #
# MULTISIG: each op code counts as 20 sigops. To create the edge case, pack another 19 sigops at the end. # MULTISIG: each op code counts as 20 sigops. To create the edge case, pack another 19 sigops at the end.
lots_of_multisigs = CScript([OP_CHECKMULTISIG] * ((MAX_BLOCK_SIGOPS-1) // 20) + [OP_CHECKSIG] * 19) lots_of_multisigs = CScript([OP_CHECKMULTISIG] * ((MAX_BLOCK_SIGOPS - 1) // 20) + [OP_CHECKSIG] * 19)
b31 = block(31, spend=out[8], script=lots_of_multisigs) b31 = block(31, spend=out[8], script=lots_of_multisigs)
assert_equal(get_legacy_sigopcount_block(b31), MAX_BLOCK_SIGOPS) assert_equal(get_legacy_sigopcount_block(b31), MAX_BLOCK_SIGOPS)
yield accepted() yield accepted()
@ -445,10 +470,9 @@ class FullBlockTest(ComparisonTestFramework):
assert_equal(get_legacy_sigopcount_block(b32), MAX_BLOCK_SIGOPS + 1) assert_equal(get_legacy_sigopcount_block(b32), MAX_BLOCK_SIGOPS + 1)
yield rejected(RejectResult(16, b'bad-blk-sigops')) yield rejected(RejectResult(16, b'bad-blk-sigops'))
# CHECKMULTISIGVERIFY # CHECKMULTISIGVERIFY
tip(31) tip(31)
lots_of_multisigs = CScript([OP_CHECKMULTISIGVERIFY] * ((MAX_BLOCK_SIGOPS-1) // 20) + [OP_CHECKSIG] * 19) lots_of_multisigs = CScript([OP_CHECKMULTISIGVERIFY] * ((MAX_BLOCK_SIGOPS - 1) // 20) + [OP_CHECKSIG] * 19)
block(33, spend=out[9], script=lots_of_multisigs) block(33, spend=out[9], script=lots_of_multisigs)
yield accepted() yield accepted()
save_spendable_output() save_spendable_output()
@ -457,7 +481,6 @@ class FullBlockTest(ComparisonTestFramework):
block(34, spend=out[10], script=too_many_multisigs) block(34, spend=out[10], script=too_many_multisigs)
yield rejected(RejectResult(16, b'bad-blk-sigops')) yield rejected(RejectResult(16, b'bad-blk-sigops'))
# CHECKSIGVERIFY # CHECKSIGVERIFY
tip(33) tip(33)
lots_of_checksigs = CScript([OP_CHECKSIGVERIFY] * (MAX_BLOCK_SIGOPS - 1)) lots_of_checksigs = CScript([OP_CHECKSIGVERIFY] * (MAX_BLOCK_SIGOPS - 1))
@ -469,7 +492,6 @@ class FullBlockTest(ComparisonTestFramework):
block(36, spend=out[11], script=too_many_checksigs) block(36, spend=out[11], script=too_many_checksigs)
yield rejected(RejectResult(16, b'bad-blk-sigops')) yield rejected(RejectResult(16, b'bad-blk-sigops'))
# Check spending of a transaction in a block which failed to connect # Check spending of a transaction in a block which failed to connect
# #
# b6 (3) # b6 (3)
@ -508,7 +530,7 @@ class FullBlockTest(ComparisonTestFramework):
b39_sigops_per_output = 6 b39_sigops_per_output = 6
# Build the redeem script, hash it, use hash to create the p2sh script # Build the redeem script, hash it, use hash to create the p2sh script
redeem_script = CScript([self.coinbase_pubkey] + [OP_2DUP, OP_CHECKSIGVERIFY]*5 + [OP_CHECKSIG]) redeem_script = CScript([self.coinbase_pubkey] + [OP_2DUP, OP_CHECKSIGVERIFY] * 5 + [OP_CHECKSIG])
redeem_script_hash = hash160(redeem_script) redeem_script_hash = hash160(redeem_script)
p2sh_script = CScript([OP_HASH160, redeem_script_hash, OP_EQUAL]) p2sh_script = CScript([OP_HASH160, redeem_script_hash, OP_EQUAL])
@ -525,7 +547,7 @@ class FullBlockTest(ComparisonTestFramework):
# Until block is full, add tx's with 1 satoshi to p2sh_script, the rest to OP_TRUE # Until block is full, add tx's with 1 satoshi to p2sh_script, the rest to OP_TRUE
tx_new = None tx_new = None
tx_last = tx tx_last = tx
total_size=len(b39.serialize()) total_size = len(b39.serialize())
while(total_size < MAX_BLOCK_BASE_SIZE): while(total_size < MAX_BLOCK_BASE_SIZE):
tx_new = create_tx(tx_last, 1, 1, p2sh_script) tx_new = create_tx(tx_last, 1, 1, p2sh_script)
tx_new.vout.append(CTxOut(tx_last.vout[1].nValue - 1, CScript([OP_TRUE]))) tx_new.vout.append(CTxOut(tx_last.vout[1].nValue - 1, CScript([OP_TRUE])))
@ -533,7 +555,7 @@ class FullBlockTest(ComparisonTestFramework):
total_size += len(tx_new.serialize()) total_size += len(tx_new.serialize())
if total_size >= MAX_BLOCK_BASE_SIZE: if total_size >= MAX_BLOCK_BASE_SIZE:
break break
b39.vtx.append(tx_new) # add tx to block b39.vtx.append(tx_new) # add tx to block
tx_last = tx_new tx_last = tx_new
b39_outputs += 1 b39_outputs += 1
@ -541,7 +563,6 @@ class FullBlockTest(ComparisonTestFramework):
yield accepted() yield accepted()
save_spendable_output() save_spendable_output()
# Test sigops in P2SH redeem scripts # Test sigops in P2SH redeem scripts
# #
# b40 creates 3333 tx's spending the 6-sigop P2SH outputs from b39 for a total of 19998 sigops. # b40 creates 3333 tx's spending the 6-sigop P2SH outputs from b39 for a total of 19998 sigops.
@ -557,7 +578,7 @@ class FullBlockTest(ComparisonTestFramework):
lastOutpoint = COutPoint(b40.vtx[1].sha256, 0) lastOutpoint = COutPoint(b40.vtx[1].sha256, 0)
new_txs = [] new_txs = []
for i in range(1, numTxes+1): for i in range(1, numTxes + 1):
tx = CTransaction() tx = CTransaction()
tx.vout.append(CTxOut(1, CScript([OP_TRUE]))) tx.vout.append(CTxOut(1, CScript([OP_TRUE])))
tx.vin.append(CTxIn(lastOutpoint, b'')) tx.vin.append(CTxIn(lastOutpoint, b''))
@ -608,7 +629,6 @@ class FullBlockTest(ComparisonTestFramework):
yield accepted() yield accepted()
save_spendable_output() save_spendable_output()
# Test a number of really invalid scenarios # Test a number of really invalid scenarios
# #
# -> b31 (8) -> b33 (9) -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) -> b44 (14) # -> b31 (8) -> b33 (9) -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) -> b44 (14)
@ -640,7 +660,7 @@ class FullBlockTest(ComparisonTestFramework):
b45.hashMerkleRoot = b45.calc_merkle_root() b45.hashMerkleRoot = b45.calc_merkle_root()
b45.calc_sha256() b45.calc_sha256()
b45.solve() b45.solve()
self.block_heights[b45.sha256] = self.block_heights[self.tip.sha256]+1 self.block_heights[b45.sha256] = self.block_heights[self.tip.sha256] + 1
self.tip = b45 self.tip = b45
self.blocks[45] = b45 self.blocks[45] = b45
yield rejected(RejectResult(16, b'bad-cb-missing')) yield rejected(RejectResult(16, b'bad-cb-missing'))
@ -648,24 +668,23 @@ class FullBlockTest(ComparisonTestFramework):
# A block with no txns # A block with no txns
tip(44) tip(44)
b46 = CBlock() b46 = CBlock()
b46.nTime = b44.nTime+1 b46.nTime = b44.nTime + 1
b46.hashPrevBlock = b44.sha256 b46.hashPrevBlock = b44.sha256
b46.nBits = 0x207fffff b46.nBits = 0x207fffff
b46.vtx = [] b46.vtx = []
b46.hashMerkleRoot = 0 b46.hashMerkleRoot = 0
b46.solve() b46.solve()
self.block_heights[b46.sha256] = self.block_heights[b44.sha256]+1 self.block_heights[b46.sha256] = self.block_heights[b44.sha256] + 1
self.tip = b46 self.tip = b46
assert 46 not in self.blocks assert 46 not in self.blocks
self.blocks[46] = b46 self.blocks[46] = b46
s = ser_uint256(b46.hashMerkleRoot)
yield rejected(RejectResult(16, b'bad-blk-length')) yield rejected(RejectResult(16, b'bad-blk-length'))
# A block with invalid work # A block with invalid work
tip(44) tip(44)
b47 = block(47, solve=False) b47 = block(47, solve=False)
target = uint256_from_compact(b47.nBits) target = uint256_from_compact(b47.nBits)
while b47.sha256 < target: #changed > to < while b47.sha256 < target: # changed > to <
b47.nNonce += 1 b47.nNonce += 1
b47.rehash() b47.rehash()
yield rejected(RejectResult(16, b'high-hash')) yield rejected(RejectResult(16, b'high-hash'))
@ -693,9 +712,9 @@ class FullBlockTest(ComparisonTestFramework):
# A block with two coinbase txns # A block with two coinbase txns
tip(44) tip(44)
b51 = block(51) block(51)
cb2 = create_coinbase(51, self.coinbase_pubkey) cb2 = create_coinbase(51, self.coinbase_pubkey)
b51 = update_block(51, [cb2]) update_block(51, [cb2])
yield rejected(RejectResult(16, b'bad-cb-multiple')) yield rejected(RejectResult(16, b'bad-cb-multiple'))
# A block w/ duplicate txns # A block w/ duplicate txns
@ -712,7 +731,7 @@ class FullBlockTest(ComparisonTestFramework):
# #
tip(43) tip(43)
block(53, spend=out[14]) block(53, spend=out[14])
yield rejected() # rejected since b44 is at same height yield rejected() # rejected since b44 is at same height
save_spendable_output() save_spendable_output()
# invalid timestamp (b35 is 5 blocks back, so its time is MedianTimePast) # invalid timestamp (b35 is 5 blocks back, so its time is MedianTimePast)
@ -729,7 +748,6 @@ class FullBlockTest(ComparisonTestFramework):
yield accepted() yield accepted()
save_spendable_output() save_spendable_output()
# Test CVE-2012-2459 # Test CVE-2012-2459
# #
# -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57p2 (16) # -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57p2 (16)
@ -737,7 +755,7 @@ class FullBlockTest(ComparisonTestFramework):
# \-> b56p2 (16) # \-> b56p2 (16)
# \-> b56 (16) # \-> b56 (16)
# #
# Merkle tree malleability (CVE-2012-2459): repeating sequences of transactions in a block without # Merkle tree malleability (CVE-2012-2459): repeating sequences of transactions in a block without
# affecting the merkle root of a block, while still invalidating it. # affecting the merkle root of a block, while still invalidating it.
# See: src/consensus/merkle.h # See: src/consensus/merkle.h
# #
@ -768,7 +786,7 @@ class FullBlockTest(ComparisonTestFramework):
tip(55) tip(55)
b56 = copy.deepcopy(b57) b56 = copy.deepcopy(b57)
self.blocks[56] = b56 self.blocks[56] = b56
assert_equal(len(b56.vtx),3) assert_equal(len(b56.vtx), 3)
b56 = update_block(56, [tx1]) b56 = update_block(56, [tx1])
assert_equal(b56.hash, b57.hash) assert_equal(b56.hash, b57.hash)
yield rejected(RejectResult(16, b'bad-txns-duplicate')) yield rejected(RejectResult(16, b'bad-txns-duplicate'))
@ -788,7 +806,7 @@ class FullBlockTest(ComparisonTestFramework):
b56p2 = copy.deepcopy(b57p2) b56p2 = copy.deepcopy(b57p2)
self.blocks["b56p2"] = b56p2 self.blocks["b56p2"] = b56p2
assert_equal(b56p2.hash, b57p2.hash) assert_equal(b56p2.hash, b57p2.hash)
assert_equal(len(b56p2.vtx),6) assert_equal(len(b56p2.vtx), 6)
b56p2 = update_block("b56p2", [tx3, tx4]) b56p2 = update_block("b56p2", [tx3, tx4])
yield rejected(RejectResult(16, b'bad-txns-duplicate')) yield rejected(RejectResult(16, b'bad-txns-duplicate'))
@ -796,7 +814,7 @@ class FullBlockTest(ComparisonTestFramework):
yield accepted() yield accepted()
tip(57) tip(57)
yield rejected() #rejected because 57p2 seen first yield rejected() # rejected because 57p2 seen first
save_spendable_output() save_spendable_output()
# Test a few invalid tx types # Test a few invalid tx types
@ -807,20 +825,20 @@ class FullBlockTest(ComparisonTestFramework):
# tx with prevout.n out of range # tx with prevout.n out of range
tip(57) tip(57)
b58 = block(58, spend=out[17]) block(58, spend=out[17])
tx = CTransaction() tx = CTransaction()
assert(len(out[17].tx.vout) < 42) assert(len(out[17].tx.vout) < 42)
tx.vin.append(CTxIn(COutPoint(out[17].tx.sha256, 42), CScript([OP_TRUE]), 0xffffffff)) tx.vin.append(CTxIn(COutPoint(out[17].tx.sha256, 42), CScript([OP_TRUE]), 0xffffffff))
tx.vout.append(CTxOut(0, b"")) tx.vout.append(CTxOut(0, b""))
tx.calc_sha256() tx.calc_sha256()
b58 = update_block(58, [tx]) update_block(58, [tx])
yield rejected(RejectResult(16, b'bad-txns-inputs-missingorspent')) yield rejected(RejectResult(16, b'bad-txns-inputs-missingorspent'))
# tx with output value > input value out of range # tx with output value > input value out of range
tip(57) tip(57)
b59 = block(59) block(59)
tx = create_and_sign_tx(out[17].tx, out[17].n, 51*COIN) tx = create_and_sign_tx(out[17].tx, out[17].n, 51 * COIN)
b59 = update_block(59, [tx]) update_block(59, [tx])
yield rejected(RejectResult(16, b'bad-txns-in-belowout')) yield rejected(RejectResult(16, b'bad-txns-in-belowout'))
# reset to good chain # reset to good chain
@ -840,31 +858,29 @@ class FullBlockTest(ComparisonTestFramework):
# #
tip(60) tip(60)
b61 = block(61, spend=out[18]) b61 = block(61, spend=out[18])
b61.vtx[0].vin[0].scriptSig = b60.vtx[0].vin[0].scriptSig #equalize the coinbases b61.vtx[0].vin[0].scriptSig = b60.vtx[0].vin[0].scriptSig # equalize the coinbases
b61.vtx[0].rehash() b61.vtx[0].rehash()
b61 = update_block(61, []) b61 = update_block(61, [])
assert_equal(b60.vtx[0].serialize(), b61.vtx[0].serialize()) assert_equal(b60.vtx[0].serialize(), b61.vtx[0].serialize())
yield rejected(RejectResult(16, b'bad-txns-BIP30')) yield rejected(RejectResult(16, b'bad-txns-BIP30'))
# Test tx.isFinal is properly rejected (not an exhaustive tx.isFinal test, that should be in data-driven transaction tests) # Test tx.isFinal is properly rejected (not an exhaustive tx.isFinal test, that should be in data-driven transaction tests)
# #
# -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) # -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17)
# \-> b62 (18) # \-> b62 (18)
# #
tip(60) tip(60)
b62 = block(62) block(62)
tx = CTransaction() tx = CTransaction()
tx.nLockTime = 0xffffffff #this locktime is non-final tx.nLockTime = 0xffffffff # this locktime is non-final
assert(out[18].n < len(out[18].tx.vout)) assert(out[18].n < len(out[18].tx.vout))
tx.vin.append(CTxIn(COutPoint(out[18].tx.sha256, out[18].n))) # don't set nSequence tx.vin.append(CTxIn(COutPoint(out[18].tx.sha256, out[18].n))) # don't set nSequence
tx.vout.append(CTxOut(0, CScript([OP_TRUE]))) tx.vout.append(CTxOut(0, CScript([OP_TRUE])))
assert(tx.vin[0].nSequence < 0xffffffff) assert(tx.vin[0].nSequence < 0xffffffff)
tx.calc_sha256() tx.calc_sha256()
b62 = update_block(62, [tx]) update_block(62, [tx])
yield rejected(RejectResult(16, b'bad-txns-nonfinal')) yield rejected(RejectResult(16, b'bad-txns-nonfinal'))
# Test a non-final coinbase is also rejected # Test a non-final coinbase is also rejected
# #
# -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) # -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17)
@ -878,7 +894,6 @@ class FullBlockTest(ComparisonTestFramework):
b63 = update_block(63, []) b63 = update_block(63, [])
yield rejected(RejectResult(16, b'bad-txns-nonfinal')) yield rejected(RejectResult(16, b'bad-txns-nonfinal'))
# This checks that a block with a bloated VARINT between the block_header and the array of tx such that # 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, # the block is > MAX_BLOCK_BASE_SIZE with the bloated varint, but <= MAX_BLOCK_BASE_SIZE without the bloated varint,
# does not cause a subsequent, identical block with canonical encoding to be rejected. The test does not # does not cause a subsequent, identical block with canonical encoding to be rejected. The test does not
@ -976,13 +991,13 @@ class FullBlockTest(ComparisonTestFramework):
# #
tip(65) tip(65)
block(68, additional_coinbase_value=10) block(68, additional_coinbase_value=10)
tx = create_and_sign_tx(out[20].tx, out[20].n, out[20].tx.vout[0].nValue-9) tx = create_and_sign_tx(out[20].tx, out[20].n, out[20].tx.vout[0].nValue - 9)
update_block(68, [tx]) update_block(68, [tx])
yield rejected(RejectResult(16, b'bad-cb-amount')) yield rejected(RejectResult(16, b'bad-cb-amount'))
tip(65) tip(65)
b69 = block(69, additional_coinbase_value=10) b69 = block(69, additional_coinbase_value=10)
tx = create_and_sign_tx(out[20].tx, out[20].n, out[20].tx.vout[0].nValue-10) tx = create_and_sign_tx(out[20].tx, out[20].n, out[20].tx.vout[0].nValue - 10)
update_block(69, [tx]) update_block(69, [tx])
yield accepted() yield accepted()
save_spendable_output() save_spendable_output()
@ -1002,7 +1017,6 @@ class FullBlockTest(ComparisonTestFramework):
update_block(70, [tx]) update_block(70, [tx])
yield rejected(RejectResult(16, b'bad-txns-inputs-missingorspent')) yield rejected(RejectResult(16, b'bad-txns-inputs-missingorspent'))
# Test accepting an invalid block which has the same hash as a valid one (via merkle tree tricks) # Test accepting an invalid block which has the same hash as a valid one (via merkle tree tricks)
# #
# -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20) -> b72 (21) # -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20) -> b72 (21)
@ -1031,7 +1045,6 @@ class FullBlockTest(ComparisonTestFramework):
yield accepted() yield accepted()
save_spendable_output() save_spendable_output()
# Test some invalid scripts and MAX_BLOCK_SIGOPS # Test some invalid scripts and MAX_BLOCK_SIGOPS
# #
# -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20) -> b72 (21) # -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20) -> b72 (21)
@ -1053,17 +1066,17 @@ class FullBlockTest(ComparisonTestFramework):
b73 = block(73) b73 = block(73)
size = MAX_BLOCK_SIGOPS - 1 + MAX_SCRIPT_ELEMENT_SIZE + 1 + 5 + 1 size = MAX_BLOCK_SIGOPS - 1 + MAX_SCRIPT_ELEMENT_SIZE + 1 + 5 + 1
a = bytearray([OP_CHECKSIG] * size) a = bytearray([OP_CHECKSIG] * size)
a[MAX_BLOCK_SIGOPS - 1] = int("4e",16) # OP_PUSHDATA4 a[MAX_BLOCK_SIGOPS - 1] = int("4e", 16) # OP_PUSHDATA4
element_size = MAX_SCRIPT_ELEMENT_SIZE + 1 element_size = MAX_SCRIPT_ELEMENT_SIZE + 1
a[MAX_BLOCK_SIGOPS] = element_size % 256 a[MAX_BLOCK_SIGOPS] = element_size % 256
a[MAX_BLOCK_SIGOPS+1] = element_size // 256 a[MAX_BLOCK_SIGOPS + 1] = element_size // 256
a[MAX_BLOCK_SIGOPS+2] = 0 a[MAX_BLOCK_SIGOPS + 2] = 0
a[MAX_BLOCK_SIGOPS+3] = 0 a[MAX_BLOCK_SIGOPS + 3] = 0
tx = create_and_sign_tx(out[22].tx, 0, 1, CScript(a)) tx = create_and_sign_tx(out[22].tx, 0, 1, CScript(a))
b73 = update_block(73, [tx]) b73 = update_block(73, [tx])
assert_equal(get_legacy_sigopcount_block(b73), MAX_BLOCK_SIGOPS+1) assert_equal(get_legacy_sigopcount_block(b73), MAX_BLOCK_SIGOPS + 1)
yield rejected(RejectResult(16, b'bad-blk-sigops')) yield rejected(RejectResult(16, b'bad-blk-sigops'))
# b74/75 - if we push an invalid script element, all prevous sigops are counted, # b74/75 - if we push an invalid script element, all prevous sigops are counted,
@ -1079,40 +1092,40 @@ class FullBlockTest(ComparisonTestFramework):
# #
# #
tip(72) tip(72)
b74 = block(74) block(74)
size = MAX_BLOCK_SIGOPS - 1 + MAX_SCRIPT_ELEMENT_SIZE + 42 # total = 20,561 size = MAX_BLOCK_SIGOPS - 1 + MAX_SCRIPT_ELEMENT_SIZE + 42 # total = 20,561
a = bytearray([OP_CHECKSIG] * size) a = bytearray([OP_CHECKSIG] * size)
a[MAX_BLOCK_SIGOPS] = 0x4e a[MAX_BLOCK_SIGOPS] = 0x4e
a[MAX_BLOCK_SIGOPS+1] = 0xfe a[MAX_BLOCK_SIGOPS + 1] = 0xfe
a[MAX_BLOCK_SIGOPS+2] = 0xff a[MAX_BLOCK_SIGOPS + 2] = 0xff
a[MAX_BLOCK_SIGOPS+3] = 0xff a[MAX_BLOCK_SIGOPS + 3] = 0xff
a[MAX_BLOCK_SIGOPS+4] = 0xff a[MAX_BLOCK_SIGOPS + 4] = 0xff
tx = create_and_sign_tx(out[22].tx, 0, 1, CScript(a)) tx = create_and_sign_tx(out[22].tx, 0, 1, CScript(a))
b74 = update_block(74, [tx]) update_block(74, [tx])
yield rejected(RejectResult(16, b'bad-blk-sigops')) yield rejected(RejectResult(16, b'bad-blk-sigops'))
tip(72) tip(72)
b75 = block(75) block(75)
size = MAX_BLOCK_SIGOPS - 1 + MAX_SCRIPT_ELEMENT_SIZE + 42 size = MAX_BLOCK_SIGOPS - 1 + MAX_SCRIPT_ELEMENT_SIZE + 42
a = bytearray([OP_CHECKSIG] * size) a = bytearray([OP_CHECKSIG] * size)
a[MAX_BLOCK_SIGOPS-1] = 0x4e a[MAX_BLOCK_SIGOPS - 1] = 0x4e
a[MAX_BLOCK_SIGOPS] = 0xff a[MAX_BLOCK_SIGOPS] = 0xff
a[MAX_BLOCK_SIGOPS+1] = 0xff a[MAX_BLOCK_SIGOPS + 1] = 0xff
a[MAX_BLOCK_SIGOPS+2] = 0xff a[MAX_BLOCK_SIGOPS + 2] = 0xff
a[MAX_BLOCK_SIGOPS+3] = 0xff a[MAX_BLOCK_SIGOPS + 3] = 0xff
tx = create_and_sign_tx(out[22].tx, 0, 1, CScript(a)) tx = create_and_sign_tx(out[22].tx, 0, 1, CScript(a))
b75 = update_block(75, [tx]) update_block(75, [tx])
yield accepted() yield accepted()
save_spendable_output() save_spendable_output()
# Check that if we push an element filled with CHECKSIGs, they are not counted # Check that if we push an element filled with CHECKSIGs, they are not counted
tip(75) tip(75)
b76 = block(76) block(76)
size = MAX_BLOCK_SIGOPS - 1 + MAX_SCRIPT_ELEMENT_SIZE + 1 + 5 size = MAX_BLOCK_SIGOPS - 1 + MAX_SCRIPT_ELEMENT_SIZE + 1 + 5
a = bytearray([OP_CHECKSIG] * size) a = bytearray([OP_CHECKSIG] * size)
a[MAX_BLOCK_SIGOPS-1] = 0x4e # PUSHDATA4, but leave the following bytes as just checksigs a[MAX_BLOCK_SIGOPS - 1] = 0x4e # PUSHDATA4, but leave the following bytes as just checksigs
tx = create_and_sign_tx(out[23].tx, 0, 1, CScript(a)) tx = create_and_sign_tx(out[23].tx, 0, 1, CScript(a))
b76 = update_block(76, [tx]) update_block(76, [tx])
yield accepted() yield accepted()
save_spendable_output() save_spendable_output()
@ -1136,18 +1149,18 @@ class FullBlockTest(ComparisonTestFramework):
# #
tip(76) tip(76)
block(77) block(77)
tx77 = create_and_sign_tx(out[24].tx, out[24].n, 10*COIN) tx77 = create_and_sign_tx(out[24].tx, out[24].n, 10 * COIN)
update_block(77, [tx77]) update_block(77, [tx77])
yield accepted() yield accepted()
save_spendable_output() save_spendable_output()
block(78) block(78)
tx78 = create_tx(tx77, 0, 9*COIN) tx78 = create_tx(tx77, 0, 9 * COIN)
update_block(78, [tx78]) update_block(78, [tx78])
yield accepted() yield accepted()
block(79) block(79)
tx79 = create_tx(tx78, 0, 8*COIN) tx79 = create_tx(tx78, 0, 8 * COIN)
update_block(79, [tx79]) update_block(79, [tx79])
yield accepted() yield accepted()
@ -1160,7 +1173,7 @@ class FullBlockTest(ComparisonTestFramework):
save_spendable_output() save_spendable_output()
block(81, spend=out[26]) block(81, spend=out[26])
yield rejected() # other chain is same length yield rejected() # other chain is same length
save_spendable_output() save_spendable_output()
block(82, spend=out[27]) block(82, spend=out[27])
@ -1173,7 +1186,6 @@ class FullBlockTest(ComparisonTestFramework):
assert(tx78.hash in mempool) assert(tx78.hash in mempool)
assert(tx79.hash in mempool) assert(tx79.hash in mempool)
# Test invalid opcodes in dead execution paths. # Test invalid opcodes in dead execution paths.
# #
# -> b81 (26) -> b82 (27) -> b83 (28) # -> b81 (26) -> b82 (27) -> b83 (28)
@ -1191,7 +1203,6 @@ class FullBlockTest(ComparisonTestFramework):
yield accepted() yield accepted()
save_spendable_output() save_spendable_output()
# Reorg on/off blocks that have OP_RETURN in them (and try to spend them) # Reorg on/off blocks that have OP_RETURN in them (and try to spend them)
# #
# -> b81 (26) -> b82 (27) -> b83 (28) -> b84 (29) -> b87 (30) -> b88 (31) # -> b81 (26) -> b82 (27) -> b83 (28) -> b84 (29) -> b87 (30) -> b88 (31)
@ -1215,7 +1226,7 @@ class FullBlockTest(ComparisonTestFramework):
tx4.vout.append(CTxOut(0, CScript([OP_RETURN]))) tx4.vout.append(CTxOut(0, CScript([OP_RETURN])))
tx5 = create_tx(tx1, 4, 0, CScript([OP_RETURN])) tx5 = create_tx(tx1, 4, 0, CScript([OP_RETURN]))
update_block(84, [tx1,tx2,tx3,tx4,tx5]) update_block(84, [tx1, tx2, tx3, tx4, tx5])
yield accepted() yield accepted()
save_spendable_output() save_spendable_output()
@ -1241,7 +1252,6 @@ class FullBlockTest(ComparisonTestFramework):
update_block("89a", [tx]) update_block("89a", [tx])
yield rejected() yield rejected()
# Test re-org of a week's worth of blocks (1088 blocks) # Test re-org of a week's worth of blocks (1088 blocks)
# This test takes a minute or two and can be accomplished in memory # This test takes a minute or two and can be accomplished in memory
# #
@ -1249,7 +1259,7 @@ class FullBlockTest(ComparisonTestFramework):
tip(88) tip(88)
LARGE_REORG_SIZE = 1088 LARGE_REORG_SIZE = 1088
test1 = TestInstance(sync_every_block=False) test1 = TestInstance(sync_every_block=False)
spend=out[32] spend = out[32]
for i in range(89, LARGE_REORG_SIZE + 89): for i in range(89, LARGE_REORG_SIZE + 89):
b = block(i, spend) b = block(i, spend)
tx = CTransaction() tx = CTransaction()
@ -1270,7 +1280,7 @@ class FullBlockTest(ComparisonTestFramework):
tip(88) tip(88)
test2 = TestInstance(sync_every_block=False) test2 = TestInstance(sync_every_block=False)
for i in range(89, LARGE_REORG_SIZE + 89): for i in range(89, LARGE_REORG_SIZE + 89):
block("alt"+str(i)) block("alt" + str(i))
test2.blocks_and_transactions.append([self.tip, False]) test2.blocks_and_transactions.append([self.tip, False])
yield test2 yield test2
@ -1288,6 +1298,5 @@ class FullBlockTest(ComparisonTestFramework):
chain1_tip += 2 chain1_tip += 2
if __name__ == '__main__': if __name__ == '__main__':
FullBlockTest().main() FullBlockTest().main()