def validate_persist_block(self, block: BamiBlock, peer: Peer = None) -> bool: """ Validate a block and if it's valid, persist it. Raises: InvalidBlockException - if block is not valid """ block = (BamiBlock.unpack(block, self.serializer) if type(block) is bytes else block) block_blob = block if type(block) is bytes else block.pack() if not block.block_invariants_valid(): # React on invalid block raise InvalidBlockException("Block invalid", str(block), peer) else: if not self.persistence.has_block(block.hash): self.process_block_unordered(block, peer) chain_id = block.com_id prefix = block.com_prefix if (self.persistence.get_chain(prefix + chain_id) and self.persistence.get_chain(prefix + chain_id).versions.get( block.com_seq_num) and block.short_hash in self.persistence.get_chain( prefix + chain_id).versions[block.com_seq_num]): raise Exception( "Inconsisistency between block store and chain store", self.persistence.get_chain(prefix + chain_id).versions, block.com_dot, ) self.persistence.add_block(block_blob, block)
def __init__(self, chain_factory: BaseChainFactory, block_store: BaseBlockStore): super().__init__() self._chain_factory = chain_factory self._block_store = block_store self.chains = dict() self.last_reconcile_seq_num = defaultdict(lambda: defaultdict(int)) self.last_frontier = defaultdict(lambda: defaultdict(lambda: Frontier( terminal=GENESIS_LINK, holes=(), inconsistencies=()))) # Sync chains with block store for block_blob in self._block_store.iterate_blocks(): self.add_block(block_blob[1], BamiBlock.unpack(block_blob[1]))
def get_block_and_blob_by_dot( self, chain_id: bytes, dot: Dot ) -> Tuple[bytes, BamiBlock]: """Get blob and serialized block and by the chain_id and dot. Can raise DatabaseDesynchronizedException if no block found.""" blk_blob = self.persistence.get_block_blob_by_dot(chain_id, dot) if not blk_blob: raise DatabaseDesynchronizedException( "Block is not found in db: {chain_id}, {dot}".format( chain_id=chain_id, dot=dot ) ) block = BamiBlock.unpack(blk_blob, self.serializer) return blk_blob, block
def received_raw_block_broadcast( self, peer: Peer, payload: RawBlockBroadcastPayload) -> None: block = BamiBlock.unpack(payload.block_bytes, self.serializer) self.validate_persist_block(block, peer) self.process_broadcast_block(block, payload.ttl)
def received_raw_block(self, peer: Peer, payload: RawBlockPayload) -> None: block = BamiBlock.unpack(payload.block_bytes, self.serializer) self.logger.debug("Received block from pull gossip %s from peer %s", block.com_dot, peer) self.validate_persist_block(block, peer)
def test_pack_unpack(self): blk = FakeBlock() blk_bytes = blk.pack() blk2 = BamiBlock.unpack(blk_bytes, blk.serializer) assert blk == blk2