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 get_valid_custody_response(spec, state, bit_challenge, custody_data, challenge_index, invalid_chunk_bit=False): chunks = custody_chunkify(spec, custody_data) chunk_index = len(chunks) - 1 chunk_bit = spec.get_custody_chunk_bit(bit_challenge.responder_key, chunks[chunk_index]) while chunk_bit == bit_challenge.chunk_bits[ chunk_index] ^ invalid_chunk_bit: chunk_index -= 1 chunk_bit = spec.get_custody_chunk_bit(bit_challenge.responder_key, chunks[chunk_index]) chunks_hash_tree_roots = [ hash_tree_root(ByteVector[spec.BYTES_PER_CUSTODY_CHUNK](chunk)) for chunk in chunks ] chunks_hash_tree_roots += [ hash_tree_root(ByteVector[spec.BYTES_PER_CUSTODY_CHUNK]( b"\0" * spec.BYTES_PER_CUSTODY_CHUNK)) for i in range(2**spec.ceillog2(len(chunks)) - len(chunks)) ] data_tree = get_merkle_tree(chunks_hash_tree_roots) data_branch = get_merkle_proof(data_tree, chunk_index) bitlist_chunk_index = chunk_index // BYTES_PER_CHUNK bitlist_chunks = chunkify(pack(bit_challenge.chunk_bits)) bitlist_tree = get_merkle_tree(bitlist_chunks, pad_to=spec.MAX_CUSTODY_CHUNKS // 256) bitlist_chunk_branch = get_merkle_proof(bitlist_tree, chunk_index // 256) + \ [len(bit_challenge.chunk_bits).to_bytes(32, "little")] bitlist_chunk_index = chunk_index // 256 chunk_bits_leaf = Bitvector[256]( bit_challenge.chunk_bits[bitlist_chunk_index * 256:(bitlist_chunk_index + 1) * 256]) return spec.CustodyResponse( challenge_index=challenge_index, chunk_index=chunk_index, chunk=ByteVector[spec.BYTES_PER_CUSTODY_CHUNK](chunks[chunk_index]), data_branch=data_branch, chunk_bits_branch=bitlist_chunk_branch, chunk_bits_leaf=chunk_bits_leaf, )
def build_deposit(spec, state, deposit_data_list, pubkey, privkey, amount, withdrawal_credentials, signed): deposit_data = build_deposit_data(spec, pubkey, privkey, amount, withdrawal_credentials, state=state, signed=signed) index = len(deposit_data_list) deposit_data_list.append(deposit_data) root = hash_tree_root( List[spec.DepositData, 2**spec.DEPOSIT_CONTRACT_TREE_DEPTH](*deposit_data_list)) tree = calc_merkle_tree_from_leaves( tuple([d.hash_tree_root() for d in deposit_data_list])) proof = list(get_merkle_proof( tree, item_index=index)) + [(index + 1).to_bytes(32, 'little')] leaf = deposit_data.hash_tree_root() assert spec.is_valid_merkle_branch(leaf, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH + 1, index, root) deposit = spec.Deposit(proof=proof, data=deposit_data) return deposit, root, deposit_data_list
def create_deposits(pubkeys: List[spec.BLSPubkey], withdrawal_cred: List[spec.Bytes32]) -> List[spec.Deposit]: # Mock proof of possession proof_of_possession = b'\x33' * 96 deposit_data = [ spec.DepositData( pubkey=pubkeys[i], withdrawal_credentials=spec.BLS_WITHDRAWAL_PREFIX_BYTE + withdrawal_cred[i][1:], amount=spec.MAX_EFFECTIVE_BALANCE, proof_of_possession=proof_of_possession, ) for i in range(len(pubkeys)) ] # Fill tree with existing deposits deposit_data_leaves = [data.hash_tree_root() for data in deposit_data] tree = calc_merkle_tree_from_leaves(tuple(deposit_data_leaves)) return [ spec.Deposit(proof=list(get_merkle_proof(tree, item_index=i)), index=i, data=deposit_data[i]) for i in range(len(deposit_data)) ]
def build_deposit(spec, state, deposit_data_leaves, pubkey, privkey, amount, withdrawal_credentials, signed): deposit_data = build_deposit_data(spec, state, pubkey, privkey, amount, withdrawal_credentials, signed) item = deposit_data.hash_tree_root() 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 spec.verify_merkle_branch(item, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH, index, root) deposit = spec.Deposit( proof=list(proof), index=index, data=deposit_data, ) return deposit, root, deposit_data_leaves
def deposit_from_context(spec, deposit_data_list, index): deposit_data = deposit_data_list[index] root = hash_tree_root(List[spec.DepositData, 2**spec.DEPOSIT_CONTRACT_TREE_DEPTH](*deposit_data_list)) tree = calc_merkle_tree_from_leaves(tuple([d.hash_tree_root() for d in deposit_data_list])) proof = list(get_merkle_proof(tree, item_index=index, tree_len=32)) + [(index + 1).to_bytes(32, 'little')] leaf = deposit_data.hash_tree_root() assert spec.is_valid_merkle_branch(leaf, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH + 1, index, root) deposit = spec.Deposit(proof=proof, data=deposit_data) return deposit, root, deposit_data_list
def get_valid_custody_response(spec, state, bit_challenge, custody_data, challenge_index, invalid_chunk_bit=False): chunks = custody_chunkify(spec, custody_data) chunk_index = len(chunks) - 1 chunk_bit = spec.get_custody_chunk_bit(bit_challenge.responder_key, chunks[chunk_index]) while chunk_bit == bit_challenge.chunk_bits[ chunk_index] ^ invalid_chunk_bit: chunk_index -= 1 chunk_bit = spec.get_custody_chunk_bit(bit_challenge.responder_key, chunks[chunk_index]) chunks_hash_tree_roots = [ hash_tree_root(ByteVector[spec.BYTES_PER_CUSTODY_CHUNK](chunk)) for chunk in chunks ] chunks_hash_tree_roots += [ hash_tree_root(ByteVector[spec.BYTES_PER_CUSTODY_CHUNK]( b"\0" * spec.BYTES_PER_CUSTODY_CHUNK)) for i in range(2**spec.ceillog2(len(chunks)) - len(chunks)) ] data_tree = get_merkle_tree(chunks_hash_tree_roots) data_branch = get_merkle_proof(data_tree, chunk_index) bitlist_chunk_index = chunk_index // BYTES_PER_CHUNK print(bitlist_chunk_index) bitlist_chunk_nodes = pack_bits_to_chunks(bit_challenge.chunk_bits) bitlist_tree = subtree_fill_to_contents(bitlist_chunk_nodes, get_depth(spec.MAX_CUSTODY_CHUNKS)) print(bitlist_tree) bitlist_chunk_branch = None # TODO; extract proof from merkle tree bitlist_chunk_index = chunk_index // 256 chunk_bits_leaf = Bitvector[256]( bit_challenge.chunk_bits[bitlist_chunk_index * 256:(bitlist_chunk_index + 1) * 256]) return spec.CustodyResponse( challenge_index=challenge_index, chunk_index=chunk_index, chunk=ByteVector[spec.BYTES_PER_CUSTODY_CHUNK](chunks[chunk_index]), data_branch=data_branch, chunk_bits_branch=bitlist_chunk_branch, chunk_bits_leaf=chunk_bits_leaf, )
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_EFFECTIVE_BALANCE // 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 = deposit_data.hash_tree_root() 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, data=deposit_data, ) pre_state.latest_eth1_data.deposit_root = root pre_state.latest_eth1_data.deposit_count = len(test_deposit_data_leaves) block = build_empty_block_for_next_slot(pre_state) block.body.deposits.append(deposit) pre_balance = get_balance(pre_state, 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.balances) == len(pre_state.balances) assert get_balance(post_state, validator_index) == pre_balance + amount return pre_state, [block], post_state
def build_deposit(state, deposit_data_leaves: List[spec.Bytes32], pubkey: spec.BLSPubkey, withdrawal_cred: spec.Bytes32, privkey: int, amount: int) -> spec.Deposit: deposit_data = build_deposit_data(state, pubkey, withdrawal_cred, privkey, amount) item = deposit_data.hash_tree_root() index = len(deposit_data_leaves) deposit_data_leaves.append(item) tree = calc_merkle_tree_from_leaves(tuple(deposit_data_leaves)) proof = list(get_merkle_proof(tree, item_index=index)) deposit = spec.Deposit( proof=list(proof), index=index, data=deposit_data, ) assert spec.verify_merkle_branch( item, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH, index, get_merkle_root(tuple(deposit_data_leaves))) return deposit