Conversation
4189012 to
2c93be0
Compare
b0dbd43 to
d9f1ca1
Compare
crates/rpc/rpc/src/debug.rs
Outdated
There was a problem hiding this comment.
reminder to self: Need 4788 call here
There was a problem hiding this comment.
wondering if we can eventually use the block executor traits here, as there will be more system contract calls and maintaining a copy of block execution logic in debug APIs seems brittle
There was a problem hiding this comment.
Agree. I also specifically need this for Optimism execution, so that would be ideal. Glad to circle back around to this before we merge, just have to get it working first.
38b2229 to
2027c7a
Compare
2027c7a to
6184498
Compare
gakonst
left a comment
There was a problem hiding this comment.
This should prob be part of the Evm Executor as a execute_witnessed() style operation? and then the RPC method calls that?
crates/rpc/rpc/src/debug.rs
Outdated
| let account_proofs = db | ||
| .cache |
There was a problem hiding this comment.
should be access list inspector instead
6184498 to
6c40fe6
Compare
6c40fe6 to
81526f9
Compare
81526f9 to
26e133c
Compare
crates/rpc/rpc/src/debug.rs
Outdated
There was a problem hiding this comment.
still need to call 4788 etc here right?
47398b0 to
ccbfa3a
Compare
| .with_bundle_update() | ||
| .build(); | ||
|
|
||
| pre_block_beacon_root_contract_call( |
There was a problem hiding this comment.
one more thing, this doesn't check if the target block is post merge
do we need to call any other systemcalls or just 4788?
Overview
Adds a new endpoint to the
debugnamespace for generating historical execution witnesses.Rationale
For ZK and Optimistic proving systems, generating execution witnesses for stateless execution can be tough. Before peter's recent cross-client validation proposal, there were fairly limited proposals for this feature pre-verkle. All existing options involve expensive-to-run nodes with large storage requirements, i.e.
gcmode=archive+state.scheme=hashgeth.Hash scheme geth does the trick, but in an abusive way towards their
debug_dbGetendpoint, which just-so-happens to key all RLP-encoded trie nodes by their hash (H(rlp(trie_node))->rlp(trie_node)).How does it work?
CacheDB.AccountProofis generated, utilizing theHistoricalStateProvider::proofmethod.H(rlp(trie_node))->rlp(trie_node).DoS concerns
Due to reth's database format only storing merkle diffs, this process can become very expensive for the same reason that state root generation in historical execution within reth can be very expensive. Each diff is layered, which means the further back we reach, the more expensive the operation becomes (approaching upper bound, potentially unable to even fit in memory due to the sheer volume of layers.)
Because of this, this endpoint has been placed in the
debug_*namespace, which is not often exposed to the open internet by node operators. Exposing this endpoint can pose major DoS concerns for node operators as it stands.Future historical
eth_getProofsupportHistorical
eth_getProofsupport was already possible inrethbefore this PR, but was never implemented due to the above DoS concerns (per @rkrasiuk). This PR does not remove the requirement for being at tip to useeth_getProof, but this could be supported in a future PR, by adding a sane default for allowedeth_getProofdepth, configurable via the CLI. A max chain depth foreth_getProofwould effectively cap the number of in-memory layers that must be applied to the trie.TODO
In order to complete this feature, we'll need to be able to also include branch sibling nodes that must be referenced in order to delete leaves in the MPT. This endpoint currently gives the entirety of the witness data required for execution, but not to re-produce the block header for the processed block. The crux of this is that we cannot know which nodes we need to reveal until we're performing the deletion, meaning we also have to compute the state root in this endpoint and collect them, as these nodes are not included within the account proofs we already generate.
To outline the problem, let's say we start with this small trie, where the root node is a branch containing 2 children (both leaf nodes):
If we want to delete the node in the
3bucket, the branch node would be left with only one child - this is an invalid state. To complete the deletion, we must revealA(which is hashed), and collapse the branch node intoA.In order of operation:
3withrlp(empty) = 0x80H(node_at(A)), and prepend the branch nibble (A) to its path.