@@ -166,6 +166,8 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6
166166 close (eventsChan )
167167 }()
168168
169+ blockHeadersQueue := []flow.BlockHeader {}
170+
169171 for ctx .Err () == nil {
170172 select {
171173 case <- ctx .Done ():
@@ -219,14 +221,24 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6
219221 for _ , evt := range blockEvents .Events {
220222 r .keyLock .NotifyTransaction (evt .TransactionID )
221223 }
222- r .keyLock .NotifyBlock (
223- flow.BlockHeader {
224- ID : blockEvents .BlockID ,
225- Height : blockEvents .Height ,
226- },
227- )
228224 lastReceivedHeight = blockHeader .Height
229225
226+ blockHeadersQueue = append (blockHeadersQueue , * blockHeader )
227+
228+ // The current `blockHeader` has a status of `BlockStatusFinalized`,
229+ // but calling `NotifyBlock` might fail if the AN has not actually
230+ // finished syncing all collections.
231+ // Hence, we keep a small queue of the incoming block headers, so
232+ // that we can call `NotifyBlock` on block N-5, where N is the
233+ // height of the current block header. This will give enough time
234+ // for the block to be sealed.
235+ if len (blockHeadersQueue ) > 5 {
236+ earliestBlockHeader := blockHeadersQueue [0 ]
237+ r .keyLock .NotifyBlock (earliestBlockHeader )
238+
239+ blockHeadersQueue = blockHeadersQueue [1 :]
240+ }
241+
230242 eventsChan <- evmEvents
231243
232244 case err , ok := <- errChan :
0 commit comments