Esempio n. 1
0
 def _get_chain_gaps(cls, db: DatabaseAPI) -> ChainGaps:
     try:
         encoded_gaps = db[SchemaV1.make_chain_gaps_lookup_key()]
     except KeyError:
         return GENESIS_CHAIN_GAPS
     else:
         return rlp.decode(encoded_gaps, sedes=chain_gaps)
Esempio n. 2
0
    def _update_header_chain_gaps(cls,
                                  db: DatabaseAPI,
                                  persisting_header: BlockHeaderAPI,
                                  base_gaps: ChainGaps = None) -> GapInfo:
        # The only reason we overwrite this here is to be able to detect when the HeaderDB
        # de-canonicalizes an uncle that should cause us to re-open a block gap.
        gap_change, gaps = super()._update_header_chain_gaps(
            db, persisting_header, base_gaps)

        if gap_change is not GapChange.NoChange or persisting_header.block_number == 0:
            return gap_change, gaps

        # We have written a header for which block number we've already had a header.
        # This might be a sign of a de-canonicalized uncle.
        current_gaps = cls._get_chain_gaps(db)
        if not is_block_number_in_gap(persisting_header.block_number,
                                      current_gaps):
            # ChainDB believes we have that block. If the header has changed, we need to re-open
            # a gap for the corresponding block.
            old_canonical_header = cls._get_canonical_block_header_by_number(
                db, persisting_header.block_number)
            if old_canonical_header != persisting_header:
                updated_gaps = reopen_gap(persisting_header.block_number,
                                          current_gaps)
                db.set(SchemaV1.make_chain_gaps_lookup_key(),
                       rlp.encode(updated_gaps, sedes=chain_gaps))

        return gap_change, gaps
Esempio n. 3
0
    def _update_chain_gaps(cls,
                           db: DatabaseAPI,
                           persisted_block: BlockAPI,
                           base_gaps: ChainGaps = None) -> GapInfo:

        # If we make many updates in a row, we can avoid reloading the integrity info by
        # continuously caching it and providing it as a parameter to this API
        if base_gaps is None:
            base_gaps = cls._get_chain_gaps(db)

        gap_change, gaps = fill_gap(persisted_block.number, base_gaps)
        if gap_change is not GapChange.NoChange:
            db.set(SchemaV1.make_chain_gaps_lookup_key(),
                   rlp.encode(gaps, sedes=chain_gaps))

        return gap_change, gaps