@@ -11,7 +11,7 @@ import (
1111
1212type getHeaderFn func (context.Context , uint64 ) (* types.Header , error )
1313
14- func queryLatestFinalizedHeader (ctx context.Context , getHeader getHeaderFn , latestBlockNumber uint64 ) (uint64 , []* ETHHeader , error ) {
14+ func queryLatestFinalizedHeader (ctx context.Context , getHeader getHeaderFn , latestBlockNumber uint64 , forkSpecs [] * ForkSpec ) (uint64 , []* ETHHeader , error ) {
1515 logger := log .GetLogger ()
1616 for i := latestBlockNumber ; i > 0 ; i -- {
1717 header , err := getHeader (ctx , i )
@@ -29,7 +29,7 @@ func queryLatestFinalizedHeader(ctx context.Context, getHeader getHeaderFn, late
2929
3030 logger .DebugContext (ctx , "Try to seek verifying headers to finalize" , "probablyFinalized" , probablyFinalized , "latest" , latestBlockNumber )
3131
32- headers , err := queryFinalizedHeader (ctx , getHeader , probablyFinalized , latestBlockNumber )
32+ headers , err := queryFinalizedHeader (ctx , getHeader , probablyFinalized , latestBlockNumber , forkSpecs )
3333 if err != nil {
3434 return 0 , nil , err
3535 }
@@ -41,31 +41,71 @@ func queryLatestFinalizedHeader(ctx context.Context, getHeader getHeaderFn, late
4141 return 0 , nil , fmt .Errorf ("no finalized header found: %d" , latestBlockNumber )
4242}
4343
44- func queryFinalizedHeader (ctx context.Context , fn getHeaderFn , height uint64 , limitHeight uint64 ) ([]* ETHHeader , error ) {
44+ // queryFinalizedHeader returns finalized header sequence
45+ // ex)
46+ // 72486611 -> target 72486610 -> target 72486608
47+ // 72486611 --------------------> source 72486608
48+ //
49+ // 72486610 -> target 72486608 -> target 72486607
50+ // 72486610 --------------------> source 72486607
51+ //
52+ // 72476712 -> target 72476710 -> target 72476708
53+ // 72476712 --------------------> source 72476708
54+ func queryFinalizedHeader (ctx context.Context , fn getHeaderFn , height uint64 , limitHeight uint64 , forkSpecs []* ForkSpec ) ([]* ETHHeader , error ) {
4555 var ethHeaders []* ETHHeader
4656 for i := height ; i + 2 <= limitHeight ; i ++ {
47- targetBlock , targetETHHeader , _ , err := queryETHHeader (ctx , fn , i )
48- if err != nil {
49- return nil , err
50- }
51- childBlock , childETHHeader , childVote , err := queryETHHeader (ctx , fn , i + 1 )
52- if err != nil {
53- return nil , err
54- }
55- _ , grandChildETHHeader , grandChildVote , err := queryETHHeader (ctx , fn , i + 2 )
57+ finalizedBlock , finalizedETHHeader , _ , err := queryETHHeader (ctx , fn , i )
5658 if err != nil {
5759 return nil , err
5860 }
61+ ethHeaders = append (ethHeaders , finalizedETHHeader )
5962
60- if childVote == nil || grandChildVote == nil ||
61- grandChildVote .Data .SourceNumber != targetBlock .Number .Uint64 () ||
62- grandChildVote .Data .SourceNumber != childVote .Data .TargetNumber ||
63- grandChildVote .Data .TargetNumber != childBlock .Number .Uint64 () {
64- // Append to verify header sequence
65- ethHeaders = append (ethHeaders , targetETHHeader )
66- continue
63+ // child: descendant whose vote.TargetNumber == finalized.Number
64+ var childList []* ETHHeader
65+ for j := i + 1 ; j + 1 <= limitHeight ; j ++ {
66+ childHeader , childETHHeader , childVote , err := queryETHHeader (ctx , fn , j )
67+ if err != nil {
68+ return nil , err
69+ }
70+ childList = append (childList , childETHHeader )
71+ if childVote == nil {
72+ continue
73+ }
74+ if childVote .Data .TargetNumber != finalizedBlock .Number .Uint64 () || childVote .Data .TargetHash != finalizedBlock .Hash () {
75+ continue
76+ }
77+
78+ // grandChild: descendant whose vote.TargetNumber == child.Number and vote.SourceNumber == child.TargetNumber
79+ var grandChildList []* ETHHeader
80+ for k := j + 1 ; k <= limitHeight ; k ++ {
81+ grandChildHeader , grandChildETHHeader , grandChildVote , err := queryETHHeader (ctx , fn , k )
82+ if err != nil {
83+ return nil , err
84+ }
85+
86+ // Ensure distance is less than or equal to k_ancestor_generation_depth
87+ currentForkSpec , _ , err := FindTargetForkSpec (forkSpecs , grandChildHeader .Number .Uint64 (), MilliTimestamp (grandChildHeader ))
88+ if err != nil {
89+ return nil , err
90+ }
91+ if k - j > uint64 (currentForkSpec .KAncestorGenerationDepth ) {
92+ break
93+ }
94+
95+ grandChildList = append (grandChildList , grandChildETHHeader )
96+ if grandChildVote == nil {
97+ continue
98+ }
99+ if grandChildVote .Data .SourceNumber == childVote .Data .TargetNumber &&
100+ grandChildVote .Data .SourceHash == childVote .Data .TargetHash &&
101+ grandChildVote .Data .TargetNumber == childHeader .Number .Uint64 () &&
102+ grandChildVote .Data .TargetHash == childHeader .Hash () {
103+ // Found headers.
104+ // ELC Requires all sequential headers from the starting header
105+ return append (append (ethHeaders , childList ... ), grandChildList ... ), nil
106+ }
107+ }
67108 }
68- return append (ethHeaders , targetETHHeader , childETHHeader , grandChildETHHeader ), nil
69109 }
70110 log .GetLogger ().DebugContext (ctx , "Insufficient verifying headers to finalize" , "height" , height , "limit" , limitHeight )
71111 return nil , nil
0 commit comments