@@ -96,92 +96,113 @@ func TestDAFollower_HandleEvent(t *testing.T) {
9696}
9797
9898func TestDAFollower_HandleCatchup (t * testing.T ) {
99- t .Run ("normal_sequential_fetch_success" , func (t * testing.T ) {
100- daRetriever := NewMockDARetriever (t )
101- ctx := t .Context ()
99+ type spec struct {
100+ daHeight uint64
101+ initialPriorityHeights []uint64
102+ pipeErr error
103+ setupMock func (m * MockDARetriever )
104+ wantErrIs error
105+ wantPipedHeights []uint64
106+ wantRemainingPriority []uint64
107+ }
108+
109+ newFollower := func (t * testing.T , s spec , m * MockDARetriever ) (* daFollower , func () []common.DAHeightEvent ) {
110+ t .Helper ()
102111
103112 var pipedEvents []common.DAHeightEvent
104113 pipeEvent := func (_ context.Context , ev common.DAHeightEvent ) error {
105114 pipedEvents = append (pipedEvents , ev )
106- return nil
115+ return s . pipeErr
107116 }
108117
109118 follower := & daFollower {
110- retriever : daRetriever ,
119+ retriever : m ,
111120 eventSink : common .EventSinkFunc (pipeEvent ),
112121 logger : zerolog .Nop (),
113- priorityHeights : make ([]uint64 , 0 ),
114- }
115-
116- events := []common.DAHeightEvent {{DaHeight : 100 }}
117- daRetriever .On ("RetrieveFromDA" , mock .Anything , uint64 (100 )).Return (events , nil )
118-
119- err := follower .HandleCatchup (ctx , 100 )
120- require .NoError (t , err )
121- assert .Len (t , pipedEvents , 1 )
122- })
123-
124- t .Run ("normal_sequential_fetch_blob_not_found_ignored" , func (t * testing.T ) {
125- daRetriever := NewMockDARetriever (t )
126- ctx := t .Context ()
127-
128- follower := & daFollower {
129- retriever : daRetriever ,
130- eventSink : common .EventSinkFunc (func (_ context.Context , _ common.DAHeightEvent ) error { return nil }),
131- logger : zerolog .Nop (),
132- priorityHeights : make ([]uint64 , 0 ),
133- }
134-
135- daRetriever .On ("RetrieveFromDA" , mock .Anything , uint64 (100 )).Return (nil , datypes .ErrBlobNotFound )
136-
137- err := follower .HandleCatchup (ctx , 100 )
138- require .NoError (t , err )
139- })
140-
141- t .Run ("normal_sequential_fetch_error_propagated" , func (t * testing.T ) {
142- daRetriever := NewMockDARetriever (t )
143- ctx := t .Context ()
144-
145- follower := & daFollower {
146- retriever : daRetriever ,
147- eventSink : common .EventSinkFunc (func (_ context.Context , _ common.DAHeightEvent ) error { return nil }),
148- logger : zerolog .Nop (),
149- priorityHeights : make ([]uint64 , 0 ),
122+ priorityHeights : append ([]uint64 (nil ), s .initialPriorityHeights ... ),
150123 }
124+ return follower , func () []common.DAHeightEvent { return pipedEvents }
125+ }
151126
152- daRetriever .On ("RetrieveFromDA" , mock .Anything , uint64 (100 )).Return (nil , datypes .ErrHeightFromFuture )
153-
154- err := follower .HandleCatchup (ctx , 100 )
155- require .ErrorIs (t , err , datypes .ErrHeightFromFuture )
156- })
157-
158- t .Run ("priority_queue_handled_first" , func (t * testing.T ) {
159- daRetriever := NewMockDARetriever (t )
160- ctx := t .Context ()
127+ specs := map [string ]spec {
128+ "seq_ok" : {
129+ daHeight : 100 ,
130+ wantPipedHeights : []uint64 {100 },
131+ setupMock : func (m * MockDARetriever ) {
132+ m .On ("RetrieveFromDA" , mock .Anything , uint64 (100 )).
133+ Return ([]common.DAHeightEvent {{DaHeight : 100 }}, nil ).Once ()
134+ },
135+ },
136+ "seq_blob_missing" : {
137+ daHeight : 100 ,
138+ setupMock : func (m * MockDARetriever ) {
139+ m .On ("RetrieveFromDA" , mock .Anything , uint64 (100 )).
140+ Return (nil , datypes .ErrBlobNotFound ).Once ()
141+ },
142+ },
143+ "seq_err" : {
144+ daHeight : 100 ,
145+ wantErrIs : datypes .ErrHeightFromFuture ,
146+ setupMock : func (m * MockDARetriever ) {
147+ m .On ("RetrieveFromDA" , mock .Anything , uint64 (100 )).
148+ Return (nil , datypes .ErrHeightFromFuture ).Once ()
149+ },
150+ },
151+ "prio_first" : {
152+ daHeight : 100 ,
153+ initialPriorityHeights : []uint64 {105 },
154+ wantPipedHeights : []uint64 {105 , 100 },
155+ setupMock : func (m * MockDARetriever ) {
156+ m .On ("RetrieveFromDA" , mock .Anything , uint64 (105 )).
157+ Return ([]common.DAHeightEvent {{DaHeight : 105 }}, nil ).Once ()
158+ m .On ("RetrieveFromDA" , mock .Anything , uint64 (100 )).
159+ Return ([]common.DAHeightEvent {{DaHeight : 100 }}, nil ).Once ()
160+ },
161+ },
162+ "skip_stale_prio_already_included" : {
163+ daHeight : 100 ,
164+ initialPriorityHeights : []uint64 {99 },
165+ wantPipedHeights : []uint64 {100 },
166+ setupMock : func (m * MockDARetriever ) {
167+ // stale priority hint (< daHeight) is discarded; only sequential height is fetched
168+ m .On ("RetrieveFromDA" , mock .Anything , uint64 (100 )).
169+ Return ([]common.DAHeightEvent {{DaHeight : 100 }}, nil ).Once ()
170+ },
171+ },
172+ }
161173
162- var pipedEvents []common.DAHeightEvent
163- pipeEvent := func (_ context.Context , ev common.DAHeightEvent ) error {
164- pipedEvents = append (pipedEvents , ev )
165- return nil
166- }
174+ for name , s := range specs {
175+ t .Run (name , func (t * testing.T ) {
176+ daRetriever := NewMockDARetriever (t )
177+ if s .setupMock != nil {
178+ s .setupMock (daRetriever )
179+ }
167180
168- follower := & daFollower {
169- retriever : daRetriever ,
170- eventSink : common .EventSinkFunc (pipeEvent ),
171- logger : zerolog .Nop (),
172- priorityHeights : []uint64 {105 }, // Priority height to fetch
173- }
181+ follower , getPipedEvents := newFollower (t , s , daRetriever )
182+ err := follower .HandleCatchup (t .Context (), s .daHeight )
174183
175- daRetriever .On ("RetrieveFromDA" , mock .Anything , uint64 (105 )).Return ([]common.DAHeightEvent {{DaHeight : 105 }}, nil ).Once ()
176- daRetriever .On ("RetrieveFromDA" , mock .Anything , uint64 (100 )).Return ([]common.DAHeightEvent {{DaHeight : 100 }}, nil ).Once ()
184+ if s .wantErrIs != nil {
185+ require .ErrorIs (t , err , s .wantErrIs )
186+ } else {
187+ require .NoError (t , err )
188+ }
177189
178- err := follower .HandleCatchup (ctx , 100 )
179- require .NoError (t , err )
190+ pipedEvents := getPipedEvents ()
191+ gotHeights := make ([]uint64 , 0 , len (pipedEvents ))
192+ for _ , ev := range pipedEvents {
193+ gotHeights = append (gotHeights , ev .DaHeight )
194+ }
195+ wantHeights := s .wantPipedHeights
196+ if wantHeights == nil {
197+ wantHeights = []uint64 {}
198+ }
199+ assert .Equal (t , wantHeights , gotHeights )
180200
181- // It should pipe 105 then 100
182- assert .Len (t , pipedEvents , 2 )
183- assert .Equal (t , uint64 (105 ), pipedEvents [0 ].DaHeight )
184- assert .Equal (t , uint64 (100 ), pipedEvents [1 ].DaHeight )
185- assert .Empty (t , follower .priorityHeights )
186- })
201+ if s .wantRemainingPriority != nil {
202+ assert .Equal (t , s .wantRemainingPriority , follower .priorityHeights )
203+ } else {
204+ assert .Empty (t , follower .priorityHeights )
205+ }
206+ })
207+ }
187208}
0 commit comments