mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-24 22:32:15 +00:00
* validate reactor messages Refs #2683 * validate blockchain messages Refs #2683 * validate evidence messages Refs #2683 * todo * check ProposalPOL and signature sizes * add a changelog entry * check addr is valid when we add it to the addrbook * validate incoming netAddr (not just nil check!) * fixes after Bucky's review * check timestamps * beef up block#ValidateBasic * move some checks into bcBlockResponseMessage * update Gopkg.lock Fix ``` grouped write of manifest, lock and vendor: failed to export github.com/tendermint/go-amino: fatal: failed to unpack tree object 6dcc6ddc143e116455c94b25c1004c99e0d0ca12 ``` by running `dep ensure -update` * bump year since now we check it * generate test/p2p/data on the fly using tendermint testnet * allow sync chains older than 1 year * use full path when creating a testnet * move testnet gen to test/docker/Dockerfile * relax LastCommitRound check Refs #2737 * fix conflicts after merge * add small comment * some ValidateBasic updates * fixes * AppHash length is not fixed
94 lines
2.5 KiB
Go
94 lines
2.5 KiB
Go
package types
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
cmn "github.com/tendermint/tendermint/libs/common"
|
|
tmtime "github.com/tendermint/tendermint/types/time"
|
|
)
|
|
|
|
var (
|
|
ErrInvalidBlockPartSignature = errors.New("Error invalid block part signature")
|
|
ErrInvalidBlockPartHash = errors.New("Error invalid block part hash")
|
|
)
|
|
|
|
// Proposal defines a block proposal for the consensus.
|
|
// It refers to the block by BlockID field.
|
|
// It must be signed by the correct proposer for the given Height/Round
|
|
// to be considered valid. It may depend on votes from a previous round,
|
|
// a so-called Proof-of-Lock (POL) round, as noted in the POLRound.
|
|
// If POLRound >= 0, then BlockID corresponds to the block that is locked in POLRound.
|
|
type Proposal struct {
|
|
Type SignedMsgType
|
|
Height int64 `json:"height"`
|
|
Round int `json:"round"`
|
|
POLRound int `json:"pol_round"` // -1 if null.
|
|
BlockID BlockID `json:"block_id"`
|
|
Timestamp time.Time `json:"timestamp"`
|
|
Signature []byte `json:"signature"`
|
|
}
|
|
|
|
// NewProposal returns a new Proposal.
|
|
// If there is no POLRound, polRound should be -1.
|
|
func NewProposal(height int64, round int, polRound int, blockID BlockID) *Proposal {
|
|
return &Proposal{
|
|
Type: ProposalType,
|
|
Height: height,
|
|
Round: round,
|
|
BlockID: blockID,
|
|
POLRound: polRound,
|
|
Timestamp: tmtime.Now(),
|
|
}
|
|
}
|
|
|
|
// ValidateBasic performs basic validation.
|
|
func (p *Proposal) ValidateBasic() error {
|
|
if p.Type != ProposalType {
|
|
return errors.New("Invalid Type")
|
|
}
|
|
if p.Height < 0 {
|
|
return errors.New("Negative Height")
|
|
}
|
|
if p.Round < 0 {
|
|
return errors.New("Negative Round")
|
|
}
|
|
if p.POLRound < -1 {
|
|
return errors.New("Negative POLRound (exception: -1)")
|
|
}
|
|
if err := p.BlockID.ValidateBasic(); err != nil {
|
|
return fmt.Errorf("Wrong BlockID: %v", err)
|
|
}
|
|
|
|
// NOTE: Timestamp validation is subtle and handled elsewhere.
|
|
|
|
if len(p.Signature) == 0 {
|
|
return errors.New("Signature is missing")
|
|
}
|
|
if len(p.Signature) > MaxSignatureSize {
|
|
return fmt.Errorf("Signature is too big (max: %d)", MaxSignatureSize)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// String returns a string representation of the Proposal.
|
|
func (p *Proposal) String() string {
|
|
return fmt.Sprintf("Proposal{%v/%v (%v, %v) %X @ %s}",
|
|
p.Height,
|
|
p.Round,
|
|
p.BlockID,
|
|
p.POLRound,
|
|
cmn.Fingerprint(p.Signature),
|
|
CanonicalTime(p.Timestamp))
|
|
}
|
|
|
|
// SignBytes returns the Proposal bytes for signing
|
|
func (p *Proposal) SignBytes(chainID string) []byte {
|
|
bz, err := cdc.MarshalBinaryLengthPrefixed(CanonicalizeProposal(chainID, p))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return bz
|
|
}
|