Skip to content

Commit

Permalink
Config: Introduce check for isthmus hardfork
Browse files Browse the repository at this point in the history
and update checks for l2 withdrawal root to be gated on Isthmus instead
of Holocene
  • Loading branch information
Vinod Damle committed Oct 9, 2024
1 parent 9fcb541 commit cdb45f2
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 10 deletions.
2 changes: 1 addition & 1 deletion beacon/engine/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ type ExecutableData struct {
BlobGasUsed *uint64 `json:"blobGasUsed"`
ExcessBlobGas *uint64 `json:"excessBlobGas"`

// OP-Stack Holocene specific field:
// OP-Stack Isthmus specific field:
// instead of computing the root from a withdrawals list, set it directly.
// The "withdrawals" list attribute must be non-nil but empty.
WithdrawalsRoot *common.Hash `json:"withdrawalsRoot,omitempty"`
Expand Down
6 changes: 3 additions & 3 deletions consensus/beacon/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -403,9 +403,9 @@ func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea
// Assign the final state root to header.
header.Root = state.IntermediateRoot(true)

if chain.Config().IsOptimismHolocene(header.Time) {
if body.Withdrawals == nil || len(body.Withdrawals) > 0 { // We verify nil/empty withdrawals in the CL pre-holocene
return nil, fmt.Errorf("expected non-nil empty withdrawals operation list in Holocene, but got: %v", body.Withdrawals)
if chain.Config().IsOptimismIsthmus(header.Time) {
if body.Withdrawals == nil || len(body.Withdrawals) > 0 { // We verify nil/empty withdrawals in the CL pre-isthmus
return nil, fmt.Errorf("expected non-nil empty withdrawals operation list in Isthmus, but got: %v", body.Withdrawals)
}
// State-root has just been computed, we can get an accurate storage-root now.
h := state.GetStorageRoot(params.OptimismL2ToL1MessagePasser)
Expand Down
6 changes: 3 additions & 3 deletions core/block_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
if block.Withdrawals() == nil {
return errors.New("missing withdrawals in block body")
}
if v.config.IsOptimismHolocene(header.Time) {
if v.config.IsOptimismIsthmus(header.Time) {
if len(block.Withdrawals()) > 0 {
return errors.New("no withdrawal block-operations allowed, withdrawalsRoot is set to storage root")
}
Expand Down Expand Up @@ -152,9 +152,9 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD
if root := statedb.IntermediateRoot(v.config.IsEIP158(header.Number)); header.Root != root {
return fmt.Errorf("invalid merkle root (remote: %x local: %x) dberr: %w", header.Root, root, statedb.Error())
}
if v.config.IsOptimismHolocene(block.Time()) {
if v.config.IsOptimismIsthmus(block.Time()) {
if header.WithdrawalsHash == nil {
return errors.New("expected withdrawals root in OP-Stack post-Holocene block header")
return errors.New("expected withdrawals root in OP-Stack post-Isthmus block header")
}
// Validate the withdrawals root against the L2 withdrawals storage, similar to how the StateRoot is verified.
if root := statedb.GetStorageRoot(params.OptimismL2ToL1MessagePasser); *header.WithdrawalsHash != root {
Expand Down
6 changes: 3 additions & 3 deletions eth/downloader/queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func (f *fetchResult) Done(kind uint) bool {
}

type OPStackChainConfig interface {
IsOptimismHolocene(time uint64) bool
IsOptimismIsthmus(time uint64) bool
}

// queue represents hashes that are either need fetching or are being fetched
Expand Down Expand Up @@ -814,8 +814,8 @@ func (q *queue) DeliverBodies(id string, txLists [][]*types.Transaction, txListH
if withdrawalLists[index] == nil {
return errInvalidBody
}
if q.opConfig != nil && q.opConfig.IsOptimismHolocene(header.Time) {
// If Holocene, we expect an empty list of withdrawal operations,
if q.opConfig != nil && q.opConfig.IsOptimismIsthmus(header.Time) {
// If Isthmus, we expect an empty list of withdrawal operations,
// but the WithdrawalsHash in the header is used for the withdrawals state storage-root.
if withdrawalListHashes[index] != types.EmptyWithdrawalsHash {
return errInvalidBody
Expand Down
9 changes: 9 additions & 0 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ type ChainConfig struct {
FjordTime *uint64 `json:"fjordTime,omitempty"` // Fjord switch time (nil = no fork, 0 = already on Optimism Fjord)
GraniteTime *uint64 `json:"graniteTime,omitempty"` // Granite switch time (nil = no fork, 0 = already on Optimism Granite)
HoloceneTime *uint64 `json:"holoceneTime,omitempty"` // Holocene switch time (nil = no fork, 0 = already on Optimism Holocene)
IsthmusTime *uint64 `json:"isthmusTime,omitempty"` // Isthmus switch time (nil = no fork, 0 = already on Optimism Isthmus)

InteropTime *uint64 `json:"interopTime,omitempty"` // Interop switch time (nil = no fork, 0 = already on optimism interop)

Expand Down Expand Up @@ -680,6 +681,10 @@ func (c *ChainConfig) IsHolocene(time uint64) bool {
return isTimestampForked(c.HoloceneTime, time)
}

func (c *ChainConfig) IsIsthmus(time uint64) bool {
return isTimestampForked(c.IsthmusTime, time)
}

func (c *ChainConfig) IsInterop(time uint64) bool {
return isTimestampForked(c.InteropTime, time)
}
Expand Down Expand Up @@ -718,6 +723,10 @@ func (c *ChainConfig) IsOptimismHolocene(time uint64) bool {
return c.IsOptimism() && c.IsHolocene(time)
}

func (c *ChainConfig) IsOptimismIsthmus(time uint64) bool {
return c.IsOptimism() && c.IsIsthmus(time)
}

// IsOptimismPreBedrock returns true iff this is an optimism node & bedrock is not yet active
func (c *ChainConfig) IsOptimismPreBedrock(num *big.Int) bool {
return c.IsOptimism() && !c.IsBedrock(num)
Expand Down

0 comments on commit cdb45f2

Please sign in to comment.