mirror of
https://github.com/tendermint/tendermint.git
synced 2026-04-27 11:05:06 +00:00
WIP: get a feel for what changes will be necessary and where to put the
new Response / Request types
This commit is contained in:
@@ -83,18 +83,6 @@ func CanonicalProposal(chainID string, proposal *Proposal) CanonicalJSONProposal
|
||||
}
|
||||
}
|
||||
|
||||
func CanonicalVote(chainID string, vote *Vote) CanonicalJSONVote {
|
||||
return CanonicalJSONVote{
|
||||
ChainID: chainID,
|
||||
Type: "vote",
|
||||
BlockID: CanonicalBlockID(vote.BlockID),
|
||||
Height: vote.Height,
|
||||
Round: vote.Round,
|
||||
Timestamp: CanonicalTime(vote.Timestamp),
|
||||
VoteType: vote.Type,
|
||||
}
|
||||
}
|
||||
|
||||
func CanonicalHeartbeat(chainID string, heartbeat *Heartbeat) CanonicalJSONHeartbeat {
|
||||
return CanonicalJSONHeartbeat{
|
||||
ChainID: chainID,
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
amino "github.com/tendermint/go-amino"
|
||||
"github.com/tendermint/go-amino"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/merkle"
|
||||
@@ -62,8 +62,9 @@ func MaxEvidenceBytesPerBlock(blockMaxBytes int) int {
|
||||
// DuplicateVoteEvidence contains evidence a validator signed two conflicting votes.
|
||||
type DuplicateVoteEvidence struct {
|
||||
PubKey crypto.PubKey
|
||||
VoteA *Vote
|
||||
VoteB *Vote
|
||||
// TODO(ismail): this probably need to be `SignedVoteReply`s
|
||||
VoteA *SignVoteReply
|
||||
VoteB *SignVoteReply
|
||||
}
|
||||
|
||||
// String returns a string representation of the evidence.
|
||||
@@ -74,7 +75,7 @@ func (dve *DuplicateVoteEvidence) String() string {
|
||||
|
||||
// Height returns the height this evidence refers to.
|
||||
func (dve *DuplicateVoteEvidence) Height() int64 {
|
||||
return dve.VoteA.Height
|
||||
return dve.VoteA.Vote.Height
|
||||
}
|
||||
|
||||
// Address returns the address of the validator.
|
||||
@@ -91,39 +92,39 @@ func (dve *DuplicateVoteEvidence) Hash() []byte {
|
||||
// To be conflicting, they must be from the same validator, for the same H/R/S, but for different blocks.
|
||||
func (dve *DuplicateVoteEvidence) Verify(chainID string, pubKey crypto.PubKey) error {
|
||||
// H/R/S must be the same
|
||||
if dve.VoteA.Height != dve.VoteB.Height ||
|
||||
dve.VoteA.Round != dve.VoteB.Round ||
|
||||
dve.VoteA.Type != dve.VoteB.Type {
|
||||
if dve.VoteA.Vote.Height != dve.VoteB.Vote.Height ||
|
||||
dve.VoteA.Vote.Round != dve.VoteB.Vote.Round ||
|
||||
dve.VoteA.Vote.Type != dve.VoteB.Vote.Type {
|
||||
return fmt.Errorf("DuplicateVoteEvidence Error: H/R/S does not match. Got %v and %v", dve.VoteA, dve.VoteB)
|
||||
}
|
||||
|
||||
// Address must be the same
|
||||
if !bytes.Equal(dve.VoteA.ValidatorAddress, dve.VoteB.ValidatorAddress) {
|
||||
return fmt.Errorf("DuplicateVoteEvidence Error: Validator addresses do not match. Got %X and %X", dve.VoteA.ValidatorAddress, dve.VoteB.ValidatorAddress)
|
||||
if !bytes.Equal(dve.VoteA.Vote.ValidatorAddress, dve.VoteB.Vote.ValidatorAddress) {
|
||||
return fmt.Errorf("DuplicateVoteEvidence Error: Validator addresses do not match. Got %X and %X", dve.VoteA.Vote.ValidatorAddress, dve.VoteB.Vote.ValidatorAddress)
|
||||
}
|
||||
|
||||
// Index must be the same
|
||||
if dve.VoteA.ValidatorIndex != dve.VoteB.ValidatorIndex {
|
||||
return fmt.Errorf("DuplicateVoteEvidence Error: Validator indices do not match. Got %d and %d", dve.VoteA.ValidatorIndex, dve.VoteB.ValidatorIndex)
|
||||
if dve.VoteA.Vote.ValidatorIndex != dve.VoteB.Vote.ValidatorIndex {
|
||||
return fmt.Errorf("DuplicateVoteEvidence Error: Validator indices do not match. Got %d and %d", dve.VoteA.Vote.ValidatorIndex, dve.VoteB.Vote.ValidatorIndex)
|
||||
}
|
||||
|
||||
// BlockIDs must be different
|
||||
if dve.VoteA.BlockID.Equals(dve.VoteB.BlockID) {
|
||||
return fmt.Errorf("DuplicateVoteEvidence Error: BlockIDs are the same (%v) - not a real duplicate vote", dve.VoteA.BlockID)
|
||||
if dve.VoteA.Vote.BlockID.Equals(dve.VoteB.Vote.BlockID) {
|
||||
return fmt.Errorf("DuplicateVoteEvidence Error: BlockIDs are the same (%v) - not a real duplicate vote", dve.VoteA.Vote.BlockID)
|
||||
}
|
||||
|
||||
// pubkey must match address (this should already be true, sanity check)
|
||||
addr := dve.VoteA.ValidatorAddress
|
||||
addr := dve.VoteA.Vote.ValidatorAddress
|
||||
if !bytes.Equal(pubKey.Address(), addr) {
|
||||
return fmt.Errorf("DuplicateVoteEvidence FAILED SANITY CHECK - address (%X) doesn't match pubkey (%v - %X)",
|
||||
addr, pubKey, pubKey.Address())
|
||||
}
|
||||
|
||||
// Signatures must be valid
|
||||
if !pubKey.VerifyBytes(dve.VoteA.SignBytes(chainID), dve.VoteA.Signature) {
|
||||
if !pubKey.VerifyBytes(dve.VoteA.Vote.SignBytes(), dve.VoteA.Signature) {
|
||||
return fmt.Errorf("DuplicateVoteEvidence Error verifying VoteA: %v", ErrVoteInvalidSignature)
|
||||
}
|
||||
if !pubKey.VerifyBytes(dve.VoteB.SignBytes(chainID), dve.VoteB.Signature) {
|
||||
if !pubKey.VerifyBytes(dve.VoteB.Vote.SignBytes(), dve.VoteB.Signature) {
|
||||
return fmt.Errorf("DuplicateVoteEvidence Error verifying VoteB: %v", ErrVoteInvalidSignature)
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ type PrivValidator interface {
|
||||
GetAddress() Address // redundant since .PubKey().Address()
|
||||
GetPubKey() crypto.PubKey
|
||||
|
||||
SignVote(chainID string, vote *Vote) error
|
||||
SignVote(vote *Vote) (SignVoteReply, error)
|
||||
SignProposal(chainID string, proposal *Proposal) error
|
||||
SignHeartbeat(chainID string, heartbeat *Heartbeat) error
|
||||
}
|
||||
@@ -62,14 +62,18 @@ func (pv *MockPV) GetPubKey() crypto.PubKey {
|
||||
}
|
||||
|
||||
// Implements PrivValidator.
|
||||
func (pv *MockPV) SignVote(chainID string, vote *Vote) error {
|
||||
signBytes := vote.SignBytes(chainID)
|
||||
func (pv *MockPV) SignVote(vote *Vote) (SignVoteReply, error) {
|
||||
signBytes := vote.SignBytes()
|
||||
sig, err := pv.privKey.Sign(signBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
// TODO(ismail): encapsulate error into reply!
|
||||
return SignVoteReply{}, err
|
||||
}
|
||||
vote.Signature = sig
|
||||
return nil
|
||||
|
||||
return SignVoteReply{
|
||||
Vote: *vote,
|
||||
Signature: sig,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Implements PrivValidator.
|
||||
|
||||
@@ -3,9 +3,7 @@ package types
|
||||
// Signable is an interface for all signable things.
|
||||
// It typically removes signatures before serializing.
|
||||
// SignBytes returns the bytes to be signed
|
||||
// NOTE: chainIDs are part of the SignBytes but not
|
||||
// necessarily the object themselves.
|
||||
// NOTE: Expected to panic if there is an error marshalling.
|
||||
type Signable interface {
|
||||
SignBytes(chainID string) []byte
|
||||
SignBytes() []byte
|
||||
}
|
||||
|
||||
@@ -31,7 +31,8 @@ func MakeCommit(blockID BlockID, height int64, round int,
|
||||
}
|
||||
|
||||
func signAddVote(privVal PrivValidator, vote *Vote, voteSet *VoteSet) (signed bool, err error) {
|
||||
err = privVal.SignVote(voteSet.ChainID(), vote)
|
||||
vote.ChainID = voteSet.ChainID()
|
||||
repl, err := privVal.SignVote(vote)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
@@ -287,7 +287,7 @@ func (vals *ValidatorSet) VerifyCommit(chainID string, blockID BlockID, height i
|
||||
}
|
||||
_, val := vals.GetByIndex(idx)
|
||||
// Validate signature.
|
||||
precommitSignBytes := precommit.SignBytes(chainID)
|
||||
precommitSignBytes := precommit.SignBytes()
|
||||
if !val.PubKey.VerifyBytes(precommitSignBytes, precommit.Signature) {
|
||||
return fmt.Errorf("Invalid commit -- invalid signature: %v", precommit)
|
||||
}
|
||||
|
||||
@@ -73,11 +73,26 @@ type Vote struct {
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
Type byte `json:"type"`
|
||||
BlockID BlockID `json:"block_id"` // zero if vote is nil.
|
||||
Signature []byte `json:"signature"`
|
||||
ChainID string `json:"chain_id"`
|
||||
}
|
||||
|
||||
func (vote *Vote) SignBytes(chainID string) []byte {
|
||||
bz, err := cdc.MarshalJSON(CanonicalVote(chainID, vote))
|
||||
type SignVoteRequest struct {
|
||||
Vote Vote
|
||||
}
|
||||
|
||||
type SignVoteReply struct {
|
||||
Vote Vote
|
||||
Signature []byte
|
||||
Err Error
|
||||
}
|
||||
|
||||
type Error struct {
|
||||
ErrCode uint16
|
||||
Description string
|
||||
}
|
||||
|
||||
func (vote *Vote) SignBytes() []byte {
|
||||
bz, err := cdc.MarshalBinary(vote)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user