def create_mock_genesis_validator_deposits(num_validators, deposit_data_leaves): deposit_timestamp = 0 proof_of_possession = b'\x33' * 96 deposit_data_list = [] for i in range(num_validators): pubkey = pubkeys_list[i] deposit_data = DepositData( amount=spec.MAX_DEPOSIT_AMOUNT, timestamp=deposit_timestamp, deposit_input=DepositInput( pubkey=pubkey, # insecurely use pubkey as withdrawal key as well withdrawal_credentials=spec.BLS_WITHDRAWAL_PREFIX_BYTE + hash(pubkey)[1:], proof_of_possession=proof_of_possession, ), ) item = hash(deposit_data.serialize()) 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, deposit_data=deposit_data_list[i] )) return genesis_validator_deposits, root
def test_deposit_in_block(state, deposit_data_leaves, pubkeys, privkeys): pre_state = deepcopy(state) test_deposit_data_leaves = deepcopy(deposit_data_leaves) index = len(test_deposit_data_leaves) pubkey = pubkeys[index] privkey = privkeys[index] deposit_data = build_deposit_data(pre_state, pubkey, privkey, spec.MAX_DEPOSIT_AMOUNT) item = hash(deposit_data.serialize()) test_deposit_data_leaves.append(item) tree = calc_merkle_tree_from_leaves(tuple(test_deposit_data_leaves)) root = get_merkle_root((tuple(test_deposit_data_leaves))) proof = list(get_merkle_proof(tree, item_index=index)) assert verify_merkle_branch(item, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH, index, root) deposit = Deposit( proof=list(proof), index=index, deposit_data=deposit_data, ) pre_state.latest_eth1_data.deposit_root = root post_state = deepcopy(pre_state) block = build_empty_block_for_next_slot(post_state) block.body.deposits.append(deposit) state_transition(post_state, block) assert len(post_state.validator_registry) == len(state.validator_registry) + 1 assert len(post_state.validator_balances) == len(state.validator_balances) + 1 assert post_state.validator_registry[index].pubkey == pubkeys[index] return pre_state, [block], post_state
def test_transfer(state, pubkeys, privkeys): pre_state = deepcopy(state) current_epoch = get_current_epoch(pre_state) sender_index = get_active_validator_indices(pre_state.validator_registry, current_epoch)[-1] recipient_index = get_active_validator_indices(pre_state.validator_registry, current_epoch)[0] transfer_pubkey = pubkeys[-1] transfer_privkey = privkeys[-1] amount = pre_state.validator_balances[sender_index] pre_transfer_recipient_balance = pre_state.validator_balances[recipient_index] transfer = Transfer( sender=sender_index, recipient=recipient_index, amount=amount, fee=0, slot=pre_state.slot + 1, pubkey=transfer_pubkey, signature=EMPTY_SIGNATURE, ) transfer.signature = bls.sign( message_hash=signed_root(transfer), privkey=transfer_privkey, domain=get_domain( fork=pre_state.fork, epoch=get_current_epoch(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_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 = post_state.validator_balances[sender_index] recipient_balance = post_state.validator_balances[recipient_index] assert sender_balance == 0 assert recipient_balance == pre_transfer_recipient_balance + amount return pre_state, [block], post_state
def build_deposit(state, deposit_data_leaves, pubkey, privkey, amount): deposit_data = build_deposit_data(state, pubkey, privkey, amount) item = hash(deposit_data.serialize()) index = len(deposit_data_leaves) 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=index)) assert verify_merkle_branch(item, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH, index, root) deposit = Deposit( proof=list(proof), index=index, deposit_data=deposit_data, ) return deposit, root, deposit_data_leaves
def build_deposit_data(state, pubkey, privkey, amount): deposit_input = DepositInput( pubkey=pubkey, # insecurely use pubkey as withdrawal key as well withdrawal_credentials=spec.BLS_WITHDRAWAL_PREFIX_BYTE + hash(pubkey)[1:], proof_of_possession=EMPTY_SIGNATURE, ) proof_of_possession = bls.sign(message_hash=signed_root(deposit_input), privkey=privkey, domain=get_domain( state.fork, get_current_epoch(state), spec.DOMAIN_DEPOSIT, )) deposit_input.proof_of_possession = proof_of_possession deposit_data = DepositData( amount=amount, timestamp=0, deposit_input=deposit_input, ) return deposit_data
def test_deposit_top_up(state): pre_state = deepcopy(state) test_deposit_data_leaves = [ZERO_HASH] * len(pre_state.validator_registry) validator_index = 0 amount = spec.MAX_DEPOSIT_AMOUNT // 4 pubkey = pubkeys[validator_index] privkey = privkeys[validator_index] deposit_data = build_deposit_data(pre_state, pubkey, privkey, amount) merkle_index = len(test_deposit_data_leaves) item = hash(deposit_data.serialize()) test_deposit_data_leaves.append(item) tree = calc_merkle_tree_from_leaves(tuple(test_deposit_data_leaves)) root = get_merkle_root((tuple(test_deposit_data_leaves))) proof = list(get_merkle_proof(tree, item_index=merkle_index)) assert verify_merkle_branch(item, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH, merkle_index, root) deposit = Deposit( proof=list(proof), index=merkle_index, deposit_data=deposit_data, ) pre_state.latest_eth1_data.deposit_root = root block = build_empty_block_for_next_slot(pre_state) block.body.deposits.append(deposit) pre_balance = pre_state.validator_balances[validator_index] post_state = deepcopy(pre_state) state_transition(post_state, block) assert len(post_state.validator_registry) == len(pre_state.validator_registry) assert len(post_state.validator_balances) == len(pre_state.validator_balances) assert post_state.validator_balances[validator_index] == pre_balance + amount return pre_state, [block], post_state