diff --git a/driver/driver.go b/driver/driver.go index eabe3ff48..6c13ef870 100644 --- a/driver/driver.go +++ b/driver/driver.go @@ -6,6 +6,9 @@ import ( "time" "github.com/cenkalti/backoff/v4" + "github.com/ethereum/go-ethereum/beacon/engine" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" @@ -16,7 +19,9 @@ import ( ) const ( - protocolStatusReportInterval = 30 * time.Second + protocolStatusReportInterval = 30 * time.Second + exchangeTransitionConfigTimeout = 30 * time.Second + exchangeTransitionConfigInterval = 1 * time.Minute ) // Driver keeps the L2 execution engine's local block chain in sync with the TaikoL1 @@ -102,9 +107,10 @@ func InitFromConfig(ctx context.Context, d *Driver, cfg *Config) (err error) { // Start starts the driver instance. func (d *Driver) Start() error { - d.wg.Add(2) + d.wg.Add(3) go d.eventLoop() go d.reportProtocolStatus() + go d.exchangeTransitionConfigLoop() return nil } @@ -221,6 +227,43 @@ func (d *Driver) reportProtocolStatus() { } } +// exchangeTransitionConfigLoop keeps exchanging transition configs with the +// L2 execution engine. +func (d *Driver) exchangeTransitionConfigLoop() { + ticker := time.NewTicker(exchangeTransitionConfigInterval) + defer func() { + ticker.Stop() + d.wg.Done() + }() + + for { + select { + case <-d.ctx.Done(): + return + case <-ticker.C: + func() { + ctx, cancel := context.WithTimeout(d.ctx, exchangeTransitionConfigTimeout) + defer cancel() + + tc, err := d.rpc.L2Engine.ExchangeTransitionConfiguration(ctx, &engine.TransitionConfigurationV1{ + TerminalTotalDifficulty: (*hexutil.Big)(common.Big0), + TerminalBlockHash: common.Hash{}, + TerminalBlockNumber: 0, + }) + if err != nil { + log.Error("Failed to exchange Transition Configuration", "error", err) + return + } + + log.Debug( + "Exchanged transition config", + "transitionConfig", tc, + ) + }() + } + } +} + // Name returns the application name. func (d *Driver) Name() string { return "driver" diff --git a/pkg/rpc/engine.go b/pkg/rpc/engine.go index ce1e8638e..1516e3b25 100644 --- a/pkg/rpc/engine.go +++ b/pkg/rpc/engine.go @@ -63,3 +63,16 @@ func (c *EngineClient) GetPayload( return result.ExecutionPayload, nil } + +// ExchangeTransitionConfiguration exchanges transition configs with the L2 execution engine. +func (c *EngineClient) ExchangeTransitionConfiguration( + ctx context.Context, + cfg *engine.TransitionConfigurationV1, +) (*engine.TransitionConfigurationV1, error) { + var result *engine.TransitionConfigurationV1 + if err := c.Client.CallContext(ctx, &result, "engine_exchangeTransitionConfigurationV1", cfg); err != nil { + return nil, err + } + + return result, nil +} diff --git a/pkg/rpc/engine_test.go b/pkg/rpc/engine_test.go index e10d4c88e..de63db04e 100644 --- a/pkg/rpc/engine_test.go +++ b/pkg/rpc/engine_test.go @@ -5,6 +5,8 @@ import ( "testing" "github.com/ethereum/go-ethereum/beacon/engine" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/stretchr/testify/require" ) @@ -29,4 +31,11 @@ func TestL2EngineBorbidden(t *testing.T) { &engine.PayloadID{}, ) require.ErrorContains(t, err, "Unauthorized") + + _, err = c.L2Engine.ExchangeTransitionConfiguration(context.Background(), &engine.TransitionConfigurationV1{ + TerminalTotalDifficulty: (*hexutil.Big)(common.Big0), + TerminalBlockHash: common.Hash{}, + TerminalBlockNumber: 0, + }) + require.ErrorContains(t, err, "Unauthorized") }