def test_open_mismatch(self, tmpdir): checkpoint = CheckPoint(urandom(80), 5, 0) hs = create_or_open_storage(tmpdir, checkpoint) hs.append(urandom(80)) assert hs[checkpoint.height] == checkpoint.raw_header assert len(hs) == checkpoint.height + 2 hs[checkpoint.height + 1] hs.close() checkpoint2 = CheckPoint(urandom(80), checkpoint.height, 0) hs = create_or_open_storage(tmpdir, checkpoint2) assert len(hs) == checkpoint.height + 1 assert hs[checkpoint.height] == checkpoint2.raw_header with pytest.raises(MissingHeader): hs[checkpoint.height + 1]
def test_pickle(self, tmpdir): testnet_genesis_checkpoint = CheckPoint(BitcoinTestnet.genesis_header, 0, 0) headers_obj = create_headers(tmpdir, testnet_genesis_checkpoint) header1 = bytes.fromhex( '0100000043497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea330900000000bac8b0fa' '927c0ac8234287e33c5f74d38d354820e24756ad709d7038fc5f31f020e7494dffff001d03e4b672' ) header2 = bytes.fromhex( '0100000006128e87be8b1b4dea47a7247d5528d2702c96826c7a648497e773b800000000e241352e' '3bec0a95a6217e10c3abb54adfa05abb12c126695595580fb92e222032e7494dffff001d00d23534' ) headers_obj.connect(header1) headers_obj.connect(header2) pickle_bytes = pickle.dumps(headers_obj) headers_obj2 = pickle.loads(pickle_bytes) assert headers_obj._short_hashes == headers_obj2._short_hashes assert headers_obj._heights == headers_obj2._heights assert headers_obj._chain_indices == headers_obj2._chain_indices assert len(headers_obj._chains) == len(headers_obj2._chains) # Chain objects cannot be directly compared, so we need to do the legwork. # This goes beyond what is needed here as it might be reused for a wider variety of # cases if necessary. for i in range(len(headers_obj._chains)): original_chain = headers_obj._chains[i] unpickled_chain = headers_obj2._chains[i] assert original_chain.tip == unpickled_chain.tip assert original_chain.work == unpickled_chain.work assert original_chain.first_height == unpickled_chain.first_height assert original_chain._header_indices == unpickled_chain._header_indices if original_chain.parent is None: assert unpickled_chain.parent is None else: assert unpickled_chain.parent is not None original_index = headers_obj._chains.index(original_chain.parent) unpickled_index = headers_obj2._chains.index(unpickled_chain.parent) assert original_index == unpickled_index header_1_hash_hex = '00000000b873e79784647a6c82962c70d228557d24a747ea4d1b8bbe878e1206' header_1_hash = hex_str_to_hash(header_1_hash_hex) headers_obj2.common_setup(headers_obj.network, storage_filename(tmpdir), testnet_genesis_checkpoint) original_header, original_chain = headers_obj.lookup(header_1_hash) unpickled_header, unpickled_chain = headers_obj2.lookup(header_1_hash) assert original_header == unpickled_header header_2_hash_hex = '000000006c02c8ea6e4ff69651f7fcde348fb9d557a06e6957b65552002a7820' header_2_hash = hex_str_to_hash(header_2_hash_hex) original_header, original_chain = headers_obj.lookup(header_2_hash) unpickled_header, unpickled_chain = headers_obj2.lookup(header_2_hash) assert original_header == unpickled_header
def test_connect(self, tmpdir): testnet_genesis_checkpoint = CheckPoint(BitcoinTestnet.genesis_header, 0, 0) headers_obj = create_headers(tmpdir, testnet_genesis_checkpoint) header1 = bytes.fromhex( '0100000043497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea330900000000bac8b0fa' '927c0ac8234287e33c5f74d38d354820e24756ad709d7038fc5f31f020e7494dffff001d03e4b672' ) header2 = bytes.fromhex( '0100000006128e87be8b1b4dea47a7247d5528d2702c96826c7a648497e773b800000000e241352e' '3bec0a95a6217e10c3abb54adfa05abb12c126695595580fb92e222032e7494dffff001d00d23534' ) # Test cache-clearing headers_obj.max_cache_size = 1 # Test they connect headers_obj.connect(header1) headers_obj.connect(header2) # Test re-adding is OK headers_obj.connect(header1) # Test bad bits raises bad_header = bytearray(header1) bad_header[72:76] = pack_le_uint32(472518933) with pytest.raises(IncorrectBits) as e: headers_obj.connect(bad_header) assert str(e.value).endswith('requires bits 0x486604799') # Test insufficient PoW raises bad_header = bytearray(header1) bad_header[0] = 2 with pytest.raises(InsufficientPoW) as e: headers_obj.connect(bad_header) assert 'exceeds its target' in str(e.value)
import pytest from bitcoinx import ( Bitcoin, BitcoinTestnet, pack_le_uint32, double_sha256, IncorrectBits, InsufficientPoW, ) from bitcoinx.chain import _HeaderStorage, Chain, Headers, CheckPoint, MissingHeader some_good_bits = [486604799, 472518933, 453281356, 436956491] empty_header = bytes(80) genesis_checkpoint = CheckPoint(Bitcoin.genesis_header, 0, 0) bsv_raw_header = bytes.fromhex( '000000203b0bc2a72e7313ac216e3c63314b8aec4be35374d66d2e0200000000000000009d14e99d' '7799f2d8b62b3c745aa94514da4c831193bd057a916e1f45183600b5d001f95b11fd02180d32952e' ) bsv_checkpoint = CheckPoint(bsv_raw_header, height=557957, prev_work=0xd54c44dbdc491c25d097bf) def random_header(prev_hash=None, height=-1, good_bits=None): good_bits = good_bits or some_good_bits raw_header = bytearray(urandom(80)) raw_header[72:76] = pack_le_uint32(random.choice(good_bits)) if prev_hash: raw_header[4:36] = prev_hash