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)
Пример #2
0
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)
Пример #4
0
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,
    }
Пример #5
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)
Пример #6
0
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)
Пример #7
0
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)
Пример #8
0
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,
    )
Пример #9
0
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)
Пример #10
0
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),
    }
Пример #11
0
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,
    }
Пример #12
0
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)))
Пример #13
0
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,
    )
Пример #14
0
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)
Пример #15
0
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)
Пример #17
0
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,
    )
Пример #18
0
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,
    )
Пример #19
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)
Пример #20
0
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,
    )
Пример #21
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
Пример #22
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
Пример #23
0
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),
            )
Пример #25
0
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
Пример #26
0
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,
    )
Пример #27
0
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,
    )
Пример #28
0
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,
    }
Пример #29
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,
    )
Пример #30
0
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,
    )