Browse Source

privval: migrate to protobuf (#4985)

pull/4997/head
Marko 5 years ago
committed by GitHub
parent
commit
f6243d8b9e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 3582 additions and 1009 deletions
  1. +2
    -0
      CHANGELOG_PENDING.md
  2. +4
    -1
      blockchain/v1/reactor_test.go
  3. +8
    -2
      consensus/byzantine_test.go
  4. +8
    -2
      consensus/common_test.go
  5. +14
    -4
      consensus/replay_test.go
  6. +9
    -3
      consensus/state.go
  7. +9
    -2
      consensus/state_test.go
  8. +6
    -1
      consensus/types/height_vote_set_test.go
  9. +1
    -0
      crypto/ed25519/ed25519.go
  10. +9
    -3
      evidence/pool_test.go
  11. +12
    -0
      libs/math/safemath.go
  12. +4
    -2
      light/helpers_test.go
  13. +0
    -14
      privval/codec.go
  14. +5
    -4
      privval/errors.go
  15. +18
    -19
      privval/file.go
  16. +38
    -31
      privval/file_test.go
  17. +31
    -56
      privval/messages.go
  18. +3
    -2
      privval/retry_signer_client.go
  19. +31
    -18
      privval/signer_client.go
  20. +135
    -41
      privval/signer_client_test.go
  21. +11
    -7
      privval/signer_endpoint.go
  22. +4
    -3
      privval/signer_listener_endpoint.go
  23. +34
    -19
      privval/signer_requestHandler.go
  24. +7
    -8
      privval/signer_server.go
  25. +1315
    -468
      proto/privval/msgs.pb.go
  26. +18
    -5
      proto/privval/msgs.proto
  27. +73
    -29
      proto/privval/types.pb.go
  28. +10
    -1
      proto/privval/types.proto
  29. +1407
    -0
      proto/types/canonical.pb.go
  30. +37
    -0
      proto/types/canonical.proto
  31. +87
    -79
      proto/types/types.pb.go
  32. +2
    -2
      proto/types/types.proto
  33. +11
    -3
      rpc/client/evidence_test.go
  34. +1
    -1
      state/tx_filter_test.go
  35. +38
    -12
      state/validation_test.go
  36. +8
    -4
      tools/tm-signer-harness/internal/test_harness.go
  37. +1
    -1
      tools/tm-signer-harness/internal/test_harness_test.go
  38. +2
    -1
      types/block.go
  39. +7
    -7
      types/block_test.go
  40. +11
    -41
      types/canonical.go
  41. +22
    -10
      types/evidence.go
  42. +11
    -3
      types/evidence_test.go
  43. +11
    -8
      types/priv_validator.go
  44. +8
    -4
      types/proposal.go
  45. +33
    -17
      types/proposal_test.go
  46. +9
    -2
      types/test_util.go
  47. +3
    -1
      types/validator_set_test.go
  48. +14
    -5
      types/vote.go
  49. +40
    -63
      types/vote_test.go

+ 2
- 0
CHANGELOG_PENDING.md View File

@ -49,6 +49,8 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi
- [store] \#4778 Transition store module to protobuf encoding
- `BlockStoreStateJSON` is now `BlockStoreState` and is encoded as binary in the database
- [rpc] \#4968 JSON encoding is now handled by `libs/json`, not Amino
- [types] \#4852 Vote & Proposal `SignBytes` is now func `VoteSignBytes` & `ProposalSignBytes`
- [privval] \#4985 `privval` reactor migration to Protobuf encoding
- [evidence] \#4949 `evidence` reactor migration to Protobuf encoding
- Apps


+ 4
- 1
blockchain/v1/reactor_test.go View File

@ -69,7 +69,10 @@ func makeVote(
BlockID: blockID,
}
_ = privVal.SignVote(header.ChainID, vote)
vpb := vote.ToProto()
_ = privVal.SignVote(header.ChainID, vpb)
vote.Signature = vpb.Signature
return vote
}


+ 8
- 2
consensus/byzantine_test.go View File

@ -181,18 +181,24 @@ func byzantineDecideProposalFunc(t *testing.T, height int64, round int32, cs *St
block1, blockParts1 := cs.createProposalBlock()
polRound, propBlockID := cs.ValidRound, types.BlockID{Hash: block1.Hash(), PartsHeader: blockParts1.Header()}
proposal1 := types.NewProposal(height, round, polRound, propBlockID)
if err := cs.privValidator.SignProposal(cs.state.ChainID, proposal1); err != nil {
p1 := proposal1.ToProto()
if err := cs.privValidator.SignProposal(cs.state.ChainID, p1); err != nil {
t.Error(err)
}
proposal1.Signature = p1.Signature
// Create a new proposal block from state/txs from the mempool.
block2, blockParts2 := cs.createProposalBlock()
polRound, propBlockID = cs.ValidRound, types.BlockID{Hash: block2.Hash(), PartsHeader: blockParts2.Header()}
proposal2 := types.NewProposal(height, round, polRound, propBlockID)
if err := cs.privValidator.SignProposal(cs.state.ChainID, proposal2); err != nil {
p2 := proposal2.ToProto()
if err := cs.privValidator.SignProposal(cs.state.ChainID, p2); err != nil {
t.Error(err)
}
proposal2.Signature = p2.Signature
block1Hash := block1.Hash()
block2Hash := block2.Hash()


+ 8
- 2
consensus/common_test.go View File

@ -105,8 +105,10 @@ func (vs *validatorStub) signVote(
Type: voteType,
BlockID: types.BlockID{Hash: hash, PartsHeader: header},
}
v := vote.ToProto()
err = vs.PrivValidator.SignVote(config.ChainID(), v)
vote.Signature = v.Signature
err = vs.PrivValidator.SignVote(config.ChainID(), vote)
return vote, err
}
@ -200,9 +202,13 @@ func decideProposal(
// Make proposal
polRound, propBlockID := validRound, types.BlockID{Hash: block.Hash(), PartsHeader: blockParts.Header()}
proposal = types.NewProposal(height, round, polRound, propBlockID)
if err := vs.SignProposal(chainID, proposal); err != nil {
p := proposal.ToProto()
if err := vs.SignProposal(chainID, p); err != nil {
panic(err)
}
proposal.Signature = p.Signature
return
}


+ 14
- 4
consensus/replay_test.go View File

@ -360,10 +360,13 @@ func TestSimulateValidatorsChange(t *testing.T) {
propBlock, _ := css[0].createProposalBlock() //changeProposer(t, cs1, vs2)
propBlockParts := propBlock.MakePartSet(partSize)
blockID := types.BlockID{Hash: propBlock.Hash(), PartsHeader: propBlockParts.Header()}
proposal := types.NewProposal(vss[1].Height, round, -1, blockID)
if err := vss[1].SignProposal(config.ChainID(), proposal); err != nil {
p := proposal.ToProto()
if err := vss[1].SignProposal(config.ChainID(), p); err != nil {
t.Fatal("failed to sign bad proposal", err)
}
proposal.Signature = p.Signature
// set the proposal block
if err := css[0].SetProposalAndBlock(proposal, propBlock, propBlockParts, "some peer"); err != nil {
@ -389,10 +392,13 @@ func TestSimulateValidatorsChange(t *testing.T) {
propBlock, _ = css[0].createProposalBlock() //changeProposer(t, cs1, vs2)
propBlockParts = propBlock.MakePartSet(partSize)
blockID = types.BlockID{Hash: propBlock.Hash(), PartsHeader: propBlockParts.Header()}
proposal = types.NewProposal(vss[2].Height, round, -1, blockID)
if err := vss[2].SignProposal(config.ChainID(), proposal); err != nil {
p = proposal.ToProto()
if err := vss[2].SignProposal(config.ChainID(), p); err != nil {
t.Fatal("failed to sign bad proposal", err)
}
proposal.Signature = p.Signature
// set the proposal block
if err := css[0].SetProposalAndBlock(proposal, propBlock, propBlockParts, "some peer"); err != nil {
@ -447,9 +453,11 @@ func TestSimulateValidatorsChange(t *testing.T) {
selfIndex := valIndexFn(0)
proposal = types.NewProposal(vss[3].Height, round, -1, blockID)
if err := vss[3].SignProposal(config.ChainID(), proposal); err != nil {
p = proposal.ToProto()
if err := vss[3].SignProposal(config.ChainID(), p); err != nil {
t.Fatal("failed to sign bad proposal", err)
}
proposal.Signature = p.Signature
// set the proposal block
if err := css[0].SetProposalAndBlock(proposal, propBlock, propBlockParts, "some peer"); err != nil {
@ -508,9 +516,11 @@ func TestSimulateValidatorsChange(t *testing.T) {
selfIndex = valIndexFn(0)
proposal = types.NewProposal(vss[1].Height, round, -1, blockID)
if err := vss[1].SignProposal(config.ChainID(), proposal); err != nil {
p = proposal.ToProto()
if err := vss[1].SignProposal(config.ChainID(), p); err != nil {
t.Fatal("failed to sign bad proposal", err)
}
proposal.Signature = p.Signature
// set the proposal block
if err := css[0].SetProposalAndBlock(proposal, propBlock, propBlockParts, "some peer"); err != nil {


+ 9
- 3
consensus/state.go View File

@ -1032,7 +1032,9 @@ func (cs *State) defaultDecideProposal(height int64, round int32) {
// Make proposal
propBlockID := types.BlockID{Hash: block.Hash(), PartsHeader: blockParts.Header()}
proposal := types.NewProposal(height, round, cs.ValidRound, propBlockID)
if err := cs.privValidator.SignProposal(cs.state.ChainID, proposal); err == nil {
p := proposal.ToProto()
if err := cs.privValidator.SignProposal(cs.state.ChainID, p); err == nil {
proposal.Signature = p.Signature
// send proposal and block parts on internal msg queue
cs.sendInternalMessage(msgInfo{&ProposalMessage{proposal}, ""})
@ -1683,11 +1685,13 @@ func (cs *State) defaultSetProposal(proposal *types.Proposal) error {
return ErrInvalidProposalPOLRound
}
p := proposal.ToProto()
// Verify signature
if !cs.Validators.GetProposer().PubKey.VerifyBytes(proposal.SignBytes(cs.state.ChainID), proposal.Signature) {
if !cs.Validators.GetProposer().PubKey.VerifyBytes(types.ProposalSignBytes(cs.state.ChainID, p), proposal.Signature) {
return ErrInvalidProposalSignature
}
proposal.Signature = p.Signature
cs.Proposal = proposal
// We don't update cs.ProposalBlockParts if it is already set.
// This happens if we're already in cstypes.RoundStepCommit or if there is a valid block in the current round.
@ -2008,8 +2012,10 @@ func (cs *State) signVote(
Type: msgType,
BlockID: types.BlockID{Hash: hash, PartsHeader: header},
}
v := vote.ToProto()
err = cs.privValidator.SignVote(cs.state.ChainID, v)
vote.Signature = v.Signature
err = cs.privValidator.SignVote(cs.state.ChainID, vote)
return vote, err
}


+ 9
- 2
consensus/state_test.go View File

@ -205,10 +205,13 @@ func TestStateBadProposal(t *testing.T) {
propBlockParts := propBlock.MakePartSet(partSize)
blockID := types.BlockID{Hash: propBlock.Hash(), PartsHeader: propBlockParts.Header()}
proposal := types.NewProposal(vs2.Height, round, -1, blockID)
if err := vs2.SignProposal(config.ChainID(), proposal); err != nil {
p := proposal.ToProto()
if err := vs2.SignProposal(config.ChainID(), p); err != nil {
t.Fatal("failed to sign bad proposal", err)
}
proposal.Signature = p.Signature
// set the proposal block
if err := cs1.SetProposalAndBlock(proposal, propBlock, propBlockParts, "some peer"); err != nil {
t.Fatal(err)
@ -1034,9 +1037,13 @@ func TestStateLockPOLSafety2(t *testing.T) {
round++ // moving to the next round
// in round 2 we see the polkad block from round 0
newProp := types.NewProposal(height, round, 0, propBlockID0)
if err := vs3.SignProposal(config.ChainID(), newProp); err != nil {
p := newProp.ToProto()
if err := vs3.SignProposal(config.ChainID(), p); err != nil {
t.Fatal(err)
}
newProp.Signature = p.Signature
if err := cs1.SetProposalAndBlock(newProp, propBlock0, propBlockParts0, "some peer"); err != nil {
t.Fatal(err)
}


+ 6
- 1
consensus/types/height_vote_set_test.go View File

@ -70,9 +70,14 @@ func makeVoteHR(t *testing.T, height int64, valIndex, round int32, privVals []ty
BlockID: types.BlockID{Hash: []byte("fakehash"), PartsHeader: types.PartSetHeader{}},
}
chainID := config.ChainID()
err = privVal.SignVote(chainID, vote)
v := vote.ToProto()
err = privVal.SignVote(chainID, v)
if err != nil {
panic(fmt.Sprintf("Error signing vote: %v", err))
}
vote.Signature = v.Signature
return vote
}

+ 1
- 0
crypto/ed25519/ed25519.go View File

@ -150,6 +150,7 @@ func (pubKey PubKey) VerifyBytes(msg []byte, sig []byte) bool {
if len(sig) != SignatureSize {
return false
}
return ed25519.Verify(ed25519.PublicKey(pubKey), msg, sig)
}


+ 9
- 3
evidence/pool_test.go View File

@ -331,14 +331,20 @@ func TestPotentialAmnesiaEvidence(t *testing.T) {
require.NoError(t, err)
voteA := makeVote(25, 0, 0, pubKey.Address(), firstBlockID)
err = val.SignVote(evidenceChainID, voteA)
vA := voteA.ToProto()
err = val.SignVote(evidenceChainID, vA)
voteA.Signature = vA.Signature
require.NoError(t, err)
voteB := makeVote(25, 1, 0, pubKey.Address(), secondBlockID)
err = val.SignVote(evidenceChainID, voteB)
vB := voteB.ToProto()
err = val.SignVote(evidenceChainID, vB)
voteB.Signature = vB.Signature
require.NoError(t, err)
voteC := makeVote(25, 0, 0, pubKey.Address(), firstBlockID)
voteC.Timestamp.Add(1 * time.Second)
err = val.SignVote(evidenceChainID, voteC)
vC := voteC.ToProto()
err = val.SignVote(evidenceChainID, vC)
voteC.Signature = vC.Signature
require.NoError(t, err)
ev := types.PotentialAmnesiaEvidence{
VoteA: voteA,


+ 12
- 0
libs/math/safemath.go View File

@ -7,6 +7,7 @@ import (
var ErrOverflowInt32 = errors.New("int32 overflow")
var ErrOverflowUint8 = errors.New("uint8 overflow")
var ErrOverflowInt8 = errors.New("int8 overflow")
// SafeAddInt32 adds two int32 integers
// If there is an overflow this will panic
@ -51,3 +52,14 @@ func SafeConvertUint8(a int64) (uint8, error) {
}
return uint8(a), nil
}
// SafeConvertInt8 takes an int64 and checks if it overflows
// If there is an overflow it returns an error
func SafeConvertInt8(a int64) (int8, error) {
if a > math.MaxInt8 {
return 0, ErrOverflowInt8
} else if a < math.MinInt8 {
return 0, ErrOverflowInt8
}
return int8(a), nil
}

+ 4
- 2
light/helpers_test.go View File

@ -108,13 +108,15 @@ func makeVote(header *types.Header, valset *types.ValidatorSet,
Type: tmproto.PrecommitType,
BlockID: blockID,
}
v := vote.ToProto()
// Sign it
signBytes := vote.SignBytes(header.ChainID)
// TODO Consider reworking makeVote API to return an error
signBytes := types.VoteSignBytes(header.ChainID, v)
sig, err := key.Sign(signBytes)
if err != nil {
panic(err)
}
vote.Signature = sig
return vote


+ 0
- 14
privval/codec.go View File

@ -1,14 +0,0 @@
package privval
import (
amino "github.com/tendermint/go-amino"
cryptoamino "github.com/tendermint/tendermint/crypto/encoding/amino"
)
var cdc = amino.NewCodec()
func init() {
cryptoamino.RegisterAmino(cdc)
RegisterRemoteSignerMsg(cdc)
}

+ 5
- 4
privval/errors.go View File

@ -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
privval/file.go View File

@ -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
privval/file_test.go View File

@ -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,
}


+ 31
- 56
privval/messages.go View File

@ -1,65 +1,40 @@
package privval
import (
amino "github.com/tendermint/go-amino"
"fmt"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/types"
)
// SignerMessage is sent between Signer Clients and Servers.
type SignerMessage interface{}
func RegisterRemoteSignerMsg(cdc *amino.Codec) {
cdc.RegisterInterface((*SignerMessage)(nil), nil)
cdc.RegisterConcrete(&PubKeyRequest{}, "tendermint/remotesigner/PubKeyRequest", nil)
cdc.RegisterConcrete(&PubKeyResponse{}, "tendermint/remotesigner/PubKeyResponse", nil)
cdc.RegisterConcrete(&SignVoteRequest{}, "tendermint/remotesigner/SignVoteRequest", nil)
cdc.RegisterConcrete(&SignedVoteResponse{}, "tendermint/remotesigner/SignedVoteResponse", nil)
cdc.RegisterConcrete(&SignProposalRequest{}, "tendermint/remotesigner/SignProposalRequest", nil)
cdc.RegisterConcrete(&SignedProposalResponse{}, "tendermint/remotesigner/SignedProposalResponse", nil)
"github.com/gogo/protobuf/proto"
cdc.RegisterConcrete(&PingRequest{}, "tendermint/remotesigner/PingRequest", nil)
cdc.RegisterConcrete(&PingResponse{}, "tendermint/remotesigner/PingResponse", nil)
}
privvalproto "github.com/tendermint/tendermint/proto/privval"
)
// TODO: Add ChainIDRequest
// PubKeyRequest requests the consensus public key from the remote signer.
type PubKeyRequest struct{}
// PubKeyResponse is a response message containing the public key.
type PubKeyResponse struct {
PubKey crypto.PubKey
Error *RemoteSignerError
}
// SignVoteRequest is a request to sign a vote
type SignVoteRequest struct {
Vote *types.Vote
}
// SignedVoteResponse is a response containing a signed vote or an error
type SignedVoteResponse struct {
Vote *types.Vote
Error *RemoteSignerError
}
// SignProposalRequest is a request to sign a proposal
type SignProposalRequest struct {
Proposal *types.Proposal
}
// SignedProposalResponse is response containing a signed proposal or an error
type SignedProposalResponse struct {
Proposal *types.Proposal
Error *RemoteSignerError
}
// PingRequest is a request to confirm that the connection is alive.
type PingRequest struct {
}
// PingResponse is a response to confirm that the connection is alive.
type PingResponse struct {
func mustWrapMsg(pb proto.Message) privvalproto.Message {
msg := privvalproto.Message{}
switch pb := pb.(type) {
case *privvalproto.Message:
msg = *pb
case *privvalproto.PubKeyRequest:
msg.Sum = &privvalproto.Message_PubKeyRequest{PubKeyRequest: pb}
case *privvalproto.PubKeyResponse:
msg.Sum = &privvalproto.Message_PubKeyResponse{PubKeyResponse: pb}
case *privvalproto.SignVoteRequest:
msg.Sum = &privvalproto.Message_SignVoteRequest{SignVoteRequest: pb}
case *privvalproto.SignedVoteResponse:
msg.Sum = &privvalproto.Message_SignedVoteResponse{SignedVoteResponse: pb}
case *privvalproto.SignedProposalResponse:
msg.Sum = &privvalproto.Message_SignedProposalResponse{SignedProposalResponse: pb}
case *privvalproto.SignProposalRequest:
msg.Sum = &privvalproto.Message_SignProposalRequest{SignProposalRequest: pb}
case *privvalproto.PingRequest:
msg.Sum = &privvalproto.Message_PingRequest{}
case *privvalproto.PingResponse:
msg.Sum = &privvalproto.Message_PingResponse{}
default:
panic(fmt.Errorf("unknown message type %T", msg))
}
return msg
}

+ 3
- 2
privval/retry_signer_client.go View File

@ -5,6 +5,7 @@ import (
"time"
"github.com/tendermint/tendermint/crypto"
tmproto "github.com/tendermint/tendermint/proto/types"
"github.com/tendermint/tendermint/types"
)
@ -58,7 +59,7 @@ func (sc *RetrySignerClient) GetPubKey() (crypto.PubKey, error) {
return nil, fmt.Errorf("exhausted all attempts to get pubkey: %w", err)
}
func (sc *RetrySignerClient) SignVote(chainID string, vote *types.Vote) error {
func (sc *RetrySignerClient) SignVote(chainID string, vote *tmproto.Vote) error {
var err error
for i := 0; i < sc.retries || sc.retries == 0; i++ {
err = sc.next.SignVote(chainID, vote)
@ -70,7 +71,7 @@ func (sc *RetrySignerClient) SignVote(chainID string, vote *types.Vote) error {
return fmt.Errorf("exhausted all attempts to sign vote: %w", err)
}
func (sc *RetrySignerClient) SignProposal(chainID string, proposal *types.Proposal) error {
func (sc *RetrySignerClient) SignProposal(chainID string, proposal *tmproto.Proposal) error {
var err error
for i := 0; i < sc.retries || sc.retries == 0; i++ {
err = sc.next.SignProposal(chainID, proposal)


+ 31
- 18
privval/signer_client.go View File

@ -1,10 +1,14 @@
package privval
import (
"errors"
"fmt"
"time"
"github.com/tendermint/tendermint/crypto"
cryptoenc "github.com/tendermint/tendermint/crypto/encoding"
privvalproto "github.com/tendermint/tendermint/proto/privval"
tmproto "github.com/tendermint/tendermint/proto/types"
"github.com/tendermint/tendermint/types"
)
@ -48,15 +52,15 @@ func (sc *SignerClient) WaitForConnection(maxWait time.Duration) error {
// Ping sends a ping request to the remote signer
func (sc *SignerClient) Ping() error {
response, err := sc.endpoint.SendRequest(&PingRequest{})
response, err := sc.endpoint.SendRequest(mustWrapMsg(&privvalproto.PingRequest{}))
if err != nil {
sc.endpoint.Logger.Error("SignerClient::Ping", "err", err)
return nil
}
_, ok := response.(*PingResponse)
if !ok {
pb := response.GetPingResponse()
if pb == nil {
sc.endpoint.Logger.Error("SignerClient::Ping", "err", "response != PingResponse")
return err
}
@ -67,64 +71,73 @@ func (sc *SignerClient) Ping() error {
// GetPubKey retrieves a public key from a remote signer
// returns an error if client is not able to provide the key
func (sc *SignerClient) GetPubKey() (crypto.PubKey, error) {
response, err := sc.endpoint.SendRequest(&PubKeyRequest{})
response, err := sc.endpoint.SendRequest(mustWrapMsg(&privvalproto.PubKeyRequest{}))
if err != nil {
sc.endpoint.Logger.Error("SignerClient::GetPubKey", "err", err)
return nil, fmt.Errorf("send: %w", err)
}
pubKeyResp, ok := response.(*PubKeyResponse)
if !ok {
pubKeyResp := response.GetPubKeyResponse()
if pubKeyResp == nil {
sc.endpoint.Logger.Error("SignerClient::GetPubKey", "err", "response != PubKeyResponse")
return nil, fmt.Errorf("unexpected response type %T", response)
}
if pubKeyResp.Error != nil {
sc.endpoint.Logger.Error("failed to get private validator's public key", "err", pubKeyResp.Error)
return nil, fmt.Errorf("remote error: %w", pubKeyResp.Error)
return nil, fmt.Errorf("remote error: %w", errors.New(pubKeyResp.Error.Description))
}
return pubKeyResp.PubKey, nil
pk, err := cryptoenc.PubKeyFromProto(*pubKeyResp.PubKey)
if err != nil {
return nil, err
}
return pk, nil
}
// SignVote requests a remote signer to sign a vote
func (sc *SignerClient) SignVote(chainID string, vote *types.Vote) error {
response, err := sc.endpoint.SendRequest(&SignVoteRequest{Vote: vote})
func (sc *SignerClient) SignVote(chainID string, vote *tmproto.Vote) error {
response, err := sc.endpoint.SendRequest(mustWrapMsg(&privvalproto.SignVoteRequest{Vote: vote}))
if err != nil {
sc.endpoint.Logger.Error("SignerClient::SignVote", "err", err)
return err
}
resp, ok := response.(*SignedVoteResponse)
if !ok {
resp := response.GetSignedVoteResponse()
if resp == nil {
sc.endpoint.Logger.Error("SignerClient::GetPubKey", "err", "response != SignedVoteResponse")
return ErrUnexpectedResponse
}
if resp.Error != nil {
return resp.Error
return &RemoteSignerError{Code: int(resp.Error.Code), Description: resp.Error.Description}
}
*vote = *resp.Vote
return nil
}
// SignProposal requests a remote signer to sign a proposal
func (sc *SignerClient) SignProposal(chainID string, proposal *types.Proposal) error {
response, err := sc.endpoint.SendRequest(&SignProposalRequest{Proposal: proposal})
func (sc *SignerClient) SignProposal(chainID string, proposal *tmproto.Proposal) error {
response, err := sc.endpoint.SendRequest(mustWrapMsg(&privvalproto.SignProposalRequest{Proposal: *proposal}))
if err != nil {
sc.endpoint.Logger.Error("SignerClient::SignProposal", "err", err)
return err
}
resp, ok := response.(*SignedProposalResponse)
if !ok {
resp := response.GetSignedProposalResponse()
if resp == nil {
sc.endpoint.Logger.Error("SignerClient::SignProposal", "err", "response != SignedProposalResponse")
return ErrUnexpectedResponse
}
if resp.Error != nil {
return resp.Error
return &RemoteSignerError{Code: int(resp.Error.Code), Description: resp.Error.Description}
}
*proposal = *resp.Proposal
return nil


+ 135
- 41
privval/signer_client_test.go View File

@ -8,7 +8,10 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/tmhash"
tmrand "github.com/tendermint/tendermint/libs/rand"
privvalproto "github.com/tendermint/tendermint/proto/privval"
tmproto "github.com/tendermint/tendermint/proto/types"
"github.com/tendermint/tendermint/types"
)
@ -95,14 +98,29 @@ func TestSignerGetPubKey(t *testing.T) {
func TestSignerProposal(t *testing.T) {
for _, tc := range getSignerTestCases(t) {
ts := time.Now()
want := &types.Proposal{Timestamp: ts}
have := &types.Proposal{Timestamp: ts}
hash := tmrand.Bytes(tmhash.Size)
have := &types.Proposal{
Type: tmproto.ProposalType,
Height: 1,
Round: 2,
POLRound: 2,
BlockID: types.BlockID{Hash: hash, PartsHeader: types.PartSetHeader{Hash: hash, Total: 2}},
Timestamp: ts,
}
want := &types.Proposal{
Type: tmproto.ProposalType,
Height: 1,
Round: 2,
POLRound: 2,
BlockID: types.BlockID{Hash: hash, PartsHeader: types.PartSetHeader{Hash: hash, Total: 2}},
Timestamp: ts,
}
defer tc.signerServer.Stop()
defer tc.signerClient.Close()
require.NoError(t, tc.mockPV.SignProposal(tc.chainID, want))
require.NoError(t, tc.signerClient.SignProposal(tc.chainID, have))
require.NoError(t, tc.mockPV.SignProposal(tc.chainID, want.ToProto()))
require.NoError(t, tc.signerClient.SignProposal(tc.chainID, have.ToProto()))
assert.Equal(t, want.Signature, have.Signature)
}
@ -111,14 +129,33 @@ func TestSignerProposal(t *testing.T) {
func TestSignerVote(t *testing.T) {
for _, tc := range getSignerTestCases(t) {
ts := time.Now()
want := &types.Vote{Timestamp: ts, Type: tmproto.PrecommitType}
have := &types.Vote{Timestamp: ts, Type: tmproto.PrecommitType}
hash := tmrand.Bytes(tmhash.Size)
valAddr := tmrand.Bytes(crypto.AddressSize)
want := &types.Vote{
Type: tmproto.PrecommitType,
Height: 1,
Round: 2,
BlockID: types.BlockID{Hash: hash, PartsHeader: types.PartSetHeader{Hash: hash, Total: 2}},
Timestamp: ts,
ValidatorAddress: valAddr,
ValidatorIndex: 1,
}
have := &types.Vote{
Type: tmproto.PrecommitType,
Height: 1,
Round: 2,
BlockID: types.BlockID{Hash: hash, PartsHeader: types.PartSetHeader{Hash: hash, Total: 2}},
Timestamp: ts,
ValidatorAddress: valAddr,
ValidatorIndex: 1,
}
defer tc.signerServer.Stop()
defer tc.signerClient.Close()
require.NoError(t, tc.mockPV.SignVote(tc.chainID, want))
require.NoError(t, tc.signerClient.SignVote(tc.chainID, have))
require.NoError(t, tc.mockPV.SignVote(tc.chainID, want.ToProto()))
require.NoError(t, tc.signerClient.SignVote(tc.chainID, have.ToProto()))
assert.Equal(t, want.Signature, have.Signature)
}
@ -127,16 +164,35 @@ func TestSignerVote(t *testing.T) {
func TestSignerVoteResetDeadline(t *testing.T) {
for _, tc := range getSignerTestCases(t) {
ts := time.Now()
want := &types.Vote{Timestamp: ts, Type: tmproto.PrecommitType}
have := &types.Vote{Timestamp: ts, Type: tmproto.PrecommitType}
hash := tmrand.Bytes(tmhash.Size)
valAddr := tmrand.Bytes(crypto.AddressSize)
want := &types.Vote{
Type: tmproto.PrecommitType,
Height: 1,
Round: 2,
BlockID: types.BlockID{Hash: hash, PartsHeader: types.PartSetHeader{Hash: hash, Total: 2}},
Timestamp: ts,
ValidatorAddress: valAddr,
ValidatorIndex: 1,
}
have := &types.Vote{
Type: tmproto.PrecommitType,
Height: 1,
Round: 2,
BlockID: types.BlockID{Hash: hash, PartsHeader: types.PartSetHeader{Hash: hash, Total: 2}},
Timestamp: ts,
ValidatorAddress: valAddr,
ValidatorIndex: 1,
}
defer tc.signerServer.Stop()
defer tc.signerClient.Close()
time.Sleep(testTimeoutReadWrite2o3)
require.NoError(t, tc.mockPV.SignVote(tc.chainID, want))
require.NoError(t, tc.signerClient.SignVote(tc.chainID, have))
require.NoError(t, tc.mockPV.SignVote(tc.chainID, want.ToProto()))
require.NoError(t, tc.signerClient.SignVote(tc.chainID, have.ToProto()))
assert.Equal(t, want.Signature, have.Signature)
// TODO(jleni): Clarify what is actually being tested
@ -144,8 +200,8 @@ func TestSignerVoteResetDeadline(t *testing.T) {
// This would exceed the deadline if it was not extended by the previous message
time.Sleep(testTimeoutReadWrite2o3)
require.NoError(t, tc.mockPV.SignVote(tc.chainID, want))
require.NoError(t, tc.signerClient.SignVote(tc.chainID, have))
require.NoError(t, tc.mockPV.SignVote(tc.chainID, want.ToProto()))
require.NoError(t, tc.signerClient.SignVote(tc.chainID, have.ToProto()))
assert.Equal(t, want.Signature, have.Signature)
}
}
@ -153,8 +209,27 @@ func TestSignerVoteResetDeadline(t *testing.T) {
func TestSignerVoteKeepAlive(t *testing.T) {
for _, tc := range getSignerTestCases(t) {
ts := time.Now()
want := &types.Vote{Timestamp: ts, Type: tmproto.PrecommitType}
have := &types.Vote{Timestamp: ts, Type: tmproto.PrecommitType}
hash := tmrand.Bytes(tmhash.Size)
valAddr := tmrand.Bytes(crypto.AddressSize)
want := &types.Vote{
Type: tmproto.PrecommitType,
Height: 1,
Round: 2,
BlockID: types.BlockID{Hash: hash, PartsHeader: types.PartSetHeader{Hash: hash, Total: 2}},
Timestamp: ts,
ValidatorAddress: valAddr,
ValidatorIndex: 1,
}
have := &types.Vote{
Type: tmproto.PrecommitType,
Height: 1,
Round: 2,
BlockID: types.BlockID{Hash: hash, PartsHeader: types.PartSetHeader{Hash: hash, Total: 2}},
Timestamp: ts,
ValidatorAddress: valAddr,
ValidatorIndex: 1,
}
defer tc.signerServer.Stop()
defer tc.signerClient.Close()
@ -168,8 +243,8 @@ func TestSignerVoteKeepAlive(t *testing.T) {
time.Sleep(testTimeoutReadWrite * 3)
tc.signerServer.Logger.Debug("TEST: Forced Wait DONE---------------------------------------------")
require.NoError(t, tc.mockPV.SignVote(tc.chainID, want))
require.NoError(t, tc.signerClient.SignVote(tc.chainID, have))
require.NoError(t, tc.mockPV.SignVote(tc.chainID, want.ToProto()))
require.NoError(t, tc.signerClient.SignVote(tc.chainID, have.ToProto()))
assert.Equal(t, want.Signature, have.Signature)
}
@ -185,14 +260,24 @@ func TestSignerSignProposalErrors(t *testing.T) {
defer tc.signerClient.Close()
ts := time.Now()
proposal := &types.Proposal{Timestamp: ts}
err := tc.signerClient.SignProposal(tc.chainID, proposal)
hash := tmrand.Bytes(tmhash.Size)
proposal := &types.Proposal{
Type: tmproto.ProposalType,
Height: 1,
Round: 2,
POLRound: 2,
BlockID: types.BlockID{Hash: hash, PartsHeader: types.PartSetHeader{Hash: hash, Total: 2}},
Timestamp: ts,
Signature: []byte("signature"),
}
err := tc.signerClient.SignProposal(tc.chainID, proposal.ToProto())
require.Equal(t, err.(*RemoteSignerError).Description, types.ErroringMockPVErr.Error())
err = tc.mockPV.SignProposal(tc.chainID, proposal)
err = tc.mockPV.SignProposal(tc.chainID, proposal.ToProto())
require.Error(t, err)
err = tc.signerClient.SignProposal(tc.chainID, proposal)
err = tc.signerClient.SignProposal(tc.chainID, proposal.ToProto())
require.Error(t, err)
}
}
@ -200,7 +285,18 @@ func TestSignerSignProposalErrors(t *testing.T) {
func TestSignerSignVoteErrors(t *testing.T) {
for _, tc := range getSignerTestCases(t) {
ts := time.Now()
vote := &types.Vote{Timestamp: ts, Type: tmproto.PrecommitType}
hash := tmrand.Bytes(tmhash.Size)
valAddr := tmrand.Bytes(crypto.AddressSize)
vote := &types.Vote{
Type: tmproto.PrecommitType,
Height: 1,
Round: 2,
BlockID: types.BlockID{Hash: hash, PartsHeader: types.PartSetHeader{Hash: hash, Total: 2}},
Timestamp: ts,
ValidatorAddress: valAddr,
ValidatorIndex: 1,
Signature: []byte("signature"),
}
// Replace signer service privval with one that always fails
tc.signerServer.privVal = types.NewErroringMockPV()
@ -209,34 +305,32 @@ func TestSignerSignVoteErrors(t *testing.T) {
defer tc.signerServer.Stop()
defer tc.signerClient.Close()
err := tc.signerClient.SignVote(tc.chainID, vote)
err := tc.signerClient.SignVote(tc.chainID, vote.ToProto())
require.Equal(t, err.(*RemoteSignerError).Description, types.ErroringMockPVErr.Error())
err = tc.mockPV.SignVote(tc.chainID, vote)
err = tc.mockPV.SignVote(tc.chainID, vote.ToProto())
require.Error(t, err)
err = tc.signerClient.SignVote(tc.chainID, vote)
err = tc.signerClient.SignVote(tc.chainID, vote.ToProto())
require.Error(t, err)
}
}
func brokenHandler(privVal types.PrivValidator, request SignerMessage, chainID string) (SignerMessage, error) {
var res SignerMessage
func brokenHandler(privVal types.PrivValidator, request privvalproto.Message,
chainID string) (privvalproto.Message, error) {
var res privvalproto.Message
var err error
switch r := request.(type) {
switch r := request.Sum.(type) {
// This is broken and will answer most requests with a pubkey response
case *PubKeyRequest:
res = &PubKeyResponse{nil, nil}
case *SignVoteRequest:
res = &PubKeyResponse{nil, nil}
case *SignProposalRequest:
res = &PubKeyResponse{nil, nil}
case *PingRequest:
err, res = nil, &PingResponse{}
case *privvalproto.Message_PubKeyRequest:
res = mustWrapMsg(&privvalproto.PubKeyResponse{PubKey: nil, Error: nil})
case *privvalproto.Message_SignVoteRequest:
res = mustWrapMsg(&privvalproto.PubKeyResponse{PubKey: nil, Error: nil})
case *privvalproto.Message_SignProposalRequest:
res = mustWrapMsg(&privvalproto.PubKeyResponse{PubKey: nil, Error: nil})
case *privvalproto.Message_PingRequest:
err, res = nil, mustWrapMsg(&privvalproto.PingResponse{})
default:
err = fmt.Errorf("unknown msg: %v", r)
}
@ -257,7 +351,7 @@ func TestSignerUnexpectedResponse(t *testing.T) {
ts := time.Now()
want := &types.Vote{Timestamp: ts, Type: tmproto.PrecommitType}
e := tc.signerClient.SignVote(tc.chainID, want)
e := tc.signerClient.SignVote(tc.chainID, want.ToProto())
assert.EqualError(t, e, "received unexpected response")
}
}

+ 11
- 7
privval/signer_endpoint.go View File

@ -6,7 +6,9 @@ import (
"sync"
"time"
"github.com/tendermint/tendermint/libs/protoio"
"github.com/tendermint/tendermint/libs/service"
privvalproto "github.com/tendermint/tendermint/proto/privval"
)
const (
@ -78,14 +80,13 @@ func (se *signerEndpoint) DropConnection() {
}
// ReadMessage reads a message from the endpoint
func (se *signerEndpoint) ReadMessage() (msg SignerMessage, err error) {
func (se *signerEndpoint) ReadMessage() (msg privvalproto.Message, err error) {
se.connMtx.Lock()
defer se.connMtx.Unlock()
if !se.isConnected() {
return nil, fmt.Errorf("endpoint is not connected")
return msg, fmt.Errorf("endpoint is not connected: %w", ErrNoConnection)
}
// Reset read deadline
deadline := time.Now().Add(se.timeoutReadWrite)
@ -93,15 +94,16 @@ func (se *signerEndpoint) ReadMessage() (msg SignerMessage, err error) {
if err != nil {
return
}
const maxRemoteSignerMsgSize = 1024 * 10
_, err = cdc.UnmarshalBinaryLengthPrefixedReader(se.conn, &msg, maxRemoteSignerMsgSize)
protoReader := protoio.NewDelimitedReader(se.conn, maxRemoteSignerMsgSize)
err = protoReader.ReadMsg(&msg)
if _, ok := err.(timeoutError); ok {
if err != nil {
err = fmt.Errorf("%v: %w", err, ErrReadTimeout)
} else {
err = fmt.Errorf("empty error: %w", ErrReadTimeout)
}
se.Logger.Debug("Dropping [read]", "obj", se)
se.dropConnection()
}
@ -110,7 +112,7 @@ func (se *signerEndpoint) ReadMessage() (msg SignerMessage, err error) {
}
// WriteMessage writes a message from the endpoint
func (se *signerEndpoint) WriteMessage(msg SignerMessage) (err error) {
func (se *signerEndpoint) WriteMessage(msg privvalproto.Message) (err error) {
se.connMtx.Lock()
defer se.connMtx.Unlock()
@ -118,6 +120,8 @@ func (se *signerEndpoint) WriteMessage(msg SignerMessage) (err error) {
return fmt.Errorf("endpoint is not connected: %w", ErrNoConnection)
}
protoWriter := protoio.NewDelimitedWriter(se.conn)
// Reset read deadline
deadline := time.Now().Add(se.timeoutReadWrite)
err = se.conn.SetWriteDeadline(deadline)
@ -125,7 +129,7 @@ func (se *signerEndpoint) WriteMessage(msg SignerMessage) (err error) {
return
}
_, err = cdc.MarshalBinaryLengthPrefixedWriter(se.conn, msg)
_, err = protoWriter.WriteMsg(&msg)
if _, ok := err.(timeoutError); ok {
if err != nil {
err = fmt.Errorf("%v: %w", err, ErrWriteTimeout)


+ 4
- 3
privval/signer_listener_endpoint.go View File

@ -8,6 +8,7 @@ import (
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/libs/service"
privvalproto "github.com/tendermint/tendermint/proto/privval"
)
// SignerValidatorEndpointOption sets an optional parameter on the SocketVal.
@ -83,7 +84,7 @@ func (sl *SignerListenerEndpoint) WaitForConnection(maxWait time.Duration) error
}
// SendRequest ensures there is a connection, sends a request and waits for a response
func (sl *SignerListenerEndpoint) SendRequest(request SignerMessage) (SignerMessage, error) {
func (sl *SignerListenerEndpoint) SendRequest(request privvalproto.Message) (*privvalproto.Message, error) {
sl.instanceMtx.Lock()
defer sl.instanceMtx.Unlock()
@ -102,7 +103,7 @@ func (sl *SignerListenerEndpoint) SendRequest(request SignerMessage) (SignerMess
return nil, err
}
return res, nil
return &res, nil
}
func (sl *SignerListenerEndpoint) ensureConnection(maxWait time.Duration) error {
@ -185,7 +186,7 @@ func (sl *SignerListenerEndpoint) pingLoop() {
select {
case <-sl.pingTimer.C:
{
_, err := sl.SendRequest(&PingRequest{})
_, err := sl.SendRequest(mustWrapMsg(&privvalproto.PingRequest{}))
if err != nil {
sl.Logger.Error("SignerListener: Ping timeout")
sl.triggerReconnect()


+ 34
- 19
privval/signer_requestHandler.go View File

@ -4,45 +4,60 @@ import (
"fmt"
"github.com/tendermint/tendermint/crypto"
cryptoenc "github.com/tendermint/tendermint/crypto/encoding"
privvalproto "github.com/tendermint/tendermint/proto/privval"
"github.com/tendermint/tendermint/types"
)
func DefaultValidationRequestHandler(
privVal types.PrivValidator,
req SignerMessage,
req privvalproto.Message,
chainID string,
) (SignerMessage, error) {
var res SignerMessage
var err error
) (privvalproto.Message, error) {
var (
res privvalproto.Message
err error
)
switch r := req.(type) {
case *PubKeyRequest:
switch r := req.Sum.(type) {
case *privvalproto.Message_PubKeyRequest:
var pubKey crypto.PubKey
pubKey, err = privVal.GetPubKey()
pk, err := cryptoenc.PubKeyToProto(pubKey)
if err != nil {
res = &PubKeyResponse{nil, &RemoteSignerError{0, err.Error()}}
} else {
res = &PubKeyResponse{pubKey, nil}
return res, err
}
case *SignVoteRequest:
err = privVal.SignVote(chainID, r.Vote)
if err != nil {
res = &SignedVoteResponse{nil, &RemoteSignerError{0, err.Error()}}
res = mustWrapMsg(&privvalproto.PubKeyResponse{
PubKey: nil, Error: &privvalproto.RemoteSignerError{Code: 0, Description: err.Error()}})
} else {
res = &SignedVoteResponse{r.Vote, nil}
res = mustWrapMsg(&privvalproto.PubKeyResponse{PubKey: &pk, Error: nil})
}
case *SignProposalRequest:
err = privVal.SignProposal(chainID, r.Proposal)
case *privvalproto.Message_SignVoteRequest:
vote := r.SignVoteRequest.Vote
err = privVal.SignVote(chainID, vote)
if err != nil {
res = &SignedProposalResponse{nil, &RemoteSignerError{0, err.Error()}}
res = mustWrapMsg(&privvalproto.SignedVoteResponse{
Vote: nil, Error: &privvalproto.RemoteSignerError{Code: 0, Description: err.Error()}})
} else {
res = &SignedProposalResponse{r.Proposal, nil}
res = mustWrapMsg(&privvalproto.SignedVoteResponse{Vote: vote, Error: nil})
}
case *PingRequest:
err, res = nil, &PingResponse{}
case *privvalproto.Message_SignProposalRequest:
proposal := r.SignProposalRequest.Proposal
err = privVal.SignProposal(chainID, &proposal)
if err != nil {
res = mustWrapMsg(&privvalproto.SignedProposalResponse{
Proposal: nil, Error: &privvalproto.RemoteSignerError{Code: 0, Description: err.Error()}})
} else {
res = mustWrapMsg(&privvalproto.SignedProposalResponse{Proposal: &proposal, Error: nil})
}
case *privvalproto.Message_PingRequest:
err, res = nil, mustWrapMsg(&privvalproto.PingResponse{})
default:
err = fmt.Errorf("unknown msg: %v", r)


+ 7
- 8
privval/signer_server.go View File

@ -5,14 +5,15 @@ import (
"sync"
"github.com/tendermint/tendermint/libs/service"
privvalproto "github.com/tendermint/tendermint/proto/privval"
"github.com/tendermint/tendermint/types"
)
// ValidationRequestHandlerFunc handles different remoteSigner requests
type ValidationRequestHandlerFunc func(
privVal types.PrivValidator,
requestMessage SignerMessage,
chainID string) (SignerMessage, error)
requestMessage privvalproto.Message,
chainID string) (privvalproto.Message, error)
type SignerServer struct {
service.BaseService
@ -70,7 +71,7 @@ func (ss *SignerServer) servicePendingRequest() {
return
}
var res SignerMessage
var res privvalproto.Message
{
// limit the scope of the lock
ss.handlerMtx.Lock()
@ -82,11 +83,9 @@ func (ss *SignerServer) servicePendingRequest() {
}
}
if res != nil {
err = ss.endpoint.WriteMessage(res)
if err != nil {
ss.Logger.Error("SignerServer: writeMessage", "err", err)
}
err = ss.endpoint.WriteMessage(res)
if err != nil {
ss.Logger.Error("SignerServer: writeMessage", "err", err)
}
}


+ 1315
- 468
proto/privval/msgs.pb.go
File diff suppressed because it is too large
View File


+ 18
- 5
proto/privval/msgs.proto View File

@ -17,18 +17,18 @@ message PubKeyRequest {}
// PubKeyResponse is a response message containing the public key.
message PubKeyResponse {
tendermint.proto.crypto.keys.PublicKey pub_key = 1 [(gogoproto.nullable) = false];
tendermint.proto.crypto.keys.PublicKey pub_key = 1;
RemoteSignerError error = 2;
}
// SignVoteRequest is a request to sign a vote
message SignVoteRequest {
tendermint.proto.types.Vote vote = 1 [(gogoproto.nullable) = false];
tendermint.proto.types.Vote vote = 1;
}
// SignedVoteResponse is a response containing a signed vote or an error
message SignVoteResponse {
tendermint.proto.types.Vote vote = 1 [(gogoproto.nullable) = false];
message SignedVoteResponse {
tendermint.proto.types.Vote vote = 1;
RemoteSignerError error = 2;
}
@ -39,7 +39,7 @@ message SignProposalRequest {
// SignedProposalResponse is response containing a signed proposal or an error
message SignedProposalResponse {
tendermint.proto.types.Proposal proposal = 1 [(gogoproto.nullable) = false];
tendermint.proto.types.Proposal proposal = 1;
RemoteSignerError error = 2;
}
@ -48,3 +48,16 @@ message PingRequest {}
// PingResponse is a response to confirm that the connection is alive.
message PingResponse {}
message Message {
oneof sum {
PubKeyRequest pub_key_request = 1;
PubKeyResponse pub_key_response = 2;
SignVoteRequest sign_vote_request = 3;
SignedVoteResponse signed_vote_response = 4;
SignProposalRequest sign_proposal_request = 5;
SignedProposalResponse signed_proposal_response = 6;
PingRequest ping_request = 7;
PingResponse ping_response = 8;
}
}

+ 73
- 29
proto/privval/types.pb.go View File

@ -24,6 +24,43 @@ var _ = math.Inf
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
type Errors int32
const (
Errors_ERRORS_UNKNOWN Errors = 0
Errors_ERRORS_UNEXPECTED_RESPONSE Errors = 1
Errors_ERRORS_NO_CONNECTION Errors = 2
Errors_ERRORS_CONNECTION_TIMEOUT Errors = 3
Errors_ERRORS_READ_TIMEOUT Errors = 4
Errors_ERRORS_WRITE_TIMEOUT Errors = 5
)
var Errors_name = map[int32]string{
0: "ERRORS_UNKNOWN",
1: "ERRORS_UNEXPECTED_RESPONSE",
2: "ERRORS_NO_CONNECTION",
3: "ERRORS_CONNECTION_TIMEOUT",
4: "ERRORS_READ_TIMEOUT",
5: "ERRORS_WRITE_TIMEOUT",
}
var Errors_value = map[string]int32{
"ERRORS_UNKNOWN": 0,
"ERRORS_UNEXPECTED_RESPONSE": 1,
"ERRORS_NO_CONNECTION": 2,
"ERRORS_CONNECTION_TIMEOUT": 3,
"ERRORS_READ_TIMEOUT": 4,
"ERRORS_WRITE_TIMEOUT": 5,
}
func (x Errors) String() string {
return proto.EnumName(Errors_name, int32(x))
}
func (Errors) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_a9d74c406df3ad93, []int{0}
}
// FilePVKey stores the immutable part of PrivValidator.
type FilePVKey struct {
Address []byte `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
@ -96,7 +133,7 @@ func (m *FilePVKey) GetFilePath() string {
// FilePVLastSignState stores the mutable part of PrivValidator.
type FilePVLastSignState struct {
Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"`
Round int64 `protobuf:"varint,2,opt,name=round,proto3" json:"round,omitempty"`
Round int32 `protobuf:"varint,2,opt,name=round,proto3" json:"round,omitempty"`
Step int32 `protobuf:"varint,3,opt,name=step,proto3" json:"step,omitempty"`
Signature []byte `protobuf:"bytes,4,opt,name=signature,proto3" json:"signature,omitempty"`
SignBytes []byte `protobuf:"bytes,5,opt,name=sign_bytes,json=signBytes,proto3" json:"sign_bytes,omitempty"`
@ -143,7 +180,7 @@ func (m *FilePVLastSignState) GetHeight() int64 {
return 0
}
func (m *FilePVLastSignState) GetRound() int64 {
func (m *FilePVLastSignState) GetRound() int32 {
if m != nil {
return m.Round
}
@ -179,6 +216,7 @@ func (m *FilePVLastSignState) GetFilePath() string {
}
func init() {
proto.RegisterEnum("tendermint.proto.privval.Errors", Errors_name, Errors_value)
proto.RegisterType((*FilePVKey)(nil), "tendermint.proto.privval.FilePVKey")
proto.RegisterType((*FilePVLastSignState)(nil), "tendermint.proto.privval.FilePVLastSignState")
}
@ -186,32 +224,38 @@ func init() {
func init() { proto.RegisterFile("proto/privval/types.proto", fileDescriptor_a9d74c406df3ad93) }
var fileDescriptor_a9d74c406df3ad93 = []byte{
// 385 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x52, 0x4d, 0x8e, 0xd3, 0x30,
0x14, 0x8e, 0x69, 0x9b, 0x4e, 0xcc, 0xac, 0x0c, 0x42, 0x61, 0x60, 0x42, 0x35, 0x0b, 0xc8, 0x2a,
0x91, 0xe0, 0x06, 0x5d, 0x8c, 0x40, 0xc3, 0xa2, 0xca, 0x48, 0x2c, 0xd8, 0x44, 0x4e, 0xf3, 0x48,
0xac, 0xc9, 0x24, 0x96, 0xfd, 0x52, 0xc9, 0xb7, 0xe0, 0x2a, 0xdc, 0x62, 0x96, 0xdd, 0x20, 0xb1,
0x42, 0xa8, 0xbd, 0x08, 0xb2, 0x53, 0x94, 0x56, 0x2c, 0x66, 0xf7, 0xbe, 0xcf, 0xcf, 0xdf, 0x8f,
0x65, 0xfa, 0x52, 0xaa, 0x0e, 0xbb, 0x54, 0x2a, 0xb1, 0xd9, 0xf0, 0x26, 0x45, 0x23, 0x41, 0x27,
0x8e, 0x63, 0x21, 0x42, 0x5b, 0x82, 0xba, 0x17, 0x2d, 0x0e, 0x4c, 0x72, 0xd8, 0xba, 0x78, 0x8b,
0xb5, 0x50, 0x65, 0x2e, 0xb9, 0x42, 0x93, 0x0e, 0x02, 0x55, 0x57, 0x75, 0xe3, 0x34, 0xec, 0x5f,
0x5c, 0x0e, 0xcc, 0x5a, 0x19, 0x89, 0x5d, 0x7a, 0x07, 0x46, 0x1f, 0x1b, 0x5c, 0xfd, 0x24, 0x34,
0xb8, 0x16, 0x0d, 0xac, 0xbe, 0xdc, 0x80, 0x61, 0x21, 0x9d, 0xf3, 0xb2, 0x54, 0xa0, 0x75, 0x48,
0x16, 0x24, 0x3e, 0xcf, 0xfe, 0x41, 0x76, 0x4d, 0xe7, 0xb2, 0x2f, 0xf2, 0x3b, 0x30, 0xe1, 0x93,
0x05, 0x89, 0x9f, 0xbe, 0x7f, 0x97, 0xfc, 0x17, 0x6d, 0xf0, 0x48, 0xac, 0x47, 0xb2, 0xea, 0x8b,
0x46, 0xac, 0x6f, 0xc0, 0x2c, 0xa7, 0x0f, 0xbf, 0xdf, 0x78, 0x99, 0x2f, 0xfb, 0xc2, 0x3a, 0x7c,
0xa2, 0x67, 0xb6, 0x81, 0x13, 0x9a, 0x38, 0xa1, 0xf8, 0x11, 0x21, 0x25, 0x36, 0x1c, 0x61, 0x54,
0x9a, 0xdb, 0xfb, 0x56, 0xea, 0x15, 0x0d, 0xbe, 0x89, 0x06, 0x72, 0xc9, 0xb1, 0x0e, 0xa7, 0x0b,
0x12, 0x07, 0xd9, 0x99, 0x25, 0x56, 0x1c, 0xeb, 0xab, 0x1f, 0x84, 0x3e, 0x1b, 0x7a, 0x7d, 0xe6,
0x1a, 0x6f, 0x45, 0xd5, 0xde, 0x22, 0x47, 0x60, 0x2f, 0xa8, 0x5f, 0x83, 0xa8, 0x6a, 0x74, 0x05,
0x27, 0xd9, 0x01, 0xb1, 0xe7, 0x74, 0xa6, 0xba, 0xbe, 0x2d, 0x5d, 0xbb, 0x49, 0x36, 0x00, 0xc6,
0xe8, 0x54, 0x23, 0x48, 0x97, 0x74, 0x96, 0xb9, 0x99, 0xbd, 0xa6, 0x81, 0x16, 0x55, 0xcb, 0xb1,
0x57, 0xe0, 0x6c, 0xcf, 0xb3, 0x91, 0x60, 0x97, 0x94, 0x5a, 0x90, 0x17, 0x06, 0x41, 0x87, 0xb3,
0xf1, 0x78, 0x69, 0x89, 0xd3, 0xcc, 0xfe, 0x69, 0xe6, 0xe5, 0xc7, 0x87, 0x5d, 0x44, 0xb6, 0xbb,
0x88, 0xfc, 0xd9, 0x45, 0xe4, 0xfb, 0x3e, 0xf2, 0xb6, 0xfb, 0xc8, 0xfb, 0xb5, 0x8f, 0xbc, 0xaf,
0x49, 0x25, 0xb0, 0xee, 0x8b, 0x64, 0xdd, 0xdd, 0xa7, 0xe3, 0x6b, 0x1d, 0x8f, 0x27, 0x5f, 0xa8,
0xf0, 0x1d, 0xfc, 0xf0, 0x37, 0x00, 0x00, 0xff, 0xff, 0xe5, 0xc6, 0x2f, 0x79, 0x5a, 0x02, 0x00,
0x00,
// 493 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x52, 0xcf, 0x6e, 0xd3, 0x4e,
0x18, 0xcc, 0x36, 0x89, 0xd3, 0xec, 0xaf, 0xfa, 0x29, 0xda, 0x56, 0xe0, 0x06, 0x62, 0xa2, 0x1e,
0x20, 0xe2, 0x60, 0x4b, 0xf0, 0x04, 0x24, 0xdd, 0x8a, 0x28, 0x60, 0x5b, 0x6b, 0x97, 0x22, 0x2e,
0x96, 0x1d, 0x2f, 0xf6, 0xaa, 0xa9, 0x6d, 0xad, 0xd7, 0x91, 0xfc, 0x16, 0x3c, 0x06, 0x57, 0xde,
0xa2, 0xc7, 0x5e, 0x90, 0x38, 0x21, 0x94, 0xbc, 0x08, 0xf2, 0x1f, 0xe2, 0x44, 0x1c, 0xb8, 0x7d,
0x33, 0xf3, 0x79, 0xe6, 0x1b, 0x79, 0xe1, 0x79, 0xc2, 0x63, 0x11, 0x6b, 0x09, 0x67, 0xeb, 0xb5,
0xbb, 0xd2, 0x44, 0x9e, 0xd0, 0x54, 0x2d, 0x39, 0x24, 0x0b, 0x1a, 0xf9, 0x94, 0xdf, 0xb1, 0x48,
0x54, 0x8c, 0x5a, 0x6f, 0x0d, 0x9f, 0x8b, 0x90, 0x71, 0xdf, 0x49, 0x5c, 0x2e, 0x72, 0xad, 0x32,
0x08, 0xe2, 0x20, 0x6e, 0xa6, 0x6a, 0x7f, 0x38, 0xaa, 0x98, 0x25, 0xcf, 0x13, 0x11, 0x6b, 0xb7,
0x34, 0x4f, 0xf7, 0x03, 0x2e, 0xbe, 0x03, 0xd8, 0xbf, 0x62, 0x2b, 0x6a, 0x7e, 0x58, 0xd0, 0x1c,
0xc9, 0xb0, 0xe7, 0xfa, 0x3e, 0xa7, 0x69, 0x2a, 0x83, 0x31, 0x98, 0x9c, 0x90, 0x3f, 0x10, 0x5d,
0xc1, 0x5e, 0x92, 0x79, 0xce, 0x2d, 0xcd, 0xe5, 0xa3, 0x31, 0x98, 0xfc, 0xf7, 0xea, 0x85, 0xfa,
0xd7, 0x69, 0x55, 0x86, 0x5a, 0x64, 0xa8, 0x66, 0xe6, 0xad, 0xd8, 0x72, 0x41, 0xf3, 0x69, 0xe7,
0xfe, 0xe7, 0xb3, 0x16, 0x91, 0x92, 0xcc, 0x2b, 0x12, 0xe6, 0xf0, 0xb8, 0x68, 0x50, 0x1a, 0xb5,
0x4b, 0xa3, 0xc9, 0x3f, 0x8c, 0x38, 0x5b, 0xbb, 0x82, 0x36, 0x4e, 0xbd, 0xe2, 0xfb, 0xc2, 0xea,
0x09, 0xec, 0x7f, 0x66, 0x2b, 0xea, 0x24, 0xae, 0x08, 0xe5, 0xce, 0x18, 0x4c, 0xfa, 0xe4, 0xb8,
0x20, 0x4c, 0x57, 0x84, 0x17, 0xdf, 0x00, 0x3c, 0xad, 0x7a, 0xbd, 0x73, 0x53, 0x61, 0xb1, 0x20,
0xb2, 0x84, 0x2b, 0x28, 0x7a, 0x04, 0xa5, 0x90, 0xb2, 0x20, 0x14, 0x65, 0xc1, 0x36, 0xa9, 0x11,
0x3a, 0x83, 0x5d, 0x1e, 0x67, 0x91, 0x5f, 0xb6, 0xeb, 0x92, 0x0a, 0x20, 0x04, 0x3b, 0xa9, 0xa0,
0x49, 0x79, 0x69, 0x97, 0x94, 0x33, 0x7a, 0x0a, 0xfb, 0x29, 0x0b, 0x22, 0x57, 0x64, 0x9c, 0x96,
0xb1, 0x27, 0xa4, 0x21, 0xd0, 0x08, 0xc2, 0x02, 0x38, 0x5e, 0x2e, 0x68, 0x2a, 0x77, 0x1b, 0x79,
0x5a, 0x10, 0x87, 0x37, 0x4b, 0x87, 0x37, 0xbf, 0xfc, 0x0a, 0xa0, 0x84, 0x39, 0x8f, 0x79, 0x8a,
0x10, 0xfc, 0x1f, 0x13, 0x62, 0x10, 0xcb, 0xb9, 0xd6, 0x17, 0xba, 0x71, 0xa3, 0x0f, 0x5a, 0x48,
0x81, 0xc3, 0x1d, 0x87, 0x3f, 0x9a, 0x78, 0x66, 0xe3, 0x4b, 0x87, 0x60, 0xcb, 0x34, 0x74, 0x0b,
0x0f, 0x00, 0x92, 0xe1, 0x59, 0xad, 0xeb, 0x86, 0x33, 0x33, 0x74, 0x1d, 0xcf, 0xec, 0xb9, 0xa1,
0x0f, 0x8e, 0xd0, 0x08, 0x9e, 0xd7, 0x4a, 0x43, 0x3b, 0xf6, 0xfc, 0x3d, 0x36, 0xae, 0xed, 0x41,
0x1b, 0x3d, 0x86, 0xa7, 0xb5, 0x4c, 0xf0, 0x9b, 0xcb, 0x9d, 0xd0, 0xd9, 0x73, 0xbc, 0x21, 0x73,
0x1b, 0xef, 0x94, 0xee, 0xf4, 0xed, 0xfd, 0x46, 0x01, 0x0f, 0x1b, 0x05, 0xfc, 0xda, 0x28, 0xe0,
0xcb, 0x56, 0x69, 0x3d, 0x6c, 0x95, 0xd6, 0x8f, 0xad, 0xd2, 0xfa, 0xa4, 0x06, 0x4c, 0x84, 0x99,
0xa7, 0x2e, 0xe3, 0x3b, 0xad, 0xf9, 0xb1, 0xfb, 0xe3, 0xc1, 0x6b, 0xf7, 0xa4, 0x12, 0xbe, 0xfe,
0x1d, 0x00, 0x00, 0xff, 0xff, 0x60, 0xba, 0xbc, 0x27, 0x05, 0x03, 0x00, 0x00,
}
func (m *FilePVKey) Marshal() (dAtA []byte, err error) {
@ -645,7 +689,7 @@ func (m *FilePVLastSignState) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
m.Round |= int64(b&0x7F) << shift
m.Round |= int32(b&0x7F) << shift
if b < 0x80 {
break
}


+ 10
- 1
proto/privval/types.proto View File

@ -18,10 +18,19 @@ message FilePVKey {
// FilePVLastSignState stores the mutable part of PrivValidator.
message FilePVLastSignState {
int64 height = 1;
int64 round = 2;
int32 round = 2;
int32 step = 3;
bytes signature = 4;
bytes sign_bytes = 5;
string file_path = 6;
}
enum Errors {
ERRORS_UNKNOWN = 0;
ERRORS_UNEXPECTED_RESPONSE = 1;
ERRORS_NO_CONNECTION = 2;
ERRORS_CONNECTION_TIMEOUT = 3;
ERRORS_READ_TIMEOUT = 4;
ERRORS_WRITE_TIMEOUT = 5;
}

+ 1407
- 0
proto/types/canonical.pb.go
File diff suppressed because it is too large
View File


+ 37
- 0
proto/types/canonical.proto View File

@ -0,0 +1,37 @@
syntax = "proto3";
package tendermint.proto.types;
option go_package = "github.com/tendermint/tendermint/proto/types";
import "third_party/proto/gogoproto/gogo.proto";
import "proto/types/types.proto";
import "google/protobuf/timestamp.proto";
message CanonicalBlockID {
bytes hash = 1;
CanonicalPartSetHeader parts_header = 2 [(gogoproto.nullable) = false];
}
message CanonicalPartSetHeader {
bytes hash = 1;
uint32 total = 2;
}
message CanonicalProposal {
SignedMsgType type = 1; // type alias for byte
int64 height = 2;
int64 round = 3;
int64 pol_round = 4 [(gogoproto.customname) = "POLRound"];
CanonicalBlockID block_id = 5 [(gogoproto.nullable) = false, (gogoproto.customname) = "BlockID"];
google.protobuf.Timestamp timestamp = 6 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
string chain_id = 7 [(gogoproto.customname) = "ChainID"];
}
message CanonicalVote {
SignedMsgType type = 1; // type alias for byte
int64 height = 2;
int64 round = 3;
CanonicalBlockID block_id = 5 [(gogoproto.nullable) = false, (gogoproto.customname) = "BlockID"];
google.protobuf.Timestamp timestamp = 6 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
string chain_id = 7 [(gogoproto.customname) = "ChainID"];
}

+ 87
- 79
proto/types/types.pb.go View File

@ -54,6 +54,10 @@ var BlockIDFlag_value = map[string]int32{
"BLOCK_ID_FLAG_NIL": 3,
}
func (x BlockIDFlag) String() string {
return proto.EnumName(BlockIDFlag_name, int32(x))
}
func (BlockIDFlag) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_ff06f8095857fb18, []int{0}
}
@ -82,6 +86,10 @@ var SignedMsgType_value = map[string]int32{
"PROPOSAL_TYPE": 3,
}
func (x SignedMsgType) String() string {
return proto.EnumName(SignedMsgType_name, int32(x))
}
func (SignedMsgType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_ff06f8095857fb18, []int{1}
}
@ -951,86 +959,86 @@ func init() { proto.RegisterFile("proto/types/types.proto", fileDescriptor_ff06f
var fileDescriptor_ff06f8095857fb18 = []byte{
// 1274 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0x4f, 0x6f, 0x1a, 0x47,
0x14, 0x67, 0x61, 0x31, 0xf0, 0x00, 0x1b, 0xaf, 0xdc, 0x84, 0xe2, 0x16, 0x13, 0xdc, 0xa4, 0x4e,
0x1a, 0x41, 0xe5, 0x4a, 0x55, 0x23, 0xf5, 0x02, 0x86, 0x38, 0x28, 0x36, 0xa0, 0x85, 0xa6, 0x6a,
0x2f, 0xab, 0x81, 0x9d, 0x2c, 0xab, 0x2c, 0xbb, 0xab, 0xdd, 0xc1, 0x32, 0x39, 0xf4, 0x5c, 0xf9,
0x94, 0x2f, 0xe0, 0x53, 0x5a, 0xa9, 0xdf, 0xa2, 0x3d, 0xe6, 0x54, 0xe5, 0xd8, 0x53, 0x5a, 0xd9,
0xdf, 0xa0, 0xea, 0x07, 0xa8, 0xe6, 0xcf, 0x2e, 0x10, 0x4c, 0x1b, 0x35, 0x51, 0x2f, 0xf6, 0xce,
0x7b, 0xbf, 0xdf, 0x9b, 0x79, 0xbf, 0xf9, 0xcd, 0x8c, 0x80, 0xeb, 0xae, 0xe7, 0x10, 0xa7, 0x4a,
0xa6, 0x2e, 0xf6, 0xf9, 0xdf, 0x0a, 0x8b, 0x28, 0xd7, 0x08, 0xb6, 0x75, 0xec, 0x8d, 0x4d, 0x9b,
0xf0, 0x48, 0x85, 0x65, 0x0b, 0xb7, 0xc8, 0xc8, 0xf4, 0x74, 0xcd, 0x45, 0x1e, 0x99, 0x56, 0x39,
0xd9, 0x70, 0x0c, 0x67, 0xf6, 0xc5, 0xd1, 0x85, 0x1d, 0xc3, 0x71, 0x0c, 0x0b, 0x73, 0xc8, 0x60,
0xf2, 0xb8, 0x4a, 0xcc, 0x31, 0xf6, 0x09, 0x1a, 0xbb, 0x02, 0xb0, 0xcd, 0x29, 0x96, 0x39, 0xf0,
0xab, 0x03, 0x93, 0x2c, 0xcc, 0x5e, 0xd8, 0xe1, 0xc9, 0xa1, 0x37, 0x75, 0x89, 0x53, 0x1d, 0x63,
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0x4d, 0x6f, 0x1a, 0x47,
0x18, 0xf6, 0xc2, 0x62, 0xe0, 0x05, 0x6c, 0xbc, 0x72, 0x13, 0x8a, 0x5b, 0x4c, 0x70, 0x93, 0x3a,
0x69, 0x04, 0x95, 0x2b, 0x55, 0x8d, 0xd4, 0x0b, 0x5f, 0x71, 0x50, 0x6c, 0x40, 0x0b, 0x4d, 0xd5,
0x5e, 0x56, 0x03, 0x3b, 0x59, 0x56, 0x59, 0x76, 0x57, 0xbb, 0x83, 0x65, 0x72, 0xe8, 0xb9, 0xf2,
0x29, 0x7f, 0xc0, 0xa7, 0xb4, 0x52, 0xff, 0x45, 0x7b, 0xcc, 0xa9, 0xca, 0xb1, 0xa7, 0xb4, 0xb2,
0xff, 0x41, 0xd5, 0x1f, 0x50, 0xcd, 0xc7, 0x2e, 0x10, 0x4c, 0x1b, 0x35, 0x51, 0x2f, 0xf6, 0xce,
0xfb, 0x3e, 0xcf, 0x3b, 0xf3, 0x3e, 0xf3, 0xcc, 0x8c, 0x80, 0xeb, 0xae, 0xe7, 0x10, 0xa7, 0x42,
0xa6, 0x2e, 0xf6, 0xf9, 0xdf, 0x32, 0x8b, 0x28, 0xd7, 0x08, 0xb6, 0x75, 0xec, 0x8d, 0x4d, 0x9b,
0xf0, 0x48, 0x99, 0x65, 0xf3, 0xb7, 0xc8, 0xc8, 0xf4, 0x74, 0xcd, 0x45, 0x1e, 0x99, 0x56, 0x38,
0xd9, 0x70, 0x0c, 0x67, 0xf6, 0xc5, 0xd1, 0xf9, 0x5d, 0xc3, 0x71, 0x0c, 0x0b, 0x73, 0xc8, 0x60,
0xf2, 0xb8, 0x42, 0xcc, 0x31, 0xf6, 0x09, 0x1a, 0xbb, 0x02, 0xb0, 0xc3, 0x29, 0x96, 0x39, 0xf0,
0x2b, 0x03, 0x93, 0x2c, 0xcc, 0x9e, 0xdf, 0xe5, 0xc9, 0xa1, 0x37, 0x75, 0x89, 0x53, 0x19, 0x63,
0xef, 0x89, 0x85, 0x17, 0x00, 0x82, 0x7d, 0x82, 0x3d, 0xdf, 0x74, 0xec, 0xe0, 0x3f, 0x4f, 0x96,
0xef, 0x41, 0xb6, 0x8b, 0x3c, 0xd2, 0xc3, 0xe4, 0x01, 0x46, 0x3a, 0xf6, 0x94, 0x2d, 0x88, 0x13,
0x87, 0x20, 0x2b, 0x2f, 0x95, 0xa4, 0xbd, 0xac, 0xca, 0x07, 0x8a, 0x02, 0xf2, 0x08, 0xf9, 0xa3,
0x7c, 0xb4, 0x24, 0xed, 0x65, 0x54, 0xf6, 0x5d, 0x9e, 0x80, 0x4c, 0xa9, 0x94, 0x61, 0xda, 0x3a,
0x3e, 0x0d, 0x18, 0x6c, 0x40, 0xa3, 0x83, 0x29, 0xc1, 0xbe, 0xa0, 0xf0, 0x81, 0x52, 0x83, 0xb8,
0xeb, 0x39, 0xce, 0xe3, 0x7c, 0xac, 0x24, 0xed, 0xa5, 0xf7, 0x6f, 0x56, 0x96, 0xa4, 0xe3, 0x7d,
0x54, 0x78, 0x1f, 0x95, 0x2e, 0x05, 0xd7, 0xe5, 0x17, 0xaf, 0x76, 0x22, 0x2a, 0x67, 0x96, 0xc7,
0x90, 0xa8, 0x5b, 0xce, 0xf0, 0x49, 0xab, 0x11, 0xae, 0x4a, 0x9a, 0xad, 0x4a, 0x69, 0x43, 0x86,
0x0a, 0xee, 0x6b, 0x23, 0xd6, 0x0f, 0x9b, 0xfe, 0xca, 0x89, 0xb8, 0x44, 0x0b, 0xcd, 0x8b, 0x89,
0xd2, 0xac, 0x00, 0x0f, 0x95, 0xff, 0x94, 0x61, 0x4d, 0x48, 0x73, 0x00, 0x09, 0x21, 0x1e, 0x9b,
0x31, 0xbd, 0xbf, 0xbb, 0x5c, 0x35, 0x50, 0xf7, 0xc0, 0xb1, 0x7d, 0x6c, 0xfb, 0x13, 0x5f, 0xd4,
0x0c, 0x98, 0xca, 0x2d, 0x48, 0x0e, 0x47, 0xc8, 0xb4, 0x35, 0x53, 0x67, 0x6b, 0x4b, 0xd5, 0xd3,
0x17, 0xaf, 0x76, 0x12, 0x07, 0x34, 0xd6, 0x6a, 0xa8, 0x09, 0x96, 0x6c, 0xe9, 0xca, 0x35, 0x58,
0x1b, 0x61, 0xd3, 0x18, 0x11, 0x26, 0x55, 0x4c, 0x15, 0x23, 0xe5, 0x0b, 0x90, 0xa9, 0x3d, 0xf2,
0x32, 0x5b, 0x41, 0xa1, 0xc2, 0xbd, 0x53, 0x09, 0xbc, 0x53, 0xe9, 0x07, 0xde, 0xa9, 0x27, 0xe9,
0xc4, 0xcf, 0x7e, 0xdf, 0x91, 0x54, 0xc6, 0x50, 0x5a, 0x90, 0xb5, 0x90, 0x4f, 0xb4, 0x01, 0x55,
0x8f, 0x4e, 0x1f, 0x67, 0x25, 0x76, 0x56, 0x49, 0x23, 0x54, 0x0e, 0x44, 0xa1, 0x5c, 0x1e, 0xd2,
0x95, 0x3d, 0xc8, 0xb1, 0x52, 0x43, 0x67, 0x3c, 0x36, 0x89, 0xc6, 0x36, 0x61, 0x8d, 0x6d, 0xc2,
0x3a, 0x8d, 0x1f, 0xb0, 0xf0, 0x03, 0xba, 0x1d, 0xdb, 0x90, 0xd2, 0x11, 0x41, 0x1c, 0x92, 0x60,
0x90, 0x24, 0x0d, 0xb0, 0xe4, 0xc7, 0xb0, 0x71, 0x82, 0x2c, 0x53, 0x47, 0xc4, 0xf1, 0x7c, 0x0e,
0x49, 0xf2, 0x2a, 0xb3, 0x30, 0x03, 0x7e, 0x0a, 0x5b, 0x36, 0x3e, 0x25, 0xda, 0xeb, 0xe8, 0x14,
0x43, 0x2b, 0x34, 0xf7, 0x68, 0x91, 0x71, 0x13, 0xd6, 0x87, 0xc1, 0x16, 0x70, 0x2c, 0x30, 0x6c,
0x36, 0x8c, 0x32, 0xd8, 0xfb, 0x90, 0x44, 0xae, 0xcb, 0x01, 0x69, 0x06, 0x48, 0x20, 0xd7, 0x65,
0xa9, 0x3b, 0xb0, 0xc9, 0x7a, 0xf4, 0xb0, 0x3f, 0xb1, 0x88, 0x28, 0x92, 0x61, 0x98, 0x0d, 0x9a,
0x50, 0x79, 0x9c, 0x61, 0x77, 0x21, 0x8b, 0x4f, 0x4c, 0x1d, 0xdb, 0x43, 0xcc, 0x71, 0x59, 0x86,
0xcb, 0x04, 0x41, 0x06, 0xba, 0x0d, 0x39, 0xd7, 0x73, 0x5c, 0xc7, 0xc7, 0x9e, 0x86, 0x74, 0xdd,
0xc3, 0xbe, 0x9f, 0x5f, 0xe7, 0xf5, 0x82, 0x78, 0x8d, 0x87, 0xcb, 0x77, 0x41, 0x6e, 0x20, 0x82,
0x94, 0x1c, 0xc4, 0xc8, 0xa9, 0x9f, 0x97, 0x4a, 0xb1, 0xbd, 0x8c, 0x4a, 0x3f, 0xaf, 0x3c, 0x88,
0x7f, 0x45, 0x41, 0x7e, 0xe4, 0x10, 0xac, 0xdc, 0x03, 0x99, 0x6e, 0x1d, 0x73, 0xe7, 0xfa, 0x6a,
0xcf, 0xf7, 0x4c, 0xc3, 0xc6, 0xfa, 0xb1, 0x6f, 0xf4, 0xa7, 0x2e, 0x56, 0x19, 0x65, 0xce, 0x6e,
0xd1, 0x05, 0xbb, 0x6d, 0x41, 0xdc, 0x73, 0x26, 0xb6, 0xce, 0x5c, 0x18, 0x57, 0xf9, 0x40, 0x79,
0x08, 0xc9, 0xd0, 0x45, 0xf2, 0x9b, 0xb9, 0x68, 0x83, 0xba, 0x88, 0x3a, 0x5d, 0x04, 0xd4, 0xc4,
0x40, 0x98, 0xa9, 0x0e, 0xa9, 0xf0, 0xc2, 0x13, 0x9e, 0x7c, 0x33, 0x5b, 0xcf, 0x68, 0xca, 0x27,
0xb0, 0x19, 0x7a, 0x23, 0x14, 0x97, 0x3b, 0x32, 0x17, 0x26, 0x84, 0xba, 0x0b, 0xb6, 0xd3, 0xf8,
0xd5, 0x95, 0x60, 0xdd, 0xcd, 0x6c, 0xd7, 0x62, 0x77, 0xd8, 0x07, 0x90, 0xf2, 0x4d, 0xc3, 0x46,
0x64, 0xe2, 0x61, 0xe1, 0xcc, 0x59, 0xa0, 0xfc, 0x3c, 0x0a, 0x6b, 0xdc, 0xe9, 0x73, 0xea, 0x49,
0x57, 0xab, 0x17, 0x5d, 0xa5, 0x5e, 0xec, 0x6d, 0xd5, 0x3b, 0x04, 0x08, 0x97, 0xe4, 0xe7, 0xe5,
0x52, 0x6c, 0x2f, 0xbd, 0x7f, 0x63, 0x55, 0x39, 0xbe, 0xdc, 0x9e, 0x69, 0x88, 0x43, 0x3d, 0x47,
0x0d, 0x9d, 0x15, 0x9f, 0xbb, 0x4c, 0x6b, 0x90, 0x1a, 0x98, 0x44, 0x43, 0x9e, 0x87, 0xa6, 0x4c,
0xce, 0xf4, 0xfe, 0x47, 0xcb, 0xb5, 0xe9, 0xbb, 0x54, 0xa1, 0xef, 0x52, 0xa5, 0x6e, 0x92, 0x1a,
0xc5, 0xaa, 0xc9, 0x81, 0xf8, 0x2a, 0x5f, 0x4a, 0x90, 0x0a, 0xa7, 0x55, 0x0e, 0x21, 0x1b, 0xb4,
0xae, 0x3d, 0xb6, 0x90, 0x21, 0xac, 0xba, 0xfb, 0x2f, 0xfd, 0xdf, 0xb7, 0x90, 0xa1, 0xa6, 0x45,
0xcb, 0x74, 0x70, 0xf5, 0x86, 0x47, 0x57, 0x6c, 0xf8, 0x82, 0xc3, 0x62, 0xff, 0xcd, 0x61, 0x0b,
0x5e, 0x90, 0x5f, 0xf7, 0xc2, 0xcf, 0x51, 0x48, 0x76, 0xd9, 0x21, 0x46, 0xd6, 0xff, 0x77, 0x0c,
0xb7, 0x21, 0xe5, 0x3a, 0x96, 0xc6, 0x33, 0x32, 0xcb, 0x24, 0x5d, 0xc7, 0x52, 0x97, 0x5c, 0x16,
0x7f, 0xa7, 0x67, 0x74, 0xed, 0x1d, 0x28, 0x98, 0x78, 0x5d, 0xc1, 0xef, 0x20, 0xc3, 0x05, 0x11,
0x8f, 0xed, 0xe7, 0x54, 0x09, 0xf6, 0x82, 0xf3, 0xb7, 0xb6, 0xb8, 0x6a, 0xf1, 0x1c, 0xaf, 0x0a,
0x34, 0xe5, 0xf1, 0x57, 0x49, 0xbc, 0xfc, 0xc5, 0x7f, 0x3e, 0x0b, 0xaa, 0x40, 0x97, 0x7f, 0x95,
0x20, 0xc5, 0xda, 0x3e, 0xc6, 0x04, 0x2d, 0x88, 0x27, 0xbd, 0xad, 0x78, 0x1f, 0x02, 0xf0, 0x62,
0xbe, 0xf9, 0x14, 0x8b, 0x8d, 0x4d, 0xb1, 0x48, 0xcf, 0x7c, 0x8a, 0x95, 0x2f, 0xc3, 0x4e, 0x63,
0x6f, 0xd2, 0xa9, 0x38, 0xba, 0x41, 0xbf, 0xd7, 0x21, 0x61, 0x4f, 0xc6, 0x1a, 0x7d, 0x26, 0x64,
0x6e, 0x19, 0x7b, 0x32, 0xee, 0x9f, 0xfa, 0x77, 0x7e, 0x91, 0x20, 0x3d, 0x77, 0x7c, 0x94, 0x02,
0x5c, 0xab, 0x1f, 0x75, 0x0e, 0x1e, 0x36, 0xb4, 0x56, 0x43, 0xbb, 0x7f, 0x54, 0x3b, 0xd4, 0xbe,
0x6a, 0x3f, 0x6c, 0x77, 0xbe, 0x6e, 0xe7, 0x22, 0x4a, 0x15, 0xb6, 0x58, 0x2e, 0x4c, 0xd5, 0xea,
0xbd, 0x66, 0xbb, 0x9f, 0x93, 0x0a, 0xef, 0x9d, 0x9d, 0x97, 0x36, 0xe7, 0xca, 0xd4, 0x06, 0x3e,
0xb6, 0xc9, 0x32, 0xe1, 0xa0, 0x73, 0x7c, 0xdc, 0xea, 0xe7, 0xa2, 0x4b, 0x04, 0x71, 0x43, 0xde,
0x86, 0xcd, 0x45, 0x42, 0xbb, 0x75, 0x94, 0x8b, 0x15, 0x94, 0xb3, 0xf3, 0xd2, 0xfa, 0x1c, 0xba,
0x6d, 0x5a, 0x85, 0xe4, 0xf7, 0xcf, 0x8b, 0x91, 0x9f, 0x7e, 0x28, 0x46, 0xee, 0xfc, 0x28, 0x41,
0x76, 0xe1, 0x94, 0x28, 0xdb, 0x70, 0xbd, 0xd7, 0x3a, 0x6c, 0x37, 0x1b, 0xda, 0x71, 0xef, 0x50,
0xeb, 0x7f, 0xd3, 0x6d, 0xce, 0x75, 0x71, 0x03, 0x32, 0x5d, 0xb5, 0xf9, 0xa8, 0xd3, 0x6f, 0xb2,
0x4c, 0x4e, 0x2a, 0x6c, 0x9c, 0x9d, 0x97, 0xd2, 0x5d, 0x0f, 0x9f, 0x38, 0x04, 0x33, 0xfe, 0x4d,
0x58, 0xef, 0xaa, 0x4d, 0xbe, 0x58, 0x0e, 0x8a, 0x16, 0x36, 0xcf, 0xce, 0x4b, 0xd9, 0xae, 0x87,
0xb9, 0x11, 0x18, 0x6c, 0x17, 0xb2, 0x5d, 0xb5, 0xd3, 0xed, 0xf4, 0x6a, 0x47, 0x1c, 0x15, 0x2b,
0xe4, 0xce, 0xce, 0x4b, 0x99, 0xe0, 0x88, 0x53, 0xd0, 0x6c, 0x9d, 0xf5, 0xfb, 0x2f, 0x2e, 0x8a,
0xd2, 0xcb, 0x8b, 0xa2, 0xf4, 0xc7, 0x45, 0x51, 0x7a, 0x76, 0x59, 0x8c, 0xbc, 0xbc, 0x2c, 0x46,
0x7e, 0xbb, 0x2c, 0x46, 0xbe, 0xbd, 0x6b, 0x98, 0x64, 0x34, 0x19, 0x54, 0x86, 0xce, 0xb8, 0x3a,
0xdb, 0xd5, 0xf9, 0xcf, 0xb9, 0x1f, 0x15, 0x83, 0x35, 0x36, 0xf8, 0xec, 0xef, 0x00, 0x00, 0x00,
0xff, 0xff, 0x5f, 0xad, 0x08, 0x71, 0x6a, 0x0c, 0x00, 0x00,
0xee, 0x41, 0xa6, 0x8b, 0x3c, 0xd2, 0xc3, 0xe4, 0x01, 0x46, 0x3a, 0xf6, 0x94, 0x6d, 0x88, 0x11,
0x87, 0x20, 0x2b, 0x27, 0x15, 0xa5, 0xfd, 0x8c, 0xca, 0x07, 0x8a, 0x02, 0xf2, 0x08, 0xf9, 0xa3,
0x5c, 0xa4, 0x28, 0xed, 0xa7, 0x55, 0xf6, 0x5d, 0x9a, 0x80, 0x4c, 0xa9, 0x94, 0x61, 0xda, 0x3a,
0x3e, 0x0d, 0x18, 0x6c, 0x40, 0xa3, 0x83, 0x29, 0xc1, 0xbe, 0xa0, 0xf0, 0x81, 0x52, 0x85, 0x98,
0xeb, 0x39, 0xce, 0xe3, 0x5c, 0xb4, 0x28, 0xed, 0xa7, 0x0e, 0x6e, 0x96, 0x97, 0xa4, 0xe3, 0x7d,
0x94, 0x79, 0x1f, 0xe5, 0x2e, 0x05, 0xd7, 0xe4, 0x17, 0xaf, 0x76, 0xd7, 0x54, 0xce, 0x2c, 0x8d,
0x21, 0x5e, 0xb3, 0x9c, 0xe1, 0x93, 0x56, 0x23, 0x5c, 0x95, 0x34, 0x5b, 0x95, 0xd2, 0x86, 0x34,
0x15, 0xdc, 0xd7, 0x46, 0xac, 0x1f, 0x36, 0xfd, 0x95, 0x13, 0x71, 0x89, 0x16, 0x9a, 0x17, 0x13,
0xa5, 0x58, 0x01, 0x1e, 0x2a, 0xfd, 0x29, 0xc3, 0xba, 0x90, 0xa6, 0x0e, 0x71, 0x21, 0x1e, 0x9b,
0x31, 0x75, 0xb0, 0xb7, 0x5c, 0x35, 0x50, 0xb7, 0xee, 0xd8, 0x3e, 0xb6, 0xfd, 0x89, 0x2f, 0x6a,
0x06, 0x4c, 0xe5, 0x16, 0x24, 0x86, 0x23, 0x64, 0xda, 0x9a, 0xa9, 0xb3, 0xb5, 0x25, 0x6b, 0xa9,
0x8b, 0x57, 0xbb, 0xf1, 0x3a, 0x8d, 0xb5, 0x1a, 0x6a, 0x9c, 0x25, 0x5b, 0xba, 0x72, 0x0d, 0xd6,
0x47, 0xd8, 0x34, 0x46, 0x84, 0x49, 0x15, 0x55, 0xc5, 0x48, 0xf9, 0x02, 0x64, 0x6a, 0x8f, 0x9c,
0xcc, 0x56, 0x90, 0x2f, 0x73, 0xef, 0x94, 0x03, 0xef, 0x94, 0xfb, 0x81, 0x77, 0x6a, 0x09, 0x3a,
0xf1, 0xb3, 0xdf, 0x77, 0x25, 0x95, 0x31, 0x94, 0x16, 0x64, 0x2c, 0xe4, 0x13, 0x6d, 0x40, 0xd5,
0xa3, 0xd3, 0xc7, 0x58, 0x89, 0xdd, 0x55, 0xd2, 0x08, 0x95, 0x03, 0x51, 0x28, 0x97, 0x87, 0x74,
0x65, 0x1f, 0xb2, 0xac, 0xd4, 0xd0, 0x19, 0x8f, 0x4d, 0xa2, 0xb1, 0x4d, 0x58, 0x67, 0x9b, 0xb0,
0x41, 0xe3, 0x75, 0x16, 0x7e, 0x40, 0xb7, 0x63, 0x07, 0x92, 0x3a, 0x22, 0x88, 0x43, 0xe2, 0x0c,
0x92, 0xa0, 0x01, 0x96, 0xfc, 0x18, 0x36, 0x4f, 0x90, 0x65, 0xea, 0x88, 0x38, 0x9e, 0xcf, 0x21,
0x09, 0x5e, 0x65, 0x16, 0x66, 0xc0, 0x4f, 0x61, 0xdb, 0xc6, 0xa7, 0x44, 0x7b, 0x1d, 0x9d, 0x64,
0x68, 0x85, 0xe6, 0x1e, 0x2d, 0x32, 0x6e, 0xc2, 0xc6, 0x30, 0xd8, 0x02, 0x8e, 0x05, 0x86, 0xcd,
0x84, 0x51, 0x06, 0x7b, 0x1f, 0x12, 0xc8, 0x75, 0x39, 0x20, 0xc5, 0x00, 0x71, 0xe4, 0xba, 0x2c,
0x75, 0x07, 0xb6, 0x58, 0x8f, 0x1e, 0xf6, 0x27, 0x16, 0x11, 0x45, 0xd2, 0x0c, 0xb3, 0x49, 0x13,
0x2a, 0x8f, 0x33, 0xec, 0x1e, 0x64, 0xf0, 0x89, 0xa9, 0x63, 0x7b, 0x88, 0x39, 0x2e, 0xc3, 0x70,
0xe9, 0x20, 0xc8, 0x40, 0xb7, 0x21, 0xeb, 0x7a, 0x8e, 0xeb, 0xf8, 0xd8, 0xd3, 0x90, 0xae, 0x7b,
0xd8, 0xf7, 0x73, 0x1b, 0xbc, 0x5e, 0x10, 0xaf, 0xf2, 0x70, 0xe9, 0x2e, 0xc8, 0x0d, 0x44, 0x90,
0x92, 0x85, 0x28, 0x39, 0xf5, 0x73, 0x52, 0x31, 0xba, 0x9f, 0x56, 0xe9, 0xe7, 0x95, 0x07, 0xf1,
0xaf, 0x08, 0xc8, 0x8f, 0x1c, 0x82, 0x95, 0x7b, 0x20, 0xd3, 0xad, 0x63, 0xee, 0xdc, 0x58, 0xed,
0xf9, 0x9e, 0x69, 0xd8, 0x58, 0x3f, 0xf6, 0x8d, 0xfe, 0xd4, 0xc5, 0x2a, 0xa3, 0xcc, 0xd9, 0x2d,
0xb2, 0x60, 0xb7, 0x6d, 0x88, 0x79, 0xce, 0xc4, 0xd6, 0x99, 0x0b, 0x63, 0x2a, 0x1f, 0x28, 0x0f,
0x21, 0x11, 0xba, 0x48, 0x7e, 0x33, 0x17, 0x6d, 0x52, 0x17, 0x51, 0xa7, 0x8b, 0x80, 0x1a, 0x1f,
0x08, 0x33, 0xd5, 0x20, 0x19, 0x5e, 0x78, 0xc2, 0x93, 0x6f, 0x66, 0xeb, 0x19, 0x4d, 0xf9, 0x04,
0xb6, 0x42, 0x6f, 0x84, 0xe2, 0x72, 0x47, 0x66, 0xc3, 0x84, 0x50, 0x77, 0xc1, 0x76, 0x1a, 0xbf,
0xba, 0xe2, 0xac, 0xbb, 0x99, 0xed, 0x5a, 0xec, 0x0e, 0xfb, 0x00, 0x92, 0xbe, 0x69, 0xd8, 0x88,
0x4c, 0x3c, 0x2c, 0x9c, 0x39, 0x0b, 0x94, 0x9e, 0x47, 0x60, 0x9d, 0x3b, 0x7d, 0x4e, 0x3d, 0xe9,
0x6a, 0xf5, 0x22, 0xab, 0xd4, 0x8b, 0xbe, 0xad, 0x7a, 0x87, 0x00, 0xe1, 0x92, 0xfc, 0x9c, 0x5c,
0x8c, 0xee, 0xa7, 0x0e, 0x6e, 0xac, 0x2a, 0xc7, 0x97, 0xdb, 0x33, 0x0d, 0x71, 0xa8, 0xe7, 0xa8,
0xa1, 0xb3, 0x62, 0x73, 0x97, 0x69, 0x15, 0x92, 0x03, 0x93, 0x68, 0xc8, 0xf3, 0xd0, 0x94, 0xc9,
0x99, 0x3a, 0xf8, 0x68, 0xb9, 0x36, 0x7d, 0x97, 0xca, 0xf4, 0x5d, 0x2a, 0xd7, 0x4c, 0x52, 0xa5,
0x58, 0x35, 0x31, 0x10, 0x5f, 0xa5, 0x4b, 0x09, 0x92, 0xe1, 0xb4, 0xca, 0x21, 0x64, 0x82, 0xd6,
0xb5, 0xc7, 0x16, 0x32, 0x84, 0x55, 0xf7, 0xfe, 0xa5, 0xff, 0xfb, 0x16, 0x32, 0xd4, 0x94, 0x68,
0x99, 0x0e, 0xae, 0xde, 0xf0, 0xc8, 0x8a, 0x0d, 0x5f, 0x70, 0x58, 0xf4, 0xbf, 0x39, 0x6c, 0xc1,
0x0b, 0xf2, 0xeb, 0x5e, 0xf8, 0x39, 0x02, 0x89, 0x2e, 0x3b, 0xc4, 0xc8, 0xfa, 0xff, 0x8e, 0xe1,
0x0e, 0x24, 0x5d, 0xc7, 0xd2, 0x78, 0x46, 0x66, 0x99, 0x84, 0xeb, 0x58, 0xea, 0x92, 0xcb, 0x62,
0xef, 0xf4, 0x8c, 0xae, 0xbf, 0x03, 0x05, 0xe3, 0xaf, 0x2b, 0xf8, 0x1d, 0xa4, 0xb9, 0x20, 0xe2,
0xb1, 0xfd, 0x9c, 0x2a, 0xc1, 0x5e, 0x70, 0xfe, 0xd6, 0x16, 0x56, 0x2d, 0x9e, 0xe3, 0x55, 0x81,
0xa6, 0x3c, 0xfe, 0x2a, 0x89, 0x97, 0xbf, 0xf0, 0xcf, 0x67, 0x41, 0x15, 0xe8, 0xd2, 0xaf, 0x12,
0x24, 0x59, 0xdb, 0xc7, 0x98, 0xa0, 0x05, 0xf1, 0xa4, 0xb7, 0x15, 0xef, 0x43, 0x00, 0x5e, 0xcc,
0x37, 0x9f, 0x62, 0xb1, 0xb1, 0x49, 0x16, 0xe9, 0x99, 0x4f, 0xb1, 0xf2, 0x65, 0xd8, 0x69, 0xf4,
0x4d, 0x3a, 0x15, 0x47, 0x37, 0xe8, 0xf7, 0x3a, 0xc4, 0xed, 0xc9, 0x58, 0xa3, 0xcf, 0x84, 0xcc,
0x2d, 0x63, 0x4f, 0xc6, 0xfd, 0x53, 0xff, 0xce, 0x2f, 0x12, 0xa4, 0xe6, 0x8e, 0x8f, 0x92, 0x87,
0x6b, 0xb5, 0xa3, 0x4e, 0xfd, 0x61, 0x43, 0x6b, 0x35, 0xb4, 0xfb, 0x47, 0xd5, 0x43, 0xed, 0xab,
0xf6, 0xc3, 0x76, 0xe7, 0xeb, 0x76, 0x76, 0x4d, 0xa9, 0xc0, 0x36, 0xcb, 0x85, 0xa9, 0x6a, 0xad,
0xd7, 0x6c, 0xf7, 0xb3, 0x52, 0xfe, 0xbd, 0xb3, 0xf3, 0xe2, 0xd6, 0x5c, 0x99, 0xea, 0xc0, 0xc7,
0x36, 0x59, 0x26, 0xd4, 0x3b, 0xc7, 0xc7, 0xad, 0x7e, 0x36, 0xb2, 0x44, 0x10, 0x37, 0xe4, 0x6d,
0xd8, 0x5a, 0x24, 0xb4, 0x5b, 0x47, 0xd9, 0x68, 0x5e, 0x39, 0x3b, 0x2f, 0x6e, 0xcc, 0xa1, 0xdb,
0xa6, 0x95, 0x4f, 0x7c, 0xff, 0xbc, 0xb0, 0xf6, 0xd3, 0x0f, 0x05, 0xe9, 0xce, 0x8f, 0x12, 0x64,
0x16, 0x4e, 0x89, 0xb2, 0x03, 0xd7, 0x7b, 0xad, 0xc3, 0x76, 0xb3, 0xa1, 0x1d, 0xf7, 0x0e, 0xb5,
0xfe, 0x37, 0xdd, 0xe6, 0x5c, 0x17, 0x37, 0x20, 0xdd, 0x55, 0x9b, 0x8f, 0x3a, 0xfd, 0x26, 0xcb,
0x64, 0xa5, 0xfc, 0xe6, 0xd9, 0x79, 0x31, 0xd5, 0xf5, 0xf0, 0x89, 0x43, 0x30, 0xe3, 0xdf, 0x84,
0x8d, 0xae, 0xda, 0xe4, 0x8b, 0xe5, 0xa0, 0x48, 0x7e, 0xeb, 0xec, 0xbc, 0x98, 0xe9, 0x7a, 0x98,
0x1b, 0x81, 0xc1, 0xf6, 0x20, 0xd3, 0x55, 0x3b, 0xdd, 0x4e, 0xaf, 0x7a, 0xc4, 0x51, 0xd1, 0x7c,
0xf6, 0xec, 0xbc, 0x98, 0x0e, 0x8e, 0x38, 0x05, 0xcd, 0xd6, 0x59, 0xbb, 0xff, 0xe2, 0xa2, 0x20,
0xbd, 0xbc, 0x28, 0x48, 0x7f, 0x5c, 0x14, 0xa4, 0x67, 0x97, 0x85, 0xb5, 0x97, 0x97, 0x85, 0xb5,
0xdf, 0x2e, 0x0b, 0x6b, 0xdf, 0xde, 0x35, 0x4c, 0x32, 0x9a, 0x0c, 0xca, 0x43, 0x67, 0x5c, 0x99,
0xed, 0xea, 0xfc, 0xe7, 0xdc, 0x8f, 0x8a, 0xc1, 0x3a, 0x1b, 0x7c, 0xf6, 0x77, 0x00, 0x00, 0x00,
0xff, 0xff, 0x94, 0x73, 0x22, 0x3b, 0x6a, 0x0c, 0x00, 0x00,
}
func (m *PartSetHeader) Marshal() (dAtA []byte, err error) {


+ 2
- 2
proto/types/types.proto View File

@ -11,7 +11,7 @@ import "proto/version/version.proto";
// BlockIdFlag indicates which BlcokID the signature is for
enum BlockIDFlag {
option (gogoproto.goproto_enum_stringer) = false;
option (gogoproto.goproto_enum_stringer) = true;
option (gogoproto.goproto_enum_prefix) = false;
BLOCKD_ID_FLAG_UNKNOWN = 0;
@ -22,7 +22,7 @@ enum BlockIDFlag {
// SignedMsgType is a type of signed message in the consensus.
enum SignedMsgType {
option (gogoproto.goproto_enum_stringer) = false;
option (gogoproto.goproto_enum_stringer) = true;
option (gogoproto.goproto_enum_prefix) = false;
SIGNED_MSG_TYPE_UNKNOWN = 0;


+ 11
- 3
rpc/client/evidence_test.go View File

@ -25,10 +25,14 @@ func newEvidence(t *testing.T, val *privval.FilePV,
chainID string) *types.DuplicateVoteEvidence {
var err error
vote.Signature, err = val.Key.PrivKey.Sign(vote.SignBytes(chainID))
v := vote.ToProto()
v2 := vote2.ToProto()
vote.Signature, err = val.Key.PrivKey.Sign(types.VoteSignBytes(chainID, v))
require.NoError(t, err)
vote2.Signature, err = val.Key.PrivKey.Sign(vote2.SignBytes(chainID))
vote2.Signature, err = val.Key.PrivKey.Sign(types.VoteSignBytes(chainID, v2))
require.NoError(t, err)
return types.NewDuplicateVoteEvidence(vote, vote2)
@ -197,8 +201,12 @@ func TestBroadcastEvidence_ConflictingHeadersEvidence(t *testing.T) {
Type: tmproto.PrecommitType,
BlockID: h2.Commit.BlockID,
}
signBytes, err := pv.Key.PrivKey.Sign(vote.SignBytes(chainID))
v := vote.ToProto()
signBytes, err := pv.Key.PrivKey.Sign(types.VoteSignBytes(chainID, v))
require.NoError(t, err)
vote.Signature = v.Signature
h2.Commit.Signatures[0] = types.NewCommitSigForBlock(signBytes, pv.Key.Address, h2.Time)
t.Logf("h1 AppHash: %X", h1.AppHash)


+ 1
- 1
state/tx_filter_test.go View File

@ -26,7 +26,7 @@ func TestTxFilter(t *testing.T) {
isErr bool
}{
{types.Tx(tmrand.Bytes(1680)), false},
{types.Tx(tmrand.Bytes(1839)), true},
{types.Tx(tmrand.Bytes(1853)), true},
{types.Tx(tmrand.Bytes(3000)), true},
}


+ 38
- 12
state/validation_test.go View File

@ -195,11 +195,17 @@ func TestValidateBlockCommit(t *testing.T) {
Type: tmproto.PrecommitType,
BlockID: blockID,
}
err = badPrivVal.SignVote(chainID, goodVote)
g := goodVote.ToProto()
b := badVote.ToProto()
err = badPrivVal.SignVote(chainID, g)
require.NoError(t, err, "height %d", height)
err = badPrivVal.SignVote(chainID, badVote)
err = badPrivVal.SignVote(chainID, b)
require.NoError(t, err, "height %d", height)
goodVote.Signature, badVote.Signature = g.Signature, b.Signature
wrongSigsCommit = types.NewCommit(goodVote.Height, goodVote.Round,
blockID, []types.CommitSig{goodVote.CommitSig(), badVote.CommitSig()})
}
@ -358,10 +364,14 @@ func TestValidateAmnesiaEvidence(t *testing.T) {
state, stateDB, vals := makeState(1, int(height))
addr, val := state.Validators.GetByIndex(0)
voteA := makeVote(height, 1, 0, addr, blockID)
err := vals[val.Address.String()].SignVote(chainID, voteA)
vA := voteA.ToProto()
err := vals[val.Address.String()].SignVote(chainID, vA)
voteA.Signature = vA.Signature
require.NoError(t, err)
voteB := makeVote(height, 2, 0, addr, types.BlockID{})
err = vals[val.Address.String()].SignVote(chainID, voteB)
vB := voteB.ToProto()
err = vals[val.Address.String()].SignVote(chainID, vB)
voteB.Signature = vB.Signature
require.NoError(t, err)
ae := types.AmnesiaEvidence{
PotentialAmnesiaEvidence: types.PotentialAmnesiaEvidence{
@ -434,13 +444,19 @@ func TestVerifyEvidenceWithAmnesiaEvidence(t *testing.T) {
addr, val := state.Validators.GetByIndex(0)
addr2, val2 := state.Validators.GetByIndex(1)
voteA := makeVote(height, 1, 0, addr, types.BlockID{})
err := vals[val.Address.String()].SignVote(chainID, voteA)
vA := voteA.ToProto()
err := vals[val.Address.String()].SignVote(chainID, vA)
voteA.Signature = vA.Signature
require.NoError(t, err)
voteB := makeVote(height, 2, 0, addr, blockID)
err = vals[val.Address.String()].SignVote(chainID, voteB)
vB := voteB.ToProto()
err = vals[val.Address.String()].SignVote(chainID, vB)
voteB.Signature = vB.Signature
require.NoError(t, err)
voteC := makeVote(height, 2, 1, addr2, blockID)
err = vals[val2.Address.String()].SignVote(chainID, voteC)
vC := voteC.ToProto()
err = vals[val2.Address.String()].SignVote(chainID, vC)
voteC.Signature = vC.Signature
require.NoError(t, err)
//var ae types.Evidence
badAe := types.AmnesiaEvidence{
@ -460,11 +476,15 @@ func TestVerifyEvidenceWithAmnesiaEvidence(t *testing.T) {
}
addr3, val3 := state.Validators.GetByIndex(2)
voteD := makeVote(height, 2, 2, addr3, blockID)
err = vals[val3.Address.String()].SignVote(chainID, voteD)
vD := voteD.ToProto()
err = vals[val3.Address.String()].SignVote(chainID, vD)
require.NoError(t, err)
voteD.Signature = vD.Signature
addr4, val4 := state.Validators.GetByIndex(3)
voteE := makeVote(height, 2, 3, addr4, blockID)
err = vals[val4.Address.String()].SignVote(chainID, voteE)
vE := voteE.ToProto()
err = vals[val4.Address.String()].SignVote(chainID, vE)
voteE.Signature = vE.Signature
require.NoError(t, err)
goodAe := types.AmnesiaEvidence{
@ -513,7 +533,9 @@ func TestVerifyEvidenceWithLunaticValidatorEvidence(t *testing.T) {
ProposerAddress: crypto.AddressHash([]byte("proposer_address")),
}
vote := makeVote(3, 1, 0, addr, blockID)
err := vals[val.Address.String()].SignVote(chainID, vote)
v := vote.ToProto()
err := vals[val.Address.String()].SignVote(chainID, v)
vote.Signature = v.Signature
require.NoError(t, err)
ev := types.LunaticValidatorEvidence{
Header: h,
@ -533,7 +555,9 @@ func TestVerifyEvidenceWithPhantomValidatorEvidence(t *testing.T) {
state.ConsensusParams.Evidence.MaxAgeNumBlocks = 1
addr, val := state.Validators.GetByIndex(0)
vote := makeVote(3, 1, 0, addr, blockID)
err := vals[val.Address.String()].SignVote(chainID, vote)
v := vote.ToProto()
err := vals[val.Address.String()].SignVote(chainID, v)
vote.Signature = v.Signature
require.NoError(t, err)
ev := types.PhantomValidatorEvidence{
Vote: vote,
@ -549,7 +573,9 @@ func TestVerifyEvidenceWithPhantomValidatorEvidence(t *testing.T) {
privVal := types.NewMockPV()
pubKey, _ := privVal.GetPubKey()
vote2 := makeVote(3, 1, 0, pubKey.Address(), blockID)
err = privVal.SignVote(chainID, vote2)
v2 := vote2.ToProto()
err = privVal.SignVote(chainID, v2)
vote2.Signature = v2.Signature
require.NoError(t, err)
ev = types.PhantomValidatorEvidence{
Vote: vote2,


+ 8
- 4
tools/tm-signer-harness/internal/test_harness.go View File

@ -229,11 +229,13 @@ func (th *TestHarness) TestSignProposal() error {
},
Timestamp: time.Now(),
}
propBytes := prop.SignBytes(th.chainID)
if err := th.signerClient.SignProposal(th.chainID, prop); err != nil {
p := prop.ToProto()
propBytes := types.ProposalSignBytes(th.chainID, p)
if err := th.signerClient.SignProposal(th.chainID, p); err != nil {
th.logger.Error("FAILED: Signing of proposal", "err", err)
return newTestHarnessError(ErrTestSignProposalFailed, err, "")
}
prop.Signature = p.Signature
th.logger.Debug("Signed proposal", "prop", prop)
// first check that it's a basically valid proposal
if err := prop.ValidateBasic(); err != nil {
@ -276,12 +278,14 @@ func (th *TestHarness) TestSignVote() error {
ValidatorAddress: tmhash.SumTruncated([]byte("addr")),
Timestamp: time.Now(),
}
voteBytes := vote.SignBytes(th.chainID)
v := vote.ToProto()
voteBytes := types.VoteSignBytes(th.chainID, v)
// sign the vote
if err := th.signerClient.SignVote(th.chainID, vote); err != nil {
if err := th.signerClient.SignVote(th.chainID, v); err != nil {
th.logger.Error("FAILED: Signing of vote", "err", err)
return newTestHarnessError(ErrTestSignVoteFailed, err, fmt.Sprintf("voteType=%d", voteType))
}
vote.Signature = v.Signature
th.logger.Debug("Signed vote", "vote", vote)
// validate the contents of the vote
if err := vote.ValidateBasic(); err != nil {


+ 1
- 1
tools/tm-signer-harness/internal/test_harness_test.go View File

@ -23,7 +23,7 @@ const (
"pub_key": {
"type": "tendermint/PubKeyEd25519",
"value": "ZCsuTjaczEyon70nmKxwvwu+jqrbq5OH3yQjcK0SFxc="
},
},
"priv_key": {
"type": "tendermint/PrivKeyEd25519",
"value": "8O39AkQsoe1sBQwud/Kdul8lg8K9SFsql9aZvwXQSt1kKy5ONpzMTKifvSeYrHC/C76Oqturk4ffJCNwrRIXFw=="


+ 2
- 1
types/block.go View File

@ -773,7 +773,8 @@ func (commit *Commit) GetVote(valIdx int32) *Vote {
// signed over are otherwise the same for all validators.
// Panics if valIdx >= commit.Size().
func (commit *Commit) VoteSignBytes(chainID string, valIdx int32) []byte {
return commit.GetVote(valIdx).SignBytes(chainID)
v := commit.GetVote(valIdx).ToProto()
return VoteSignBytes(chainID, v)
}
// Type returns the vote type of the commit, which is always VoteTypePrecommit


+ 7
- 7
types/block_test.go View File

@ -378,9 +378,9 @@ func TestBlockMaxDataBytes(t *testing.T) {
}{
0: {-10, 1, 0, true, 0},
1: {10, 1, 0, true, 0},
2: {849, 1, 0, true, 0},
3: {850, 1, 0, false, 0},
4: {851, 1, 0, false, 1},
2: {846, 1, 0, true, 0},
3: {848, 1, 0, false, 0},
4: {849, 1, 0, false, 1},
}
for i, tc := range testCases {
@ -408,10 +408,10 @@ func TestBlockMaxDataBytesUnknownEvidence(t *testing.T) {
}{
0: {-10, 0, 1, true, 0},
1: {10, 0, 1, true, 0},
2: {849, 0, 1, true, 0},
3: {850, 0, 1, false, 0},
4: {1294, 1, 1, false, 0},
5: {1295, 1, 1, false, 1},
2: {847, 0, 1, true, 0},
3: {848, 0, 1, false, 0},
4: {1292, 1, 1, false, 0},
5: {1293, 1, 1, false, 1},
}
for i, tc := range testCases {


+ 11
- 41
types/canonical.go View File

@ -3,7 +3,6 @@ package types
import (
"time"
"github.com/tendermint/tendermint/libs/bytes"
tmproto "github.com/tendermint/tendermint/proto/types"
tmtime "github.com/tendermint/tendermint/types/time"
)
@ -13,66 +12,37 @@ import (
// TimeFormat is used for generating the sigs
const TimeFormat = time.RFC3339Nano
type CanonicalBlockID struct {
Hash bytes.HexBytes
PartsHeader CanonicalPartSetHeader
}
type CanonicalPartSetHeader struct {
Hash bytes.HexBytes
Total uint32
}
type CanonicalProposal struct {
Type tmproto.SignedMsgType // type alias for byte
Height int64 `binary:"fixed64"`
Round int64 `binary:"fixed64"`
POLRound int64 `binary:"fixed64"`
BlockID CanonicalBlockID
Timestamp time.Time
ChainID string
}
type CanonicalVote struct {
Type tmproto.SignedMsgType // type alias for byte
Height int64 `binary:"fixed64"`
Round int64 `binary:"fixed64"`
BlockID CanonicalBlockID
Timestamp time.Time
ChainID string
}
//-----------------------------------
// Canonicalize the structs
func CanonicalizeBlockID(blockID BlockID) CanonicalBlockID {
return CanonicalBlockID{
func CanonicalizeBlockID(blockID tmproto.BlockID) tmproto.CanonicalBlockID {
return tmproto.CanonicalBlockID{
Hash: blockID.Hash,
PartsHeader: CanonicalizePartSetHeader(blockID.PartsHeader),
}
}
func CanonicalizePartSetHeader(psh PartSetHeader) CanonicalPartSetHeader {
return CanonicalPartSetHeader{
psh.Hash,
psh.Total,
func CanonicalizePartSetHeader(psh tmproto.PartSetHeader) tmproto.CanonicalPartSetHeader {
return tmproto.CanonicalPartSetHeader{
Hash: psh.Hash,
Total: psh.Total,
}
}
func CanonicalizeProposal(chainID string, proposal *Proposal) CanonicalProposal {
return CanonicalProposal{
func CanonicalizeProposal(chainID string, proposal *tmproto.Proposal) tmproto.CanonicalProposal {
return tmproto.CanonicalProposal{
Type: tmproto.ProposalType,
Height: proposal.Height,
Round: int64(proposal.Round), // cast int->int64 to make amino encode it fixed64 (does not work for int)
POLRound: int64(proposal.POLRound),
POLRound: int64(proposal.PolRound),
BlockID: CanonicalizeBlockID(proposal.BlockID),
Timestamp: proposal.Timestamp,
ChainID: chainID,
}
}
func CanonicalizeVote(chainID string, vote *Vote) CanonicalVote {
return CanonicalVote{
func CanonicalizeVote(chainID string, vote *tmproto.Vote) tmproto.CanonicalVote {
return tmproto.CanonicalVote{
Type: vote.Type,
Height: vote.Height,
Round: int64(vote.Round), // cast int->int64 to make amino encode it fixed64 (does not work for int)


+ 22
- 10
types/evidence.go View File

@ -463,12 +463,13 @@ func (dve *DuplicateVoteEvidence) Verify(chainID string, pubKey crypto.PubKey) e
return fmt.Errorf("address (%X) doesn't match pubkey (%v - %X)",
addr, pubKey, pubKey.Address())
}
va := dve.VoteA.ToProto()
vb := dve.VoteB.ToProto()
// Signatures must be valid
if !pubKey.VerifyBytes(dve.VoteA.SignBytes(chainID), dve.VoteA.Signature) {
if !pubKey.VerifyBytes(VoteSignBytes(chainID, va), dve.VoteA.Signature) {
return fmt.Errorf("verifying VoteA: %w", ErrVoteInvalidSignature)
}
if !pubKey.VerifyBytes(dve.VoteB.SignBytes(chainID), dve.VoteB.Signature) {
if !pubKey.VerifyBytes(VoteSignBytes(chainID, vb), dve.VoteB.Signature) {
return fmt.Errorf("verifying VoteB: %w", ErrVoteInvalidSignature)
}
@ -841,8 +842,8 @@ func (e PhantomValidatorEvidence) Bytes() []byte {
func (e PhantomValidatorEvidence) Verify(chainID string, pubKey crypto.PubKey) error {
// signature must be verified to the chain ID
if !pubKey.VerifyBytes(e.Vote.SignBytes(chainID), e.Vote.Signature) {
v := e.Vote.ToProto()
if !pubKey.VerifyBytes(VoteSignBytes(chainID, v), e.Vote.Signature) {
return errors.New("invalid signature")
}
@ -930,7 +931,8 @@ func (e LunaticValidatorEvidence) Verify(chainID string, pubKey crypto.PubKey) e
)
}
if !pubKey.VerifyBytes(e.Vote.SignBytes(chainID), e.Vote.Signature) {
v := e.Vote.ToProto()
if !pubKey.VerifyBytes(VoteSignBytes(chainID, v), e.Vote.Signature) {
return errors.New("invalid signature")
}
@ -1072,11 +1074,14 @@ func (e PotentialAmnesiaEvidence) Verify(chainID string, pubKey crypto.PubKey) e
addr, pubKey, pubKey.Address())
}
va := e.VoteA.ToProto()
vb := e.VoteB.ToProto()
// Signatures must be valid
if !pubKey.VerifyBytes(e.VoteA.SignBytes(chainID), e.VoteA.Signature) {
if !pubKey.VerifyBytes(VoteSignBytes(chainID, va), e.VoteA.Signature) {
return fmt.Errorf("verifying VoteA: %w", ErrVoteInvalidSignature)
}
if !pubKey.VerifyBytes(e.VoteB.SignBytes(chainID), e.VoteB.Signature) {
if !pubKey.VerifyBytes(VoteSignBytes(chainID, vb), e.VoteB.Signature) {
return fmt.Errorf("verifying VoteB: %w", ErrVoteInvalidSignature)
}
@ -1247,7 +1252,8 @@ func (e ProofOfLockChange) ValidateVotes(valSet *ValidatorSet, chainID string) e
for _, validator := range valSet.Validators {
if bytes.Equal(validator.Address, vote.ValidatorAddress) {
exists = true
if !validator.PubKey.VerifyBytes(vote.SignBytes(chainID), vote.Signature) {
v := vote.ToProto()
if !validator.PubKey.VerifyBytes(VoteSignBytes(chainID, v), vote.Signature) {
return fmt.Errorf("cannot verify vote (from validator: %d) against signature: %v",
vote.ValidatorIndex, vote.Signature)
}
@ -1615,7 +1621,13 @@ func NewMockPOLC(height int64, time time.Time, pubKey crypto.PubKey) ProofOfLock
pKey, _ := voteVal.GetPubKey()
vote := Vote{Type: tmproto.PrecommitType, Height: height, Round: 1, BlockID: BlockID{},
Timestamp: time, ValidatorAddress: pKey.Address(), ValidatorIndex: 1, Signature: []byte{}}
_ = voteVal.SignVote("mock-chain-id", &vote)
v := vote.ToProto()
if err := voteVal.SignVote("mock-chain-id", v); err != nil {
panic(err)
}
vote.Signature = v.Signature
return ProofOfLockChange{
Votes: []Vote{vote},
PubKey: pubKey,


+ 11
- 3
types/evidence_test.go View File

@ -34,12 +34,17 @@ func TestEvidence(t *testing.T) {
const chainID = "mychain"
vote1 := makeVote(t, val, chainID, 0, 10, 2, 1, blockID, defaultVoteTime)
err := val.SignVote(chainID, vote1)
v1 := vote1.ToProto()
err := val.SignVote(chainID, v1)
require.NoError(t, err)
badVote := makeVote(t, val, chainID, 0, 10, 2, 1, blockID, defaultVoteTime)
err = val2.SignVote(chainID, badVote)
bv := badVote.ToProto()
err = val2.SignVote(chainID, bv)
require.NoError(t, err)
vote1.Signature = v1.Signature
badVote.Signature = bv.Signature
cases := []voteData{
{vote1, makeVote(t, val, chainID, 0, 10, 2, 1, blockID2, defaultVoteTime), true}, // different block ids
{vote1, makeVote(t, val, chainID, 0, 10, 2, 1, blockID3, defaultVoteTime), true},
@ -542,10 +547,13 @@ func makeVote(
BlockID: blockID,
Timestamp: time,
}
err = val.SignVote(chainID, v)
vpb := v.ToProto()
err = val.SignVote(chainID, vpb)
if err != nil {
panic(err)
}
v.Signature = vpb.Signature
return v
}


+ 11
- 8
types/priv_validator.go View File

@ -7,6 +7,7 @@ import (
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
tmproto "github.com/tendermint/tendermint/proto/types"
)
// PrivValidator defines the functionality of a local Tendermint validator
@ -14,8 +15,8 @@ import (
type PrivValidator interface {
GetPubKey() (crypto.PubKey, error)
SignVote(chainID string, vote *Vote) error
SignProposal(chainID string, proposal *Proposal) error
SignVote(chainID string, vote *tmproto.Vote) error
SignProposal(chainID string, proposal *tmproto.Proposal) error
}
type PrivValidatorsByAddress []PrivValidator
@ -71,12 +72,13 @@ func (pv MockPV) GetPubKey() (crypto.PubKey, error) {
}
// Implements PrivValidator.
func (pv MockPV) SignVote(chainID string, vote *Vote) error {
func (pv MockPV) SignVote(chainID string, vote *tmproto.Vote) error {
useChainID := chainID
if pv.breakVoteSigning {
useChainID = "incorrect-chain-id"
}
signBytes := vote.SignBytes(useChainID)
signBytes := VoteSignBytes(useChainID, vote)
sig, err := pv.PrivKey.Sign(signBytes)
if err != nil {
return err
@ -86,12 +88,13 @@ func (pv MockPV) SignVote(chainID string, vote *Vote) error {
}
// Implements PrivValidator.
func (pv MockPV) SignProposal(chainID string, proposal *Proposal) error {
func (pv MockPV) SignProposal(chainID string, proposal *tmproto.Proposal) error {
useChainID := chainID
if pv.breakProposalSigning {
useChainID = "incorrect-chain-id"
}
signBytes := proposal.SignBytes(useChainID)
signBytes := ProposalSignBytes(useChainID, proposal)
sig, err := pv.PrivKey.Sign(signBytes)
if err != nil {
return err
@ -128,12 +131,12 @@ type ErroringMockPV struct {
var ErroringMockPVErr = errors.New("erroringMockPV always returns an error")
// Implements PrivValidator.
func (pv *ErroringMockPV) SignVote(chainID string, vote *Vote) error {
func (pv *ErroringMockPV) SignVote(chainID string, vote *tmproto.Vote) error {
return ErroringMockPVErr
}
// Implements PrivValidator.
func (pv *ErroringMockPV) SignProposal(chainID string, proposal *Proposal) error {
func (pv *ErroringMockPV) SignProposal(chainID string, proposal *tmproto.Proposal) error {
return ErroringMockPVErr
}


+ 8
- 4
types/proposal.go View File

@ -5,6 +5,8 @@ import (
"fmt"
"time"
"github.com/gogo/protobuf/proto"
"github.com/tendermint/tendermint/libs/bytes"
tmproto "github.com/tendermint/tendermint/proto/types"
tmtime "github.com/tendermint/tendermint/types/time"
@ -71,6 +73,7 @@ func (p *Proposal) ValidateBasic() error {
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)
}
@ -88,9 +91,10 @@ func (p *Proposal) String() string {
CanonicalTime(p.Timestamp))
}
// SignBytes returns the Proposal bytes for signing
func (p *Proposal) SignBytes(chainID string) []byte {
bz, err := cdc.MarshalBinaryLengthPrefixed(CanonicalizeProposal(chainID, p))
// ProposalSignBytes returns the Proposal bytes for signing
func ProposalSignBytes(chainID string, p *tmproto.Proposal) []byte {
pb := CanonicalizeProposal(chainID, p)
bz, err := proto.Marshal(&pb)
if err != nil {
panic(err)
}
@ -100,7 +104,7 @@ func (p *Proposal) SignBytes(chainID string) []byte {
// ToProto converts Proposal to protobuf
func (p *Proposal) ToProto() *tmproto.Proposal {
if p == nil {
return nil
return &tmproto.Proposal{}
}
pb := new(tmproto.Proposal)


+ 33
- 17
types/proposal_test.go View File

@ -5,14 +5,19 @@ import (
"testing"
"time"
"github.com/gogo/protobuf/proto"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto/tmhash"
tmrand "github.com/tendermint/tendermint/libs/rand"
tmproto "github.com/tendermint/tendermint/proto/types"
)
var testProposal *Proposal
var (
testProposal *Proposal
pbp *tmproto.Proposal
)
func init() {
var stamp, err = time.Parse(TimeFormat, "2018-02-11T07:09:22.765Z")
@ -26,13 +31,14 @@ func init() {
POLRound: -1,
Timestamp: stamp,
}
pbp = testProposal.ToProto()
}
func TestProposalSignable(t *testing.T) {
chainID := "test_chain_id"
signBytes := testProposal.SignBytes(chainID)
expected, err := cdc.MarshalBinaryLengthPrefixed(CanonicalizeProposal(chainID, testProposal))
signBytes := ProposalSignBytes(chainID, pbp)
pb := CanonicalizeProposal(chainID, pbp)
expected, err := proto.Marshal(&pb)
require.NoError(t, err)
require.Equal(t, expected, signBytes, "Got unexpected sign bytes for Proposal")
}
@ -52,41 +58,49 @@ func TestProposalVerifySignature(t *testing.T) {
prop := NewProposal(
4, 2, 2,
BlockID{[]byte{1, 2, 3}, PartSetHeader{777, []byte("proper")}})
signBytes := prop.SignBytes("test_chain_id")
BlockID{tmrand.Bytes(tmhash.Size), PartSetHeader{777, tmrand.Bytes(tmhash.Size)}})
p := prop.ToProto()
signBytes := ProposalSignBytes("test_chain_id", p)
// sign it
err = privVal.SignProposal("test_chain_id", prop)
err = privVal.SignProposal("test_chain_id", p)
require.NoError(t, err)
prop.Signature = p.Signature
// verify the same proposal
valid := pubKey.VerifyBytes(signBytes, prop.Signature)
require.True(t, valid)
// serialize, deserialize and verify again....
newProp := new(Proposal)
bs, err := cdc.MarshalBinaryLengthPrefixed(prop)
newProp := new(tmproto.Proposal)
pb := prop.ToProto()
bs, err := proto.Marshal(pb)
require.NoError(t, err)
err = cdc.UnmarshalBinaryLengthPrefixed(bs, &newProp)
err = proto.Unmarshal(bs, newProp)
require.NoError(t, err)
np, err := ProposalFromProto(newProp)
require.NoError(t, err)
// verify the transmitted proposal
newSignBytes := newProp.SignBytes("test_chain_id")
newSignBytes := ProposalSignBytes("test_chain_id", pb)
require.Equal(t, string(signBytes), string(newSignBytes))
valid = pubKey.VerifyBytes(newSignBytes, newProp.Signature)
valid = pubKey.VerifyBytes(newSignBytes, np.Signature)
require.True(t, valid)
}
func BenchmarkProposalWriteSignBytes(b *testing.B) {
for i := 0; i < b.N; i++ {
testProposal.SignBytes("test_chain_id")
ProposalSignBytes("test_chain_id", pbp)
}
}
func BenchmarkProposalSign(b *testing.B) {
privVal := NewMockPV()
for i := 0; i < b.N; i++ {
err := privVal.SignProposal("test_chain_id", testProposal)
err := privVal.SignProposal("test_chain_id", pbp)
if err != nil {
b.Error(err)
}
@ -95,13 +109,13 @@ func BenchmarkProposalSign(b *testing.B) {
func BenchmarkProposalVerifySignature(b *testing.B) {
privVal := NewMockPV()
err := privVal.SignProposal("test_chain_id", testProposal)
err := privVal.SignProposal("test_chain_id", pbp)
require.NoError(b, err)
pubKey, err := privVal.GetPubKey()
require.NoError(b, err)
for i := 0; i < b.N; i++ {
pubKey.VerifyBytes(testProposal.SignBytes("test_chain_id"), testProposal.Signature)
pubKey.VerifyBytes(ProposalSignBytes("test_chain_id", pbp), testProposal.Signature)
}
}
@ -136,7 +150,9 @@ func TestProposalValidateBasic(t *testing.T) {
prop := NewProposal(
4, 2, 2,
blockID)
err := privVal.SignProposal("test_chain_id", prop)
p := prop.ToProto()
err := privVal.SignProposal("test_chain_id", p)
prop.Signature = p.Signature
require.NoError(t, err)
tc.malleateProposal(prop)
assert.Equal(t, tc.expectErr, prop.ValidateBasic() != nil, "Validate Basic had an unexpected result")


+ 9
- 2
types/test_util.go View File

@ -36,10 +36,12 @@ func MakeCommit(blockID BlockID, height int64, round int32,
}
func signAddVote(privVal PrivValidator, vote *Vote, voteSet *VoteSet) (signed bool, err error) {
err = privVal.SignVote(voteSet.ChainID(), vote)
v := vote.ToProto()
err = privVal.SignVote(voteSet.ChainID(), v)
if err != nil {
return false, err
}
vote.Signature = v.Signature
return voteSet.AddVote(vote)
}
@ -66,9 +68,14 @@ func MakeVote(
Type: tmproto.PrecommitType,
BlockID: blockID,
}
if err := privVal.SignVote(chainID, vote); err != nil {
v := vote.ToProto()
if err := privVal.SignVote(chainID, v); err != nil {
return nil, err
}
vote.Signature = v.Signature
return vote, nil
}


+ 3
- 1
types/validator_set_test.go View File

@ -667,7 +667,9 @@ func TestValidatorSetVerifyCommit(t *testing.T) {
Type: tmproto.PrecommitType,
BlockID: blockID,
}
sig, err := privKey.Sign(vote.SignBytes(chainID))
v := vote.ToProto()
sig, err := privKey.Sign(VoteSignBytes(chainID, v))
assert.NoError(t, err)
vote.Signature = sig
commit := NewCommit(vote.Height, vote.Round, blockID, []CommitSig{vote.CommitSig()})


+ 14
- 5
types/vote.go View File

@ -6,6 +6,8 @@ import (
"fmt"
"time"
"github.com/gogo/protobuf/proto"
"github.com/tendermint/tendermint/crypto"
tmbytes "github.com/tendermint/tendermint/libs/bytes"
tmproto "github.com/tendermint/tendermint/proto/types"
@ -13,7 +15,7 @@ import (
const (
// MaxVoteBytes is a maximum vote size (including amino overhead).
MaxVoteBytes int64 = 211
MaxVoteBytes int64 = 209
nilVoteStr string = "nil-Vote"
)
@ -81,8 +83,11 @@ func (vote *Vote) CommitSig() CommitSig {
}
}
func (vote *Vote) SignBytes(chainID string) []byte {
bz, err := cdc.MarshalBinaryLengthPrefixed(CanonicalizeVote(chainID, vote))
//VoteSignBytes take the chainID & a vote, represented in protobuf, and creates a signature.
// If any error arises this will panic
func VoteSignBytes(chainID string, vote *tmproto.Vote) []byte {
pb := CanonicalizeVote(chainID, vote)
bz, err := proto.Marshal(&pb)
if err != nil {
panic(err)
}
@ -126,8 +131,8 @@ func (vote *Vote) Verify(chainID string, pubKey crypto.PubKey) error {
if !bytes.Equal(pubKey.Address(), vote.ValidatorAddress) {
return ErrVoteInvalidValidatorAddress
}
if !pubKey.VerifyBytes(vote.SignBytes(chainID), vote.Signature) {
v := vote.ToProto()
if !pubKey.VerifyBytes(VoteSignBytes(chainID, v), vote.Signature) {
return ErrVoteInvalidSignature
}
return nil
@ -152,11 +157,13 @@ func (vote *Vote) ValidateBasic() error {
if err := vote.BlockID.ValidateBasic(); err != nil {
return fmt.Errorf("wrong BlockID: %v", err)
}
// BlockID.ValidateBasic would not err if we for instance have an empty hash but a
// non-empty PartsSetHeader:
if !vote.BlockID.IsZero() && !vote.BlockID.IsComplete() {
return fmt.Errorf("blockID must be either empty or complete, got: %v", vote.BlockID)
}
if len(vote.ValidatorAddress) != crypto.AddressSize {
return fmt.Errorf("expected ValidatorAddress size to be %d bytes, got %d bytes",
crypto.AddressSize,
@ -169,9 +176,11 @@ func (vote *Vote) ValidateBasic() error {
if len(vote.Signature) == 0 {
return errors.New("signature is missing")
}
if len(vote.Signature) > MaxSignatureSize {
return fmt.Errorf("signature is too big (max: %d)", MaxSignatureSize)
}
return nil
}


+ 40
- 63
types/vote_test.go View File

@ -5,6 +5,7 @@ import (
"testing"
"time"
"github.com/gogo/protobuf/proto"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -47,9 +48,11 @@ func exampleVote(t byte) *Vote {
func TestVoteSignable(t *testing.T) {
vote := examplePrecommit()
signBytes := vote.SignBytes("test_chain_id")
v := vote.ToProto()
signBytes := VoteSignBytes("test_chain_id", v)
pb := CanonicalizeVote("test_chain_id", v)
expected, err := cdc.MarshalBinaryLengthPrefixed(CanonicalizeVote("test_chain_id", vote))
expected, err := proto.Marshal(&pb)
require.NoError(t, err)
require.Equal(t, expected, signBytes, "Got unexpected sign bytes for Vote.")
@ -65,79 +68,47 @@ func TestVoteSignBytesTestVectors(t *testing.T) {
0: {
"", &Vote{},
// NOTE: Height and Round are skipped here. This case needs to be considered while parsing.
[]byte{0xd, 0x2a, 0xb, 0x8, 0x80, 0x92, 0xb8, 0xc3, 0x98, 0xfe, 0xff, 0xff, 0xff, 0x1},
[]byte{0x2a, 0x2, 0x12, 0x0, 0x32, 0xb, 0x8, 0x80, 0x92, 0xb8,
0xc3, 0x98, 0xfe, 0xff, 0xff, 0xff, 0x1},
},
// with proper (fixed size) height and round (PreCommit):
1: {
"", &Vote{Height: 1, Round: 1, Type: tmproto.PrecommitType},
[]byte{
0x21, // length
0x8, // (field_number << 3) | wire_type
0x2, // PrecommitType
0x11, // (field_number << 3) | wire_type
0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // height
0x19, // (field_number << 3) | wire_type
0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // round
0x2a, // (field_number << 3) | wire_type
// remaining fields (timestamp):
[]byte{0x8, 0x2, 0x10, 0x1, 0x18, 0x1, 0x2a, 0x2, 0x12, 0x0, 0x32,
0xb, 0x8, 0x80, 0x92, 0xb8, 0xc3, 0x98, 0xfe, 0xff, 0xff, 0xff, 0x1},
},
// with proper (fixed size) height and round (PreVote):
2: {
"", &Vote{Height: 1, Round: 1, Type: tmproto.PrevoteType},
[]byte{
0x21, // length
0x8, // (field_number << 3) | wire_type
0x1, // PrevoteType
0x11, // (field_number << 3) | wire_type
0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // height
0x19, // (field_number << 3) | wire_type
0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // round
0x2a, // (field_number << 3) | wire_type
// remaining fields (timestamp):
0xb, 0x8, 0x80, 0x92, 0xb8, 0xc3, 0x98, 0xfe, 0xff, 0xff, 0xff, 0x1},
[]byte{0x8, 0x1, 0x10, 0x1, 0x18, 0x1, 0x2a, 0x2, 0x12, 0x0,
0x32, 0xb, 0x8, 0x80, 0x92, 0xb8, 0xc3, 0x98, 0xfe, 0xff, 0xff, 0xff, 0x1},
},
3: {
"", &Vote{Height: 1, Round: 1},
[]byte{
0x1f, // length
0x11, // (field_number << 3) | wire_type
0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // height
0x19, // (field_number << 3) | wire_type
0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // round
// remaining fields (timestamp):
0x2a,
0xb, 0x8, 0x80, 0x92, 0xb8, 0xc3, 0x98, 0xfe, 0xff, 0xff, 0xff, 0x1},
[]byte{0x10, 0x1, 0x18, 0x1, 0x2a, 0x2, 0x12, 0x0, 0x32, 0xb,
0x8, 0x80, 0x92, 0xb8, 0xc3, 0x98, 0xfe, 0xff, 0xff, 0xff, 0x1},
},
// containing non-empty chain_id:
4: {
"test_chain_id", &Vote{Height: 1, Round: 1},
[]byte{
0x2e, // length
0x11, // (field_number << 3) | wire_type
0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // height
0x19, // (field_number << 3) | wire_type
0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // round
// remaining fields:
0x2a, // (field_number << 3) | wire_type
0xb, 0x8, 0x80, 0x92, 0xb8, 0xc3, 0x98, 0xfe, 0xff, 0xff, 0xff, 0x1, // timestamp
// (field_number << 3) | wire_type
0x32,
0xd, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64}, // chainID
[]byte{0x10, 0x1, 0x18, 0x1, 0x2a, 0x2, 0x12, 0x0, 0x32, 0xb, 0x8,
0x80, 0x92, 0xb8, 0xc3, 0x98, 0xfe, 0xff, 0xff, 0xff, 0x1, 0x3a, 0xd,
0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64},
},
}
for i, tc := range tests {
got := tc.vote.SignBytes(tc.chainID)
v := tc.vote.ToProto()
got := VoteSignBytes(tc.chainID, v)
require.Equal(t, tc.want, got, "test case #%v: got unexpected sign bytes for Vote.", i)
}
}
func TestVoteProposalNotEq(t *testing.T) {
cv := CanonicalizeVote("", &Vote{Height: 1, Round: 1})
p := CanonicalizeProposal("", &Proposal{Height: 1, Round: 1})
vb, err := cdc.MarshalBinaryLengthPrefixed(cv)
cv := CanonicalizeVote("", &tmproto.Vote{Height: 1, Round: 1})
p := CanonicalizeProposal("", &tmproto.Proposal{Height: 1, Round: 1})
vb, err := proto.Marshal(&cv)
require.NoError(t, err)
pb, err := cdc.MarshalBinaryLengthPrefixed(p)
pb, err := proto.Marshal(&p)
require.NoError(t, err)
require.NotEqual(t, vb, pb)
}
@ -148,25 +119,26 @@ func TestVoteVerifySignature(t *testing.T) {
require.NoError(t, err)
vote := examplePrecommit()
signBytes := vote.SignBytes("test_chain_id")
v := vote.ToProto()
signBytes := VoteSignBytes("test_chain_id", v)
// sign it
err = privVal.SignVote("test_chain_id", vote)
err = privVal.SignVote("test_chain_id", v)
require.NoError(t, err)
// verify the same vote
valid := pubkey.VerifyBytes(vote.SignBytes("test_chain_id"), vote.Signature)
valid := pubkey.VerifyBytes(VoteSignBytes("test_chain_id", v), v.Signature)
require.True(t, valid)
// serialize, deserialize and verify again....
precommit := new(Vote)
bs, err := cdc.MarshalBinaryLengthPrefixed(vote)
precommit := new(tmproto.Vote)
bs, err := proto.Marshal(v)
require.NoError(t, err)
err = cdc.UnmarshalBinaryLengthPrefixed(bs, &precommit)
err = proto.Unmarshal(bs, precommit)
require.NoError(t, err)
// verify the transmitted vote
newSignBytes := precommit.SignBytes("test_chain_id")
newSignBytes := VoteSignBytes("test_chain_id", precommit)
require.Equal(t, string(signBytes), string(newSignBytes))
valid = pubkey.VerifyBytes(newSignBytes, precommit.Signature)
require.True(t, valid)
@ -233,11 +205,12 @@ func TestMaxVoteBytes(t *testing.T) {
},
}
v := vote.ToProto()
privVal := NewMockPV()
err := privVal.SignVote("test_chain_id", vote)
err := privVal.SignVote("test_chain_id", v)
require.NoError(t, err)
bz, err := cdc.MarshalBinaryLengthPrefixed(vote)
bz, err := proto.Marshal(v)
require.NoError(t, err)
assert.EqualValues(t, MaxVoteBytes, len(bz))
@ -245,13 +218,13 @@ func TestMaxVoteBytes(t *testing.T) {
func TestVoteString(t *testing.T) {
str := examplePrecommit().String()
expected := `Vote{56789:6AF1F4111082 12345/02/2(Precommit) 8B01023386C3 000000000000 @ 2017-12-25T03:00:01.234Z}`
expected := `Vote{56789:6AF1F4111082 12345/02/PRECOMMIT_TYPE(Precommit) 8B01023386C3 000000000000 @ 2017-12-25T03:00:01.234Z}` //nolint:lll //ignore line length for tests
if str != expected {
t.Errorf("got unexpected string for Vote. Expected:\n%v\nGot:\n%v", expected, str)
}
str2 := examplePrevote().String()
expected = `Vote{56789:6AF1F4111082 12345/02/1(Prevote) 8B01023386C3 000000000000 @ 2017-12-25T03:00:01.234Z}`
expected = `Vote{56789:6AF1F4111082 12345/02/PREVOTE_TYPE(Prevote) 8B01023386C3 000000000000 @ 2017-12-25T03:00:01.234Z}` //nolint:lll //ignore line length for tests
if str2 != expected {
t.Errorf("got unexpected string for Vote. Expected:\n%v\nGot:\n%v", expected, str2)
}
@ -280,7 +253,9 @@ func TestVoteValidateBasic(t *testing.T) {
tc := tc
t.Run(tc.testName, func(t *testing.T) {
vote := examplePrecommit()
err := privVal.SignVote("test_chain_id", vote)
v := vote.ToProto()
err := privVal.SignVote("test_chain_id", v)
vote.Signature = v.Signature
require.NoError(t, err)
tc.malleateVote(vote)
assert.Equal(t, tc.expectErr, vote.ValidateBasic() != nil, "Validate Basic had an unexpected result")
@ -291,7 +266,9 @@ func TestVoteValidateBasic(t *testing.T) {
func TestVoteProtobuf(t *testing.T) {
privVal := NewMockPV()
vote := examplePrecommit()
err := privVal.SignVote("test_chain_id", vote)
v := vote.ToProto()
err := privVal.SignVote("test_chain_id", v)
vote.Signature = v.Signature
require.NoError(t, err)
testCases := []struct {


Loading…
Cancel
Save