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 sample_beacon_state_params(sample_fork_params, sample_eth1_data_params): return { 'slot': 0, 'genesis_time': 0, 'fork': Fork(**sample_fork_params), 'validator_registry': (), 'validator_balances': (), 'validator_registry_update_slot': 10, 'validator_registry_exit_count': 10, 'latest_randao_mixes': (), 'latest_vdf_outputs': (), 'persistent_committees': (), 'persistent_committee_reassignments': (), 'previous_epoch_start_shard': 1, 'current_epoch_start_shard': 2, 'previous_epoch_calculation_slot': 5, 'current_epoch_calculation_slot': 10, 'previous_epoch_seed': b'\x77' * 32, 'current_epoch_seed': b'\x88' * 32, 'custody_challenges': (), 'previous_justified_slot': 0, 'justified_slot': 0, 'justification_bitfield': 0, 'finalized_slot': 0, 'latest_crosslinks': (), 'latest_block_roots': (), 'latest_index_roots': (), 'latest_penalized_balances': (), 'latest_attestations': (), 'batched_block_roots': (), 'latest_eth1_data': Eth1Data(**sample_eth1_data_params), 'eth1_data_votes': (), }
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 sample_beacon_state_params(sample_fork_params, sample_eth1_data_params): return { 'slot': 0, 'genesis_time': 0, 'fork': Fork(**sample_fork_params), 'validator_registry': (), 'validator_balances': (), 'validator_registry_update_epoch': 0, 'latest_randao_mixes': (), 'previous_epoch_start_shard': 1, 'current_epoch_start_shard': 2, 'previous_calculation_epoch': 0, 'current_calculation_epoch': 0, 'previous_epoch_seed': b'\x77' * 32, 'current_epoch_seed': b'\x88' * 32, 'previous_justified_epoch': 0, 'justified_epoch': 0, 'justification_bitfield': 0, 'finalized_epoch': 0, 'latest_crosslinks': (), 'latest_block_roots': (), 'latest_index_roots': (), 'latest_penalized_balances': (), 'latest_attestations': (), 'batched_block_roots': (), 'latest_eth1_data': Eth1Data(**sample_eth1_data_params), 'eth1_data_votes': (), 'deposit_index': 0, }
def test_randao_processing_validates_randao_reveal(sample_beacon_block_params, sample_beacon_state_params, sample_fork_params, keymap, config): proposer_pubkey, proposer_privkey = first(keymap.items()) state = SerenityBeaconState(**sample_beacon_state_params).copy( validator_registry=tuple( mock_validator_record(proposer_pubkey) for _ in range(config.TARGET_COMMITTEE_SIZE)), validator_balances=(config.MAX_DEPOSIT_AMOUNT, ) * config.TARGET_COMMITTEE_SIZE, latest_randao_mixes=tuple( ZERO_HASH32 for _ in range(config.LATEST_RANDAO_MIXES_LENGTH)), ) epoch = state.current_epoch(config.EPOCH_LENGTH) slot = epoch * config.EPOCH_LENGTH message = (epoch + 1).to_bytes(32, byteorder="big") fork = Fork(**sample_fork_params) domain = get_domain(fork, slot, SignatureDomain.DOMAIN_RANDAO) randao_reveal = bls.sign(message, proposer_privkey, domain) block = SerenityBeaconBlock(**sample_beacon_block_params).copy( randao_reveal=randao_reveal, ) with pytest.raises(ValidationError): process_randao(state, block, config)
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.copy(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_indexed_attestation_messages( sample_indexed_attestation_params) valid_params = _correct_indexed_attestation_params( validator_count, message_hashes, sample_indexed_attestation_params, privkeys, state, config, ) valid_votes = IndexedAttestation(**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(**invalid_params) with pytest.raises(ValidationError): validate_indexed_attestation_aggregate_signature( state, invalid_votes, slots_per_epoch)
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_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.copy(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_indexed_attestation_messages( sample_indexed_attestation_params) params = _correct_indexed_attestation_params( validator_count, message_hashes, 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_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 sample_beacon_state_params( config, genesis_slot, genesis_epoch, sample_fork_params, sample_eth1_data_params, sample_block_header_params, sample_crosslink_record_params, ): return { # Versioning "genesis_time": 0, "slot": genesis_slot + 100, "fork": Fork(**sample_fork_params), # History "latest_block_header": BeaconBlockHeader(**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(**sample_eth1_data_params), "eth1_data_votes": (), "eth1_deposit_index": 0, # Registry "validators": (), "balances": (), # Shuffling "start_shard": 1, "randao_mixes": (ZERO_HASH32, ) * config.EPOCHS_PER_HISTORICAL_VECTOR, "active_index_roots": (ZERO_HASH32, ) * config.EPOCHS_PER_HISTORICAL_VECTOR, "compact_committees_roots": (ZERO_HASH32, ) * config.EPOCHS_PER_HISTORICAL_VECTOR, # Slashings "slashings": (0, ) * config.EPOCHS_PER_SLASHINGS_VECTOR, # Attestations "previous_epoch_attestations": (), "current_epoch_attestations": (), # Crosslinks "previous_crosslinks": ((Crosslink(**sample_crosslink_record_params), ) * config.SHARD_COUNT), "current_crosslinks": ((Crosslink(**sample_crosslink_record_params), ) * config.SHARD_COUNT), # Justification "justification_bits": (False, ) * JUSTIFICATION_BITS_LENGTH, "previous_justified_checkpoint": Checkpoint(epoch=0, root=b"\x99" * 32), "current_justified_checkpoint": Checkpoint(epoch=0, root=b"\x55" * 32), # Finality "finalized_checkpoint": Checkpoint(epoch=0, root=b"\x33" * 32), }
def sample_beacon_state_params(config, genesis_slot, genesis_epoch, sample_fork_params, sample_eth1_data_params, sample_block_header_params, sample_crosslink_record_params): return { # Versioning 'genesis_time': 0, 'slot': genesis_slot + 100, 'fork': Fork(**sample_fork_params), # History 'latest_block_header': BeaconBlockHeader(**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(**sample_eth1_data_params), 'eth1_data_votes': (), 'eth1_deposit_index': 0, # Registry 'validators': (), 'balances': (), # Shuffling 'start_shard': 1, 'randao_mixes': (ZERO_HASH32, ) * config.EPOCHS_PER_HISTORICAL_VECTOR, 'active_index_roots': (ZERO_HASH32, ) * config.EPOCHS_PER_HISTORICAL_VECTOR, # Slashings 'slashed_balances': (0, ) * config.EPOCHS_PER_SLASHED_BALANCES_VECTOR, # Attestations 'previous_epoch_attestations': (), 'current_epoch_attestations': (), # Crosslinks 'previous_crosslinks': ((Crosslink(**sample_crosslink_record_params), ) * config.SHARD_COUNT), 'current_crosslinks': ((Crosslink(**sample_crosslink_record_params), ) * config.SHARD_COUNT), # Justification 'previous_justified_epoch': 0, 'previous_justified_root': b'\x99' * 32, 'current_justified_epoch': 0, 'current_justified_root': b'\x55' * 32, 'justification_bitfield': 0, # Finality 'finalized_epoch': 0, 'finalized_root': b'\x33' * 32, }
def test_randao_processing(sample_beacon_block_params, sample_beacon_state_params, sample_fork_params, keymap, config): proposer_pubkey, proposer_privkey = first(keymap.items()) state = SerenityBeaconState(**sample_beacon_state_params).copy( validator_registry=tuple( mock_validator_record(proposer_pubkey) for _ in range(config.TARGET_COMMITTEE_SIZE)), validator_balances=(config.MAX_DEPOSIT_AMOUNT, ) * config.TARGET_COMMITTEE_SIZE, latest_randao_mixes=tuple( ZERO_HASH32 for _ in range(config.LATEST_RANDAO_MIXES_LENGTH)), ) epoch = state.current_epoch(config.EPOCH_LENGTH) slot = epoch * config.EPOCH_LENGTH message = epoch.to_bytes(32, byteorder="big") fork = Fork(**sample_fork_params) domain = get_domain(fork, slot, SignatureDomain.DOMAIN_RANDAO) randao_reveal = bls.sign(message, proposer_privkey, domain) block = SerenityBeaconBlock(**sample_beacon_block_params).copy( randao_reveal=randao_reveal, ) new_state = process_randao(state, block, config) updated_index = epoch % config.LATEST_RANDAO_MIXES_LENGTH original_mixes = state.latest_randao_mixes updated_mixes = new_state.latest_randao_mixes assert all( updated == original if index != updated_index else updated != original for index, (updated, original) in enumerate(zip(updated_mixes, original_mixes)))
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_randao_reveal_validation(is_valid, epoch, expected_epoch, proposer_key_index, expected_proposer_key_index, privkeys, pubkeys, sample_fork_params, config): message_hash = epoch.to_bytes(32, byteorder="little") slot = epoch * config.SLOTS_PER_EPOCH fork = Fork(**sample_fork_params) domain = get_domain(fork, slot, SignatureDomain.DOMAIN_RANDAO) proposer_privkey = privkeys[proposer_key_index] randao_reveal = bls.sign( message_hash=message_hash, privkey=proposer_privkey, domain=domain, ) expected_proposer_pubkey = pubkeys[expected_proposer_key_index] try: validate_randao_reveal( randao_reveal=randao_reveal, proposer_pubkey=expected_proposer_pubkey, epoch=expected_epoch, fork=fork, ) except ValidationError: if is_valid: raise else: if not is_valid: pytest.fail("Did not raise")
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 test_get_fork_version(previous_version, current_version, slot, current_slot, expected): fork = Fork( previous_version=previous_version, current_version=current_version, slot=slot, ) assert expected == get_fork_version( fork, current_slot, )
def test_get_domain(previous_version, current_version, slot, current_slot, domain_type, expected): fork = Fork( previous_version=previous_version, current_version=current_version, slot=slot, ) assert expected == get_domain( fork=fork, slot=current_slot, domain_type=domain_type, )
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 test_get_domain(previous_version, current_version, epoch, current_epoch, domain_type, expected): fork = Fork( previous_version=previous_version, current_version=current_version, epoch=epoch, ) assert expected == get_domain( fork=fork, epoch=current_epoch, domain_type=domain_type, )
def create_mock_initial_validator_deposits( num_validators: int, config: BeaconConfig, pubkeys: Sequence[BLSPubkey], keymap: Dict[BLSPubkey, int]) -> Tuple[Deposit, ...]: # Mock data withdrawal_credentials = b'\x22' * 32 randao_commitment = b'\x33' * 32 custody_commitment = b'\x44' * 32 deposit_timestamp = 0 fork = Fork( previous_version=config.GENESIS_FORK_VERSION, current_version=config.GENESIS_FORK_VERSION, epoch=config.GENESIS_EPOCH, ) initial_validator_deposits = tuple( Deposit( branch=( b'\x11' * 32 for j in range(10) ), index=i, deposit_data=DepositData( deposit_input=DepositInput( pubkey=pubkeys[i], withdrawal_credentials=withdrawal_credentials, randao_commitment=randao_commitment, custody_commitment=custody_commitment, proof_of_possession=sign_proof_of_possession( deposit_input=DepositInput( pubkey=pubkeys[i], withdrawal_credentials=withdrawal_credentials, randao_commitment=randao_commitment, custody_commitment=custody_commitment, ), privkey=keymap[pubkeys[i]], fork=fork, slot=config.GENESIS_SLOT, epoch_length=config.EPOCH_LENGTH, ), ), amount=config.MAX_DEPOSIT_AMOUNT, timestamp=deposit_timestamp, ), ) for i in range(num_validators) ) return initial_validator_deposits
def create_mock_genesis_validator_deposits( num_validators: int, config: BeaconConfig, pubkeys: Sequence[BLSPubkey], keymap: Dict[BLSPubkey, int]) -> Tuple[Deposit, ...]: # Mock data withdrawal_credentials = Hash32(b'\x22' * 32) deposit_timestamp = Timestamp(0) fork = Fork( previous_version=config.GENESIS_FORK_VERSION, current_version=config.GENESIS_FORK_VERSION, epoch=config.GENESIS_EPOCH, ) genesis_validator_deposits = tuple( Deposit( branch=tuple( Hash32(b'\x11' * 32) for j in range(10) ), index=i, deposit_data=DepositData( deposit_input=DepositInput( pubkey=pubkeys[i], withdrawal_credentials=withdrawal_credentials, proof_of_possession=sign_proof_of_possession( deposit_input=DepositInput( pubkey=pubkeys[i], withdrawal_credentials=withdrawal_credentials, ), privkey=keymap[pubkeys[i]], fork=fork, slot=config.GENESIS_SLOT, slots_per_epoch=config.SLOTS_PER_EPOCH, ), ), amount=config.MAX_DEPOSIT_AMOUNT, timestamp=deposit_timestamp, ), ) for i in range(num_validators) ) return genesis_validator_deposits
def sample_beacon_state_params(config, 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_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 create_mock_genesis_validator_deposits_and_root( num_validators: int, config: Eth2Config, pubkeys: Sequence[BLSPubkey], keymap: Dict[BLSPubkey, int]) -> Tuple[Tuple[Deposit, ...], Hash32]: # Mock data withdrawal_credentials = Hash32(b'\x22' * 32) 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_array = tuple() # type: Tuple[DepositData, ...] deposit_data_leaves = tuple() # type: Tuple[Hash32, ...] for i in range(num_validators): deposit_data = create_mock_deposit_data( config=config, pubkeys=pubkeys, keymap=keymap, validator_index=ValidatorIndex(i), withdrawal_credentials=withdrawal_credentials, fork=fork, ) item = hash_eth2(ssz.encode(deposit_data)) deposit_data_leaves += (item,) deposit_data_array += (deposit_data,) tree = calc_merkle_tree_from_leaves(deposit_data_leaves) root = get_merkle_root(deposit_data_leaves) genesis_validator_deposits = tuple( Deposit( proof=get_merkle_proof(tree, item_index=i), index=i, deposit_data=deposit_data_array[i], ) for i in range(num_validators) ) return genesis_validator_deposits, root
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_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 sample_beacon_state_params(genesis_slot, genesis_epoch, sample_fork_params, sample_eth1_data_params, sample_block_header_params): return { 'slot': genesis_slot + 100, 'genesis_time': 0, 'fork': Fork(**sample_fork_params), 'validator_registry': (), 'validator_balances': (), 'validator_registry_update_epoch': 0, 'latest_randao_mixes': (), 'previous_shuffling_start_shard': 1, 'current_shuffling_start_shard': 2, 'previous_shuffling_epoch': genesis_epoch, 'current_shuffling_epoch': genesis_epoch, 'previous_shuffling_seed': b'\x77' * 32, 'current_shuffling_seed': b'\x88' * 32, 'previous_epoch_attestations': (), 'current_epoch_attestations': (), 'previous_justified_epoch': 0, 'current_justified_epoch': 0, 'previous_justified_root': b'\x99' * 32, 'current_justified_root': b'\x55' * 32, 'justification_bitfield': 0, 'finalized_epoch': 0, 'finalized_root': b'\x33' * 32, 'latest_crosslinks': (), 'latest_block_roots': (), 'latest_state_roots': (), 'latest_active_index_roots': (), 'latest_slashed_balances': (), 'latest_block_header': BeaconBlockHeader(**sample_block_header_params), 'historical_roots': (), 'latest_eth1_data': Eth1Data(**sample_eth1_data_params), 'eth1_data_votes': (), 'deposit_index': 0, }
def test_get_domain(previous_version, current_version, epoch, current_epoch, domain_type, genesis_state, slots_per_epoch, expected): state = genesis_state fork = Fork( previous_version=previous_version, current_version=current_version, epoch=epoch, ) assert expected == get_domain( state=state.copy( fork=fork, ), domain_type=domain_type, slots_per_epoch=slots_per_epoch, message_epoch=current_epoch, )
def test_verify_indexed_attestation_after_fork( genesis_state, slots_per_epoch, validator_count, privkeys, sample_beacon_state_params, genesis_validators, genesis_balances, sample_indexed_attestation_params, sample_fork_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.copy( slot=20, fork=Fork(**past_fork_params), ) message_hashes = _create_indexed_attestation_messages( sample_indexed_attestation_params) valid_params = _correct_indexed_attestation_params( validator_count, message_hashes, sample_indexed_attestation_params, privkeys, state, config, ) _run_verify_indexed_vote( slots_per_epoch, valid_params, state, max_validators_per_committee, True, )