def _read_state_randao_mixes(self, state_root: Root, EPOCHS_PER_HISTORICAL_VECTOR: int, SLOTS_PER_EPOCH: int) -> Iterable[Root]: """ Reconstructs the ``randao_mixes`` at a given state root. """ state_slot = self._read_state_slot(state_root) state_epoch = compute_epoch_at_slot(state_slot, SLOTS_PER_EPOCH) finalized_slot = self.get_finalized_head(BeaconBlock).slot non_finalized_state_roots = dict( enumerate( self.get_state_parents(state_root, state_slot - finalized_slot), finalized_slot, )) # create a list of epochs that corresponds to each mix in ``state.randao_mixes`` epochs = [ Epoch(n) for n in range(state_epoch - EPOCHS_PER_HISTORICAL_VECTOR + 1, state_epoch + 1) ] offset = EPOCHS_PER_HISTORICAL_VECTOR - epochs[ 0] % EPOCHS_PER_HISTORICAL_VECTOR epochs = epochs[offset:] + epochs[:offset] genesis_root = self._read_state_root_at_slot(Slot(0)) genesis_randao_mix = Root( Hash32(self.db[SchemaV1.state_root_to_randao_mix(genesis_root)])) for epoch in epochs: if epoch < 0: yield genesis_randao_mix elif epoch == state_epoch: # yield the randao mix at the particular slot key = SchemaV1.state_root_to_randao_mix(state_root) yield Root(Hash32(self.db[key])) else: # yield the randao mix at the last slot in the epoch slot = Slot((epoch + 1) * SLOTS_PER_EPOCH - 1) if slot in non_finalized_state_roots: root = non_finalized_state_roots[slot] else: root = self._read_state_root_at_slot(slot) key = SchemaV1.state_root_to_randao_mix(root) yield Root(Hash32(self.db[key]))
def get_state_by_slot(self, slot: Slot, state_class: Type[BeaconState], config: Eth2Config) -> Optional[BeaconState]: key = SchemaV1.slot_to_state_root(slot) try: root = Root(Hash32(self.db[key])) except KeyError: return None return self.get_state_by_root(root, state_class, config)
def get_block_by_slot( self, slot: Slot, block_class: Type[BaseBeaconBlock]) -> Optional[BaseBeaconBlock]: key = SchemaV1.slot_to_block_root(slot) try: root = Root(Hash32(self.db[key])) except KeyError: return None return self.get_block_by_root(root, block_class)
def _bytes_to_roots(roots_bytes: bytes) -> Iterable[Root]: bytes_len = len(roots_bytes) if bytes_len % 32 != 0: raise ValueError("bytes not divisible by 32") for i in range(0, int(bytes_len / 32)): start = i * 32 end = start + 32 yield Root(Hash32(roots_bytes[start:end]))
def _read_state_balances(self, state_root: Root, VALIDATOR_REGISTRY_LIMIT: int) -> Tuple[Gwei]: state_root_to_balances_root = SchemaV1.state_root_to_balances_root( state_root) balances_root = Root(Hash32(self.db[state_root_to_balances_root])) balances_root_to_balances = SchemaV1.balances_root_to_balances( balances_root) return ssz.decode( self.db[balances_root_to_balances], ssz.List(ssz.uint64, VALIDATOR_REGISTRY_LIMIT), )
def _read_state_validators(self, state_root: Root) -> Iterable[Validator]: state_root_to_validators_root = SchemaV1.state_root_to_validators_root( state_root) validators_root = Root(Hash32(self.db[state_root_to_validators_root])) validators_root_to_roots_of_validators = SchemaV1.validators_root_to_roots_of_validators( validators_root) roots = _bytes_to_roots( self.db[validators_root_to_roots_of_validators]) for root in roots: yield ssz.decode(self.db[bytes(root)], Validator)
def _read_state_block_roots( self, state_root: Root, SLOTS_PER_HISTORICAL_ROOT: int) -> Iterable[Root]: """ Reconstructs ``state.block_roots`` at a given state root. """ for root in self._read_state_state_roots(state_root, SLOTS_PER_HISTORICAL_ROOT): if root == default_root: yield default_root else: key = SchemaV1.state_root_to_latest_block_header_root(root) yield Root(Hash32(self.db[key]))
def get_finalized_head( self, block_class: Type[BaseBeaconBlock]) -> BaseBeaconBlock: finalized_head_root_key = SchemaV1.finalized_head_root() finalized_head_root = Root(Hash32(self.db[finalized_head_root_key])) return self.get_block_by_root(finalized_head_root, block_class)
def _read_state_root_at_slot(self, slot: Slot) -> Root: key = SchemaV1.slot_to_state_root(slot) return Root(Hash32(self.db[key]))
def _read_state_parent_state_root(self, state_root: Root) -> Root: key = SchemaV1.state_root_to_parent_state_root(state_root) return Root(Hash32(self.db[key]))
def _read_state_block_header(self, state_root: Root) -> BeaconBlockHeader: block_root = Root( Hash32(self.db[SchemaV1.state_root_to_latest_block_header_root( state_root)])) key = SchemaV1.block_root_to_block_header(block_root) return ssz.decode(self.db[key], BeaconBlockHeader)
def get_justified_head( self, block_class: Type[BaseBeaconBlock]) -> BaseBeaconBlock: justified_head_root_key = SchemaV1.justified_head_root() justified_head_root = Root(Hash32(self.db[justified_head_root_key])) return self.get_block_by_root(justified_head_root, block_class)
def get_canonical_head( self, block_class: Type[BaseBeaconBlock]) -> BaseBeaconBlock: canonical_head_root_key = SchemaV1.canonical_head_root() canonical_head_root = Root(Hash32(self.db[canonical_head_root_key])) return self.get_block_by_root(canonical_head_root, block_class)