Beispiel #1
0
def test_process_voluntary_exits(
    genesis_state,
    sample_beacon_block_params,
    sample_beacon_block_body_params,
    config,
    keymap,
    success,
):
    state = genesis_state.set(
        "slot",
        compute_start_slot_at_epoch(
            config.GENESIS_EPOCH + config.PERSISTENT_COMMITTEE_PERIOD,
            config.SLOTS_PER_EPOCH,
        ),
    )
    validator_index = 0
    validator = state.validators[validator_index].set("activation_epoch",
                                                      config.GENESIS_EPOCH)
    state = state.transform(["validators", validator_index], validator)
    valid_voluntary_exit = create_mock_voluntary_exit(state, config, keymap,
                                                      validator_index)

    if success:
        block_body = BeaconBlockBody.create(
            **sample_beacon_block_body_params).set("voluntary_exits",
                                                   (valid_voluntary_exit, ))
        block = SerenityBeaconBlock.create(**sample_beacon_block_params).mset(
            "slot", state.slot, "body", block_body)

        new_state = process_voluntary_exits(state, block, config)
        updated_validator = new_state.validators[validator_index]
        assert updated_validator.exit_epoch != FAR_FUTURE_EPOCH
        assert updated_validator.exit_epoch > state.current_epoch(
            config.SLOTS_PER_EPOCH)
        assert updated_validator.withdrawable_epoch == (
            updated_validator.exit_epoch +
            config.MIN_VALIDATOR_WITHDRAWABILITY_DELAY)
    else:
        invalid_voluntary_exit = valid_voluntary_exit.set(
            "signature",
            b"\x12" * 96  # Put wrong signature
        )
        block_body = BeaconBlockBody.create(
            **sample_beacon_block_body_params).set("voluntary_exits",
                                                   (invalid_voluntary_exit, ))
        block = SerenityBeaconBlock.create(**sample_beacon_block_params).mset(
            "slot", state.slot, "body", block_body)

        with pytest.raises(ValidationError):
            process_voluntary_exits(state, block, config)
Beispiel #2
0
def test_process_attester_slashings(
    genesis_state,
    sample_beacon_block_params,
    sample_beacon_block_body_params,
    config,
    keymap,
    min_attestation_inclusion_delay,
    success,
):
    attesting_state = genesis_state.mset(
        "slot",
        genesis_state.slot + config.SLOTS_PER_EPOCH,
        "block_roots",
        tuple(
            i.to_bytes(32, "little")
            for i in range(config.SLOTS_PER_HISTORICAL_ROOT)),
    )
    valid_attester_slashing = create_mock_attester_slashing_is_double_vote(
        attesting_state, config, keymap, attestation_epoch=0)
    state = attesting_state.set(
        "slot", attesting_state.slot + min_attestation_inclusion_delay)

    if success:
        block_body = BeaconBlockBody.create(
            **sample_beacon_block_body_params).set("attester_slashings",
                                                   (valid_attester_slashing, ))
        block = SerenityBeaconBlock.create(**sample_beacon_block_params).mset(
            "slot", state.slot, "body", block_body)

        attester_index = valid_attester_slashing.attestation_1.attesting_indices[
            0]

        new_state = process_attester_slashings(state, block, config)
        # Check if slashed
        assert not state.validators[attester_index].slashed
        assert new_state.validators[attester_index].slashed
    else:
        invalid_attester_slashing = valid_attester_slashing.transform(
            ["attestation_2", "data"],
            valid_attester_slashing.attestation_1.data)
        block_body = BeaconBlockBody.create(
            **sample_beacon_block_body_params).set(
                "attester_slashings", (invalid_attester_slashing, ))
        block = SerenityBeaconBlock.create(**sample_beacon_block_params).mset(
            "slot", state.slot, "body", block_body)

        with pytest.raises(ValidationError):
            process_attester_slashings(state, block, config)
def test_randao_processing_validates_randao_reveal(
    sample_beacon_block_params,
    sample_beacon_block_body_params,
    sample_beacon_state_params,
    sample_fork_params,
    keymap,
    config,
):
    proposer_pubkey, proposer_privkey = first(keymap.items())
    state = SerenityBeaconState.create(**sample_beacon_state_params).mset(
        "validators",
        tuple(
            create_mock_validator(proposer_pubkey, config)
            for _ in range(config.TARGET_COMMITTEE_SIZE)),
        "balances",
        (config.MAX_EFFECTIVE_BALANCE, ) * config.TARGET_COMMITTEE_SIZE,
        "randao_mixes",
        tuple(ZERO_HASH32 for _ in range(config.EPOCHS_PER_HISTORICAL_VECTOR)),
    )

    epoch = state.current_epoch(config.SLOTS_PER_EPOCH)
    message_hash = (epoch + 1).to_bytes(32, byteorder="little")
    domain = get_domain(state, SignatureDomain.DOMAIN_RANDAO,
                        config.SLOTS_PER_EPOCH)
    randao_reveal = bls.sign(message_hash, proposer_privkey, domain)

    block_body = BeaconBlockBody.create(**sample_beacon_block_body_params).set(
        "randao_reveal", randao_reveal)

    block = SerenityBeaconBlock.create(**sample_beacon_block_params).set(
        "body", block_body)

    with pytest.raises(ValidationError):
        process_randao(state, block, config)
def test_ensure_update_eth1_vote_if_exists(genesis_state, config,
                                           vote_offsets):
    # one less than a majority is the majority divided by 2
    threshold = config.SLOTS_PER_ETH1_VOTING_PERIOD // 2
    data_votes = tuple(
        concat((Eth1Data.create(block_hash=(i).to_bytes(32, "little")), ) *
               (threshold + offset) for i, offset in enumerate(vote_offsets)))
    state = genesis_state

    for vote in data_votes:
        state = process_eth1_data(
            state,
            BeaconBlock.create(body=BeaconBlockBody.create(eth1_data=vote)),
            config,
        )

    if not vote_offsets:
        assert state.eth1_data == genesis_state.eth1_data

    # we should update the 'latest' entry if we have a majority
    for offset in vote_offsets:
        if offset <= 0:
            assert genesis_state.eth1_data == state.eth1_data
        else:
            assert state.eth1_data == data_votes[0]
def test_process_eth1_data(
    original_votes,
    block_data,
    expected_votes,
    sample_beacon_state_params,
    sample_beacon_block_params,
    sample_beacon_block_body_params,
    config,
):
    eth1_data_votes = tuple(mapcat(_expand_eth1_votes, original_votes))
    state = BeaconState.create(**sample_beacon_state_params).set(
        "eth1_data_votes", eth1_data_votes)

    block_body = BeaconBlockBody.create(
        **sample_beacon_block_body_params).mset(
            "eth1_data", Eth1Data.create(block_hash=block_data))

    block = BeaconBlock.create(**sample_beacon_block_params).set(
        "body", block_body)

    updated_state = process_eth1_data(state, block, config)
    updated_votes = updated_state.eth1_data_votes
    expanded_expected_votes = tuple(mapcat(_expand_eth1_votes, expected_votes))

    assert tuple(updated_votes) == expanded_expected_votes
Beispiel #6
0
def sample_beacon_block_params(sample_beacon_block_body_params):
    return {
        "slot": GENESIS_SLOT + 10,
        "parent_root": ZERO_HASH32,
        "state_root": b"\x55" * 32,
        "body": BeaconBlockBody.create(**sample_beacon_block_body_params),
    }
Beispiel #7
0
def sample_beacon_block_params(sample_beacon_block_body_params, genesis_slot):
    return {
        "slot": genesis_slot + 10,
        "parent_root": ZERO_HASH32,
        "state_root": b"\x55" * 32,
        "body": BeaconBlockBody.create(**sample_beacon_block_body_params),
    }
Beispiel #8
0
def create_block_proposal(
    slot: Slot,
    parent_root: Root,
    randao_reveal: BLSSignature,
    eth1_data: Eth1Data,
    attestations: Sequence[Attestation],
    state: BeaconState,
    state_machine: BaseBeaconStateMachine,
) -> BeaconBlock:
    config = state_machine.config
    state_at_slot, _ = state_machine.apply_state_transition(state,
                                                            future_slot=slot)
    proposer_index = get_beacon_proposer_index(state_at_slot, config)

    block_body = BeaconBlockBody.create(randao_reveal=randao_reveal,
                                        eth1_data=eth1_data,
                                        attestations=attestations)
    proposal = BeaconBlock.create(
        slot=slot,
        parent_root=parent_root,
        body=block_body,
        proposer_index=proposer_index,
    )
    block_with_empty_signature = SignedBeaconBlock.create(
        message=proposal, signature=EMPTY_SIGNATURE)
    post_state, block_with_state_root = state_machine.apply_state_transition(
        state, block_with_empty_signature, check_proposer_signature=False)
    return block_with_state_root.message
Beispiel #9
0
def create_unsigned_block_on_state(
    *,
    state: BeaconState,
    config: Eth2Config,
    block_class: Type[BaseBeaconBlock],
    parent_block: BaseBeaconBlock,
    slot: Slot,
    attestations: Sequence[Attestation],
    eth1_data: Eth1Data = None,
    deposits: Sequence[Deposit] = None,
    check_proposer_index: bool = True,
) -> BeaconBlock:
    """
    Create a beacon block with the given parameters.
    """
    block = block_class.from_parent(parent_block=parent_block,
                                    block_params=FromBlockParams(slot=slot))

    # MAX_ATTESTATIONS
    attestations = attestations[:config.MAX_ATTESTATIONS]

    # TODO: Add more operations
    if eth1_data is None:
        eth1_data = state.eth1_data
    body = BeaconBlockBody.create(eth1_data=eth1_data,
                                  attestations=attestations)
    if deposits is not None and len(deposits) > 0:
        body = body.set("deposits", deposits)

    block = block.set("body", body)

    return block
Beispiel #10
0
 def run_with(
     cls,
     inputs: Tuple[BeaconState, OperationOrBlockHeader],
     config: Optional[Eth2Config],
 ) -> BeaconState:
     state, operation = inputs
     # NOTE: we do not have an easy way to evaluate a single operation on the state
     # So, we wrap it in a beacon block. The following statement lets us rely on
     # the config given in a particular handler class while working w/in the
     # update API provided by `py-ssz`.
     # NOTE: we ignore the type here, otherwise need to spell out each of the keyword
     # arguments individually... save some work and just build them dynamically
     block = BeaconBlock.create(body=BeaconBlockBody.create(
         **{f"{cls.name}s": (operation, )}  # type: ignore
     ))
     try:
         return cls.processor(state, block, config)
     except ValidationError as e:
         # if already a ValidationError, re-raise
         raise e
     except Exception as e:
         # check if the exception is expected...
         for exception in cls.expected_exceptions:
             if isinstance(e, exception):
                 raise ValidationError() from e
         # else raise (and fail the pytest test case ...)
         raise e
Beispiel #11
0
 async def _get_block_proposal(self, request: web.Request) -> web.Response:
     slot = Slot(int(request.query["slot"]))
     randao_reveal = BLSSignature(
         decode_hex(request.query["randao_reveal"]).ljust(96, b"\x00"))
     block = BeaconBlock.create(
         slot=slot,
         body=BeaconBlockBody.create(randao_reveal=randao_reveal))
     return web.json_response(to_formatted_dict(block))
Beispiel #12
0
def genesis_state(eth2_config, genesis_time, genesis_validators):
    balances = tuple(validator.effective_balance for validator in genesis_validators)
    state = BeaconState.create(
        latest_block_header=BeaconBlockHeader.create(
            body_root=BeaconBlockBody.create().hash_tree_root
        ),
        validators=genesis_validators,
        balances=balances,
        config=eth2_config,
    )
    state.genesis_time = genesis_time
    return state
Beispiel #13
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 #14
0
def test_block_body_empty(sample_attestation_params):
    block_body = BeaconBlockBody.create()
    assert tuple(block_body.proposer_slashings) == ()
    assert tuple(block_body.attester_slashings) == ()
    assert tuple(block_body.attestations) == ()
    assert tuple(block_body.deposits) == ()
    assert tuple(block_body.voluntary_exits) == ()

    assert block_body.is_empty

    block_body = block_body.set(
        "attestations", (Attestation.create(**sample_attestation_params), ))
    assert not block_body.is_empty
Beispiel #15
0
def create_block_on_state(
        *,
        state: BeaconState,
        config: Eth2Config,
        state_machine: BaseBeaconStateMachine,
        block_class: Type[BaseBeaconBlock],
        parent_block: BaseBeaconBlock,
        slot: Slot,
        validator_index: ValidatorIndex,
        privkey: int,
        attestations: Sequence[Attestation],
        check_proposer_index: bool = True) -> BaseBeaconBlock:
    """
    Create a beacon block with the given parameters.
    """
    if check_proposer_index:
        validate_proposer_index(state, config, slot, validator_index)

    block = block_class.from_parent(parent_block=parent_block,
                                    block_params=FromBlockParams(slot=slot))

    # MAX_ATTESTATIONS
    attestations = attestations[:config.MAX_ATTESTATIONS]

    # TODO: Add more operations
    randao_reveal = _generate_randao_reveal(privkey, slot, state, config)
    eth1_data = state.eth1_data
    body = BeaconBlockBody.create(randao_reveal=randao_reveal,
                                  eth1_data=eth1_data,
                                  attestations=attestations)

    block = block.set("body", body)

    # Apply state transition to get state root
    state, block = state_machine.import_block(block,
                                              state,
                                              check_proposer_signature=False)

    # Sign
    signature = sign_transaction(
        message_hash=block.signing_root,
        privkey=privkey,
        state=state,
        slot=slot,
        signature_domain=SignatureDomain.DOMAIN_BEACON_PROPOSER,
        slots_per_epoch=config.SLOTS_PER_EPOCH,
    )

    block = block.set("signature", signature)

    return block
Beispiel #16
0
def test_process_attestations(
    genesis_state,
    genesis_block,
    sample_beacon_block_params,
    sample_beacon_block_body_params,
    config,
    keymap,
    fixture_sm_class,
    chaindb,
    genesis_fork_choice_context,
    success,
):

    attestation_slot = 0
    current_slot = attestation_slot + config.MIN_ATTESTATION_INCLUSION_DELAY
    state = genesis_state.set("slot", current_slot)

    attestations = create_mock_signed_attestations_at_slot(
        state=state,
        config=config,
        state_machine=fixture_sm_class(chaindb, genesis_fork_choice_context),
        attestation_slot=attestation_slot,
        beacon_block_root=genesis_block.message.hash_tree_root,
        keymap=keymap,
        voted_attesters_ratio=1.0,
    )

    assert len(attestations) > 0

    if not success:
        # create invalid attestation
        # i.e. wrong slot
        invalid_attestation_data = attestations[-1].data.set(
            "slot", state.slot + 1)
        invalid_attestation = attestations[-1].set("data",
                                                   invalid_attestation_data)
        attestations = attestations[:-1] + (invalid_attestation, )

    block_body = BeaconBlockBody.create(**sample_beacon_block_body_params).set(
        "attestations", attestations)
    block = SerenityBeaconBlock.create(**sample_beacon_block_params).mset(
        "slot", current_slot, "body", block_body)

    if success:
        new_state = process_attestations(state, block, config)

        assert len(new_state.current_epoch_attestations) == len(attestations)
    else:
        with pytest.raises(ValidationError):
            process_attestations(state, block, config)
Beispiel #17
0
def create_block_proposal(
    slot: Slot,
    parent_root: Root,
    randao_reveal: BLSSignature,
    eth1_data: Eth1Data,
    state: BeaconState,
    state_machine: BaseBeaconStateMachine,
) -> BeaconBlock:
    proposal = BeaconBlock.create(
        slot=slot,
        parent_root=parent_root,
        body=BeaconBlockBody.create(randao_reveal=randao_reveal, eth1_data=eth1_data),
    )
    signed_block = SignedBeaconBlock.create(message=proposal, signature=EMPTY_SIGNATURE)
    post_state, signed_block = state_machine.import_block(
        signed_block, state, check_proposer_signature=False
    )
    return signed_block.message
def test_randao_processing(
    sample_beacon_block_params,
    sample_beacon_block_body_params,
    sample_beacon_state_params,
    keymap,
    config,
):
    proposer_pubkey, proposer_privkey = first(keymap.items())
    state = SerenityBeaconState.create(**sample_beacon_state_params).mset(
        "validators",
        tuple(
            create_mock_validator(proposer_pubkey, config)
            for _ in range(config.TARGET_COMMITTEE_SIZE)),
        "balances",
        (config.MAX_EFFECTIVE_BALANCE, ) * config.TARGET_COMMITTEE_SIZE,
        "randao_mixes",
        tuple(ZERO_HASH32 for _ in range(config.EPOCHS_PER_HISTORICAL_VECTOR)),
    )

    epoch = state.current_epoch(config.SLOTS_PER_EPOCH)
    slot = compute_start_slot_at_epoch(epoch, config.SLOTS_PER_EPOCH)

    randao_reveal = _generate_randao_reveal(privkey=proposer_privkey,
                                            slot=slot,
                                            state=state,
                                            config=config)

    block_body = BeaconBlockBody.create(**sample_beacon_block_body_params).set(
        "randao_reveal", randao_reveal)

    block = SerenityBeaconBlock.create(**sample_beacon_block_params).set(
        "body", block_body)

    new_state = process_randao(state, block, config)

    updated_index = epoch % config.EPOCHS_PER_HISTORICAL_VECTOR
    original_mixes = state.randao_mixes
    updated_mixes = new_state.randao_mixes

    assert all(
        updated == original if index != updated_index else updated != original
        for index, (updated,
                    original) in enumerate(zip(updated_mixes, original_mixes)))
def test_process_proposer_slashings(
    genesis_state,
    sample_beacon_block_params,
    sample_beacon_block_body_params,
    config,
    keymap,
    block_root_1,
    block_root_2,
    success,
):
    current_slot = config.GENESIS_SLOT + 1
    state = genesis_state.set("slot", current_slot)
    whistleblower_index = get_beacon_proposer_index(state,
                                                    CommitteeConfig(config))
    slashing_proposer_index = (whistleblower_index + 1) % len(state.validators)
    proposer_slashing = create_mock_proposer_slashing_at_block(
        state,
        config,
        keymap,
        block_root_1=block_root_1,
        block_root_2=block_root_2,
        proposer_index=slashing_proposer_index,
    )
    proposer_slashings = (proposer_slashing, )

    block_body = BeaconBlockBody.create(**sample_beacon_block_body_params).set(
        "proposer_slashings", proposer_slashings)
    block = SerenityBeaconBlock.create(**sample_beacon_block_params).mset(
        "slot", current_slot, "body", block_body)

    if success:
        new_state = process_proposer_slashings(state, block, config)
        # Check if slashed
        assert (new_state.balances[slashing_proposer_index] <
                state.balances[slashing_proposer_index])
    else:
        with pytest.raises(ValidationError):
            process_proposer_slashings(state, block, config)
Beispiel #20
0
async def test_request_beacon_blocks_by_root(monkeypatch):
    async with ConnectionPairFactory() as (alice, bob):

        # Mock up block database
        head_block = BeaconBlock.create(
            slot=0,
            parent_root=ZERO_HASH32,
            state_root=ZERO_HASH32,
            signature=EMPTY_SIGNATURE,
            body=BeaconBlockBody.create(),
        )
        blocks = [head_block.set("slot", slot) for slot in range(5)]
        mock_root_to_block_db = {block.signing_root: block for block in blocks}

        def get_block_by_root(root):
            validate_word(root)
            if root in mock_root_to_block_db:
                return mock_root_to_block_db[root]
            else:
                raise BlockNotFound

        monkeypatch.setattr(bob.chain, "get_block_by_root", get_block_by_root)

        requesting_block_roots = [
            blocks[0].signing_root,
            b"\x12" * 32,  # Unknown block root
            blocks[1].signing_root,
            b"\x23" * 32,  # Unknown block root
            blocks[3].signing_root,
        ]
        requested_blocks = await alice.request_beacon_blocks_by_root(
            peer_id=bob.peer_id, block_roots=requesting_block_roots
        )

        expected_blocks = [blocks[0], blocks[1], blocks[3]]
        assert len(requested_blocks) == len(expected_blocks)
        assert set(requested_blocks) == set(expected_blocks)
Beispiel #21
0
 async def fetch_block_proposal(self, slot: Slot,
                                randao_reveal: BLSSignature) -> BeaconBlock:
     body = BeaconBlockBody.create(randao_reveal=randao_reveal)
     return BeaconBlock.create(slot=slot, body=body)
Beispiel #22
0
async def test_request_beacon_blocks_by_range_invalid_request(monkeypatch):
    async with ConnectionPairFactory() as (alice, bob):

        head_slot = 1
        request_head_block_root = b"\x56" * 32
        head_block = BeaconBlock.create(
            slot=head_slot,
            parent_root=ZERO_HASH32,
            state_root=ZERO_HASH32,
            signature=EMPTY_SIGNATURE,
            body=BeaconBlockBody.create(),
        )

        # TEST: Can not request blocks with `start_slot` greater than head block slot
        start_slot = 2

        def get_block_by_root(root):
            return head_block

        monkeypatch.setattr(bob.chain, "get_block_by_root", get_block_by_root)

        count = 1
        step = 1
        with pytest.raises(RequestFailure):
            await alice.request_beacon_blocks_by_range(
                peer_id=bob.peer_id,
                head_block_root=request_head_block_root,
                start_slot=start_slot,
                count=count,
                step=step,
            )

        # TEST: Can not request fork chain blocks with `start_slot`
        # lower than peer's latest finalized slot
        start_slot = head_slot
        state_machine = bob.chain.get_state_machine()
        old_state = bob.chain.get_head_state()
        new_checkpoint = old_state.finalized_checkpoint.set(
            "epoch", old_state.finalized_checkpoint.epoch + 1
        )

        def get_canonical_block_by_slot(slot):
            raise BlockNotFound

        monkeypatch.setattr(
            bob.chain, "get_canonical_block_by_slot", get_canonical_block_by_slot
        )

        def get_state_machine(at_slot=None):
            class MockStateMachine:
                state = old_state.set("finalized_checkpoint", new_checkpoint)
                config = state_machine.config

            return MockStateMachine()

        def get_head_state():
            return old_state.set("finalized_checkpoint", new_checkpoint)

        monkeypatch.setattr(bob.chain, "get_state_machine", get_state_machine)
        monkeypatch.setattr(bob.chain, "get_head_state", get_head_state)

        with pytest.raises(RequestFailure):
            await alice.request_beacon_blocks_by_range(
                peer_id=bob.peer_id,
                head_block_root=request_head_block_root,
                start_slot=start_slot,
                count=count,
                step=step,
            )
Beispiel #23
0
def test_get_genesis_beacon_state(
    validator_count,
    pubkeys,
    genesis_epoch,
    genesis_slot,
    max_committees_per_slot,
    slots_per_historical_root,
    epochs_per_slashings_vector,
    epochs_per_historical_vector,
    config,
    keymap,
):
    genesis_deposits, deposit_root = create_mock_deposits_and_root(
        pubkeys=pubkeys[:validator_count], keymap=keymap, config=config)

    genesis_eth1_data = Eth1Data.create(
        deposit_count=len(genesis_deposits),
        deposit_root=deposit_root,
        block_hash=ZERO_HASH32,
    )
    eth1_timestamp = 10
    eth1_block_hash = genesis_eth1_data.block_hash

    state = initialize_beacon_state_from_eth1(
        eth1_block_hash=eth1_block_hash,
        eth1_timestamp=eth1_timestamp,
        deposits=genesis_deposits,
        config=config,
    )

    # Versioning
    assert state.slot == genesis_slot
    assert state.genesis_time == _genesis_time_from_eth1_timestamp(
        eth1_timestamp)
    assert state.fork == Fork.create()

    # History
    assert state.latest_block_header == BeaconBlockHeader.create(
        body_root=BeaconBlockBody.create().hash_tree_root)
    assert len(state.block_roots) == slots_per_historical_root
    assert tuple(
        state.block_roots) == (ZERO_HASH32, ) * slots_per_historical_root
    assert len(state.state_roots) == slots_per_historical_root
    assert tuple(
        state.block_roots) == (ZERO_HASH32, ) * slots_per_historical_root
    assert len(state.historical_roots) == 0

    # Ethereum 1.0 chain data
    assert state.eth1_data == genesis_eth1_data
    assert len(state.eth1_data_votes) == 0
    assert state.eth1_deposit_index == len(genesis_deposits)

    # Validator registry
    assert len(state.validators) == validator_count
    assert len(state.balances) == validator_count

    # Shuffling
    assert len(state.randao_mixes) == epochs_per_historical_vector
    assert (tuple(state.randao_mixes) == (eth1_block_hash, ) *
            epochs_per_historical_vector)

    # Slashings
    assert len(state.slashings) == epochs_per_slashings_vector
    assert tuple(state.slashings) == (Gwei(0), ) * epochs_per_slashings_vector

    # Attestations
    assert len(state.previous_epoch_attestations) == 0
    assert len(state.current_epoch_attestations) == 0

    # Justification
    assert state.previous_justified_checkpoint.epoch == genesis_epoch
    assert state.previous_justified_checkpoint.root == ZERO_HASH32
    assert state.current_justified_checkpoint.epoch == genesis_epoch
    assert state.current_justified_checkpoint.root == ZERO_HASH32
    assert state.justification_bits == (False, ) * JUSTIFICATION_BITS_LENGTH

    # Finalization
    assert state.finalized_checkpoint.epoch == genesis_epoch
    assert state.finalized_checkpoint.root == ZERO_HASH32

    for i in range(len(genesis_deposits)):
        assert state.validators[i].is_active(genesis_epoch)