Documentation ¶
Overview ¶
Package state implements the whole state transition function which consists of per slot, per-epoch transitions. It also bootstraps the genesis beacon state for slot 0.
Package state implements the whole state transition function which consists of per slot, per-epoch transitions. It also bootstraps the genesis beacon state for slot 0.
Index ¶
- func CalculateStateRoot(ctx context.Context, state *pb.BeaconState, block *ethpb.BeaconBlock) ([32]byte, error)
- func CanProcessEpoch(state *pb.BeaconState) bool
- func ExecuteStateTransition(ctx context.Context, state *pb.BeaconState, block *ethpb.BeaconBlock) (*pb.BeaconState, error)
- func ExecuteStateTransitionNoVerify(ctx context.Context, state *pb.BeaconState, block *ethpb.BeaconBlock) (*pb.BeaconState, error)
- func GenesisBeaconState(deposits []*ethpb.Deposit, genesisTime uint64, eth1Data *ethpb.Eth1Data) (*pb.BeaconState, error)
- func IsValidGenesisState(chainStartDepositCount uint64, currentTime uint64) bool
- func ProcessBlock(ctx context.Context, state *pb.BeaconState, block *ethpb.BeaconBlock) (*pb.BeaconState, error)
- func ProcessEpoch(ctx context.Context, state *pb.BeaconState) (*pb.BeaconState, error)
- func ProcessEpochPrecompute(ctx context.Context, state *pb.BeaconState) (*pb.BeaconState, error)
- func ProcessOperations(ctx context.Context, state *pb.BeaconState, body *ethpb.BeaconBlockBody) (*pb.BeaconState, error)
- func ProcessSlot(ctx context.Context, state *pb.BeaconState) (*pb.BeaconState, error)
- func ProcessSlots(ctx context.Context, state *pb.BeaconState, slot uint64) (*pb.BeaconState, error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CalculateStateRoot ¶
func CalculateStateRoot( ctx context.Context, state *pb.BeaconState, block *ethpb.BeaconBlock, ) ([32]byte, error)
CalculateStateRoot defines the procedure for a state transition function. This does not validate any BLS signatures in a block, it is used for calculating the state root of the state for the block proposer to use. This does not modify state.
WARNING: This method does not validate any BLS signatures. This is used for proposer to compute state root before proposing a new block, and this does not modify state.
Spec pseudocode definition:
def state_transition(state: BeaconState, block: BeaconBlock, validate_state_root: bool=False) -> BeaconState: # Process slots (including those with no blocks) since block process_slots(state, block.slot) # Process block process_block(state, block) # Return post-state return state
func CanProcessEpoch ¶
func CanProcessEpoch(state *pb.BeaconState) bool
CanProcessEpoch checks the eligibility to process epoch. The epoch can be processed at the end of the last slot of every epoch
Spec pseudocode definition:
If (state.slot + 1) % SLOTS_PER_EPOCH == 0:
func ExecuteStateTransition ¶
func ExecuteStateTransition( ctx context.Context, state *pb.BeaconState, block *ethpb.BeaconBlock, ) (*pb.BeaconState, error)
ExecuteStateTransition defines the procedure for a state transition function.
Spec pseudocode definition:
def state_transition(state: BeaconState, block: BeaconBlock, validate_state_root: bool=False) -> BeaconState: # Process slots (including those with no blocks) since block process_slots(state, block.slot) # Process block process_block(state, block) # Validate state root (`validate_state_root == True` in production) if validate_state_root: assert block.state_root == hash_tree_root(state) # Return post-state return state
func ExecuteStateTransitionNoVerify ¶
func ExecuteStateTransitionNoVerify( ctx context.Context, state *pb.BeaconState, block *ethpb.BeaconBlock, ) (*pb.BeaconState, error)
ExecuteStateTransitionNoVerify defines the procedure for a state transition function. This does not validate any BLS signatures in a block, it is used for performing a state transition as quickly as possible. This function should only be used when we can trust the data we're receiving entirely, such as initial sync or for processing past accepted blocks.
WARNING: This method does not validate any signatures in a block. This method also modifies the passed in state.
Spec pseudocode definition:
def state_transition(state: BeaconState, block: BeaconBlock, validate_state_root: bool=False) -> BeaconState: # Process slots (including those with no blocks) since block process_slots(state, block.slot) # Process block process_block(state, block) # Return post-state return state
func GenesisBeaconState ¶
func GenesisBeaconState(deposits []*ethpb.Deposit, genesisTime uint64, eth1Data *ethpb.Eth1Data) (*pb.BeaconState, error)
GenesisBeaconState gets called when MinGenesisActiveValidatorCount count of full deposits were made to the deposit contract and the ChainStart log gets emitted.
Spec pseudocode definition:
def initialize_beacon_state_from_eth1(eth1_block_hash: Hash, eth1_timestamp: uint64, deposits: Sequence[Deposit]) -> BeaconState: state = BeaconState( genesis_time=eth1_timestamp - eth1_timestamp % SECONDS_PER_DAY + 2 * SECONDS_PER_DAY, eth1_data=Eth1Data(block_hash=eth1_block_hash, deposit_count=len(deposits)), latest_block_header=BeaconBlockHeader(body_root=hash_tree_root(BeaconBlockBody())), ) # Process deposits leaves = list(map(lambda deposit: deposit.data, deposits)) for index, deposit in enumerate(deposits): deposit_data_list = List[DepositData, 2**DEPOSIT_CONTRACT_TREE_DEPTH](*leaves[:index + 1]) state.eth1_data.deposit_root = hash_tree_root(deposit_data_list) process_deposit(state, deposit) # Process activations for index, validator in enumerate(state.validators): balance = state.balances[index] validator.effective_balance = min(balance - balance % EFFECTIVE_BALANCE_INCREMENT, MAX_EFFECTIVE_BALANCE) if validator.effective_balance == MAX_EFFECTIVE_BALANCE: validator.activation_eligibility_epoch = GENESIS_EPOCH validator.activation_epoch = GENESIS_EPOCH # Populate active_index_roots and compact_committees_roots indices_list = List[ValidatorIndex, VALIDATOR_REGISTRY_LIMIT](get_active_validator_indices(state, GENESIS_EPOCH)) active_index_root = hash_tree_root(indices_list) committee_root = get_compact_committees_root(state, GENESIS_EPOCH) for index in range(EPOCHS_PER_HISTORICAL_VECTOR): state.active_index_roots[index] = active_index_root state.compact_committees_roots[index] = committee_root return state
func IsValidGenesisState ¶
IsValidGenesisState gets called whenever there's a deposit event, it checks whether there's enough effective balance to trigger and if the minimum genesis time arrived already.
Spec pseudocode definition:
def is_valid_genesis_state(state: BeaconState) -> bool: if state.genesis_time < MIN_GENESIS_TIME: return False if len(get_active_validator_indices(state, GENESIS_EPOCH)) < MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: return False return True
This method has been modified from the spec to allow whole states not to be saved but instead only cache the relevant information.
func ProcessBlock ¶
func ProcessBlock( ctx context.Context, state *pb.BeaconState, block *ethpb.BeaconBlock, ) (*pb.BeaconState, error)
ProcessBlock creates a new, modified beacon state by applying block operation transformations as defined in the Ethereum Serenity specification, including processing proposer slashings, processing block attestations, and more.
Spec pseudocode definition:
def process_block(state: BeaconState, block: BeaconBlock) -> None: process_block_header(state, block) process_randao(state, block.body) process_eth1_data(state, block.body) process_operations(state, block.body)
func ProcessEpoch ¶
func ProcessEpoch(ctx context.Context, state *pb.BeaconState) (*pb.BeaconState, error)
ProcessEpoch describes the per epoch operations that are performed on the beacon state. It focuses on the validator registry, adjusting balances, and finalizing slots.
Spec pseudocode definition:
def process_epoch(state: BeaconState) -> None: process_justification_and_finalization(state) process_crosslinks(state) process_rewards_and_penalties(state) process_registry_updates(state) # @process_reveal_deadlines # @process_challenge_deadlines process_slashings(state) process_final_updates(state) # @after_process_final_updates
func ProcessEpochPrecompute ¶
func ProcessEpochPrecompute(ctx context.Context, state *pb.BeaconState) (*pb.BeaconState, error)
ProcessEpochPrecompute describes the per epoch operations that are performed on the beacon state. It's optimized by pre computing validator attested info and epoch total/attested balances upfront.
func ProcessOperations ¶
func ProcessOperations( ctx context.Context, state *pb.BeaconState, body *ethpb.BeaconBlockBody) (*pb.BeaconState, error)
ProcessOperations processes the operations in the beacon block and updates beacon state with the operations in block.
Spec pseudocode definition:
def process_operations(state: BeaconState, body: BeaconBlockBody) -> None: # Verify that outstanding deposits are processed up to the maximum number of deposits assert len(body.deposits) == min(MAX_DEPOSITS, state.eth1_data.deposit_count - state.eth1_deposit_index) # Verify that there are no duplicate transfers assert len(body.transfers) == len(set(body.transfers)) all_operations = ( (body.proposer_slashings, process_proposer_slashing), (body.attester_slashings, process_attester_slashing), (body.attestations, process_attestation), (body.deposits, process_deposit), (body.voluntary_exits, process_voluntary_exit), (body.transfers, process_transfer), ) # type: Sequence[Tuple[List, Callable]] for operations, function in all_operations: for operation in operations: function(state, operation)
func ProcessSlot ¶
func ProcessSlot(ctx context.Context, state *pb.BeaconState) (*pb.BeaconState, error)
ProcessSlot happens every slot and focuses on the slot counter and block roots record updates. It happens regardless if there's an incoming block or not. Spec pseudocode definition:
def process_slot(state: BeaconState) -> None: # Cache state root previous_state_root = hash_tree_root(state) state.state_roots[state.slot % SLOTS_PER_HISTORICAL_ROOT] = previous_state_root # Cache latest block header state root if state.latest_block_header.state_root == Bytes32(): state.latest_block_header.state_root = previous_state_root # Cache block root previous_block_root = signing_root(state.latest_block_header) state.block_roots[state.slot % SLOTS_PER_HISTORICAL_ROOT] = previous_block_root
func ProcessSlots ¶
func ProcessSlots(ctx context.Context, state *pb.BeaconState, slot uint64) (*pb.BeaconState, error)
ProcessSlots process through skip skips and apply epoch transition when it's needed
Spec pseudocode definition:
def process_slots(state: BeaconState, slot: Slot) -> None: assert state.slot <= slot while state.slot < slot: process_slot(state) # Process epoch on the first slot of the next epoch if (state.slot + 1) % SLOTS_PER_EPOCH == 0: process_epoch(state) state.slot += 1 ]
Types ¶
This section is empty.