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

Isthmus: withdrawals root in block header #383

Merged
merged 6 commits into from
Dec 10, 2024
Merged

Conversation

protolambda
Copy link
Collaborator

@protolambda protolambda commented Sep 21, 2024

Description

L2 withdrawals storage root is retrieve from the state upon block-sealing, and then inserted into the header as withdrawals-root.

The L1 withdrawals-root is computed as an MPT hash of withdrawals operations. The OP-Stack uses contract-storage instead. In some places this means we have to verify the block-body withdrawals-list is empty, while the header is set to the storage root.

Tests

Work in progress.

Additional context

This PR is used as feature-branch. Changes will not be merged into optimism until the withdrawals changes (specs, op-geth, op-node, and ideally other implementations) are complete for Holocene upgrade.

Metadata

Part of ethereum-optimism/optimism#12044

@protolambda protolambda changed the title all: withdrawals root in header is reused to commit to OP-Stack L2 withdrawals storage root Holocene: withdrawals root in block header Sep 21, 2024
@vdamle vdamle changed the title Holocene: withdrawals root in block header Isthmus: withdrawals root in block header Oct 9, 2024
@vdamle vdamle force-pushed the l2-withdrawals-root branch from 8d2f6ac to 823e2d9 Compare October 22, 2024 18:14
@vdamle
Copy link
Contributor

vdamle commented Oct 22, 2024

Rebased changes in this branch with latest changes in optimism branch

@protolambda
Copy link
Collaborator Author

Functionality is almost good to go.
I did a full review of all withdrawal mentions in op-geth, and found some minor issues, and I pushed a fix commit for the tedious bits.

  • There is a quirk where newFetchResult sees a non-nil withdrawals-root,
    and does not match the hash of empty withdrawals, and it will try fetch withdrawals that aren't there.
    This is fine, we can ignore it for a simple diff, but it is a slight optimization loss.

  • In a few places it was logging a common.Hash with %x, which I believe first calls .String(), and then formats the string as hex.
    This is double hex encoding, not desired. Changed it to %s. Would may be a neat little PR to upstream geth, albeit only better error messaging.

  • debug_executionWitness I think will work without changes,
    since it happens to run ValidateState with a side-effect on the pre-fetcher because of the storage-root retrieval during validation.
    I added a warning to the debug method implementation, so it's not such an opaque side-effect.

  • beacon/exec_data_test.go fuzz test is kind of broken, and should not be merged in its current state:

    • Chained decode code-paths in single fuzzer -> e.g. we don't reach exec data if receipt fails.
    • If we do want this fuzz test, then there should be be multiple fuzz definitions, one per time. Perhaps using a helper func with generics,
      to not repeat the var value V, decodeEncodeJSON(input, &value) ... each time.
    • Raw byte array as json input -> fuzzer has to guess at key words, go fuzzer is not that good.
    • It is only testing types not even part of the beacon package (light client beacon-chain support),
      we shouldn't have to touch this package much at all, except ExecutableData because of the engine-API.
    • Try to put a simple panic in ExecutableData -> no panic actually hit. Always many iterations, then some nonsense other JSON related error (see below).
      // example of something you could add to `func (e ExecutableData) MarshalJSON()` in `gen_ed.go` without effect:
      if enc.BlobGasUsed != nil {
          panic("the fuzzer found a JSON field")
      }
      
    • It does hit other nonsense things like: (bytes 7b7d = utf8 {}, just short enough to generate after 145272 attempts on my machine):
      --- FAIL: FuzzJSON (13.00s)
      --- FAIL: FuzzJSON (0.00s)
          exec_data_test.go:43: encode-decode is not equal, 
              input : 7b7d
              output: 7b2252656365697665644174223a22303030312d30312d30315430303a30303a30305a222c22526563656976656446726f6d223a6e756c6c7d
      
      And the output here is {"ReceivedAt":"0001-01-01T00:00:00Z","ReceivedFrom":null}, i.e. internal fields of the block-type,
      because types.Block isn't actually meant to be json-encoded/decoded (there are API different handlers for it).
    • Or another fun one: hex: 5b205d, utf8: [ ]. Not equal to 5b5d, utf8 [], i.e. whitespace is lost in JSON.
  • The fork.yaml EVM t8ntool entry doesn't mention any file path.

  • Please change each of the commits to the <domain>: <change description> format that geth uses.

  • The commits author info (email or name) isn't set to your github account data exactly, you may want to amend those commits.

@vdamle vdamle force-pushed the l2-withdrawals-root branch 2 times, most recently from f5949e0 to 6579db6 Compare December 6, 2024 20:19
@vdamle
Copy link
Contributor

vdamle commented Dec 6, 2024

@protolambda Thank you for taking a look, for the changes you pushed and the suggestions. I have done the following:

  • Cleaned all commit messages to adhere to the format. Couple of commits have additional descriptions, from what I can tell, that should be fine.
  • Updated the author email to the public email listed in my github profile.
  • Split the fuzz tests into two files:
    • exec_data_test.go now tests only ExecutableData
    • core types are now fuzz tested in core/types/json_fuzzer_test.go -- with a generic fuzzJSONForType()
    • split the fuzz tests into individual once to address the problem you highlighted. Also sanitized the input/output by stripping out spaces/CR/LF so that the checks can complete.
    • I have added a seed corpus struct for all fuzz tests and a f.Add(object). It obviously increases the diff size, but seems to be a best practice noted in go fuzz testing doc.

Please take a look whenever you get a chance. FYI @tynes

Copy link
Collaborator Author

@protolambda protolambda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but after discussing with @tynes I think we are over-thinking the json fuzz-tests:

  • Even if they work, upstream geth seems to do fine without them
  • The json functionality is auto-generated with a lib that is widely used in geth already.
  • The fuzzing doesn't seem to run in CI or get enough fuzzing time to be meaningful, especially since it's fuzzing the raw JSON, and even with a fuzz-corpus hint it might not get far.

Let's drop the fuzz tests and get this merged.

protolambda and others added 5 commits December 10, 2024 09:05
…orage root

* update checks for l2 withdrawal root to be gated on Isthmus
* core: pass chainConfig to NewBlock for withdrawalRoot checks and fix usage
  this is so that we can check whether Isthmus is active within NewBlock()
* genesis: read and set withdrawalsRoot to storageRoot of L2toL1MP contract
* prioritize supplied withdrawalsRoot in beacon engine header check
@vdamle vdamle force-pushed the l2-withdrawals-root branch from 6579db6 to 1750edc Compare December 10, 2024 14:20
@vdamle
Copy link
Contributor

vdamle commented Dec 10, 2024

LGTM, but after discussing with @tynes I think we are over-thinking the json fuzz-tests:

  • Even if they work, upstream geth seems to do fine without them
  • The json functionality is auto-generated with a lib that is widely used in geth already.
  • The fuzzing doesn't seem to run in CI or get enough fuzzing time to be meaningful, especially since it's fuzzing the raw JSON, and even with a fuzz-corpus hint it might not get far.

Let's drop the fuzz tests and get this merged.

Thanks for the feedback @protolambda @tynes

I've dropped the fuzz tests from the earlier commit and rebased against the updated base branch. Should be ready for a final pass and hopefully it's good to go!

@vdamle vdamle requested a review from tynes December 10, 2024 14:22
Copy link
Collaborator Author

@protolambda protolambda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! (cannot approve my own PR, but at this point it's really @vdamle authoring the commits here)

@tynes tynes merged commit 2ff9b8b into optimism Dec 10, 2024
10 checks passed
@tynes tynes deleted the l2-withdrawals-root branch December 10, 2024 15:56
@protolambda protolambda restored the l2-withdrawals-root branch December 16, 2024 14:28
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

Successfully merging this pull request may close these issues.

3 participants