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

Method CheckAndSetLastCertificate

controller/block.go:586–632  ·  view source on GitHub ↗

CheckAndSetLastCertificate() validates the last quorum certificate included in the block and sets it in the ephemeral indexer NOTE: This must come before ApplyBlock in order to have the proposers 'lastCertificate' which is used for distributing rewards

(candidate *lib.BlockHeader)

Source from the content-addressed store, hash-verified

584// CheckAndSetLastCertificate() validates the last quorum certificate included in the block and sets it in the ephemeral indexer
585// NOTE: This must come before ApplyBlock in order to have the proposers 'lastCertificate' which is used for distributing rewards
586func (c *Controller) CheckAndSetLastCertificate(candidate *lib.BlockHeader) lib.ErrorI {
587 if candidate.Height > 1 {
588 // load the last quorum certificate from state
589 lastCertificate, err := c.FSM.LoadCertificateHashesOnly(candidate.Height - 1)
590 // if an error occurred
591 if err != nil {
592 // exit with error
593 return err
594 }
595 // ensure the candidate 'last certificate' is for the same block and result as the expected
596 if !candidate.LastQuorumCertificate.EqualPayloads(lastCertificate) {
597 // exit with error
598 return lib.ErrInvalidLastQuorumCertificate()
599 }
600 // the synced blocks were already validated during consensus, no need to validate again
601 if !c.Syncing().Load() {
602 // define a convenience variable for the 'root height'
603 rHeight, height := candidate.LastQuorumCertificate.Header.RootHeight, candidate.LastQuorumCertificate.Header.Height
604 // get the committee from the 'root chain' from the n-1 height because state heights represent 'end block state' once committed
605 vs, err := c.LoadCommittee(c.LoadRootChainId(height), rHeight) // TODO investigate - during consensus it works without -1 but during syncing might need -1?
606 if err != nil {
607 // exit with error
608 return err
609 }
610 // ensure the last quorum certificate is valid
611 isPartialQC, err := candidate.LastQuorumCertificate.Check(vs, 0, &lib.View{
612 Height: candidate.Height - 1, RootHeight: rHeight, NetworkId: c.Config.NetworkID, ChainId: c.Config.ChainId,
613 }, true)
614 // if the check failed
615 if err != nil {
616 // exit with error
617 return err
618 }
619 // ensure is a full +2/3rd maj QC
620 if isPartialQC {
621 return lib.ErrNoMaj23()
622 }
623 }
624 // update the LastQuorumCertificate in the ephemeral store to ensure deterministic last-COMMIT-QC (multiple valid versions can exist)
625 if err = c.FSM.Store().(lib.StoreI).IndexQC(candidate.LastQuorumCertificate); err != nil {
626 // exit with error
627 return err
628 }
629 }
630 // exit
631 return nil
632}
633
634// SetFSMInConsensusModeForProposals() is how the Validator is configured for `base chain` specific parameter upgrades
635func (c *Controller) SetFSMInConsensusModeForProposals() (reset func()) {

Callers 1

ApplyAndValidateBlockMethod · 0.95

Calls 11

SyncingMethod · 0.95
LoadCommitteeMethod · 0.95
LoadRootChainIdMethod · 0.95
ErrNoMaj23Function · 0.92
EqualPayloadsMethod · 0.80
LoadMethod · 0.80
StoreMethod · 0.80
CheckMethod · 0.65
IndexQCMethod · 0.65

Tested by

no test coverage detected