@@ -181,6 +181,123 @@ func TestService_GetRecentPreState(t *testing.T) {
181181 require .NotNil (t , service .getRecentPreState (ctx , & ethpb.Checkpoint {Epoch : 1 , Root : ckRoot }))
182182}
183183
184+ func TestService_GetRecentPreState_Epoch_0 (t * testing.T ) {
185+ service , _ := minimalTestService (t )
186+ ctx := t .Context ()
187+ require .IsNil (t , service .getRecentPreState (ctx , & ethpb.Checkpoint {}))
188+ }
189+
190+ func TestService_GetRecentPreState_Old_Checkpoint (t * testing.T ) {
191+ service , _ := minimalTestService (t )
192+ ctx := t .Context ()
193+ s , err := util .NewBeaconState ()
194+ require .NoError (t , err )
195+ ckRoot := bytesutil .PadTo ([]byte {'A' }, fieldparams .RootLength )
196+ cp0 := & ethpb.Checkpoint {Epoch : 0 , Root : ckRoot }
197+ err = s .SetFinalizedCheckpoint (cp0 )
198+ require .NoError (t , err )
199+
200+ st , root , err := prepareForkchoiceState (ctx , 33 , [32 ]byte (ckRoot ), [32 ]byte {}, [32 ]byte {'R' }, cp0 , cp0 )
201+ require .NoError (t , err )
202+ require .NoError (t , service .cfg .ForkChoiceStore .InsertNode (ctx , st , root ))
203+ service .head = & head {
204+ root : [32 ]byte (ckRoot ),
205+ state : s ,
206+ slot : 33 ,
207+ }
208+ require .IsNil (t , service .getRecentPreState (ctx , & ethpb.Checkpoint {}))
209+ }
210+
211+ func TestService_GetRecentPreState_Same_DependentRoots (t * testing.T ) {
212+ service , _ := minimalTestService (t )
213+ ctx := t .Context ()
214+ s , err := util .NewBeaconState ()
215+ require .NoError (t , err )
216+ ckRoot := bytesutil .PadTo ([]byte {'A' }, fieldparams .RootLength )
217+ cp0 := & ethpb.Checkpoint {Epoch : 0 , Root : ckRoot }
218+
219+ // Create a fork 31 <-- 32 <--- 64
220+ // \---------33
221+ // With the same dependent root at epoch 0 for a checkpoint at epoch 2
222+ st , blk , err := prepareForkchoiceState (ctx , 31 , [32 ]byte (ckRoot ), [32 ]byte {}, [32 ]byte {}, cp0 , cp0 )
223+ require .NoError (t , err )
224+ require .NoError (t , service .cfg .ForkChoiceStore .InsertNode (ctx , st , blk ))
225+ st , blk , err = prepareForkchoiceState (ctx , 32 , [32 ]byte {'S' }, blk .Root (), [32 ]byte {}, cp0 , cp0 )
226+ require .NoError (t , err )
227+ require .NoError (t , service .cfg .ForkChoiceStore .InsertNode (ctx , st , blk ))
228+ st , blk , err = prepareForkchoiceState (ctx , 64 , [32 ]byte {'T' }, blk .Root (), [32 ]byte {}, cp0 , cp0 )
229+ require .NoError (t , err )
230+ require .NoError (t , service .cfg .ForkChoiceStore .InsertNode (ctx , st , blk ))
231+ st , blk , err = prepareForkchoiceState (ctx , 33 , [32 ]byte {'U' }, [32 ]byte (ckRoot ), [32 ]byte {}, cp0 , cp0 )
232+ require .NoError (t , err )
233+ require .NoError (t , service .cfg .ForkChoiceStore .InsertNode (ctx , st , blk ))
234+ cpRoot := blk .Root ()
235+
236+ service .head = & head {
237+ root : [32 ]byte {'T' },
238+ state : s ,
239+ slot : 64 ,
240+ }
241+ require .NotNil (t , service .getRecentPreState (ctx , & ethpb.Checkpoint {Epoch : 2 , Root : cpRoot [:]}))
242+ }
243+
244+ func TestService_GetRecentPreState_Different_DependentRoots (t * testing.T ) {
245+ service , _ := minimalTestService (t )
246+ ctx := t .Context ()
247+ s , err := util .NewBeaconState ()
248+ require .NoError (t , err )
249+ ckRoot := bytesutil .PadTo ([]byte {'A' }, fieldparams .RootLength )
250+ cp0 := & ethpb.Checkpoint {Epoch : 0 , Root : ckRoot }
251+
252+ // Create a fork 30 <-- 31 <-- 32 <--- 64
253+ // \---------33
254+ // With the same dependent root at epoch 0 for a checkpoint at epoch 2
255+ st , blk , err := prepareForkchoiceState (ctx , 30 , [32 ]byte (ckRoot ), [32 ]byte {}, [32 ]byte {}, cp0 , cp0 )
256+ require .NoError (t , err )
257+ require .NoError (t , service .cfg .ForkChoiceStore .InsertNode (ctx , st , blk ))
258+ st , blk , err = prepareForkchoiceState (ctx , 31 , [32 ]byte {'S' }, blk .Root (), [32 ]byte {}, cp0 , cp0 )
259+ require .NoError (t , err )
260+ require .NoError (t , service .cfg .ForkChoiceStore .InsertNode (ctx , st , blk ))
261+ st , blk , err = prepareForkchoiceState (ctx , 32 , [32 ]byte {'T' }, blk .Root (), [32 ]byte {}, cp0 , cp0 )
262+ require .NoError (t , err )
263+ require .NoError (t , service .cfg .ForkChoiceStore .InsertNode (ctx , st , blk ))
264+ st , blk , err = prepareForkchoiceState (ctx , 64 , [32 ]byte {'U' }, blk .Root (), [32 ]byte {}, cp0 , cp0 )
265+ require .NoError (t , err )
266+ require .NoError (t , service .cfg .ForkChoiceStore .InsertNode (ctx , st , blk ))
267+ st , blk , err = prepareForkchoiceState (ctx , 33 , [32 ]byte {'V' }, [32 ]byte (ckRoot ), [32 ]byte {}, cp0 , cp0 )
268+ require .NoError (t , err )
269+ require .NoError (t , service .cfg .ForkChoiceStore .InsertNode (ctx , st , blk ))
270+ cpRoot := blk .Root ()
271+
272+ service .head = & head {
273+ root : [32 ]byte {'T' },
274+ state : s ,
275+ slot : 64 ,
276+ }
277+ require .IsNil (t , service .getRecentPreState (ctx , & ethpb.Checkpoint {Epoch : 2 , Root : cpRoot [:]}))
278+ }
279+
280+ func TestService_GetRecentPreState_Different (t * testing.T ) {
281+ service , _ := minimalTestService (t )
282+ ctx := t .Context ()
283+ s , err := util .NewBeaconState ()
284+ require .NoError (t , err )
285+ ckRoot := bytesutil .PadTo ([]byte {'A' }, fieldparams .RootLength )
286+ cp0 := & ethpb.Checkpoint {Epoch : 0 , Root : ckRoot }
287+ err = s .SetFinalizedCheckpoint (cp0 )
288+ require .NoError (t , err )
289+
290+ st , root , err := prepareForkchoiceState (ctx , 33 , [32 ]byte (ckRoot ), [32 ]byte {}, [32 ]byte {'R' }, cp0 , cp0 )
291+ require .NoError (t , err )
292+ require .NoError (t , service .cfg .ForkChoiceStore .InsertNode (ctx , st , root ))
293+ service .head = & head {
294+ root : [32 ]byte (ckRoot ),
295+ state : s ,
296+ slot : 33 ,
297+ }
298+ require .IsNil (t , service .getRecentPreState (ctx , & ethpb.Checkpoint {}))
299+ }
300+
184301func TestService_GetAttPreState_Concurrency (t * testing.T ) {
185302 service , _ := minimalTestService (t )
186303 ctx := t .Context ()
0 commit comments