diff --git a/packages/taiko-client/cmd/flags/driver.go b/packages/taiko-client/cmd/flags/driver.go index 67ddc823fbe..3c28dc7571a 100644 --- a/packages/taiko-client/cmd/flags/driver.go +++ b/packages/taiko-client/cmd/flags/driver.go @@ -8,6 +8,14 @@ import ( // Optional flags used by driver. var ( + P2PSync = &cli.BoolFlag{ + Name: "p2p.sync", + Usage: "Try P2P syncing blocks between L2 execution engines, " + + "will be helpful to bring a new node online quickly", + Value: false, + Category: driverCategory, + EnvVars: []string{"P2P_SYNC"}, + } P2PSyncTimeout = &cli.DurationFlag{ Name: "p2p.syncTimeout", Usage: "P2P syncing timeout, if no sync progress is made within this time span, " + @@ -19,7 +27,6 @@ var ( CheckPointSyncURL = &cli.StringFlag{ Name: "p2p.checkPointSyncUrl", Usage: "HTTP RPC endpoint of another synced L2 execution engine node", - Required: true, Category: driverCategory, EnvVars: []string{"P2P_CHECK_POINT_SYNC_URL"}, } @@ -53,6 +60,7 @@ var DriverFlags = MergeFlags(CommonFlags, []cli.Flag{ L2WSEndpoint, L2AuthEndpoint, JWTSecret, + P2PSync, P2PSyncTimeout, CheckPointSyncURL, MaxExponent, diff --git a/packages/taiko-client/driver/chain_syncer/chain_syncer.go b/packages/taiko-client/driver/chain_syncer/chain_syncer.go index ab9f36b43d6..6e17215d73d 100644 --- a/packages/taiko-client/driver/chain_syncer/chain_syncer.go +++ b/packages/taiko-client/driver/chain_syncer/chain_syncer.go @@ -32,6 +32,10 @@ type L2ChainSyncer struct { // Sync mode syncMode string + + // If this flag is activated, will try P2P beacon sync if current node is behind of the protocol's + // the latest verified block head + p2pSync bool } // New creates a new chain syncer instance. @@ -39,6 +43,7 @@ func New( ctx context.Context, rpc *rpc.Client, state *state.State, + p2pSync bool, p2pSyncTimeout time.Duration, maxRetrieveExponent uint64, blobServerEndpoint *url.URL, @@ -73,6 +78,7 @@ func New( blobSyncer: blobSyncer, progressTracker: tracker, syncMode: syncMode, + p2pSync: p2pSync, }, nil } @@ -98,6 +104,7 @@ func (s *L2ChainSyncer) Sync() error { if s.progressTracker.Triggered() { log.Info( "Switch to insert pending blocks one by one", + "p2pEnabled", s.p2pSync, "p2pOutOfSync", s.progressTracker.OutOfSync(), ) @@ -163,12 +170,13 @@ func (s *L2ChainSyncer) AheadOfHeadToSync(heightToSync uint64) bool { // needNewBeaconSyncTriggered checks whether the current L2 execution engine needs to trigger // another new beacon sync, the following conditions should be met: -// 1. The protocol's latest verified block head is not zero. -// 2. The L2 execution engine's chain is behind of the protocol's latest verified block head. -// 3. The L2 execution engine's chain has met a sync timeout issue. +// 1. The `P2PSync` flag is set. +// 2. The protocol's latest verified block head is not zero. +// 3. The L2 execution engine's chain is behind of the protocol's latest verified block head. +// 4. The L2 execution engine's chain has met a sync timeout issue. func (s *L2ChainSyncer) needNewBeaconSyncTriggered() (uint64, bool, error) { // If the flag is not set or there was a finished beacon sync, we simply return false. - if s.progressTracker.Finished() { + if !s.p2pSync || s.progressTracker.Finished() { return 0, false, nil } diff --git a/packages/taiko-client/driver/chain_syncer/chain_syncer_test.go b/packages/taiko-client/driver/chain_syncer/chain_syncer_test.go index f18e10b7b23..5327317f02e 100644 --- a/packages/taiko-client/driver/chain_syncer/chain_syncer_test.go +++ b/packages/taiko-client/driver/chain_syncer/chain_syncer_test.go @@ -39,6 +39,7 @@ func (s *ChainSyncerTestSuite) SetupTest() { context.Background(), s.RPCClient, state, + false, 1*time.Hour, 0, nil, diff --git a/packages/taiko-client/driver/config.go b/packages/taiko-client/driver/config.go index 418e3c8a7a6..3eb3b95e236 100644 --- a/packages/taiko-client/driver/config.go +++ b/packages/taiko-client/driver/config.go @@ -17,6 +17,7 @@ import ( // Config contains the configurations to initialize a Taiko driver. type Config struct { *rpc.ClientConfig + P2PSync bool P2PSyncTimeout time.Duration RetryInterval time.Duration MaxExponent uint64 @@ -33,10 +34,11 @@ func NewConfigFromCliContext(c *cli.Context) (*Config, error) { } var ( + p2pSync = c.Bool(flags.P2PSync.Name) l2CheckPoint = c.String(flags.CheckPointSyncURL.Name) ) - if len(l2CheckPoint) == 0 { + if p2pSync && len(l2CheckPoint) == 0 { return nil, errors.New("empty L2 check point URL") } @@ -63,8 +65,8 @@ func NewConfigFromCliContext(c *cli.Context) (*Config, error) { } } - if beaconEndpoint == "" { - return nil, errors.New("empty L1 beacon endpoint") + if beaconEndpoint == "" && blobServerEndpoint == nil && socialScanEndpoint == nil { + return nil, errors.New("empty L1 beacon endpoint, blob server and Social Scan endpoint") } var timeout = c.Duration(flags.RPCTimeout.Name) @@ -81,6 +83,7 @@ func NewConfigFromCliContext(c *cli.Context) (*Config, error) { Timeout: timeout, }, RetryInterval: c.Duration(flags.BackOffRetryInterval.Name), + P2PSync: p2pSync, P2PSyncTimeout: c.Duration(flags.P2PSyncTimeout.Name), MaxExponent: c.Uint64(flags.MaxExponent.Name), BlobServerEndpoint: blobServerEndpoint, diff --git a/packages/taiko-client/driver/config_test.go b/packages/taiko-client/driver/config_test.go index 829501f038c..f65359467dd 100644 --- a/packages/taiko-client/driver/config_test.go +++ b/packages/taiko-client/driver/config_test.go @@ -34,6 +34,7 @@ func (s *DriverTestSuite) TestNewConfigFromCliContext() { s.Equal(taikoL2, c.TaikoL2Address.String()) s.Equal(120*time.Second, c.P2PSyncTimeout) s.NotEmpty(c.JwtSecret) + s.True(c.P2PSync) s.Equal(l2CheckPoint, c.L2CheckPoint) s.Nil(new(Driver).InitFromCli(context.Background(), ctx)) @@ -51,6 +52,7 @@ func (s *DriverTestSuite) TestNewConfigFromCliContext() { "--" + flags.JWTSecret.Name, os.Getenv("JWT_SECRET"), "--" + flags.P2PSyncTimeout.Name, "120s", "--" + flags.RPCTimeout.Name, "5s", + "--" + flags.P2PSync.Name, "--" + flags.CheckPointSyncURL.Name, l2CheckPoint, })) } @@ -68,6 +70,7 @@ func (s *DriverTestSuite) TestNewConfigFromCliContextEmptyL2CheckPoint() { s.ErrorContains(app.Run([]string{ "TestNewConfigFromCliContext", "--" + flags.JWTSecret.Name, os.Getenv("JWT_SECRET"), + "--" + flags.P2PSync.Name, "--" + flags.L2WSEndpoint.Name, "", }), "empty L2 check point URL") } @@ -82,6 +85,7 @@ func (s *DriverTestSuite) SetupApp() *cli.App { &cli.StringFlag{Name: flags.TaikoL1Address.Name}, &cli.StringFlag{Name: flags.TaikoL2Address.Name}, &cli.StringFlag{Name: flags.JWTSecret.Name}, + &cli.BoolFlag{Name: flags.P2PSync.Name}, &cli.DurationFlag{Name: flags.P2PSyncTimeout.Name}, &cli.DurationFlag{Name: flags.RPCTimeout.Name}, &cli.StringFlag{Name: flags.CheckPointSyncURL.Name}, diff --git a/packages/taiko-client/driver/driver.go b/packages/taiko-client/driver/driver.go index 50bba29e016..a5990139dcb 100644 --- a/packages/taiko-client/driver/driver.go +++ b/packages/taiko-client/driver/driver.go @@ -69,7 +69,7 @@ func (d *Driver) InitFromConfig(ctx context.Context, cfg *Config) (err error) { return err } - if peers == 0 { + if cfg.P2PSync && peers == 0 { log.Warn("P2P syncing verified blocks enabled, but no connected peer found in L2 execution engine") } @@ -77,6 +77,7 @@ func (d *Driver) InitFromConfig(ctx context.Context, cfg *Config) (err error) { d.ctx, d.rpc, d.state, + cfg.P2PSync, cfg.P2PSyncTimeout, cfg.MaxExponent, cfg.BlobServerEndpoint,