The Deposit Contract inserts all deposits into a Merkle tree. According to the Beacon Chains spec, when a deposit is processed on the Beacon Chain, it must be verified that the deposit is indeed a valid leaf the in the Merkle tree. This is specified in process_deposit():

def process_deposit(state: BeaconState, deposit: Deposit) -> None:
    # Verify the Merkle branch
    assert is_valid_merkle_branch(
        depth=DEPOSIT_CONTRACT_TREE_DEPTH + 1,  # Add 1 for the List length mix-in

    # Deposits must be processed in order
    state.eth1_deposit_index += 1


I don't understand the point of this. If the Eth1 data was trusted, then validating the data seems unnecessary. On the other hand, if the Eth1 data is not trusted, then the above check does not seem to help, because then we also wouldn't be able to trust state.eth1_data.deposit_root, i.e., the Merkle root could conceivably be completely unrelated to the state of the actual Deposit Contract. Checking that some untrusted piece of data is in some untrusted Merkle tree does not seem to increase security in any way.

I feel I'm deeply misunderstanding something here.


1 Answer 1


The is_valid_merkle_branch() checks to ensure that it's not possible to fake a deposit in the process_deposit() function. The eth1data.deposit_root from the deposit contract has been agreed by the beacon chain and includes all pending deposits visible to the beacon chain. The deposit itself contains a Merkle proof that it is included in that root. The state.eth1_deposit_index counter ensures that deposits are processed in order. In short, the proposer provides leaf and branch, but neither index nor root.

  • I understand why Merkle trees are used in general, just not in the case of the Deposit Contract. I'm particular confused about the is_valid_merkle_branch() check in the process_deposit() function, because I don't understand what goal is achieved here.
    – DaviD.
    Sep 25, 2022 at 21:18
  • 1
    Oh, ok. I have revised my answer. Sep 25, 2022 at 21:46
  • Does this mean that each consensus client computes index and root itself and these data points can thus be trusted? For index this makes sense, because process_deposit() computes the new value of state.eth1_deposit_index by incrementing it. In the case of root this is where my confusion comes in, because it seems that it is never explicitly computed by the spec, it is just taken from the proposed block, which is why I thought it cannot be trusted. I guess a more fundamental question is: Do validators just execute the spec, or do they do more? Anyway, really appreciate your help!
    – DaviD.
    Sep 26, 2022 at 9:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.