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

Method pollMaxHeight

controller/consensus.go:626–688  ·  view source on GitHub ↗

pollMaxHeight() polls all peers for their local MaxHeight and totalVDFIterations for a specific chainId NOTE: unlike other P2P transmissions - RequestBlock enforces a minimum reputation on `mustConnects` to ensure a byzantine validator cannot cause syncing issues above max_height

(backoff int)

Source from the content-addressed store, hash-verified

624// NOTE: unlike other P2P transmissions - RequestBlock enforces a minimum reputation on `mustConnects`
625// to ensure a byzantine validator cannot cause syncing issues above max_height
626func (c *Controller) pollMaxHeight(backoff int) (max, minVDF uint64, syncingPeerList []string) {
627 // initialize max height and minimumVDFIterations to -1
628 maxHeight, minimumVDFIterations := -1, -1
629 // empty inbox to start fresh
630 c.emptyInbox(Block)
631 // log the initialization
632 c.log.Infof("Polling chain peers for max height")
633 // initialize the syncing peers list
634 syncingPeerList = make([]string, 0)
635 // ask only for 'max height' from all peers
636 go c.RequestBlock(true)
637 // debug log the current status
638 c.log.Debug("Waiting for peer max heights")
639 // loop until timeout case
640 for {
641 // block until one of the cases is satisfied
642 select {
643 // handle the inbound message
644 case m := <-c.P2P.Inbox(Block):
645 // unmarshal the inbound message payload as a block message
646 blockMessage := new(lib.BlockMessage)
647 if err := lib.Unmarshal(m.Message, blockMessage); err != nil {
648 // log the unexpected behavior
649 c.log.Warnf("Invalid block message response from %s", lib.BytesToTruncatedString(m.Sender.Address.PublicKey))
650 // slash the peer reputation
651 c.P2P.ChangeReputation(m.Sender.Address.PublicKey, p2p.InvalidMsgRep)
652 // reset loop
653 continue
654 }
655 // log the receipt of the block message
656 c.log.Debugf("Received a block response from peer %s with max height at %d", lib.BytesToTruncatedString(m.Sender.Address.PublicKey), maxHeight)
657 // don't listen to any peers below the minimumVDFIterations
658 if int(blockMessage.TotalVdfIterations) < minimumVDFIterations {
659 // log the status
660 c.log.Warnf("Ignoring below the minimum vdf iterations")
661 // reset loop
662 continue
663 }
664 // update the minimum vdf iterations
665 minimumVDFIterations = int(blockMessage.TotalVdfIterations)
666 // add to syncing peer list
667 syncingPeerList = append(syncingPeerList, lib.BytesToString(m.Sender.Address.PublicKey))
668 // if the maximum height is exceeded, update the max height
669 if int(blockMessage.MaxHeight) > maxHeight {
670 // reset syncing variables if peer exceeds the previous minimum vdf iterations
671 maxHeight = int(blockMessage.MaxHeight)
672 }
673 // if a timeout occurred
674 case <-time.After(p2p.PollMaxHeightTimeoutS * time.Second * time.Duration(backoff)):
675 // if the maximum height or vdf iterations remains unset
676 if maxHeight == -1 || minimumVDFIterations == -1 {
677 // log the status of no heights received
678 c.log.Warn("No heights received from peers. Trying again")
679 // try again with greater backoff
680 return c.pollMaxHeight(backoff + 1)
681 }
682 // log the max height among the peers
683 c.log.Debugf("Peer max height is %d 🔝", maxHeight)

Callers 1

SyncMethod · 0.95

Calls 12

emptyInboxMethod · 0.95
RequestBlockMethod · 0.95
UnmarshalFunction · 0.92
BytesToTruncatedStringFunction · 0.92
BytesToStringFunction · 0.92
InboxMethod · 0.80
ChangeReputationMethod · 0.80
InfofMethod · 0.65
DebugMethod · 0.65
WarnfMethod · 0.65
DebugfMethod · 0.65
WarnMethod · 0.65

Tested by

no test coverage detected