Beispiel #1
0
def test_process_deposit(config, deposit_contract_tree_depth,
                         sample_beacon_state_params, keymap, pubkeys):
    validator_index = 0
    withdrawal_credentials = b'\x34' * 32
    state, deposit = create_mock_deposit(
        config,
        sample_beacon_state_params,
        keymap,
        pubkeys,
        withdrawal_credentials,
        validator_index,
    )

    # Add the first validator
    result_state = process_deposit(
        state=state,
        deposit=deposit,
        slots_per_epoch=config.SLOTS_PER_EPOCH,
        deposit_contract_tree_depth=deposit_contract_tree_depth,
    )

    assert len(result_state.validator_registry) == 1
    validator = result_state.validator_registry[validator_index]
    assert validator.pubkey == pubkeys[validator_index]
    assert validator.withdrawal_credentials == withdrawal_credentials
    assert result_state.validator_balances[
        validator_index] == config.MAX_DEPOSIT_AMOUNT
    # test immutable
    assert len(state.validator_registry) == 0
Beispiel #2
0
def process_deposits(state: BeaconState, block: BaseBeaconBlock,
                     config: Eth2Config) -> BeaconState:
    if len(block.body.deposits) > config.MAX_DEPOSITS:
        raise ValidationError(f"The block ({block}) has too many deposits:\n"
                              f"\tFound {len(block.body.deposits)} deposits, "
                              f"maximum: {config.MAX_DEPOSITS}")

    for deposit in block.body.deposits:
        state = process_deposit(state, deposit, config)

    return state
Beispiel #3
0
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
Beispiel #4
0
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)
Beispiel #5
0
def FuzzerRunOne(input_data: bytes) -> typing.Optional[bytes]:
    test_case = ssz.decode(input_data, sedes=DepositTestCase)

    # TODO(gnattishness) any other relevant exceptions to catch?
    try:
        post = process_deposit(
            state=test_case.pre,
            deposit=test_case.deposit,
            config=SERENITY_CONFIG,
        )
    except ValidationError:
        return None
    return ssz.encode(post)
Beispiel #6
0
def process_deposits(state: BeaconState, block: BaseBeaconBlock,
                     config: Eth2Config) -> BeaconState:
    if len(block.body.deposits) > config.MAX_DEPOSITS:
        raise ValidationError(f"The block ({block}) has too many deposits:\n"
                              f"\tFound {len(block.body.deposits)} deposits, "
                              f"maximum: {config.MAX_DEPOSITS}")

    for deposit in block.body.deposits:
        state = process_deposit(
            state,
            deposit,
            slots_per_epoch=config.SLOTS_PER_EPOCH,
            deposit_contract_tree_depth=config.DEPOSIT_CONTRACT_TREE_DEPTH,
        )

    return state
def test_process_deposit(config, sample_beacon_state_params, keymap,
                         genesis_state, validator_count, is_new_validator,
                         pubkeys):
    state = genesis_state
    withdrawal_credentials = b'\x34' * 32
    if is_new_validator:
        validator_index = validator_count
    else:
        validator_index = validator_count - 1

    pubkey = pubkeys[validator_index]

    state, deposit = create_mock_deposit(
        state,
        pubkey,
        keymap,
        withdrawal_credentials,
        config,
    )

    validator_count_before_deposit = state.validator_count

    result_state = process_deposit(
        state=state,
        deposit=deposit,
        config=config,
    )

    # test immutability
    assert len(state.validators) == validator_count_before_deposit

    validator = result_state.validators[validator_index]
    if is_new_validator:
        assert len(result_state.validators) == len(state.validators) + 1
        assert validator.pubkey == pubkeys[validator_index]
        assert validator.withdrawal_credentials == withdrawal_credentials
        assert result_state.balances[
            validator_index] == config.MAX_EFFECTIVE_BALANCE
    else:
        assert len(result_state.validators) == len(state.validators)
        assert validator.pubkey == pubkeys[validator_index]
        assert result_state.balances[
            validator_index] == 2 * config.MAX_EFFECTIVE_BALANCE
Beispiel #8
0
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
Beispiel #9
0
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,
    )
Beispiel #10
0
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
Beispiel #11
0
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
Beispiel #12
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
Beispiel #13
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