def __recover_from_db(self): """ Recover the best chain from local database. """ Logger.info("Recovering root chain from local database...") if b"tipHash" not in self.db: return None r_hash = self.db.get(b"tipHash") r_block = RootBlock.deserialize(self.db.get(b"rblock_" + r_hash)) if r_block.header.height <= 0: return None # use the parent of the tipHash block as the new tip # since it's guaranteed to have been accepted by all the shards # while shards might not have seen the block of tipHash r_hash = r_block.header.hash_prev_block r_block = RootBlock.deserialize(self.db.get(b"rblock_" + r_hash)) self.tip_header = r_block.header # type: RootBlockHeader while len(self.r_header_pool) < self.max_num_blocks_to_recover: self.r_header_pool[r_hash] = r_block.header for m_header in r_block.minor_block_header_list: mtokens = TokenBalanceMap.deserialize( self.db.get(b"mheader_" + m_header.get_hash())).balance_map self.m_hash_dict[m_header.get_hash()] = mtokens if r_block.header.height <= 0: break r_hash = r_block.header.hash_prev_block r_block = RootBlock.deserialize(self.db.get(b"rblock_" + r_hash))
def contain_minor_block_by_hash(self, h): if h in self.m_hash_dict: return True tokens = self.db.get(b"mheader_" + h) if tokens is None: return False self.m_hash_dict[h] = TokenBalanceMap.deserialize(tokens).balance_map return True
def test_token_serialization(self): # ignore 0 values in TokenBalanceMap m0 = TokenBalanceMap({3234: 10, 0: 0, 3567: 0}) m1 = TokenBalanceMap({3234: 10}) self.assertEqual(m0.serialize(bytearray()), m1.serialize(bytearray())) self.assertEqual( TokenBalanceMap.deserialize(m0.serialize(bytearray())).balance_map, {3234: 10}, ) mx = FakeTokenBalanceMap({3232: 109, 0: 0, 3567: 999999}) bb = bytearray(b"\x00\x00\x00\x03\x00\x00\x02\x0c\xa0\x01m\x02\r\xef\x03\x0fB?") self.assertEqual(mx.serialize(bytearray()), bb) self.assertEqual( TokenBalanceMap.deserialize(bb).balance_map, {3232: 109, 3567: 999999} ) # if skip_func == None, do not omit key/value pairs md0 = MapData({5: 0, 1: 2, 10: 9}) md1 = MapData({10: 9, 3: 0, 1: 2}) self.assertNotEqual(md0.serialize(), md1.serialize())
def get_minor_block_coinbase_tokens(self, h: bytes): tokens = self.db.get(b"mheader_" + h) if tokens is None: raise KeyError() return TokenBalanceMap.deserialize(tokens).balance_map
def test_zero_balance(self): m0 = TokenBalanceMap({3234: 10, 0: 0, 3567: 0}) m1 = TokenBalanceMap.deserialize(m0.serialize()) self.assertEqual(m0, m1)