Exemple #1
0
def sign_block(state, block, proposer_index=None):
    assert state.slot <= block.slot

    if proposer_index is None:
        if block.slot == state.slot:
            proposer_index = get_beacon_proposer_index(state)
        else:
            if slot_to_epoch(state.slot) + 1 > slot_to_epoch(block.slot):
                print(
                    "warning: block slot far away, and no proposer index manually given."
                    " Signing block is slow due to transition for proposer index calculation."
                )
            # use stub state to get proposer index of future slot
            stub_state = deepcopy(state)
            state_transition_to(stub_state, block.slot)
            proposer_index = get_beacon_proposer_index(stub_state)

    privkey = privkeys[proposer_index]

    block.body.randao_reveal = bls_sign(
        privkey=privkey,
        message_hash=hash_tree_root(slot_to_epoch(block.slot)),
        domain=get_domain(
            state,
            message_epoch=slot_to_epoch(block.slot),
            domain_type=spec.DOMAIN_RANDAO,
        ))
    block.signature = bls_sign(message_hash=signing_root(block),
                               privkey=privkey,
                               domain=get_domain(state,
                                                 spec.DOMAIN_BEACON_PROPOSER,
                                                 slot_to_epoch(block.slot)))
Exemple #2
0
def sign_transfer(state, transfer, privkey):
    transfer.signature = bls_sign(message_hash=signing_root(transfer),
                                  privkey=privkey,
                                  domain=get_domain(
                                      state=state,
                                      domain_type=spec.DOMAIN_TRANSFER,
                                      message_epoch=get_current_epoch(state),
                                  ))
    return transfer
Exemple #3
0
def sign_voluntary_exit(state, voluntary_exit, privkey):
    voluntary_exit.signature = bls_sign(
        message_hash=signing_root(voluntary_exit),
        privkey=privkey,
        domain=get_domain(
            state=state,
            domain_type=spec.DOMAIN_VOLUNTARY_EXIT,
            message_epoch=voluntary_exit.epoch,
        )
    )
Exemple #4
0
def sign_block_header(state, header, privkey):
    domain = get_domain(
        state=state,
        domain_type=spec.DOMAIN_BEACON_PROPOSER,
    )
    header.signature = bls_sign(
        message_hash=signing_root(header),
        privkey=privkey,
        domain=domain,
    )
Exemple #5
0
def sign_deposit_data(state, deposit_data, privkey):
    signature = bls_sign(
        message_hash=signing_root(deposit_data),
        privkey=privkey,
        domain=get_domain(
            state,
            spec.DOMAIN_DEPOSIT,
        )
    )
    deposit_data.signature = signature
Exemple #6
0
def get_attestation_signature(state, attestation_data, privkey, custody_bit=0b0):
    message_hash = AttestationDataAndCustodyBit(
        data=attestation_data,
        custody_bit=custody_bit,
    ).hash_tree_root()

    return bls.sign(
        message_hash=message_hash,
        privkey=privkey,
        domain=get_domain(
            state=state,
            domain_type=spec.DOMAIN_ATTESTATION,
            message_epoch=slot_to_epoch(attestation_data.slot),
        )
    )
Exemple #7
0
def build_voluntary_exit(state, epoch, validator_index, privkey):
    voluntary_exit = VoluntaryExit(
        epoch=epoch,
        validator_index=validator_index,
    )
    voluntary_exit.signature = bls.sign(
        message_hash=signing_root(voluntary_exit),
        privkey=privkey,
        domain=get_domain(
            state=state,
            domain_type=spec.DOMAIN_VOLUNTARY_EXIT,
            message_epoch=epoch,
        ))

    return voluntary_exit
Exemple #8
0
def test_transfer(state):
    # overwrite default 0 to test
    spec.MAX_TRANSFERS = 1

    pre_state = deepcopy(state)
    current_epoch = get_current_epoch(pre_state)
    sender_index = get_active_validator_indices(pre_state, current_epoch)[-1]
    recipient_index = get_active_validator_indices(pre_state, current_epoch)[0]
    transfer_pubkey = pubkeys[-1]
    transfer_privkey = privkeys[-1]
    amount = get_balance(pre_state, sender_index)
    pre_transfer_recipient_balance = get_balance(pre_state, recipient_index)
    transfer = Transfer(
        sender=sender_index,
        recipient=recipient_index,
        amount=amount,
        fee=0,
        slot=pre_state.slot + 1,
        pubkey=transfer_pubkey,
    )
    transfer.signature = bls.sign(message_hash=signing_root(transfer),
                                  privkey=transfer_privkey,
                                  domain=get_domain(
                                      state=pre_state,
                                      domain_type=spec.DOMAIN_TRANSFER,
                                  ))

    # ensure withdrawal_credentials reproducable
    pre_state.validator_registry[sender_index].withdrawal_credentials = (
        spec.BLS_WITHDRAWAL_PREFIX_BYTE + hash(transfer_pubkey)[1:])
    # un-activate so validator can transfer
    pre_state.validator_registry[
        sender_index].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH

    post_state = deepcopy(pre_state)
    #
    # Add to state via block transition
    #
    block = build_empty_block_for_next_slot(post_state)
    block.body.transfers.append(transfer)
    state_transition(post_state, block)

    sender_balance = get_balance(post_state, sender_index)
    recipient_balance = get_balance(post_state, recipient_index)
    assert sender_balance == 0
    assert recipient_balance == pre_transfer_recipient_balance + amount

    return pre_state, [block], post_state
Exemple #9
0
def build_deposit_data(state, pubkey, privkey, amount):
    deposit_data = DepositData(
        pubkey=pubkey,
        # insecurely use pubkey as withdrawal key as well
        withdrawal_credentials=spec.BLS_WITHDRAWAL_PREFIX_BYTE +
        hash(pubkey)[1:],
        amount=amount,
    )
    signature = bls.sign(message_hash=signing_root(deposit_data),
                         privkey=privkey,
                         domain=get_domain(
                             state,
                             spec.DOMAIN_DEPOSIT,
                         ))
    deposit_data.signature = signature
    return deposit_data
Exemple #10
0
def build_deposit_data(state, pubkey: spec.BLSPubkey,
                       withdrawal_cred: spec.Bytes32, privkey: int,
                       amount: int):
    deposit_data = spec.DepositData(
        pubkey=pubkey,
        withdrawal_credentials=spec.BLS_WITHDRAWAL_PREFIX_BYTE +
        withdrawal_cred[1:],
        amount=amount,
    )
    deposit_data.proof_of_possession = bls.sign(
        message_hash=signing_root(deposit_data),
        privkey=privkey,
        domain=spec.get_domain(
            state,
            spec.get_current_epoch(state),
            spec.DOMAIN_DEPOSIT,
        ))
    return deposit_data
Exemple #11
0
def test_voluntary_exit(state):
    pre_state = deepcopy(state)
    validator_index = get_active_validator_indices(
        pre_state, get_current_epoch(pre_state))[-1]

    # move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow for exit
    pre_state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH

    post_state = deepcopy(pre_state)

    voluntary_exit = VoluntaryExit(
        epoch=get_current_epoch(pre_state),
        validator_index=validator_index,
    )
    voluntary_exit.signature = bls.sign(
        message_hash=signing_root(voluntary_exit),
        privkey=privkeys[validator_index],
        domain=get_domain(
            state=pre_state,
            domain_type=spec.DOMAIN_VOLUNTARY_EXIT,
        ))

    #
    # Add to state via block transition
    #
    initiate_exit_block = build_empty_block_for_next_slot(post_state)
    initiate_exit_block.body.voluntary_exits.append(voluntary_exit)
    state_transition(post_state, initiate_exit_block)

    assert post_state.validator_registry[
        validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH

    #
    # Process within epoch transition
    #
    exit_block = build_empty_block_for_next_slot(post_state)
    exit_block.slot += spec.SLOTS_PER_EPOCH
    state_transition(post_state, exit_block)

    assert post_state.validator_registry[
        validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH

    return pre_state, [initiate_exit_block, exit_block], post_state
Exemple #12
0
def test_voluntary_exit(state):
    validator_index = get_active_validator_indices(
        state,
        get_current_epoch(state)
    )[-1]

    # move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow for exit
    state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH

    yield 'pre', state

    voluntary_exit = VoluntaryExit(
        epoch=get_current_epoch(state),
        validator_index=validator_index,
    )
    voluntary_exit.signature = bls_sign(
        message_hash=signing_root(voluntary_exit),
        privkey=privkeys[validator_index],
        domain=get_domain(
            state=state,
            domain_type=spec.DOMAIN_VOLUNTARY_EXIT,
        )
    )

    # Add to state via block transition
    initiate_exit_block = build_empty_block_for_next_slot(state)
    initiate_exit_block.body.voluntary_exits.append(voluntary_exit)
    sign_block(state, initiate_exit_block)
    state_transition(state, initiate_exit_block)

    assert state.validator_registry[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH

    # Process within epoch transition
    exit_block = build_empty_block_for_next_slot(state)
    exit_block.slot += spec.SLOTS_PER_EPOCH
    sign_block(state, exit_block)
    state_transition(state, exit_block)

    yield 'blocks', [initiate_exit_block, exit_block], [spec.BeaconBlock]
    yield 'post', state

    assert state.validator_registry[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH
Exemple #13
0
def get_valid_transfer(state,
                       slot=None,
                       sender_index=None,
                       amount=None,
                       fee=None):
    if slot is None:
        slot = state.slot
    current_epoch = get_current_epoch(state)
    if sender_index is None:
        sender_index = get_active_validator_indices(state, current_epoch)[-1]
    recipient_index = get_active_validator_indices(state, current_epoch)[0]
    transfer_pubkey = pubkeys[-1]
    transfer_privkey = privkeys[-1]

    if fee is None:
        fee = get_balance(state, sender_index) // 32
    if amount is None:
        amount = get_balance(state, sender_index) - fee

    transfer = Transfer(
        sender=sender_index,
        recipient=recipient_index,
        amount=amount,
        fee=fee,
        slot=slot,
        pubkey=transfer_pubkey,
        signature=ZERO_HASH,
    )
    transfer.signature = bls.sign(message_hash=signing_root(transfer),
                                  privkey=transfer_privkey,
                                  domain=get_domain(
                                      state=state,
                                      domain_type=spec.DOMAIN_TRANSFER,
                                      message_epoch=get_current_epoch(state),
                                  ))

    # ensure withdrawal_credentials reproducable
    state.validator_registry[transfer.sender].withdrawal_credentials = (
        spec.BLS_WITHDRAWAL_PREFIX_BYTE + spec.hash(transfer.pubkey)[1:])

    return transfer
Exemple #14
0
def get_valid_proposer_slashing(state):
    current_epoch = get_current_epoch(state)
    validator_index = get_active_validator_indices(state, current_epoch)[-1]
    privkey = pubkey_to_privkey[
        state.validator_registry[validator_index].pubkey]
    slot = state.slot

    header_1 = BeaconBlockHeader(
        slot=slot,
        previous_block_root=ZERO_HASH,
        state_root=ZERO_HASH,
        block_body_root=ZERO_HASH,
    )
    header_2 = deepcopy(header_1)
    header_2.previous_block_root = b'\x02' * 32
    header_2.slot = slot + 1

    domain = get_domain(
        state=state,
        domain_type=spec.DOMAIN_BEACON_PROPOSER,
    )
    header_1.signature = bls.sign(
        message_hash=signing_root(header_1),
        privkey=privkey,
        domain=domain,
    )
    header_2.signature = bls.sign(
        message_hash=signing_root(header_2),
        privkey=privkey,
        domain=domain,
    )

    return ProposerSlashing(
        proposer_index=validator_index,
        header_1=header_1,
        header_2=header_2,
    )