Merge remote-tracking branch 'origin' into jasmina/4457-blocksync-verification_part1

This commit is contained in:
Jasmina Malicevic
2022-04-29 12:46:25 +02:00
51 changed files with 641 additions and 436 deletions
+1
View File
@@ -47,6 +47,7 @@ Special thanks to external contributors on this release:
- [libs/service] \#7288 Remove SetLogger method on `service.Service` interface. (@tychoish)
- [abci/client] \#7607 Simplify client interface (removes most "async" methods). (@creachadair)
- [libs/json] \#7673 Remove the libs/json (tmjson) library. (@creachadair)
- [crypto] \#8412 \#8432 Remove `crypto/tmhash` package in favor of small functions in `crypto` package and cleanup of unused functions. (@tychoish)
- Blockchain Protocol
+27 -4
View File
@@ -145,6 +145,27 @@ subcommands: `blockchain`, `peers`, `unsafe-signer` and `unsafe-all`.
- `tendermint reset unsafe-all`: A summation of the other three commands. This will delete
the entire `data` directory which may include application data as well.
### Go API Changes
#### `crypto` Package Cleanup
The `github.com/tendermint/tendermint/crypto/tmhash` package was removed
to improve clarity. Users are encouraged to use the standard library
`crypto/sha256` package directly. However, as a convenience, some constants
and one function have moved to the Tendermint `crypto` package:
- The `crypto.Checksum` function returns the sha256 checksum of a
byteslice. This is a wrapper around `sha256.Sum265` from the
standard libary, but provided as a function to ease type
requirements (the library function returns a `[32]byte` rather than
a `[]byte`).
- `tmhash.TruncatedSize` is now `crypto.AddressSize` which was
previously an alias for the same value.
- `tmhash.Size` and `tmhash.BlockSize` are now `crypto.HashSize` and
`crypto.HashSize`.
- `tmhash.SumTruncated` is now available via `crypto.AddressHash` or by
`crypto.Checksum(<...>)[:crypto.AddressSize]`
## v0.35
### ABCI Changes
@@ -259,11 +280,13 @@ the full RPC interface provided as direct function calls. Import the
the node service as in the following:
```go
node := node.NewDefault() //construct the node object
// start and set up the node service
logger := log.NewNopLogger()
client := local.New(node.(local.NodeService))
// use client object to interact with the node
// Construct and start up a node with default settings.
node := node.NewDefault(logger)
// Construct a local (in-memory) RPC client to the node.
client := local.New(logger, node.(local.NodeService))
```
### gRPC Support
+18 -3
View File
@@ -1,14 +1,18 @@
package crypto
import (
"github.com/tendermint/tendermint/crypto/tmhash"
"crypto/sha256"
"github.com/tendermint/tendermint/internal/jsontypes"
"github.com/tendermint/tendermint/libs/bytes"
)
const (
// HashSize is the size in bytes of an AddressHash.
HashSize = sha256.Size
// AddressSize is the size of a pubkey address.
AddressSize = tmhash.TruncatedSize
AddressSize = 20
)
// An address is a []byte, but hex-encoded even in JSON.
@@ -16,8 +20,19 @@ const (
// Use an alias so Unmarshal methods (with ptr receivers) are available too.
type Address = bytes.HexBytes
// AddressHash computes a truncated SHA-256 hash of bz for use as
// a peer address.
//
// See: https://docs.tendermint.com/master/spec/core/data_structures.html#address
func AddressHash(bz []byte) Address {
return Address(tmhash.SumTruncated(bz))
h := sha256.Sum256(bz)
return Address(h[:AddressSize])
}
// Checksum returns the SHA256 of the bz.
func Checksum(bz []byte) []byte {
h := sha256.Sum256(bz)
return h[:]
}
type PubKey interface {
+1 -2
View File
@@ -13,7 +13,6 @@ import (
"github.com/oasisprotocol/curve25519-voi/primitives/ed25519/extra/cache"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/internal/jsontypes"
)
@@ -163,7 +162,7 @@ func (pubKey PubKey) Address() crypto.Address {
if len(pubKey) != PubKeySize {
panic("pubkey is incorrect size")
}
return crypto.Address(tmhash.SumTruncated(pubKey))
return crypto.AddressHash(pubKey)
}
// Bytes returns the PubKey byte format.
+4 -4
View File
@@ -3,7 +3,7 @@ package merkle
import (
"hash"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/crypto"
)
// TODO: make these have a large predefined capacity
@@ -14,12 +14,12 @@ var (
// returns tmhash(<empty>)
func emptyHash() []byte {
return tmhash.Sum([]byte{})
return crypto.Checksum([]byte{})
}
// returns tmhash(0x00 || leaf)
func leafHash(leaf []byte) []byte {
return tmhash.Sum(append(leafPrefix, leaf...))
return crypto.Checksum(append(leafPrefix, leaf...))
}
// returns tmhash(0x00 || leaf)
@@ -36,7 +36,7 @@ func innerHash(left []byte, right []byte) []byte {
n := copy(data, innerPrefix)
n += copy(data[n:], left)
copy(data[n:], right)
return tmhash.Sum(data)
return crypto.Checksum(data)[:]
}
func innerHashOpt(s hash.Hash, left []byte, right []byte) []byte {
+5 -5
View File
@@ -5,7 +5,7 @@ import (
"errors"
"fmt"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/crypto"
tmcrypto "github.com/tendermint/tendermint/proto/tendermint/crypto"
)
@@ -102,15 +102,15 @@ func (sp *Proof) ValidateBasic() error {
if sp.Index < 0 {
return errors.New("negative Index")
}
if len(sp.LeafHash) != tmhash.Size {
return fmt.Errorf("expected LeafHash size to be %d, got %d", tmhash.Size, len(sp.LeafHash))
if len(sp.LeafHash) != crypto.HashSize {
return fmt.Errorf("expected LeafHash size to be %d, got %d", crypto.HashSize, len(sp.LeafHash))
}
if len(sp.Aunts) > MaxAunts {
return fmt.Errorf("expected no more than %d aunts, got %d", MaxAunts, len(sp.Aunts))
}
for i, auntHash := range sp.Aunts {
if len(auntHash) != tmhash.Size {
return fmt.Errorf("expected Aunts#%d size to be %d, got %d", i, tmhash.Size, len(auntHash))
if len(auntHash) != crypto.HashSize {
return fmt.Errorf("expected Aunts#%d size to be %d, got %d", i, crypto.HashSize, len(auntHash))
}
}
return nil
+5 -5
View File
@@ -20,7 +20,7 @@ import (
"encoding/hex"
"testing"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/crypto"
)
func TestRFC6962Hasher(t *testing.T) {
@@ -39,7 +39,7 @@ func TestRFC6962Hasher(t *testing.T) {
// echo -n '' | sha256sum
{
desc: "RFC6962 Empty Tree",
want: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"[:tmhash.Size*2],
want: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"[:crypto.HashSize*2],
got: emptyTreeHash,
},
@@ -47,19 +47,19 @@ func TestRFC6962Hasher(t *testing.T) {
// echo -n 00 | xxd -r -p | sha256sum
{
desc: "RFC6962 Empty Leaf",
want: "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d"[:tmhash.Size*2],
want: "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d"[:crypto.HashSize*2],
got: emptyLeafHash,
},
// echo -n 004C313233343536 | xxd -r -p | sha256sum
{
desc: "RFC6962 Leaf",
want: "395aa064aa4c29f7010acfe3f25db9485bbd4b91897b6ad7ad547639252b4d56"[:tmhash.Size*2],
want: "395aa064aa4c29f7010acfe3f25db9485bbd4b91897b6ad7ad547639252b4d56"[:crypto.HashSize*2],
got: leafHash,
},
// echo -n 014E3132334E343536 | xxd -r -p | sha256sum
{
desc: "RFC6962 Node",
want: "aa217fe888e47007fa15edab33c2b492a722cb106c64667fc2b044444de66bbb"[:tmhash.Size*2],
want: "aa217fe888e47007fa15edab33c2b492a722cb106c64667fc2b044444de66bbb"[:crypto.HashSize*2],
got: innerHash([]byte("N123"), []byte("N456")),
},
} {
+4 -4
View File
@@ -7,7 +7,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/crypto"
ctest "github.com/tendermint/tendermint/internal/libs/test"
tmrand "github.com/tendermint/tendermint/libs/rand"
)
@@ -53,7 +53,7 @@ func TestProof(t *testing.T) {
items := make([][]byte, total)
for i := 0; i < total; i++ {
items[i] = testItem(tmrand.Bytes(tmhash.Size))
items[i] = testItem(tmrand.Bytes(crypto.HashSize))
}
rootHash = HashFromByteSlices(items)
@@ -106,7 +106,7 @@ func TestHashAlternatives(t *testing.T) {
items := make([][]byte, total)
for i := 0; i < total; i++ {
items[i] = testItem(tmrand.Bytes(tmhash.Size))
items[i] = testItem(tmrand.Bytes(crypto.HashSize))
}
rootHash1 := HashFromByteSlicesIterative(items)
@@ -119,7 +119,7 @@ func BenchmarkHashAlternatives(b *testing.B) {
items := make([][]byte, total)
for i := 0; i < total; i++ {
items[i] = testItem(tmrand.Bytes(tmhash.Size))
items[i] = testItem(tmrand.Bytes(crypto.HashSize))
}
b.ResetTimer()
+1 -2
View File
@@ -7,7 +7,6 @@ import (
"github.com/oasisprotocol/curve25519-voi/primitives/sr25519"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/tmhash"
)
var _ crypto.PubKey = PubKey{}
@@ -31,7 +30,7 @@ func (pubKey PubKey) Address() crypto.Address {
if len(pubKey) != PubKeySize {
panic("pubkey is incorrect size")
}
return crypto.Address(tmhash.SumTruncated(pubKey))
return crypto.AddressHash(pubKey)
}
// Bytes returns the PubKey byte format.
-25
View File
@@ -1,25 +0,0 @@
package tmhash
import (
"crypto/sha256"
)
const (
Size = sha256.Size
BlockSize = sha256.BlockSize
TruncatedSize = 20
)
// Sum returns the SHA256 of the bz.
func Sum(bz []byte) []byte {
h := sha256.Sum256(bz)
return h[:]
}
//-------------------------------------------------------------
// SumTruncated returns the first 20 bytes of SHA256 of the bz.
func SumTruncated(bz []byte) []byte {
hash := sha256.Sum256(bz)
return hash[:TruncatedSize]
}
+5 -1
View File
@@ -159,7 +159,11 @@ func signVote(
chainID string,
blockID types.BlockID) *types.Vote {
v, err := vs.signVote(ctx, voteType, chainID, blockID, []byte("extension"))
var ext []byte
if voteType == tmproto.PrecommitType {
ext = []byte("extension")
}
v, err := vs.signVote(ctx, voteType, chainID, blockID, ext)
require.NoError(t, err, "failed to sign vote")
vs.lastVote = v
+8 -2
View File
@@ -220,9 +220,13 @@ type VoteMessage struct {
func (*VoteMessage) TypeTag() string { return "tendermint/Vote" }
// ValidateBasic performs basic validation.
// ValidateBasic checks whether the vote within the message is well-formed.
func (m *VoteMessage) ValidateBasic() error {
return m.Vote.ValidateBasic()
// Here we validate votes with vote extensions, since we require vote
// extensions to be sent in precommit messages during consensus. Prevote
// messages should never have vote extensions, and this is also validated
// here.
return m.Vote.ValidateWithExtension()
}
// String returns a string representation.
@@ -534,6 +538,8 @@ func MsgFromProto(msg *tmcons.Message) (Message, error) {
Part: parts,
}
case *tmcons.Message_Vote:
// Vote validation will be handled in the vote message ValidateBasic
// call below.
vote, err := types.VoteFromProto(msg.Vote.Vote)
if err != nil {
return nil, fmt.Errorf("vote msg to proto error: %w", err)
+2 -2
View File
@@ -12,8 +12,8 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/merkle"
"github.com/tendermint/tendermint/crypto/tmhash"
cstypes "github.com/tendermint/tendermint/internal/consensus/types"
"github.com/tendermint/tendermint/internal/test/factory"
"github.com/tendermint/tendermint/libs/bits"
@@ -667,7 +667,7 @@ func TestProposalPOLMessageValidateBasic(t *testing.T) {
func TestBlockPartMessageValidateBasic(t *testing.T) {
testPart := new(types.Part)
testPart.Proof.LeafHash = tmhash.Sum([]byte("leaf"))
testPart.Proof.LeafHash = crypto.Checksum([]byte("leaf"))
testCases := []struct {
testName string
messageHeight int64
+3 -3
View File
@@ -13,7 +13,7 @@ import (
"github.com/tendermint/tendermint/abci/example/kvstore"
abci "github.com/tendermint/tendermint/abci/types"
abcimocks "github.com/tendermint/tendermint/abci/types/mocks"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/crypto"
cstypes "github.com/tendermint/tendermint/internal/consensus/types"
"github.com/tendermint/tendermint/internal/eventbus"
tmpubsub "github.com/tendermint/tendermint/internal/pubsub"
@@ -2769,7 +2769,7 @@ func TestStateOutputVoteStats(t *testing.T) {
peerID, err := types.NewNodeID("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
require.NoError(t, err)
randBytes := tmrand.Bytes(tmhash.Size)
randBytes := tmrand.Bytes(crypto.HashSize)
blockID := types.BlockID{
Hash: randBytes,
}
@@ -2807,7 +2807,7 @@ func TestSignSameVoteTwice(t *testing.T) {
_, vss := makeState(ctx, t, makeStateArgs{config: config, validators: 2})
randBytes := tmrand.Bytes(tmhash.Size)
randBytes := tmrand.Bytes(crypto.HashSize)
vote := signVote(
ctx,
@@ -7,7 +7,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/internal/test/factory"
tmrand "github.com/tendermint/tendermint/libs/rand"
tmtime "github.com/tendermint/tendermint/libs/time"
@@ -71,7 +71,7 @@ func makeVoteHR(
pubKey, err := privVal.GetPubKey(ctx)
require.NoError(t, err)
randBytes := tmrand.Bytes(tmhash.Size)
randBytes := tmrand.Bytes(crypto.HashSize)
vote := &types.Vote{
ValidatorAddress: pubKey.Address(),
+2 -3
View File
@@ -16,7 +16,6 @@ import (
dbm "github.com/tendermint/tm-db"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/internal/eventbus"
"github.com/tendermint/tendermint/internal/evidence"
"github.com/tendermint/tendermint/internal/evidence/mocks"
@@ -523,10 +522,10 @@ func TestEvidenceListSerialization(t *testing.T) {
Round: 2,
Timestamp: stamp,
BlockID: types.BlockID{
Hash: tmhash.Sum([]byte("blockID_hash")),
Hash: crypto.Checksum([]byte("blockID_hash")),
PartSetHeader: types.PartSetHeader{
Total: 1000000,
Hash: tmhash.Sum([]byte("blockID_part_set_header_hash")),
Hash: crypto.Checksum([]byte("blockID_part_set_header_hash")),
},
},
ValidatorAddress: crypto.AddressHash([]byte("validator_address")),
+3 -4
View File
@@ -11,7 +11,6 @@ import (
dbm "github.com/tendermint/tm-db"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/internal/eventbus"
"github.com/tendermint/tendermint/internal/evidence"
"github.com/tendermint/tendermint/internal/evidence/mocks"
@@ -273,7 +272,7 @@ func TestVerifyLightClientAttack_Equivocation(t *testing.T) {
// conflicting header has different next validators hash which should have been correctly derived from
// the previous round
ev.ConflictingBlock.Header.NextValidatorsHash = crypto.CRandBytes(tmhash.Size)
ev.ConflictingBlock.Header.NextValidatorsHash = crypto.CRandBytes(crypto.HashSize)
assert.Error(t, evidence.VerifyLightClientAttack(ev, trustedSignedHeader, trustedSignedHeader, nil,
defaultEvidenceTime.Add(1*time.Minute), 2*time.Hour))
@@ -618,8 +617,8 @@ func makeVote(
func makeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) types.BlockID {
var (
h = make([]byte, tmhash.Size)
psH = make([]byte, tmhash.Size)
h = make([]byte, crypto.HashSize)
psH = make([]byte, crypto.HashSize)
)
copy(h, hash)
copy(psH, partSetHash)
+2 -3
View File
@@ -8,7 +8,6 @@ import (
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/internal/libs/protoio"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/tendermint/tendermint/types"
@@ -25,10 +24,10 @@ func aVote(t testing.TB) *types.Vote {
Round: 2,
Timestamp: stamp,
BlockID: types.BlockID{
Hash: tmhash.Sum([]byte("blockID_hash")),
Hash: crypto.Checksum([]byte("blockID_hash")),
PartSetHeader: types.PartSetHeader{
Total: 1000000,
Hash: tmhash.Sum([]byte("blockID_part_set_header_hash")),
Hash: crypto.Checksum([]byte("blockID_part_set_header_hash")),
},
},
ValidatorAddress: crypto.AddressHash([]byte("validator_address")),
+8 -9
View File
@@ -18,7 +18,6 @@ import (
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/crypto/encoding"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/internal/eventbus"
mpmocks "github.com/tendermint/tendermint/internal/mempool/mocks"
"github.com/tendermint/tendermint/internal/proxy"
@@ -180,14 +179,14 @@ func TestFinalizeBlockByzantineValidators(t *testing.T) {
Height: 10,
Time: defaultEvidenceTime,
LastBlockID: blockID,
LastCommitHash: crypto.CRandBytes(tmhash.Size),
DataHash: crypto.CRandBytes(tmhash.Size),
LastCommitHash: crypto.CRandBytes(crypto.HashSize),
DataHash: crypto.CRandBytes(crypto.HashSize),
ValidatorsHash: state.Validators.Hash(),
NextValidatorsHash: state.Validators.Hash(),
ConsensusHash: crypto.CRandBytes(tmhash.Size),
AppHash: crypto.CRandBytes(tmhash.Size),
LastResultsHash: crypto.CRandBytes(tmhash.Size),
EvidenceHash: crypto.CRandBytes(tmhash.Size),
ConsensusHash: crypto.CRandBytes(crypto.HashSize),
AppHash: crypto.CRandBytes(crypto.HashSize),
LastResultsHash: crypto.CRandBytes(crypto.HashSize),
EvidenceHash: crypto.CRandBytes(crypto.HashSize),
ProposerAddress: crypto.CRandBytes(crypto.AddressSize),
}
@@ -1003,8 +1002,8 @@ func TestPrepareProposalErrorOnPrepareProposalError(t *testing.T) {
func makeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) types.BlockID {
var (
h = make([]byte, tmhash.Size)
psH = make([]byte, tmhash.Size)
h = make([]byte, crypto.HashSize)
psH = make([]byte, crypto.HashSize)
)
copy(h, hash)
copy(psH, partSetHash)
+2 -2
View File
@@ -12,8 +12,8 @@ import (
abciclient "github.com/tendermint/tendermint/abci/client"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/internal/eventbus"
mpmocks "github.com/tendermint/tendermint/internal/mempool/mocks"
"github.com/tendermint/tendermint/internal/proxy"
@@ -68,7 +68,7 @@ func TestValidateBlockHeader(t *testing.T) {
lastCommit := types.NewCommit(0, 0, types.BlockID{}, nil)
// some bad values
wrongHash := tmhash.Sum([]byte("this hash is wrong"))
wrongHash := crypto.Checksum([]byte("this hash is wrong"))
wrongVersion1 := state.Version.Consensus
wrongVersion1.Block += 2
wrongVersion2 := state.Version.Consensus
+1 -2
View File
@@ -7,7 +7,6 @@ import (
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/types"
"github.com/tendermint/tendermint/version"
)
@@ -25,7 +24,7 @@ func RandomAddress() []byte {
}
func RandomHash() []byte {
return crypto.CRandBytes(tmhash.Size)
return crypto.CRandBytes(crypto.HashSize)
}
func MakeBlockID() types.BlockID {
+1
View File
@@ -40,5 +40,6 @@ func MakeVote(
}
v.Signature = vpb.Signature
v.ExtensionSignature = vpb.ExtensionSignature
return v, nil
}
+1 -2
View File
@@ -9,7 +9,6 @@ import (
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/crypto/tmhash"
tmtime "github.com/tendermint/tendermint/libs/time"
provider_mocks "github.com/tendermint/tendermint/light/provider/mocks"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
@@ -222,5 +221,5 @@ func mockNodeFromHeadersAndVals(headers map[int64]*types.SignedHeader,
}
func hash(s string) []byte {
return tmhash.Sum([]byte(s))
return crypto.Checksum([]byte(s))
}
+8 -9
View File
@@ -11,7 +11,6 @@ import (
dbm "github.com/tendermint/tm-db"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/internal/test/factory"
tmrand "github.com/tendermint/tendermint/libs/rand"
"github.com/tendermint/tendermint/types"
@@ -205,14 +204,14 @@ func randLightBlock(ctx context.Context, t *testing.T, height int64) *types.Ligh
Height: height,
Time: time.Now(),
LastBlockID: types.BlockID{},
LastCommitHash: crypto.CRandBytes(tmhash.Size),
DataHash: crypto.CRandBytes(tmhash.Size),
ValidatorsHash: crypto.CRandBytes(tmhash.Size),
NextValidatorsHash: crypto.CRandBytes(tmhash.Size),
ConsensusHash: crypto.CRandBytes(tmhash.Size),
AppHash: crypto.CRandBytes(tmhash.Size),
LastResultsHash: crypto.CRandBytes(tmhash.Size),
EvidenceHash: crypto.CRandBytes(tmhash.Size),
LastCommitHash: crypto.CRandBytes(crypto.HashSize),
DataHash: crypto.CRandBytes(crypto.HashSize),
ValidatorsHash: crypto.CRandBytes(crypto.HashSize),
NextValidatorsHash: crypto.CRandBytes(crypto.HashSize),
ConsensusHash: crypto.CRandBytes(crypto.HashSize),
AppHash: crypto.CRandBytes(crypto.HashSize),
LastResultsHash: crypto.CRandBytes(crypto.HashSize),
EvidenceHash: crypto.CRandBytes(crypto.HashSize),
ProposerAddress: crypto.CRandBytes(crypto.AddressSize),
},
Commit: &types.Commit{},
+3 -3
View File
@@ -5,7 +5,7 @@ import (
"fmt"
"time"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/crypto"
)
// TrustOptions are the trust parameters needed when a new light client
@@ -43,9 +43,9 @@ func (opts TrustOptions) ValidateBasic() error {
if opts.Height <= 0 {
return errors.New("negative or zero height")
}
if len(opts.Hash) != tmhash.Size {
if len(opts.Hash) != crypto.HashSize {
return fmt.Errorf("expected hash size to be %d bytes, got %d bytes",
tmhash.Size,
crypto.HashSize,
len(opts.Hash),
)
}
+4 -5
View File
@@ -20,7 +20,6 @@ import (
"github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/internal/eventbus"
"github.com/tendermint/tendermint/internal/evidence"
"github.com/tendermint/tendermint/internal/mempool"
@@ -498,10 +497,10 @@ func TestMaxProposalBlockSize(t *testing.T) {
)
blockID := types.BlockID{
Hash: tmhash.Sum([]byte("blockID_hash")),
Hash: crypto.Checksum([]byte("blockID_hash")),
PartSetHeader: types.PartSetHeader{
Total: math.MaxInt32,
Hash: tmhash.Sum([]byte("blockID_part_set_header_hash")),
Hash: crypto.Checksum([]byte("blockID_part_set_header_hash")),
},
}
@@ -516,8 +515,8 @@ func TestMaxProposalBlockSize(t *testing.T) {
state.LastBlockID = blockID
state.LastBlockHeight = math.MaxInt64 - 2
state.LastBlockTime = timestamp
state.LastResultsHash = tmhash.Sum([]byte("last_results_hash"))
state.AppHash = tmhash.Sum([]byte("app_hash"))
state.LastResultsHash = crypto.Checksum([]byte("last_results_hash"))
state.AppHash = crypto.Checksum([]byte("app_hash"))
state.Version.Consensus.Block = math.MaxInt64
state.Version.Consensus.App = math.MaxInt64
maxChainID := ""
+14 -8
View File
@@ -372,11 +372,20 @@ func (pv *FilePV) signVote(chainID string, vote *tmproto.Vote) error {
}
signBytes := types.VoteSignBytes(chainID, vote)
extSignBytes := types.VoteExtensionSignBytes(chainID, vote)
// We always sign the vote extension. See below for details.
extSig, err := pv.Key.PrivKey.Sign(extSignBytes)
if err != nil {
return err
// Vote extensions are non-deterministic, so it is possible that an
// application may have created a different extension. We therefore always
// re-sign the vote extensions of precommits. For prevotes, the extension
// signature will always be empty.
var extSig []byte
if vote.Type == tmproto.PrecommitType {
extSignBytes := types.VoteExtensionSignBytes(chainID, vote)
extSig, err = pv.Key.PrivKey.Sign(extSignBytes)
if err != nil {
return err
}
} else if len(vote.Extension) > 0 {
return errors.New("unexpected vote extension - extensions are only allowed in precommits")
}
// We might crash before writing to the wal,
@@ -402,9 +411,6 @@ func (pv *FilePV) signVote(chainID string, vote *tmproto.Vote) error {
vote.Signature = lss.Signature
}
// Vote extensions are non-deterministic, so it's possible that an
// application may have created a different extension. We therefore
// always re-sign the vote extension.
vote.ExtensionSignature = extSig
return nil
+9 -9
View File
@@ -12,8 +12,8 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/crypto/tmhash"
tmrand "github.com/tendermint/tendermint/libs/rand"
tmtime "github.com/tendermint/tendermint/libs/time"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
@@ -47,7 +47,7 @@ func TestResetValidator(t *testing.T) {
// test vote
height, round := int64(10), int32(1)
voteType := tmproto.PrevoteType
randBytes := tmrand.Bytes(tmhash.Size)
randBytes := tmrand.Bytes(crypto.HashSize)
blockID := types.BlockID{Hash: randBytes, PartSetHeader: types.PartSetHeader{}}
vote := newVote(privVal.Key.Address, 0, height, round, voteType, blockID, nil)
err := privVal.SignVote(ctx, "mychainid", vote.ToProto())
@@ -150,8 +150,8 @@ func TestSignVote(t *testing.T) {
privVal, _, _ := newTestFilePV(t)
randbytes := tmrand.Bytes(tmhash.Size)
randbytes2 := tmrand.Bytes(tmhash.Size)
randbytes := tmrand.Bytes(crypto.HashSize)
randbytes2 := tmrand.Bytes(crypto.HashSize)
block1 := types.BlockID{Hash: randbytes,
PartSetHeader: types.PartSetHeader{Total: 5, Hash: randbytes}}
@@ -199,8 +199,8 @@ func TestSignProposal(t *testing.T) {
privVal, _, _ := newTestFilePV(t)
randbytes := tmrand.Bytes(tmhash.Size)
randbytes2 := tmrand.Bytes(tmhash.Size)
randbytes := tmrand.Bytes(crypto.HashSize)
randbytes2 := tmrand.Bytes(crypto.HashSize)
block1 := types.BlockID{Hash: randbytes,
PartSetHeader: types.PartSetHeader{Total: 5, Hash: randbytes}}
@@ -246,7 +246,7 @@ func TestDifferByTimestamp(t *testing.T) {
privVal, err := GenFilePV(tempKeyFile.Name(), tempStateFile.Name(), "")
require.NoError(t, err)
randbytes := tmrand.Bytes(tmhash.Size)
randbytes := tmrand.Bytes(crypto.HashSize)
height, round := int64(10), int32(1)
chainID := "mychainid"
@@ -285,8 +285,8 @@ func TestVoteExtensionsAreAlwaysSigned(t *testing.T) {
assert.NoError(t, err)
block := types.BlockID{
Hash: tmrand.Bytes(tmhash.Size),
PartSetHeader: types.PartSetHeader{Total: 5, Hash: tmrand.Bytes(tmhash.Size)},
Hash: tmrand.Bytes(crypto.HashSize),
PartSetHeader: types.PartSetHeader{Total: 5, Hash: tmrand.Bytes(crypto.HashSize)},
}
height, round := int64(10), int32(1)
+2 -3
View File
@@ -14,7 +14,6 @@ import (
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/libs/log"
tmrand "github.com/tendermint/tendermint/libs/rand"
tmgrpc "github.com/tendermint/tendermint/privval/grpc"
@@ -86,7 +85,7 @@ func TestSignerClient_SignVote(t *testing.T) {
require.NoError(t, err)
ts := time.Now()
hash := tmrand.Bytes(tmhash.Size)
hash := tmrand.Bytes(crypto.HashSize)
valAddr := tmrand.Bytes(crypto.AddressSize)
want := &types.Vote{
@@ -141,7 +140,7 @@ func TestSignerClient_SignProposal(t *testing.T) {
require.NoError(t, err)
ts := time.Now()
hash := tmrand.Bytes(tmhash.Size)
hash := tmrand.Bytes(crypto.HashSize)
have := &types.Proposal{
Type: tmproto.ProposalType,
+2 -3
View File
@@ -9,7 +9,6 @@ import (
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/libs/log"
tmrand "github.com/tendermint/tendermint/libs/rand"
tmgrpc "github.com/tendermint/tendermint/privval/grpc"
@@ -57,7 +56,7 @@ func TestGetPubKey(t *testing.T) {
func TestSignVote(t *testing.T) {
ts := time.Now()
hash := tmrand.Bytes(tmhash.Size)
hash := tmrand.Bytes(crypto.HashSize)
valAddr := tmrand.Bytes(crypto.AddressSize)
testCases := []struct {
@@ -133,7 +132,7 @@ func TestSignVote(t *testing.T) {
func TestSignProposal(t *testing.T) {
ts := time.Now()
hash := tmrand.Bytes(tmhash.Size)
hash := tmrand.Bytes(crypto.HashSize)
testCases := []struct {
name string
+3 -4
View File
@@ -11,7 +11,6 @@ import (
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/crypto/encoding"
"github.com/tendermint/tendermint/crypto/tmhash"
cryptoproto "github.com/tendermint/tendermint/proto/tendermint/crypto"
privproto "github.com/tendermint/tendermint/proto/tendermint/privval"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
@@ -25,7 +24,7 @@ func exampleVote() *types.Vote {
Type: tmproto.PrecommitType,
Height: 3,
Round: 2,
BlockID: types.BlockID{Hash: tmhash.Sum([]byte("blockID_hash")), PartSetHeader: types.PartSetHeader{Total: 1000000, Hash: tmhash.Sum([]byte("blockID_part_set_header_hash"))}},
BlockID: types.BlockID{Hash: crypto.Checksum([]byte("blockID_hash")), PartSetHeader: types.PartSetHeader{Total: 1000000, Hash: crypto.Checksum([]byte("blockID_part_set_header_hash"))}},
Timestamp: stamp,
ValidatorAddress: crypto.AddressHash([]byte("validator_address")),
ValidatorIndex: 56789,
@@ -43,10 +42,10 @@ func exampleProposal() *types.Proposal {
POLRound: 2,
Signature: []byte("it's a signature"),
BlockID: types.BlockID{
Hash: tmhash.Sum([]byte("blockID_hash")),
Hash: crypto.Checksum([]byte("blockID_hash")),
PartSetHeader: types.PartSetHeader{
Total: 1000000,
Hash: tmhash.Sum([]byte("blockID_part_set_header_hash")),
Hash: crypto.Checksum([]byte("blockID_part_set_header_hash")),
},
},
}
+6 -7
View File
@@ -11,7 +11,6 @@ import (
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/libs/log"
tmrand "github.com/tendermint/tendermint/libs/rand"
cryptoproto "github.com/tendermint/tendermint/proto/tendermint/crypto"
@@ -143,7 +142,7 @@ func TestSignerProposal(t *testing.T) {
defer tc.closer()
ts := time.Now()
hash := tmrand.Bytes(tmhash.Size)
hash := tmrand.Bytes(crypto.HashSize)
have := &types.Proposal{
Type: tmproto.ProposalType,
Height: 1,
@@ -183,7 +182,7 @@ func TestSignerVote(t *testing.T) {
defer tc.closer()
ts := time.Now()
hash := tmrand.Bytes(tmhash.Size)
hash := tmrand.Bytes(crypto.HashSize)
valAddr := tmrand.Bytes(crypto.AddressSize)
want := &types.Vote{
Type: tmproto.PrecommitType,
@@ -224,7 +223,7 @@ func TestSignerVoteResetDeadline(t *testing.T) {
for _, tc := range getSignerTestCases(ctx, t, logger) {
t.Run(tc.name, func(t *testing.T) {
ts := time.Now()
hash := tmrand.Bytes(tmhash.Size)
hash := tmrand.Bytes(crypto.HashSize)
valAddr := tmrand.Bytes(crypto.AddressSize)
want := &types.Vote{
Type: tmproto.PrecommitType,
@@ -277,7 +276,7 @@ func TestSignerVoteKeepAlive(t *testing.T) {
defer tc.closer()
ts := time.Now()
hash := tmrand.Bytes(tmhash.Size)
hash := tmrand.Bytes(crypto.HashSize)
valAddr := tmrand.Bytes(crypto.AddressSize)
want := &types.Vote{
Type: tmproto.PrecommitType,
@@ -330,7 +329,7 @@ func TestSignerSignProposalErrors(t *testing.T) {
tc.mockPV = types.NewErroringMockPV()
ts := time.Now()
hash := tmrand.Bytes(tmhash.Size)
hash := tmrand.Bytes(crypto.HashSize)
proposal := &types.Proposal{
Type: tmproto.ProposalType,
Height: 1,
@@ -368,7 +367,7 @@ func TestSignerSignVoteErrors(t *testing.T) {
defer tc.closer()
ts := time.Now()
hash := tmrand.Bytes(tmhash.Size)
hash := tmrand.Bytes(crypto.HashSize)
valAddr := tmrand.Bytes(crypto.AddressSize)
vote := &types.Vote{
Type: tmproto.PrecommitType,
+4 -4
View File
@@ -7,7 +7,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/crypto"
tmrand "github.com/tendermint/tendermint/libs/rand"
"github.com/tendermint/tendermint/privval"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
@@ -54,16 +54,16 @@ func makeEvidences(
Type: tmproto.PrevoteType,
Timestamp: timestamp,
BlockID: types.BlockID{
Hash: tmhash.Sum(tmrand.Bytes(tmhash.Size)),
Hash: crypto.Checksum(tmrand.Bytes(crypto.HashSize)),
PartSetHeader: types.PartSetHeader{
Total: 1000,
Hash: tmhash.Sum([]byte("partset")),
Hash: crypto.Checksum([]byte("partset")),
},
},
}
vote2 := vote
vote2.BlockID.Hash = tmhash.Sum([]byte("blockhash2"))
vote2.BlockID.Hash = crypto.Checksum([]byte("blockhash2"))
correct = newEvidence(t, val, &vote, &vote2, chainID, timestamp)
fakes = make([]*types.DuplicateVoteEvidence, 0)
+7 -9
View File
@@ -118,17 +118,15 @@ func writeListOfEndpoints(w http.ResponseWriter, r *http.Request, funcMap map[st
noArgs := make(map[string]string)
for name, rf := range funcMap {
base := fmt.Sprintf("//%s/%s", r.Host, name)
// N.B. Check argNames, not args, since the type list includes the type
// of the leading context argument.
if len(rf.argNames) == 0 {
if len(rf.args) == 0 {
noArgs[name] = base
} else {
query := append([]string(nil), rf.argNames...)
for i, arg := range query {
query[i] = arg + "=_"
}
hasArgs[name] = base + "?" + strings.Join(query, "&")
continue
}
var query []string
for _, arg := range rf.args {
query = append(query, arg.name+"=_")
}
hasArgs[name] = base + "?" + strings.Join(query, "&")
}
w.Header().Set("Content-Type", "text/html")
_ = listOfEndpoints.Execute(w, map[string]map[string]string{
+17 -9
View File
@@ -23,7 +23,7 @@ func makeHTTPHandler(rpcFunc *RPCFunc, logger log.Logger) func(http.ResponseWrit
ctx := rpctypes.WithCallInfo(req.Context(), &rpctypes.CallInfo{
HTTPRequest: req,
})
args, err := parseURLParams(rpcFunc.argNames, req)
args, err := parseURLParams(rpcFunc.args, req)
if err != nil {
w.Header().Set("Content-Type", "text/plain")
w.WriteHeader(http.StatusBadRequest)
@@ -40,7 +40,7 @@ func makeHTTPHandler(rpcFunc *RPCFunc, logger log.Logger) func(http.ResponseWrit
}
}
func parseURLParams(argNames []string, req *http.Request) ([]byte, error) {
func parseURLParams(args []argInfo, req *http.Request) ([]byte, error) {
if err := req.ParseForm(); err != nil {
return nil, fmt.Errorf("invalid HTTP request: %w", err)
}
@@ -52,15 +52,15 @@ func parseURLParams(argNames []string, req *http.Request) ([]byte, error) {
}
params := make(map[string]interface{})
for _, name := range argNames {
v, ok := getArg(name)
for _, arg := range args {
v, ok := getArg(arg.name)
if !ok {
continue
}
if z, err := decodeInteger(v); err == nil {
params[name] = z
params[arg.name] = z
} else if b, err := strconv.ParseBool(v); err == nil {
params[name] = b
params[arg.name] = b
} else if lc := strings.ToLower(v); strings.HasPrefix(lc, "0x") {
dec, err := hex.DecodeString(lc[2:])
if err != nil {
@@ -68,15 +68,23 @@ func parseURLParams(argNames []string, req *http.Request) ([]byte, error) {
} else if len(dec) == 0 {
return nil, errors.New("invalid empty hex string")
}
params[name] = dec
if arg.isBinary {
params[arg.name] = dec
} else {
params[arg.name] = string(dec)
}
} else if isQuotedString(v) {
var dec string
if err := json.Unmarshal([]byte(v), &dec); err != nil {
return nil, fmt.Errorf("invalid quoted string: %w", err)
}
params[name] = dec
if arg.isBinary {
params[arg.name] = []byte(dec)
} else {
params[arg.name] = dec
}
} else {
params[name] = v
params[arg.name] = v
}
}
return json.Marshal(params)
+16 -10
View File
@@ -188,44 +188,50 @@ func TestParseURI(t *testing.T) {
tests := []struct {
name string
url string
args []string
args []argInfo
want string
fail bool
}{
{
name: "quoted numbers and strings",
url: `http://localhost?num="7"&str="flew"&neg="-10"`,
args: []string{"neg", "num", "str", "other"},
args: []argInfo{{name: "neg"}, {name: "num"}, {name: "str"}, {name: "other"}},
want: `{"neg":-10,"num":7,"str":"flew"}`,
},
{
name: "unquoted numbers and strings",
url: `http://localhost?num1=7&str1=cabbage&num2=-199&str2=hey+you`,
args: []string{"num1", "num2", "str1", "str2", "other"},
args: []argInfo{{name: "num1"}, {name: "num2"}, {name: "str1"}, {name: "str2"}, {name: "other"}},
want: `{"num1":7,"num2":-199,"str1":"cabbage","str2":"hey you"}`,
},
{
name: "byte strings in hex",
name: "quoted byte strings",
url: `http://localhost?left="Fahrvergnügen"&right="Applesauce"`,
args: []argInfo{{name: "left", isBinary: true}, {name: "right", isBinary: false}},
want: `{"left":"RmFocnZlcmduw7xnZW4=","right":"Applesauce"}`,
},
{
name: "hexadecimal byte strings",
url: `http://localhost?lower=0x626f62&upper=0X646F7567`,
args: []string{"upper", "lower", "other"},
want: `{"lower":"Ym9i","upper":"ZG91Zw=="}`,
args: []argInfo{{name: "upper", isBinary: true}, {name: "lower", isBinary: false}, {name: "other"}},
want: `{"lower":"bob","upper":"ZG91Zw=="}`,
},
{
name: "invalid hex odd length",
url: `http://localhost?bad=0xa`,
args: []string{"bad", "superbad"},
args: []argInfo{{name: "bad"}, {name: "superbad"}},
fail: true,
},
{
name: "invalid hex empty",
url: `http://localhost?bad=0x`,
args: []string{"bad"},
args: []argInfo{{name: "bad"}},
fail: true,
},
{
name: "invalid quoted string",
url: `http://localhost?bad="double""`,
args: []string{"bad"},
args: []argInfo{{name: "bad"}},
fail: true,
},
}
@@ -305,7 +311,7 @@ func TestParseURI(t *testing.T) {
if err != nil {
t.Fatalf("NewRequest for %q: %v", test.url, err)
}
bits, err := parseURLParams(echo.argNames, hreq)
bits, err := parseURLParams(echo.args, hreq)
if err != nil {
t.Fatalf("Parse %#q: unexpected error: %v", test.url, err)
}
+35 -15
View File
@@ -32,11 +32,20 @@ func RegisterRPCFuncs(mux *http.ServeMux, funcMap map[string]*RPCFunc, logger lo
// RPCFunc contains the introspected type information for a function.
type RPCFunc struct {
f reflect.Value // underlying rpc function
param reflect.Type // the parameter struct, or nil
result reflect.Type // the non-error result type, or nil
argNames []string // name of each argument (for display)
ws bool // websocket only
f reflect.Value // underlying rpc function
param reflect.Type // the parameter struct, or nil
result reflect.Type // the non-error result type, or nil
args []argInfo // names and type information (for URL decoding)
ws bool // websocket only
}
// argInfo records the name of a field, along with a bit to tell whether the
// value of the field requires binary data, having underlying type []byte. The
// flag is needed when decoding URL parameters, where we permit quoted strings
// to be passed for either argument type.
type argInfo struct {
name string
isBinary bool // value wants binary data
}
// Call parses the given JSON parameters and calls the function wrapped by rf
@@ -96,12 +105,12 @@ func (rf *RPCFunc) adjustParams(data []byte) (json.RawMessage, error) {
var args []json.RawMessage
if err := json.Unmarshal(base, &args); err != nil {
return nil, err
} else if len(args) != len(rf.argNames) {
return nil, fmt.Errorf("got %d arguments, want %d", len(args), len(rf.argNames))
} else if len(args) != len(rf.args) {
return nil, fmt.Errorf("got %d arguments, want %d", len(args), len(rf.args))
}
m := make(map[string]json.RawMessage)
for i, arg := range args {
m[rf.argNames[i]] = arg
m[rf.args[i].name] = arg
}
return json.Marshal(m)
} else if bytes.HasPrefix(base, []byte("{")) || bytes.Equal(base, []byte("null")) {
@@ -180,12 +189,15 @@ func newRPCFunc(f interface{}) (*RPCFunc, error) {
rtype = ft.Out(0)
}
var argNames []string
var args []argInfo
if ptype != nil {
for i := 0; i < ptype.NumField(); i++ {
field := ptype.Field(i)
if tag := strings.SplitN(field.Tag.Get("json"), ",", 2)[0]; tag != "" && tag != "-" {
argNames = append(argNames, tag)
args = append(args, argInfo{
name: tag,
isBinary: isByteArray(field.Type),
})
} else if tag == "-" {
// If the tag is "-" the field should explicitly be ignored, even
// if it is otherwise eligible.
@@ -194,16 +206,19 @@ func newRPCFunc(f interface{}) (*RPCFunc, error) {
// Note that this is an aesthetic choice; the standard decoder will
// match without regard to case anyway.
name := strings.ToLower(field.Name[:1]) + field.Name[1:]
argNames = append(argNames, name)
args = append(args, argInfo{
name: name,
isBinary: isByteArray(field.Type),
})
}
}
}
return &RPCFunc{
f: fv,
param: ptype,
result: rtype,
argNames: argNames,
f: fv,
param: ptype,
result: rtype,
args: args,
}, nil
}
@@ -225,3 +240,8 @@ func isNullOrEmpty(params json.RawMessage) bool {
bytes.Equal(params, []byte("{}")) ||
bytes.Equal(params, []byte("[]"))
}
// isByteArray reports whether t is (equivalent to) []byte.
func isByteArray(t reflect.Type) bool {
return t.Kind() == reflect.Slice && t.Elem().Kind() == reflect.Uint8
}
+11 -12
View File
@@ -12,7 +12,6 @@ import (
"time"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/internal/test/factory"
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/privval"
@@ -256,26 +255,26 @@ func makeHeaderRandom(chainID string, height int64) *types.Header {
Height: height,
Time: time.Now(),
LastBlockID: makeBlockID([]byte("headerhash"), 1000, []byte("partshash")),
LastCommitHash: crypto.CRandBytes(tmhash.Size),
DataHash: crypto.CRandBytes(tmhash.Size),
ValidatorsHash: crypto.CRandBytes(tmhash.Size),
NextValidatorsHash: crypto.CRandBytes(tmhash.Size),
ConsensusHash: crypto.CRandBytes(tmhash.Size),
AppHash: crypto.CRandBytes(tmhash.Size),
LastResultsHash: crypto.CRandBytes(tmhash.Size),
EvidenceHash: crypto.CRandBytes(tmhash.Size),
LastCommitHash: crypto.CRandBytes(crypto.HashSize),
DataHash: crypto.CRandBytes(crypto.HashSize),
ValidatorsHash: crypto.CRandBytes(crypto.HashSize),
NextValidatorsHash: crypto.CRandBytes(crypto.HashSize),
ConsensusHash: crypto.CRandBytes(crypto.HashSize),
AppHash: crypto.CRandBytes(crypto.HashSize),
LastResultsHash: crypto.CRandBytes(crypto.HashSize),
EvidenceHash: crypto.CRandBytes(crypto.HashSize),
ProposerAddress: crypto.CRandBytes(crypto.AddressSize),
}
}
func makeRandomBlockID() types.BlockID {
return makeBlockID(crypto.CRandBytes(tmhash.Size), 100, crypto.CRandBytes(tmhash.Size))
return makeBlockID(crypto.CRandBytes(crypto.HashSize), 100, crypto.CRandBytes(crypto.HashSize))
}
func makeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) types.BlockID {
var (
h = make([]byte, tmhash.Size)
psH = make([]byte, tmhash.Size)
h = make([]byte, crypto.HashSize)
psH = make([]byte, crypto.HashSize)
)
copy(h, hash)
copy(psH, partSetHash)
+7 -4
View File
@@ -13,7 +13,6 @@ import (
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/merkle"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/libs/bits"
tmbytes "github.com/tendermint/tendermint/libs/bytes"
tmmath "github.com/tendermint/tendermint/libs/math"
@@ -780,7 +779,11 @@ func CommitToVoteSet(chainID string, commit *Commit, vals *ValidatorSet) *VoteSe
if commitSig.Absent() {
continue // OK, some precommits can be missing.
}
added, err := voteSet.AddVote(commit.GetVote(int32(idx)))
vote := commit.GetVote(int32(idx))
if err := vote.ValidateBasic(); err != nil {
panic(fmt.Errorf("failed to validate vote reconstructed from LastCommit: %w", err))
}
added, err := voteSet.AddVote(vote)
if !added || err != nil {
panic(fmt.Errorf("failed to reconstruct LastCommit: %w", err))
}
@@ -1122,9 +1125,9 @@ func (blockID BlockID) IsNil() bool {
// IsComplete returns true if this is a valid BlockID of a non-nil block.
func (blockID BlockID) IsComplete() bool {
return len(blockID.Hash) == tmhash.Size &&
return len(blockID.Hash) == crypto.HashSize &&
blockID.PartSetHeader.Total > 0 &&
len(blockID.PartSetHeader.Hash) == tmhash.Size
len(blockID.PartSetHeader.Hash) == crypto.HashSize
}
// String returns a human readable string representation of the BlockID.
+5 -5
View File
@@ -5,13 +5,13 @@ import (
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/crypto"
tmrand "github.com/tendermint/tendermint/libs/rand"
)
func TestBlockMeta_ToProto(t *testing.T) {
h := MakeRandHeader()
bi := BlockID{Hash: h.Hash(), PartSetHeader: PartSetHeader{Total: 123, Hash: tmrand.Bytes(tmhash.Size)}}
bi := BlockID{Hash: h.Hash(), PartSetHeader: PartSetHeader{Total: 123, Hash: tmrand.Bytes(crypto.HashSize)}}
bm := &BlockMeta{
BlockID: bi,
@@ -48,9 +48,9 @@ func TestBlockMeta_ToProto(t *testing.T) {
func TestBlockMeta_ValidateBasic(t *testing.T) {
h := MakeRandHeader()
bi := BlockID{Hash: h.Hash(), PartSetHeader: PartSetHeader{Total: 123, Hash: tmrand.Bytes(tmhash.Size)}}
bi2 := BlockID{Hash: tmrand.Bytes(tmhash.Size),
PartSetHeader: PartSetHeader{Total: 123, Hash: tmrand.Bytes(tmhash.Size)}}
bi := BlockID{Hash: h.Hash(), PartSetHeader: PartSetHeader{Total: 123, Hash: tmrand.Bytes(crypto.HashSize)}}
bi2 := BlockID{Hash: tmrand.Bytes(crypto.HashSize),
PartSetHeader: PartSetHeader{Total: 123, Hash: tmrand.Bytes(crypto.HashSize)}}
bi3 := BlockID{Hash: []byte("incorrect hash"),
PartSetHeader: PartSetHeader{Total: 123, Hash: []byte("incorrect hash")}}
+98 -99
View File
@@ -19,7 +19,6 @@ import (
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/merkle"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/libs/bits"
"github.com/tendermint/tendermint/libs/bytes"
tmrand "github.com/tendermint/tendermint/libs/rand"
@@ -213,8 +212,8 @@ func TestBlockString(t *testing.T) {
func makeBlockIDRandom() BlockID {
var (
blockHash = make([]byte, tmhash.Size)
partSetHash = make([]byte, tmhash.Size)
blockHash = make([]byte, crypto.HashSize)
partSetHash = make([]byte, crypto.HashSize)
)
rand.Read(blockHash) //nolint: errcheck // ignore errcheck for read
rand.Read(partSetHash) //nolint: errcheck // ignore errcheck for read
@@ -223,8 +222,8 @@ func makeBlockIDRandom() BlockID {
func makeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) BlockID {
var (
h = make([]byte, tmhash.Size)
psH = make([]byte, tmhash.Size)
h = make([]byte, crypto.HashSize)
psH = make([]byte, crypto.HashSize)
)
copy(h, hash)
copy(psH, partSetHash)
@@ -324,10 +323,10 @@ func TestMaxCommitBytes(t *testing.T) {
Height: math.MaxInt64,
Round: math.MaxInt32,
BlockID: BlockID{
Hash: tmhash.Sum([]byte("blockID_hash")),
Hash: crypto.Checksum([]byte("blockID_hash")),
PartSetHeader: PartSetHeader{
Total: math.MaxInt32,
Hash: tmhash.Sum([]byte("blockID_part_set_header_hash")),
Hash: crypto.Checksum([]byte("blockID_part_set_header_hash")),
},
},
Signatures: []CommitSig{cs},
@@ -359,15 +358,15 @@ func TestHeaderHash(t *testing.T) {
ChainID: "chainId",
Height: 3,
Time: time.Date(2019, 10, 13, 16, 14, 44, 0, time.UTC),
LastBlockID: makeBlockID(make([]byte, tmhash.Size), 6, make([]byte, tmhash.Size)),
LastCommitHash: tmhash.Sum([]byte("last_commit_hash")),
DataHash: tmhash.Sum([]byte("data_hash")),
ValidatorsHash: tmhash.Sum([]byte("validators_hash")),
NextValidatorsHash: tmhash.Sum([]byte("next_validators_hash")),
ConsensusHash: tmhash.Sum([]byte("consensus_hash")),
AppHash: tmhash.Sum([]byte("app_hash")),
LastResultsHash: tmhash.Sum([]byte("last_results_hash")),
EvidenceHash: tmhash.Sum([]byte("evidence_hash")),
LastBlockID: makeBlockID(make([]byte, crypto.HashSize), 6, make([]byte, crypto.HashSize)),
LastCommitHash: crypto.Checksum([]byte("last_commit_hash")),
DataHash: crypto.Checksum([]byte("data_hash")),
ValidatorsHash: crypto.Checksum([]byte("validators_hash")),
NextValidatorsHash: crypto.Checksum([]byte("next_validators_hash")),
ConsensusHash: crypto.Checksum([]byte("consensus_hash")),
AppHash: crypto.Checksum([]byte("app_hash")),
LastResultsHash: crypto.Checksum([]byte("last_results_hash")),
EvidenceHash: crypto.Checksum([]byte("evidence_hash")),
ProposerAddress: crypto.AddressHash([]byte("proposer_address")),
}, hexBytesFromString(t, "F740121F553B5418C3EFBD343C2DBFE9E007BB67B0D020A0741374BAB65242A4")},
{"nil header yields nil", nil, nil},
@@ -376,15 +375,15 @@ func TestHeaderHash(t *testing.T) {
ChainID: "chainId",
Height: 3,
Time: time.Date(2019, 10, 13, 16, 14, 44, 0, time.UTC),
LastBlockID: makeBlockID(make([]byte, tmhash.Size), 6, make([]byte, tmhash.Size)),
LastCommitHash: tmhash.Sum([]byte("last_commit_hash")),
DataHash: tmhash.Sum([]byte("data_hash")),
LastBlockID: makeBlockID(make([]byte, crypto.HashSize), 6, make([]byte, crypto.HashSize)),
LastCommitHash: crypto.Checksum([]byte("last_commit_hash")),
DataHash: crypto.Checksum([]byte("data_hash")),
ValidatorsHash: nil,
NextValidatorsHash: tmhash.Sum([]byte("next_validators_hash")),
ConsensusHash: tmhash.Sum([]byte("consensus_hash")),
AppHash: tmhash.Sum([]byte("app_hash")),
LastResultsHash: tmhash.Sum([]byte("last_results_hash")),
EvidenceHash: tmhash.Sum([]byte("evidence_hash")),
NextValidatorsHash: crypto.Checksum([]byte("next_validators_hash")),
ConsensusHash: crypto.Checksum([]byte("consensus_hash")),
AppHash: crypto.Checksum([]byte("app_hash")),
LastResultsHash: crypto.Checksum([]byte("last_results_hash")),
EvidenceHash: crypto.Checksum([]byte("evidence_hash")),
ProposerAddress: crypto.AddressHash([]byte("proposer_address")),
}, nil},
}
@@ -455,15 +454,15 @@ func TestMaxHeaderBytes(t *testing.T) {
ChainID: maxChainID,
Height: math.MaxInt64,
Time: timestamp,
LastBlockID: makeBlockID(make([]byte, tmhash.Size), math.MaxInt32, make([]byte, tmhash.Size)),
LastCommitHash: tmhash.Sum([]byte("last_commit_hash")),
DataHash: tmhash.Sum([]byte("data_hash")),
ValidatorsHash: tmhash.Sum([]byte("validators_hash")),
NextValidatorsHash: tmhash.Sum([]byte("next_validators_hash")),
ConsensusHash: tmhash.Sum([]byte("consensus_hash")),
AppHash: tmhash.Sum([]byte("app_hash")),
LastResultsHash: tmhash.Sum([]byte("last_results_hash")),
EvidenceHash: tmhash.Sum([]byte("evidence_hash")),
LastBlockID: makeBlockID(make([]byte, crypto.HashSize), math.MaxInt32, make([]byte, crypto.HashSize)),
LastCommitHash: crypto.Checksum([]byte("last_commit_hash")),
DataHash: crypto.Checksum([]byte("data_hash")),
ValidatorsHash: crypto.Checksum([]byte("validators_hash")),
NextValidatorsHash: crypto.Checksum([]byte("next_validators_hash")),
ConsensusHash: crypto.Checksum([]byte("consensus_hash")),
AppHash: crypto.Checksum([]byte("app_hash")),
LastResultsHash: crypto.Checksum([]byte("last_results_hash")),
EvidenceHash: crypto.Checksum([]byte("evidence_hash")),
ProposerAddress: crypto.AddressHash([]byte("proposer_address")),
}
@@ -765,7 +764,7 @@ func MakeRandHeader() Header {
chainID := "test"
t := time.Now()
height := mrand.Int63()
randBytes := tmrand.Bytes(tmhash.Size)
randBytes := tmrand.Bytes(crypto.HashSize)
randAddress := tmrand.Bytes(crypto.AddressSize)
h := Header{
Version: version.Consensus{Block: version.BlockProtocol, App: 1},
@@ -1014,7 +1013,7 @@ func TestHeader_ValidateBasic(t *testing.T) {
ChainID: string(make([]byte, MaxChainIDLen)),
Height: 1,
LastBlockID: BlockID{
Hash: make([]byte, tmhash.Size+1),
Hash: make([]byte, crypto.HashSize+1),
},
},
true, "wrong Hash",
@@ -1026,9 +1025,9 @@ func TestHeader_ValidateBasic(t *testing.T) {
ChainID: string(make([]byte, MaxChainIDLen)),
Height: 1,
LastBlockID: BlockID{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
PartSetHeader: PartSetHeader{
Hash: make([]byte, tmhash.Size+1),
Hash: make([]byte, crypto.HashSize+1),
},
},
},
@@ -1041,12 +1040,12 @@ func TestHeader_ValidateBasic(t *testing.T) {
ChainID: string(make([]byte, MaxChainIDLen)),
Height: 1,
LastBlockID: BlockID{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
PartSetHeader: PartSetHeader{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
},
},
LastCommitHash: make([]byte, tmhash.Size+1),
LastCommitHash: make([]byte, crypto.HashSize+1),
},
true, "wrong LastCommitHash",
},
@@ -1057,13 +1056,13 @@ func TestHeader_ValidateBasic(t *testing.T) {
ChainID: string(make([]byte, MaxChainIDLen)),
Height: 1,
LastBlockID: BlockID{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
PartSetHeader: PartSetHeader{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
},
},
LastCommitHash: make([]byte, tmhash.Size),
DataHash: make([]byte, tmhash.Size+1),
LastCommitHash: make([]byte, crypto.HashSize),
DataHash: make([]byte, crypto.HashSize+1),
},
true, "wrong DataHash",
},
@@ -1074,14 +1073,14 @@ func TestHeader_ValidateBasic(t *testing.T) {
ChainID: string(make([]byte, MaxChainIDLen)),
Height: 1,
LastBlockID: BlockID{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
PartSetHeader: PartSetHeader{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
},
},
LastCommitHash: make([]byte, tmhash.Size),
DataHash: make([]byte, tmhash.Size),
EvidenceHash: make([]byte, tmhash.Size+1),
LastCommitHash: make([]byte, crypto.HashSize),
DataHash: make([]byte, crypto.HashSize),
EvidenceHash: make([]byte, crypto.HashSize+1),
},
true, "wrong EvidenceHash",
},
@@ -1092,14 +1091,14 @@ func TestHeader_ValidateBasic(t *testing.T) {
ChainID: string(make([]byte, MaxChainIDLen)),
Height: 1,
LastBlockID: BlockID{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
PartSetHeader: PartSetHeader{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
},
},
LastCommitHash: make([]byte, tmhash.Size),
DataHash: make([]byte, tmhash.Size),
EvidenceHash: make([]byte, tmhash.Size),
LastCommitHash: make([]byte, crypto.HashSize),
DataHash: make([]byte, crypto.HashSize),
EvidenceHash: make([]byte, crypto.HashSize),
ProposerAddress: make([]byte, crypto.AddressSize+1),
},
true, "invalid ProposerAddress length",
@@ -1111,16 +1110,16 @@ func TestHeader_ValidateBasic(t *testing.T) {
ChainID: string(make([]byte, MaxChainIDLen)),
Height: 1,
LastBlockID: BlockID{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
PartSetHeader: PartSetHeader{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
},
},
LastCommitHash: make([]byte, tmhash.Size),
DataHash: make([]byte, tmhash.Size),
EvidenceHash: make([]byte, tmhash.Size),
LastCommitHash: make([]byte, crypto.HashSize),
DataHash: make([]byte, crypto.HashSize),
EvidenceHash: make([]byte, crypto.HashSize),
ProposerAddress: make([]byte, crypto.AddressSize),
ValidatorsHash: make([]byte, tmhash.Size+1),
ValidatorsHash: make([]byte, crypto.HashSize+1),
},
true, "wrong ValidatorsHash",
},
@@ -1131,17 +1130,17 @@ func TestHeader_ValidateBasic(t *testing.T) {
ChainID: string(make([]byte, MaxChainIDLen)),
Height: 1,
LastBlockID: BlockID{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
PartSetHeader: PartSetHeader{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
},
},
LastCommitHash: make([]byte, tmhash.Size),
DataHash: make([]byte, tmhash.Size),
EvidenceHash: make([]byte, tmhash.Size),
LastCommitHash: make([]byte, crypto.HashSize),
DataHash: make([]byte, crypto.HashSize),
EvidenceHash: make([]byte, crypto.HashSize),
ProposerAddress: make([]byte, crypto.AddressSize),
ValidatorsHash: make([]byte, tmhash.Size),
NextValidatorsHash: make([]byte, tmhash.Size+1),
ValidatorsHash: make([]byte, crypto.HashSize),
NextValidatorsHash: make([]byte, crypto.HashSize+1),
},
true, "wrong NextValidatorsHash",
},
@@ -1152,18 +1151,18 @@ func TestHeader_ValidateBasic(t *testing.T) {
ChainID: string(make([]byte, MaxChainIDLen)),
Height: 1,
LastBlockID: BlockID{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
PartSetHeader: PartSetHeader{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
},
},
LastCommitHash: make([]byte, tmhash.Size),
DataHash: make([]byte, tmhash.Size),
EvidenceHash: make([]byte, tmhash.Size),
LastCommitHash: make([]byte, crypto.HashSize),
DataHash: make([]byte, crypto.HashSize),
EvidenceHash: make([]byte, crypto.HashSize),
ProposerAddress: make([]byte, crypto.AddressSize),
ValidatorsHash: make([]byte, tmhash.Size),
NextValidatorsHash: make([]byte, tmhash.Size),
ConsensusHash: make([]byte, tmhash.Size+1),
ValidatorsHash: make([]byte, crypto.HashSize),
NextValidatorsHash: make([]byte, crypto.HashSize),
ConsensusHash: make([]byte, crypto.HashSize+1),
},
true, "wrong ConsensusHash",
},
@@ -1174,19 +1173,19 @@ func TestHeader_ValidateBasic(t *testing.T) {
ChainID: string(make([]byte, MaxChainIDLen)),
Height: 1,
LastBlockID: BlockID{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
PartSetHeader: PartSetHeader{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
},
},
LastCommitHash: make([]byte, tmhash.Size),
DataHash: make([]byte, tmhash.Size),
EvidenceHash: make([]byte, tmhash.Size),
LastCommitHash: make([]byte, crypto.HashSize),
DataHash: make([]byte, crypto.HashSize),
EvidenceHash: make([]byte, crypto.HashSize),
ProposerAddress: make([]byte, crypto.AddressSize),
ValidatorsHash: make([]byte, tmhash.Size),
NextValidatorsHash: make([]byte, tmhash.Size),
ConsensusHash: make([]byte, tmhash.Size),
LastResultsHash: make([]byte, tmhash.Size+1),
ValidatorsHash: make([]byte, crypto.HashSize),
NextValidatorsHash: make([]byte, crypto.HashSize),
ConsensusHash: make([]byte, crypto.HashSize),
LastResultsHash: make([]byte, crypto.HashSize+1),
},
true, "wrong LastResultsHash",
},
@@ -1197,19 +1196,19 @@ func TestHeader_ValidateBasic(t *testing.T) {
ChainID: string(make([]byte, MaxChainIDLen)),
Height: 1,
LastBlockID: BlockID{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
PartSetHeader: PartSetHeader{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
},
},
LastCommitHash: make([]byte, tmhash.Size),
DataHash: make([]byte, tmhash.Size),
EvidenceHash: make([]byte, tmhash.Size),
LastCommitHash: make([]byte, crypto.HashSize),
DataHash: make([]byte, crypto.HashSize),
EvidenceHash: make([]byte, crypto.HashSize),
ProposerAddress: make([]byte, crypto.AddressSize),
ValidatorsHash: make([]byte, tmhash.Size),
NextValidatorsHash: make([]byte, tmhash.Size),
ConsensusHash: make([]byte, tmhash.Size),
LastResultsHash: make([]byte, tmhash.Size),
ValidatorsHash: make([]byte, crypto.HashSize),
NextValidatorsHash: make([]byte, crypto.HashSize),
ConsensusHash: make([]byte, crypto.HashSize),
LastResultsHash: make([]byte, crypto.HashSize),
},
false, "",
},
@@ -1262,9 +1261,9 @@ func TestCommit_ValidateBasic(t *testing.T) {
Height: 1,
Round: 1,
BlockID: BlockID{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
PartSetHeader: PartSetHeader{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
},
},
},
@@ -1276,9 +1275,9 @@ func TestCommit_ValidateBasic(t *testing.T) {
Height: 1,
Round: 1,
BlockID: BlockID{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
PartSetHeader: PartSetHeader{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
},
},
Signatures: []CommitSig{
@@ -1297,9 +1296,9 @@ func TestCommit_ValidateBasic(t *testing.T) {
Height: 1,
Round: 1,
BlockID: BlockID{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
PartSetHeader: PartSetHeader{
Hash: make([]byte, tmhash.Size),
Hash: make([]byte, crypto.HashSize),
},
},
Signatures: []CommitSig{
+2 -2
View File
@@ -4,13 +4,13 @@ import (
"reflect"
"testing"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/crypto"
tmrand "github.com/tendermint/tendermint/libs/rand"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
)
func TestCanonicalizeBlockID(t *testing.T) {
randhash := tmrand.Bytes(tmhash.Size)
randhash := tmrand.Bytes(crypto.HashSize)
block1 := tmproto.BlockID{Hash: randhash,
PartSetHeader: tmproto.PartSetHeader{Total: 5, Hash: randhash}}
block2 := tmproto.BlockID{Hash: randhash,
+28 -14
View File
@@ -12,8 +12,8 @@ import (
"time"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/merkle"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/internal/jsontypes"
tmmath "github.com/tendermint/tendermint/libs/math"
tmrand "github.com/tendermint/tendermint/libs/rand"
@@ -113,7 +113,7 @@ func (dve *DuplicateVoteEvidence) Bytes() []byte {
// Hash returns the hash of the evidence.
func (dve *DuplicateVoteEvidence) Hash() []byte {
return tmhash.Sum(dve.Bytes())
return crypto.Checksum(dve.Bytes())
}
// Height returns the height of the infraction
@@ -211,14 +211,28 @@ func DuplicateVoteEvidenceFromProto(pb *tmproto.DuplicateVoteEvidence) (*Duplica
return nil, errors.New("nil duplicate vote evidence")
}
vA, err := VoteFromProto(pb.VoteA)
if err != nil {
return nil, err
var vA *Vote
if pb.VoteA != nil {
var err error
vA, err = VoteFromProto(pb.VoteA)
if err != nil {
return nil, err
}
if err = vA.ValidateBasic(); err != nil {
return nil, err
}
}
vB, err := VoteFromProto(pb.VoteB)
if err != nil {
return nil, err
var vB *Vote
if pb.VoteB != nil {
var err error
vB, err = VoteFromProto(pb.VoteB)
if err != nil {
return nil, err
}
if err = vB.ValidateBasic(); err != nil {
return nil, err
}
}
dve := &DuplicateVoteEvidence{
@@ -360,10 +374,10 @@ func (l *LightClientAttackEvidence) ConflictingHeaderIsInvalid(trustedHeader *He
func (l *LightClientAttackEvidence) Hash() []byte {
buf := make([]byte, binary.MaxVarintLen64)
n := binary.PutVarint(buf, l.CommonHeight)
bz := make([]byte, tmhash.Size+n)
copy(bz[:tmhash.Size-1], l.ConflictingBlock.Hash().Bytes())
copy(bz[tmhash.Size:], buf)
return tmhash.Sum(bz)
bz := make([]byte, crypto.HashSize+n)
copy(bz[:crypto.HashSize-1], l.ConflictingBlock.Hash().Bytes())
copy(bz[crypto.HashSize:], buf)
return crypto.Checksum(bz)
}
// Height returns the last height at which the primary provider and witness provider had the same header.
@@ -829,10 +843,10 @@ func makeMockVote(height int64, round, index int32, addr Address,
func randBlockID() BlockID {
return BlockID{
Hash: tmrand.Bytes(tmhash.Size),
Hash: tmrand.Bytes(crypto.HashSize),
PartSetHeader: PartSetHeader{
Total: 1,
Hash: tmrand.Bytes(tmhash.Size),
Hash: tmrand.Bytes(crypto.HashSize),
},
}
}
+18 -19
View File
@@ -13,7 +13,6 @@ import (
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/crypto/tmhash"
tmrand "github.com/tendermint/tendermint/libs/rand"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/tendermint/tendermint/version"
@@ -93,15 +92,15 @@ func TestDuplicateVoteEvidence(t *testing.T) {
ev, err := NewMockDuplicateVoteEvidence(ctx, height, time.Now(), "mock-chain-id")
require.NoError(t, err)
assert.Equal(t, ev.Hash(), tmhash.Sum(ev.Bytes()))
assert.Equal(t, ev.Hash(), crypto.Checksum(ev.Bytes()))
assert.NotNil(t, ev.String())
assert.Equal(t, ev.Height(), height)
}
func TestDuplicateVoteEvidenceValidation(t *testing.T) {
val := NewMockPV()
blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt32, tmhash.Sum([]byte("partshash")))
blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt32, tmhash.Sum([]byte("partshash")))
blockID := makeBlockID(crypto.Checksum([]byte("blockhash")), math.MaxInt32, crypto.Checksum([]byte("partshash")))
blockID2 := makeBlockID(crypto.Checksum([]byte("blockhash2")), math.MaxInt32, crypto.Checksum([]byte("partshash")))
const chainID = "mychain"
ctx, cancel := context.WithCancel(context.Background())
@@ -153,7 +152,7 @@ func TestLightClientAttackEvidenceBasic(t *testing.T) {
header := makeHeaderRandom()
header.Height = height
blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt32, tmhash.Sum([]byte("partshash")))
blockID := makeBlockID(crypto.Checksum([]byte("blockhash")), math.MaxInt32, crypto.Checksum([]byte("partshash")))
commit, err := makeCommit(ctx, blockID, height, 1, voteSet, privVals, defaultVoteTime)
require.NoError(t, err)
lcae := &LightClientAttackEvidence{
@@ -217,7 +216,7 @@ func TestLightClientAttackEvidenceValidation(t *testing.T) {
header := makeHeaderRandom()
header.Height = height
header.ValidatorsHash = valSet.Hash()
blockID := makeBlockID(header.Hash(), math.MaxInt32, tmhash.Sum([]byte("partshash")))
blockID := makeBlockID(header.Hash(), math.MaxInt32, crypto.Checksum([]byte("partshash")))
commit, err := makeCommit(ctx, blockID, height, 1, voteSet, privVals, time.Now())
require.NoError(t, err)
lcae := &LightClientAttackEvidence{
@@ -332,14 +331,14 @@ func makeHeaderRandom() *Header {
Height: int64(mrand.Uint32() + 1),
Time: time.Now(),
LastBlockID: makeBlockIDRandom(),
LastCommitHash: crypto.CRandBytes(tmhash.Size),
DataHash: crypto.CRandBytes(tmhash.Size),
ValidatorsHash: crypto.CRandBytes(tmhash.Size),
NextValidatorsHash: crypto.CRandBytes(tmhash.Size),
ConsensusHash: crypto.CRandBytes(tmhash.Size),
AppHash: crypto.CRandBytes(tmhash.Size),
LastResultsHash: crypto.CRandBytes(tmhash.Size),
EvidenceHash: crypto.CRandBytes(tmhash.Size),
LastCommitHash: crypto.CRandBytes(crypto.HashSize),
DataHash: crypto.CRandBytes(crypto.HashSize),
ValidatorsHash: crypto.CRandBytes(crypto.HashSize),
NextValidatorsHash: crypto.CRandBytes(crypto.HashSize),
ConsensusHash: crypto.CRandBytes(crypto.HashSize),
AppHash: crypto.CRandBytes(crypto.HashSize),
LastResultsHash: crypto.CRandBytes(crypto.HashSize),
EvidenceHash: crypto.CRandBytes(crypto.HashSize),
ProposerAddress: crypto.CRandBytes(crypto.AddressSize),
}
}
@@ -350,8 +349,8 @@ func TestEvidenceProto(t *testing.T) {
// -------- Votes --------
val := NewMockPV()
blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt32, tmhash.Sum([]byte("partshash")))
blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt32, tmhash.Sum([]byte("partshash")))
blockID := makeBlockID(crypto.Checksum([]byte("blockhash")), math.MaxInt32, crypto.Checksum([]byte("partshash")))
blockID2 := makeBlockID(crypto.Checksum([]byte("blockhash2")), math.MaxInt32, crypto.Checksum([]byte("partshash")))
const chainID = "mychain"
v := makeVote(ctx, t, val, chainID, math.MaxInt32, math.MaxInt64, 1, 0x01, blockID, defaultVoteTime)
v2 := makeVote(ctx, t, val, chainID, math.MaxInt32, math.MaxInt64, 2, 0x01, blockID2, defaultVoteTime)
@@ -395,8 +394,8 @@ func TestEvidenceVectors(t *testing.T) {
// Votes for duplicateEvidence
val := NewMockPV()
val.PrivKey = ed25519.GenPrivKeyFromSecret([]byte("it's a secret")) // deterministic key
blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt32, tmhash.Sum([]byte("partshash")))
blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt32, tmhash.Sum([]byte("partshash")))
blockID := makeBlockID(crypto.Checksum([]byte("blockhash")), math.MaxInt32, crypto.Checksum([]byte("partshash")))
blockID2 := makeBlockID(crypto.Checksum([]byte("blockhash2")), math.MaxInt32, crypto.Checksum([]byte("partshash")))
const chainID = "mychain"
v := makeVote(ctx, t, val, chainID, math.MaxInt32, math.MaxInt64, 1, 0x01, blockID, defaultVoteTime)
v2 := makeVote(ctx, t, val, chainID, math.MaxInt32, math.MaxInt64, 2, 0x01, blockID2, defaultVoteTime)
@@ -424,7 +423,7 @@ func TestEvidenceVectors(t *testing.T) {
EvidenceHash: []byte("f2564c78071e26643ae9b3e2a19fa0dc10d4d9e873aa0be808660123f11a1e78"),
ProposerAddress: []byte("2915b7b15f979e48ebc61774bb1d86ba3136b7eb"),
}
blockID3 := makeBlockID(header.Hash(), math.MaxInt32, tmhash.Sum([]byte("partshash")))
blockID3 := makeBlockID(header.Hash(), math.MaxInt32, crypto.Checksum([]byte("partshash")))
commit, err := makeCommit(ctx, blockID3, height, 1, voteSet, privVals, defaultVoteTime)
require.NoError(t, err)
lcae := &LightClientAttackEvidence{
+10 -3
View File
@@ -96,9 +96,16 @@ func (pv MockPV) SignVote(ctx context.Context, chainID string, vote *tmproto.Vot
return err
}
vote.Signature = sig
extSig, err := pv.PrivKey.Sign(extSignBytes)
if err != nil {
return err
var extSig []byte
// We only sign vote extensions for precommits
if vote.Type == tmproto.PrecommitType {
extSig, err = pv.PrivKey.Sign(extSignBytes)
if err != nil {
return err
}
} else if len(vote.Extension) > 0 {
return errors.New("unexpected vote extension - vote extensions are only allowed in precommits")
}
vote.ExtensionSignature = extSig
return nil
+3 -3
View File
@@ -10,7 +10,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/internal/libs/protoio"
tmrand "github.com/tendermint/tendermint/libs/rand"
tmtime "github.com/tendermint/tendermint/libs/time"
@@ -61,7 +61,7 @@ func TestProposalVerifySignature(t *testing.T) {
prop := NewProposal(
4, 2, 2,
BlockID{tmrand.Bytes(tmhash.Size), PartSetHeader{777, tmrand.Bytes(tmhash.Size)}}, tmtime.Now())
BlockID{tmrand.Bytes(crypto.HashSize), PartSetHeader{777, tmrand.Bytes(crypto.HashSize)}}, tmtime.Now())
p := prop.ToProto()
signBytes := ProposalSignBytes("test_chain_id", p)
@@ -163,7 +163,7 @@ func TestProposalValidateBasic(t *testing.T) {
p.Signature = make([]byte, MaxSignatureSize+1)
}, true},
}
blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt32, tmhash.Sum([]byte("partshash")))
blockID := makeBlockID(crypto.Checksum([]byte("blockhash")), math.MaxInt32, crypto.Checksum([]byte("partshash")))
for _, tc := range testCases {
tc := tc
+2 -2
View File
@@ -8,8 +8,8 @@ import (
"sort"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/merkle"
"github.com/tendermint/tendermint/crypto/tmhash"
tmbytes "github.com/tendermint/tendermint/libs/bytes"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
)
@@ -23,7 +23,7 @@ type Tx []byte
func (tx Tx) Key() TxKey { return sha256.Sum256(tx) }
// Hash computes the TMHASH hash of the wire encoded transaction.
func (tx Tx) Hash() []byte { return tmhash.Sum(tx) }
func (tx Tx) Hash() []byte { return crypto.Checksum(tx) }
// String returns the hex-encoded transaction as a string.
func (tx Tx) String() string { return fmt.Sprintf("Tx{%X}", []byte(tx)) }
+4 -4
View File
@@ -4,8 +4,8 @@ import (
"errors"
"fmt"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/batch"
"github.com/tendermint/tendermint/crypto/tmhash"
tmmath "github.com/tendermint/tendermint/libs/math"
)
@@ -132,11 +132,11 @@ func VerifyCommitLightTrusting(chainID string, vals *ValidatorSet, commit *Commi
}
// ValidateHash returns an error if the hash is not empty, but its
// size != tmhash.Size.
// size != crypto.HashSize.
func ValidateHash(h []byte) error {
if len(h) > 0 && len(h) != tmhash.Size {
if len(h) > 0 && len(h) != crypto.HashSize {
return fmt.Errorf("expected size to be %d bytes, got %d bytes",
tmhash.Size,
crypto.HashSize,
len(h),
)
}
+90 -40
View File
@@ -61,6 +61,30 @@ type Vote struct {
ExtensionSignature []byte `json:"extension_signature"`
}
// VoteFromProto attempts to convert the given serialization (Protobuf) type to
// our Vote domain type. No validation is performed on the resulting vote -
// this is left up to the caller to decide whether to call ValidateBasic or
// ValidateWithExtension.
func VoteFromProto(pv *tmproto.Vote) (*Vote, error) {
blockID, err := BlockIDFromProto(&pv.BlockID)
if err != nil {
return nil, err
}
return &Vote{
Type: pv.Type,
Height: pv.Height,
Round: pv.Round,
BlockID: *blockID,
Timestamp: pv.Timestamp,
ValidatorAddress: pv.ValidatorAddress,
ValidatorIndex: pv.ValidatorIndex,
Signature: pv.Signature,
Extension: pv.Extension,
ExtensionSignature: pv.ExtensionSignature,
}, nil
}
// CommitSig converts the Vote to a CommitSig.
func (vote *Vote) CommitSig() CommitSig {
if vote == nil {
@@ -164,24 +188,49 @@ func (vote *Vote) String() string {
)
}
func (vote *Vote) Verify(chainID string, pubKey crypto.PubKey) error {
func (vote *Vote) verifyAndReturnProto(chainID string, pubKey crypto.PubKey) (*tmproto.Vote, error) {
if !bytes.Equal(pubKey.Address(), vote.ValidatorAddress) {
return ErrVoteInvalidValidatorAddress
return nil, ErrVoteInvalidValidatorAddress
}
v := vote.ToProto()
if !pubKey.VerifySignature(VoteSignBytes(chainID, v), vote.Signature) {
return ErrVoteInvalidSignature
return nil, ErrVoteInvalidSignature
}
extSignBytes := VoteExtensionSignBytes(chainID, v)
// TODO: Remove extension signature nil check to enforce vote extension
// signing once we resolve https://github.com/tendermint/tendermint/issues/8272
if vote.ExtensionSignature != nil && !pubKey.VerifySignature(extSignBytes, vote.ExtensionSignature) {
return ErrVoteInvalidSignature
return v, nil
}
// Verify checks whether the signature associated with this vote corresponds to
// the given chain ID and public key. This function does not validate vote
// extension signatures - to do so, use VerifyWithExtension instead.
func (vote *Vote) Verify(chainID string, pubKey crypto.PubKey) error {
_, err := vote.verifyAndReturnProto(chainID, pubKey)
return err
}
// VerifyWithExtension performs the same verification as Verify, but
// additionally checks whether the vote extension signature corresponds to the
// given chain ID and public key. We only verify vote extension signatures for
// precommits.
func (vote *Vote) VerifyWithExtension(chainID string, pubKey crypto.PubKey) error {
v, err := vote.verifyAndReturnProto(chainID, pubKey)
if err != nil {
return err
}
// We only verify vote extension signatures for precommits.
if vote.Type == tmproto.PrecommitType {
extSignBytes := VoteExtensionSignBytes(chainID, v)
// TODO: Remove extension signature nil check to enforce vote extension
// signing once we resolve https://github.com/tendermint/tendermint/issues/8272
if vote.ExtensionSignature != nil && !pubKey.VerifySignature(extSignBytes, vote.ExtensionSignature) {
return ErrVoteInvalidSignature
}
}
return nil
}
// ValidateBasic performs basic validation.
// ValidateBasic checks whether the vote is well-formed. It does not, however,
// check vote extensions - for vote validation with vote extension validation,
// use ValidateWithExtension.
func (vote *Vote) ValidateBasic() error {
if !IsVoteTypeValid(vote.Type) {
return errors.New("invalid Type")
@@ -224,10 +273,38 @@ func (vote *Vote) ValidateBasic() error {
return fmt.Errorf("signature is too big (max: %d)", MaxSignatureSize)
}
// TODO: Remove the extension length check such that we always require
// extension signatures to be present.
if len(vote.Extension) > 0 && len(vote.ExtensionSignature) == 0 {
return errors.New("vote extension signature is missing")
// We should only ever see vote extensions in precommits.
if vote.Type != tmproto.PrecommitType {
if len(vote.Extension) > 0 {
return errors.New("unexpected vote extension")
}
if len(vote.ExtensionSignature) > 0 {
return errors.New("unexpected vote extension signature")
}
}
return nil
}
// ValidateWithExtension performs the same validations as ValidateBasic, but
// additionally checks whether a vote extension signature is present. This
// function is used in places where vote extension signatures are expected.
func (vote *Vote) ValidateWithExtension() error {
if err := vote.ValidateBasic(); err != nil {
return err
}
// We should always see vote extension signatures in precommits
if vote.Type == tmproto.PrecommitType {
// TODO(thane): Remove extension length check once
// https://github.com/tendermint/tendermint/issues/8272 is
// resolved.
if len(vote.Extension) > 0 && len(vote.ExtensionSignature) == 0 {
return errors.New("vote extension signature is missing")
}
if len(vote.ExtensionSignature) > MaxSignatureSize {
return fmt.Errorf("vote extension signature is too big (max: %d)", MaxSignatureSize)
}
}
return nil
@@ -269,30 +346,3 @@ func VotesToProto(votes []*Vote) []*tmproto.Vote {
}
return res
}
// FromProto converts a proto generetad type to a handwritten type
// return type, nil if everything converts safely, otherwise nil, error
func VoteFromProto(pv *tmproto.Vote) (*Vote, error) {
if pv == nil {
return nil, errors.New("nil vote")
}
blockID, err := BlockIDFromProto(&pv.BlockID)
if err != nil {
return nil, err
}
vote := new(Vote)
vote.Type = pv.Type
vote.Height = pv.Height
vote.Round = pv.Round
vote.BlockID = *blockID
vote.Timestamp = pv.Timestamp
vote.ValidatorAddress = pv.ValidatorAddress
vote.ValidatorIndex = pv.ValidatorIndex
vote.Signature = pv.Signature
vote.Extension = pv.Extension
vote.ExtensionSignature = pv.ExtensionSignature
return vote, vote.ValidateBasic()
}
+1 -1
View File
@@ -194,7 +194,7 @@ func (voteSet *VoteSet) addVote(vote *Vote) (added bool, err error) {
}
// Check signature.
if err := vote.Verify(voteSet.chainID, val.PubKey); err != nil {
if err := vote.VerifyWithExtension(voteSet.chainID, val.PubKey); err != nil {
return false, fmt.Errorf("failed to verify vote with ChainID %s and PubKey %s: %w", voteSet.chainID, val.PubKey, err)
}
+126 -41
View File
@@ -11,7 +11,6 @@ import (
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/internal/libs/protoio"
tmtime "github.com/tendermint/tendermint/libs/time"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
@@ -24,7 +23,9 @@ func examplePrevote(t *testing.T) *Vote {
func examplePrecommit(t testing.TB) *Vote {
t.Helper()
return exampleVote(t, byte(tmproto.PrecommitType))
vote := exampleVote(t, byte(tmproto.PrecommitType))
vote.ExtensionSignature = []byte("signature")
return vote
}
func exampleVote(tb testing.TB, t byte) *Vote {
@@ -38,16 +39,17 @@ func exampleVote(tb testing.TB, t byte) *Vote {
Round: 2,
Timestamp: stamp,
BlockID: BlockID{
Hash: tmhash.Sum([]byte("blockID_hash")),
Hash: crypto.Checksum([]byte("blockID_hash")),
PartSetHeader: PartSetHeader{
Total: 1000000,
Hash: tmhash.Sum([]byte("blockID_part_set_header_hash")),
Hash: crypto.Checksum([]byte("blockID_part_set_header_hash")),
},
},
ValidatorAddress: crypto.AddressHash([]byte("validator_address")),
ValidatorIndex: 56789,
}
}
func TestVoteSignable(t *testing.T) {
vote := examplePrecommit(t)
v := vote.ToProto()
@@ -221,8 +223,8 @@ func TestVoteExtension(t *testing.T) {
includeSignature: true,
expectError: false,
},
// TODO: Re-enable once
// https://github.com/tendermint/tendermint/issues/8272 is resolved.
// TODO(thane): Re-enable once
// https://github.com/tendermint/tendermint/issues/8272 is resolved
//{
// name: "no extension signature",
// extension: []byte("extension"),
@@ -269,7 +271,7 @@ func TestVoteExtension(t *testing.T) {
if tc.includeSignature {
vote.ExtensionSignature = v.ExtensionSignature
}
err = vote.Verify("test_chain_id", pk)
err = vote.VerifyWithExtension("test_chain_id", pk)
if tc.expectError {
require.Error(t, err)
} else {
@@ -336,39 +338,115 @@ func TestVoteString(t *testing.T) {
}
}
func TestVoteValidateBasic(t *testing.T) {
func signVote(ctx context.Context, t *testing.T, pv PrivValidator, chainID string, vote *Vote) {
t.Helper()
v := vote.ToProto()
require.NoError(t, pv.SignVote(ctx, chainID, v))
vote.Signature = v.Signature
vote.ExtensionSignature = v.ExtensionSignature
}
func TestValidVotes(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
privVal := NewMockPV()
testCases := []struct {
testName string
name string
vote *Vote
malleateVote func(*Vote)
expectErr bool
}{
{"Good Vote", func(v *Vote) {}, false},
{"Negative Height", func(v *Vote) { v.Height = -1 }, true},
{"Negative Round", func(v *Vote) { v.Round = -1 }, true},
{"Invalid BlockID", func(v *Vote) {
v.BlockID = BlockID{[]byte{1, 2, 3}, PartSetHeader{111, []byte("blockparts")}}
}, true},
{"Invalid Address", func(v *Vote) { v.ValidatorAddress = make([]byte, 1) }, true},
{"Invalid ValidatorIndex", func(v *Vote) { v.ValidatorIndex = -1 }, true},
{"Invalid Signature", func(v *Vote) { v.Signature = nil }, true},
{"Too big Signature", func(v *Vote) { v.Signature = make([]byte, MaxSignatureSize+1) }, true},
{"good prevote", examplePrevote(t), func(v *Vote) {}},
{"good precommit without vote extension", examplePrecommit(t), func(v *Vote) { v.Extension = nil }},
{"good precommit with vote extension", examplePrecommit(t), func(v *Vote) { v.Extension = []byte("extension") }},
}
for _, tc := range testCases {
tc := tc
t.Run(tc.testName, func(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
signVote(ctx, t, privVal, "test_chain_id", tc.vote)
tc.malleateVote(tc.vote)
require.NoError(t, tc.vote.ValidateBasic(), "ValidateBasic for %s", tc.name)
require.NoError(t, tc.vote.ValidateWithExtension(), "ValidateWithExtension for %s", tc.name)
}
}
vote := examplePrecommit(t)
v := vote.ToProto()
err := privVal.SignVote(ctx, "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")
})
func TestInvalidVotes(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
privVal := NewMockPV()
testCases := []struct {
name string
malleateVote func(*Vote)
}{
{"negative height", func(v *Vote) { v.Height = -1 }},
{"negative round", func(v *Vote) { v.Round = -1 }},
{"invalid block ID", func(v *Vote) { v.BlockID = BlockID{[]byte{1, 2, 3}, PartSetHeader{111, []byte("blockparts")}} }},
{"invalid address", func(v *Vote) { v.ValidatorAddress = make([]byte, 1) }},
{"invalid validator index", func(v *Vote) { v.ValidatorIndex = -1 }},
{"invalid signature", func(v *Vote) { v.Signature = nil }},
{"oversized signature", func(v *Vote) { v.Signature = make([]byte, MaxSignatureSize+1) }},
}
for _, tc := range testCases {
prevote := examplePrevote(t)
signVote(ctx, t, privVal, "test_chain_id", prevote)
tc.malleateVote(prevote)
require.Error(t, prevote.ValidateBasic(), "ValidateBasic for %s in invalid prevote", tc.name)
require.Error(t, prevote.ValidateWithExtension(), "ValidateWithExtension for %s in invalid prevote", tc.name)
precommit := examplePrecommit(t)
signVote(ctx, t, privVal, "test_chain_id", precommit)
tc.malleateVote(precommit)
require.Error(t, precommit.ValidateBasic(), "ValidateBasic for %s in invalid precommit", tc.name)
require.Error(t, precommit.ValidateWithExtension(), "ValidateWithExtension for %s in invalid precommit", tc.name)
}
}
func TestInvalidPrevotes(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
privVal := NewMockPV()
testCases := []struct {
name string
malleateVote func(*Vote)
}{
{"vote extension present", func(v *Vote) { v.Extension = []byte("extension") }},
{"vote extension signature present", func(v *Vote) { v.ExtensionSignature = []byte("signature") }},
}
for _, tc := range testCases {
prevote := examplePrevote(t)
signVote(ctx, t, privVal, "test_chain_id", prevote)
tc.malleateVote(prevote)
require.Error(t, prevote.ValidateBasic(), "ValidateBasic for %s", tc.name)
require.Error(t, prevote.ValidateWithExtension(), "ValidateWithExtension for %s", tc.name)
}
}
func TestInvalidPrecommitExtensions(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
privVal := NewMockPV()
testCases := []struct {
name string
malleateVote func(*Vote)
}{
{"vote extension present without signature", func(v *Vote) {
v.Extension = []byte("extension")
v.ExtensionSignature = nil
}},
// TODO(thane): Re-enable once https://github.com/tendermint/tendermint/issues/8272 is resolved
//{"missing vote extension signature", func(v *Vote) { v.ExtensionSignature = nil }},
{"oversized vote extension signature", func(v *Vote) { v.ExtensionSignature = make([]byte, MaxSignatureSize+1) }},
}
for _, tc := range testCases {
precommit := examplePrecommit(t)
signVote(ctx, t, privVal, "test_chain_id", precommit)
tc.malleateVote(precommit)
// We don't expect an error from ValidateBasic, because it doesn't
// handle vote extensions.
require.NoError(t, precommit.ValidateBasic(), "ValidateBasic for %s", tc.name)
require.Error(t, precommit.ValidateWithExtension(), "ValidateWithExtension for %s", tc.name)
}
}
@@ -384,21 +462,28 @@ func TestVoteProtobuf(t *testing.T) {
require.NoError(t, err)
testCases := []struct {
msg string
v1 *Vote
expPass bool
msg string
vote *Vote
convertsOk bool
passesValidateBasic bool
}{
{"success", vote, true},
{"fail vote validate basic", &Vote{}, false},
{"failure nil", nil, false},
{"success", vote, true, true},
{"fail vote validate basic", &Vote{}, true, false},
}
for _, tc := range testCases {
protoProposal := tc.v1.ToProto()
protoProposal := tc.vote.ToProto()
v, err := VoteFromProto(protoProposal)
if tc.expPass {
if tc.convertsOk {
require.NoError(t, err)
require.Equal(t, tc.v1, v, tc.msg)
} else {
require.Error(t, err)
}
err = v.ValidateBasic()
if tc.passesValidateBasic {
require.NoError(t, err)
require.Equal(t, tc.vote, v, tc.msg)
} else {
require.Error(t, err)
}