class TestVerifyHeader(ElectrumTestCase): # Data for Zcash testnet header #1464167 valid_header = "04000000a9454c4ce26f7a34e32a5a36271c87854ec61d1e5b34cca79b08ba80fc283e00511973598670257752db4fdd82c80035ea9ce58693a0192a22e9dab738036ddf511cf33585c105f54c968ae6668c47fe3d4910ad50a0cd48cd2c6b5b74ce70675d7ad76008c6601f0a005dbc8ff9becddd5ecec9db6e8958147d020ab37ccd789c821c9425050000fd40050065e0fb1b9c16afdadfc14c2731e9c556ecce692938ec0566ef4fab0ace1bb72a1c4e76520936f78a89006a891dcaa1a26f973591f19066cccae72a7de0461b06ea1fde7065358754a98be25549eece6319d450039416f02ac814d891fea06150efc1456461bbf4d538d8157434a37681a769b4ce1d4de94183b39e76101de6df6644a318d35e3a946cb7ae56cd91f71a695449f8ad5cd72d301bbcefa66992c6d1f1dfd0f0d15c041a71ba5b1525e59f53532eaeb7d0a19ecaf2737b07b51a9df11aa970fe7b95050854edd74f291f6a9a064ceba9a0fabe57ea413246d9a915d09abb5bbb4220216a316d8947c36d6642e7022caf7da5bf5b42f1067f54b1b4cd14ed50fb8076e30ed8883c6d54e6234034f4c354997e58f4c569e45b7797beac995d41380c2db4e720e9e075610ed2364022078d1b53ea241f17ace970e190e96d3f98e34438ba050d89ed52478700884cdc838f7b094ee911606e301f5c82ae4d773910bee9416859f53f1fd311fb8df4bf5a4be474eb0f175c21117d95fe91980ac6b408c24982094e3fc78352a33eb8a3dd9d5917dc06f62fba90fdf01e1ff6c2173f9c90d91fbe13c18b346f49cf6405696ed668171fb2d33455e7a375eb58e524ee3071c5a8b81f0b4529f3efa0cb9f783b34c5f59d694ecc6573ab57146d3de225468da44bc1b71ef4e7ee4552c9aabbae64550b7d8e67ef0f9e26e92b4103b78977aadbf1bb49fc0f9adc4a720a24a1c3ca72745a48cc20a8a987ccf6186dafd581538c2d606623fab7a6e5da5b51b31a0461739d962ada85bb8b5686e6cbf46ab281d0ff167c26f83ec1048b8fc576dce712f2ffea1f8c263d41d35c0506fc61e5be359f8359dd497d825acc031aeb48310b56dbe90dff9728b2a70ccd3c9382a6f6989cf93671c6436491a0e6d088c5495561ac31a6b20f046500cbaf43b89df357741910de6323294512b18b844d015bb4fe6308a8087c11e058428e46f5a7f59efb5c2a614181de57c4bdf9b3c2ef0bc276dfb2559df69b38df54bc2a65cb5f70d317a08ddfd0d65544761c1700e9bd2728593893425be268c6fa5839e33d71fcd726011a26964d69488a78b5c7a64fbeca938b3adb1b1635368260940c5cfd5563767edaba4e16fd1e7c401af61f00be29eb9d8356e2869bfab02102f06b76e903a88d338d47633983cab226953fe714be7ae874e30c3eb2a8d9d97c9ed71728e423edaad2938d9a832b2993ab05ef11b0e7c73ac632e0d65d82a8305c879742117e92b7534951948d64b193d5a5bac56d58ae810b5e1ec8fc4436b7f803b25d54cec65b6cdb5e592a342e4d614631575ba0d836b2b8d41a3624e6d8a5ac17b4236d18ce2c1ce7e5441db767b28af153978fc423dd8be545d1fadf2990c5325ed6f0ea806f5f8e270315e54aff084e4c6db561c925e307370bd43f265e0c7deed4e29913dd9f740229db4e7e95d8b210a7660351ea03b70eff57f35ea1cc673ac8c8925f58f2ef1e134cf258c79811cae3821bf85e4a495a83efb6440c510128a24efe54e11965a4d8d925bd955333d301548a5c121da2f1f1a99ee5ba3fb6a3a6e1f0dd31731024869e4acba6c2b923b1a2d31131249f723c0306176352573696da718f9c43b56facfa959719f7a2320802b6348e936ff3b43f85915fcfbacd7ebdf391cd22dd06256b6696c364318369467a1d5975ccaf476716910a1624d02b92dc06c1c77925947dcf2e7ca57e18a53cbe984e9d274da6f213f47dd5cccfae4f029f0de0f4f66f11bceb9180514177c3e9418d48f7df121e31f6f1dacc598965abd34d00e52c1e96823eb8b30eb39b0795d8d3f2cf6a89ae817758fb4a3ffc6eee124450f638cd31eeebeeb2bf9077d935c05c196f81" target = Blockchain.bits_to_target(526435848) prev_hash = "003e28fc80ba089ba7cc345b1e1dc64e85871c27365a2ae3347a6fe24c4c45a9" def setUp(self): super().setUp() self.header = deserialize_header(bfh(self.valid_header), 1296288) def test_valid_header(self): Blockchain.verify_header(self.header, self.prev_hash, self.target) def test_expected_hash_mismatch(self): with self.assertRaises(Exception): Blockchain.verify_header(self.header, self.prev_hash, self.target, expected_header_hash="foo") def test_prev_hash_mismatch(self): with self.assertRaises(Exception): Blockchain.verify_header(self.header, "foo", self.target) def test_target_mismatch(self): with self.assertRaises(Exception): other_target = Blockchain.bits_to_target(0x1d00eeee) Blockchain.verify_header(self.header, self.prev_hash, other_target) def test_insufficient_pow(self): with self.assertRaises(Exception): self.header["nonce"] = 42 Blockchain.verify_header(self.header, self.prev_hash, self.target)
def test_parents_after_forking(self): blockchain.blockchains[constants.net.GENESIS] = chain_u = Blockchain( config=self.config, forkpoint=0, parent=None, forkpoint_hash=constants.net.GENESIS, prev_hash=None) open(chain_u.path(), 'w+').close() self._append_header(chain_u, self.HEADERS['A']) self._append_header(chain_u, self.HEADERS['B']) self._append_header(chain_u, self.HEADERS['C']) self._append_header(chain_u, self.HEADERS['D']) self._append_header(chain_u, self.HEADERS['E']) self._append_header(chain_u, self.HEADERS['F']) self._append_header(chain_u, self.HEADERS['O']) self._append_header(chain_u, self.HEADERS['P']) self._append_header(chain_u, self.HEADERS['Q']) self.assertEqual(None, chain_u.parent) chain_l = chain_u.fork(self.HEADERS['G']) self._append_header(chain_l, self.HEADERS['H']) self._append_header(chain_l, self.HEADERS['I']) self._append_header(chain_l, self.HEADERS['J']) self._append_header(chain_l, self.HEADERS['K']) self._append_header(chain_l, self.HEADERS['L']) self.assertEqual(None, chain_l.parent) self.assertEqual(chain_l, chain_u.parent) chain_z = chain_l.fork(self.HEADERS['M']) self._append_header(chain_z, self.HEADERS['N']) self._append_header(chain_z, self.HEADERS['X']) self._append_header(chain_z, self.HEADERS['Y']) self._append_header(chain_z, self.HEADERS['Z']) self.assertEqual(chain_z, chain_u.parent) self.assertEqual(chain_z, chain_l.parent) self.assertEqual(None, chain_z.parent) self._append_header(chain_u, self.HEADERS['R']) self._append_header(chain_u, self.HEADERS['S']) self._append_header(chain_u, self.HEADERS['T']) self._append_header(chain_u, self.HEADERS['U']) self.assertEqual(chain_z, chain_u.parent) self.assertEqual(chain_z, chain_l.parent) self.assertEqual(None, chain_z.parent)
def test_get_height_of_last_common_block_with_chain(self): blockchain.blockchains[constants.net.GENESIS] = chain_u = Blockchain( config=self.config, forkpoint=0, parent=None, forkpoint_hash=constants.net.GENESIS, prev_hash=None) open(chain_u.path(), 'w+').close() self._append_header(chain_u, self.HEADERS['A']) self._append_header(chain_u, self.HEADERS['B']) self._append_header(chain_u, self.HEADERS['C']) self._append_header(chain_u, self.HEADERS['D']) self._append_header(chain_u, self.HEADERS['E']) self._append_header(chain_u, self.HEADERS['F']) self._append_header(chain_u, self.HEADERS['O']) self._append_header(chain_u, self.HEADERS['P']) self._append_header(chain_u, self.HEADERS['Q']) chain_l = chain_u.fork(self.HEADERS['G']) self._append_header(chain_l, self.HEADERS['H']) self._append_header(chain_l, self.HEADERS['I']) self._append_header(chain_l, self.HEADERS['J']) self._append_header(chain_l, self.HEADERS['K']) self._append_header(chain_l, self.HEADERS['L']) self.assertEqual({ chain_u: 8, chain_l: 5 }, chain_u.get_parent_heights()) self.assertEqual({chain_l: 11}, chain_l.get_parent_heights()) chain_z = chain_l.fork(self.HEADERS['M']) self._append_header(chain_z, self.HEADERS['N']) self._append_header(chain_z, self.HEADERS['X']) self._append_header(chain_z, self.HEADERS['Y']) self._append_header(chain_z, self.HEADERS['Z']) self.assertEqual({ chain_u: 8, chain_z: 5 }, chain_u.get_parent_heights()) self.assertEqual({ chain_l: 11, chain_z: 8 }, chain_l.get_parent_heights()) self.assertEqual({chain_z: 13}, chain_z.get_parent_heights()) self.assertEqual( 5, chain_u.get_height_of_last_common_block_with_chain(chain_l)) self.assertEqual( 5, chain_l.get_height_of_last_common_block_with_chain(chain_u)) self.assertEqual( 5, chain_u.get_height_of_last_common_block_with_chain(chain_z)) self.assertEqual( 5, chain_z.get_height_of_last_common_block_with_chain(chain_u)) self.assertEqual( 8, chain_l.get_height_of_last_common_block_with_chain(chain_z)) self.assertEqual( 8, chain_z.get_height_of_last_common_block_with_chain(chain_l)) self._append_header(chain_u, self.HEADERS['R']) self._append_header(chain_u, self.HEADERS['S']) self._append_header(chain_u, self.HEADERS['T']) self._append_header(chain_u, self.HEADERS['U']) self.assertEqual({ chain_u: 12, chain_z: 5 }, chain_u.get_parent_heights()) self.assertEqual({ chain_l: 11, chain_z: 8 }, chain_l.get_parent_heights()) self.assertEqual({chain_z: 13}, chain_z.get_parent_heights()) self.assertEqual( 5, chain_u.get_height_of_last_common_block_with_chain(chain_l)) self.assertEqual( 5, chain_l.get_height_of_last_common_block_with_chain(chain_u)) self.assertEqual( 5, chain_u.get_height_of_last_common_block_with_chain(chain_z)) self.assertEqual( 5, chain_z.get_height_of_last_common_block_with_chain(chain_u)) self.assertEqual( 8, chain_l.get_height_of_last_common_block_with_chain(chain_z)) self.assertEqual( 8, chain_z.get_height_of_last_common_block_with_chain(chain_l))
def _append_header(self, chain: Blockchain, header: dict): self.assertTrue(chain.can_connect(header)) chain.save_header(header)
def test_insufficient_pow(self): with self.assertRaises(Exception): self.header["nonce"] = 42 Blockchain.verify_header(self.header, self.prev_hash, self.target)
def test_target_mismatch(self): with self.assertRaises(Exception): other_target = Blockchain.bits_to_target(0x1d00eeee) Blockchain.verify_header(self.header, self.prev_hash, other_target)
def test_prev_hash_mismatch(self): with self.assertRaises(Exception): Blockchain.verify_header(self.header, "foo", self.target)
def test_expected_hash_mismatch(self): with self.assertRaises(Exception): Blockchain.verify_header(self.header, self.prev_hash, self.target, expected_header_hash="foo")
def test_valid_header(self): Blockchain.verify_header(self.header, self.prev_hash, self.target)
def test_get_chains_that_contain_header(self): blockchain.blockchains[constants.net.GENESIS] = chain_u = Blockchain( config=self.config, forkpoint=0, parent=None, forkpoint_hash=constants.net.GENESIS, prev_hash=None) open(chain_u.path(), 'w+').close() self._append_header(chain_u, self.HEADERS['A']) self._append_header(chain_u, self.HEADERS['B']) self._append_header(chain_u, self.HEADERS['C']) self._append_header(chain_u, self.HEADERS['D']) self._append_header(chain_u, self.HEADERS['E']) self._append_header(chain_u, self.HEADERS['F']) self._append_header(chain_u, self.HEADERS['O']) self._append_header(chain_u, self.HEADERS['P']) self._append_header(chain_u, self.HEADERS['Q']) chain_l = chain_u.fork(self.HEADERS['G']) self._append_header(chain_l, self.HEADERS['H']) self._append_header(chain_l, self.HEADERS['I']) self._append_header(chain_l, self.HEADERS['J']) self._append_header(chain_l, self.HEADERS['K']) self._append_header(chain_l, self.HEADERS['L']) chain_z = chain_l.fork(self.HEADERS['M']) self.assertEqual([chain_l, chain_z, chain_u], self.get_chains_that_contain_header_helper( self.HEADERS['A'])) self.assertEqual([chain_l, chain_z, chain_u], self.get_chains_that_contain_header_helper( self.HEADERS['C'])) self.assertEqual([chain_l, chain_z, chain_u], self.get_chains_that_contain_header_helper( self.HEADERS['F'])) self.assertEqual([chain_l, chain_z], self.get_chains_that_contain_header_helper( self.HEADERS['G'])) self.assertEqual([chain_l, chain_z], self.get_chains_that_contain_header_helper( self.HEADERS['I'])) self.assertEqual([chain_z], self.get_chains_that_contain_header_helper( self.HEADERS['M'])) self.assertEqual([chain_l], self.get_chains_that_contain_header_helper( self.HEADERS['K'])) self._append_header(chain_z, self.HEADERS['N']) self._append_header(chain_z, self.HEADERS['X']) self._append_header(chain_z, self.HEADERS['Y']) self._append_header(chain_z, self.HEADERS['Z']) self.assertEqual([chain_z, chain_l, chain_u], self.get_chains_that_contain_header_helper( self.HEADERS['A'])) self.assertEqual([chain_z, chain_l, chain_u], self.get_chains_that_contain_header_helper( self.HEADERS['C'])) self.assertEqual([chain_z, chain_l, chain_u], self.get_chains_that_contain_header_helper( self.HEADERS['F'])) self.assertEqual([chain_u], self.get_chains_that_contain_header_helper( self.HEADERS['O'])) self.assertEqual([chain_z, chain_l], self.get_chains_that_contain_header_helper( self.HEADERS['I']))
def test_doing_multiple_swaps_after_single_new_header(self): blockchain.blockchains[constants.net.GENESIS] = chain_u = Blockchain( config=self.config, forkpoint=0, parent=None, forkpoint_hash=constants.net.GENESIS, prev_hash=None) open(chain_u.path(), 'w+').close() self._append_header(chain_u, self.HEADERS['A']) self._append_header(chain_u, self.HEADERS['B']) self._append_header(chain_u, self.HEADERS['C']) self._append_header(chain_u, self.HEADERS['D']) self._append_header(chain_u, self.HEADERS['E']) self._append_header(chain_u, self.HEADERS['F']) self._append_header(chain_u, self.HEADERS['O']) self._append_header(chain_u, self.HEADERS['P']) self._append_header(chain_u, self.HEADERS['Q']) self._append_header(chain_u, self.HEADERS['R']) self._append_header(chain_u, self.HEADERS['S']) self.assertEqual(1, len(blockchain.blockchains)) self.assertEqual(0, len(os.listdir(os.path.join(self.data_dir, "forks")))) chain_l = chain_u.fork(self.HEADERS['G']) self._append_header(chain_l, self.HEADERS['H']) self._append_header(chain_l, self.HEADERS['I']) self._append_header(chain_l, self.HEADERS['J']) self._append_header(chain_l, self.HEADERS['K']) # now chain_u is best chain, but it's tied with chain_l self.assertEqual(2, len(blockchain.blockchains)) self.assertEqual(1, len(os.listdir(os.path.join(self.data_dir, "forks")))) chain_z = chain_l.fork(self.HEADERS['M']) self._append_header(chain_z, self.HEADERS['N']) self._append_header(chain_z, self.HEADERS['X']) self.assertEqual(3, len(blockchain.blockchains)) self.assertEqual(2, len(os.listdir(os.path.join(self.data_dir, "forks")))) # chain_z became best chain, do checks self.assertEqual(0, chain_z.forkpoint) self.assertEqual(None, chain_z.parent) self.assertEqual(constants.net.GENESIS, chain_z._forkpoint_hash) self.assertEqual(None, chain_z._prev_hash) self.assertEqual(os.path.join(self.data_dir, "blockchain_headers"), chain_z.path()) self.assertEqual(12 * 80, os.stat(chain_z.path()).st_size) self.assertEqual(9, chain_l.forkpoint) self.assertEqual(chain_z, chain_l.parent) self.assertEqual(hash_header(self.HEADERS['J']), chain_l._forkpoint_hash) self.assertEqual(hash_header(self.HEADERS['I']), chain_l._prev_hash) self.assertEqual( os.path.join( self.data_dir, "forks", "fork2_9_67b0765c4090086b9dcecb70ba3d10e807df305cce403e4c6e4ca9edfe4d5a1d_a879ddca14a9d4d1c81ee90401910e7a186ee6511972aefa8791524a94463cf9" ), chain_l.path()) self.assertEqual(2 * 80, os.stat(chain_l.path()).st_size) self.assertEqual(6, chain_u.forkpoint) self.assertEqual(chain_z, chain_u.parent) self.assertEqual(hash_header(self.HEADERS['O']), chain_u._forkpoint_hash) self.assertEqual(hash_header(self.HEADERS['F']), chain_u._prev_hash) self.assertEqual( os.path.join( self.data_dir, "forks", "fork2_6_61b274ea009f7566740eec9aeff7676c6dffb4136a1033427f5d7647e0fe0bed_a9e0ca750c5f9d2e2a22d858c2282d64936f672ab6030ba9edd45f291e9f9b1f" ), chain_u.path()) self.assertEqual(5 * 80, os.stat(chain_u.path()).st_size) self.assertEqual(constants.net.GENESIS, chain_z.get_hash(0)) self.assertEqual(hash_header(self.HEADERS['F']), chain_z.get_hash(5)) self.assertEqual(hash_header(self.HEADERS['G']), chain_z.get_hash(6)) self.assertEqual(hash_header(self.HEADERS['I']), chain_z.get_hash(8)) self.assertEqual(hash_header(self.HEADERS['M']), chain_z.get_hash(9)) self.assertEqual(hash_header(self.HEADERS['X']), chain_z.get_hash(11)) for b in (chain_u, chain_l, chain_z): self.assertTrue( all([ b.can_connect(b.read_header(i), False) for i in range(b.height()) ]))
def test_forking_and_swapping(self): blockchain.blockchains[constants.net.GENESIS] = chain_u = Blockchain( config=self.config, forkpoint=0, parent=None, forkpoint_hash=constants.net.GENESIS, prev_hash=None) open(chain_u.path(), 'w+').close() self._append_header(chain_u, self.HEADERS['A']) self._append_header(chain_u, self.HEADERS['B']) self._append_header(chain_u, self.HEADERS['C']) self._append_header(chain_u, self.HEADERS['D']) self._append_header(chain_u, self.HEADERS['E']) self._append_header(chain_u, self.HEADERS['F']) self._append_header(chain_u, self.HEADERS['O']) self._append_header(chain_u, self.HEADERS['P']) self._append_header(chain_u, self.HEADERS['Q']) self._append_header(chain_u, self.HEADERS['R']) chain_l = chain_u.fork(self.HEADERS['G']) self._append_header(chain_l, self.HEADERS['H']) self._append_header(chain_l, self.HEADERS['I']) self._append_header(chain_l, self.HEADERS['J']) # do checks self.assertEqual(2, len(blockchain.blockchains)) self.assertEqual(1, len(os.listdir(os.path.join(self.data_dir, "forks")))) self.assertEqual(0, chain_u.forkpoint) self.assertEqual(None, chain_u.parent) self.assertEqual(constants.net.GENESIS, chain_u._forkpoint_hash) self.assertEqual(None, chain_u._prev_hash) self.assertEqual(os.path.join(self.data_dir, "blockchain_headers"), chain_u.path()) self.assertEqual(10 * 80, os.stat(chain_u.path()).st_size) self.assertEqual(6, chain_l.forkpoint) self.assertEqual(chain_u, chain_l.parent) self.assertEqual(hash_header(self.HEADERS['G']), chain_l._forkpoint_hash) self.assertEqual(hash_header(self.HEADERS['F']), chain_l._prev_hash) self.assertEqual( os.path.join( self.data_dir, "forks", "fork2_6_61b274ea009f7566740eec9aeff7676c6dffb4136a1033427f5d7647e0fe0bed_e3599615f2e4e04bd143ecaead68800b3e4497113eddc17c1e3602e01622caf8" ), chain_l.path()) self.assertEqual(4 * 80, os.stat(chain_l.path()).st_size) self._append_header(chain_l, self.HEADERS['K']) # chains were swapped, do checks self.assertEqual(2, len(blockchain.blockchains)) self.assertEqual(1, len(os.listdir(os.path.join(self.data_dir, "forks")))) self.assertEqual(6, chain_u.forkpoint) self.assertEqual(chain_l, chain_u.parent) self.assertEqual(hash_header(self.HEADERS['O']), chain_u._forkpoint_hash) self.assertEqual(hash_header(self.HEADERS['F']), chain_u._prev_hash) self.assertEqual( os.path.join( self.data_dir, "forks", "fork2_6_61b274ea009f7566740eec9aeff7676c6dffb4136a1033427f5d7647e0fe0bed_a9e0ca750c5f9d2e2a22d858c2282d64936f672ab6030ba9edd45f291e9f9b1f" ), chain_u.path()) self.assertEqual(4 * 80, os.stat(chain_u.path()).st_size) self.assertEqual(0, chain_l.forkpoint) self.assertEqual(None, chain_l.parent) self.assertEqual(constants.net.GENESIS, chain_l._forkpoint_hash) self.assertEqual(None, chain_l._prev_hash) self.assertEqual(os.path.join(self.data_dir, "blockchain_headers"), chain_l.path()) self.assertEqual(11 * 80, os.stat(chain_l.path()).st_size) for b in (chain_u, chain_l): self.assertTrue( all([ b.can_connect(b.read_header(i), False) for i in range(b.height()) ])) self._append_header(chain_u, self.HEADERS['S']) self._append_header(chain_u, self.HEADERS['T']) self._append_header(chain_u, self.HEADERS['U']) self._append_header(chain_l, self.HEADERS['L']) chain_z = chain_l.fork(self.HEADERS['M']) self._append_header(chain_z, self.HEADERS['N']) self._append_header(chain_z, self.HEADERS['X']) self._append_header(chain_z, self.HEADERS['Y']) self._append_header(chain_z, self.HEADERS['Z']) # chain_z became best chain, do checks self.assertEqual(3, len(blockchain.blockchains)) self.assertEqual(2, len(os.listdir(os.path.join(self.data_dir, "forks")))) self.assertEqual(0, chain_z.forkpoint) self.assertEqual(None, chain_z.parent) self.assertEqual(constants.net.GENESIS, chain_z._forkpoint_hash) self.assertEqual(None, chain_z._prev_hash) self.assertEqual(os.path.join(self.data_dir, "blockchain_headers"), chain_z.path()) self.assertEqual(14 * 80, os.stat(chain_z.path()).st_size) self.assertEqual(9, chain_l.forkpoint) self.assertEqual(chain_z, chain_l.parent) self.assertEqual(hash_header(self.HEADERS['J']), chain_l._forkpoint_hash) self.assertEqual(hash_header(self.HEADERS['I']), chain_l._prev_hash) self.assertEqual( os.path.join( self.data_dir, "forks", "fork2_9_67b0765c4090086b9dcecb70ba3d10e807df305cce403e4c6e4ca9edfe4d5a1d_a879ddca14a9d4d1c81ee90401910e7a186ee6511972aefa8791524a94463cf9" ), chain_l.path()) self.assertEqual(3 * 80, os.stat(chain_l.path()).st_size) self.assertEqual(6, chain_u.forkpoint) self.assertEqual(chain_z, chain_u.parent) self.assertEqual(hash_header(self.HEADERS['O']), chain_u._forkpoint_hash) self.assertEqual(hash_header(self.HEADERS['F']), chain_u._prev_hash) self.assertEqual( os.path.join( self.data_dir, "forks", "fork2_6_61b274ea009f7566740eec9aeff7676c6dffb4136a1033427f5d7647e0fe0bed_a9e0ca750c5f9d2e2a22d858c2282d64936f672ab6030ba9edd45f291e9f9b1f" ), chain_u.path()) self.assertEqual(7 * 80, os.stat(chain_u.path()).st_size) for b in (chain_u, chain_l, chain_z): self.assertTrue( all([ b.can_connect(b.read_header(i), False) for i in range(b.height()) ])) self.assertEqual(constants.net.GENESIS, chain_z.get_hash(0)) self.assertEqual(hash_header(self.HEADERS['F']), chain_z.get_hash(5)) self.assertEqual(hash_header(self.HEADERS['G']), chain_z.get_hash(6)) self.assertEqual(hash_header(self.HEADERS['I']), chain_z.get_hash(8)) self.assertEqual(hash_header(self.HEADERS['M']), chain_z.get_hash(9)) self.assertEqual(hash_header(self.HEADERS['Z']), chain_z.get_hash(13))