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

Inconsistent debug_storageRangeAt behavior #14186

Open
Wollac opened this issue Mar 17, 2025 · 9 comments
Open

Inconsistent debug_storageRangeAt behavior #14186

Wollac opened this issue Mar 17, 2025 · 9 comments
Assignees

Comments

@Wollac
Copy link

Wollac commented Mar 17, 2025

System information

  • Erigon version: v3.0.0-rc.3
  • OS & Version: Linux
  • Chain/Network: Ethereum

Expected behaviour

The debug_accountRange RPC call should be consistent with Geth and behave as follows:

  • It requires six parameters:
    1. blockNrOrHash
    2. start
    3. maxResults
    4. nocode
    5. nostorage
    6. incompletes
  • The start parameter is the hashed address (i.e. its hexadecimal representation).
  • Accounts are returned in an order sorted by their hashed address (i.e. the key in the MPT).
  • Each account entry includes not only the account details but also the corresponding address and key (which is the hash of the address).

This behaviour appears to be related to #12726.

For example, executing the following command on Geth:

curl -X POST -H "Content-Type: application/json" \
  --data '{"method":"debug_accountRange","params":["latest","",3,true,true,true],"id":1,"jsonrpc":"2.0"}'

returns a response similar to:

{
  "accounts": {
    "0xBb0588062f133b31d4665E10C145888850CB686C": {
      "balance": "0",
      "nonce": 1,
      "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
      "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
      "address": "0xbb0588062f133b31d4665e10c145888850cb686c",
      "key": "0x01f9eab6ce456de98d44b5351258dfc60630594a62e80f0c82744c0df9b848cc"
    },
    "pre(0x005e54f1867fd030f90673b8b625ac8f0656e44a88cfc0b3af3e3f3c3d486960)": {
      "balance": "1",
      "nonce": 0,
      "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
      "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
      "key": "0x005e54f1867fd030f90673b8b625ac8f0656e44a88cfc0b3af3e3f3c3d486960"
    },
    "pre(0x021fe3360ba8c02e194f8e7facdeb9088b3cf433b6498bd6900d50df0266ffe3)": {
      "balance": "1",
      "nonce": 0,
      "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
      "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
      "key": "0x021fe3360ba8c02e194f8e7facdeb9088b3cf433b6498bd6900d50df0266ffe3"
    }
  }
}

In this example,
keccak(0xbb0588062f133b31d4665e10c145888850cb686c) = 0x01f9eab6ce456de98d44b5351258dfc60630594a62e80f0c82744c0df9b848cc
which is the closest such hash to the zero hash.
If the incompletes flag is set to true, Geth will also return accounts from the MPT for which it does not know the address (denoted by pre(...) in the map key).

Actual behaviour

When calling:

curl -X POST -H "Content-Type: application/json" \
  --data '{"method":"debug_accountRange","params":["latest","",3,true,true],"id":1,"jsonrpc":"2.0"}' 

on Erigon, the response is similar to:

"accounts": {
  "0x0000000000000000000000000000000000000000": {
    "balance": "1",
    "nonce": 0,
    "root": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
  },
  "0x0000000000000000000000000000000000000001": {
    "balance": "1",
    "nonce": 0,
    "root": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
  },
  "0x0000000000000000000000000000000000000002": {
    "balance": "1",
    "nonce": 0,
    "root": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
  }
}

Here, Erigon returns accounts starting with the address closest to zero, and the additional details (such as the actual account address and its corresponding key) are missing.

Steps to reproduce the behaviour

  1. Run Erigon (version v3.0.0-rc.3) on your system.
  2. Execute the provided curl command with the parameters:
    • On Geth: include all six parameters.
    • On Erigon: note that the command only uses five parameters.
  3. Observe the difference in the order and content of returned accounts.

See the Erigon command example above for further details.

@Giulio2002
Copy link
Contributor

@AskAlexSharov this seems a minor issue

@AskAlexSharov
Copy link
Collaborator

@Wollac Erigon doesn't store hashed state (where keys are hashed). So, we can't iterate by hashed state keys in sorted order. Can only iterate by preimages (plain state). and in debug_accountRange seems we also only support non-hashed keys (as start argument).

Deep reason is: actually Ethereum blocks execution doesn't require hashed state - and Erigon executing blocks on plain state. "Hashed state" only exists in Merkle tree root calculation spec and we using it only there.

@AskAlexSharov
Copy link
Collaborator

hmm... we of-course can hack empty key for compatibility... why not... let me take a look.

@AskAlexSharov
Copy link
Collaborator

hmm... we of-course can hack empty key for compatibility... why not... let me take a look.

but no. order will not match anyway - even if we start from same key as geth.

@AskAlexSharov
Copy link
Collaborator

so, will not fix. but added this issue as known corner case: #14219

@Wollac what do you think?

@Giulio2002 Giulio2002 closed this as not planned Won't fix, can't repro, duplicate, stale Mar 19, 2025
@Giulio2002
Copy link
Contributor

@awskii do you think we can do this by looking at commitment.kv potentially?

@Wollac
Copy link
Author

Wollac commented Mar 21, 2025

@AskAlexSharov
I assume the same applies to debug_accountRange as well as debug_storageRangeAt, so this should be added to the rpcd docs as well?

I ran into this issue as some RPC providers were using Geth or Erigon to process debug_storageRangeAt requests and we were getting inconsistent responses depending on which node software they selected, hopefully with this now being stated in the rpc docs this will be fixed on their end as well.

@AskAlexSharov
Copy link
Collaborator

@awskii do you think we can do this by looking at commitment.kv potentially?

Yes, but maybe we can user-understandable error for next 2 cases:

  • request of 32bytes key (interpreted as addr hash)
  • request of empty key (interpreted as addr hash)

And support only next cases:

  • 20 byte keys (interpreted as addr)
  • 1 < N < 20 (interpreted as addr prefix)

@AskAlexSharov AskAlexSharov reopened this Mar 22, 2025
@VBulikov
Copy link
Member

VBulikov added Imp2 as Importance

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

No branches or pull requests

4 participants