def make_deposit_tree_and_root( list_deposit_data: Sequence[DepositData], ) -> Tuple[MerkleTree, Hash32]: deposit_data_leaves = [data.hash_tree_root for data in list_deposit_data] length_mix_in = len(list_deposit_data).to_bytes(32, byteorder="little") tree = calc_merkle_tree_from_leaves(deposit_data_leaves) tree_root = get_root(tree) tree_root_with_mix_in = hash_eth2(tree_root + length_mix_in) return tree, tree_root_with_mix_in
def create_mock_deposits_and_root( pubkeys: Sequence[BLSPubkey], keymap: Dict[BLSPubkey, int], config: Eth2Config, withdrawal_credentials: Sequence[Hash32] = None, leaves: Sequence[Hash32] = None, ) -> Tuple[Tuple[Deposit, ...], Hash32]: """ Creates as many new deposits as there are keys in ``pubkeys``. Optionally provide corresponding ``withdrawal_credentials`` to include those. Optionally provide the prefix in the sequence of leaves leading up to the new deposits made by this function to get the correct updated root. If ``leaves`` is empty, this function simulates the genesis deposit tree calculation. """ if not withdrawal_credentials: withdrawal_credentials = tuple( Hash32(b"\x22" * 32) for _ in range(len(pubkeys))) else: assert len(withdrawal_credentials) == len(pubkeys) if not leaves: leaves = tuple() deposit_datas = tuple() # type: Tuple[DepositData, ...] deposit_data_leaves = cast(Tuple[Hash32, ...], leaves) # type: Tuple[Hash32, ...] for key, credentials in zip(pubkeys, withdrawal_credentials): privkey = keymap[key] deposit_data = create_mock_deposit_data( config=config, pubkey=key, privkey=privkey, withdrawal_credentials=credentials, ) item = deposit_data.hash_tree_root deposit_data_leaves += (item, ) deposit_datas += (deposit_data, ) deposits: Tuple[Deposit, ...] = tuple() for index, data in enumerate(deposit_datas): length_mix_in = Hash32((index + 1).to_bytes(32, byteorder="little")) tree = calc_merkle_tree_from_leaves(deposit_data_leaves[:index + 1]) deposit = Deposit( proof=(get_merkle_proof(tree, item_index=index) + (length_mix_in, )), data=data, ) deposits += (deposit, ) if len(deposit_data_leaves) > 0: tree_root = get_root(tree) return deposits, hash_eth2(tree_root + length_mix_in) else: return tuple(), ZERO_HASH32
def create_mock_deposits_and_root( pubkeys: Sequence[BLSPubkey], keymap: Dict[BLSPubkey, int], config: Eth2Config, withdrawal_credentials: Sequence[Hash32] = None, leaves: Sequence[Hash32] = None) -> Tuple[Tuple[Deposit, ...], Hash32]: """ Creates as many new deposits as there are keys in ``pubkeys``. Optionally provide corresponding ``withdrawal_credentials`` to include those. Optionally provide the prefix in the sequence of leaves leading up to the new deposits made by this function to get the correct updated root. If ``leaves`` is empty, this function simulates the genesis deposit tree calculation. """ if not withdrawal_credentials: withdrawal_credentials = tuple( Hash32(b'\x22' * 32) for _ in range(len(pubkeys))) else: assert len(withdrawal_credentials) == len(pubkeys) if not leaves: leaves = tuple() deposit_datas = tuple() # type: Tuple[DepositData, ...] deposit_data_leaves = cast(Tuple[Hash32, ...], leaves) # type: Tuple[Hash32, ...] for key, credentials in zip(pubkeys, withdrawal_credentials): privkey = keymap[key] deposit_data = create_mock_deposit_data( config=config, pubkey=key, privkey=privkey, withdrawal_credentials=credentials, ) item = deposit_data.root deposit_data_leaves += (item, ) deposit_datas += (deposit_data, ) tree = calc_merkle_tree_from_leaves(deposit_data_leaves) deposits = tuple( Deposit( proof=get_merkle_proof(tree, item_index=i), data=data, ) for i, data in enumerate(deposit_datas)) return deposits, get_root(tree)
def test_merkle_root_and_proofs(items, expected_root): tree = calc_merkle_tree(items) assert get_root(tree) == expected_root for index in range(len(items)): item = items[index] proof = get_merkle_proof(tree, index) assert verify_merkle_proof(expected_root, hash_eth2(item), index, proof) assert not verify_merkle_proof(b"\x32" * 32, hash_eth2(item), index, proof) assert not verify_merkle_proof(expected_root, hash_eth2(b"\x32" * 32), index, proof) if len(items) > 1: assert not verify_merkle_proof(expected_root, hash_eth2(item), (index + 1) % len(items), proof) for replaced_index in range(len(proof)): altered_proof = proof[:replaced_index] + ( b"\x32" * 32, ) + proof[replaced_index + 1:] assert not verify_merkle_proof(expected_root, hash_eth2(item), index, altered_proof)