Skip to content

Commit 322eac1

Browse files
geokneesebastianst
andauthored
op-node: add FETCH_WITHDRAWAL_ROOT_FROM_STATE config var (#15150)
* op-node: add MESSAGE_PASSER_ROOT_FROM_STATE config var - wired up to the L2ClientConfig. - escape hatch for isthmus behaviour in L2Client.outputV0 * add log * debug log * downgrade logs to debug level * Update op-service/sources/l2_client.go Co-authored-by: Sebastian Stammler <[email protected]> * reinstate accidentally deleted field * rename MessagePasserRootFromState to FetchWithdrawalRootFromState * Update op-node/flags/flags.go Co-authored-by: Sebastian Stammler <[email protected]> * prefer "withdrawal root" to "messagePasserStorageRoot" --------- Co-authored-by: Sebastian Stammler <[email protected]>
1 parent 958a0b7 commit 322eac1

File tree

5 files changed

+27
-8
lines changed

5 files changed

+27
-8
lines changed

op-node/flags/flags.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,13 @@ var (
141141
EnvVars: prefixEnvVars("RPC_ADMIN_STATE"),
142142
Category: OperationsCategory,
143143
}
144+
FetchWithdrawalRootFromState = &cli.BoolFlag{
145+
Name: "fetch-withdrawal-root-from-state",
146+
Usage: "Read withdrawal_storage_root (aka message passer storage root) from state trie (via execution layer) instead of the block header. Restores pre-Isthmus behavior, requires an archive EL client.",
147+
Required: false,
148+
EnvVars: prefixEnvVars("FETCH_WITHDRAWAL_ROOT_FROM_STATE"),
149+
Category: OperationsCategory,
150+
}
144151
L1TrustRPC = &cli.BoolFlag{
145152
Name: "l1.trustrpc",
146153
Usage: "Trust the L1 RPC, sync faster at risk of malicious/buggy RPC providing bad or inconsistent L1 data",
@@ -451,6 +458,7 @@ var optionalFlags = []cli.Flag{
451458
BeaconCheckIgnore,
452459
BeaconFetchAllSidecars,
453460
SyncModeFlag,
461+
FetchWithdrawalRootFromState,
454462
RPCListenAddr,
455463
RPCListenPort,
456464
L1TrustRPC,

op-node/node/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ type Config struct {
7878
AltDA altda.CLIConfig
7979

8080
IgnoreMissingPectraBlobSchedule bool
81+
FetchWithdrawalRootFromState bool
8182
}
8283

8384
// ConductorRPCFunc retrieves the endpoint. The RPC may not immediately be available.

op-node/node/node.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,8 @@ func (n *OpNode) initL2(ctx context.Context, cfg *Config) error {
389389
return fmt.Errorf("failed to setup L2 execution-engine RPC client: %w", err)
390390
}
391391

392+
rpcCfg.FetchWithdrawalRootFromState = cfg.FetchWithdrawalRootFromState
393+
392394
n.l2Source, err = sources.NewEngineClient(rpcClient, n.log, n.metrics.L2SourceCache, rpcCfg)
393395
if err != nil {
394396
return fmt.Errorf("failed to create Engine client: %w", err)

op-node/service.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ func NewConfig(ctx *cli.Context, log log.Logger) (*node.Config, error) {
117117
AltDA: altda.ReadCLIConfig(ctx),
118118

119119
IgnoreMissingPectraBlobSchedule: ctx.Bool(flags.IgnoreMissingPectraBlobSchedule.Name),
120+
FetchWithdrawalRootFromState: ctx.Bool(flags.FetchWithdrawalRootFromState.Name),
120121
}
121122

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

op-service/sources/l2_client.go

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ import (
2222
type L2ClientConfig struct {
2323
EthClientConfig
2424

25-
L2BlockRefsCacheSize int
26-
L1ConfigsCacheSize int
25+
L2BlockRefsCacheSize int
26+
L1ConfigsCacheSize int
27+
FetchWithdrawalRootFromState bool
2728

2829
RollupCfg *rollup.Config
2930
}
@@ -75,6 +76,8 @@ type L2Client struct {
7576
// cache SystemConfig by L2 hash
7677
// common.Hash -> eth.SystemConfig
7778
systemConfigsCache *caching.LRUCache[common.Hash, eth.SystemConfig]
79+
80+
fetchWithdrawalRootFromState bool
7881
}
7982

8083
var _ apis.L2EthExtendedClient = (*L2Client)(nil)
@@ -89,10 +92,11 @@ func NewL2Client(client client.RPC, log log.Logger, metrics caching.Metrics, con
8992
}
9093

9194
return &L2Client{
92-
EthClient: ethClient,
93-
rollupCfg: config.RollupCfg,
94-
l2BlockRefsCache: caching.NewLRUCache[common.Hash, eth.L2BlockRef](metrics, "blockrefs", config.L2BlockRefsCacheSize),
95-
systemConfigsCache: caching.NewLRUCache[common.Hash, eth.SystemConfig](metrics, "systemconfigs", config.L1ConfigsCacheSize),
95+
EthClient: ethClient,
96+
rollupCfg: config.RollupCfg,
97+
l2BlockRefsCache: caching.NewLRUCache[common.Hash, eth.L2BlockRef](metrics, "blockrefs", config.L2BlockRefsCacheSize),
98+
systemConfigsCache: caching.NewLRUCache[common.Hash, eth.SystemConfig](metrics, "systemconfigs", config.L1ConfigsCacheSize),
99+
fetchWithdrawalRootFromState: config.FetchWithdrawalRootFromState,
96100
}, nil
97101
}
98102

@@ -197,11 +201,14 @@ func (s *L2Client) outputV0(ctx context.Context, block eth.BlockInfo) (*eth.Outp
197201

198202
blockHash := block.Hash()
199203
var messagePasserStorageRoot eth.Bytes32
200-
if s.rollupCfg.IsIsthmus(block.Time()) {
201-
// If Isthmus hard fork has activated, we can get the messagePasserStorageRoot directly from the header
204+
if s.rollupCfg.IsIsthmus(block.Time()) && !s.fetchWithdrawalRootFromState {
205+
s.log.Debug("Retrieving withdrawal root from block header")
206+
// If Isthmus hard fork has activated, we can get the withdrawal root directly from the header
202207
// instead of having to compute it from the contract storage trie.
203208
messagePasserStorageRoot = eth.Bytes32(*block.WithdrawalsRoot())
209+
204210
} else {
211+
s.log.Debug("Bypassing block header, retrieving withdrawal root from state")
205212
proof, err := s.GetProof(ctx, predeploys.L2ToL1MessagePasserAddr, []common.Hash{}, blockHash.String())
206213
if err != nil {
207214
return nil, fmt.Errorf("failed to get contract proof at block %s: %w", blockHash, err)

0 commit comments

Comments
 (0)