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

core: do not trigger rewind behaviour when modifying pre-genesis hardfork times / blocks #332

Merged
merged 18 commits into from
Jun 14, 2024

Conversation

geoknee
Copy link
Contributor

@geoknee geoknee commented Jun 5, 2024

Replaces #257

Currently, no Optimism hard forks are checked as a part of this function:

op-geth/params/config.go

Lines 807 to 876 in 0d7fd67

func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, headNumber *big.Int, headTimestamp uint64) *ConfigCompatError {
if isForkBlockIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, headNumber) {
return newBlockCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock)
}
if isForkBlockIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, headNumber) {
return newBlockCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock)
}
if c.IsDAOFork(headNumber) && c.DAOForkSupport != newcfg.DAOForkSupport {
return newBlockCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock)
}
if isForkBlockIncompatible(c.EIP150Block, newcfg.EIP150Block, headNumber) {
return newBlockCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block)
}
if isForkBlockIncompatible(c.EIP155Block, newcfg.EIP155Block, headNumber) {
return newBlockCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block)
}
if isForkBlockIncompatible(c.EIP158Block, newcfg.EIP158Block, headNumber) {
return newBlockCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block)
}
if c.IsEIP158(headNumber) && !configBlockEqual(c.ChainID, newcfg.ChainID) {
return newBlockCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block)
}
if isForkBlockIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, headNumber) {
return newBlockCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock)
}
if isForkBlockIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, headNumber) {
return newBlockCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock)
}
if isForkBlockIncompatible(c.PetersburgBlock, newcfg.PetersburgBlock, headNumber) {
// the only case where we allow Petersburg to be set in the past is if it is equal to Constantinople
// mainly to satisfy fork ordering requirements which state that Petersburg fork be set if Constantinople fork is set
if isForkBlockIncompatible(c.ConstantinopleBlock, newcfg.PetersburgBlock, headNumber) {
return newBlockCompatError("Petersburg fork block", c.PetersburgBlock, newcfg.PetersburgBlock)
}
}
if isForkBlockIncompatible(c.IstanbulBlock, newcfg.IstanbulBlock, headNumber) {
return newBlockCompatError("Istanbul fork block", c.IstanbulBlock, newcfg.IstanbulBlock)
}
if isForkBlockIncompatible(c.MuirGlacierBlock, newcfg.MuirGlacierBlock, headNumber) {
return newBlockCompatError("Muir Glacier fork block", c.MuirGlacierBlock, newcfg.MuirGlacierBlock)
}
if isForkBlockIncompatible(c.BerlinBlock, newcfg.BerlinBlock, headNumber) {
return newBlockCompatError("Berlin fork block", c.BerlinBlock, newcfg.BerlinBlock)
}
if isForkBlockIncompatible(c.LondonBlock, newcfg.LondonBlock, headNumber) {
return newBlockCompatError("London fork block", c.LondonBlock, newcfg.LondonBlock)
}
if isForkBlockIncompatible(c.ArrowGlacierBlock, newcfg.ArrowGlacierBlock, headNumber) {
return newBlockCompatError("Arrow Glacier fork block", c.ArrowGlacierBlock, newcfg.ArrowGlacierBlock)
}
if isForkBlockIncompatible(c.GrayGlacierBlock, newcfg.GrayGlacierBlock, headNumber) {
return newBlockCompatError("Gray Glacier fork block", c.GrayGlacierBlock, newcfg.GrayGlacierBlock)
}
if isForkBlockIncompatible(c.MergeNetsplitBlock, newcfg.MergeNetsplitBlock, headNumber) {
return newBlockCompatError("Merge netsplit fork block", c.MergeNetsplitBlock, newcfg.MergeNetsplitBlock)
}
if isForkTimestampIncompatible(c.ShanghaiTime, newcfg.ShanghaiTime, headTimestamp) {
return newTimestampCompatError("Shanghai fork timestamp", c.ShanghaiTime, newcfg.ShanghaiTime)
}
if isForkTimestampIncompatible(c.CancunTime, newcfg.CancunTime, headTimestamp) {
return newTimestampCompatError("Cancun fork timestamp", c.CancunTime, newcfg.CancunTime)
}
if isForkTimestampIncompatible(c.PragueTime, newcfg.PragueTime, headTimestamp) {
return newTimestampCompatError("Prague fork timestamp", c.PragueTime, newcfg.PragueTime)
}
if isForkTimestampIncompatible(c.VerkleTime, newcfg.VerkleTime, headTimestamp) {
return newTimestampCompatError("Verkle fork timestamp", c.VerkleTime, newcfg.VerkleTime)
}
return nil
}

So modifying an optimism hard fork time will not cause a chain rewind, whereas modifying a non-optimism hardfork will cause a chain rewind.

Towards https://github.com/ethereum-optimism/client-pod/issues/918
Counterpart to ethereum-optimism/superchain-registry#260

  • adds all of the optimism hard forks to the check so they have the same behaviour
  • modifies the check so that changing a hardfork from a pregenesis timestamp to another pregenesis timestamp is considered a compatible change.

@geoknee geoknee requested a review from a team as a code owner June 5, 2024 16:39
@geoknee geoknee requested a review from axelKingsley June 5, 2024 16:39
@geoknee geoknee marked this pull request as draft June 6, 2024 14:24
@geoknee
Copy link
Contributor Author

geoknee commented Jun 6, 2024

Next steps following sync with @sebastianst

  1. Add some unit test for checkCompatible and patch it to include all Optimism hard forks
  2. Patch it again so that pre-genesis hardfork times are always considered compatible
  3. Test out the a "test release" of op-geth on a) a devnet replica and/or b) our prod metal replica (but protect that one first by asking devinfra to take a disk snapshot prior)

@geoknee
Copy link
Contributor Author

geoknee commented Jun 6, 2024

Shanghai activates with Canyon
The code that ties these together is outside of the function covered by the test on this PR. So a "live" test which say modifies a canyon time can also modify the shanghai time (which would cause a chain rewind currently).

@geoknee geoknee changed the title core: add test for chain rewind behaviour when modifying pre-genesis hardfork times core: do not trigger rewind behaviour when modifying pre-genesis hardfork times / blocks Jun 7, 2024
core/genesis.go Outdated Show resolved Hide resolved
@geoknee geoknee marked this pull request as ready for review June 7, 2024 17:22
@geoknee geoknee requested a review from sebastianst June 7, 2024 17:23
@geoknee
Copy link
Contributor Author

geoknee commented Jun 13, 2024

Next steps following sync with @sebastianst

  1. Add some unit test for checkCompatible and patch it to include all Optimism hard forks

Done

  1. Patch it again so that pre-genesis hardfork times are always considered compatible

Done

  1. Test out the a "test release" of op-geth on a) a devnet replica and/or b) our prod metal replica (but protect that one first by asking devinfra to take a disk snapshot prior)

Done!

core/blockchain_test.go Outdated Show resolved Hide resolved
core/genesis.go Outdated Show resolved Hide resolved
params/config_test.go Outdated Show resolved Hide resolved
params/config_test.go Outdated Show resolved Hide resolved
core/blockchain_test.go Outdated Show resolved Hide resolved
core/blockchain_test.go Outdated Show resolved Hide resolved
core/blockchain_test.go Outdated Show resolved Hide resolved
This allows us to handle the case where the genesis itself (and therefore the genesis timestamp) is undefined. We handle that by declaring all time stamps as POST genesis, so they can't pass the compatibilty check via the new escape hatch.
@geoknee
Copy link
Contributor Author

geoknee commented Jun 14, 2024

We already pass a uint46 ptr to the isTimestampPreGenesis, so we might as well also pass it to CheckCompatible.

2a67982

@sebastianst sebastianst enabled auto-merge (squash) June 14, 2024 10:27
@sebastianst sebastianst merged commit a34e174 into optimism Jun 14, 2024
9 of 10 checks passed
@sebastianst sebastianst deleted the gk/rewind branch June 14, 2024 10:31
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.

2 participants