def create_mock_genesis_validator_deposits(num_validators, deposit_data_leaves=None): if not deposit_data_leaves: deposit_data_leaves = [] signature = b'\x33' * 96 deposit_data_list = [] for i in range(num_validators): pubkey = pubkeys[i] deposit_data = DepositData( pubkey=pubkey, # insecurely use pubkey as withdrawal key as well withdrawal_credentials=spec.BLS_WITHDRAWAL_PREFIX_BYTE + hash(pubkey)[1:], amount=spec.MAX_EFFECTIVE_BALANCE, signature=signature, ) item = deposit_data.hash_tree_root() deposit_data_leaves.append(item) tree = calc_merkle_tree_from_leaves(tuple(deposit_data_leaves)) root = get_merkle_root((tuple(deposit_data_leaves))) proof = list(get_merkle_proof(tree, item_index=i)) assert verify_merkle_branch(item, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH, i, root) deposit_data_list.append(deposit_data) genesis_validator_deposits = [] for i in range(num_validators): genesis_validator_deposits.append(Deposit( proof=list(get_merkle_proof(tree, item_index=i)), index=i, data=deposit_data_list[i] )) return genesis_validator_deposits, root
def shuffling_test_cases(): for seed in [ spec.hash(spec.int_to_bytes4(seed_init_value)) for seed_init_value in range(30) ]: for count in [0, 1, 2, 3, 5, 10, 33, 100, 1000]: yield shuffling_case(seed, count)
def shuffling_test_cases(): for seed in [ spec.hash(seed_init_value.to_bytes(length=4, byteorder='little')) for seed_init_value in range(30) ]: for count in [0, 1, 2, 3, 5, 10, 33, 100, 1000, 9999]: yield shuffling_case(seed, count)
def calc_beacon_proposer_index(state: BeaconState, slot: spec.Slot) -> spec.ValidatorIndex: epoch = spec.compute_epoch_at_slot(slot) seed = spec.hash( spec.get_seed(state, epoch, spec.DOMAIN_BEACON_PROPOSER) + spec.int_to_bytes(state.slot, length=8)) indices = spec.get_active_validator_indices(state, epoch) return spec.compute_proposer_index(state, indices, seed)
def build_deposit_data(state, pubkey, privkey, amount, signed=False): deposit_data = DepositData( pubkey=pubkey, # insecurely use pubkey as withdrawal key as well withdrawal_credentials=spec.BLS_WITHDRAWAL_PREFIX_BYTE + spec.hash(pubkey)[1:], amount=amount, ) if signed: sign_deposit_data(state, deposit_data, privkey) return deposit_data
def build_mock_validator(i: int, balance: int): pubkey = pubkeys[i] # insecurely use pubkey as withdrawal key as well withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX_BYTE + spec.hash( pubkey)[1:] return spec.Validator( pubkey=pubkeys[i], withdrawal_credentials=withdrawal_credentials, activation_eligibility_epoch=spec.FAR_FUTURE_EPOCH, activation_epoch=spec.FAR_FUTURE_EPOCH, exit_epoch=spec.FAR_FUTURE_EPOCH, withdrawable_epoch=spec.FAR_FUTURE_EPOCH, effective_balance=min( balance - balance % spec.EFFECTIVE_BALANCE_INCREMENT, spec.MAX_EFFECTIVE_BALANCE))
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
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
def test_invalid_withdrawal_credentials_top_up(state): validator_index = 0 amount = spec.MAX_EFFECTIVE_BALANCE // 4 withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX_BYTE + spec.hash( b"junk")[1:] deposit = prepare_state_and_deposit( state, validator_index, amount, withdrawal_credentials=withdrawal_credentials, ) # inconsistent withdrawal credentials, in top-ups, are allowed! yield from run_deposit_processing(state, deposit, validator_index, valid=True, effective=True)
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
def get_valid_transfer(state, slot=None, sender_index=None, amount=None, fee=None, signed=False): 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, ) if signed: sign_transfer(state, transfer, transfer_privkey) # ensure withdrawal_credentials reproducible state.validator_registry[transfer.sender].withdrawal_credentials = ( spec.BLS_WITHDRAWAL_PREFIX_BYTE + spec.hash(transfer.pubkey)[1:]) return transfer
from py_ecc import bls from eth2spec.phase0.spec import hash privkeys = list(range(1, 101)) pubkeys = [bls.privtopub(k) for k in privkeys] # Insecure, but easier to follow withdrawal_creds = [hash(bls.privtopub(k)) for k in privkeys]