Example #1
0
def create_deposit_data(*,
                        config: Eth2Config,
                        pubkey: BLSPubkey,
                        privkey: int,
                        withdrawal_credentials: Hash32,
                        fork: Fork,
                        deposit_timestamp: Timestamp,
                        amount: Gwei = None) -> DepositData:
    if amount is None:
        amount = config.MAX_DEPOSIT_AMOUNT

    return DepositData(
        deposit_input=DepositInput(
            pubkey=pubkey,
            withdrawal_credentials=withdrawal_credentials,
            proof_of_possession=sign_proof_of_possession(
                deposit_input=DepositInput(
                    pubkey=pubkey,
                    withdrawal_credentials=withdrawal_credentials,
                ),
                privkey=privkey,
                fork=fork,
                slot=config.GENESIS_SLOT,
                slots_per_epoch=config.SLOTS_PER_EPOCH,
            ),
        ),
        amount=amount,
        timestamp=deposit_timestamp,
    )
Example #2
0
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
Example #3
0
def validate_proof_of_possession(state: BeaconState, pubkey: BLSPubkey,
                                 proof_of_possession: BLSSignature,
                                 withdrawal_credentials: Hash32,
                                 randao_commitment: Hash32,
                                 custody_commitment: Hash32) -> None:
    deposit_input = DepositInput(
        pubkey=pubkey,
        withdrawal_credentials=withdrawal_credentials,
        randao_commitment=randao_commitment,
        custody_commitment=custody_commitment,
        proof_of_possession=EMPTY_SIGNATURE,
    )

    is_valid_signature = bls.verify(
        pubkey=pubkey,
        # TODO: change to hash_tree_root(deposit_input) when we have SSZ tree hashing
        message=deposit_input.root,
        signature=proof_of_possession,
        domain=get_domain(
            state.fork_data,
            state.slot,
            SignatureDomain.DOMAIN_DEPOSIT,
        ),
    )

    if not is_valid_signature:
        raise ValidationError("BLS signature verification error")
Example #4
0
def make_deposit_input(pubkey, withdrawal_credentials, randao_commitment,
                       custody_commitment):
    return DepositInput(
        pubkey=pubkey,
        withdrawal_credentials=withdrawal_credentials,
        randao_commitment=randao_commitment,
        custody_commitment=custody_commitment,
        proof_of_possession=EMPTY_SIGNATURE,
    )
Example #5
0
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
Example #6
0
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_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,
            )
Example #8
0
def validate_proof_of_possession(state: BeaconState, pubkey: BLSPubkey,
                                 proof_of_possession: BLSSignature,
                                 withdrawal_credentials: Hash32,
                                 epoch_length: int) -> None:
    deposit_input = DepositInput(
        pubkey=pubkey,
        withdrawal_credentials=withdrawal_credentials,
        proof_of_possession=EMPTY_SIGNATURE,
    )

    is_valid_signature = bls.verify(
        pubkey=pubkey,
        # TODO: change to hash_tree_root(deposit_input) when we have SSZ tree hashing
        message=deposit_input.root,
        signature=proof_of_possession,
        domain=get_domain(
            state.fork,
            state.current_epoch(epoch_length),
            SignatureDomain.DOMAIN_DEPOSIT,
        ),
    )

    if not is_valid_signature:
        raise ValidationError("BLS signature verification error")
Example #9
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
Example #10
0
def sample_deposit_data_params(sample_deposit_input_params):
    return {
        'deposit_input': DepositInput(**sample_deposit_input_params),
        'amount': 56,
        'timestamp': 1501851927,
    }
Example #11
0
def test_get_genesis_beacon_state(
        privkeys, pubkeys, num_validators, genesis_epoch, genesis_slot,
        genesis_fork_version, genesis_start_shard, shard_count,
        min_seed_lookahead, latest_block_roots_length,
        latest_active_index_roots_length, slots_per_epoch, max_deposit_amount,
        latest_slashed_exit_length, latest_randao_mixes_length,
        activation_exit_delay, sample_eth1_data_params):
    withdrawal_credentials = b'\x22' * 32
    fork = Fork(
        previous_version=genesis_fork_version,
        current_version=genesis_fork_version,
        epoch=genesis_epoch,
    )

    validator_count = 5

    genesis_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,
                    proof_of_possession=sign_proof_of_possession(
                        deposit_input=DepositInput(
                            pubkey=pubkeys[i],
                            withdrawal_credentials=withdrawal_credentials,
                        ),
                        privkey=privkeys[i],
                        fork=fork,
                        slot=genesis_slot,
                        slots_per_epoch=slots_per_epoch,
                    ),
                ),
                amount=max_deposit_amount,
                timestamp=0,
            ),
        ) for i in range(validator_count))
    genesis_time = 10
    latest_eth1_data = Eth1Data(**sample_eth1_data_params)

    state = get_genesis_beacon_state(
        genesis_validator_deposits=genesis_validator_deposits,
        genesis_time=genesis_time,
        latest_eth1_data=latest_eth1_data,
        genesis_epoch=genesis_epoch,
        genesis_slot=genesis_slot,
        genesis_fork_version=genesis_fork_version,
        genesis_start_shard=genesis_start_shard,
        shard_count=shard_count,
        min_seed_lookahead=min_seed_lookahead,
        latest_block_roots_length=latest_block_roots_length,
        latest_active_index_roots_length=latest_active_index_roots_length,
        slots_per_epoch=slots_per_epoch,
        max_deposit_amount=max_deposit_amount,
        latest_slashed_exit_length=latest_slashed_exit_length,
        latest_randao_mixes_length=latest_randao_mixes_length,
        activation_exit_delay=activation_exit_delay,
    )

    # Misc
    assert state.slot == genesis_slot
    assert state.genesis_time == genesis_time
    assert state.fork.previous_version == genesis_fork_version
    assert state.fork.current_version == genesis_fork_version
    assert state.fork.epoch == genesis_epoch

    # Validator registry
    assert len(state.validator_registry) == validator_count
    assert len(state.validator_balances) == validator_count
    assert state.validator_registry_update_epoch == genesis_epoch

    # Randomness and committees
    assert len(state.latest_randao_mixes) == latest_randao_mixes_length
    assert state.previous_shuffling_start_shard == genesis_start_shard
    assert state.current_shuffling_start_shard == genesis_start_shard
    assert state.previous_shuffling_epoch == genesis_epoch
    assert state.current_shuffling_epoch == genesis_epoch
    assert state.previous_shuffling_seed == ZERO_HASH32

    # Finality
    assert state.previous_justified_epoch == genesis_epoch
    assert state.justified_epoch == genesis_epoch
    assert state.justification_bitfield == 0
    assert state.finalized_epoch == genesis_epoch

    # Recent state
    assert len(state.latest_crosslinks) == shard_count
    assert state.latest_crosslinks[0] == CrosslinkRecord(
        epoch=genesis_epoch,
        crosslink_data_root=ZERO_HASH32,
    )
    assert len(state.latest_block_roots) == latest_block_roots_length
    assert state.latest_block_roots[0] == ZERO_HASH32
    assert len(state.latest_slashed_balances) == latest_slashed_exit_length
    assert state.latest_slashed_balances[0] == Gwei(0)

    assert len(state.latest_attestations) == 0
    assert len(state.batched_block_roots) == 0

    # Ethereum 1.0 chain data
    assert state.latest_eth1_data == latest_eth1_data
    assert len(state.eth1_data_votes) == 0
    assert state.deposit_index == len(genesis_validator_deposits)

    assert state.validator_registry[0].is_active(genesis_epoch)
Example #12
0
def test_get_initial_beacon_state(
        privkeys, pubkeys, num_validators, genesis_epoch, genesis_slot,
        genesis_fork_version, genesis_start_shard, shard_count, seed_lookahead,
        latest_block_roots_length, latest_index_roots_length, epoch_length,
        max_deposit_amount, latest_penalized_exit_length,
        latest_randao_mixes_length, entry_exit_delay, sample_eth1_data_params):
    withdrawal_credentials = b'\x22' * 32
    randao_commitment = b'\x33' * 32
    custody_commitment = b'\x44' * 32
    fork = Fork(
        previous_version=genesis_fork_version,
        current_version=genesis_fork_version,
        epoch=genesis_epoch,
    )

    validator_count = 5

    initial_validator_deposits = (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=privkeys[i],
                    fork=fork,
                    slot=genesis_slot,
                    epoch_length=epoch_length,
                ),
            ),
            amount=max_deposit_amount,
            timestamp=0,
        ),
    ) for i in range(validator_count))
    genesis_time = 10
    latest_eth1_data = Eth1Data(**sample_eth1_data_params)

    state = get_initial_beacon_state(
        initial_validator_deposits=initial_validator_deposits,
        genesis_time=genesis_time,
        latest_eth1_data=latest_eth1_data,
        genesis_epoch=genesis_epoch,
        genesis_slot=genesis_slot,
        genesis_fork_version=genesis_fork_version,
        genesis_start_shard=genesis_start_shard,
        shard_count=shard_count,
        seed_lookahead=seed_lookahead,
        latest_block_roots_length=latest_block_roots_length,
        latest_index_roots_length=latest_index_roots_length,
        epoch_length=epoch_length,
        max_deposit_amount=max_deposit_amount,
        latest_penalized_exit_length=latest_penalized_exit_length,
        latest_randao_mixes_length=latest_randao_mixes_length,
        entry_exit_delay=entry_exit_delay,
    )

    # Misc
    assert state.slot == genesis_slot
    assert state.genesis_time == genesis_time
    assert state.fork.previous_version == genesis_fork_version
    assert state.fork.current_version == genesis_fork_version
    assert state.fork.epoch == genesis_epoch

    # Validator registry
    assert len(state.validator_registry) == validator_count
    assert len(state.validator_balances) == validator_count
    assert state.validator_registry_update_epoch == genesis_epoch
    assert state.validator_registry_exit_count == 0

    # Randomness and committees
    assert len(state.latest_randao_mixes) == latest_randao_mixes_length
    assert len(
        state.latest_vdf_outputs) == latest_randao_mixes_length // epoch_length

    # TODO: `persistent_committees`, `persistent_committee_reassignments` will be removed
    assert len(state.persistent_committees) == 0
    assert len(state.persistent_committee_reassignments) == 0
    assert state.previous_epoch_start_shard == genesis_start_shard
    assert state.current_epoch_start_shard == genesis_start_shard
    assert state.previous_calculation_epoch == genesis_epoch
    assert state.current_calculation_epoch == genesis_epoch
    assert state.previous_epoch_seed == ZERO_HASH32

    # Custody challenges
    assert len(state.custody_challenges) == 0

    # Finality
    assert state.previous_justified_epoch == genesis_epoch
    assert state.justified_epoch == genesis_epoch
    assert state.justification_bitfield == 0
    assert state.finalized_epoch == genesis_epoch

    # Recent state
    assert len(state.latest_crosslinks) == shard_count
    assert state.latest_crosslinks[0] == CrosslinkRecord(
        epoch=genesis_epoch,
        shard_block_root=ZERO_HASH32,
    )
    assert len(state.latest_block_roots) == latest_block_roots_length
    assert state.latest_block_roots[0] == ZERO_HASH32
    assert len(state.latest_penalized_balances) == latest_penalized_exit_length
    assert state.latest_penalized_balances[0] == Gwei(0)

    assert len(state.latest_attestations) == 0
    assert len(state.batched_block_roots) == 0

    # Ethereum 1.0 chain data
    assert state.latest_eth1_data == latest_eth1_data
    assert len(state.eth1_data_votes) == 0

    assert state.validator_registry[0].is_active(genesis_epoch)
Example #13
0
def test_defaults(sample_deposit_input_params):
    deposit_input = DepositInput(**sample_deposit_input_params)

    assert deposit_input.pubkey == sample_deposit_input_params['pubkey']