risc0 / zeth

A "Type 0" zkEVM. Prove validity of Ethereum blocks using RISC Zero's zkVM
Apache License 2.0
381 stars 68 forks source link

Optimism L1 -> L2 derivation #51

Closed intoverflow closed 11 months ago

intoverflow commented 1 year ago

This PR builds on prior work by @Wollac and @hashcashier. It introduces a new tool: op-derive. This tool has two inputs:

  1. block_no, an L2 block number (used as the initial "safe head")
  2. blocks, a block count (indicating how many blocks should be derived)

The tool begins by reading the system transaction from the initial safe head. This allows the tool to determine which L1 block it should begin reading from.

It then applies the L1 -> L2 derivation process for the specified sequence of L2 blocks (block_no + 1, block_no + 2, ..., block_no + blocks).

Along the way, the tool verifies that each of the derived L2 blocks have the expected block number, parent block, and list of transactions.

This complements Zeth's existing op-block tool, which can prove that a given list of transactions generates a given block.

Direct links:

The derive logic is defined in the library; the host and guest both use this same function. The function fetches data using the BatcherDb trait. In the guest, we use an in-memory implementation; on the host, we use an implementation that fetches data using RPC, and which also saves this data to an in-memory implementation that can be later passed to the guest ("preflight data fetching").

Sample output

Starting from op block 110800000, we derive 10 blocks:

Eth tail: 18341377 0x4eb45301f17a8fcdbf65dd1122361db575792b517287121675bf856dfb8122f2
Op Head: 110800000 0x1545e3edbd5b7a5cb1ce231c9eabb6da6dd97596b8db21b81201187b5de6245e
Derived: 110800001 0x45eb3f54dfe4dfe462ebb5f13a4e48b4e3332f0ef48106f241f190dde7b68086
Derived: 110800002 0x89d059ee39f9d41560dbe7f658bb311628e04f7453b566aac5e48b9d01f5183a
Derived: 110800003 0x39c420afa9c7e36a5d2c90c1606035c5264fc3831e21b0fd9e2ae7c75d5e48fb
Derived: 110800004 0x562299262875e710d33b213408673094a81aad435093ee54dbe4eab87a71cb2c
Derived: 110800005 0xf399e43c3ed2d5a691202f059f497e20a1167403bb3eb85544269d194c17f2d2
Derived: 110800006 0xd9f3a0765136a70b2678d7b146323e34cc3321bd9052b45de07835ae0f0a32e1
Derived: 110800007 0xb2cbf289486819481d901c1ca3451db5d7b697a3643c9cccfbe4b3fe43d9583d
Derived: 110800008 0x28ee07c0cdc0ad79254affe94b025ac4585bf4159f1641eaf2ef4b10ac779b3b
Derived: 110800009 0x55cb0f317da978e69480ada142661741128b579f6d77abd40022b2d6113bdde0
Derived: 110800010 0x8684698f999dc866f034df4fcf954ce1e929dd2fd98c03399003039b5a773e18

Semantically, this output means: if L2 block 110800000 and L1 block 18341377 both have the correct hash, then L2 block 110800001 with the indicated hash has the correct block number, parent block, and list of transactions.

Additionally, if L2 block 110800001 has the correct hash, then L2 block 110800002 with the indicated hash has the correct block number, parent block, and list of transactions.

(And so on, inductively.)

Testing

Tested with by deriving 10,000 blocks starting from 110800000:

$ RUST_LOG=info ../zeth/target/release/op-derive \
        --eth-rpc-url="https://eth-mainnet.g.alchemy.com/v2/[my api key]" \
        --op-rpc-url="https://opt-mainnet.g.alchemy.com/v2/[my api key]" \
        --cache
        --block-no=110800000
        --blocks=10000
...
Eth tail: 18343028 0x053b8fbc01b52f4e8eda7539818b3f6c86a11ef1ceeecefbf73fe1930d3ec2e9
Op Head: 110800000 0x1545e3edbd5b7a5cb1ce231c9eabb6da6dd97596b8db21b81201187b5de6245e
Derived: 110800001 0x45eb3f54dfe4dfe462ebb5f13a4e48b4e3332f0ef48106f241f190dde7b68086
...
Derived: 110800010 0x8684698f999dc866f034df4fcf954ce1e929dd2fd98c03399003039b5a773e18
...
Derived: 110800100 0x31f3a2aef4d2bfad22ad8d75bc5e0e5f1f04bab51367bc9502712af72359d725
...
Derived: 110801000 0xea3dc1b2acdb188539fcaf165c51fc61f630f2a20bfeebd8da31528d7cccef9d
...
Derived: 110810000 0xe346f9d53c24d5214f6a8fcfb294e1319aee886be11eb02f2fe7e012436bdda4
intoverflow commented 1 year ago

This PR is based on https://github.com/risc0/zeth/tree/rkhalil/op-derive. It might make more sense to submit this branch as a PR into that branch, then submit that branch as a PR into main. Let me know what you think.

Wollac commented 11 months ago

We should also absolutely add an e2e test similar to block_cli_ethereum for the derivation data now in the repo

Wollac commented 11 months ago

We should also absolutely add an e2e test similar to block_cli_ethereum for the derivation data now in the repo

done