2019-03-18 20:14:26 +00:00
|
|
|
from . import spec
|
|
|
|
|
|
|
|
|
2019-03-27 17:21:07 +00:00
|
|
|
from typing import (
|
2019-03-18 20:14:26 +00:00
|
|
|
Any,
|
|
|
|
Callable,
|
2019-03-27 17:21:07 +00:00
|
|
|
List
|
2019-03-18 20:14:26 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
from .spec import (
|
|
|
|
BeaconState,
|
|
|
|
BeaconBlock,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2019-03-19 23:10:36 +00:00
|
|
|
def expected_deposit_count(state: BeaconState) -> int:
|
|
|
|
return min(
|
|
|
|
spec.MAX_DEPOSITS,
|
|
|
|
state.latest_eth1_data.deposit_count - state.deposit_index
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2019-03-31 15:00:21 +00:00
|
|
|
def process_operation_type(state: BeaconState,
|
|
|
|
operations: List[Any],
|
|
|
|
max_operations: int,
|
|
|
|
tx_fn: Callable[[BeaconState, Any], None]) -> None:
|
|
|
|
assert len(operations) <= max_operations
|
|
|
|
for operation in operations:
|
|
|
|
tx_fn(state, operation)
|
2019-03-18 20:14:26 +00:00
|
|
|
|
|
|
|
|
2019-03-31 15:00:21 +00:00
|
|
|
def process_operations(state: BeaconState, block: BeaconBlock) -> None:
|
|
|
|
process_operation_type(
|
2019-03-18 20:14:26 +00:00
|
|
|
state,
|
|
|
|
block.body.proposer_slashings,
|
|
|
|
spec.MAX_PROPOSER_SLASHINGS,
|
|
|
|
spec.process_proposer_slashing,
|
|
|
|
)
|
2019-03-19 23:10:36 +00:00
|
|
|
|
2019-03-31 15:00:21 +00:00
|
|
|
process_operation_type(
|
2019-03-18 20:14:26 +00:00
|
|
|
state,
|
|
|
|
block.body.attester_slashings,
|
|
|
|
spec.MAX_ATTESTER_SLASHINGS,
|
|
|
|
spec.process_attester_slashing,
|
|
|
|
)
|
2019-03-19 23:10:36 +00:00
|
|
|
|
2019-03-31 15:00:21 +00:00
|
|
|
process_operation_type(
|
2019-03-18 20:14:26 +00:00
|
|
|
state,
|
|
|
|
block.body.attestations,
|
|
|
|
spec.MAX_ATTESTATIONS,
|
|
|
|
spec.process_attestation,
|
|
|
|
)
|
2019-03-19 23:10:36 +00:00
|
|
|
|
|
|
|
assert len(block.body.deposits) == expected_deposit_count(state)
|
2019-03-31 15:00:21 +00:00
|
|
|
process_operation_type(
|
2019-03-18 20:14:26 +00:00
|
|
|
state,
|
|
|
|
block.body.deposits,
|
|
|
|
spec.MAX_DEPOSITS,
|
|
|
|
spec.process_deposit,
|
|
|
|
)
|
2019-03-19 23:10:36 +00:00
|
|
|
|
2019-03-31 15:00:21 +00:00
|
|
|
process_operation_type(
|
2019-03-18 20:14:26 +00:00
|
|
|
state,
|
|
|
|
block.body.voluntary_exits,
|
|
|
|
spec.MAX_VOLUNTARY_EXITS,
|
|
|
|
spec.process_voluntary_exit,
|
|
|
|
)
|
2019-03-19 23:10:36 +00:00
|
|
|
|
2019-03-18 20:14:26 +00:00
|
|
|
assert len(block.body.transfers) == len(set(block.body.transfers))
|
2019-03-31 15:00:21 +00:00
|
|
|
process_operation_type(
|
2019-03-18 20:14:26 +00:00
|
|
|
state,
|
|
|
|
block.body.transfers,
|
|
|
|
spec.MAX_TRANSFERS,
|
|
|
|
spec.process_transfer,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def process_block(state: BeaconState,
|
|
|
|
block: BeaconBlock,
|
|
|
|
verify_state_root: bool=False) -> None:
|
|
|
|
spec.process_block_header(state, block)
|
|
|
|
spec.process_randao(state, block)
|
|
|
|
spec.process_eth1_data(state, block)
|
|
|
|
|
2019-03-31 15:00:21 +00:00
|
|
|
process_operations(state, block)
|
2019-03-18 20:14:26 +00:00
|
|
|
if verify_state_root:
|
|
|
|
spec.verify_block_state_root(state, block)
|
|
|
|
|
|
|
|
|
|
|
|
def process_epoch_transition(state: BeaconState) -> None:
|
|
|
|
spec.update_justification_and_finalization(state)
|
|
|
|
spec.process_crosslinks(state)
|
|
|
|
spec.maybe_reset_eth1_period(state)
|
|
|
|
spec.apply_rewards(state)
|
2019-04-06 15:09:07 +00:00
|
|
|
spec.process_balance_driven_status_transitions(state)
|
2019-03-26 16:13:17 +00:00
|
|
|
spec.update_registry(state)
|
2019-03-18 20:14:26 +00:00
|
|
|
spec.process_slashings(state)
|
|
|
|
spec.finish_epoch_update(state)
|
|
|
|
|
|
|
|
|
2019-04-07 13:36:05 +00:00
|
|
|
def state_transition_to(state: BeaconState, up_to: int) -> BeaconState:
|
|
|
|
while state.slot < up_to:
|
2019-03-18 20:14:26 +00:00
|
|
|
spec.cache_state(state)
|
|
|
|
if (state.slot + 1) % spec.SLOTS_PER_EPOCH == 0:
|
|
|
|
process_epoch_transition(state)
|
|
|
|
spec.advance_slot(state)
|
2019-04-07 13:36:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
def state_transition(state: BeaconState,
|
|
|
|
block: BeaconBlock,
|
|
|
|
verify_state_root: bool=False) -> BeaconState:
|
|
|
|
state_transition_to(state, block.slot)
|
|
|
|
process_block(state, block, verify_state_root)
|
|
|
|
|