Skip to content

Commit 6638905

Browse files
authored
op-node: Add pectra blob schedule fix kill-switch (#14922)
* op-node: Add pectra blob schedule fix kill-switch * move ignore flag into node config
1 parent bf97453 commit 6638905

File tree

5 files changed

+114
-0
lines changed

5 files changed

+114
-0
lines changed

Diff for: op-node/flags/flags.go

+11
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,16 @@ var (
419419
Destination: new(string),
420420
Category: InteropCategory,
421421
}
422+
423+
IgnoreMissingPectraBlobSchedule = &cli.BoolFlag{
424+
Name: "ignore-missing-pectra-blob-schedule",
425+
Usage: "Ignore missing pectra blob schedule fix for Sepolia and Holesky chains. Only set if you know what you are doing!" +
426+
"Ask your chain's operator for the correct Pectra blob schedule activation time and set it via the rollup.json config" +
427+
"or use the --override.pectrablobschedule flag.",
428+
EnvVars: prefixEnvVars("IGNORE_MISSING_PECTRA_BLOB_SCHEDULE"),
429+
Category: RollupCategory,
430+
Hidden: true,
431+
}
422432
)
423433

424434
var requiredFlags = []cli.Flag{
@@ -471,6 +481,7 @@ var optionalFlags = []cli.Flag{
471481
InteropRPCAddr,
472482
InteropRPCPort,
473483
InteropJWTSecret,
484+
IgnoreMissingPectraBlobSchedule,
474485
}
475486

476487
var DeprecatedFlags = []cli.Flag{

Diff for: op-node/node/config.go

+11
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ type Config struct {
7676

7777
// AltDA config
7878
AltDA altda.CLIConfig
79+
80+
IgnoreMissingPectraBlobSchedule bool
7981
}
8082

8183
// ConductorRPCFunc retrieves the endpoint. The RPC may not immediately be available.
@@ -127,6 +129,8 @@ func (cfg *Config) LoadPersisted(log log.Logger) error {
127129
return nil
128130
}
129131

132+
var ErrMissingPectraBlobSchedule = errors.New("probably missing Pectra blob schedule")
133+
130134
// Check verifies that the given configuration makes sense
131135
func (cfg *Config) Check() error {
132136
if err := cfg.L1.Check(); err != nil {
@@ -154,6 +158,13 @@ func (cfg *Config) Check() error {
154158
if err := cfg.Rollup.Check(); err != nil {
155159
return fmt.Errorf("rollup config error: %w", err)
156160
}
161+
if !cfg.IgnoreMissingPectraBlobSchedule && cfg.Rollup.ProbablyMissingPectraBlobSchedule() {
162+
log.Error("Your rollup config seems to be missing the Pectra blob schedule fix. " +
163+
"Reach out to your chain operator for the correct Pectra blob schedule configuration. " +
164+
"If you know what you are doing, you can disable this error by setting the " +
165+
"'--ignore-missing-pectra-blob-schedule' flag or 'IGNORE_MISSING_PECTRA_BLOB_SCHEDULE' env var.")
166+
return ErrMissingPectraBlobSchedule
167+
}
157168
if err := cfg.Metrics.Check(); err != nil {
158169
return fmt.Errorf("metrics config error: %w", err)
159170
}

Diff for: op-node/rollup/types.go

+26
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,32 @@ func (cfg *Config) HasOptimismWithdrawalsRoot(timestamp uint64) bool {
358358
return cfg.IsIsthmus(timestamp)
359359
}
360360

361+
// ProbablyMissingPectraBlobSchedule returns whether the chain is likely missing the Pectra blob
362+
// schedule fix.
363+
// A chain probably needs the Pectra blob schedule fix if:
364+
// - its L1 in Holesky or Sepolia, and
365+
// - its genesis is before the L1's Prague activation.
366+
func (cfg *Config) ProbablyMissingPectraBlobSchedule() bool {
367+
if cfg.PectraBlobScheduleTime != nil {
368+
return false
369+
}
370+
371+
var pragueTime uint64
372+
if cfg.L1ChainID.Cmp(params.HoleskyChainConfig.ChainID) == 0 {
373+
pragueTime = *params.HoleskyChainConfig.PragueTime
374+
} else if cfg.L1ChainID.Cmp(params.SepoliaChainConfig.ChainID) == 0 {
375+
pragueTime = *params.SepoliaChainConfig.PragueTime
376+
} else {
377+
// Only Holesky and Sepolia chains may have run into the
378+
// Pectra blob schedule bug.
379+
return false
380+
}
381+
382+
// Only chains whose genesis was before the L1's prague activation need
383+
// the Pectra blob schedule fix.
384+
return pragueTime >= cfg.Genesis.L2Time
385+
}
386+
361387
// validateAltDAConfig checks the two approaches to configuring alt-da mode.
362388
// If the legacy values are set, they are copied to the new location. If both are set, they are check for consistency.
363389
func validateAltDAConfig(cfg *Config) error {

Diff for: op-node/rollup/types_test.go

+64
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/stretchr/testify/require"
1414

1515
"github.com/ethereum/go-ethereum/common"
16+
"github.com/ethereum/go-ethereum/params"
1617

1718
"github.com/ethereum-optimism/optimism/op-service/eth"
1819
)
@@ -823,3 +824,66 @@ func TestConfigImplementsBlockType(t *testing.T) {
823824
})
824825
}
825826
}
827+
828+
func TestConfig_ProbablyMissingPectraBlobSchedule(t *testing.T) {
829+
hol, sep := params.HoleskyChainConfig, params.SepoliaChainConfig
830+
831+
for _, tt := range []struct {
832+
name string
833+
pectraBlobScheduleTime *uint64
834+
l2genesisTime uint64
835+
l1chainID *big.Int
836+
expMissing bool
837+
}{
838+
{
839+
name: "sepolia-ok",
840+
pectraBlobScheduleTime: u64ptr(1742486400), // sepolia superchain
841+
l2genesisTime: 1691802540, // op-sepolia
842+
l1chainID: sep.ChainID,
843+
},
844+
{
845+
name: "holesky-ok",
846+
pectraBlobScheduleTime: u64ptr(1742486400), // sepolia superchain
847+
l2genesisTime: 1691802540, // op-sepolia
848+
l1chainID: hol.ChainID,
849+
},
850+
{
851+
name: "sepolia-missing",
852+
l2genesisTime: 1691802540, // op-sepolia
853+
l1chainID: sep.ChainID,
854+
expMissing: true,
855+
},
856+
{
857+
name: "holesky-missing",
858+
l2genesisTime: 1691802540, // op-sepolia
859+
l1chainID: hol.ChainID,
860+
expMissing: true,
861+
},
862+
{
863+
name: "sepolia-young-genesis",
864+
l2genesisTime: *sep.PragueTime + 1,
865+
l1chainID: sep.ChainID,
866+
},
867+
{
868+
name: "holesky-young-genesis",
869+
l2genesisTime: *hol.PragueTime + 1,
870+
l1chainID: hol.ChainID,
871+
},
872+
{
873+
name: "other-missing-ok",
874+
l2genesisTime: 1691802540,
875+
l1chainID: big.NewInt(1),
876+
},
877+
} {
878+
t.Run(tt.name, func(t *testing.T) {
879+
cfg := &Config{
880+
Genesis: Genesis{
881+
L2Time: tt.l2genesisTime,
882+
},
883+
PectraBlobScheduleTime: tt.pectraBlobScheduleTime,
884+
L1ChainID: tt.l1chainID,
885+
}
886+
assert.Equal(t, tt.expMissing, cfg.ProbablyMissingPectraBlobSchedule())
887+
})
888+
}
889+
}

Diff for: op-node/service.go

+2
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ func NewConfig(ctx *cli.Context, log log.Logger) (*node.Config, error) {
115115
ConductorRpcTimeout: ctx.Duration(flags.ConductorRpcTimeoutFlag.Name),
116116

117117
AltDA: altda.ReadCLIConfig(ctx),
118+
119+
IgnoreMissingPectraBlobSchedule: ctx.Bool(flags.IgnoreMissingPectraBlobSchedule.Name),
118120
}
119121

120122
if err := cfg.LoadPersisted(log); err != nil {

0 commit comments

Comments
 (0)