package light
|
|
|
|
import (
|
|
"bytes"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/tendermint/tendermint/types"
|
|
|
|
lightErr "github.com/tendermint/tendermint/light/errors"
|
|
)
|
|
|
|
var _ Certifier = &Static{}
|
|
|
|
// Static assumes a static set of validators, set on
|
|
// initilization and checks against them.
|
|
// The signatures on every header is checked for > 2/3 votes
|
|
// against the known validator set upon Certify
|
|
//
|
|
// Good for testing or really simple chains. Building block
|
|
// to support real-world functionality.
|
|
type Static struct {
|
|
chainID string
|
|
vSet *types.ValidatorSet
|
|
vhash []byte
|
|
}
|
|
|
|
// NewStatic returns a new certifier with a static validator set.
|
|
func NewStatic(chainID string, vals *types.ValidatorSet) *Static {
|
|
return &Static{
|
|
chainID: chainID,
|
|
vSet: vals,
|
|
}
|
|
}
|
|
|
|
// ChainID returns the chain id.
|
|
func (c *Static) ChainID() string {
|
|
return c.chainID
|
|
}
|
|
|
|
// Validators returns the validator set.
|
|
func (c *Static) Validators() *types.ValidatorSet {
|
|
return c.vSet
|
|
}
|
|
|
|
// Hash returns the hash of the validator set.
|
|
func (c *Static) Hash() []byte {
|
|
if len(c.vhash) == 0 {
|
|
c.vhash = c.vSet.Hash()
|
|
}
|
|
return c.vhash
|
|
}
|
|
|
|
// Certify makes sure that the commit is valid.
|
|
func (c *Static) Certify(commit Commit) error {
|
|
// do basic sanity checks
|
|
err := commit.ValidateBasic(c.chainID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// make sure it has the same validator set we have (static means static)
|
|
if !bytes.Equal(c.Hash(), commit.Header.ValidatorsHash) {
|
|
return lightErr.ErrValidatorsChanged()
|
|
}
|
|
|
|
// then make sure we have the proper signatures for this
|
|
err = c.vSet.VerifyCommit(c.chainID, commit.Commit.BlockID,
|
|
commit.Header.Height, commit.Commit)
|
|
return errors.WithStack(err)
|
|
}
|