mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-10 11:57:28 -03:00
qa: Add tests for submitheader
This commit is contained in:
parent
36b1b63f20
commit
fa091b0016
1 changed files with 74 additions and 5 deletions
|
@ -9,16 +9,23 @@
|
|||
- submitblock"""
|
||||
|
||||
import copy
|
||||
from binascii import b2a_hex
|
||||
from decimal import Decimal
|
||||
|
||||
from test_framework.blocktools import create_coinbase
|
||||
from test_framework.messages import CBlock
|
||||
from test_framework.messages import (
|
||||
CBlock,
|
||||
CBlockHeader,
|
||||
)
|
||||
from test_framework.mininode import (
|
||||
P2PDataStore,
|
||||
)
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import assert_equal, assert_raises_rpc_error
|
||||
from test_framework.util import (
|
||||
assert_equal,
|
||||
assert_raises_rpc_error,
|
||||
bytes_to_hex_str as b2x,
|
||||
)
|
||||
|
||||
def b2x(b):
|
||||
return b2a_hex(b).decode('ascii')
|
||||
|
||||
def assert_template(node, block, expect, rehash=True):
|
||||
if rehash:
|
||||
|
@ -131,5 +138,67 @@ class MiningTest(BitcoinTestFramework):
|
|||
bad_block.hashPrevBlock = 123
|
||||
assert_template(node, bad_block, 'inconclusive-not-best-prevblk')
|
||||
|
||||
self.log.info('submitheader tests')
|
||||
assert_raises_rpc_error(-22, 'Block header decode failed', lambda: node.submitheader(hexdata='xx' * 80))
|
||||
assert_raises_rpc_error(-22, 'Block header decode failed', lambda: node.submitheader(hexdata='ff' * 78))
|
||||
assert_raises_rpc_error(-25, 'Must submit previous header', lambda: node.submitheader(hexdata='ff' * 80))
|
||||
|
||||
block.solve()
|
||||
|
||||
def chain_tip(b_hash, *, status='headers-only', branchlen=1):
|
||||
return {'hash': b_hash, 'height': 202, 'branchlen': branchlen, 'status': status}
|
||||
|
||||
assert chain_tip(block.hash) not in node.getchaintips()
|
||||
node.submitheader(hexdata=b2x(block.serialize()))
|
||||
assert chain_tip(block.hash) in node.getchaintips()
|
||||
node.submitheader(hexdata=b2x(CBlockHeader(block).serialize())) # Noop
|
||||
assert chain_tip(block.hash) in node.getchaintips()
|
||||
|
||||
bad_block_root = copy.deepcopy(block)
|
||||
bad_block_root.hashMerkleRoot += 2
|
||||
bad_block_root.solve()
|
||||
assert chain_tip(bad_block_root.hash) not in node.getchaintips()
|
||||
node.submitheader(hexdata=b2x(CBlockHeader(bad_block_root).serialize()))
|
||||
assert chain_tip(bad_block_root.hash) in node.getchaintips()
|
||||
# Should still reject invalid blocks, even if we have the header:
|
||||
assert_equal(node.submitblock(hexdata=b2x(bad_block_root.serialize())), 'invalid')
|
||||
assert chain_tip(bad_block_root.hash) in node.getchaintips()
|
||||
# We know the header for this invalid block, so should just return early without error:
|
||||
node.submitheader(hexdata=b2x(CBlockHeader(bad_block_root).serialize()))
|
||||
assert chain_tip(bad_block_root.hash) in node.getchaintips()
|
||||
|
||||
bad_block_lock = copy.deepcopy(block)
|
||||
bad_block_lock.vtx[0].nLockTime = 2**32 - 1
|
||||
bad_block_lock.vtx[0].rehash()
|
||||
bad_block_lock.hashMerkleRoot = bad_block_lock.calc_merkle_root()
|
||||
bad_block_lock.solve()
|
||||
assert_equal(node.submitblock(hexdata=b2x(bad_block_lock.serialize())), 'invalid')
|
||||
# Build a "good" block on top of the submitted bad block
|
||||
bad_block2 = copy.deepcopy(block)
|
||||
bad_block2.hashPrevBlock = bad_block_lock.sha256
|
||||
bad_block2.solve()
|
||||
assert_raises_rpc_error(-25, 'bad-prevblk', lambda: node.submitheader(hexdata=b2x(CBlockHeader(bad_block2).serialize())))
|
||||
|
||||
# Should reject invalid header right away
|
||||
bad_block_time = copy.deepcopy(block)
|
||||
bad_block_time.nTime = 1
|
||||
bad_block_time.solve()
|
||||
assert_raises_rpc_error(-25, 'time-too-old', lambda: node.submitheader(hexdata=b2x(CBlockHeader(bad_block_time).serialize())))
|
||||
|
||||
# Should ask for the block from a p2p node, if they announce the header as well:
|
||||
node.add_p2p_connection(P2PDataStore())
|
||||
node.p2p.wait_for_getheaders(timeout=5) # Drop the first getheaders
|
||||
node.p2p.send_blocks_and_test(blocks=[block], rpc=node)
|
||||
# Must be active now:
|
||||
assert chain_tip(block.hash, status='active', branchlen=0) in node.getchaintips()
|
||||
|
||||
# Building a few blocks should give the same results
|
||||
node.generate(10)
|
||||
assert_raises_rpc_error(-25, 'time-too-old', lambda: node.submitheader(hexdata=b2x(CBlockHeader(bad_block_time).serialize())))
|
||||
assert_raises_rpc_error(-25, 'bad-prevblk', lambda: node.submitheader(hexdata=b2x(CBlockHeader(bad_block2).serialize())))
|
||||
node.submitheader(hexdata=b2x(CBlockHeader(block).serialize()))
|
||||
node.submitheader(hexdata=b2x(CBlockHeader(bad_block_root).serialize()))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
MiningTest().main()
|
||||
|
|
Loading…
Reference in a new issue