示例#1
0
def test_get_aggregate_from_valid_committee_attestations(
        sample_attestation_params, privkeys, genesis_state, config):
    committee_size = 16
    empty_bitfield = get_empty_bitfield(committee_size)
    base_attestation = Attestation.create(**sample_attestation_params)
    attestations = []
    expected_bitfield = empty_bitfield

    for i in range(4, 16, 2):
        attestations.append(
            base_attestation.mset(
                "aggregation_bits",
                set_voted(empty_bitfield, i),
                "signature",
                sign_transaction(
                    object=base_attestation.data,
                    privkey=privkeys[i],
                    state=genesis_state,
                    slot=genesis_state.slot,
                    signature_domain=SignatureDomain.DOMAIN_BEACON_ATTESTER,
                    slots_per_epoch=config.SLOTS_PER_EPOCH,
                ),
            ))
        expected_bitfield = set_voted(expected_bitfield, i)

    aggregate_attestation = get_aggregate_from_valid_committee_attestations(
        attestations)

    assert aggregate_attestation.aggregation_bits == expected_bitfield
示例#2
0
def create_block_on_state(
    *,
    state: BeaconState,
    config: Eth2Config,
    state_machine: BaseBeaconStateMachine,
    signed_block_class: Type[BaseSignedBeaconBlock],
    parent_block: BaseBeaconBlock,
    slot: Slot,
    validator_index: ValidatorIndex,
    privkey: int,
    attestations: Sequence[Attestation],
    eth1_data: Eth1Data = None,
    deposits: Sequence[Deposit] = None,
    check_proposer_index: bool = True,
) -> SignedBeaconBlock:
    """
    Create a beacon block with the given parameters.
    """
    if check_proposer_index:
        validate_proposer_index(state, config, slot, validator_index)

    block_class = signed_block_class.block_class
    block = create_unsigned_block_on_state(
        state=state,
        config=config,
        block_class=block_class,
        parent_block=parent_block.message,
        slot=slot,
        attestations=attestations,
        eth1_data=eth1_data,
        deposits=deposits,
    )

    # Randao reveal
    randao_reveal = _generate_randao_reveal(privkey, slot, state, config)
    block = block.set("body", block.body.set("randao_reveal", randao_reveal))

    # Apply state transition to get state root
    signed_block = signed_block_class.create(message=block,
                                             signature=EMPTY_SIGNATURE)
    post_state, signed_block = state_machine.import_block(
        signed_block, state, check_proposer_signature=False)

    # Sign
    signature = sign_transaction(
        message_hash=signed_block.message.hash_tree_root,
        privkey=privkey,
        state=post_state,
        slot=slot,
        signature_domain=SignatureDomain.DOMAIN_BEACON_PROPOSER,
        slots_per_epoch=config.SLOTS_PER_EPOCH,
    )
    signed_block = signed_block.set("signature", signature)

    return signed_block
示例#3
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.
    """
    # Check proposer
    if check_proposer_index:
        validate_proposer_index(state, config, slot, validator_index)

    # Prepare block: slot and previous_block_root
    block = block_class.from_parent(
        parent_block=parent_block,
        block_params=FromBlockParams(slot=slot),
    )

    # TODO: Add more operations
    randao_reveal = _generate_randao_reveal(privkey, slot, state.fork, config)
    eth1_data = Eth1Data.create_empty_data()
    body = BeaconBlockBody.create_empty_body().copy(
        randao_reveal=randao_reveal,
        eth1_data=eth1_data,
        attestations=attestations,
    )

    block = block.copy(body=body, )

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

    # Sign
    # TODO make sure we use the correct signed_root
    signature = sign_transaction(
        message_hash=block.signed_root,
        privkey=privkey,
        fork=state.fork,
        slot=slot,
        signature_domain=SignatureDomain.DOMAIN_BEACON_BLOCK,
        slots_per_epoch=config.SLOTS_PER_EPOCH,
    )

    block = block.copy(signature=signature, )

    return block
示例#4
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
示例#5
0
def generate_randao_reveal(privkey: int, slot: Slot, state: BeaconState,
                           config: Eth2Config) -> BLSSignature:
    """
    Return the RANDAO reveal for the validator represented by ``privkey``.
    The current implementation requires a validator to provide the BLS signature
    over the SSZ-serialized epoch in which they are proposing a block.
    """
    epoch = compute_epoch_at_slot(slot, config.SLOTS_PER_EPOCH)

    randao_reveal = sign_transaction(
        object=SerializableUint64(epoch),
        privkey=privkey,
        state=state,
        slot=slot,
        signature_domain=SignatureDomain.DOMAIN_RANDAO,
        slots_per_epoch=config.SLOTS_PER_EPOCH,
    )
    return randao_reveal
示例#6
0
def _generate_randao_reveal(privkey: int, slot: Slot, fork: Fork,
                            config: Eth2Config) -> BLSSignature:
    """
    Return the RANDAO reveal for the validator represented by ``privkey``.
    The current implementation requires a validator to provide the BLS signature
    over the SSZ-serialized epoch in which they are proposing a block.
    """
    epoch = slot_to_epoch(slot, config.SLOTS_PER_EPOCH)

    message_hash = Hash32(epoch.to_bytes(32, byteorder='little'))

    randao_reveal = sign_transaction(
        message_hash=message_hash,
        privkey=privkey,
        fork=fork,
        slot=slot,
        signature_domain=SignatureDomain.DOMAIN_RANDAO,
        slots_per_epoch=config.SLOTS_PER_EPOCH,
    )
    return randao_reveal
示例#7
0
def _generate_randao_reveal(privkey: int, slot: Slot, state: BeaconState,
                            config: Eth2Config) -> BLSSignature:
    """
    Return the RANDAO reveal for the validator represented by ``privkey``.
    The current implementation requires a validator to provide the BLS signature
    over the SSZ-serialized epoch in which they are proposing a block.
    """
    epoch = compute_epoch_of_slot(slot, config.SLOTS_PER_EPOCH)

    message_hash = ssz.get_hash_tree_root(epoch, sedes=ssz.sedes.uint64)

    randao_reveal = sign_transaction(
        message_hash=message_hash,
        privkey=privkey,
        state=state,
        slot=slot,
        signature_domain=SignatureDomain.DOMAIN_RANDAO,
        slots_per_epoch=config.SLOTS_PER_EPOCH,
    )
    return randao_reveal
def create_block_on_state(
        *,
        state: BeaconState,
        config: BeaconConfig,
        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.
    """
    # Check proposer
    if check_proposer_index:
        validate_proposer_index(state, config, slot, validator_index)

    # Prepare block: slot and parent_root
    block = block_class.from_parent(
        parent_block=parent_block,
        block_params=FromBlockParams(slot=slot),
    )

    # TODO: Add more operations
    randao_reveal = EMPTY_SIGNATURE
    eth1_data = Eth1Data.create_empty_data()
    body = BeaconBlockBody.create_empty_body().copy(
        attestations=attestations, )

    block = block.copy(
        randao_reveal=randao_reveal,
        eth1_data=eth1_data,
        body=body,
    )

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

    # Sign
    empty_signature_block_root = block.block_without_signature_root
    proposal_root = Proposal(
        slot,
        config.BEACON_CHAIN_SHARD_NUMBER,
        empty_signature_block_root,
    ).root

    signature = sign_transaction(
        message_hash=proposal_root,
        privkey=privkey,
        fork=state.fork,
        slot=slot,
        signature_domain=SignatureDomain.DOMAIN_PROPOSAL,
        slots_per_epoch=config.SLOTS_PER_EPOCH,
    )

    block = block.copy(signature=signature, )

    return block