@@ -5,10 +5,7 @@ package bootstrap
55
66import (
77 "context"
8- "errors"
98 "fmt"
10- "math"
11- "time"
129
1310 "go.uber.org/zap"
1411
@@ -31,22 +28,14 @@ const (
3128 stripeDistance = 2000
3229 stripeWidth = 5
3330 cacheSize = 100000
34-
35- // Parameters for delaying bootstrapping to avoid potential CPU burns
36- bootstrappingDelay = 10 * time .Second
3731)
3832
39- var (
40- _ common.BootstrapableEngine = (* bootstrapper )(nil )
41-
42- errUnexpectedTimeout = errors .New ("unexpected timeout fired" )
43- )
33+ var _ common.BootstrapableEngine = (* bootstrapper )(nil )
4434
4535func New (
4636 ctx context.Context ,
4737 config Config ,
48- startAvalancheConsensus func (ctx context.Context , lastReqID uint32 ) error ,
49- startSnowmanBootstrapping func (ctx context.Context , lastReqID uint32 ) error ,
38+ onFinished func (ctx context.Context , lastReqID uint32 ) error ,
5039) (common.BootstrapableEngine , error ) {
5140 b := & bootstrapper {
5241 Config : config ,
@@ -60,26 +49,8 @@ func New(
6049
6150 processedCache : & cache.LRU [ids.ID , struct {}]{Size : cacheSize },
6251 Fetcher : common.Fetcher {
63- OnFinished : func (ctx context.Context , lastReqID uint32 ) error {
64- linearized , err := config .Manager .StopVertexAccepted (ctx )
65- if err != nil {
66- return err
67- }
68- if ! linearized {
69- return startAvalancheConsensus (ctx , lastReqID )
70- }
71-
72- // Invariant: edge will only be the stop vertex after its
73- // acceptance.
74- edge := config .Manager .Edge (ctx )
75- stopVertexID := edge [0 ]
76- if err := config .VM .Linearize (ctx , stopVertexID ); err != nil {
77- return err
78- }
79- return startSnowmanBootstrapping (ctx , lastReqID )
80- },
52+ OnFinished : onFinished ,
8153 },
82- executedStateTransitions : math .MaxInt32 ,
8354 }
8455
8556 if err := b .metrics .Initialize ("bs" , config .Ctx .AvalancheRegisterer ); err != nil {
@@ -132,10 +103,6 @@ type bootstrapper struct {
132103
133104 // Contains IDs of vertices that have recently been processed
134105 processedCache * cache.LRU [ids.ID , struct {}]
135- // number of state transitions executed
136- executedStateTransitions int
137-
138- awaitingTimeout bool
139106}
140107
141108func (b * bootstrapper ) Clear () error {
@@ -319,16 +286,8 @@ func (b *bootstrapper) Disconnected(ctx context.Context, nodeID ids.NodeID) erro
319286 return b .StartupTracker .Disconnected (ctx , nodeID )
320287}
321288
322- func (b * bootstrapper ) Timeout (ctx context.Context ) error {
323- if ! b .awaitingTimeout {
324- return errUnexpectedTimeout
325- }
326- b .awaitingTimeout = false
327-
328- if ! b .Config .BootstrapTracker .IsBootstrapped () {
329- return b .Restart (ctx , true )
330- }
331- return b .OnFinished (ctx , b .Config .SharedCfg .RequestID )
289+ func (* bootstrapper ) Timeout (context.Context ) error {
290+ return nil
332291}
333292
334293func (* bootstrapper ) Gossip (context.Context ) error {
@@ -358,6 +317,42 @@ func (b *bootstrapper) Start(ctx context.Context, startReqID uint32) error {
358317
359318 b .Config .SharedCfg .RequestID = startReqID
360319
320+ // If the network was already linearized, don't attempt to linearize it
321+ // again.
322+ linearized , err := b .Manager .StopVertexAccepted (ctx )
323+ if err != nil {
324+ return fmt .Errorf ("failed to get linearization status: %w" , err )
325+ }
326+ if linearized {
327+ edge := b .Manager .Edge (ctx )
328+ return b .ForceAccepted (ctx , edge )
329+ }
330+
331+ // If requested, assume the currently accepted state is what was linearized.
332+ //
333+ // Note: This is used to linearize networks that were created after the
334+ // linearization occurred.
335+ if b .Config .LinearizeOnStartup {
336+ edge := b .Manager .Edge (ctx )
337+ stopVertex , err := b .Manager .BuildStopVtx (ctx , edge )
338+ if err != nil {
339+ return fmt .Errorf ("failed to create stop vertex: %w" , err )
340+ }
341+ if err := stopVertex .Verify (ctx ); err != nil {
342+ return fmt .Errorf ("failed to verify stop vertex: %w" , err )
343+ }
344+ if err := stopVertex .Accept (ctx ); err != nil {
345+ return fmt .Errorf ("failed to accept stop vertex: %w" , err )
346+ }
347+
348+ stopVertexID := stopVertex .ID ()
349+ b .Ctx .Log .Info ("accepted stop vertex" ,
350+ zap .Stringer ("vtxID" , stopVertexID ),
351+ )
352+
353+ return b .ForceAccepted (ctx , []ids.ID {stopVertexID })
354+ }
355+
361356 if ! b .StartupTracker .ShouldStart () {
362357 return nil
363358 }
@@ -570,7 +565,7 @@ func (b *bootstrapper) ForceAccepted(ctx context.Context, acceptedContainerIDs [
570565func (b * bootstrapper ) checkFinish (ctx context.Context ) error {
571566 // If there are outstanding requests for vertices or we still need to fetch vertices, we can't finish
572567 pendingJobs := b .VtxBlocked .MissingIDs ()
573- if b .IsBootstrapped () || len (pendingJobs ) > 0 || b . awaitingTimeout {
568+ if b .IsBootstrapped () || len (pendingJobs ) > 0 {
574569 return nil
575570 }
576571
@@ -597,7 +592,7 @@ func (b *bootstrapper) checkFinish(ctx context.Context) error {
597592 b .Ctx .Log .Debug ("executing vertices" )
598593 }
599594
600- executedVts , err : = b .VtxBlocked .ExecuteAll (
595+ _ , err = b .VtxBlocked .ExecuteAll (
601596 ctx ,
602597 b .Config .Ctx ,
603598 b ,
@@ -614,39 +609,18 @@ func (b *bootstrapper) checkFinish(ctx context.Context) error {
614609 if err != nil {
615610 return err
616611 }
617- if linearized {
618- b .processedCache . Flush ( )
619- return b .OnFinished (ctx , b . Config . SharedCfg . RequestID )
612+ if ! linearized {
613+ b .Ctx . Log . Debug ( "checking for stop vertex before finishing bootstrapping" )
614+ return b .Restart (ctx , true )
620615 }
621616
622- previouslyExecuted := b .executedStateTransitions
623- b .executedStateTransitions = executedVts
624-
625- // Note that executedVts < c*previouslyExecuted is enforced so that the
626- // bootstrapping process will terminate even as new vertices are being
627- // issued.
628- if executedVts > 0 && executedVts < previouslyExecuted / 2 && b .Config .RetryBootstrap {
629- b .Ctx .Log .Debug ("checking for more vertices before finishing bootstrapping" )
630- return b .Restart (ctx , true )
617+ // Invariant: edge will only be the stop vertex after its acceptance.
618+ edge := b .Manager .Edge (ctx )
619+ stopVertexID := edge [0 ]
620+ if err := b .VM .Linearize (ctx , stopVertexID ); err != nil {
621+ return err
631622 }
632623
633- // Notify the subnet that this chain is synced
634- b .Config .BootstrapTracker .Bootstrapped (b .Ctx .ChainID )
635624 b .processedCache .Flush ()
636-
637- // If the subnet hasn't finished bootstrapping, this chain should remain
638- // syncing.
639- if ! b .Config .BootstrapTracker .IsBootstrapped () {
640- if ! b .Config .SharedCfg .Restarted {
641- b .Ctx .Log .Info ("waiting for the remaining chains in this subnet to finish syncing" )
642- } else {
643- b .Ctx .Log .Debug ("waiting for the remaining chains in this subnet to finish syncing" )
644- }
645- // Restart bootstrapping after [bootstrappingDelay] to keep up to date
646- // on the latest tip.
647- b .Config .Timer .RegisterTimeout (bootstrappingDelay )
648- b .awaitingTimeout = true
649- return nil
650- }
651625 return b .OnFinished (ctx , b .Config .SharedCfg .RequestID )
652626}
0 commit comments