def test_verify_slashable_vote_data(num_validators, param_mapper, should_succeed, needs_fork_data, privkeys, sample_beacon_state_params, activated_genesis_validators, genesis_balances, sample_slashable_vote_data_params, sample_fork_data_params, max_casper_votes): state = BeaconState(**sample_beacon_state_params).copy( validator_registry=activated_genesis_validators, validator_balances=genesis_balances, fork_data=ForkData(**sample_fork_data_params), ) # NOTE: we can do this before "correcting" the params as they # touch disjoint subsets of the provided params messages = _create_slashable_vote_data_messages(sample_slashable_vote_data_params) params = _correct_slashable_vote_data_params( num_validators, sample_slashable_vote_data_params, messages, privkeys, state.fork_data, ) if needs_fork_data: params = param_mapper(params, state.fork_data) else: params = param_mapper(params) _run_verify_slashable_vote(params, state, max_casper_votes, should_succeed)
def test_process_eth1_data(original_votes, block_data, expected_votes, sample_beacon_state_params, sample_beacon_block_params, sample_beacon_block_body_params): eth1_data_votes = tuple( Eth1DataVote(data, vote_count) for data, vote_count in original_votes ) state = BeaconState(**sample_beacon_state_params).copy( eth1_data_votes=eth1_data_votes, ) block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy( eth1_data=block_data, ) block = BeaconBlock(**sample_beacon_block_params).copy( body=block_body, ) updated_state = process_eth1_data(state, block) updated_votes = tuple( (vote.eth1_data, vote.vote_count) for vote in updated_state.eth1_data_votes ) assert updated_votes == expected_votes
def test_verify_slashable_vote_data_signature(num_validators, privkeys, sample_beacon_state_params, activated_genesis_validators, genesis_balances, sample_slashable_vote_data_params, sample_fork_data_params): state = BeaconState(**sample_beacon_state_params).copy( validator_registry=activated_genesis_validators, validator_balances=genesis_balances, fork_data=ForkData(**sample_fork_data_params), ) # NOTE: we can do this before "correcting" the params as they # touch disjoint subsets of the provided params messages = _create_slashable_vote_data_messages(sample_slashable_vote_data_params) valid_params = _correct_slashable_vote_data_params( num_validators, sample_slashable_vote_data_params, messages, privkeys, state.fork_data, ) valid_votes = SlashableVoteData(**valid_params) assert verify_slashable_vote_data_signature(state, valid_votes) invalid_params = _corrupt_signature(valid_params, state.fork_data) invalid_votes = SlashableVoteData(**invalid_params) assert not verify_slashable_vote_data_signature(state, invalid_votes)
def genesis_state(sample_beacon_state_params, activated_genesis_validators, genesis_balances, epoch_length, target_committee_size, genesis_slot, shard_count, latest_block_roots_length): initial_shuffling = get_shuffling( seed=ZERO_HASH32, validators=activated_genesis_validators, crosslinking_start_shard=0, slot=genesis_slot, epoch_length=epoch_length, target_committee_size=target_committee_size, shard_count=shard_count ) return BeaconState(**sample_beacon_state_params).copy( validator_registry=activated_genesis_validators, validator_balances=genesis_balances, shard_committees_at_slots=initial_shuffling + initial_shuffling, latest_block_roots=tuple(ZERO_HASH32 for _ in range(latest_block_roots_length)), latest_crosslinks=tuple( CrosslinkRecord( slot=genesis_slot, shard_block_root=ZERO_HASH32, ) for _ in range(shard_count) ) )
def empty_beacon_state(latest_block_roots_length, latest_penalized_exit_length): return BeaconState( slot=0, genesis_time=0, fork_data=ForkData( pre_fork_version=0, post_fork_version=0, fork_slot=0, ), validator_registry=(), validator_balances=(), validator_registry_latest_change_slot=10, validator_registry_exit_count=10, validator_registry_delta_chain_tip=b'\x55' * 32, latest_randao_mixes=(), latest_vdf_outputs=(), shard_committees_at_slots=(), persistent_committees=(), persistent_committee_reassignments=(), previous_justified_slot=0, justified_slot=0, justification_bitfield=0, finalized_slot=0, latest_crosslinks=(), latest_block_roots=(ZERO_HASH32,) * latest_block_roots_length, latest_penalized_exit_balances=(0,) * latest_penalized_exit_length, latest_attestations=(), batched_block_roots=(), processed_pow_receipt_root=b'\x55' * 32, candidate_pow_receipt_roots=(), )
def test_process_eth1_data(original_votes, block_data, expected_votes, sample_beacon_state_params, sample_beacon_block_params, sample_beacon_block_body_params, config): eth1_data_votes = tuple(mapcat( _expand_eth1_votes, original_votes, )) state = BeaconState(**sample_beacon_state_params).copy( eth1_data_votes=eth1_data_votes, ) block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy( eth1_data=Eth1Data( block_hash=block_data, ), ) block = BeaconBlock(**sample_beacon_block_params).copy( body=block_body, ) updated_state = process_eth1_data(state, block, config) updated_votes = updated_state.eth1_data_votes expanded_expected_votes = tuple(mapcat( _expand_eth1_votes, expected_votes, )) assert updated_votes == expanded_expected_votes
def test_defaults(sample_beacon_state_params): state = BeaconState(**sample_beacon_state_params) assert state.validator_registry == sample_beacon_state_params[ 'validator_registry'] assert state.validator_registry_update_slot == sample_beacon_state_params[ 'validator_registry_update_slot'] # noqa: E501 assert rlp.encode(state)
def test_validator_registry_and_balances_length(sample_beacon_state_params, config): # When len(BeaconState.validator_registry) != len(BeaconState.validtor_balances) with pytest.raises(ValueError): BeaconState(**sample_beacon_state_params).copy( validator_registry=tuple( mock_validator(pubkey, config) for pubkey in range(10)), )
def test_verify_slashable_attestation_signature( slots_per_epoch, num_validators, privkeys, sample_beacon_state_params, activated_genesis_validators, genesis_balances, sample_slashable_attestation_params, sample_fork_params): state = BeaconState(**sample_beacon_state_params).copy( validator_registry=activated_genesis_validators, validator_balances=genesis_balances, fork=Fork(**sample_fork_params), ) # NOTE: we can do this before "correcting" the params as they # touch disjoint subsets of the provided params message_hashes = _create_slashable_attestation_messages( sample_slashable_attestation_params) valid_params = _correct_slashable_attestation_params( slots_per_epoch, num_validators, sample_slashable_attestation_params, message_hashes, privkeys, state.fork, ) valid_votes = SlashableAttestation(**valid_params) assert verify_slashable_attestation_signature(state, valid_votes, slots_per_epoch) invalid_params = _corrupt_signature(slots_per_epoch, valid_params, state.fork) invalid_votes = SlashableAttestation(**invalid_params) assert not verify_slashable_attestation_signature(state, invalid_votes, slots_per_epoch)
def test_get_block_root_at_slot(sample_beacon_state_params, current_slot, target_slot, success, slots_per_epoch, slots_per_historical_root, sample_block): blocks, block_roots = generate_mock_latest_historical_roots( sample_block, current_slot, slots_per_epoch, slots_per_historical_root, ) state = BeaconState(**sample_beacon_state_params).copy( slot=current_slot, block_roots=block_roots, ) if success: block_root = get_block_root_at_slot( state, target_slot, slots_per_historical_root, ) assert block_root == blocks[target_slot].signing_root else: with pytest.raises(ValidationError): get_block_root_at_slot( state, target_slot, slots_per_historical_root, )
def test_verify_slashable_attestation( epoch_length, num_validators, param_mapper, should_succeed, needs_fork, privkeys, sample_beacon_state_params, activated_genesis_validators, genesis_balances, sample_slashable_attestation_params, sample_fork_params, max_indices_per_slashable_vote): state = BeaconState(**sample_beacon_state_params).copy( validator_registry=activated_genesis_validators, validator_balances=genesis_balances, fork=Fork(**sample_fork_params), ) # NOTE: we can do this before "correcting" the params as they # touch disjoint subsets of the provided params messages = _create_slashable_attestation_messages( sample_slashable_attestation_params) params = _correct_slashable_attestation_params( epoch_length, num_validators, sample_slashable_attestation_params, messages, privkeys, state.fork, ) if needs_fork: params = param_mapper(epoch_length, params, state.fork) else: params = param_mapper(params) _run_verify_slashable_vote( epoch_length, params, state, max_indices_per_slashable_vote, should_succeed, )
def test_verify_slashable_vote_data_after_fork( num_validators, privkeys, sample_beacon_state_params, activated_genesis_validators, genesis_balances, sample_slashable_vote_data_params, sample_fork_params, max_casper_votes): # Test that slashable data is still valid after fork # Slashable data slot = 10, fork slot = 15, current slot = 20 past_fork_params = { 'previous_version': 0, 'current_version': 1, 'slot': 15, } state = BeaconState(**sample_beacon_state_params).copy( validator_registry=activated_genesis_validators, validator_balances=genesis_balances, fork=Fork(**past_fork_params), slot=20, ) messages = _create_slashable_vote_data_messages( sample_slashable_vote_data_params) valid_params = _correct_slashable_vote_data_params( num_validators, sample_slashable_vote_data_params, messages, privkeys, state.fork, ) _run_verify_slashable_vote(valid_params, state, max_casper_votes, True)
def test_validate_block_slot(sample_beacon_state_params, sample_beacon_block_params, state_slot, block_slot, expected): state = BeaconState(**sample_beacon_state_params).copy(slot=state_slot, ) block = BeaconBlock(**sample_beacon_block_params).copy(slot=block_slot, ) if isinstance(expected, Exception): with pytest.raises(ValidationError): validate_block_slot(state, block) else: validate_block_slot(state, block)
def test_justification_without_mock(sample_beacon_state_params, latest_block_roots_length, config): state = BeaconState(**sample_beacon_state_params).copy( latest_block_roots=tuple(ZERO_HASH32 for _ in range(latest_block_roots_length)), justification_bitfield=0b0, ) state = process_justification(state, config) assert state.justification_bitfield == 0b11
def is_genesis_trigger(deposits: Sequence[Deposit], timestamp: int, config: Eth2Config) -> bool: state = BeaconState(config=config) for deposit in deposits: state = process_deposit(state, deposit, config) active_validator_count = 0 for validator in state.validators: if validator.effective_balance == config.MAX_EFFECTIVE_BALANCE: active_validator_count += 1 return active_validator_count == config.GENESIS_ACTIVE_VALIDATOR_COUNT
def test_process_justification(monkeypatch, config, sample_beacon_state_params, states, genesis_epoch=0): from eth2.beacon.state_machines.forks.serenity import epoch_processing for i in range(len(states) - 1): ( current_epoch, current_epoch_justifiable, previous_epoch_justifiable, previous_justified_epoch_before, justified_epoch_before, justification_bitfield_before, finalized_epoch_before, ) = states[i] ( previous_justified_epoch_after, justified_epoch_after, justification_bitfield_after, finalized_epoch_after, ) = states[i + 1][-4:] slot = (current_epoch + 1) * config.SLOTS_PER_EPOCH - 1 def mock_current_previous_epochs_justifiable(current_epoch, previous_epoch, state, config): return current_epoch_justifiable, previous_epoch_justifiable with monkeypatch.context() as m: m.setattr( epoch_processing, '_current_previous_epochs_justifiable', mock_current_previous_epochs_justifiable, ) state = BeaconState(**sample_beacon_state_params).copy( slot=slot, previous_justified_epoch=previous_justified_epoch_before, justified_epoch=justified_epoch_before, justification_bitfield=justification_bitfield_before, finalized_epoch=finalized_epoch_before, ) state = process_justification(state, config) assert state.previous_justified_epoch == previous_justified_epoch_after assert state.justified_epoch == justified_epoch_after assert state.justification_bitfield == justification_bitfield_after assert state.finalized_epoch == finalized_epoch_after
def test_validate_serenity_proposer_signature( proposer_privkey, proposer_pubkey, is_valid_signature, sample_beacon_block_params, sample_beacon_state_params, sample_shard_committee_params, beacon_chain_shard_number, epoch_length, max_deposit): state = BeaconState(**sample_beacon_state_params).copy( validator_registry=tuple( mock_validator_record(proposer_pubkey) for _ in range(10)), validator_balances=(max_deposit * GWEI_PER_ETH, ) * 10, shard_committees_at_slots=get_sample_shard_committees_at_slots( num_slot=128, num_shard_committee_per_slot=10, sample_shard_committee_params=sample_shard_committee_params, ), ) default_block = BeaconBlock(**sample_beacon_block_params) empty_signature_block_root = default_block.block_without_signature_root proposal_root = ProposalSignedData( state.slot, beacon_chain_shard_number, empty_signature_block_root, ).root proposed_block = BeaconBlock(**sample_beacon_block_params).copy( signature=bls.sign( message=proposal_root, privkey=proposer_privkey, domain=SignatureDomain.DOMAIN_PROPOSAL, ), ) if is_valid_signature: validate_serenity_proposer_signature( state, proposed_block, beacon_chain_shard_number, epoch_length, ) else: with pytest.raises(ValidationError): validate_serenity_proposer_signature( state, proposed_block, beacon_chain_shard_number, epoch_length, )
def test_validate_proposer_signature( slots_per_epoch, shard_count, proposer_privkey, proposer_pubkey, is_valid_signature, sample_beacon_block_params, sample_beacon_state_params, target_committee_size, max_effective_balance, config): state = BeaconState(**sample_beacon_state_params).copy( validators=tuple( create_mock_validator(proposer_pubkey, config) for _ in range(10) ), balances=(max_effective_balance,) * 10, ) block = BeaconBlock(**sample_beacon_block_params) header = block.header proposed_block = block.copy( signature=bls.sign( message_hash=header.signing_root, privkey=proposer_privkey, domain=get_domain( state, SignatureDomain.DOMAIN_BEACON_PROPOSER, slots_per_epoch, ), ), ) if is_valid_signature: validate_proposer_signature( state, proposed_block, CommitteeConfig(config), ) else: with pytest.raises(ValidationError): validate_proposer_signature( state, proposed_block, CommitteeConfig(config), )
def test_validate_proof_of_possession(epoch_length, sample_beacon_state_params, pubkeys, privkeys, expected): state = BeaconState(**sample_beacon_state_params) privkey = privkeys[0] pubkey = pubkeys[0] withdrawal_credentials = b'\x34' * 32 custody_commitment = b'\x12' * 32 randao_commitment = b'\x56' * 32 deposit_input = DepositInput( pubkey=pubkey, withdrawal_credentials=withdrawal_credentials, randao_commitment=randao_commitment, custody_commitment=custody_commitment, ) if expected is True: proof_of_possession = sign_proof_of_possession( deposit_input, privkey, state.fork, state.slot, epoch_length, ) validate_proof_of_possession( state=state, pubkey=pubkey, proof_of_possession=proof_of_possession, withdrawal_credentials=withdrawal_credentials, randao_commitment=randao_commitment, custody_commitment=custody_commitment, epoch_length=epoch_length, ) else: proof_of_possession = b'\x11' * 96 with pytest.raises(ValidationError): validate_proof_of_possession( state=state, pubkey=pubkey, proof_of_possession=proof_of_possession, withdrawal_credentials=withdrawal_credentials, randao_commitment=randao_commitment, custody_commitment=custody_commitment, epoch_length=epoch_length, )
def test_validate_proposer_signature( slots_per_epoch, shard_count, proposer_privkey, proposer_pubkey, is_valid_signature, sample_beacon_block_params, sample_beacon_state_params, beacon_chain_shard_number, genesis_epoch, target_committee_size, max_deposit_amount, config): state = BeaconState(**sample_beacon_state_params).copy( validator_registry=tuple( mock_validator_record(proposer_pubkey, config) for _ in range(10)), validator_balances=(max_deposit_amount, ) * 10, ) default_block = BeaconBlock(**sample_beacon_block_params) empty_signature_block_root = default_block.block_without_signature_root proposal_signed_root = Proposal( state.slot, beacon_chain_shard_number, empty_signature_block_root, ).signed_root proposed_block = BeaconBlock(**sample_beacon_block_params).copy( signature=bls.sign( message_hash=proposal_signed_root, privkey=proposer_privkey, domain=SignatureDomain.DOMAIN_PROPOSAL, ), ) if is_valid_signature: validate_proposer_signature( state, proposed_block, beacon_chain_shard_number, CommitteeConfig(config), ) else: with pytest.raises(ValidationError): validate_proposer_signature( state, proposed_block, beacon_chain_shard_number, CommitteeConfig(config), )
def test_validate_proof_of_possession( slots_per_epoch, sample_beacon_state_params, pubkeys, privkeys, expected): state = BeaconState(**sample_beacon_state_params) privkey = privkeys[0] pubkey = pubkeys[0] withdrawal_credentials = b'\x34' * 32 deposit_input = DepositInput( pubkey=pubkey, withdrawal_credentials=withdrawal_credentials, ) if expected is True: proof_of_possession = sign_proof_of_possession( deposit_input, privkey, state.fork, state.slot, slots_per_epoch, ) validate_proof_of_possession( state=state, pubkey=pubkey, proof_of_possession=proof_of_possession, withdrawal_credentials=withdrawal_credentials, slots_per_epoch=slots_per_epoch, ) else: proof_of_possession = b'\x11' * 96 with pytest.raises(ValidationError): validate_proof_of_possession( state=state, pubkey=pubkey, proof_of_possession=proof_of_possession, withdrawal_credentials=withdrawal_credentials, slots_per_epoch=slots_per_epoch, )
def test_validate_proposer_signature( slots_per_epoch, shard_count, proposer_privkey, proposer_pubkey, is_valid_signature, sample_beacon_block_params, sample_beacon_state_params, target_committee_size, max_deposit_amount, config): state = BeaconState(**sample_beacon_state_params).copy( validator_registry=tuple( mock_validator(proposer_pubkey, config) for _ in range(10)), validator_balances=(max_deposit_amount, ) * 10, ) block = BeaconBlock(**sample_beacon_block_params) header = block.header proposed_block = block.copy(signature=bls.sign( message_hash=header.signing_root, privkey=proposer_privkey, domain=get_domain( Fork( config.GENESIS_FORK_VERSION.to_bytes(4, 'little'), config.GENESIS_FORK_VERSION.to_bytes(4, 'little'), config.GENESIS_EPOCH, ), slot_to_epoch(state.slot, slots_per_epoch), SignatureDomain.DOMAIN_BEACON_BLOCK, ), ), ) if is_valid_signature: validate_proposer_signature( state, proposed_block, CommitteeConfig(config), ) else: with pytest.raises(ValidationError): validate_proposer_signature( state, proposed_block, CommitteeConfig(config), )
def test_verify_slashable_attestation_after_fork( slots_per_epoch, num_validators, privkeys, sample_beacon_state_params, activated_genesis_validators, genesis_balances, sample_slashable_attestation_params, sample_fork_params, max_indices_per_slashable_vote): # Test that slashable data is still valid after fork # Slashable 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 = BeaconState(**sample_beacon_state_params).copy( validator_registry=activated_genesis_validators, validator_balances=genesis_balances, fork=Fork(**past_fork_params), slot=20, ) message_hashes = _create_slashable_attestation_messages(sample_slashable_attestation_params) valid_params = _correct_slashable_attestation_params( slots_per_epoch, num_validators, sample_slashable_attestation_params, message_hashes, privkeys, state.fork, ) _run_verify_slashable_vote( slots_per_epoch, valid_params, state, max_indices_per_slashable_vote, True, )
def test_add_pending_validator(sample_beacon_state_params, sample_validator_record_params): validator_registry_len = 2 state = BeaconState(**sample_beacon_state_params).copy( validator_registry=[ ValidatorRecord(**sample_validator_record_params) for _ in range(validator_registry_len) ], validator_balances=(100, ) * validator_registry_len, ) validator = ValidatorRecord(**sample_validator_record_params) amount = 5566 state = add_pending_validator( state, validator, amount, ) assert state.validator_registry[-1] == validator
def initialize_beacon_state_from_eth1(*, eth1_block_hash: Hash32, eth1_timestamp: Timestamp, deposits: Sequence[Deposit], config: Eth2Config) -> BeaconState: state = BeaconState( genesis_time=_genesis_time_from_eth1_timestamp(eth1_timestamp), eth1_data=Eth1Data(block_hash=eth1_block_hash, deposit_count=len(deposits)), latest_block_header=BeaconBlockHeader( body_root=BeaconBlockBody().hash_tree_root), randao_mixes=(eth1_block_hash, ) * config.EPOCHS_PER_HISTORICAL_VECTOR, config=config, ) # Process genesis deposits for index, deposit in enumerate(deposits): deposit_data_list = tuple(deposit.data for deposit in deposits[:index + 1]) state = state.copy(eth1_data=state.eth1_data.copy( deposit_root=ssz.get_hash_tree_root( deposit_data_list, ssz.List(DepositData, 2**DEPOSIT_CONTRACT_TREE_DEPTH), ))) 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.update_validator_with_fn( validator_index, lambda v, *_: v.copy(effective_balance=effective_balance)) if effective_balance == config.MAX_EFFECTIVE_BALANCE: state = state.update_validator_with_fn(validator_index, activate_validator, config.GENESIS_EPOCH) return state
def get_genesis_beacon_state(*, genesis_deposits: Sequence[Deposit], genesis_time: Timestamp, genesis_eth1_data: Eth1Data, config: Eth2Config) -> BeaconState: state = BeaconState( genesis_time=genesis_time, eth1_data=genesis_eth1_data, latest_block_header=BeaconBlockHeader( body_root=BeaconBlockBody().root, ), config=config, ) # Process genesis deposits for deposit in genesis_deposits: 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) effective_balance = state.validators[validator_index].effective_balance is_enough_effective_balance = effective_balance >= config.MAX_EFFECTIVE_BALANCE if is_enough_effective_balance: state = state.update_validator_with_fn( validator_index, activate_validator, config.GENESIS_EPOCH, ) return genesis_state_with_active_index_roots( state, config, )
def create_mock_deposit(config, sample_beacon_state_params, keymap, pubkeys, withdrawal_credentials, validator_index): state = BeaconState(**sample_beacon_state_params).copy( slot=1, validator_registry=(), ) fork = Fork( previous_version=config.GENESIS_FORK_VERSION.to_bytes(4, 'little'), current_version=config.GENESIS_FORK_VERSION.to_bytes(4, 'little'), epoch=config.GENESIS_EPOCH, ) deposit_data = create_mock_deposit_data( config=config, pubkeys=pubkeys, keymap=keymap, validator_index=validator_index, withdrawal_credentials=withdrawal_credentials, fork=fork, ) item = hash_eth2(ssz.encode(deposit_data)) test_deposit_data_leaves = (item, ) tree = calc_merkle_tree_from_leaves(test_deposit_data_leaves) root = get_merkle_root(test_deposit_data_leaves) proof = list(get_merkle_proof(tree, item_index=validator_index)) state = state.copy(latest_eth1_data=state.latest_eth1_data.copy( deposit_root=root, ), ) deposit = Deposit( proof=proof, index=validator_index, deposit_data=deposit_data, ) return state, deposit
def test_process_deposit(epoch_length, sample_beacon_state_params, privkeys, pubkeys, max_deposit_amount): state = BeaconState(**sample_beacon_state_params).copy( slot=1, validator_registry=(), ) privkey_1 = privkeys[0] pubkey_1 = pubkeys[0] amount = max_deposit_amount withdrawal_credentials = b'\x34' * 32 custody_commitment = b'\x11' * 32 randao_commitment = b'\x56' * 32 deposit_input = DepositInput( pubkey=pubkey_1, withdrawal_credentials=withdrawal_credentials, randao_commitment=randao_commitment, custody_commitment=custody_commitment, ) proof_of_possession = sign_proof_of_possession( deposit_input, privkey_1, state.fork, state.slot, epoch_length, ) # Add the first validator result_state = process_deposit( state=state, pubkey=pubkey_1, amount=amount, proof_of_possession=proof_of_possession, withdrawal_credentials=withdrawal_credentials, randao_commitment=randao_commitment, custody_commitment=custody_commitment, epoch_length=epoch_length, ) assert len(result_state.validator_registry) == 1 index = 0 assert result_state.validator_registry[0].pubkey == pubkey_1 assert result_state.validator_registry[ index].withdrawal_credentials == withdrawal_credentials assert result_state.validator_registry[ index].randao_commitment == randao_commitment assert result_state.validator_balances[index] == amount # test immutable assert len(state.validator_registry) == 0 # Add the second validator privkey_2 = privkeys[1] pubkey_2 = pubkeys[1] deposit_input = DepositInput( pubkey=pubkey_2, withdrawal_credentials=withdrawal_credentials, randao_commitment=randao_commitment, custody_commitment=custody_commitment, ) proof_of_possession = sign_proof_of_possession( deposit_input, privkey_2, state.fork, state.slot, epoch_length, ) result_state = process_deposit( state=result_state, pubkey=pubkey_2, amount=amount, proof_of_possession=proof_of_possession, withdrawal_credentials=withdrawal_credentials, randao_commitment=randao_commitment, custody_commitment=custody_commitment, epoch_length=epoch_length, ) assert len(result_state.validator_registry) == 2 assert result_state.validator_registry[1].pubkey == pubkey_2
def state(sample_beacon_state_params): return BeaconState(**sample_beacon_state_params)
def get_genesis_beacon_state(*, genesis_validator_deposits: Sequence[Deposit], genesis_time: Timestamp, latest_eth1_data: Eth1Data, genesis_slot: SlotNumber, genesis_epoch: EpochNumber, genesis_fork_version: int, genesis_start_shard: ShardNumber, shard_count: int, seed_lookahead: int, latest_block_roots_length: int, latest_index_roots_length: int, epoch_length: int, max_deposit_amount: Gwei, latest_penalized_exit_length: int, latest_randao_mixes_length: int, entry_exit_delay: int) -> BeaconState: state = BeaconState( # Misc slot=genesis_slot, genesis_time=genesis_time, fork=Fork( previous_version=genesis_fork_version, current_version=genesis_fork_version, epoch=genesis_epoch, ), # Validator registry validator_registry=(), validator_balances=(), validator_registry_update_epoch=genesis_epoch, # Randomness and committees latest_randao_mixes=(ZERO_HASH32,) * latest_randao_mixes_length, previous_epoch_start_shard=genesis_start_shard, current_epoch_start_shard=genesis_start_shard, previous_calculation_epoch=genesis_epoch, current_calculation_epoch=genesis_epoch, previous_epoch_seed=ZERO_HASH32, current_epoch_seed=ZERO_HASH32, # Finality previous_justified_epoch=genesis_epoch, justified_epoch=genesis_epoch, justification_bitfield=0, finalized_epoch=genesis_epoch, # Recent state latest_crosslinks=( (CrosslinkRecord(epoch=genesis_epoch, shard_block_root=ZERO_HASH32),) * shard_count ), latest_block_roots=(ZERO_HASH32,) * latest_block_roots_length, latest_index_roots=(ZERO_HASH32,) * latest_index_roots_length, latest_penalized_balances=(Gwei(0),) * latest_penalized_exit_length, latest_attestations=(), batched_block_roots=(), # Ethereum 1.0 chain data latest_eth1_data=latest_eth1_data, eth1_data_votes=(), deposit_index=len(genesis_validator_deposits), ) # Process initial deposits for deposit in genesis_validator_deposits: state = process_deposit( state=state, pubkey=deposit.deposit_data.deposit_input.pubkey, amount=deposit.deposit_data.amount, proof_of_possession=deposit.deposit_data.deposit_input.proof_of_possession, withdrawal_credentials=deposit.deposit_data.deposit_input.withdrawal_credentials, epoch_length=epoch_length, ) # Process initial activations for validator_index, _ in enumerate(state.validator_registry): validator_index = ValidatorIndex(validator_index) is_enough_effective_balance = get_effective_balance( state.validator_balances, validator_index, max_deposit_amount, ) >= max_deposit_amount if is_enough_effective_balance: state = activate_validator( state=state, index=validator_index, is_genesis=True, genesis_epoch=genesis_epoch, epoch_length=epoch_length, entry_exit_delay=entry_exit_delay, ) # TODO: chanege to hash_tree_root active_validator_indices = get_active_validator_indices( state.validator_registry, genesis_epoch, ) genesis_active_index_root = hash_eth2( b''.join( [ index.to_bytes(32, 'big') for index in active_validator_indices ] ) ) latest_index_roots = (genesis_active_index_root,) * latest_index_roots_length state = state.copy( latest_index_roots=latest_index_roots, ) current_epoch_seed = generate_seed( state=state, epoch=genesis_epoch, epoch_length=epoch_length, seed_lookahead=seed_lookahead, entry_exit_delay=entry_exit_delay, latest_index_roots_length=latest_index_roots_length, latest_randao_mixes_length=latest_randao_mixes_length, ) state = state.copy( current_epoch_seed=current_epoch_seed, ) return state