@@ -239,8 +239,8 @@ type indexerStatus struct {
239239}
240240
241241// blockData represents the indexable data of a single block being sent from the
242- // reader to the sender goroutine and optionally queued in blockDataCh inbetween .
243- // It also returns the latest revertCount known before reading the block data,
242+ // reader to the sender goroutine and optionally queued in blockDataCh between .
243+ // It also includes the latest revertCount known before reading the block data,
244244// which allows the sender to guarantee that all sent block data is always
245245// consistent with the indexer's canonical chain view while the reading of block
246246// data can still happen asynchronously.
@@ -352,10 +352,14 @@ func (s *indexServer) historicSendLoop() {
352352 case nextBlockData := <- s .blockDataCh :
353353 s .lock .Lock ()
354354 s .status .resetQueue = true
355+ // check if received block data is indeed from the next expected
356+ // block and is still guaranteed to be canonical; ignore and request
357+ // again otherwise.
355358 if ! s .status .needBlocks .IsEmpty () && s .status .needBlocks .First () == nextBlockData .blockNumber &&
356359 (nextBlockData .revertCount == s .status .revertCount || (nextBlockData .revertCount + 1 == s .status .revertCount && nextBlockData .blockNumber <= s .lastRevertBlock )) {
357360 s .status .ready , s .status .needBlocks = s .indexer .AddBlockData (nextBlockData .header , nextBlockData .receipts )
358- if nextBlockData .header != nil {
361+ // check if the has actually been found in the database
362+ if nextBlockData .header != nil && nextBlockData .receipts != nil {
359363 s .status .resetQueue = false
360364 if s .status .needBlocks .IsEmpty () {
361365 s .logDelivered (nextBlockData .blockNumber )
@@ -364,6 +368,16 @@ func (s *indexServer) historicSendLoop() {
364368 s .logDelivered (nextBlockData .blockNumber )
365369 }
366370 } else {
371+ // report error and update missingBlockCutoff in order to
372+ // avoid spinning forever on the same error.
373+ if time .Since (s .lastHistoryErrorLog ) >= time .Second * 10 {
374+ s .lastHistoryErrorLog = time .Now ()
375+ if nextBlockData .header == nil {
376+ log .Error ("Historical header is missing" , "number" , nextBlockData .blockNumber )
377+ } else {
378+ log .Error ("Historical receipts are missing" , "number" , nextBlockData .blockNumber , "hash" , nextBlockData .header .Hash ())
379+ }
380+ }
367381 s .missingBlockCutoff = max (s .missingBlockCutoff , nextBlockData .blockNumber + 1 )
368382 s .indexer .SetHistoryCutoff (max (s .historyCutoff , s .missingBlockCutoff ))
369383 s .status .ready , s .status .needBlocks = s .indexer .Status ()
@@ -484,17 +498,12 @@ func (s *indexServer) historicReadLoop() {
484498 if ! sendRange .IsEmpty () && ! status .suspended {
485499 // Send next item to the queue.
486500 bd := blockData {blockNumber : sendRange .First (), revertCount : status .revertCount }
487- if header := s .parent .chain .GetHeaderByNumber (bd .blockNumber ); header != nil {
488- if receipts := s .parent .chain .GetReceipts (header .Hash (), bd .blockNumber ); receipts != nil {
489- bd .header , bd .receipts = header , receipts
490- } else {
491- log .Error ("Historical receipts are missing" , "number" , bd .blockNumber , "hash" , header .Hash ())
492- }
493- } else {
494- log .Error ("Historical header missing" , "number" , bd .blockNumber )
501+ if bd .header = s .parent .chain .GetHeaderByNumber (bd .blockNumber ); bd .header != nil {
502+ bd .receipts = s .parent .chain .GetReceipts (bd .header .Hash (), bd .blockNumber )
495503 }
496- // Note that a response with empty block data is still sent in case of
504+ // Note that a response with missing block data is still sent in case of
497505 // a read error, signaling to the sender logic that something is missing.
506+ // This might be either due to a database error or a reorg.
498507 select {
499508 case s .blockDataCh <- bd :
500509 sendRange .SetFirst (bd .blockNumber + 1 )
0 commit comments