MCPcopy
hub / github.com/canopy-network/canopy / Sync

Method Sync

controller/consensus.go:69–149  ·  view source on GitHub ↗

Sync() downloads the blockchain from peers until 'synced' to the latest 'height' 1) Get the height and begin block params from the state_machine 2) Get peer max_height from P2P 3) Fill a queue of blocks by requesting them from randomly chosen peers 4) When available, process next block from queue 5)

()

Source from the content-addressed store, hash-verified

67// 7) Do this until reach the max-peer-height
68// 8) Stay on top by listening to incoming cert messages
69func (c *Controller) Sync() {
70 // log the initialization of the syncing process
71 c.log.Infof("Sync started 🔄 for committee %d", c.Config.ChainId)
72 // set the Controller as 'syncing'
73 c.isSyncing.Store(true)
74 // check if node is alone in the validator set
75 if c.singleNodeNetwork() && len(c.checkpoints) == 0 {
76 // complete syncing
77 c.finishSyncing()
78 // exit
79 return
80 }
81 // Find the height the FSM is expecting to receive next
82 fsmHeight := c.FSM.Height()
83 // queue contains block requests either in-flight or completed
84 queue := map[uint64]blockSyncRequest{}
85 // How often to send block requests to maintain the queue
86 requestTicker := time.NewTicker(blockRequestInterval)
87 defer requestTicker.Stop()
88 // Get an initial max height, min vdf iterations and syncing peers
89 maxHeight, minVDFIterations, _ := c.pollMaxHeight(1)
90 c.log.Infof("Starting sync 🔄 at height %d", fsmHeight)
91 // Create a limiter to prevent peers from disconnecting and slashing rep
92 limiter := lib.NewLimiter(p2p.MaxBlockReqPerWindow*rateScaleFactor, c.P2P.MaxPossiblePeers()*p2p.MaxBlockReqPerWindow, p2p.BlockReqWindowS, "SYNC", c.log)
93
94 // Loop until the sync is complete
95 // The purpose is to keep the queue full and hand the next block to the FSM
96 // - List of current peers queried from P2P module
97 // - Block requests are sent to a peer if there is room available in the queue
98 // - Peers are chosen randomly from ones which are not rate-limited
99 // - Block responses are verified and given to the FSM in the expected order
100 for !c.syncingDone(maxHeight, minVDFIterations) {
101 select {
102 case <-limiter.TimeToReset():
103 limiter.Reset()
104 case <-requestTicker.C:
105 // Get current chain height
106 fsmHeight := c.FSM.Height()
107 // Get an updated list of available peers
108 peers, _, _ := c.P2P.PeerSet.GetAllInfos()
109 // Update syncing peers list
110 syncingPeers := make([]string, len(peers))
111 for _, peer := range peers {
112 syncingPeers = append(syncingPeers, lib.BytesToString(peer.Address.PublicKey))
113 }
114 // Calculate the height to stop at when updating queue
115 stopHeight := min(fsmHeight+blockSyncQueueSize, maxHeight)
116 // Send block requests for any missing heights in the queue
117 c.sendBlockRequests(fsmHeight, stopHeight, queue, limiter, syncingPeers)
118 case msg := <-c.P2P.Inbox(Block):
119 // verify the response
120 blockMsg, height := c.verifyResponse(msg, queue)
121 // Update queued request with this response
122 if blockMsg != nil {
123 c.log.Debugf("Received height %d from %s", height, lib.BytesToTruncatedString(msg.Sender.Address.PublicKey))
124 // find the queued request for this height
125 // verifyResponse() confirms this height is present in the queue
126 req := queue[height]

Callers 1

StartMethod · 0.95

Calls 15

singleNodeNetworkMethod · 0.95
finishSyncingMethod · 0.95
pollMaxHeightMethod · 0.95
syncingDoneMethod · 0.95
sendBlockRequestsMethod · 0.95
verifyResponseMethod · 0.95
processQueueMethod · 0.95
applyTimeoutsMethod · 0.95
NewLimiterFunction · 0.92
BytesToStringFunction · 0.92
BytesToTruncatedStringFunction · 0.92
StoreMethod · 0.80

Tested by

no test coverage detected