Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of Nimbus eth_getProof RPC Endpoint. #1960

Merged
merged 8 commits into from
Jan 9, 2024

Conversation

bhartnett
Copy link
Contributor

@bhartnett bhartnett commented Jan 8, 2024

This PR includes changes to implement the eth_getProof RPC endpoint implemented as follows:

  • The account and storage proofs contain an array of RLP encoded merkle patrica trie nodes starting from the root node, following the path of the trie key until reaching the leaf node. The leaf node is also included as the final node in the proof.
  • When getting an account that doesn't exist in the state we return values set with defaults. Balance, nonce, codeHash and storageHash will be zero in this case.
  • When returning an account that doesn't exist in the state we also return a proof that proves the absence of the value in the state. In this case the proof will contain all nodes that do exist following the path of the provided key.
  • If an existing account is not a contract account then the code hash will be equal to the keccak256 hash of an empty string.
  • If an account has no storage slots populated then it will have a storageRoot equal to the keccak256 hash of the empty root node.
  • If the slots array parameter is empty then we return an empty list for the storageProof.
  • If we supply a non empty array of slots as a parameter then we return a storage proof for each non existent slot with the slot value equal to zero. These proofs will prove that the slot doesn't exist in the state. If the storage state is empty then the proof will be empty. If the storage state is not empty then the proof will contain all rlp nodes following the path of the slot key.

Here is the link to the spec: https://eips.ethereum.org/EIPS/eip-1186. Note that the spec is in the 'Stagnant' state so it was never moved to final.

@bhartnett bhartnett requested review from jangko and kdeme January 8, 2024 08:06
@@ -1,5 +1,5 @@
# Nimbus
# Copyright (c) 2023 Status Research & Development GmbH
# Copyright (c) 2024 Status Research & Development GmbH
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the correct way to update the copyright notice? Or should it be 2023-2024?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2023-2024

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I'll update in that case.

rootHash
rootHash,
getAccountProof,
getStorageProof
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exporting the new proof procs to be used with the ReadOnlyStateDB type.


# This implementation of getBranch on the CoreDbPhkRef type is a temporary solution
# which can be removed once we get an equivient proc defined on the CoreDbPhkRef type
# in the db layer.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code was copied from the HexaryTrie library in order to implement getBranch on the CoreDbPhkRef type.

@@ -249,6 +253,29 @@ proc isDeadAccount*(db: AccountStateDB, address: EthAddress): bool =
else:
result = true

proc removeEmptyRlpNode(branch: var seq[MptNodeRlpBytes]) =
if branch.len() == 1 and branch[0] == emptyRlp:
branch.del(0)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The getBranch code returns a single node with a value of emptyRlp (zero encoded as rlp) if the trie state is empty. We remove this because this isn't a valid proof and causes the proof verification to fail. Also Geth returns an empty list in this case so we do the same.

ProofResponse(
address: w3Addr(address),
accountProof: seq[RlpEncodedBytes](accountProof),
storageProof: storage)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We return zero values (default values) for the account if the account doesn't exist, including the codeHash and storageHash.

@jangko
Copy link
Contributor

jangko commented Jan 8, 2024

looks good to me

@kdeme kdeme requested a review from mjfh January 8, 2024 11:18
@bhartnett
Copy link
Contributor Author

looks good to me

Great. Planning to merge it after I update the copyright notices.

@bhartnett bhartnett merged commit 79c6bdc into master Jan 9, 2024
20 of 21 checks passed
@bhartnett bhartnett deleted the nimbus-eth-getproof-rpc-endpoint-1944 branch January 9, 2024 02:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants