@@ -13,10 +13,11 @@ import (
13
13
"sync"
14
14
"time"
15
15
16
- "github.com/ChainSafe/gossamer/dot/peerset "
16
+ "github.com/ChainSafe/chaindb "
17
17
"github.com/libp2p/go-libp2p-core/peer"
18
18
19
19
"github.com/ChainSafe/gossamer/dot/network"
20
+ "github.com/ChainSafe/gossamer/dot/peerset"
20
21
"github.com/ChainSafe/gossamer/dot/types"
21
22
"github.com/ChainSafe/gossamer/lib/common"
22
23
"github.com/ChainSafe/gossamer/lib/common/variadic"
@@ -522,7 +523,7 @@ func (cs *chainSync) setMode(mode chainSyncState) {
522
523
case bootstrap :
523
524
cs .handler = newBootstrapSyncer (cs .blockState )
524
525
case tip :
525
- cs .handler = newTipSyncer (cs .blockState , cs .pendingBlocks , cs .readyBlocks )
526
+ cs .handler = newTipSyncer (cs .blockState , cs .pendingBlocks , cs .readyBlocks , cs . handleReadyBlock )
526
527
}
527
528
528
529
cs .state = mode
@@ -692,41 +693,59 @@ func (cs *chainSync) doSync(req *network.BlockRequestMessage, peersTried map[pee
692
693
// response was validated! place into ready block queue
693
694
for _ , bd := range resp .BlockData {
694
695
// block is ready to be processed!
695
- handleReadyBlock (bd , cs . pendingBlocks , cs . readyBlocks )
696
+ cs . handleReadyBlock (bd )
696
697
}
697
698
698
699
return nil
699
700
}
700
701
701
- func handleReadyBlock (bd * types.BlockData , pendingBlocks DisjointBlockSet , readyBlocks * blockQueue ) {
702
- // see if there are any descendents in the pending queue that are now ready to be processed,
703
- // as we have just become aware of their parent block
702
+ func (cs * chainSync ) handleReadyBlock (bd * types.BlockData ) {
703
+ if cs .readyBlocks .has (bd .Hash ) {
704
+ logger .Tracef ("ignoring block %s in response, already in ready queue" , bd .Hash )
705
+ return
706
+ }
704
707
705
708
// if header was not requested, get it from the pending set
706
709
// if we're expecting headers, validate should ensure we have a header
707
710
if bd .Header == nil {
708
- block := pendingBlocks .getBlock (bd .Hash )
711
+ block := cs . pendingBlocks .getBlock (bd .Hash )
709
712
if block == nil {
710
- logger .Criticalf ("block with unknown header is ready: hash=%s" , bd .Hash )
713
+ // block wasn't in the pending set!
714
+ // let's check the db as maybe we already processed it
715
+ has , err := cs .blockState .HasHeader (bd .Hash )
716
+ if err != nil && ! errors .Is (err , chaindb .ErrKeyNotFound ) {
717
+ logger .Debugf ("failed to check if header is known for hash %s: %s" , bd .Hash , err )
718
+ return
719
+ }
720
+
721
+ if has {
722
+ logger .Tracef ("ignoring block we've already processed, hash=%s" , bd .Hash )
723
+ return
724
+ }
725
+
726
+ // this is bad and shouldn't happen
727
+ logger .Errorf ("block with unknown header is ready: hash=%s" , bd .Hash )
711
728
return
712
729
}
713
730
714
731
bd .Header = block .header
715
732
}
716
733
717
734
if bd .Header == nil {
718
- logger .Criticalf ("new ready block number (unknown) with hash %s" , bd .Hash )
735
+ logger .Errorf ("new ready block number (unknown) with hash %s" , bd .Hash )
719
736
return
720
737
}
721
738
722
739
logger .Tracef ("new ready block number %s with hash %s" , bd .Header .Number , bd .Hash )
723
740
741
+ // see if there are any descendents in the pending queue that are now ready to be processed,
742
+ // as we have just become aware of their parent block
724
743
ready := []* types.BlockData {bd }
725
- ready = pendingBlocks .getReadyDescendants (bd .Hash , ready )
744
+ ready = cs . pendingBlocks .getReadyDescendants (bd .Hash , ready )
726
745
727
746
for _ , rb := range ready {
728
- pendingBlocks .removeBlock (rb .Hash )
729
- readyBlocks .push (rb )
747
+ cs . pendingBlocks .removeBlock (rb .Hash )
748
+ cs . readyBlocks .push (rb )
730
749
}
731
750
}
732
751
0 commit comments