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

Change header encoding mechanism #300

Merged
merged 4 commits into from
Dec 20, 2024

Conversation

piersy
Copy link

@piersy piersy commented Dec 17, 2024

This changes the way that we detect pre-gingerbread headers when encoding.

Closes https://github.com/celo-org/celo-blockchain-planning/issues/588

Previously we would interpret a gasLimit of zero to indicate pre-gingerbread headers, since prior to the gingerbread hardfork celo blocks lacked the gasLimit field.

This however caused lots of problems with the go tests (existing and ones that continue to be added) that routinely use blocks where gasLimit has not been set.

So now we detect pre-gingerbread blocks when decoding and set a flag on the struct that is used to select the encoding.
New blocks are assumed to be post gingerbread, which is ok because it's not possible to run op-geth without gingerbread set, because we haven't ported across the pre-gingerbread state transition logic.

I was able to revert some test modifications because of this but this didn't fix the tests that broke during the celo11 rebase (skipped in this commit), it seems like those problems were caused by something else.

Remove changes to do with determining whether a decoded block was
pre-gingerbread based on it's gas limit.
Previously we looked for a gas limit of zero, now we use an explicit
unexported field set at creation time.
@piersy piersy requested a review from alecps December 17, 2024 20:56
@piersy piersy requested a review from karlb December 18, 2024 08:55
Copy link

@karlb karlb left a comment

Choose a reason for hiding this comment

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

I clearly prefer this to the previous approach!

@piersy piersy merged commit 57eef86 into celo11 Dec 20, 2024
7 checks passed
@piersy piersy deleted the piersy/change-header-encoding-mechanism branch December 20, 2024 10:09
karlb pushed a commit that referenced this pull request Jan 27, 2025
This changes the way that we detect pre-gingerbread headers when encoding.

Closes celo-org/celo-blockchain-planning#588

Previously we would interpret a `gasLimit` of zero to indicate pre-gingerbread headers, since prior to the gingerbread hardfork celo blocks lacked the `gasLimit` field.

This however caused lots of problems with the go tests (existing and ones that continue to be added) that routinely use blocks where gasLimit has not been set.

So now we detect pre-gingerbread blocks when decoding and set a flag on the struct that is used to select the encoding.
New blocks are assumed to be post gingerbread, which is ok because it's not possible to run op-geth without gingerbread set, because we haven't ported across the pre-gingerbread state transition logic.

I was able to revert some test modifications because of this but this didn't fix the tests that broke during the celo11 rebase (skipped in [this commit](d981efb)), it seems like those problems were caused by something else.
karlb pushed a commit that referenced this pull request Jan 28, 2025
This changes the way that we detect pre-gingerbread headers when encoding.

Closes celo-org/celo-blockchain-planning#588

Previously we would interpret a `gasLimit` of zero to indicate pre-gingerbread headers, since prior to the gingerbread hardfork celo blocks lacked the `gasLimit` field.

This however caused lots of problems with the go tests (existing and ones that continue to be added) that routinely use blocks where gasLimit has not been set.

So now we detect pre-gingerbread blocks when decoding and set a flag on the struct that is used to select the encoding.
New blocks are assumed to be post gingerbread, which is ok because it's not possible to run op-geth without gingerbread set, because we haven't ported across the pre-gingerbread state transition logic.

I was able to revert some test modifications because of this but this didn't fix the tests that broke during the celo11 rebase (skipped in [this commit](d981efb)), it seems like those problems were caused by something else.
karlb pushed a commit that referenced this pull request Feb 3, 2025
This changes the way that we detect pre-gingerbread headers when encoding.

Closes celo-org/celo-blockchain-planning#588

Previously we would interpret a `gasLimit` of zero to indicate pre-gingerbread headers, since prior to the gingerbread hardfork celo blocks lacked the `gasLimit` field.

This however caused lots of problems with the go tests (existing and ones that continue to be added) that routinely use blocks where gasLimit has not been set.

So now we detect pre-gingerbread blocks when decoding and set a flag on the struct that is used to select the encoding.
New blocks are assumed to be post gingerbread, which is ok because it's not possible to run op-geth without gingerbread set, because we haven't ported across the pre-gingerbread state transition logic.

I was able to revert some test modifications because of this but this didn't fix the tests that broke during the celo11 rebase (skipped in [this commit](d981efb)), it seems like those problems were caused by something else.
karlb pushed a commit that referenced this pull request Feb 11, 2025
This changes the way that we detect pre-gingerbread headers when encoding.

Closes celo-org/celo-blockchain-planning#588

Previously we would interpret a `gasLimit` of zero to indicate pre-gingerbread headers, since prior to the gingerbread hardfork celo blocks lacked the `gasLimit` field.

This however caused lots of problems with the go tests (existing and ones that continue to be added) that routinely use blocks where gasLimit has not been set.

So now we detect pre-gingerbread blocks when decoding and set a flag on the struct that is used to select the encoding.
New blocks are assumed to be post gingerbread, which is ok because it's not possible to run op-geth without gingerbread set, because we haven't ported across the pre-gingerbread state transition logic.

I was able to revert some test modifications because of this but this didn't fix the tests that broke during the celo11 rebase (skipped in [this commit](d981efb)), it seems like those problems were caused by something else.
piersy added a commit that referenced this pull request Feb 12, 2025
When the celo blockchain launched it did so without `gasLimit`, `difficulty`
and `uncleHash` fields on the celo block.

In the gingerbread hardfork these fields were added to the block, to improve
celo's compatibility with ethereum, and a zero (or not) `uncleHash` was used to
distinguish the old and new block formats.

When transitioning to the op-stack we discovered that these fields are set to
default values during genesis init if they are unset. This broke our approach
to encoding, so to prevent this happening we would only set defaults in a
migrated chain context (where cel2 time is set an non zero), this allowed us to
skip setting defaults for migrated chains but retain the defaults for tests
which rely heavily on them.

In the op-stack we were using a zero gas limit as an indication of what type of
block encoding to use, but this presented it's own problems for some tests that
used blocks without a gas limit set, so we subsequently switched (#300) to
having an explicit flag set inside headers to specify which encoding to use.
When loading blocks from leveldb the RLP structure could be introspected to
determine the type of block that was being loaded, our thinking was that for
all migrated blocks we could rely on this approach to setting the encoding, and
for any new blocks they would all be being created after the cel2 fork and so
would use the most recent encoding. We removed the special casing of default
setting in `toBlockWithRoot` and relied on the explicit flag.

Unfortunately we forgot about what happens at genesis init, where `NewBlock` is
called to create the genesis block. With the special casing removed, the
defaults being set and `NewBlock` always producing blocks that use the new
encoding we discovered that initing the genesis on a migrated chain resulted in
a different genesis block.

To fix this the special casing has been re-introduced in `toBlockWithRoot` and
extended to prevent default setting of `uncleHash` inside `NewBlock` when
operating in the context of a migrated chain. Also if the genesis block is a
pre-gingerbread block it is marked as such so that it is encoded correctly.

There's was one remaining issue which is that `TestFeeHistory`, initialises a
pre-gingerbread genesis but expects it to have the new block format, so to
account for that an extra condition was added to only use the old format for
pre-gingerbread blocks that are being initialised as a result of executing the
initGenesis command.

---------

Co-authored-by: Paul Lange <[email protected]>
@piersy piersy mentioned this pull request Feb 14, 2025
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