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

Method HandlePeerBlock

controller/block.go:504–582  ·  view source on GitHub ↗

HandlePeerBlock() validates and handles an inbound certificate (with a block) from a remote peer

(msg *lib.BlockMessage, syncing bool)

Source from the content-addressed store, hash-verified

502
503// HandlePeerBlock() validates and handles an inbound certificate (with a block) from a remote peer
504func (c *Controller) HandlePeerBlock(msg *lib.BlockMessage, syncing bool) (*lib.QuorumCertificate, lib.ErrorI) {
505 // log the start of 'peer block handling'
506 c.log.Info("Handling peer block")
507 // define a convenience variable for the certificate
508 qc := msg.BlockAndCertificate
509 // do a basic validation on the QC before loading the committee
510 if err := qc.CheckBasic(); err != nil {
511 // exit with error
512 return nil, err
513 }
514 // if syncing the blockchain
515 if syncing {
516 // use checkpoints to protect against long-range attacks
517 if qc.Header.Height%CheckpointFrequency == 0 {
518 // attempt to load the checkpoint from the file
519 checkpoint := c.checkpointFromFile(qc.Header.Height, qc.Header.ChainId)
520 // if checkpoint loading from file failed
521 if checkpoint == nil {
522 var err lib.ErrorI
523 // get the checkpoint from the base chain (or file if independent)
524 checkpoint, err = c.RCManager.GetCheckpoint(c.LoadRootChainId(qc.Header.Height), qc.Header.Height, c.Config.ChainId)
525 // if getting the checkpoint failed
526 if err != nil {
527 // warn of the inability to get the checkpoint
528 c.log.Warnf(err.Error())
529 }
530 }
531 // if checkpoint fails
532 if len(checkpoint) != 0 && !bytes.Equal(qc.BlockHash, checkpoint) {
533 // log and kill program
534 c.log.Fatalf("Invalid checkpoint %s vs %s at height %d", lib.BytesToString(qc.BlockHash), checkpoint, qc.Header.Height)
535 }
536 }
537 } else {
538 // load the committee from the root chain using the root height embedded in the certificate message
539 v, err := c.Consensus.LoadCommittee(c.LoadRootChainId(qc.Header.Height), qc.Header.RootHeight)
540 if err != nil {
541 // exit with error
542 return nil, err
543 }
544 // validate the quorum certificate
545 isPartialQC, err := qc.Check(v, c.LoadMaxBlockSize(), &lib.View{NetworkId: c.Config.NetworkID, ChainId: c.Config.ChainId}, false)
546 if err != nil {
547 // exit with error
548 return nil, err
549 }
550 // if the quorum certificate doesn't have a +2/3rds majority
551 if isPartialQC {
552 // exit with error
553 return nil, lib.ErrNoMaj23()
554 }
555 // update the non signer percent for the validators
556 c.Metrics.UpdateNonSignerPercent(qc.Signature, v)
557 }
558 // ensure the proposal inside the quorum certificate is valid at a stateless level
559 block, err := qc.CheckProposalBasic(c.FSM.Height(), c.Config.NetworkID, c.Config.ChainId)
560 // if this certificate isn't finalized
561 if err == nil && qc.Header.Phase != lib.Phase_PRECOMMIT_VOTE {

Callers 2

processQueueMethod · 0.95
ListenForBlockMethod · 0.95

Calls 15

checkpointFromFileMethod · 0.95
LoadRootChainIdMethod · 0.95
LoadMaxBlockSizeMethod · 0.95
CommitCertificateMethod · 0.95
BytesToStringFunction · 0.92
ErrNoMaj23Function · 0.92
ErrWrongPhaseFunction · 0.92
EqualMethod · 0.80
CheckProposalBasicMethod · 0.80
InfoMethod · 0.65
GetCheckpointMethod · 0.65

Tested by

no test coverage detected