示例#1
0
    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)
示例#2
0
    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]))
示例#3
0
 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
示例#4
0
 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)
示例#5
0
 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)
示例#6
0
 def test_pack_unpack(self):
     blk = FakeBlock()
     blk_bytes = blk.pack()
     blk2 = BamiBlock.unpack(blk_bytes, blk.serializer)
     assert blk == blk2