Commit cd64143e authored by Andreas Bigger's avatar Andreas Bigger

feat: l1 and l2 source validation

parent 64c8b4bb
......@@ -124,6 +124,30 @@ func (n *OpNode) initL1(ctx context.Context, cfg *Config) error {
return fmt.Errorf("failed to create L1 source: %w", err)
}
// Validate the L1 Client Chain ID
id, err := n.l1Source.L1ChainID(ctx)
if err != nil {
n.log.Warn("failed to verify L1 RPC chain id", "err", err)
} else {
if cfg.Rollup.L1ChainID != id {
n.log.Warn("incorrect L1 RPC chain id", "expected", cfg.Rollup.L1ChainID, "actual", id)
} else {
n.log.Info("L1 RPC chain id verified", "id", id)
}
}
// Validate the Rollup L1 Genesis Blockhash
l1GenesisBlockRef, err := n.l1Source.L1BlockRefByNumber(ctx, cfg.Rollup.Genesis.L1.Number)
if err != nil {
n.log.Warn("failed to validate L1 genesis block", "err", err)
} else {
if l1GenesisBlockRef.Hash != cfg.Rollup.Genesis.L1.Hash {
n.log.Warn("incorrect L1 genesis block", "expected", cfg.Rollup.Genesis.L1.Hash, "actual", l1GenesisBlockRef.Hash)
} else {
n.log.Info("L1 genesis block verified", "hash", l1GenesisBlockRef.Hash)
}
}
// Keep subscribed to the L1 heads, which keeps the L1 maintainer pointing to the best headers to sync
n.l1HeadsSub = event.ResubscribeErr(time.Second*10, func(ctx context.Context, err error) (event.Subscription, error) {
if err != nil {
......@@ -189,6 +213,30 @@ func (n *OpNode) initL2(ctx context.Context, cfg *Config, snapshotLog log.Logger
return fmt.Errorf("failed to create Engine client: %w", err)
}
// Validate the L2 Client Chain ID
id, err := n.l2Source.L2ChainID(ctx)
if err != nil {
n.log.Warn("failed to verify L2 RPC chain id", "err", err)
} else {
if cfg.Rollup.L2ChainID != id {
n.log.Warn("incorrect L2 RPC chain id", "expected", cfg.Rollup.L2ChainID, "actual", id)
} else {
n.log.Info("L2 RPC chain id verified", "id", id)
}
}
// Validate the Rollup L2 Genesis Blockhash
l2GenesisBlockRef, err := n.l2Source.L2BlockRefByNumber(ctx, cfg.Rollup.Genesis.L2.Number)
if err != nil {
n.log.Warn("failed to validate L2 genesis block", "err", err)
} else {
if l2GenesisBlockRef.Hash != cfg.Rollup.Genesis.L2.Hash {
n.log.Warn("incorrect L2 genesis block", "expected", cfg.Rollup.Genesis.L2.Hash, "actual", l2GenesisBlockRef.Hash)
} else {
n.log.Info("L2 genesis block verified", "hash", l2GenesisBlockRef.Hash)
}
}
n.l2Driver = driver.NewDriver(&cfg.Driver, &cfg.Rollup, n.l2Source, n.l1Source, n, n.log, snapshotLog, n.metrics)
return nil
......
......@@ -3,6 +3,7 @@ package sources
import (
"context"
"fmt"
"math/big"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
......@@ -207,6 +208,16 @@ func (s *EthClient) payloadCall(ctx context.Context, method string, id any) (*et
return payload, nil
}
// ChainID fetches the chain id of the internal RPC.
func (s *EthClient) ChainID(ctx context.Context) (*big.Int, error) {
var id *big.Int
err := s.client.CallContext(ctx, &id, "eth_chainId")
if err != nil {
return nil, err
}
return id, nil
}
func (s *EthClient) InfoByHash(ctx context.Context, hash common.Hash) (eth.BlockInfo, error) {
if header, ok := s.headersCache.Get(hash); ok {
return header.(*HeaderInfo), nil
......
......@@ -3,6 +3,7 @@ package sources
import (
"context"
"fmt"
"math/big"
"strings"
"github.com/ethereum/go-ethereum"
......@@ -68,6 +69,11 @@ func NewL1Client(client client.RPC, log log.Logger, metrics caching.Metrics, con
}, nil
}
// L1ChainID fetches the chain id for the RPC Client.
func (s *L1Client) L1ChainID(ctx context.Context) (*big.Int, error) {
return s.ChainID(ctx)
}
func (s *L1Client) L1BlockRefByLabel(ctx context.Context, label eth.BlockLabel) (eth.L1BlockRef, error) {
info, err := s.InfoByLabel(ctx, label)
if err != nil {
......
......@@ -3,6 +3,7 @@ package sources
import (
"context"
"fmt"
"math/big"
"strings"
"github.com/ethereum/go-ethereum"
......@@ -84,6 +85,11 @@ func NewL2Client(client client.RPC, log log.Logger, metrics caching.Metrics, con
}, nil
}
// L2ChainID fetches the chain id for the RPC Client.
func (s *L2Client) L2ChainID(ctx context.Context) (*big.Int, error) {
return s.ChainID(ctx)
}
// L2BlockRefByLabel returns the L2 block reference for the given label.
func (s *L2Client) L2BlockRefByLabel(ctx context.Context, label eth.BlockLabel) (eth.L2BlockRef, error) {
payload, err := s.PayloadByLabel(ctx, label)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment