github.com/okex/exchain@v1.8.0/libs/tendermint/lite/commit.go (about)

     1  package lite
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"fmt"
     7  
     8  	"github.com/okex/exchain/libs/tendermint/types"
     9  )
    10  
    11  // FullCommit contains a SignedHeader (the block header and a commit that signs it),
    12  // the validator set which signed the commit, and the next validator set. The
    13  // next validator set (which is proven from the block header) allows us to
    14  // revert to block-by-block updating of lite Verifier's latest validator set,
    15  // even in the face of arbitrarily large power changes.
    16  type FullCommit struct {
    17  	SignedHeader   types.SignedHeader  `json:"signed_header"`
    18  	Validators     *types.ValidatorSet `json:"validator_set"`
    19  	NextValidators *types.ValidatorSet `json:"next_validator_set"`
    20  }
    21  
    22  // NewFullCommit returns a new FullCommit.
    23  func NewFullCommit(signedHeader types.SignedHeader, valset, nextValset *types.ValidatorSet) FullCommit {
    24  	return FullCommit{
    25  		SignedHeader:   signedHeader,
    26  		Validators:     valset,
    27  		NextValidators: nextValset,
    28  	}
    29  }
    30  
    31  // Validate the components and check for consistency.
    32  // This also checks to make sure that Validators actually
    33  // signed the SignedHeader.Commit.
    34  // If > 2/3 did not sign the Commit from fc.Validators, it
    35  // is not a valid commit!
    36  func (fc FullCommit) ValidateFull(chainID string) error {
    37  	// Ensure that Validators exists and matches the header.
    38  	if fc.Validators.Size() == 0 {
    39  		return errors.New("need FullCommit.Validators")
    40  	}
    41  	if !bytes.Equal(
    42  		fc.SignedHeader.ValidatorsHash,
    43  		fc.Validators.Hash(fc.Height())) {
    44  		return fmt.Errorf("header has vhash %X but valset hash is %X",
    45  			fc.SignedHeader.ValidatorsHash,
    46  			fc.Validators.Hash(fc.Height()),
    47  		)
    48  	}
    49  	// Ensure that NextValidators exists and matches the header.
    50  	if fc.NextValidators.Size() == 0 {
    51  		return errors.New("need FullCommit.NextValidators")
    52  	}
    53  	if !bytes.Equal(
    54  		fc.SignedHeader.NextValidatorsHash,
    55  		fc.NextValidators.Hash(fc.Height()+1)) {
    56  		return fmt.Errorf("header has next vhash %X but next valset hash is %X",
    57  			fc.SignedHeader.NextValidatorsHash,
    58  			fc.NextValidators.Hash(fc.Height()+1),
    59  		)
    60  	}
    61  	// Validate the header.
    62  	err := fc.SignedHeader.ValidateBasic(chainID)
    63  	if err != nil {
    64  		return err
    65  	}
    66  	// Validate the signatures on the commit.
    67  	hdr, cmt := fc.SignedHeader.Header, fc.SignedHeader.Commit
    68  	return fc.Validators.VerifyCommit(
    69  		hdr.ChainID, cmt.BlockID,
    70  		hdr.Height, cmt)
    71  }
    72  
    73  // Height returns the height of the header.
    74  func (fc FullCommit) Height() int64 {
    75  	if fc.SignedHeader.Header == nil {
    76  		panic("should not happen")
    77  	}
    78  	return fc.SignedHeader.Height
    79  }
    80  
    81  // ChainID returns the chainID of the header.
    82  func (fc FullCommit) ChainID() string {
    83  	if fc.SignedHeader.Header == nil {
    84  		panic("should not happen")
    85  	}
    86  	return fc.SignedHeader.ChainID
    87  }