コード例 #1
0
def test_activate_validator(is_genesis, filled_beacon_state, genesis_epoch,
                            epoch_length, entry_exit_delay,
                            max_deposit_amount):
    validator_count = 10
    state = filled_beacon_state.copy(
        validator_registry=tuple(
            mock_validator_record(
                pubkey=index.to_bytes(48, 'big'),
                is_active=False,
            ) for index in range(validator_count)),
        validator_balances=(max_deposit_amount, ) * validator_count,
    )
    index = 1
    # Check that the `index`th validator in `state` is inactivated
    assert state.validator_registry[index].activation_epoch == FAR_FUTURE_EPOCH

    result_state = activate_validator(
        state=state,
        index=index,
        is_genesis=is_genesis,
        genesis_epoch=genesis_epoch,
        epoch_length=epoch_length,
        entry_exit_delay=entry_exit_delay,
    )

    if is_genesis:
        assert result_state.validator_registry[
            index].activation_epoch == genesis_epoch
    else:
        assert (result_state.validator_registry[index].activation_epoch ==
                get_entry_exit_effect_epoch(
                    state.current_epoch(epoch_length),
                    entry_exit_delay,
                ))
コード例 #2
0
def test_activate_validator(is_genesis, filled_beacon_state, genesis_epoch,
                            slots_per_epoch, activation_exit_delay,
                            max_deposit_amount, config):
    validator_count = 10
    state = filled_beacon_state.copy(
        validator_registry=tuple(
            mock_validator(
                pubkey=index.to_bytes(48, 'little'),
                config=config,
                is_active=False,
            ) for index in range(validator_count)),
        validator_balances=(max_deposit_amount, ) * validator_count,
    )
    index = 1
    # Check that the `index`th validator in `state` is inactivated
    assert state.validator_registry[index].activation_epoch == FAR_FUTURE_EPOCH

    result_state = activate_validator(
        state=state,
        index=index,
        is_genesis=is_genesis,
        genesis_epoch=genesis_epoch,
        slots_per_epoch=slots_per_epoch,
        activation_exit_delay=activation_exit_delay,
    )

    if is_genesis:
        assert result_state.validator_registry[
            index].activation_epoch == genesis_epoch
    else:
        assert (result_state.validator_registry[index].activation_epoch ==
                get_delayed_activation_exit_epoch(
                    state.current_epoch(slots_per_epoch),
                    activation_exit_delay,
                ))
コード例 #3
0
ファイル: initializer.py プロジェクト: wschwab/trinity
def create_mock_validator(
    pubkey: BLSPubkey,
    config: Eth2Config,
    withdrawal_credentials: Hash32 = ZERO_HASH32,
    is_active: bool = True,
) -> Validator:
    validator = Validator.create_pending_validator(
        pubkey, withdrawal_credentials, config.MAX_EFFECTIVE_BALANCE, config)
    if is_active:
        return activate_validator(validator, config.GENESIS_EPOCH)
    else:
        return validator
コード例 #4
0
ファイル: genesis.py プロジェクト: root-servers/trinity
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)
コード例 #5
0
def test_activate_validator(genesis_state, is_already_activated,
                            validator_count, pubkeys, config):
    some_future_epoch = config.GENESIS_EPOCH + random.randrange(1, 2**32)

    if is_already_activated:
        assert validator_count > 0
        some_validator = genesis_state.validators[0]
        assert some_validator.activation_eligibility_epoch == config.GENESIS_EPOCH
        assert some_validator.activation_epoch == config.GENESIS_EPOCH
    else:
        some_validator = create_mock_validator(pubkeys[:validator_count + 1],
                                               config,
                                               is_active=is_already_activated)
        assert some_validator.activation_eligibility_epoch == FAR_FUTURE_EPOCH
        assert some_validator.activation_epoch == FAR_FUTURE_EPOCH
    assert not some_validator.slashed

    activated_validator = activate_validator(some_validator, some_future_epoch)
    assert activated_validator.activation_eligibility_epoch == some_future_epoch
    assert activated_validator.activation_epoch == some_future_epoch
    assert not activated_validator.slashed
コード例 #6
0
def test_activate_validator(genesis, filled_beacon_state, genesis_slot,
                            entry_exit_delay, max_deposit):
    validator_count = 10
    state = filled_beacon_state.copy(
        validator_registry=tuple(
            mock_validator_record(
                pubkey=index.to_bytes(48, 'big'),
                is_active=False,
            ) for index in range(validator_count)),
        validator_balances=(max_deposit * GWEI_PER_ETH, ) * validator_count,
    )
    index = 1
    # Check that the `index`th validator in `state` is inactivated
    assert state.validator_registry[index].activation_slot == FAR_FUTURE_SLOT

    result_state = activate_validator(
        state=state,
        index=index,
        genesis=genesis,
        genesis_slot=genesis_slot,
        entry_exit_delay=entry_exit_delay,
    )
    result_validator = result_state.validator_registry[index]

    new_validator_registry_delta_chain_tip = ValidatorRegistryDeltaBlock(
        latest_registry_delta_root=state.validator_registry_delta_chain_tip,
        validator_index=index,
        pubkey=result_validator.pubkey,
        slot=result_validator.activation_slot,
        flag=ValidatorRegistryDeltaFlag.ACTIVATION,
    ).root

    assert (result_state.validator_registry_delta_chain_tip ==
            new_validator_registry_delta_chain_tip)
    if genesis:
        state.validator_registry[index].activation_slot == genesis_slot
    else:
        state.validator_registry[
            index].activation_slot == state.slot + entry_exit_delay
コード例 #7
0
ファイル: on_startup.py プロジェクト: berand/trinity
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
コード例 #8
0
def update_validator_registry(state: BeaconState,
                              config: BeaconConfig) -> BeaconState:
    """
    Update validator registry.
    """
    current_epoch = state.current_epoch(config.SLOTS_PER_EPOCH)
    # The active validators
    active_validator_indices = get_active_validator_indices(
        state.validator_registry, current_epoch)
    # The total effective balance of active validators
    total_balance = get_total_balance(
        state.validator_balances,
        active_validator_indices,
        config.MAX_DEPOSIT_AMOUNT,
    )

    # The maximum balance churn in Gwei (for deposits and exits separately)
    max_balance_churn = max(
        config.MAX_DEPOSIT_AMOUNT,
        total_balance // (2 * config.MAX_BALANCE_CHURN_QUOTIENT))

    # Activate validators within the allowable balance churn
    # linter didn't like a bare lambda
    state = _churn_validators(
        state=state,
        config=config,
        check_should_churn_fn=lambda state, index: _is_ready_to_activate(
            state,
            index,
            max_deposit_amount=config.MAX_DEPOSIT_AMOUNT,
        ),
        churn_fn=lambda state, index: activate_validator(
            state,
            index,
            is_genesis=False,
            genesis_epoch=config.GENESIS_EPOCH,
            slots_per_epoch=config.SLOTS_PER_EPOCH,
            activation_exit_delay=config.ACTIVATION_EXIT_DELAY,
        ),
        max_balance_churn=max_balance_churn,
    )

    # Exit validators within the allowable balance churn
    # linter didn't like a bare lambda
    state = _churn_validators(
        state=state,
        config=config,
        check_should_churn_fn=lambda state, index: _is_ready_to_exit(
            state, index),
        churn_fn=lambda state, index: exit_validator(
            state,
            index,
            slots_per_epoch=config.SLOTS_PER_EPOCH,
            activation_exit_delay=config.ACTIVATION_EXIT_DELAY,
        ),
        max_balance_churn=max_balance_churn,
    )

    state = state.copy(validator_registry_update_epoch=current_epoch, )

    return state
コード例 #9
0
def get_genesis_beacon_state(
        *, genesis_validator_deposits: Sequence[Deposit],
        genesis_time: Timestamp, genesis_eth1_data: Eth1Data,
        genesis_slot: Slot, genesis_epoch: Epoch, genesis_fork_version: int,
        genesis_start_shard: Shard, shard_count: int, min_seed_lookahead: int,
        slots_per_historical_root: int, latest_active_index_roots_length: int,
        slots_per_epoch: int, max_deposit_amount: Gwei,
        latest_slashed_exit_length: int, latest_randao_mixes_length: int,
        activation_exit_delay: int, deposit_contract_tree_depth: int,
        block_class: Type[BaseBeaconBlock]) -> BeaconState:
    state = BeaconState(
        # Misc
        slot=genesis_slot,
        genesis_time=genesis_time,
        fork=Fork(
            previous_version=genesis_fork_version.to_bytes(4, 'little'),
            current_version=genesis_fork_version.to_bytes(4, 'little'),
            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_shuffling_start_shard=genesis_start_shard,
        current_shuffling_start_shard=genesis_start_shard,
        previous_shuffling_epoch=genesis_epoch,
        current_shuffling_epoch=genesis_epoch,
        previous_shuffling_seed=ZERO_HASH32,
        current_shuffling_seed=ZERO_HASH32,

        # Finality
        previous_epoch_attestations=(),
        current_epoch_attestations=(),
        previous_justified_epoch=genesis_epoch,
        current_justified_epoch=genesis_epoch,
        previous_justified_root=ZERO_HASH32,
        current_justified_root=ZERO_HASH32,
        justification_bitfield=0,
        finalized_epoch=genesis_epoch,
        finalized_root=ZERO_HASH32,

        # Recent state
        latest_crosslinks=((CrosslinkRecord(
            epoch=genesis_epoch, crosslink_data_root=ZERO_HASH32), ) *
                           shard_count),
        latest_block_roots=(ZERO_HASH32, ) * slots_per_historical_root,
        latest_state_roots=(ZERO_HASH32, ) * slots_per_historical_root,
        latest_active_index_roots=(ZERO_HASH32, ) *
        latest_active_index_roots_length,
        latest_slashed_balances=(Gwei(0), ) * latest_slashed_exit_length,
        latest_block_header=get_temporary_block_header(
            BeaconBlock.create_empty_block(genesis_slot), ),
        historical_roots=(),

        # Ethereum 1.0 chain data
        latest_eth1_data=genesis_eth1_data,
        eth1_data_votes=(),
        deposit_index=0,
    )

    # Process genesis deposits
    for deposit in genesis_validator_deposits:
        state = process_deposit(
            state=state,
            deposit=deposit,
            slots_per_epoch=slots_per_epoch,
            deposit_contract_tree_depth=deposit_contract_tree_depth,
        )

    # Process genesis 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,
                slots_per_epoch=slots_per_epoch,
                activation_exit_delay=activation_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, 'little') for index in active_validator_indices]))
    latest_active_index_roots = (
        genesis_active_index_root, ) * latest_active_index_roots_length
    state = state.copy(latest_active_index_roots=latest_active_index_roots, )

    current_shuffling_seed = generate_seed(
        state=state,
        epoch=genesis_epoch,
        slots_per_epoch=slots_per_epoch,
        min_seed_lookahead=min_seed_lookahead,
        activation_exit_delay=activation_exit_delay,
        latest_active_index_roots_length=latest_active_index_roots_length,
        latest_randao_mixes_length=latest_randao_mixes_length,
    )
    state = state.copy(current_shuffling_seed=current_shuffling_seed, )

    return state
コード例 #10
0
def get_initial_beacon_state(*, initial_validator_deposits: Sequence[Deposit],
                             genesis_time: Timestamp,
                             latest_eth1_data: Eth1Data,
                             genesis_slot: SlotNumber,
                             genesis_fork_version: int,
                             genesis_start_shard: ShardNumber,
                             shard_count: int, latest_block_roots_length: int,
                             epoch_length: int, target_committee_size: int,
                             max_deposit: Ether,
                             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,
            slot=genesis_slot,
        ),

        # Validator registry
        validator_registry=(),
        validator_balances=(),
        validator_registry_update_slot=genesis_slot,
        validator_registry_exit_count=0,
        validator_registry_delta_chain_tip=ZERO_HASH32,

        # Randomness and committees
        latest_randao_mixes=tuple(ZERO_HASH32
                                  for _ in range(latest_randao_mixes_length)),
        latest_vdf_outputs=tuple(ZERO_HASH32
                                 for _ in range(latest_randao_mixes_length //
                                                epoch_length)),
        # TODO Remove `persistent_committees`, `persistent_committee_reassignments`
        persistent_committees=(),
        persistent_committee_reassignments=(),
        previous_epoch_start_shard=genesis_start_shard,
        current_epoch_start_shard=genesis_start_shard,
        previous_epoch_calculation_slot=genesis_slot,
        current_epoch_calculation_slot=genesis_slot,
        previous_epoch_randao_mix=ZERO_HASH32,
        current_epoch_randao_mix=ZERO_HASH32,

        # Custody challenges
        custody_challenges=(),

        # Finality
        previous_justified_slot=genesis_slot,
        justified_slot=genesis_slot,
        justification_bitfield=0,
        finalized_slot=genesis_slot,

        # Recent state
        latest_crosslinks=tuple([
            CrosslinkRecord(slot=genesis_slot, shard_block_root=ZERO_HASH32)
            for _ in range(shard_count)
        ]),
        latest_block_roots=tuple(ZERO_HASH32
                                 for _ in range(latest_block_roots_length)),
        latest_penalized_balances=tuple(
            Gwei(0) for _ in range(latest_penalized_exit_length)),
        latest_attestations=(),
        batched_block_roots=(),

        # Ethereum 1.0 chain data
        latest_eth1_data=latest_eth1_data,
        eth1_data_votes=(),
    )

    # Process initial deposits
    for deposit in initial_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,
            randao_commitment=deposit.deposit_data.deposit_input.
            randao_commitment,
            custody_commitment=deposit.deposit_data.deposit_input.
            custody_commitment,
        )

    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,
        ) >= max_deposit * GWEI_PER_ETH
        if is_enough_effective_balance:
            state = activate_validator(
                state,
                validator_index,
                genesis=True,
                genesis_slot=genesis_slot,
                entry_exit_delay=entry_exit_delay,
            )

    return state