def test_chain2_at_genesis(base_db, genesis_state, genesis_block, config): genesis_block = genesis_block.message chain_db = BeaconChainDB.from_genesis(base_db, genesis_state, SignedBeaconBlock, config) block_at_genesis = chain_db.get_block_by_slot(GENESIS_SLOT, BeaconBlock) assert block_at_genesis == genesis_block block_at_genesis = chain_db.get_block_by_root(genesis_block.hash_tree_root, BeaconBlock) assert block_at_genesis == genesis_block genesis_signature = chain_db.get_block_signature_by_root( genesis_block.hash_tree_root) assert genesis_signature == EMPTY_SIGNATURE state_at_genesis = chain_db.get_state_by_slot(GENESIS_SLOT, BeaconState, config) assert state_at_genesis == genesis_state state_at_genesis = chain_db.get_state_by_root(genesis_state.hash_tree_root, BeaconState, config) assert state_at_genesis == genesis_state finalized_head = chain_db.get_finalized_head(BeaconBlock) assert finalized_head == genesis_block
def test_chain2_at_genesis(base_db, genesis_state, genesis_block, config): genesis_block = genesis_block.message chain_db = BeaconChainDB.from_genesis(base_db, genesis_state, SignedBeaconBlock, config) block_at_genesis = chain_db.get_block_by_slot(GENESIS_SLOT, BeaconBlock) assert block_at_genesis == genesis_block block_at_genesis = chain_db.get_block_by_root(genesis_block.hash_tree_root, BeaconBlock) assert block_at_genesis == genesis_block genesis_signature = chain_db.get_block_signature_by_root( genesis_block.hash_tree_root) assert genesis_signature == EMPTY_SIGNATURE state_at_genesis = chain_db.get_state_by_slot(GENESIS_SLOT, BeaconState) assert state_at_genesis == genesis_state state_at_genesis = chain_db.get_state_by_root(genesis_state.hash_tree_root, BeaconState) assert state_at_genesis == genesis_state finalized_head = chain_db.get_finalized_head(BeaconBlock) assert finalized_head == genesis_block some_future_slot = Slot(22) assert not chain_db.get_block_by_slot(some_future_slot, BeaconBlock) assert not chain_db.get_state_by_slot(some_future_slot, BeaconState) block_at_future_slot = SignedBeaconBlock.create(message=BeaconBlock.create( slot=some_future_slot)) chain_db.persist_block(block_at_future_slot) future_block = chain_db.get_block_by_root( block_at_future_slot.message.hash_tree_root, BeaconBlock) assert block_at_future_slot.message == future_block # NOTE: only finalized blocks are stored by slot in the DB # non-finalized but canonical blocks are determined by fork choice, separately from the DB assert not chain_db.get_block_by_slot(some_future_slot, BeaconBlock) # assume the fork choice did finalize this block... chain_db.mark_canonical_block(block_at_future_slot.message) assert chain_db.get_block_by_slot(some_future_slot, BeaconBlock) == future_block
def test_chain2_full(base_db, genesis_state, config): chain_db = BeaconChainDB.from_genesis(base_db, genesis_state, SignedBeaconBlock, config) state = genesis_state states = [genesis_state] blocks = {} num_slots = 500 skip_slots = [5, 64, 100, 300, 301, 302, 401] finalized_slots = [8, 24, 32, 72, 152, 160, 328, 336, 344, 352, 400] # create a new state at each slot using ``_mini_stf()`` and persist it for _ in range(1, num_slots): if state.slot not in skip_slots: new_block = BeaconBlock.create(slot=state.slot, state_root=state.hash_tree_root) blocks[state.slot] = new_block chain_db.persist_block(SignedBeaconBlock.create(message=new_block)) else: new_block = None state = _mini_stf(state, new_block, config) chain_db.persist_state(state, config) states.append(state) # test that each state created above equals the state stored at its root for state in states: # finalize a slot two epochs after processing it # this is here to test the reconstruction of ``state.randao_mixes`` maybe_finalized_slot = state.slot - config.SLOTS_PER_EPOCH * 2 if maybe_finalized_slot in finalized_slots: chain_db.mark_finalized_head(blocks[maybe_finalized_slot]) retrieved_state = chain_db._read_state(state.hash_tree_root, BeaconState, config) assert retrieved_state == state for slot in range(0, num_slots): if slot in blocks and slot <= finalized_slots[-1]: assert chain_db.get_block_by_slot(Slot(slot), BeaconBlock) == blocks[slot] else: assert chain_db.get_block_by_slot(Slot(slot), BeaconBlock) is None
def from_genesis(cls, base_db: AtomicDatabaseAPI, genesis_state: BeaconState) -> "BeaconChain": for starting_slot, state_machine_class in cls._sm_configuration: if starting_slot == GENESIS_SLOT: signed_block_class = state_machine_class.signed_block_class fork_choice_class = state_machine_class.fork_choice_class config = state_machine_class.config # NOTE: important this happens as soon as it can... override_lengths(config) break else: raise Exception("state machine configuration missing genesis era") assert genesis_state.slot == GENESIS_SLOT chain_db = BeaconChainDB.from_genesis(base_db, genesis_state, signed_block_class, config) block_sink = ChainDBBlockSink(chain_db) fork_choice = fork_choice_class.from_genesis(genesis_state, config, block_sink) return cls(chain_db, fork_choice)