コード例 #1
0
def test_validate_serenity_proposer_signature(
        proposer_privkey, proposer_pubkey, is_valid_signature,
        sample_beacon_block_params, sample_beacon_state_params,
        sample_shard_committee_params, beacon_chain_shard_number, epoch_length,
        max_deposit):

    state = BeaconState(**sample_beacon_state_params).copy(
        validator_registry=tuple(
            mock_validator_record(proposer_pubkey) for _ in range(10)),
        validator_balances=(max_deposit * GWEI_PER_ETH, ) * 10,
        shard_committees_at_slots=get_sample_shard_committees_at_slots(
            num_slot=128,
            num_shard_committee_per_slot=10,
            sample_shard_committee_params=sample_shard_committee_params,
        ),
    )

    default_block = BeaconBlock(**sample_beacon_block_params)
    empty_signature_block_root = default_block.block_without_signature_root

    proposal_root = ProposalSignedData(
        state.slot,
        beacon_chain_shard_number,
        empty_signature_block_root,
    ).root

    proposed_block = BeaconBlock(**sample_beacon_block_params).copy(
        signature=bls.sign(
            message=proposal_root,
            privkey=proposer_privkey,
            domain=SignatureDomain.DOMAIN_PROPOSAL,
        ), )

    if is_valid_signature:
        validate_serenity_proposer_signature(
            state,
            proposed_block,
            beacon_chain_shard_number,
            epoch_length,
        )
    else:
        with pytest.raises(ValidationError):
            validate_serenity_proposer_signature(
                state,
                proposed_block,
                beacon_chain_shard_number,
                epoch_length,
            )
コード例 #2
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(**sample_beacon_state_params).copy(
        eth1_data_votes=eth1_data_votes,
    )

    block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy(
        eth1_data=Eth1Data(
            block_hash=block_data,
        ),
    )

    block = BeaconBlock(**sample_beacon_block_params).copy(
        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 updated_votes == expanded_expected_votes
コード例 #3
0
ファイル: test_req_resp.py プロジェクト: skylenet/trinity
async def test_get_blocks_from_canonical_chain_by_slot(
    monkeypatch, db_block_slots, slot_of_requested_blocks, expected_block_slots
):
    node = NodeFactory()

    # Mock up block database
    mock_slot_to_block_db = {
        slot: BeaconBlock(
            slot=slot,
            parent_root=ZERO_HASH32,
            state_root=ZERO_HASH32,
            signature=EMPTY_SIGNATURE,
            body=BeaconBlockBody(),
        )
        for slot in db_block_slots
    }

    def get_canonical_block_by_slot(slot):
        if slot in mock_slot_to_block_db:
            return mock_slot_to_block_db[slot]
        else:
            raise BlockNotFound

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

    result_blocks = node._get_blocks_from_canonical_chain_by_slot(
        slot_of_requested_blocks=slot_of_requested_blocks
    )

    expected_blocks = [mock_slot_to_block_db[slot] for slot in expected_block_slots]
    assert len(result_blocks) == len(expected_blocks)
    assert set(result_blocks) == set(expected_blocks)
コード例 #4
0
ファイル: operations.py プロジェクト: wschwab/trinity
 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(
         body=BeaconBlockBody(**{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(e)
         # else raise (and fail the pytest test case ...)
         raise e
コード例 #5
0
def _mk_block(block_params, slot, parent, block_offset):
    return BeaconBlock(**block_params).copy(
        slot=slot,
        parent_root=parent.signing_root,
        # mix in something unique
        state_root=block_offset.to_bytes(32, byteorder="big"),
    )
コード例 #6
0
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(
                    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(
            body=BeaconBlockBody(
                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]
コード例 #7
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):
    eth1_data_votes = tuple(
        Eth1DataVote(data, vote_count)
        for data, vote_count in original_votes
    )
    state = BeaconState(**sample_beacon_state_params).copy(
        eth1_data_votes=eth1_data_votes,
    )

    block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy(
        eth1_data=block_data,
    )

    block = BeaconBlock(**sample_beacon_block_params).copy(
        body=block_body,
    )

    updated_state = process_eth1_data(state, block)
    updated_votes = tuple(
        (vote.eth1_data, vote.vote_count)
        for vote in updated_state.eth1_data_votes
    )
    assert updated_votes == expected_votes
コード例 #8
0
ファイル: test_higher_slot.py プロジェクト: s0b0lev/trinity
def test_higher_slot_fork_choice_scoring(sample_beacon_block_params, slot):
    block = BeaconBlock(**sample_beacon_block_params).copy(slot=slot, )

    expected_score = slot

    score = higher_slot_scoring(block)

    assert score == expected_score
コード例 #9
0
def test_update_attestations(sample_attestation_params, sample_beacon_block_params):
    block = BeaconBlock(**sample_beacon_block_params)
    attestations = block.body.attestations
    attestations = list(attestations)
    attestations.append(Attestation(**sample_attestation_params))
    body2 = block.body.copy(attestations=attestations)
    block2 = block.copy(body=body2)
    assert len(block2.body.attestations) == 1
コード例 #10
0
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, beacon_chain_shard_number, genesis_epoch,
        target_committee_size, max_deposit_amount, config):

    state = BeaconState(**sample_beacon_state_params).copy(
        validator_registry=tuple(
            mock_validator_record(proposer_pubkey, config) for _ in range(10)),
        validator_balances=(max_deposit_amount, ) * 10,
    )

    default_block = BeaconBlock(**sample_beacon_block_params)
    empty_signature_block_root = default_block.block_without_signature_root

    proposal_signed_root = Proposal(
        state.slot,
        beacon_chain_shard_number,
        empty_signature_block_root,
    ).signed_root

    proposed_block = BeaconBlock(**sample_beacon_block_params).copy(
        signature=bls.sign(
            message_hash=proposal_signed_root,
            privkey=proposer_privkey,
            domain=SignatureDomain.DOMAIN_PROPOSAL,
        ), )

    if is_valid_signature:
        validate_proposer_signature(
            state,
            proposed_block,
            beacon_chain_shard_number,
            CommitteeConfig(config),
        )
    else:
        with pytest.raises(ValidationError):
            validate_proposer_signature(
                state,
                proposed_block,
                beacon_chain_shard_number,
                CommitteeConfig(config),
            )
コード例 #11
0
def test_validate_block_slot(sample_beacon_state_params,
                             sample_beacon_block_params, state_slot,
                             block_slot, expected):
    state = BeaconState(**sample_beacon_state_params).copy(slot=state_slot, )
    block = BeaconBlock(**sample_beacon_block_params).copy(slot=block_slot, )
    if isinstance(expected, Exception):
        with pytest.raises(ValidationError):
            validate_block_slot(state, block)
    else:
        validate_block_slot(state, block)
コード例 #12
0
def create_test_block(parent=None, **kwargs):
    defaults = {
        "slot": SERENITY_CONFIG.GENESIS_SLOT,
        "previous_block_root": ZERO_HASH32,
        "state_root": ZERO_HASH32,  # note: not the actual genesis state root
        "signature": EMPTY_SIGNATURE,
        "body": BeaconBlockBody.create_empty_body()
    }

    if parent is not None:
        kwargs["previous_block_root"] = parent.signing_root
        kwargs["slot"] = parent.slot + 1

    return BeaconBlock(**merge(defaults, kwargs))
コード例 #13
0
ファイル: test_operations.py プロジェクト: s0b0lev/trinity
def test_operation_fixture(config, test_case):
    config = config._replace(MAX_TRANSFERS=1, )
    post_state = test_case.pre
    block = BeaconBlock().copy(body=BeaconBlockBody(
        **{test_case.handler + 's': (
            test_case.operation, )}  # TODO: it looks awful
    ))
    _, operation_processing = handler_to_processing_call_map[test_case.handler]

    if test_case.is_valid:
        post_state = operation_processing(post_state, block, config)
        validate_state(test_case.post, post_state)
    else:
        with pytest.raises((ValidationError, IndexError, SignatureError)):
            operation_processing(post_state, block, config)
コード例 #14
0
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_effective_balance,
        config):

    state = BeaconState(**sample_beacon_state_params).copy(
        validators=tuple(
            create_mock_validator(proposer_pubkey, config)
            for _ in range(10)
        ),
        balances=(max_effective_balance,) * 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(
                state,
                SignatureDomain.DOMAIN_BEACON_PROPOSER,
                slots_per_epoch,
            ),
        ),
    )

    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),
            )
コード例 #15
0
def create_test_block(parent=None, **kwargs):
    defaults = {
        "slot": 0,
        "parent_root": ZERO_HASH32,
        "state_root": ZERO_HASH32,  # note: not the actual genesis state root
        "randao_reveal": EMPTY_SIGNATURE,
        "eth1_data": Eth1Data.create_empty_data(),
        "signature": EMPTY_SIGNATURE,
        "body": BeaconBlockBody.create_empty_body()
    }

    if parent is not None:
        kwargs["parent_root"] = parent.root
        kwargs["slot"] = parent.slot + 1

    return BeaconBlock(**merge(defaults, kwargs))
コード例 #16
0
ファイル: helpers.py プロジェクト: btcpimp/trinity
def create_test_block(parent=None, **kwargs):
    defaults = {
        "slot": 0,
        "parent_root": ZERO_HASH32,
        "state_root": ZERO_HASH32,  # note: not the actual genesis state root
        "randao_reveal": ZERO_HASH32,
        "candidate_pow_receipt_root": ZERO_HASH32,
        "signature": (0, 0),
        "body": empty_body()
    }

    if parent is not None:
        kwargs["parent_root"] = parent.root
        kwargs["slot"] = parent.slot + 1

    return BeaconBlock(**merge(defaults, kwargs))
コード例 #17
0
ファイル: test_req_resp.py プロジェクト: skylenet/trinity
async def test_get_blocks_from_fork_chain_by_root(
    monkeypatch, fork_chain_block_slots, slot_of_requested_blocks, expected_block_slots
):
    node = NodeFactory()

    mock_block = BeaconBlock(
        slot=0,
        parent_root=ZERO_HASH32,
        state_root=ZERO_HASH32,
        signature=EMPTY_SIGNATURE,
        body=BeaconBlockBody(),
    )

    # Mock up fork chain block database
    fork_chain_blocks = []
    for slot in fork_chain_block_slots:
        if len(fork_chain_blocks) == 0:
            fork_chain_blocks.append(mock_block.copy(slot=slot))
        else:
            fork_chain_blocks.append(
                mock_block.copy(
                    slot=slot, parent_root=fork_chain_blocks[-1].signing_root
                )
            )
    mock_root_to_block_db = {block.signing_root: block for block in fork_chain_blocks}

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

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

    requested_blocks = node._get_blocks_from_fork_chain_by_root(
        start_slot=slot_of_requested_blocks[0],
        peer_head_block=fork_chain_blocks[-1],
        slot_of_requested_blocks=slot_of_requested_blocks,
    )

    expected_blocks = [
        block for block in fork_chain_blocks if block.slot in expected_block_slots
    ]
    assert len(requested_blocks) == len(expected_blocks)
    assert set(requested_blocks) == set(expected_blocks)
コード例 #18
0
ファイル: test_commands.py プロジェクト: s0b0lev/trinity
async def test_send_single_block(request, event_loop):
    alice, msg_buffer = await get_command_setup(request, event_loop)

    request_id = 5
    block = BeaconBlock(
        slot=1,
        parent_root=ZERO_HASH32,
        state_root=ZERO_HASH32,
        signature=EMPTY_SIGNATURE,
        body=BeaconBlockBody(),
    )
    alice.sub_proto.send_blocks((block, ), request_id=request_id)

    message = await msg_buffer.msg_queue.get()
    assert isinstance(message.command, BeaconBlocks)
    assert message.payload == {
        "request_id": request_id,
        "encoded_blocks": (ssz.encode(block), ),
    }
コード例 #19
0
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),
            )
コード例 #20
0
ファイル: test_commands.py プロジェクト: s0b0lev/trinity
async def test_send_multiple_blocks(request, event_loop):
    alice, msg_buffer = await get_command_setup(request, event_loop)

    request_id = 5
    blocks = tuple(
        BeaconBlock(
            slot=slot,
            parent_root=ZERO_HASH32,
            state_root=ZERO_HASH32,
            signature=EMPTY_SIGNATURE,
            body=BeaconBlockBody(),
        ) for slot in range(3))
    alice.sub_proto.send_blocks(blocks, request_id=request_id)

    message = await msg_buffer.msg_queue.get()
    assert isinstance(message.command, BeaconBlocks)
    assert message.payload == {
        "request_id": request_id,
        "encoded_blocks": tuple(ssz.encode(block) for block in blocks),
    }
コード例 #21
0
ファイル: test_commands.py プロジェクト: nrryuya/trinity
async def test_send_single_block(request, event_loop):
    alice, msg_buffer = await get_command_setup(request, event_loop)

    request_id = 5
    block = BeaconBlock(
        slot=1,
        parent_root=ZERO_HASH32,
        state_root=ZERO_HASH32,
        randao_reveal=ZERO_HASH32,
        eth1_data=Eth1Data.create_empty_data(),
        signature=EMPTY_SIGNATURE,
        body=BeaconBlockBody.create_empty_body(),
    )
    alice.sub_proto.send_blocks((block, ), request_id=request_id)

    message = await msg_buffer.msg_queue.get()
    assert isinstance(message.command, BeaconBlocks)
    assert message.payload == {
        "request_id": request_id,
        "blocks": (block, ),
    }
コード例 #22
0
ファイル: test_req_resp.py プロジェクト: skylenet/trinity
async def test_request_recent_beacon_blocks(monkeypatch):
    async with ConnectionPairFactory() as (alice, bob):

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

        def get_block_by_hash_tree_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_hash_tree_root", get_block_by_hash_tree_root
        )

        requesting_block_roots = [
            blocks[0].hash_tree_root,
            b"\x12" * 32,  # Unknown block root
            blocks[1].hash_tree_root,
            b"\x23" * 32,  # Unknown block root
            blocks[3].hash_tree_root,
        ]
        requested_blocks = await alice.request_recent_beacon_blocks(
            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)
コード例 #23
0
ファイル: test_block.py プロジェクト: s0b0lev/trinity
def test_block_is_not_genesis(sample_beacon_block_params):
    genesis_block = BeaconBlock(**sample_beacon_block_params)
    another_block = BeaconBlock.from_parent(genesis_block, FromBlockParams())
    assert genesis_block.is_genesis
    assert not another_block.is_genesis
コード例 #24
0
ファイル: test_block.py プロジェクト: s0b0lev/trinity
def test_defaults(sample_beacon_block_params):
    block = BeaconBlock(**sample_beacon_block_params)
    assert block.slot == sample_beacon_block_params['slot']
    assert block.is_genesis
コード例 #25
0
ファイル: test_req_resp.py プロジェクト: wschwab/trinity
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(
            slot=head_slot,
            parent_root=ZERO_HASH32,
            state_root=ZERO_HASH32,
            signature=EMPTY_SIGNATURE,
            body=BeaconBlockBody(),
        )

        # 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.copy(
            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.copy(finalized_checkpoint=new_checkpoint)
                config = state_machine.config

            return MockStateMachine()

        def get_head_state():
            return old_state.copy(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,
            )
コード例 #26
0
def test_defaults(sample_beacon_block_params):
    block = BeaconBlock(**sample_beacon_block_params)
    assert block.slot == sample_beacon_block_params['slot']
    assert len(block.body.custody_challenges) == 0