diff --git a/snow/engine/snowman/bootstrap/bootstrapper.go b/snow/engine/snowman/bootstrap/bootstrapper.go index ad1d3d901bcd..0f0a516539af 100644 --- a/snow/engine/snowman/bootstrap/bootstrapper.go +++ b/snow/engine/snowman/bootstrap/bootstrapper.go @@ -149,7 +149,42 @@ func (b *bootstrapper) Start(ctx context.Context, startReqID uint32) error { b.startingHeight = lastAccepted.Height() b.Config.SharedCfg.RequestID = startReqID - if !b.StartupTracker.ShouldStart() { + return b.tryStartBootstrapping(ctx) +} + +func (b *bootstrapper) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error { + if err := b.VM.Connected(ctx, nodeID, nodeVersion); err != nil { + return err + } + + if err := b.StartupTracker.Connected(ctx, nodeID, nodeVersion); err != nil { + return err + } + // Ensure fetchFrom reflects proper validator list + if _, ok := b.Beacons.GetValidator(b.Ctx.SubnetID, nodeID); ok { + b.fetchFrom.Add(nodeID) + } + + return b.tryStartBootstrapping(ctx) +} + +func (b *bootstrapper) Disconnected(ctx context.Context, nodeID ids.NodeID) error { + if err := b.VM.Disconnected(ctx, nodeID); err != nil { + return err + } + + if err := b.StartupTracker.Disconnected(ctx, nodeID); err != nil { + return err + } + + b.markUnavailable(nodeID) + return nil +} + +// tryStartBootstrapping will start bootstrapping the first time it is called +// while the startupTracker is reporting that the protocol should start. +func (b *bootstrapper) tryStartBootstrapping(ctx context.Context) error { + if b.started || !b.StartupTracker.ShouldStart() { return nil } @@ -246,40 +281,6 @@ func (b *bootstrapper) GetAncestorsFailed(ctx context.Context, nodeID ids.NodeID return b.fetch(ctx, blkID) } -func (b *bootstrapper) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error { - if err := b.VM.Connected(ctx, nodeID, nodeVersion); err != nil { - return err - } - - if err := b.StartupTracker.Connected(ctx, nodeID, nodeVersion); err != nil { - return err - } - // Ensure fetchFrom reflects proper validator list - if _, ok := b.Beacons.GetValidator(b.Ctx.SubnetID, nodeID); ok { - b.fetchFrom.Add(nodeID) - } - - if b.started || !b.StartupTracker.ShouldStart() { - return nil - } - - b.started = true - return b.Startup(ctx) -} - -func (b *bootstrapper) Disconnected(ctx context.Context, nodeID ids.NodeID) error { - if err := b.VM.Disconnected(ctx, nodeID); err != nil { - return err - } - - if err := b.StartupTracker.Disconnected(ctx, nodeID); err != nil { - return err - } - - b.markUnavailable(nodeID) - return nil -} - func (b *bootstrapper) Timeout(ctx context.Context) error { if !b.awaitingTimeout { return errUnexpectedTimeout diff --git a/snow/engine/snowman/syncer/state_syncer.go b/snow/engine/snowman/syncer/state_syncer.go index c912bbd12093..da377bdcc046 100644 --- a/snow/engine/snowman/syncer/state_syncer.go +++ b/snow/engine/snowman/syncer/state_syncer.go @@ -112,6 +112,53 @@ func (ss *stateSyncer) Context() *snow.ConsensusContext { return ss.Ctx } +func (ss *stateSyncer) Start(ctx context.Context, startReqID uint32) error { + ss.Ctx.Log.Info("starting state sync") + + ss.Ctx.State.Set(snow.EngineState{ + Type: p2p.EngineType_ENGINE_TYPE_SNOWMAN, + State: snow.StateSyncing, + }) + if err := ss.VM.SetState(ctx, snow.StateSyncing); err != nil { + return fmt.Errorf("failed to notify VM that state syncing has started: %w", err) + } + + ss.requestID = startReqID + + return ss.tryStartSyncing(ctx) +} + +func (ss *stateSyncer) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error { + if err := ss.VM.Connected(ctx, nodeID, nodeVersion); err != nil { + return err + } + + if err := ss.StartupTracker.Connected(ctx, nodeID, nodeVersion); err != nil { + return err + } + + return ss.tryStartSyncing(ctx) +} + +func (ss *stateSyncer) Disconnected(ctx context.Context, nodeID ids.NodeID) error { + if err := ss.VM.Disconnected(ctx, nodeID); err != nil { + return err + } + + return ss.StartupTracker.Disconnected(ctx, nodeID) +} + +// tryStartSyncing will start syncing the first time it is called while the +// startupTracker is reporting that the protocol should start. +func (ss *stateSyncer) tryStartSyncing(ctx context.Context) error { + if ss.started || !ss.StartupTracker.ShouldStart() { + return nil + } + + ss.started = true + return ss.startup(ctx) +} + func (ss *stateSyncer) StateSummaryFrontier(ctx context.Context, nodeID ids.NodeID, requestID uint32, summaryBytes []byte) error { // ignores any late responses if requestID != ss.requestID { @@ -426,27 +473,6 @@ func (ss *stateSyncer) GetAcceptedStateSummaryFailed(ctx context.Context, nodeID return ss.AcceptedStateSummary(ctx, nodeID, requestID, nil) } -func (ss *stateSyncer) Start(ctx context.Context, startReqID uint32) error { - ss.Ctx.Log.Info("starting state sync") - - ss.Ctx.State.Set(snow.EngineState{ - Type: p2p.EngineType_ENGINE_TYPE_SNOWMAN, - State: snow.StateSyncing, - }) - if err := ss.VM.SetState(ctx, snow.StateSyncing); err != nil { - return fmt.Errorf("failed to notify VM that state syncing has started: %w", err) - } - - ss.requestID = startReqID - - if !ss.StartupTracker.ShouldStart() { - return nil - } - - ss.started = true - return ss.startup(ctx) -} - // startup do start the whole state sync process by // sampling frontier seeders, listing state syncers to request votes to // and reaching out frontier seeders if any. Otherwise, it moves immediately @@ -580,31 +606,6 @@ func (ss *stateSyncer) Notify(ctx context.Context, msg common.Message) error { return ss.onDoneStateSyncing(ctx, ss.requestID) } -func (ss *stateSyncer) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error { - if err := ss.VM.Connected(ctx, nodeID, nodeVersion); err != nil { - return err - } - - if err := ss.StartupTracker.Connected(ctx, nodeID, nodeVersion); err != nil { - return err - } - - if ss.started || !ss.StartupTracker.ShouldStart() { - return nil - } - - ss.started = true - return ss.startup(ctx) -} - -func (ss *stateSyncer) Disconnected(ctx context.Context, nodeID ids.NodeID) error { - if err := ss.VM.Disconnected(ctx, nodeID); err != nil { - return err - } - - return ss.StartupTracker.Disconnected(ctx, nodeID) -} - func (*stateSyncer) Gossip(context.Context) error { return nil }