def test_get_fork_version( previous_version, current_version, epoch, current_epoch, expected ): fork = Fork.create( previous_version=previous_version, current_version=current_version, epoch=epoch ) assert expected == _get_fork_version(fork, current_epoch)
def test_verify_indexed_attestation_signature( slots_per_epoch, validator_count, genesis_state, config, privkeys, sample_attestation_params, sample_indexed_attestation_params, sample_fork_params, ): state = genesis_state.set("fork", Fork.create(**sample_fork_params)) attestation = Attestation.create(**sample_attestation_params) valid_params = _correct_indexed_attestation_params( validator_count, attestation, sample_indexed_attestation_params, privkeys, state, config, ) valid_votes = IndexedAttestation.create(**valid_params) validate_indexed_attestation_aggregate_signature(state, valid_votes, slots_per_epoch) invalid_params = _corrupt_signature(slots_per_epoch, valid_params, state.fork) invalid_votes = IndexedAttestation.create(**invalid_params) with pytest.raises(ValidationError): validate_indexed_attestation_aggregate_signature( state, invalid_votes, slots_per_epoch)
def test_verify_indexed_attestation_after_fork( genesis_state, slots_per_epoch, validator_count, privkeys, sample_attestation_params, sample_indexed_attestation_params, config, max_validators_per_committee, ): # Test that indexed data is still valid after fork # Indexed data slot = 10, fork slot = 15, current slot = 20 past_fork_params = { "previous_version": (0).to_bytes(4, "little"), "current_version": (1).to_bytes(4, "little"), "epoch": 15, } state = genesis_state.mset("slot", 20, "fork", Fork.create(**past_fork_params)) attestation = Attestation.create(**sample_attestation_params) valid_params = _correct_indexed_attestation_params( validator_count, attestation, sample_indexed_attestation_params, privkeys, state, config, ) _run_verify_indexed_vote(slots_per_epoch, valid_params, state, max_validators_per_committee, True)
def test_validate_indexed_attestation( slots_per_epoch, validator_count, genesis_state, param_mapper, should_succeed, needs_fork, is_testing_max_length, privkeys, sample_indexed_attestation_params, sample_fork_params, max_validators_per_committee, config, ): state = genesis_state.set("fork", Fork.create(**sample_fork_params)) attestation = IndexedAttestation.create( **sample_indexed_attestation_params) params = _correct_indexed_attestation_params( validator_count, attestation, sample_indexed_attestation_params, privkeys, state, config, ) if needs_fork: params = param_mapper(slots_per_epoch, params, state.fork) elif is_testing_max_length: params = param_mapper(max_validators_per_committee, params) else: params = param_mapper(params) _run_verify_indexed_vote(slots_per_epoch, params, state, max_validators_per_committee, should_succeed)
def initialize_beacon_state_from_eth1(*, eth1_block_hash: Hash32, eth1_timestamp: Timestamp, deposits: Sequence[Deposit], config: Eth2Config) -> BeaconState: fork = Fork.create( previous_version=config.GENESIS_FORK_VERSION, current_version=config.GENESIS_FORK_VERSION, epoch=GENESIS_EPOCH, ) state = BeaconState.create( genesis_time=_genesis_time_from_eth1_timestamp(eth1_timestamp, config.GENESIS_DELAY), fork=fork, eth1_data=Eth1Data.create(block_hash=eth1_block_hash, deposit_count=len(deposits)), latest_block_header=BeaconBlockHeader.create( body_root=BeaconBlockBody.create().hash_tree_root), block_roots=(ZERO_ROOT, ) * config.SLOTS_PER_HISTORICAL_ROOT, state_roots=(ZERO_HASH32, ) * config.SLOTS_PER_HISTORICAL_ROOT, randao_mixes=(eth1_block_hash, ) * config.EPOCHS_PER_HISTORICAL_VECTOR, slashings=(Gwei(0), ) * config.EPOCHS_PER_SLASHINGS_VECTOR, config=config, ) # Process genesis deposits for index, deposit in enumerate(deposits): deposit_data_list = tuple(deposit.data for deposit in deposits[:index + 1]) deposit_root = ssz.get_hash_tree_root( deposit_data_list, ssz.List(DepositData, 2**DEPOSIT_CONTRACT_TREE_DEPTH)) state = state.transform(("eth1_data", "deposit_root"), deposit_root) state = process_deposit(state=state, deposit=deposit, config=config) # Process genesis activations for validator_index in range(len(state.validators)): validator_index = ValidatorIndex(validator_index) balance = state.balances[validator_index] effective_balance = calculate_effective_balance(balance, config) state = state.transform( ("validators", validator_index, "effective_balance"), effective_balance) if effective_balance == config.MAX_EFFECTIVE_BALANCE: activated_validator = activate_validator( state.validators[validator_index], GENESIS_EPOCH) state = state.transform(("validators", validator_index), activated_validator) return state.set("genesis_validators_root", state.validators.hash_tree_root)
def sample_beacon_state_params( config, genesis_slot, genesis_epoch, sample_fork_params, sample_eth1_data_params, sample_block_header_params, ): return { # Versioning "genesis_time": 0, "slot": genesis_slot + 100, "fork": Fork.create(**sample_fork_params), # History "latest_block_header": BeaconBlockHeader.create(**sample_block_header_params), "block_roots": (ZERO_HASH32, ) * config.SLOTS_PER_HISTORICAL_ROOT, "state_roots": (ZERO_HASH32, ) * config.SLOTS_PER_HISTORICAL_ROOT, "historical_roots": (), # Eth1 "eth1_data": Eth1Data.create(**sample_eth1_data_params), "eth1_data_votes": (), "eth1_deposit_index": 0, # Registry "validators": (), "balances": (), # Shuffling "randao_mixes": (ZERO_HASH32, ) * config.EPOCHS_PER_HISTORICAL_VECTOR, # Slashings "slashings": (0, ) * config.EPOCHS_PER_SLASHINGS_VECTOR, # Attestations "previous_epoch_attestations": (), "current_epoch_attestations": (), # Justification "justification_bits": (False, ) * JUSTIFICATION_BITS_LENGTH, "previous_justified_checkpoint": Checkpoint.create(epoch=0, root=b"\x99" * 32), "current_justified_checkpoint": Checkpoint.create(epoch=0, root=b"\x55" * 32), # Finality "finalized_checkpoint": Checkpoint.create(epoch=0, root=b"\x33" * 32), }
def test_get_domain( previous_version, current_version, epoch, current_epoch, signature_domain, genesis_state, slots_per_epoch, expected, ): state = genesis_state fork = Fork.create( previous_version=previous_version, current_version=current_version, epoch=epoch ) assert expected == get_domain( state=state.set("fork", fork), signature_domain=signature_domain, slots_per_epoch=slots_per_epoch, message_epoch=current_epoch, )
def test_validate_indexed_attestation( slots_per_epoch, validator_count, genesis_state, param_mapper, should_succeed, needs_fork, is_testing_max_length, privkeys, sample_beacon_state_params, genesis_validators, genesis_balances, sample_indexed_attestation_params, sample_fork_params, max_validators_per_committee, config, ): state = genesis_state.set("fork", Fork.create(**sample_fork_params)) # NOTE: we can do this before "correcting" the params as they # touch disjoint subsets of the provided params message_hash = _create_indexed_attestation_messages( sample_indexed_attestation_params) params = _correct_indexed_attestation_params( validator_count, message_hash, sample_indexed_attestation_params, privkeys, state, config, ) if needs_fork: params = param_mapper(slots_per_epoch, params, state.fork) elif is_testing_max_length: params = param_mapper(max_validators_per_committee, params) else: params = param_mapper(params) _run_verify_indexed_vote(slots_per_epoch, params, state, max_validators_per_committee, should_succeed)
def test_verify_indexed_attestation_signature( slots_per_epoch, validator_count, genesis_state, config, privkeys, sample_beacon_state_params, genesis_validators, genesis_balances, sample_indexed_attestation_params, sample_fork_params, ): state = genesis_state.set("fork", Fork.create(**sample_fork_params)) # NOTE: we can do this before "correcting" the params as they # touch disjoint subsets of the provided params message_hash = _create_indexed_attestation_messages( sample_indexed_attestation_params) valid_params = _correct_indexed_attestation_params( validator_count, message_hash, sample_indexed_attestation_params, privkeys, state, config, ) valid_votes = IndexedAttestation.create(**valid_params) validate_indexed_attestation_aggregate_signature(state, valid_votes, slots_per_epoch) invalid_params = _corrupt_signature(slots_per_epoch, valid_params, state.fork) invalid_votes = IndexedAttestation.create(**invalid_params) with pytest.raises(ValidationError): validate_indexed_attestation_aggregate_signature( state, invalid_votes, slots_per_epoch)
def test_get_genesis_beacon_state( validator_count, pubkeys, genesis_epoch, genesis_slot, max_committees_per_slot, slots_per_historical_root, epochs_per_slashings_vector, epochs_per_historical_vector, config, keymap, ): genesis_deposits, deposit_root = create_mock_deposits_and_root( pubkeys=pubkeys[:validator_count], keymap=keymap, config=config) genesis_eth1_data = Eth1Data.create( deposit_count=len(genesis_deposits), deposit_root=deposit_root, block_hash=ZERO_HASH32, ) eth1_timestamp = 10 eth1_block_hash = genesis_eth1_data.block_hash state = initialize_beacon_state_from_eth1( eth1_block_hash=eth1_block_hash, eth1_timestamp=eth1_timestamp, deposits=genesis_deposits, config=config, ) # Versioning assert state.slot == genesis_slot assert state.genesis_time == _genesis_time_from_eth1_timestamp( eth1_timestamp) assert state.fork == Fork.create() # History assert state.latest_block_header == BeaconBlockHeader.create( body_root=BeaconBlockBody.create().hash_tree_root) assert len(state.block_roots) == slots_per_historical_root assert tuple( state.block_roots) == (ZERO_HASH32, ) * slots_per_historical_root assert len(state.state_roots) == slots_per_historical_root assert tuple( state.block_roots) == (ZERO_HASH32, ) * slots_per_historical_root assert len(state.historical_roots) == 0 # Ethereum 1.0 chain data assert state.eth1_data == genesis_eth1_data assert len(state.eth1_data_votes) == 0 assert state.eth1_deposit_index == len(genesis_deposits) # Validator registry assert len(state.validators) == validator_count assert len(state.balances) == validator_count # Shuffling assert len(state.randao_mixes) == epochs_per_historical_vector assert (tuple(state.randao_mixes) == (eth1_block_hash, ) * epochs_per_historical_vector) # Slashings assert len(state.slashings) == epochs_per_slashings_vector assert tuple(state.slashings) == (Gwei(0), ) * epochs_per_slashings_vector # Attestations assert len(state.previous_epoch_attestations) == 0 assert len(state.current_epoch_attestations) == 0 # Justification assert state.previous_justified_checkpoint.epoch == genesis_epoch assert state.previous_justified_checkpoint.root == ZERO_HASH32 assert state.current_justified_checkpoint.epoch == genesis_epoch assert state.current_justified_checkpoint.root == ZERO_HASH32 assert state.justification_bits == (False, ) * JUSTIFICATION_BITS_LENGTH # Finalization assert state.finalized_checkpoint.epoch == genesis_epoch assert state.finalized_checkpoint.root == ZERO_HASH32 for i in range(len(genesis_deposits)): assert state.validators[i].is_active(genesis_epoch)
def test_defaults(sample_fork_params): fork = Fork.create(**sample_fork_params) assert fork.previous_version == sample_fork_params["previous_version"] assert fork.current_version == sample_fork_params["current_version"] assert fork.epoch == sample_fork_params["epoch"] assert ssz.encode(fork)