mirror of
https://github.com/tendermint/tendermint.git
synced 2026-09-10 10:06:20 +00:00
Merge branch 'master' into marko/4698grpc_priv
This commit is contained in:
+5
-4
@@ -1,6 +1,7 @@
|
||||
package privval
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
@@ -13,12 +14,12 @@ func (e EndpointTimeoutError) Temporary() bool { return true }
|
||||
|
||||
// Socket errors.
|
||||
var (
|
||||
ErrUnexpectedResponse = fmt.Errorf("received unexpected response")
|
||||
ErrNoConnection = fmt.Errorf("endpoint is not connected")
|
||||
ErrUnexpectedResponse = errors.New("received unexpected response")
|
||||
ErrNoConnection = errors.New("endpoint is not connected")
|
||||
ErrConnectionTimeout = EndpointTimeoutError{}
|
||||
|
||||
ErrReadTimeout = fmt.Errorf("endpoint read timed out")
|
||||
ErrWriteTimeout = fmt.Errorf("endpoint write timed out")
|
||||
ErrReadTimeout = errors.New("endpoint read timed out")
|
||||
ErrWriteTimeout = errors.New("endpoint write timed out")
|
||||
)
|
||||
|
||||
// RemoteSignerError allows (remote) validators to include meaningful error descriptions in their reply.
|
||||
|
||||
+18
-19
@@ -7,6 +7,8 @@ import (
|
||||
"io/ioutil"
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
tmbytes "github.com/tendermint/tendermint/libs/bytes"
|
||||
@@ -27,7 +29,7 @@ const (
|
||||
)
|
||||
|
||||
// A vote is either stepPrevote or stepPrecommit.
|
||||
func voteToStep(vote *types.Vote) int8 {
|
||||
func voteToStep(vote *tmproto.Vote) int8 {
|
||||
switch vote.Type {
|
||||
case tmproto.PrevoteType:
|
||||
return stepPrevote
|
||||
@@ -199,6 +201,7 @@ func loadFilePV(keyFilePath, stateFilePath string, loadState bool) *FilePV {
|
||||
pvKey.filePath = keyFilePath
|
||||
|
||||
pvState := FilePVLastSignState{}
|
||||
|
||||
if loadState {
|
||||
stateJSONBytes, err := ioutil.ReadFile(stateFilePath)
|
||||
if err != nil {
|
||||
@@ -245,7 +248,7 @@ func (pv *FilePV) GetPubKey() (crypto.PubKey, error) {
|
||||
|
||||
// SignVote signs a canonical representation of the vote, along with the
|
||||
// chainID. Implements PrivValidator.
|
||||
func (pv *FilePV) SignVote(chainID string, vote *types.Vote) error {
|
||||
func (pv *FilePV) SignVote(chainID string, vote *tmproto.Vote) error {
|
||||
if err := pv.signVote(chainID, vote); err != nil {
|
||||
return fmt.Errorf("error signing vote: %v", err)
|
||||
}
|
||||
@@ -254,7 +257,7 @@ func (pv *FilePV) SignVote(chainID string, vote *types.Vote) error {
|
||||
|
||||
// SignProposal signs a canonical representation of the proposal, along with
|
||||
// the chainID. Implements PrivValidator.
|
||||
func (pv *FilePV) SignProposal(chainID string, proposal *types.Proposal) error {
|
||||
func (pv *FilePV) SignProposal(chainID string, proposal *tmproto.Proposal) error {
|
||||
if err := pv.signProposal(chainID, proposal); err != nil {
|
||||
return fmt.Errorf("error signing proposal: %v", err)
|
||||
}
|
||||
@@ -295,7 +298,7 @@ func (pv *FilePV) String() string {
|
||||
// signVote checks if the vote is good to sign and sets the vote signature.
|
||||
// It may need to set the timestamp as well if the vote is otherwise the same as
|
||||
// a previously signed vote (ie. we crashed after signing but before the vote hit the WAL).
|
||||
func (pv *FilePV) signVote(chainID string, vote *types.Vote) error {
|
||||
func (pv *FilePV) signVote(chainID string, vote *tmproto.Vote) error {
|
||||
height, round, step := vote.Height, vote.Round, voteToStep(vote)
|
||||
|
||||
lss := pv.LastSignState
|
||||
@@ -305,7 +308,7 @@ func (pv *FilePV) signVote(chainID string, vote *types.Vote) error {
|
||||
return err
|
||||
}
|
||||
|
||||
signBytes := vote.SignBytes(chainID)
|
||||
signBytes := types.VoteSignBytes(chainID, vote)
|
||||
|
||||
// We might crash before writing to the wal,
|
||||
// causing us to try to re-sign for the same HRS.
|
||||
@@ -337,7 +340,7 @@ func (pv *FilePV) signVote(chainID string, vote *types.Vote) error {
|
||||
// signProposal checks if the proposal is good to sign and sets the proposal signature.
|
||||
// It may need to set the timestamp as well if the proposal is otherwise the same as
|
||||
// a previously signed proposal ie. we crashed after signing but before the proposal hit the WAL).
|
||||
func (pv *FilePV) signProposal(chainID string, proposal *types.Proposal) error {
|
||||
func (pv *FilePV) signProposal(chainID string, proposal *tmproto.Proposal) error {
|
||||
height, round, step := proposal.Height, proposal.Round, stepPropose
|
||||
|
||||
lss := pv.LastSignState
|
||||
@@ -347,7 +350,7 @@ func (pv *FilePV) signProposal(chainID string, proposal *types.Proposal) error {
|
||||
return err
|
||||
}
|
||||
|
||||
signBytes := proposal.SignBytes(chainID)
|
||||
signBytes := types.ProposalSignBytes(chainID, proposal)
|
||||
|
||||
// We might crash before writing to the wal,
|
||||
// causing us to try to re-sign for the same HRS.
|
||||
@@ -393,11 +396,11 @@ func (pv *FilePV) saveSigned(height int64, round int32, step int8,
|
||||
// returns the timestamp from the lastSignBytes.
|
||||
// returns true if the only difference in the votes is their timestamp.
|
||||
func checkVotesOnlyDifferByTimestamp(lastSignBytes, newSignBytes []byte) (time.Time, bool) {
|
||||
var lastVote, newVote types.CanonicalVote
|
||||
if err := cdc.UnmarshalBinaryLengthPrefixed(lastSignBytes, &lastVote); err != nil {
|
||||
var lastVote, newVote tmproto.CanonicalVote
|
||||
if err := proto.Unmarshal(lastSignBytes, &lastVote); err != nil {
|
||||
panic(fmt.Sprintf("LastSignBytes cannot be unmarshalled into vote: %v", err))
|
||||
}
|
||||
if err := cdc.UnmarshalBinaryLengthPrefixed(newSignBytes, &newVote); err != nil {
|
||||
if err := proto.Unmarshal(newSignBytes, &newVote); err != nil {
|
||||
panic(fmt.Sprintf("signBytes cannot be unmarshalled into vote: %v", err))
|
||||
}
|
||||
|
||||
@@ -407,20 +410,18 @@ func checkVotesOnlyDifferByTimestamp(lastSignBytes, newSignBytes []byte) (time.T
|
||||
now := tmtime.Now()
|
||||
lastVote.Timestamp = now
|
||||
newVote.Timestamp = now
|
||||
lastVoteBytes, _ := tmjson.Marshal(lastVote)
|
||||
newVoteBytes, _ := tmjson.Marshal(newVote)
|
||||
|
||||
return lastTime, bytes.Equal(newVoteBytes, lastVoteBytes)
|
||||
return lastTime, proto.Equal(&newVote, &lastVote)
|
||||
}
|
||||
|
||||
// returns the timestamp from the lastSignBytes.
|
||||
// returns true if the only difference in the proposals is their timestamp
|
||||
func checkProposalsOnlyDifferByTimestamp(lastSignBytes, newSignBytes []byte) (time.Time, bool) {
|
||||
var lastProposal, newProposal types.CanonicalProposal
|
||||
if err := cdc.UnmarshalBinaryLengthPrefixed(lastSignBytes, &lastProposal); err != nil {
|
||||
var lastProposal, newProposal tmproto.CanonicalProposal
|
||||
if err := proto.Unmarshal(lastSignBytes, &lastProposal); err != nil {
|
||||
panic(fmt.Sprintf("LastSignBytes cannot be unmarshalled into proposal: %v", err))
|
||||
}
|
||||
if err := cdc.UnmarshalBinaryLengthPrefixed(newSignBytes, &newProposal); err != nil {
|
||||
if err := proto.Unmarshal(newSignBytes, &newProposal); err != nil {
|
||||
panic(fmt.Sprintf("signBytes cannot be unmarshalled into proposal: %v", err))
|
||||
}
|
||||
|
||||
@@ -429,8 +430,6 @@ func checkProposalsOnlyDifferByTimestamp(lastSignBytes, newSignBytes []byte) (ti
|
||||
now := tmtime.Now()
|
||||
lastProposal.Timestamp = now
|
||||
newProposal.Timestamp = now
|
||||
lastProposalBytes, _ := cdc.MarshalBinaryLengthPrefixed(lastProposal)
|
||||
newProposalBytes, _ := cdc.MarshalBinaryLengthPrefixed(newProposal)
|
||||
|
||||
return lastTime, bytes.Equal(newProposalBytes, lastProposalBytes)
|
||||
return lastTime, proto.Equal(&newProposal, &lastProposal)
|
||||
}
|
||||
|
||||
+38
-31
@@ -52,10 +52,10 @@ func TestResetValidator(t *testing.T) {
|
||||
|
||||
// test vote
|
||||
height, round := int64(10), int32(1)
|
||||
voteType := byte(tmproto.PrevoteType)
|
||||
voteType := tmproto.PrevoteType
|
||||
blockID := types.BlockID{Hash: []byte{1, 2, 3}, PartsHeader: types.PartSetHeader{}}
|
||||
vote := newVote(privVal.Key.Address, 0, height, round, voteType, blockID)
|
||||
err = privVal.SignVote("mychainid", vote)
|
||||
err = privVal.SignVote("mychainid", vote.ToProto())
|
||||
assert.NoError(t, err, "expected no error signing vote")
|
||||
|
||||
// priv val after signing is not same as empty
|
||||
@@ -121,8 +121,8 @@ func TestUnmarshalValidatorKey(t *testing.T) {
|
||||
privKey := ed25519.GenPrivKey()
|
||||
pubKey := privKey.PubKey()
|
||||
addr := pubKey.Address()
|
||||
pubBytes := []byte(pubKey.(ed25519.PubKey))
|
||||
privBytes := []byte(privKey)
|
||||
pubBytes := pubKey.Bytes()
|
||||
privBytes := privKey.Bytes()
|
||||
pubB64 := base64.StdEncoding.EncodeToString(pubBytes)
|
||||
privB64 := base64.StdEncoding.EncodeToString(privBytes)
|
||||
|
||||
@@ -167,15 +167,16 @@ func TestSignVote(t *testing.T) {
|
||||
block2 := types.BlockID{Hash: []byte{3, 2, 1}, PartsHeader: types.PartSetHeader{}}
|
||||
|
||||
height, round := int64(10), int32(1)
|
||||
voteType := byte(tmproto.PrevoteType)
|
||||
voteType := tmproto.PrevoteType
|
||||
|
||||
// sign a vote for first time
|
||||
vote := newVote(privVal.Key.Address, 0, height, round, voteType, block1)
|
||||
err = privVal.SignVote("mychainid", vote)
|
||||
v := vote.ToProto()
|
||||
err = privVal.SignVote("mychainid", v)
|
||||
assert.NoError(err, "expected no error signing vote")
|
||||
|
||||
// try to sign the same vote again; should be fine
|
||||
err = privVal.SignVote("mychainid", vote)
|
||||
err = privVal.SignVote("mychainid", v)
|
||||
assert.NoError(err, "expected no error on signing same vote")
|
||||
|
||||
// now try some bad votes
|
||||
@@ -187,14 +188,15 @@ func TestSignVote(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
err = privVal.SignVote("mychainid", c)
|
||||
cpb := c.ToProto()
|
||||
err = privVal.SignVote("mychainid", cpb)
|
||||
assert.Error(err, "expected error on signing conflicting vote")
|
||||
}
|
||||
|
||||
// try signing a vote with a different time stamp
|
||||
sig := vote.Signature
|
||||
vote.Timestamp = vote.Timestamp.Add(time.Duration(1000))
|
||||
err = privVal.SignVote("mychainid", vote)
|
||||
err = privVal.SignVote("mychainid", v)
|
||||
assert.NoError(err)
|
||||
assert.Equal(sig, vote.Signature)
|
||||
}
|
||||
@@ -215,11 +217,12 @@ func TestSignProposal(t *testing.T) {
|
||||
|
||||
// sign a proposal for first time
|
||||
proposal := newProposal(height, round, block1)
|
||||
err = privVal.SignProposal("mychainid", proposal)
|
||||
pbp := proposal.ToProto()
|
||||
err = privVal.SignProposal("mychainid", pbp)
|
||||
assert.NoError(err, "expected no error signing proposal")
|
||||
|
||||
// try to sign the same proposal again; should be fine
|
||||
err = privVal.SignProposal("mychainid", proposal)
|
||||
err = privVal.SignProposal("mychainid", pbp)
|
||||
assert.NoError(err, "expected no error on signing same proposal")
|
||||
|
||||
// now try some bad Proposals
|
||||
@@ -231,14 +234,14 @@ func TestSignProposal(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
err = privVal.SignProposal("mychainid", c)
|
||||
err = privVal.SignProposal("mychainid", c.ToProto())
|
||||
assert.Error(err, "expected error on signing conflicting proposal")
|
||||
}
|
||||
|
||||
// try signing a proposal with a different time stamp
|
||||
sig := proposal.Signature
|
||||
proposal.Timestamp = proposal.Timestamp.Add(time.Duration(1000))
|
||||
err = privVal.SignProposal("mychainid", proposal)
|
||||
err = privVal.SignProposal("mychainid", pbp)
|
||||
assert.NoError(err)
|
||||
assert.Equal(sig, proposal.Signature)
|
||||
}
|
||||
@@ -258,56 +261,60 @@ func TestDifferByTimestamp(t *testing.T) {
|
||||
// test proposal
|
||||
{
|
||||
proposal := newProposal(height, round, block1)
|
||||
err := privVal.SignProposal(chainID, proposal)
|
||||
pb := proposal.ToProto()
|
||||
err := privVal.SignProposal(chainID, pb)
|
||||
assert.NoError(t, err, "expected no error signing proposal")
|
||||
signBytes := proposal.SignBytes(chainID)
|
||||
signBytes := types.ProposalSignBytes(chainID, pb)
|
||||
|
||||
sig := proposal.Signature
|
||||
timeStamp := proposal.Timestamp
|
||||
|
||||
// manipulate the timestamp. should get changed back
|
||||
proposal.Timestamp = proposal.Timestamp.Add(time.Millisecond)
|
||||
pb.Timestamp = pb.Timestamp.Add(time.Millisecond)
|
||||
var emptySig []byte
|
||||
proposal.Signature = emptySig
|
||||
err = privVal.SignProposal("mychainid", proposal)
|
||||
err = privVal.SignProposal("mychainid", pb)
|
||||
assert.NoError(t, err, "expected no error on signing same proposal")
|
||||
|
||||
assert.Equal(t, timeStamp, proposal.Timestamp)
|
||||
assert.Equal(t, signBytes, proposal.SignBytes(chainID))
|
||||
assert.Equal(t, timeStamp, pb.Timestamp)
|
||||
assert.Equal(t, signBytes, types.ProposalSignBytes(chainID, pb))
|
||||
assert.Equal(t, sig, proposal.Signature)
|
||||
}
|
||||
|
||||
// test vote
|
||||
{
|
||||
voteType := byte(tmproto.PrevoteType)
|
||||
voteType := tmproto.PrevoteType
|
||||
blockID := types.BlockID{Hash: []byte{1, 2, 3}, PartsHeader: types.PartSetHeader{}}
|
||||
vote := newVote(privVal.Key.Address, 0, height, round, voteType, blockID)
|
||||
err := privVal.SignVote("mychainid", vote)
|
||||
v := vote.ToProto()
|
||||
err := privVal.SignVote("mychainid", v)
|
||||
assert.NoError(t, err, "expected no error signing vote")
|
||||
|
||||
signBytes := vote.SignBytes(chainID)
|
||||
sig := vote.Signature
|
||||
signBytes := types.VoteSignBytes(chainID, v)
|
||||
sig := v.Signature
|
||||
timeStamp := vote.Timestamp
|
||||
|
||||
// manipulate the timestamp. should get changed back
|
||||
vote.Timestamp = vote.Timestamp.Add(time.Millisecond)
|
||||
v.Timestamp = v.Timestamp.Add(time.Millisecond)
|
||||
var emptySig []byte
|
||||
vote.Signature = emptySig
|
||||
err = privVal.SignVote("mychainid", vote)
|
||||
v.Signature = emptySig
|
||||
err = privVal.SignVote("mychainid", v)
|
||||
assert.NoError(t, err, "expected no error on signing same vote")
|
||||
|
||||
assert.Equal(t, timeStamp, vote.Timestamp)
|
||||
assert.Equal(t, signBytes, vote.SignBytes(chainID))
|
||||
assert.Equal(t, sig, vote.Signature)
|
||||
assert.Equal(t, timeStamp, v.Timestamp)
|
||||
assert.Equal(t, signBytes, types.VoteSignBytes(chainID, v))
|
||||
assert.Equal(t, sig, v.Signature)
|
||||
}
|
||||
}
|
||||
|
||||
func newVote(addr types.Address, idx int32, height int64, round int32, typ byte, blockID types.BlockID) *types.Vote {
|
||||
func newVote(addr types.Address, idx int32, height int64, round int32,
|
||||
typ tmproto.SignedMsgType, blockID types.BlockID) *types.Vote {
|
||||
return &types.Vote{
|
||||
ValidatorAddress: addr,
|
||||
ValidatorIndex: idx,
|
||||
Height: height,
|
||||
Round: round,
|
||||
Type: tmproto.SignedMsgType(typ),
|
||||
Type: typ,
|
||||
Timestamp: tmtime.Now(),
|
||||
BlockID: blockID,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user