Skip to content

Optimizations for eth_getProof #27308

@prestwich

Description

@prestwich

Encountered while writing #27306

Rationale

eth_getProof is significantly more resource-intensive than it should be

  • eth_getProof implementations performs N+1 deep copies, when only 1 is necessary
  • eth_getProof implementations performs these expensive deep copies before performing cheap hex deserialization
  • GetProof calls state.StorageTrie to see if the account has state
    • This performs a deep copy of the state object
  • Then, for each user-provided key
    • It deserializes the hex string into bytes, failing on error
    • Then calls GetStorageProof
    • state.GetStorageProof immediately calls state.StorageTrie again
      • This performs another deep copy of the same state object,
      • This deep copy is performed for each user-provided hex key until an error is encountered
  • As a result, the RPC expends significant resources on invalid requests, which could be cheaply shortcut

So a correct request will result in N+1 deep copies of the state object (1 before the loop, and N within the loop). It will perform deep copies even if the input is malformatted (invalid hex), repeatedly until it encounters the invalid input.

Implementation

Do you have ideas regarding the implementation of this feature?

Suggestions:

  1. Greedily validate input to prevent deep copying when input is invalid
    • Perform all hex deserialization first at the start of the function, rather than within the for loop [as currently written].
    • shortcut if any hex deser fails
    • this prevents resource expenditure on bad caller input
  2. Do not call state.GetStorageProof within the loop.
    • instead, use the storageTrie reference from outside the loop to generate the storage proof
    • call storageTrie.Prove and perform validation on the result within the loop (inlining the checks in state.GetStorageProof)
    • this cuts out N deep copies of the state object

Are you willing to implement this feature?

Yes

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions