scroll-tech / go-ethereum

Scroll's fork of the official Go implementation of the Ethereum protocol
GNU Lesser General Public License v3.0
493 stars 276 forks source link

create trace from block + storage proof statelessly #103

Closed lispc closed 1 year ago

lispc commented 2 years ago

currently we generate block trace in l2geth. But the trace is very heavy due to structLog per step.

while In theory, if we have Block + Storage Witness, we can re-execute the block statelessly. So prover server can re-construct the full trace locally without network overhead.

So we plan to try to implement this feature. it gives us more freedom in future architecture design.

The first step:

(1) write a command line tool, the input is a trace json https://github.com/scroll-tech/integration-test/#a-complete-guide-on-how-to-generate-trace . The tool traverse the storage trace in this json, and insert the trie node into trie database (backed by a local in-memory db). And then re-execute the txs in the block (of course the per step StructLog will be be used here), we can get a new trace json. Finally we assert the new trace json is identical to the old one.

Use this branch https://github.com/scroll-tech/go-ethereum/pull/101. The branch can use two types of storage backend: zktrie and old mpt. Finally we plan to use the zktrie backend. For this issue, both zktrie and old mpt is ok. But i am afraid whether it works for old mpt since the mpt is very complext and so the "storage trace" may not contain enough witness sibling nodes. I suggest use zktrie to implement this feature, whenever storage trace misses some needed sibling nodes, we treat it as a bug that should be fixed.

hsyodyssey commented 2 years ago

Please correct me if I made a mistake. Basically, we need a cli tool for Prover server that can update the system state with the given trace json. Meanwhile, the updated result is equal to the result of executing the original transactions in a certain block.

lispc commented 2 years ago

p-code:

func POC_reconstuct_trace(blk *BlockResult) {
   partial_db := insert_trie_entries_into_db(blk.StorageTrace)
   blk2 := stateless_exec(partial_db, blk.BlockTrace)
   assert(blk2.ExecutionResults.deepEqual(blk.ExecutionResults))
}

We are not building a cli tool, but to write a POC function to make sure the ExecutionResults in BlockResult can be removed and reconstructed.

We can discuss this furthur in Monday meeting.

hsyodyssey commented 2 years ago

oh, got it, I thought we needed a package like t8n. Without cli is fine. We can discuss it later to make sure we are on the same track. Enjoy your weekend :)😄。

hsyodyssey commented 2 years ago

Hi Zhuo, I simply modified the pseudo code of PoC. Could you check if I understand it right?

func POC_reconstuct_trace(blk *BlockResult) {
   snap_db := env.context.stateDB.Copy()
   partial_db := insert_trie_entries_into_db(blk.StorageTrace, env.context.stateDB)
   blk2 := stateless_exec(snap_db, blk.BlockTrace)
   assert(blk2.ExecutionResults.deepEqual(blk.ExecutionResults)&&partial_db.deepEqual(snap_db))
}
lispc commented 2 years ago

i am afraid not.

what's env.context.stateDB? Is it empty here snap_db := env.context.stateDB.Copy()? This POC_reconstuct_trace is expected to be executed without any chaindata on disk.

hsyodyssey commented 2 years ago

oh i see, I seem to understand. There is one detail that I may have to confirm with you. Can have a brief chat when you have time?

lispc commented 2 years ago

@hsyodyssey you can work on this branch: https://github.com/scroll-tech/go-ethereum/pull/113

hsyodyssey commented 2 years ago

@hsyodyssey you can work on this branch: #113

Copy that.