From 1e4faac4f6dd19647fae4c87030d72571fa0cb0a Mon Sep 17 00:00:00 2001
From: lklimek <842586+lklimek@users.noreply.github.com>
Date: Thu, 10 Nov 2022 16:38:21 +0100
Subject: [PATCH] feat!: include state id in block signature (#478)
* chore: remove state id signature - main code building
* chore(bytes): improve fixed-len serialization
* test: update unit tests after state id refactor
* fix(types): block ID of nil-block is nil
* test(e2e) fix single tests after state id refactor
* chore: state id refactor - self-review
* refactor!: AppHash size MUST be 32 bytes
* chore(types): stateID.AppVersion equals to Header.Version.App
* doc: Document StateID encoding
* chore(types): block ID IsNil should check StateID
* refactor(types): change stateid.apphash to [32]byte
* chore: move state ID to CanonicalVote and replace block id with hash of block id in CanonicalVote
* fix(proto/types): correct handling of nil blockid in CanonicalVote
* doc(consensus): update block/vote signing&verification
* doc(core): revert fixed-length encoding info
* chore: refactor after review feedback - WIP (tests don't build)
* chore: minor fixes after state id refactor
* test: update tests for state ID (except vectors / sizes)
* chore: restore state ID hash in BlockID to not increase the block size
* test: fix tests after state id refactor
* chore: fix conflicts after merge 0.10-dev
* doc(consensus): update vote/block signing with state id
* refactor(types): remove unused QuorumSingsVerifier.shouldVerifyState
* chore: fix typo
* chore: make linter happy
* refactor: move panic() from RoundState.BlockID() to Block.BlockID()
* chore: minor code style changes
* fix(e2e): ensure trusted light block already exists
---
abci/client/doc.go | 8 +-
abci/example/kvstore/kvstore.go | 2 +-
abci/server/server.go | 5 +-
abci/types/application.go | 3 +-
abci/types/types.go | 2 +-
abci/types/types.pb.go | 553 ++++++---------
config/config.go | 13 +-
config/toml.go | 3 -
crypto/crypto.go | 4 +-
crypto/merkle/doc.go | 25 +-
crypto/merkle/tree.go | 8 +-
crypto/secp256k1/secp256k1.go | 6 +-
dash/quorum/validator_conn_executor_test.go | 2 +-
docs/tendermint-core/state-id.md | 62 --
internal/blocksync/pool.go | 1 +
internal/blocksync/reactor.go | 9 +-
internal/blocksync/reactor_test.go | 17 +-
internal/consensus/byzantine_test.go | 14 +-
internal/consensus/common_test.go | 14 +-
internal/consensus/helper_test.go | 3 +-
internal/consensus/invalid_test.go | 6 +-
internal/consensus/msgs_test.go | 11 +-
internal/consensus/pbts_test.go | 7 +-
internal/consensus/reactor.go | 4 +-
internal/consensus/replay_test.go | 13 +-
internal/consensus/replayer.go | 7 +-
internal/consensus/state.go | 76 +--
internal/consensus/state_test.go | 194 ++----
.../consensus/types/height_vote_set_test.go | 13 +-
internal/consensus/types/round_state.go | 19 +-
internal/consensus/wal_test.go | 16 +-
internal/evidence/doc.go | 7 +-
internal/evidence/pool.go | 10 +-
internal/evidence/pool_test.go | 6 +-
internal/evidence/verify.go | 8 +-
internal/evidence/verify_test.go | 49 +-
internal/inspect/doc.go | 22 +-
internal/jsontypes/jsontypes.go | 8 +-
internal/libs/clist/clist.go | 2 -
internal/libs/flowrate/flowrate.go | 8 +-
internal/p2p/channel.go | 9 +-
internal/p2p/conn/connection.go | 3 +-
internal/p2p/peermanager.go | 46 +-
internal/p2p/router.go | 32 +-
internal/pubsub/pubsub.go | 41 +-
internal/pubsub/query/query.go | 4 +-
internal/pubsub/query/query_test.go | 4 +-
internal/pubsub/query/syntax/doc.go | 39 +-
internal/rpc/core/env.go | 2 +-
internal/state/current_round_state.go | 14 -
internal/state/execution.go | 22 +-
internal/state/execution_test.go | 34 +-
internal/state/helpers_test.go | 12 +-
internal/state/rollback.go | 2 -
internal/state/rollback_test.go | 2 -
internal/state/state.go | 20 -
internal/state/state_test.go | 29 +-
internal/state/test/factory/block.go | 4 +-
internal/state/tx_filter.go | 8 +-
internal/state/tx_filter_test.go | 39 +-
internal/state/validation.go | 2 +-
internal/state/validation_test.go | 24 +-
internal/statesync/reactor_test.go | 20 +-
internal/statesync/stateprovider.go | 2 -
internal/store/store_test.go | 23 +-
internal/test/factory/block.go | 1 +
internal/test/factory/commit.go | 5 +-
internal/test/factory/vote.go | 6 +-
libs/bytes/bytes.go | 4 +
libs/bytes/marshal.go | 135 ++++
libs/bytes/marshal_test.go | 120 ++++
light/client.go | 68 +-
light/client_test.go | 18 +-
light/detector.go | 4 +-
light/doc.go | 50 +-
light/helpers_test.go | 28 +-
light/provider/http/http.go | 2 +-
light/rpc/client.go | 1 +
node/node_test.go | 20 +-
node/setup.go | 1 -
privval/dash_core_signer_client.go | 28 +-
privval/doc.go | 10 +-
privval/file.go | 48 +-
privval/file_test.go | 67 +-
privval/grpc/client.go | 5 +-
privval/grpc/client_test.go | 31 +-
privval/grpc/server.go | 6 +-
privval/grpc/server_test.go | 56 +-
privval/msgs_test.go | 21 +-
privval/retry_signer_client.go | 4 +-
privval/signer_client.go | 4 -
privval/signer_client_test.go | 134 ++--
privval/signer_requestHandler.go | 18 +-
proto/tendermint/abci/types.proto | 2 -
proto/tendermint/privval/types.pb.go | 194 ++----
proto/tendermint/privval/types.proto | 9 +-
proto/tendermint/state/types.pb.go | 169 ++---
proto/tendermint/state/types.proto | 2 -
proto/tendermint/types/canonical.go | 24 +
proto/tendermint/types/canonical.pb.go | 249 ++++---
proto/tendermint/types/canonical.proto | 18 +-
proto/tendermint/types/types.go | 166 +++++
proto/tendermint/types/types.pb.go | 638 ++++++++----------
proto/tendermint/types/types.proto | 30 +-
proto/tendermint/types/types_test.go | 167 +++++
rpc/client/evidence_test.go | 29 +-
rpc/client/examples_test.go | 6 +-
rpc/client/http/http.go | 36 +-
rpc/client/mock/client.go | 1 -
rpc/jsonrpc/doc.go | 65 +-
rpc/jsonrpc/server/rpc_func.go | 8 +-
rpc/jsonrpc/types/types.go | 1 -
scripts/keymigrate/migrate.go | 2 +-
scripts/metricsgen/metricsgen_test.go | 8 +-
spec/abci++/api.md | 4 +-
spec/consensus/signing.md | 114 +++-
spec/core/encoding.md | 2 +-
test/e2e/node/config.go | 2 +-
test/e2e/pkg/mockcoreserver/expect.go | 10 +-
test/e2e/pkg/mockcoreserver/server.go | 6 +-
test/e2e/pkg/mockcoreserver/server_test.go | 4 +-
test/e2e/runner/evidence.go | 24 +-
test/e2e/runner/setup.go | 5 +-
test/e2e/tests/block_test.go | 4 +-
types/block.go | 213 +++---
types/block_meta.go | 4 +-
types/block_meta_test.go | 12 +-
types/block_test.go | 500 +++++++-------
types/canonical.go | 37 +-
types/canonical_test.go | 29 +-
types/evidence.go | 17 +-
types/evidence_test.go | 87 ++-
types/genesis.go | 8 +-
types/genesis_test.go | 4 +-
types/light.go | 17 +-
types/light_test.go | 114 ++--
types/part_set.go | 6 -
types/priv_validator.go | 14 +-
types/proposal_test.go | 57 +-
types/quorum.go | 33 -
types/quorum_sign_data.go | 19 +-
types/quorum_sign_data_test.go | 40 +-
types/signs_recoverer.go | 14 -
types/signs_recoverer_test.go | 13 +-
types/stateid.go | 160 -----
types/test_util.go | 25 +-
types/utils.go | 6 +-
types/validation.go | 11 +-
types/validation_test.go | 64 +-
types/validator_address.go | 2 +-
types/validator_set.go | 9 +-
types/validator_set_test.go | 8 +-
types/vote.go | 79 +--
types/vote_dash.go | 2 -
types/vote_extension.go | 13 +
types/vote_set.go | 30 +-
types/vote_set_test.go | 121 +---
types/vote_test.go | 347 +++++-----
158 files changed, 3261 insertions(+), 3425 deletions(-)
delete mode 100644 docs/tendermint-core/state-id.md
create mode 100644 libs/bytes/marshal.go
create mode 100644 libs/bytes/marshal_test.go
create mode 100644 proto/tendermint/types/canonical.go
create mode 100644 proto/tendermint/types/types_test.go
delete mode 100644 types/stateid.go
diff --git a/abci/client/doc.go b/abci/client/doc.go
index 5bb3bf58a9..e933554439 100644
--- a/abci/client/doc.go
+++ b/abci/client/doc.go
@@ -1,9 +1,9 @@
// Package abciclient provides an ABCI implementation in Go.
//
// There are 3 clients available:
-// 1. socket (unix or TCP)
-// 2. local (in memory)
-// 3. gRPC
+// 1. socket (unix or TCP)
+// 2. local (in memory)
+// 3. gRPC
//
// ## Socket client
//
@@ -12,7 +12,7 @@
//
// ## Local client
//
-// The global mutex is locked during each call
+// # The global mutex is locked during each call
//
// ## gRPC client
//
diff --git a/abci/example/kvstore/kvstore.go b/abci/example/kvstore/kvstore.go
index 1c55c29e53..ded10c0bbb 100644
--- a/abci/example/kvstore/kvstore.go
+++ b/abci/example/kvstore/kvstore.go
@@ -25,7 +25,7 @@ import (
"github.com/tendermint/tendermint/version"
)
-const ProtocolVersion uint64 = 0x1
+const ProtocolVersion uint64 = 0x12345678
//---------------------------------------------------
diff --git a/abci/server/server.go b/abci/server/server.go
index 0e0173ca65..0e731d404d 100644
--- a/abci/server/server.go
+++ b/abci/server/server.go
@@ -2,9 +2,8 @@
Package server is used to start a new ABCI server.
It contains two server implementation:
- * gRPC server
- * socket server
-
+ - gRPC server
+ - socket server
*/
package server
diff --git a/abci/types/application.go b/abci/types/application.go
index a9e0d44f8f..f42f185eb1 100644
--- a/abci/types/application.go
+++ b/abci/types/application.go
@@ -6,9 +6,10 @@ import (
"github.com/tendermint/tendermint/crypto"
)
-//go:generate ../../scripts/mockery_generate.sh Application
// Application is an interface that enables any finite, deterministic state machine
// to be driven by a blockchain-based replication engine via the ABCI.
+//
+//go:generate ../../scripts/mockery_generate.sh Application
type Application interface {
// Info/Query Connection
Info(context.Context, *RequestInfo) (*ResponseInfo, error) // Return application info
diff --git a/abci/types/types.go b/abci/types/types.go
index e716006450..ed297d18cd 100644
--- a/abci/types/types.go
+++ b/abci/types/types.go
@@ -276,7 +276,7 @@ func (m *ResponsePrepareProposal) Validate() error {
}
func isValidApphash(apphash tmbytes.HexBytes) bool {
- return len(apphash) >= crypto.SmallAppHashSize && len(apphash) <= crypto.LargeAppHashSize
+ return len(apphash) == crypto.DefaultAppHashSize
}
func (r ResponseProcessProposal) Validate() error {
diff --git a/abci/types/types.pb.go b/abci/types/types.pb.go
index 5dbfcc1112..3648497f5f 100644
--- a/abci/types/types.pb.go
+++ b/abci/types/types.pb.go
@@ -3000,7 +3000,6 @@ type CommitInfo struct {
Round int32 `protobuf:"varint,1,opt,name=round,proto3" json:"round,omitempty"`
QuorumHash []byte `protobuf:"bytes,3,opt,name=quorum_hash,json=quorumHash,proto3" json:"quorum_hash,omitempty"`
BlockSignature []byte `protobuf:"bytes,4,opt,name=block_signature,json=blockSignature,proto3" json:"block_signature,omitempty"`
- StateSignature []byte `protobuf:"bytes,5,opt,name=state_signature,json=stateSignature,proto3" json:"state_signature,omitempty"`
ThresholdVoteExtensions []*types1.VoteExtension `protobuf:"bytes,6,rep,name=threshold_vote_extensions,json=thresholdVoteExtensions,proto3" json:"threshold_vote_extensions,omitempty"`
}
@@ -3058,13 +3057,6 @@ func (m *CommitInfo) GetBlockSignature() []byte {
return nil
}
-func (m *CommitInfo) GetStateSignature() []byte {
- if m != nil {
- return m.StateSignature
- }
- return nil
-}
-
func (m *CommitInfo) GetThresholdVoteExtensions() []*types1.VoteExtension {
if m != nil {
return m.ThresholdVoteExtensions
@@ -3082,7 +3074,6 @@ type ExtendedCommitInfo struct {
// information, including vote extensions.
QuorumHash []byte `protobuf:"bytes,3,opt,name=quorum_hash,json=quorumHash,proto3" json:"quorum_hash,omitempty"`
BlockSignature []byte `protobuf:"bytes,4,opt,name=block_signature,json=blockSignature,proto3" json:"block_signature,omitempty"`
- StateSignature []byte `protobuf:"bytes,5,opt,name=state_signature,json=stateSignature,proto3" json:"state_signature,omitempty"`
ThresholdVoteExtensions []*types1.VoteExtension `protobuf:"bytes,6,rep,name=threshold_vote_extensions,json=thresholdVoteExtensions,proto3" json:"threshold_vote_extensions,omitempty"`
}
@@ -3140,13 +3131,6 @@ func (m *ExtendedCommitInfo) GetBlockSignature() []byte {
return nil
}
-func (m *ExtendedCommitInfo) GetStateSignature() []byte {
- if m != nil {
- return m.StateSignature
- }
- return nil
-}
-
func (m *ExtendedCommitInfo) GetThresholdVoteExtensions() []*types1.VoteExtension {
if m != nil {
return m.ThresholdVoteExtensions
@@ -4114,232 +4098,231 @@ func init() {
func init() { proto.RegisterFile("tendermint/abci/types.proto", fileDescriptor_252557cfdd89a31a) }
var fileDescriptor_252557cfdd89a31a = []byte{
- // 3585 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5b, 0x4b, 0x70, 0x23, 0xd5,
- 0xd5, 0x56, 0x4b, 0xb2, 0x1e, 0x47, 0xaf, 0xf6, 0xb5, 0x67, 0x46, 0xa3, 0x99, 0xb1, 0x4d, 0xcf,
- 0x0f, 0x33, 0x0c, 0x60, 0xc3, 0xcc, 0x0f, 0x03, 0x3f, 0xfc, 0xff, 0x5f, 0xb2, 0xac, 0x89, 0xec,
+ // 3572 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5b, 0xcb, 0x73, 0x23, 0xd5,
+ 0xd5, 0x57, 0x4b, 0xb2, 0x1e, 0x47, 0xaf, 0xf6, 0xb5, 0x67, 0x46, 0xa3, 0x99, 0xb1, 0x4d, 0xcf,
+ 0x07, 0x33, 0x0c, 0x60, 0xc3, 0xcc, 0x07, 0x03, 0x1f, 0x7c, 0xdf, 0x57, 0xb2, 0xac, 0x89, 0xec,
0xf1, 0xd8, 0xa6, 0x2d, 0x9b, 0x22, 0x04, 0x9a, 0xb6, 0x74, 0x2d, 0x35, 0x23, 0xa9, 0x9b, 0xee,
0x96, 0x91, 0xd9, 0x26, 0x64, 0xc1, 0x8a, 0x5d, 0xb2, 0x21, 0xbb, 0x2c, 0xb3, 0xc9, 0x32, 0xa9,
- 0xca, 0x36, 0x2c, 0x59, 0x92, 0x05, 0x84, 0x62, 0x36, 0xa9, 0x2c, 0xb3, 0x49, 0x55, 0x16, 0xa9,
- 0xd4, 0x7d, 0xf4, 0x4b, 0x52, 0xeb, 0x31, 0xa4, 0x92, 0x0a, 0xc9, 0x4e, 0xf7, 0xdc, 0x73, 0x4e,
- 0xdf, 0xc7, 0xb9, 0xe7, 0x9c, 0xfb, 0x9d, 0x2b, 0xb8, 0x62, 0xe3, 0x5e, 0x13, 0x9b, 0x5d, 0xad,
- 0x67, 0x6f, 0xa8, 0x27, 0x0d, 0x6d, 0xc3, 0x3e, 0x37, 0xb0, 0xb5, 0x6e, 0x98, 0xba, 0xad, 0xa3,
- 0x82, 0xd7, 0xb9, 0x4e, 0x3a, 0x4b, 0xd7, 0x7c, 0xdc, 0x0d, 0xf3, 0xdc, 0xb0, 0xf5, 0x0d, 0xc3,
- 0xd4, 0xf5, 0x53, 0xc6, 0x5f, 0xf2, 0x2b, 0xa3, 0x7a, 0x36, 0x9a, 0xaa, 0xd5, 0xe6, 0x9d, 0x57,
- 0x47, 0x65, 0x1f, 0xe2, 0x73, 0xfe, 0xa9, 0x80, 0x66, 0x26, 0x6a, 0xa8, 0xa6, 0xda, 0x75, 0xba,
- 0x57, 0x7c, 0xdd, 0x67, 0xd8, 0xb4, 0x34, 0xbd, 0xe7, 0x1f, 0x69, 0x69, 0xb5, 0xa5, 0xeb, 0xad,
- 0x0e, 0xde, 0xa0, 0xad, 0x93, 0xfe, 0xe9, 0x86, 0xad, 0x75, 0xb1, 0x65, 0xab, 0x5d, 0x83, 0x33,
- 0x2c, 0xb7, 0xf4, 0x96, 0x4e, 0x7f, 0x6e, 0x90, 0x5f, 0x8c, 0x2a, 0x7d, 0x94, 0x86, 0xa4, 0x8c,
- 0xdf, 0xef, 0x63, 0xcb, 0x46, 0xb7, 0x21, 0x8e, 0x1b, 0x6d, 0xbd, 0x28, 0xac, 0x09, 0x37, 0x33,
- 0xb7, 0xaf, 0xae, 0x0f, 0xcd, 0x7d, 0x9d, 0xf3, 0x55, 0x1b, 0x6d, 0xbd, 0x16, 0x91, 0x29, 0x2f,
- 0x7a, 0x11, 0x16, 0x4e, 0x3b, 0x7d, 0xab, 0x5d, 0x8c, 0x52, 0xa1, 0x6b, 0x61, 0x42, 0xf7, 0x08,
- 0x53, 0x2d, 0x22, 0x33, 0x6e, 0xf2, 0x29, 0xad, 0x77, 0xaa, 0x17, 0x63, 0x93, 0x3f, 0xb5, 0xdd,
- 0x3b, 0xa5, 0x9f, 0x22, 0xbc, 0x68, 0x13, 0x40, 0xeb, 0x69, 0xb6, 0xd2, 0x68, 0xab, 0x5a, 0xaf,
- 0x18, 0xa7, 0x92, 0x4f, 0x84, 0x4b, 0x6a, 0x76, 0x85, 0x30, 0xd6, 0x22, 0x72, 0x5a, 0x73, 0x1a,
- 0x64, 0xb8, 0xef, 0xf7, 0xb1, 0x79, 0x5e, 0x5c, 0x98, 0x3c, 0xdc, 0xd7, 0x09, 0x13, 0x19, 0x2e,
- 0xe5, 0x46, 0xaf, 0x41, 0xaa, 0xd1, 0xc6, 0x8d, 0x87, 0x8a, 0x3d, 0x28, 0x26, 0xa9, 0xe4, 0x6a,
- 0x98, 0x64, 0x85, 0xf0, 0xd5, 0x07, 0xb5, 0x88, 0x9c, 0x6c, 0xb0, 0x9f, 0x68, 0x0f, 0xf2, 0x1d,
- 0xcd, 0xb2, 0x15, 0xab, 0xa7, 0x1a, 0x56, 0x5b, 0xb7, 0xad, 0x62, 0x86, 0xea, 0x78, 0x32, 0x4c,
- 0xc7, 0xae, 0x66, 0xd9, 0x87, 0x0e, 0x73, 0x2d, 0x22, 0xe7, 0x3a, 0x7e, 0x02, 0xd1, 0xa7, 0x9f,
- 0x9e, 0x62, 0xd3, 0x55, 0x58, 0xcc, 0x4e, 0xd6, 0xb7, 0x4f, 0xb8, 0x1d, 0x79, 0xa2, 0x4f, 0xf7,
- 0x13, 0xd0, 0x5b, 0xb0, 0xd4, 0xd1, 0xd5, 0xa6, 0xab, 0x4e, 0x69, 0xb4, 0xfb, 0xbd, 0x87, 0xc5,
- 0x1c, 0x55, 0xfa, 0x74, 0xe8, 0x20, 0x75, 0xb5, 0xe9, 0xa8, 0xa8, 0x10, 0x81, 0x5a, 0x44, 0x5e,
- 0xec, 0x0c, 0x13, 0xd1, 0x3b, 0xb0, 0xac, 0x1a, 0x46, 0xe7, 0x7c, 0x58, 0x7b, 0x9e, 0x6a, 0xbf,
- 0x15, 0xa6, 0xbd, 0x4c, 0x64, 0x86, 0xd5, 0x23, 0x75, 0x84, 0x8a, 0xea, 0x20, 0x1a, 0x26, 0x36,
- 0x54, 0x13, 0x2b, 0x86, 0xa9, 0x1b, 0xba, 0xa5, 0x76, 0x8a, 0x05, 0xaa, 0xfb, 0x46, 0x98, 0xee,
- 0x03, 0xc6, 0x7f, 0xc0, 0xd9, 0x6b, 0x11, 0xb9, 0x60, 0x04, 0x49, 0x4c, 0xab, 0xde, 0xc0, 0x96,
- 0xe5, 0x69, 0x15, 0xa7, 0x69, 0xa5, 0xfc, 0x41, 0xad, 0x01, 0x12, 0xaa, 0x42, 0x06, 0x0f, 0x88,
- 0xb8, 0x72, 0xa6, 0xdb, 0xb8, 0xb8, 0x48, 0x15, 0x4a, 0xa1, 0xe7, 0x8c, 0xb2, 0x1e, 0xeb, 0x36,
- 0xae, 0x45, 0x64, 0xc0, 0x6e, 0x0b, 0xa9, 0x70, 0xe1, 0x0c, 0x9b, 0xda, 0xe9, 0x39, 0x55, 0xa3,
- 0xd0, 0x1e, 0xe2, 0x0f, 0x8a, 0x88, 0x2a, 0x7c, 0x26, 0x4c, 0xe1, 0x31, 0x15, 0x22, 0x2a, 0xaa,
- 0x8e, 0x48, 0x2d, 0x22, 0x2f, 0x9d, 0x8d, 0x92, 0x89, 0x89, 0x9d, 0x6a, 0x3d, 0xb5, 0xa3, 0x7d,
- 0x88, 0x95, 0x93, 0x8e, 0xde, 0x78, 0x58, 0x5c, 0x9a, 0x6c, 0x62, 0xf7, 0x38, 0xf7, 0x26, 0x61,
- 0x26, 0x26, 0x76, 0xea, 0x27, 0x6c, 0x26, 0x61, 0xe1, 0x4c, 0xed, 0xf4, 0xf1, 0x4e, 0x3c, 0x95,
- 0x10, 0x93, 0x3b, 0xf1, 0x54, 0x4a, 0x4c, 0xef, 0xc4, 0x53, 0x69, 0x11, 0x76, 0xe2, 0x29, 0x10,
- 0x33, 0xd2, 0x0d, 0xc8, 0xf8, 0xdc, 0x0b, 0x2a, 0x42, 0xb2, 0x8b, 0x2d, 0x4b, 0x6d, 0x61, 0xea,
- 0x8d, 0xd2, 0xb2, 0xd3, 0x94, 0xf2, 0x90, 0xf5, 0xbb, 0x14, 0xe9, 0x13, 0xc1, 0x95, 0x24, 0xde,
- 0x82, 0x48, 0x72, 0xf7, 0xe8, 0x48, 0xf2, 0x26, 0xba, 0x0e, 0x39, 0x3a, 0x15, 0xc5, 0xe9, 0x27,
- 0x2e, 0x2b, 0x2e, 0x67, 0x29, 0xf1, 0x98, 0x33, 0xad, 0x42, 0xc6, 0xb8, 0x6d, 0xb8, 0x2c, 0x31,
- 0xca, 0x02, 0xc6, 0x6d, 0xc3, 0x61, 0x78, 0x02, 0xb2, 0x64, 0xde, 0x2e, 0x47, 0x9c, 0x7e, 0x24,
- 0x43, 0x68, 0x9c, 0x45, 0xfa, 0x51, 0x0c, 0xc4, 0x61, 0x37, 0x84, 0x5e, 0x86, 0x38, 0xf1, 0xc8,
- 0xdc, 0xb9, 0x96, 0xd6, 0x99, 0xbb, 0x5e, 0x77, 0xdc, 0xf5, 0x7a, 0xdd, 0x71, 0xd7, 0x9b, 0xa9,
- 0xcf, 0xbe, 0x5a, 0x8d, 0x7c, 0xf2, 0xfb, 0x55, 0x41, 0xa6, 0x12, 0xe8, 0x32, 0x71, 0x3e, 0xaa,
- 0xd6, 0x53, 0xb4, 0x26, 0x1d, 0x72, 0x9a, 0x78, 0x16, 0x55, 0xeb, 0x6d, 0x37, 0xd1, 0x2e, 0x88,
- 0x0d, 0xbd, 0x67, 0xe1, 0x9e, 0xd5, 0xb7, 0x14, 0x16, 0x2e, 0xb8, 0x4b, 0x0d, 0x38, 0x46, 0x16,
- 0x27, 0x2a, 0x0e, 0xe7, 0x01, 0x65, 0x94, 0x0b, 0x8d, 0x20, 0x01, 0xed, 0x41, 0xee, 0x4c, 0xed,
- 0x68, 0x4d, 0xd5, 0xd6, 0x4d, 0xc5, 0xc2, 0x36, 0xf7, 0xb1, 0xd7, 0x47, 0xf6, 0xfc, 0xd8, 0xe1,
- 0x3a, 0xc4, 0xf6, 0x91, 0xd1, 0x54, 0x6d, 0xbc, 0x19, 0xff, 0xec, 0xab, 0x55, 0x41, 0xce, 0x9e,
- 0xf9, 0x7a, 0xd0, 0x53, 0x50, 0x50, 0x0d, 0x43, 0xb1, 0x6c, 0xd5, 0xc6, 0xca, 0xc9, 0xb9, 0x8d,
- 0x2d, 0xea, 0x76, 0xb3, 0x72, 0x4e, 0x35, 0x8c, 0x43, 0x42, 0xdd, 0x24, 0x44, 0xf4, 0x24, 0xe4,
- 0x89, 0x87, 0xd6, 0xd4, 0x8e, 0xd2, 0xc6, 0x5a, 0xab, 0x6d, 0x17, 0x13, 0x6b, 0xc2, 0xcd, 0x98,
- 0x9c, 0xe3, 0xd4, 0x1a, 0x25, 0xa2, 0x75, 0x58, 0x72, 0xd8, 0x1a, 0xba, 0x89, 0x1d, 0x5e, 0xe2,
- 0x8f, 0x73, 0xf2, 0x22, 0xef, 0xaa, 0xe8, 0x26, 0x66, 0xfc, 0x52, 0xd3, 0xb5, 0x14, 0xea, 0xcd,
- 0x11, 0x82, 0x78, 0x53, 0xb5, 0x55, 0xba, 0x03, 0x59, 0x99, 0xfe, 0x26, 0x34, 0x43, 0xb5, 0xdb,
- 0x7c, 0x5d, 0xe9, 0x6f, 0x74, 0x11, 0x12, 0x5c, 0x75, 0x8c, 0x0e, 0x83, 0xb7, 0xd0, 0x32, 0x2c,
- 0x18, 0xa6, 0x7e, 0x86, 0xe9, 0xb2, 0xa4, 0x64, 0xd6, 0x90, 0x64, 0xc8, 0x07, 0x3d, 0x3f, 0xca,
- 0x43, 0xd4, 0x1e, 0xf0, 0xaf, 0x44, 0xed, 0x01, 0x7a, 0x1e, 0xe2, 0x64, 0x03, 0xe8, 0x37, 0xf2,
- 0x63, 0x62, 0x1d, 0x97, 0xab, 0x9f, 0x1b, 0x58, 0xa6, 0x9c, 0xd2, 0x45, 0x58, 0x1e, 0x17, 0x09,
- 0xa4, 0xb6, 0x4b, 0x0f, 0x78, 0x74, 0xf4, 0x22, 0xa4, 0xdc, 0x50, 0xc0, 0xec, 0xeb, 0xf2, 0xc8,
- 0x57, 0x1c, 0x66, 0xd9, 0x65, 0x25, 0x86, 0x45, 0xf6, 0xa7, 0xad, 0xf2, 0xf0, 0x9d, 0x95, 0x93,
- 0xaa, 0x61, 0xd4, 0x54, 0xab, 0x2d, 0xbd, 0x0b, 0xc5, 0x30, 0x37, 0xef, 0x5b, 0x1f, 0x81, 0x9e,
- 0x0e, 0x67, 0x7d, 0x2e, 0x42, 0xe2, 0x54, 0x37, 0xbb, 0xaa, 0x4d, 0x95, 0xe5, 0x64, 0xde, 0x22,
- 0xeb, 0xc6, 0x5c, 0x7e, 0x8c, 0x92, 0x59, 0x43, 0x52, 0xe0, 0x72, 0xa8, 0xab, 0x27, 0x22, 0x5a,
- 0xaf, 0x89, 0xd9, 0x2a, 0xe6, 0x64, 0xd6, 0xf0, 0x14, 0xb1, 0xc1, 0xb2, 0x06, 0xf9, 0xac, 0x45,
- 0xe7, 0x4a, 0xf5, 0xa7, 0x65, 0xde, 0x92, 0xbe, 0x88, 0xc3, 0xc5, 0xf1, 0x0e, 0x1f, 0xad, 0x41,
- 0xb6, 0xab, 0x0e, 0x14, 0x7b, 0xc0, 0xad, 0x52, 0xa0, 0xfb, 0x0c, 0x5d, 0x75, 0x50, 0x1f, 0x30,
- 0x93, 0x14, 0x21, 0x66, 0x0f, 0xac, 0x62, 0x74, 0x2d, 0x76, 0x33, 0x2b, 0x93, 0x9f, 0xe8, 0x08,
- 0x16, 0x3b, 0x7a, 0x43, 0xed, 0x28, 0x1d, 0xd5, 0xb2, 0x95, 0x86, 0xde, 0xed, 0x6a, 0x36, 0x3f,
- 0x6b, 0xa3, 0x07, 0x84, 0xb9, 0x6e, 0xdc, 0xac, 0x50, 0x36, 0xe2, 0x97, 0xe8, 0x01, 0x89, 0xc8,
- 0x05, 0xaa, 0x63, 0x57, 0xb5, 0x6c, 0xd6, 0x85, 0xb6, 0x20, 0xd3, 0xd5, 0xac, 0x13, 0xdc, 0x56,
- 0xcf, 0x34, 0xdd, 0x2c, 0xc6, 0xd7, 0x62, 0x63, 0xf3, 0xa1, 0x07, 0x1e, 0x0f, 0xd7, 0xe4, 0x17,
- 0xf3, 0x6d, 0xc9, 0x42, 0xc0, 0x64, 0x1d, 0xa7, 0x93, 0x98, 0xdb, 0xe9, 0x3c, 0x0f, 0xcb, 0x3d,
- 0x3c, 0xb0, 0x15, 0xf7, 0x40, 0x5b, 0xcc, 0x4e, 0x92, 0x74, 0xe9, 0x11, 0xe9, 0x73, 0xbd, 0x80,
- 0x45, 0x4c, 0x86, 0xec, 0x8e, 0xa9, 0xf7, 0x7b, 0xcd, 0x62, 0x6a, 0x4d, 0xb8, 0xb9, 0x20, 0xb3,
- 0x06, 0xba, 0x0b, 0x45, 0x7a, 0x58, 0x99, 0x07, 0x23, 0x9e, 0x16, 0x37, 0x9d, 0x93, 0xdb, 0xa4,
- 0x9b, 0x7b, 0x81, 0xf4, 0x53, 0x1f, 0xb9, 0x4b, 0x7b, 0xf9, 0x69, 0xdf, 0x80, 0x65, 0x16, 0x79,
- 0xb1, 0x49, 0x42, 0x30, 0xd9, 0x2c, 0x3a, 0x00, 0x4c, 0x07, 0xb0, 0xe8, 0xf4, 0x1d, 0x98, 0x7a,
- 0x7d, 0x40, 0xbf, 0xff, 0xbc, 0x2b, 0xd0, 0x54, 0x88, 0x59, 0x3b, 0x0e, 0xfa, 0x94, 0x1a, 0x29,
- 0x72, 0xfa, 0xca, 0x86, 0xeb, 0xca, 0xef, 0x7a, 0xa1, 0xa2, 0x35, 0x9a, 0x0e, 0xf2, 0x2e, 0xcf,
- 0x6d, 0xba, 0x91, 0x44, 0xfa, 0xd9, 0x82, 0xcf, 0xb4, 0x82, 0x21, 0x9e, 0x1b, 0x8e, 0xe0, 0x19,
- 0xce, 0xa1, 0x6f, 0x5c, 0x7e, 0xdb, 0x61, 0x09, 0xf3, 0x95, 0x51, 0x77, 0x30, 0x6c, 0x33, 0xee,
- 0xd0, 0xc3, 0xcd, 0x26, 0xf6, 0x78, 0x66, 0x83, 0x20, 0x4e, 0xd7, 0x34, 0xce, 0x3c, 0x22, 0xf9,
- 0x1d, 0x6a, 0x4a, 0xe3, 0xb7, 0xf7, 0x1f, 0x69, 0x60, 0xdf, 0x45, 0x53, 0x42, 0x75, 0xb8, 0x38,
- 0x34, 0x29, 0xa5, 0x4f, 0x23, 0x6a, 0xb1, 0x3d, 0x7a, 0xcf, 0x70, 0xe2, 0xb8, 0x6f, 0x92, 0xf2,
- 0x52, 0x60, 0xce, 0x2c, 0x1a, 0x4b, 0x47, 0xb0, 0x38, 0x92, 0x44, 0xba, 0xbb, 0x2d, 0x8c, 0xdd,
- 0xed, 0xe8, 0xf8, 0xdd, 0x8e, 0xf9, 0x76, 0x5b, 0xfa, 0x5a, 0x80, 0x52, 0x78, 0x2e, 0x39, 0xf6,
- 0x03, 0x2f, 0xc0, 0x05, 0x2f, 0xa7, 0xf0, 0x2f, 0x3e, 0xf3, 0xe1, 0xc8, 0xed, 0xf4, 0x56, 0x7f,
- 0x42, 0xfc, 0x65, 0x63, 0x8a, 0xfb, 0x2d, 0xf0, 0x01, 0x14, 0x82, 0x59, 0x30, 0x49, 0x32, 0xc8,
- 0x69, 0xf8, 0xaf, 0x10, 0xaf, 0x1c, 0x18, 0xb3, 0x9c, 0x3f, 0xf3, 0x37, 0x2d, 0xe9, 0xb7, 0x71,
- 0x37, 0xc6, 0x06, 0x52, 0xda, 0x31, 0x07, 0xfb, 0x15, 0x48, 0xcc, 0x7b, 0x94, 0xb9, 0xc0, 0x7f,
- 0x8e, 0xef, 0x77, 0xe5, 0xf8, 0xfa, 0x53, 0xa8, 0x76, 0x30, 0x85, 0xfa, 0x5d, 0x1a, 0x52, 0x32,
- 0xb6, 0x0c, 0x22, 0x84, 0x36, 0x21, 0x8d, 0x07, 0x0d, 0x6c, 0xd8, 0xce, 0xbd, 0x64, 0xfc, 0xbd,
- 0x8f, 0x71, 0x57, 0x1d, 0xce, 0x5a, 0x44, 0xf6, 0xc4, 0xd0, 0x1d, 0x0e, 0xcf, 0x84, 0x23, 0x2d,
- 0x5c, 0xdc, 0x8f, 0xcf, 0xbc, 0xe4, 0xe0, 0x33, 0x2c, 0x55, 0x59, 0x09, 0x95, 0x1a, 0x02, 0x68,
- 0xee, 0x70, 0x80, 0x26, 0x3e, 0xe5, 0x63, 0x01, 0x84, 0xa6, 0x12, 0x40, 0x68, 0x16, 0xa6, 0x4c,
- 0x33, 0x04, 0xa2, 0x79, 0xc9, 0x81, 0x68, 0x12, 0x53, 0x46, 0x3c, 0x84, 0xd1, 0xfc, 0xaf, 0x0f,
- 0xa3, 0x49, 0x51, 0xd1, 0xb5, 0x50, 0xd1, 0x31, 0x20, 0xcd, 0xfe, 0x08, 0x48, 0xc3, 0x40, 0x95,
- 0xa7, 0x42, 0x95, 0x4c, 0x41, 0x69, 0xf6, 0x47, 0x50, 0x9a, 0xdc, 0x14, 0x85, 0x53, 0x60, 0x9a,
- 0x1f, 0x8c, 0x87, 0x69, 0xc2, 0x81, 0x14, 0x3e, 0xcc, 0xd9, 0x70, 0x1a, 0x25, 0x04, 0xa7, 0x29,
- 0x84, 0x62, 0x0a, 0x4c, 0xfd, 0xcc, 0x40, 0xcd, 0xd1, 0x18, 0xa0, 0x86, 0x41, 0x2a, 0x37, 0x43,
- 0x95, 0xcf, 0x80, 0xd4, 0x1c, 0x8d, 0x41, 0x6a, 0x16, 0xa7, 0xaa, 0x9d, 0x0a, 0xd5, 0xdc, 0x0b,
- 0x42, 0x35, 0x28, 0x24, 0xd1, 0xf7, 0x8e, 0x6c, 0x08, 0x56, 0x73, 0x12, 0x86, 0xd5, 0x30, 0x3c,
- 0xe5, 0xd9, 0x50, 0x8d, 0x73, 0x80, 0x35, 0xfb, 0x23, 0x60, 0xcd, 0xf2, 0x14, 0x4b, 0x9b, 0x1d,
- 0xad, 0x49, 0x8a, 0x29, 0x3f, 0x4e, 0xb3, 0x13, 0x4f, 0x65, 0xc4, 0xac, 0xf4, 0x34, 0xc9, 0x2f,
- 0x86, 0x9c, 0x15, 0x09, 0x31, 0xd8, 0x34, 0x75, 0x93, 0xe3, 0x2e, 0xac, 0x21, 0xdd, 0x24, 0xb7,
- 0x70, 0xcf, 0x31, 0x4d, 0x40, 0x76, 0x0a, 0x90, 0x0b, 0x38, 0x23, 0xe9, 0x4b, 0xc1, 0x93, 0xa5,
- 0xd8, 0x8e, 0xff, 0x06, 0x9f, 0xe6, 0x37, 0x78, 0x1f, 0xde, 0x13, 0x0d, 0xe2, 0x3d, 0xab, 0x90,
- 0xf1, 0x7b, 0x7f, 0x0e, 0xe5, 0xa8, 0x9e, 0xd7, 0xbf, 0x05, 0x8b, 0x34, 0x21, 0x67, 0xa8, 0x10,
- 0x0f, 0x45, 0x71, 0x1a, 0x36, 0x0b, 0xa4, 0x83, 0xad, 0x0e, 0x0b, 0x42, 0xcf, 0xc1, 0x92, 0x8f,
- 0xd7, 0xf5, 0xf9, 0x0c, 0xcf, 0x10, 0x5d, 0xee, 0x32, 0x73, 0xfe, 0x3b, 0xf1, 0x54, 0x53, 0xc4,
- 0xf2, 0x35, 0x9e, 0xef, 0x8f, 0x8f, 0x7a, 0xd2, 0x1f, 0xa2, 0xde, 0x32, 0x7a, 0x40, 0xd1, 0x38,
- 0x4c, 0x47, 0x78, 0x6c, 0x4c, 0xc7, 0x1f, 0xa0, 0x62, 0x81, 0x00, 0x85, 0xde, 0x82, 0xe5, 0x00,
- 0xdc, 0xe3, 0x24, 0x9e, 0xcd, 0xf9, 0x50, 0x9f, 0x88, 0x2f, 0x89, 0x73, 0x7b, 0xd0, 0xdb, 0x70,
- 0x85, 0xe6, 0x07, 0x21, 0xc9, 0x2d, 0x9e, 0x2d, 0xb9, 0xbd, 0x44, 0x74, 0x54, 0x46, 0x13, 0xdc,
- 0x30, 0x2c, 0xe8, 0x34, 0x0c, 0x0b, 0xfa, 0xb3, 0xe0, 0x19, 0x97, 0x8b, 0x06, 0x35, 0xf4, 0x26,
- 0xe6, 0x08, 0x03, 0xfd, 0x4d, 0x72, 0xbc, 0x8e, 0xde, 0xe2, 0x38, 0x02, 0xf9, 0x49, 0xb8, 0xdc,
- 0x30, 0x98, 0xe6, 0x51, 0xce, 0x05, 0x27, 0x58, 0x86, 0xc5, 0xc1, 0x09, 0x11, 0x62, 0x0f, 0x31,
- 0x0b, 0x5a, 0x59, 0x99, 0xfc, 0x24, 0x7c, 0xf4, 0x14, 0xf1, 0x9c, 0x88, 0x35, 0xd0, 0xcb, 0x90,
- 0xa6, 0x05, 0x23, 0x45, 0x37, 0x2c, 0x1e, 0xa7, 0x02, 0x89, 0x23, 0x2b, 0x0c, 0xad, 0x1f, 0x10,
- 0x9e, 0x7d, 0xc3, 0x92, 0x53, 0x06, 0xff, 0xe5, 0x4b, 0xed, 0xd2, 0x81, 0xd4, 0xee, 0x2a, 0xa4,
- 0xc9, 0xe8, 0x2d, 0x43, 0x6d, 0xe0, 0x22, 0xd0, 0x81, 0x7a, 0x04, 0xe9, 0x91, 0x00, 0x85, 0xa1,
- 0xb0, 0x37, 0x76, 0xee, 0xce, 0xd9, 0x8a, 0x06, 0xd1, 0xb1, 0x91, 0xd9, 0x5f, 0x03, 0x68, 0xa9,
- 0x96, 0xf2, 0x81, 0xda, 0xb3, 0x71, 0x93, 0x2f, 0x41, 0xba, 0xa5, 0x5a, 0x6f, 0x50, 0x42, 0x70,
- 0x30, 0xa9, 0xa1, 0xc1, 0xf8, 0xb0, 0x9a, 0xb4, 0x1f, 0xab, 0x41, 0x25, 0x48, 0x19, 0xa6, 0xa6,
- 0x9b, 0x9a, 0x7d, 0x4e, 0x67, 0x10, 0x93, 0xdd, 0x36, 0xba, 0x0e, 0xb9, 0x2e, 0xee, 0x1a, 0xba,
- 0xde, 0x51, 0x98, 0x7b, 0xc9, 0x50, 0xd1, 0x2c, 0x27, 0x56, 0xa9, 0x97, 0x39, 0x80, 0x0b, 0x63,
- 0xc3, 0x32, 0xba, 0x0b, 0x69, 0x2f, 0xa2, 0x0b, 0x34, 0xcf, 0x9e, 0x80, 0x8d, 0x79, 0xbc, 0xd2,
- 0x6f, 0x04, 0x4f, 0x65, 0x10, 0x6d, 0xab, 0x42, 0xc2, 0xc4, 0x56, 0xbf, 0xc3, 0xf0, 0xaf, 0xfc,
- 0xed, 0xe7, 0x66, 0x0b, 0xe8, 0x84, 0xda, 0xef, 0xd8, 0x32, 0x17, 0x96, 0xde, 0x81, 0x04, 0xa3,
- 0xa0, 0x0c, 0x24, 0x8f, 0xf6, 0xee, 0xef, 0xed, 0xbf, 0xb1, 0x27, 0x46, 0x10, 0x40, 0xa2, 0x5c,
- 0xa9, 0x54, 0x0f, 0xea, 0xa2, 0x80, 0xd2, 0xb0, 0x50, 0xde, 0xdc, 0x97, 0xeb, 0x62, 0x94, 0x90,
- 0xe5, 0xea, 0x4e, 0xb5, 0x52, 0x17, 0x63, 0x68, 0x11, 0x72, 0xec, 0xb7, 0x72, 0x6f, 0x5f, 0x7e,
- 0x50, 0xae, 0x8b, 0x71, 0x1f, 0xe9, 0xb0, 0xba, 0xb7, 0x55, 0x95, 0xc5, 0x05, 0xe9, 0x05, 0xb8,
- 0x1c, 0x9a, 0x02, 0x78, 0x50, 0x9a, 0xe0, 0x83, 0xd2, 0xa4, 0x9f, 0x46, 0xc9, 0xfd, 0x2e, 0x2c,
- 0xae, 0xa3, 0x9d, 0xa1, 0x89, 0xdf, 0x9e, 0x23, 0x29, 0x18, 0x9a, 0x3d, 0x7a, 0x12, 0xf2, 0x26,
- 0x3e, 0xc5, 0x76, 0xa3, 0xcd, 0xf2, 0x0c, 0x86, 0xb5, 0xe5, 0xe4, 0x1c, 0xa7, 0x52, 0x21, 0x8b,
- 0xb1, 0xbd, 0x87, 0x1b, 0xb6, 0xc2, 0x2c, 0xc5, 0xa2, 0x77, 0xa5, 0x34, 0x61, 0x23, 0xd4, 0x43,
- 0x46, 0x94, 0xde, 0x9d, 0x6b, 0x2d, 0xd3, 0xb0, 0x20, 0x57, 0xeb, 0xf2, 0x9b, 0x62, 0x0c, 0x21,
- 0xc8, 0xd3, 0x9f, 0xca, 0xe1, 0x5e, 0xf9, 0xe0, 0xb0, 0xb6, 0x4f, 0xd6, 0x72, 0x09, 0x0a, 0xce,
- 0x5a, 0x3a, 0xc4, 0x05, 0xe9, 0x57, 0x31, 0xb8, 0x14, 0x92, 0x95, 0xa0, 0x97, 0x01, 0xec, 0x81,
- 0x62, 0xe2, 0x86, 0x6e, 0x36, 0xc3, 0x8d, 0xac, 0x3e, 0x90, 0x29, 0x87, 0x9c, 0xb6, 0xf9, 0x2f,
- 0x6b, 0x02, 0x02, 0x8b, 0x5e, 0xe3, 0x4a, 0xc9, 0xac, 0x2c, 0x7e, 0x43, 0xbc, 0x36, 0xe6, 0x4a,
- 0x8b, 0x1b, 0x44, 0x31, 0x5d, 0x5b, 0xaa, 0x98, 0xf2, 0xa3, 0x37, 0xe1, 0xd2, 0x50, 0x10, 0xe1,
- 0x9e, 0xd7, 0xe2, 0x69, 0xf9, 0x0c, 0xb1, 0xe4, 0x42, 0x30, 0x96, 0x30, 0xcf, 0x6b, 0x4d, 0x40,
- 0x2c, 0x9a, 0x8f, 0x8f, 0x58, 0x84, 0x06, 0x23, 0x3c, 0x6f, 0x09, 0x62, 0x4c, 0x30, 0x92, 0x7e,
- 0x19, 0xd8, 0xbc, 0x60, 0xa2, 0xb7, 0x0f, 0x09, 0xcb, 0x56, 0xed, 0xbe, 0xc5, 0x8d, 0xfa, 0xee,
- 0xac, 0x59, 0xe3, 0xba, 0xf3, 0xe3, 0x90, 0x8a, 0xcb, 0x5c, 0xcd, 0xbf, 0xe4, 0x9e, 0xfe, 0x9d,
- 0x52, 0x81, 0xf1, 0xab, 0xff, 0x22, 0xe4, 0x83, 0x4b, 0x15, 0x7e, 0x48, 0x3d, 0x2f, 0x17, 0x95,
- 0x3a, 0xb0, 0x34, 0x06, 0xb0, 0x41, 0x77, 0x79, 0x35, 0x85, 0xed, 0xd6, 0xf5, 0xd1, 0x29, 0x07,
- 0xd8, 0xbd, 0xa2, 0x0a, 0x89, 0x4c, 0x5e, 0xf6, 0xcd, 0x36, 0xc6, 0x23, 0x48, 0x0d, 0x40, 0xa3,
- 0xb9, 0xfc, 0x38, 0x70, 0x49, 0xf8, 0x16, 0xe0, 0xd2, 0xcf, 0x05, 0xb8, 0x32, 0x21, 0xbf, 0x47,
- 0xaf, 0x0f, 0xd9, 0xe2, 0x2b, 0xf3, 0xdc, 0x0e, 0xd6, 0x19, 0x2d, 0x68, 0x8d, 0xd2, 0x1d, 0xc8,
- 0xfa, 0xe9, 0xb3, 0x2d, 0xfd, 0x8f, 0x7d, 0xb1, 0x2f, 0x88, 0x82, 0xd5, 0x20, 0x81, 0xcf, 0x70,
- 0xcf, 0x8d, 0xa5, 0x17, 0x47, 0xd7, 0x81, 0x74, 0x6f, 0x16, 0x49, 0x62, 0xf8, 0xc7, 0xaf, 0x56,
- 0x45, 0xc6, 0xfd, 0xac, 0xde, 0xd5, 0x6c, 0xdc, 0x35, 0xec, 0x73, 0x99, 0xcb, 0x93, 0xb0, 0x6e,
- 0x62, 0x9b, 0xb8, 0x90, 0x40, 0xcd, 0x2f, 0xcb, 0x88, 0x3c, 0x6d, 0xfb, 0x93, 0x00, 0xe0, 0x81,
- 0x68, 0x1e, 0x88, 0x25, 0xf8, 0x41, 0xac, 0x55, 0xc8, 0xbc, 0xdf, 0xd7, 0xcd, 0x7e, 0xd7, 0x9f,
- 0xe5, 0x02, 0x23, 0xd1, 0x63, 0x77, 0x03, 0x0a, 0x2c, 0x6d, 0xb7, 0xb4, 0x56, 0x4f, 0xb5, 0xfb,
- 0x26, 0xe6, 0x90, 0x59, 0x9e, 0x92, 0x0f, 0x1d, 0x2a, 0x61, 0x64, 0xc5, 0x4a, 0x8f, 0x91, 0x25,
- 0xf8, 0x79, 0x4a, 0xf6, 0x18, 0xdf, 0x82, 0xcb, 0x76, 0xdb, 0xc4, 0x56, 0x5b, 0xef, 0x34, 0x95,
- 0x61, 0x0b, 0x49, 0xd0, 0x95, 0x59, 0x9d, 0x62, 0x99, 0xf2, 0x25, 0x57, 0xc3, 0x71, 0xd0, 0x4a,
- 0xfe, 0x22, 0x00, 0x1a, 0x2d, 0x20, 0xfd, 0x9b, 0x4c, 0xfe, 0x43, 0x58, 0xa0, 0x16, 0x44, 0x72,
- 0x4f, 0xf7, 0x9c, 0xa7, 0xf9, 0x11, 0x7e, 0x1b, 0x40, 0xb5, 0x6d, 0x53, 0x3b, 0xe9, 0x13, 0xa7,
- 0x17, 0x1d, 0xfd, 0x94, 0x67, 0x81, 0x65, 0x87, 0x6f, 0xf3, 0x2a, 0x37, 0xc5, 0x65, 0x4f, 0xd4,
- 0x67, 0x8e, 0x3e, 0x85, 0xd2, 0x1e, 0xe4, 0x83, 0xb2, 0x4e, 0x52, 0xcf, 0xc6, 0x10, 0x4c, 0xea,
- 0xd9, 0x65, 0x93, 0x27, 0xf5, 0xee, 0x95, 0x20, 0xc6, 0x4a, 0xc3, 0xb4, 0x21, 0xfd, 0x55, 0x80,
- 0xac, 0xdf, 0x99, 0xcf, 0x9c, 0x77, 0xcf, 0x76, 0x0f, 0x99, 0x92, 0x89, 0x5f, 0x86, 0x14, 0xe9,
- 0xee, 0x5b, 0xb8, 0xc9, 0xcf, 0x56, 0xb2, 0xa5, 0x5a, 0x47, 0x16, 0x6e, 0xfa, 0x4e, 0x71, 0xf2,
- 0x5b, 0x9e, 0xe2, 0x89, 0xe9, 0xbe, 0xf4, 0x91, 0x00, 0x29, 0x77, 0xf2, 0xc1, 0xb2, 0x71, 0x00,
- 0x99, 0x66, 0x6b, 0x17, 0xf5, 0xd7, 0x7a, 0x59, 0x11, 0x3d, 0xe6, 0x16, 0xd1, 0x5f, 0x75, 0x73,
- 0xcf, 0x30, 0x44, 0xd2, 0xbf, 0xd2, 0x0e, 0xdc, 0xce, 0x53, 0xed, 0x9f, 0xf0, 0x71, 0x90, 0xa4,
- 0x0b, 0xfd, 0x0f, 0x24, 0xd4, 0x86, 0x8b, 0xc3, 0xe6, 0xc7, 0x00, 0x94, 0x0e, 0xeb, 0x7a, 0x7d,
- 0x50, 0xa6, 0x9c, 0x32, 0x97, 0xe0, 0xa3, 0x8a, 0x3a, 0xa3, 0x92, 0xfe, 0x9f, 0xe8, 0x65, 0x3c,
- 0x41, 0xcf, 0x9a, 0x07, 0x38, 0xda, 0x7b, 0xb0, 0xbf, 0xb5, 0x7d, 0x6f, 0xbb, 0xba, 0xc5, 0xb3,
- 0xcf, 0xad, 0xad, 0xea, 0x96, 0x18, 0x25, 0x7c, 0x72, 0xf5, 0xc1, 0xfe, 0x71, 0x75, 0x4b, 0x8c,
- 0x49, 0x65, 0x48, 0xbb, 0xb1, 0x94, 0x3e, 0x30, 0xd0, 0x3f, 0xe0, 0x85, 0xec, 0x98, 0xcc, 0x1a,
- 0x68, 0x05, 0x32, 0x7e, 0xd4, 0x9b, 0x1d, 0x5e, 0x72, 0x87, 0x64, 0x68, 0xb7, 0xf4, 0x0b, 0x01,
- 0x0a, 0xae, 0x0e, 0x9e, 0x4d, 0xbd, 0x0a, 0x49, 0xa3, 0x7f, 0xa2, 0x38, 0xb6, 0x3b, 0x54, 0x5b,
- 0x70, 0xae, 0x98, 0xfd, 0x93, 0x8e, 0xd6, 0xb8, 0x8f, 0xcf, 0x79, 0xec, 0x4e, 0x18, 0xfd, 0x93,
- 0xfb, 0xcc, 0xc4, 0xd9, 0x30, 0xa2, 0x13, 0x86, 0x11, 0x1b, 0x1a, 0x06, 0xba, 0x01, 0xd9, 0x9e,
- 0xde, 0xc4, 0x8a, 0xda, 0x6c, 0x9a, 0xd8, 0xb2, 0x98, 0xa5, 0x72, 0xcd, 0x19, 0xd2, 0x53, 0x66,
- 0x1d, 0xd2, 0xd7, 0x02, 0xa0, 0xd1, 0xfc, 0x01, 0x1d, 0xc2, 0xa2, 0x97, 0x82, 0x38, 0x79, 0x0d,
- 0x0b, 0x32, 0x6b, 0xe1, 0xf9, 0x47, 0x00, 0x87, 0x10, 0xcf, 0x82, 0x64, 0x92, 0xab, 0x2e, 0x7b,
- 0xae, 0xca, 0xa0, 0xf3, 0xa5, 0x8b, 0x12, 0x9d, 0x71, 0x51, 0x22, 0x32, 0x72, 0xe5, 0xdd, 0x9e,
- 0xa9, 0x3e, 0x57, 0x32, 0xa0, 0x58, 0x1f, 0x11, 0xe3, 0xf3, 0x0c, 0x1b, 0x92, 0xf0, 0x6d, 0x86,
- 0x24, 0xdd, 0x01, 0xf1, 0x75, 0xf7, 0xfb, 0xfc, 0x4b, 0x43, 0xc3, 0x14, 0x46, 0x86, 0x79, 0x06,
- 0x29, 0xe2, 0x7d, 0x69, 0x74, 0xf9, 0x3f, 0x48, 0xbb, 0xab, 0xe7, 0xbe, 0x51, 0x0a, 0x5d, 0x76,
- 0x3e, 0x12, 0x4f, 0x04, 0xdd, 0x82, 0x45, 0x12, 0x37, 0x9c, 0x1a, 0x37, 0x83, 0x21, 0xa3, 0xd4,
- 0x1b, 0x16, 0x58, 0xc7, 0xae, 0x83, 0x91, 0x91, 0x34, 0x48, 0x74, 0x02, 0xdc, 0x3f, 0x63, 0x00,
- 0xe4, 0x56, 0x39, 0x84, 0xc6, 0xb2, 0x3d, 0xcc, 0x05, 0xf2, 0x35, 0xe9, 0x87, 0x51, 0xc8, 0xf8,
- 0x4a, 0x70, 0xe8, 0xbf, 0x03, 0xa9, 0xe7, 0xda, 0xa4, 0x72, 0x9d, 0x2f, 0xef, 0x0c, 0x4c, 0x2c,
- 0x3a, 0xff, 0xc4, 0xc2, 0xca, 0xa1, 0x4e, 0xed, 0x2e, 0x3e, 0x77, 0xed, 0xee, 0x59, 0x40, 0xb6,
- 0x6e, 0xab, 0x1d, 0x12, 0xbc, 0xb5, 0x5e, 0x4b, 0x61, 0xa7, 0x9d, 0x05, 0x10, 0x91, 0xf6, 0x1c,
- 0xd3, 0x8e, 0x03, 0x42, 0x97, 0x7e, 0x2d, 0x40, 0xca, 0xc5, 0x3e, 0xe6, 0x7d, 0xfb, 0x73, 0x11,
- 0x12, 0xfc, 0x7a, 0xcf, 0x1e, 0xff, 0xf0, 0xd6, 0xd8, 0xd2, 0x65, 0x09, 0x52, 0x5d, 0x6c, 0xab,
- 0x34, 0x1a, 0xb2, 0xcc, 0xc3, 0x6d, 0x3f, 0x76, 0xf1, 0xf0, 0xd6, 0x2b, 0x90, 0xf1, 0xbd, 0xaf,
- 0x22, 0x91, 0x75, 0xaf, 0xfa, 0x86, 0x18, 0x29, 0x25, 0x3f, 0xfe, 0x74, 0x2d, 0xb6, 0x87, 0x3f,
- 0x40, 0x45, 0xe2, 0x8e, 0x2b, 0xb5, 0x6a, 0xe5, 0xbe, 0x28, 0x94, 0x32, 0x1f, 0x7f, 0xba, 0x96,
- 0x94, 0x31, 0xad, 0x09, 0xdd, 0xba, 0x0f, 0x85, 0xa1, 0x1d, 0x0d, 0xfa, 0x78, 0x04, 0xf9, 0xad,
- 0xa3, 0x83, 0xdd, 0xed, 0x4a, 0xb9, 0x5e, 0x55, 0x8e, 0xf7, 0xeb, 0x55, 0x51, 0x40, 0x97, 0x60,
- 0x69, 0x77, 0xfb, 0x7b, 0xb5, 0xba, 0x52, 0xd9, 0xdd, 0xae, 0xee, 0xd5, 0x95, 0x72, 0xbd, 0x5e,
- 0xae, 0xdc, 0x17, 0xa3, 0xb7, 0xbf, 0x04, 0x28, 0x94, 0x37, 0x2b, 0xdb, 0x65, 0xc3, 0xe8, 0x68,
- 0x0d, 0x95, 0x46, 0x8c, 0x0a, 0xc4, 0x29, 0x24, 0x3e, 0xf1, 0xa5, 0x75, 0x69, 0x72, 0xa1, 0x0f,
- 0xdd, 0x83, 0x05, 0x8a, 0x96, 0xa3, 0xc9, 0x4f, 0xaf, 0x4b, 0x53, 0x2a, 0x7f, 0x64, 0x30, 0xf4,
- 0x1c, 0x4e, 0x7c, 0x8b, 0x5d, 0x9a, 0x5c, 0x08, 0x44, 0xbb, 0x90, 0x74, 0x30, 0xc6, 0x69, 0x0f,
- 0xa4, 0x4b, 0x53, 0xab, 0x73, 0x64, 0x6a, 0x0c, 0xab, 0x9d, 0xfc, 0x4c, 0xbb, 0x34, 0xa5, 0x44,
- 0x88, 0x64, 0x48, 0x7b, 0xf0, 0xfa, 0xf4, 0x17, 0xe3, 0xa5, 0x19, 0x4a, 0x96, 0xe8, 0x1d, 0xc8,
- 0x05, 0x81, 0xc6, 0xd9, 0x1e, 0x73, 0x97, 0x66, 0x2c, 0x27, 0x12, 0xfd, 0x41, 0xd4, 0x71, 0xb6,
- 0xc7, 0xdd, 0xa5, 0x19, 0xab, 0x8b, 0xe8, 0x3d, 0x58, 0x1c, 0x45, 0x05, 0x67, 0x7f, 0xeb, 0x5d,
- 0x9a, 0xa3, 0xde, 0x88, 0xba, 0x80, 0xc6, 0xa0, 0x89, 0x73, 0x3c, 0xfd, 0x2e, 0xcd, 0x53, 0x7e,
- 0x44, 0x4d, 0x28, 0x0c, 0x23, 0x74, 0xb3, 0x3e, 0x05, 0x2f, 0xcd, 0x5c, 0x8a, 0x64, 0x5f, 0x09,
- 0x42, 0x49, 0xb3, 0x3e, 0x0d, 0x2f, 0xcd, 0x5c, 0x99, 0x44, 0x47, 0x00, 0x3e, 0x38, 0x62, 0x86,
- 0xa7, 0xe2, 0xa5, 0x59, 0x6a, 0x94, 0xc8, 0x80, 0xa5, 0x71, 0xf8, 0xc3, 0x3c, 0x2f, 0xc7, 0x4b,
- 0x73, 0x95, 0x2e, 0x89, 0x3d, 0x07, 0x91, 0x84, 0xd9, 0x5e, 0x92, 0x97, 0x66, 0xac, 0x61, 0x6e,
- 0x56, 0x3f, 0xfb, 0x66, 0x45, 0xf8, 0xfc, 0x9b, 0x15, 0xe1, 0xeb, 0x6f, 0x56, 0x84, 0x4f, 0x1e,
- 0xad, 0x44, 0x3e, 0x7f, 0xb4, 0x12, 0xf9, 0xe2, 0xd1, 0x4a, 0xe4, 0xfb, 0xcf, 0xb4, 0x34, 0xbb,
- 0xdd, 0x3f, 0x59, 0x6f, 0xe8, 0xdd, 0x0d, 0xff, 0x5f, 0x6c, 0xc6, 0xfd, 0xeb, 0xe7, 0x24, 0x41,
- 0xc3, 0xe7, 0x9d, 0xbf, 0x05, 0x00, 0x00, 0xff, 0xff, 0xfd, 0xe1, 0x3d, 0x23, 0x15, 0x34, 0x00,
- 0x00,
+ 0xca, 0x36, 0x64, 0x47, 0x76, 0x64, 0x01, 0xa1, 0x98, 0x4d, 0x2a, 0xff, 0x40, 0x76, 0xa9, 0xd4,
+ 0x7d, 0xf4, 0x4b, 0x52, 0xeb, 0x31, 0xa4, 0x92, 0x82, 0xca, 0x4e, 0xf7, 0xdc, 0x73, 0x4e, 0xdf,
+ 0xc7, 0xb9, 0xe7, 0x9c, 0xfb, 0x3b, 0x57, 0x70, 0xc5, 0xc6, 0xbd, 0x26, 0x36, 0xbb, 0x5a, 0xcf,
+ 0xde, 0x50, 0x4f, 0x1a, 0xda, 0x86, 0x7d, 0x6e, 0x60, 0x6b, 0xdd, 0x30, 0x75, 0x5b, 0x47, 0x05,
+ 0xaf, 0x73, 0x9d, 0x74, 0x96, 0xae, 0xf9, 0xb8, 0x1b, 0xe6, 0xb9, 0x61, 0xeb, 0x1b, 0x86, 0xa9,
+ 0xeb, 0xa7, 0x8c, 0xbf, 0xe4, 0x57, 0x46, 0xf5, 0x6c, 0x34, 0x55, 0xab, 0xcd, 0x3b, 0xaf, 0x8e,
+ 0xca, 0x3e, 0xc4, 0xe7, 0xfc, 0x53, 0x01, 0xcd, 0x4c, 0xd4, 0x50, 0x4d, 0xb5, 0xeb, 0x74, 0xaf,
+ 0xf8, 0xba, 0xcf, 0xb0, 0x69, 0x69, 0x7a, 0xcf, 0x3f, 0xd2, 0xd2, 0x6a, 0x4b, 0xd7, 0x5b, 0x1d,
+ 0xbc, 0x41, 0x5b, 0x27, 0xfd, 0xd3, 0x0d, 0x5b, 0xeb, 0x62, 0xcb, 0x56, 0xbb, 0x06, 0x67, 0x58,
+ 0x6e, 0xe9, 0x2d, 0x9d, 0xfe, 0xdc, 0x20, 0xbf, 0x18, 0x55, 0xfa, 0x28, 0x0d, 0x49, 0x19, 0xbf,
+ 0xdf, 0xc7, 0x96, 0x8d, 0x6e, 0x43, 0x1c, 0x37, 0xda, 0x7a, 0x51, 0x58, 0x13, 0x6e, 0x66, 0x6e,
+ 0x5f, 0x5d, 0x1f, 0x9a, 0xfb, 0x3a, 0xe7, 0xab, 0x36, 0xda, 0x7a, 0x2d, 0x22, 0x53, 0x5e, 0xf4,
+ 0x22, 0x2c, 0x9c, 0x76, 0xfa, 0x56, 0xbb, 0x18, 0xa5, 0x42, 0xd7, 0xc2, 0x84, 0xee, 0x11, 0xa6,
+ 0x5a, 0x44, 0x66, 0xdc, 0xe4, 0x53, 0x5a, 0xef, 0x54, 0x2f, 0xc6, 0x26, 0x7f, 0x6a, 0xbb, 0x77,
+ 0x4a, 0x3f, 0x45, 0x78, 0xd1, 0x26, 0x80, 0xd6, 0xd3, 0x6c, 0xa5, 0xd1, 0x56, 0xb5, 0x5e, 0x31,
+ 0x4e, 0x25, 0x9f, 0x08, 0x97, 0xd4, 0xec, 0x0a, 0x61, 0xac, 0x45, 0xe4, 0xb4, 0xe6, 0x34, 0xc8,
+ 0x70, 0xdf, 0xef, 0x63, 0xf3, 0xbc, 0xb8, 0x30, 0x79, 0xb8, 0xaf, 0x13, 0x26, 0x32, 0x5c, 0xca,
+ 0x8d, 0x5e, 0x83, 0x54, 0xa3, 0x8d, 0x1b, 0x0f, 0x15, 0x7b, 0x50, 0x4c, 0x52, 0xc9, 0xd5, 0x30,
+ 0xc9, 0x0a, 0xe1, 0xab, 0x0f, 0x6a, 0x11, 0x39, 0xd9, 0x60, 0x3f, 0xd1, 0x1e, 0xe4, 0x3b, 0x9a,
+ 0x65, 0x2b, 0x56, 0x4f, 0x35, 0xac, 0xb6, 0x6e, 0x5b, 0xc5, 0x0c, 0xd5, 0xf1, 0x64, 0x98, 0x8e,
+ 0x5d, 0xcd, 0xb2, 0x0f, 0x1d, 0xe6, 0x5a, 0x44, 0xce, 0x75, 0xfc, 0x04, 0xa2, 0x4f, 0x3f, 0x3d,
+ 0xc5, 0xa6, 0xab, 0xb0, 0x98, 0x9d, 0xac, 0x6f, 0x9f, 0x70, 0x3b, 0xf2, 0x44, 0x9f, 0xee, 0x27,
+ 0xa0, 0xb7, 0x60, 0xa9, 0xa3, 0xab, 0x4d, 0x57, 0x9d, 0xd2, 0x68, 0xf7, 0x7b, 0x0f, 0x8b, 0x39,
+ 0xaa, 0xf4, 0xe9, 0xd0, 0x41, 0xea, 0x6a, 0xd3, 0x51, 0x51, 0x21, 0x02, 0xb5, 0x88, 0xbc, 0xd8,
+ 0x19, 0x26, 0xa2, 0x77, 0x60, 0x59, 0x35, 0x8c, 0xce, 0xf9, 0xb0, 0xf6, 0x3c, 0xd5, 0x7e, 0x2b,
+ 0x4c, 0x7b, 0x99, 0xc8, 0x0c, 0xab, 0x47, 0xea, 0x08, 0x15, 0xd5, 0x41, 0x34, 0x4c, 0x6c, 0xa8,
+ 0x26, 0x56, 0x0c, 0x53, 0x37, 0x74, 0x4b, 0xed, 0x14, 0x0b, 0x54, 0xf7, 0x8d, 0x30, 0xdd, 0x07,
+ 0x8c, 0xff, 0x80, 0xb3, 0xd7, 0x22, 0x72, 0xc1, 0x08, 0x92, 0x98, 0x56, 0xbd, 0x81, 0x2d, 0xcb,
+ 0xd3, 0x2a, 0x4e, 0xd3, 0x4a, 0xf9, 0x83, 0x5a, 0x03, 0x24, 0x54, 0x85, 0x0c, 0x1e, 0x10, 0x71,
+ 0xe5, 0x4c, 0xb7, 0x71, 0x71, 0x91, 0x2a, 0x94, 0x42, 0xcf, 0x19, 0x65, 0x3d, 0xd6, 0x6d, 0x5c,
+ 0x8b, 0xc8, 0x80, 0xdd, 0x16, 0x52, 0xe1, 0xc2, 0x19, 0x36, 0xb5, 0xd3, 0x73, 0xaa, 0x46, 0xa1,
+ 0x3d, 0xc4, 0x1f, 0x14, 0x11, 0x55, 0xf8, 0x4c, 0x98, 0xc2, 0x63, 0x2a, 0x44, 0x54, 0x54, 0x1d,
+ 0x91, 0x5a, 0x44, 0x5e, 0x3a, 0x1b, 0x25, 0x13, 0x13, 0x3b, 0xd5, 0x7a, 0x6a, 0x47, 0xfb, 0x10,
+ 0x2b, 0x27, 0x1d, 0xbd, 0xf1, 0xb0, 0xb8, 0x34, 0xd9, 0xc4, 0xee, 0x71, 0xee, 0x4d, 0xc2, 0x4c,
+ 0x4c, 0xec, 0xd4, 0x4f, 0xd8, 0x4c, 0xc2, 0xc2, 0x99, 0xda, 0xe9, 0xe3, 0x9d, 0x78, 0x2a, 0x21,
+ 0x26, 0x77, 0xe2, 0xa9, 0x94, 0x98, 0xde, 0x89, 0xa7, 0xd2, 0x22, 0xec, 0xc4, 0x53, 0x20, 0x66,
+ 0xa4, 0x1b, 0x90, 0xf1, 0xb9, 0x17, 0x54, 0x84, 0x64, 0x17, 0x5b, 0x96, 0xda, 0xc2, 0xd4, 0x1b,
+ 0xa5, 0x65, 0xa7, 0x29, 0xe5, 0x21, 0xeb, 0x77, 0x29, 0xd2, 0x27, 0x82, 0x2b, 0x49, 0xbc, 0x05,
+ 0x91, 0xe4, 0xee, 0xd1, 0x91, 0xe4, 0x4d, 0x74, 0x1d, 0x72, 0x74, 0x2a, 0x8a, 0xd3, 0x4f, 0x5c,
+ 0x56, 0x5c, 0xce, 0x52, 0xe2, 0x31, 0x67, 0x5a, 0x85, 0x8c, 0x71, 0xdb, 0x70, 0x59, 0x62, 0x94,
+ 0x05, 0x8c, 0xdb, 0x86, 0xc3, 0xf0, 0x04, 0x64, 0xc9, 0xbc, 0x5d, 0x8e, 0x38, 0xfd, 0x48, 0x86,
+ 0xd0, 0x38, 0x8b, 0xf4, 0x93, 0x18, 0x88, 0xc3, 0x6e, 0x08, 0xbd, 0x0c, 0x71, 0xe2, 0x91, 0xb9,
+ 0x73, 0x2d, 0xad, 0x33, 0x77, 0xbd, 0xee, 0xb8, 0xeb, 0xf5, 0xba, 0xe3, 0xae, 0x37, 0x53, 0x9f,
+ 0x7d, 0xb5, 0x1a, 0xf9, 0xe4, 0xcf, 0xab, 0x82, 0x4c, 0x25, 0xd0, 0x65, 0xe2, 0x7c, 0x54, 0xad,
+ 0xa7, 0x68, 0x4d, 0x3a, 0xe4, 0x34, 0xf1, 0x2c, 0xaa, 0xd6, 0xdb, 0x6e, 0xa2, 0x5d, 0x10, 0x1b,
+ 0x7a, 0xcf, 0xc2, 0x3d, 0xab, 0x6f, 0x29, 0x2c, 0x5c, 0x70, 0x97, 0x1a, 0x70, 0x8c, 0x2c, 0x4e,
+ 0x54, 0x1c, 0xce, 0x03, 0xca, 0x28, 0x17, 0x1a, 0x41, 0x02, 0xda, 0x83, 0xdc, 0x99, 0xda, 0xd1,
+ 0x9a, 0xaa, 0xad, 0x9b, 0x8a, 0x85, 0x6d, 0xee, 0x63, 0xaf, 0x8f, 0xec, 0xf9, 0xb1, 0xc3, 0x75,
+ 0x88, 0xed, 0x23, 0xa3, 0xa9, 0xda, 0x78, 0x33, 0xfe, 0xd9, 0x57, 0xab, 0x82, 0x9c, 0x3d, 0xf3,
+ 0xf5, 0xa0, 0xa7, 0xa0, 0xa0, 0x1a, 0x86, 0x62, 0xd9, 0xaa, 0x8d, 0x95, 0x93, 0x73, 0x1b, 0x5b,
+ 0xd4, 0xed, 0x66, 0xe5, 0x9c, 0x6a, 0x18, 0x87, 0x84, 0xba, 0x49, 0x88, 0xe8, 0x49, 0xc8, 0x13,
+ 0x0f, 0xad, 0xa9, 0x1d, 0xa5, 0x8d, 0xb5, 0x56, 0xdb, 0x2e, 0x26, 0xd6, 0x84, 0x9b, 0x31, 0x39,
+ 0xc7, 0xa9, 0x35, 0x4a, 0x44, 0xeb, 0xb0, 0xe4, 0xb0, 0x35, 0x74, 0x13, 0x3b, 0xbc, 0xc4, 0x1f,
+ 0xe7, 0xe4, 0x45, 0xde, 0x55, 0xd1, 0x4d, 0xcc, 0xf8, 0xa5, 0xa6, 0x6b, 0x29, 0xd4, 0x9b, 0x23,
+ 0x04, 0xf1, 0xa6, 0x6a, 0xab, 0x74, 0x07, 0xb2, 0x32, 0xfd, 0x4d, 0x68, 0x86, 0x6a, 0xb7, 0xf9,
+ 0xba, 0xd2, 0xdf, 0xe8, 0x22, 0x24, 0xb8, 0xea, 0x18, 0x1d, 0x06, 0x6f, 0xa1, 0x65, 0x58, 0x30,
+ 0x4c, 0xfd, 0x0c, 0xd3, 0x65, 0x49, 0xc9, 0xac, 0x21, 0xc9, 0x90, 0x0f, 0x7a, 0x7e, 0x94, 0x87,
+ 0xa8, 0x3d, 0xe0, 0x5f, 0x89, 0xda, 0x03, 0xf4, 0x3c, 0xc4, 0xc9, 0x06, 0xd0, 0x6f, 0xe4, 0xc7,
+ 0xc4, 0x3a, 0x2e, 0x57, 0x3f, 0x37, 0xb0, 0x4c, 0x39, 0xa5, 0x8b, 0xb0, 0x3c, 0x2e, 0x12, 0x48,
+ 0x6d, 0x97, 0x1e, 0xf0, 0xe8, 0xe8, 0x45, 0x48, 0xb9, 0xa1, 0x80, 0xd9, 0xd7, 0xe5, 0x91, 0xaf,
+ 0x38, 0xcc, 0xb2, 0xcb, 0x4a, 0x0c, 0x8b, 0xec, 0x4f, 0x5b, 0xe5, 0xe1, 0x3b, 0x2b, 0x27, 0x55,
+ 0xc3, 0xa8, 0xa9, 0x56, 0x5b, 0x7a, 0x17, 0x8a, 0x61, 0x6e, 0xde, 0xb7, 0x3e, 0x02, 0x3d, 0x1d,
+ 0xce, 0xfa, 0x5c, 0x84, 0xc4, 0xa9, 0x6e, 0x76, 0x55, 0x9b, 0x2a, 0xcb, 0xc9, 0xbc, 0x45, 0xd6,
+ 0x8d, 0xb9, 0xfc, 0x18, 0x25, 0xb3, 0x86, 0xa4, 0xc0, 0xe5, 0x50, 0x57, 0x4f, 0x44, 0xb4, 0x5e,
+ 0x13, 0xb3, 0x55, 0xcc, 0xc9, 0xac, 0xe1, 0x29, 0x62, 0x83, 0x65, 0x0d, 0xf2, 0x59, 0x8b, 0xce,
+ 0x95, 0xea, 0x4f, 0xcb, 0xbc, 0x25, 0x7d, 0x11, 0x87, 0x8b, 0xe3, 0x1d, 0x3e, 0x5a, 0x83, 0x6c,
+ 0x57, 0x1d, 0x28, 0xf6, 0x80, 0x5b, 0xa5, 0x40, 0xf7, 0x19, 0xba, 0xea, 0xa0, 0x3e, 0x60, 0x26,
+ 0x29, 0x42, 0xcc, 0x1e, 0x58, 0xc5, 0xe8, 0x5a, 0xec, 0x66, 0x56, 0x26, 0x3f, 0xd1, 0x11, 0x2c,
+ 0x76, 0xf4, 0x86, 0xda, 0x51, 0x3a, 0xaa, 0x65, 0x2b, 0x0d, 0xbd, 0xdb, 0xd5, 0x6c, 0x7e, 0xd6,
+ 0x46, 0x0f, 0x08, 0x73, 0xdd, 0xb8, 0x59, 0xa1, 0x6c, 0xc4, 0x2f, 0xd1, 0x03, 0x12, 0x91, 0x0b,
+ 0x54, 0xc7, 0xae, 0x6a, 0xd9, 0xac, 0x0b, 0x6d, 0x41, 0xa6, 0xab, 0x59, 0x27, 0xb8, 0xad, 0x9e,
+ 0x69, 0xba, 0x59, 0x8c, 0xaf, 0xc5, 0xc6, 0xe6, 0x43, 0x0f, 0x3c, 0x1e, 0xae, 0xc9, 0x2f, 0xe6,
+ 0xdb, 0x92, 0x85, 0x80, 0xc9, 0x3a, 0x4e, 0x27, 0x31, 0xb7, 0xd3, 0x79, 0x1e, 0x96, 0x7b, 0x78,
+ 0x60, 0x2b, 0xee, 0x81, 0xb6, 0x98, 0x9d, 0x24, 0xe9, 0xd2, 0x23, 0xd2, 0xe7, 0x7a, 0x01, 0x8b,
+ 0x98, 0x0c, 0xd9, 0x1d, 0x53, 0xef, 0xf7, 0x9a, 0xc5, 0xd4, 0x9a, 0x70, 0x73, 0x41, 0x66, 0x0d,
+ 0x74, 0x17, 0x8a, 0xf4, 0xb0, 0x32, 0x0f, 0x46, 0x3c, 0x2d, 0x6e, 0x3a, 0x27, 0xb7, 0x49, 0x37,
+ 0xf7, 0x02, 0xe9, 0xa7, 0x3e, 0x72, 0x97, 0xf6, 0xf2, 0xd3, 0xbe, 0x01, 0xcb, 0x2c, 0xf2, 0x62,
+ 0x93, 0x84, 0x60, 0xb2, 0x59, 0x74, 0x00, 0x98, 0x0e, 0x60, 0xd1, 0xe9, 0x3b, 0x30, 0xf5, 0xfa,
+ 0x80, 0x7e, 0xff, 0x79, 0x57, 0xa0, 0xa9, 0x10, 0xb3, 0x76, 0x1c, 0xf4, 0x29, 0x35, 0x52, 0xe4,
+ 0xf4, 0x95, 0x0d, 0xd7, 0x95, 0xdf, 0xf5, 0x42, 0x45, 0x6b, 0x34, 0x1d, 0xe4, 0x5d, 0x9e, 0xdb,
+ 0x74, 0x23, 0x89, 0xf4, 0x8b, 0x05, 0x9f, 0x69, 0x05, 0x43, 0x3c, 0x37, 0x1c, 0xc1, 0x33, 0x9c,
+ 0x43, 0xdf, 0xb8, 0xfc, 0xb6, 0xc3, 0x12, 0xe6, 0x2b, 0xa3, 0xee, 0x60, 0xd8, 0x66, 0xdc, 0xa1,
+ 0x87, 0x9b, 0x4d, 0xec, 0xf1, 0xcc, 0x06, 0x41, 0x9c, 0xae, 0x69, 0x9c, 0x79, 0x44, 0xf2, 0x3b,
+ 0xd4, 0x94, 0xc6, 0x6f, 0xef, 0xbf, 0xd2, 0xc0, 0xbe, 0x8f, 0xa6, 0x84, 0xea, 0x70, 0x71, 0x68,
+ 0x52, 0x4a, 0x9f, 0x46, 0xd4, 0x62, 0x7b, 0xf4, 0x9e, 0xe1, 0xc4, 0x71, 0xdf, 0x24, 0xe5, 0xa5,
+ 0xc0, 0x9c, 0x59, 0x34, 0x96, 0x8e, 0x60, 0x71, 0x24, 0x89, 0x74, 0x77, 0x5b, 0x18, 0xbb, 0xdb,
+ 0xd1, 0xf1, 0xbb, 0x1d, 0xf3, 0xed, 0xb6, 0xf4, 0xb5, 0x00, 0xa5, 0xf0, 0x5c, 0x72, 0xec, 0x07,
+ 0x5e, 0x80, 0x0b, 0x5e, 0x4e, 0xe1, 0x5f, 0x7c, 0xe6, 0xc3, 0x91, 0xdb, 0xe9, 0xad, 0xfe, 0x84,
+ 0xf8, 0xcb, 0xc6, 0x14, 0xf7, 0x5b, 0xe0, 0x03, 0x28, 0x04, 0xb3, 0x60, 0x92, 0x64, 0x90, 0xd3,
+ 0xf0, 0x5f, 0x21, 0x5e, 0x39, 0x30, 0x66, 0x39, 0x7f, 0xe6, 0x6f, 0x5a, 0xd2, 0xef, 0xe3, 0x6e,
+ 0x8c, 0x0d, 0xa4, 0xb4, 0x63, 0x0e, 0xf6, 0x2b, 0x90, 0x98, 0xf7, 0x28, 0x73, 0x81, 0xff, 0x1c,
+ 0xdf, 0xef, 0xcb, 0xf1, 0xf5, 0xa7, 0x50, 0xed, 0x60, 0x0a, 0xf5, 0xa7, 0x34, 0xa4, 0x64, 0x6c,
+ 0x19, 0x44, 0x08, 0x6d, 0x42, 0x1a, 0x0f, 0x1a, 0xd8, 0xb0, 0x9d, 0x7b, 0xc9, 0xf8, 0x7b, 0x1f,
+ 0xe3, 0xae, 0x3a, 0x9c, 0xb5, 0x88, 0xec, 0x89, 0xa1, 0x3b, 0x1c, 0x9e, 0x09, 0x47, 0x5a, 0xb8,
+ 0xb8, 0x1f, 0x9f, 0x79, 0xc9, 0xc1, 0x67, 0x58, 0xaa, 0xb2, 0x12, 0x2a, 0x35, 0x04, 0xd0, 0xdc,
+ 0xe1, 0x00, 0x4d, 0x7c, 0xca, 0xc7, 0x02, 0x08, 0x4d, 0x25, 0x80, 0xd0, 0x2c, 0x4c, 0x99, 0x66,
+ 0x08, 0x44, 0xf3, 0x92, 0x03, 0xd1, 0x24, 0xa6, 0x8c, 0x78, 0x08, 0xa3, 0xf9, 0x5f, 0x1f, 0x46,
+ 0x93, 0xa2, 0xa2, 0x6b, 0xa1, 0xa2, 0x63, 0x40, 0x9a, 0xfd, 0x11, 0x90, 0x86, 0x81, 0x2a, 0x4f,
+ 0x85, 0x2a, 0x99, 0x82, 0xd2, 0xec, 0x8f, 0xa0, 0x34, 0xb9, 0x29, 0x0a, 0xa7, 0xc0, 0x34, 0x3f,
+ 0x1a, 0x0f, 0xd3, 0x84, 0x03, 0x29, 0x7c, 0x98, 0xb3, 0xe1, 0x34, 0x4a, 0x08, 0x4e, 0x53, 0x08,
+ 0xc5, 0x14, 0x98, 0xfa, 0x99, 0x81, 0x9a, 0xa3, 0x31, 0x40, 0x0d, 0x83, 0x54, 0x6e, 0x86, 0x2a,
+ 0x9f, 0x01, 0xa9, 0x39, 0x1a, 0x83, 0xd4, 0x2c, 0x4e, 0x55, 0x3b, 0x15, 0xaa, 0xb9, 0x17, 0x84,
+ 0x6a, 0x50, 0x48, 0xa2, 0xef, 0x1d, 0xd9, 0x10, 0xac, 0xe6, 0x24, 0x0c, 0xab, 0x61, 0x78, 0xca,
+ 0xb3, 0xa1, 0x1a, 0xe7, 0x00, 0x6b, 0xf6, 0x47, 0xc0, 0x9a, 0xe5, 0x29, 0x96, 0x36, 0x3b, 0x5a,
+ 0x93, 0x14, 0x53, 0x7e, 0x9c, 0x66, 0x27, 0x9e, 0xca, 0x88, 0x59, 0xe9, 0x69, 0x92, 0x5f, 0x0c,
+ 0x39, 0x2b, 0x12, 0x62, 0xb0, 0x69, 0xea, 0x26, 0xc7, 0x5d, 0x58, 0x43, 0xba, 0x49, 0x6e, 0xe1,
+ 0x9e, 0x63, 0x9a, 0x80, 0xec, 0x14, 0x20, 0x17, 0x70, 0x46, 0xd2, 0x97, 0x82, 0x27, 0x4b, 0xb1,
+ 0x1d, 0xff, 0x0d, 0x3e, 0xcd, 0x6f, 0xf0, 0x3e, 0xbc, 0x27, 0x1a, 0xc4, 0x7b, 0x56, 0x21, 0xe3,
+ 0xf7, 0xfe, 0x1c, 0xca, 0x51, 0x3d, 0xaf, 0x7f, 0x0b, 0x16, 0x69, 0x42, 0xce, 0x50, 0x21, 0x1e,
+ 0x8a, 0xe2, 0x34, 0x6c, 0x16, 0x48, 0x07, 0x5b, 0x1d, 0x16, 0x84, 0x9e, 0x83, 0x25, 0x1f, 0xaf,
+ 0xeb, 0xf3, 0x19, 0x9e, 0x21, 0xba, 0xdc, 0x65, 0xe6, 0xfc, 0x77, 0xe2, 0xa9, 0xa6, 0x88, 0xe5,
+ 0x6b, 0x3c, 0xdf, 0x1f, 0x1f, 0xf5, 0xa4, 0xbf, 0x44, 0xbd, 0x65, 0xf4, 0x80, 0xa2, 0x71, 0x98,
+ 0x8e, 0xf0, 0xd8, 0x98, 0x8e, 0x3f, 0x40, 0xc5, 0x02, 0x01, 0x0a, 0xbd, 0x05, 0xcb, 0x01, 0xb8,
+ 0xc7, 0x49, 0x3c, 0x9b, 0xf3, 0xa1, 0x3e, 0x11, 0x5f, 0x12, 0xe7, 0xf6, 0xa0, 0xb7, 0xe1, 0x0a,
+ 0xcd, 0x0f, 0x42, 0x92, 0x5b, 0x3c, 0x5b, 0x72, 0x7b, 0x89, 0xe8, 0xa8, 0x8c, 0x26, 0xb8, 0x61,
+ 0x58, 0xd0, 0x69, 0x18, 0x16, 0xf4, 0x37, 0xc1, 0x33, 0x2e, 0x17, 0x0d, 0x6a, 0xe8, 0x4d, 0xcc,
+ 0x11, 0x06, 0xfa, 0x9b, 0xe4, 0x78, 0x1d, 0xbd, 0xc5, 0x71, 0x04, 0xf2, 0x93, 0x70, 0xb9, 0x61,
+ 0x30, 0xcd, 0xa3, 0x9c, 0x0b, 0x4e, 0xb0, 0x0c, 0x8b, 0x83, 0x13, 0x22, 0xc4, 0x1e, 0x62, 0x16,
+ 0xb4, 0xb2, 0x32, 0xf9, 0x49, 0xf8, 0xe8, 0x29, 0xe2, 0x39, 0x11, 0x6b, 0xa0, 0x97, 0x21, 0x4d,
+ 0x0b, 0x46, 0x8a, 0x6e, 0x58, 0x3c, 0x4e, 0x05, 0x12, 0x47, 0x56, 0x18, 0x5a, 0x3f, 0x20, 0x3c,
+ 0xfb, 0x86, 0x25, 0xa7, 0x0c, 0xfe, 0xcb, 0x97, 0xda, 0xa5, 0x03, 0xa9, 0xdd, 0x55, 0x48, 0x93,
+ 0xd1, 0x5b, 0x86, 0xda, 0xc0, 0x45, 0xa0, 0x03, 0xf5, 0x08, 0xd2, 0x23, 0x01, 0x0a, 0x43, 0x61,
+ 0x6f, 0xec, 0xdc, 0x9d, 0xb3, 0x15, 0x0d, 0xa2, 0x63, 0x23, 0xb3, 0xbf, 0x06, 0xd0, 0x52, 0x2d,
+ 0xe5, 0x03, 0xb5, 0x67, 0xe3, 0x26, 0x5f, 0x82, 0x74, 0x4b, 0xb5, 0xde, 0xa0, 0x84, 0xe0, 0x60,
+ 0x52, 0x43, 0x83, 0xf1, 0x61, 0x35, 0x69, 0x3f, 0x56, 0x83, 0x4a, 0x90, 0x32, 0x4c, 0x4d, 0x37,
+ 0x35, 0xfb, 0x9c, 0xce, 0x20, 0x26, 0xbb, 0x6d, 0x74, 0x1d, 0x72, 0x5d, 0xdc, 0x35, 0x74, 0xbd,
+ 0xa3, 0x30, 0xf7, 0x92, 0xa1, 0xa2, 0x59, 0x4e, 0xac, 0x52, 0x2f, 0x73, 0x00, 0x17, 0xc6, 0x86,
+ 0x65, 0x74, 0x17, 0xd2, 0x5e, 0x44, 0x17, 0x68, 0x9e, 0x3d, 0x01, 0x1b, 0xf3, 0x78, 0xa5, 0xdf,
+ 0x09, 0x9e, 0xca, 0x20, 0xda, 0x56, 0x85, 0x84, 0x89, 0xad, 0x7e, 0x87, 0xe1, 0x5f, 0xf9, 0xdb,
+ 0xcf, 0xcd, 0x16, 0xd0, 0x09, 0xb5, 0xdf, 0xb1, 0x65, 0x2e, 0x2c, 0xbd, 0x03, 0x09, 0x46, 0x41,
+ 0x19, 0x48, 0x1e, 0xed, 0xdd, 0xdf, 0xdb, 0x7f, 0x63, 0x4f, 0x8c, 0x20, 0x80, 0x44, 0xb9, 0x52,
+ 0xa9, 0x1e, 0xd4, 0x45, 0x01, 0xa5, 0x61, 0xa1, 0xbc, 0xb9, 0x2f, 0xd7, 0xc5, 0x28, 0x21, 0xcb,
+ 0xd5, 0x9d, 0x6a, 0xa5, 0x2e, 0xc6, 0xd0, 0x22, 0xe4, 0xd8, 0x6f, 0xe5, 0xde, 0xbe, 0xfc, 0xa0,
+ 0x5c, 0x17, 0xe3, 0x3e, 0xd2, 0x61, 0x75, 0x6f, 0xab, 0x2a, 0x8b, 0x0b, 0xd2, 0x0b, 0x70, 0x39,
+ 0x34, 0x05, 0xf0, 0xa0, 0x34, 0xc1, 0x07, 0xa5, 0x49, 0x3f, 0x8f, 0x92, 0xfb, 0x5d, 0x58, 0x5c,
+ 0x47, 0x3b, 0x43, 0x13, 0xbf, 0x3d, 0x47, 0x52, 0x30, 0x34, 0x7b, 0xf4, 0x24, 0xe4, 0x4d, 0x7c,
+ 0x8a, 0xed, 0x46, 0x9b, 0xe5, 0x19, 0x0c, 0x6b, 0xcb, 0xc9, 0x39, 0x4e, 0xa5, 0x42, 0x16, 0x63,
+ 0x7b, 0x0f, 0x37, 0x6c, 0x85, 0x59, 0x8a, 0x45, 0xef, 0x4a, 0x69, 0xc2, 0x46, 0xa8, 0x87, 0x8c,
+ 0x28, 0xbd, 0x3b, 0xd7, 0x5a, 0xa6, 0x61, 0x41, 0xae, 0xd6, 0xe5, 0x37, 0xc5, 0x18, 0x42, 0x90,
+ 0xa7, 0x3f, 0x95, 0xc3, 0xbd, 0xf2, 0xc1, 0x61, 0x6d, 0x9f, 0xac, 0xe5, 0x12, 0x14, 0x9c, 0xb5,
+ 0x74, 0x88, 0x0b, 0xd2, 0x6f, 0x62, 0x70, 0x29, 0x24, 0x2b, 0x41, 0x2f, 0x03, 0xd8, 0x03, 0xc5,
+ 0xc4, 0x0d, 0xdd, 0x6c, 0x86, 0x1b, 0x59, 0x7d, 0x20, 0x53, 0x0e, 0x39, 0x6d, 0xf3, 0x5f, 0xd6,
+ 0x04, 0x04, 0x16, 0xbd, 0xc6, 0x95, 0x92, 0x59, 0x59, 0xfc, 0x86, 0x78, 0x6d, 0xcc, 0x95, 0x16,
+ 0x37, 0x88, 0x62, 0xba, 0xb6, 0x54, 0x31, 0xe5, 0x47, 0x6f, 0xc2, 0xa5, 0xa1, 0x20, 0xc2, 0x3d,
+ 0xaf, 0xc5, 0xd3, 0xf2, 0x19, 0x62, 0xc9, 0x85, 0x60, 0x2c, 0x61, 0x9e, 0xd7, 0x9a, 0x80, 0x58,
+ 0x34, 0x1f, 0x1f, 0xb1, 0x08, 0x0d, 0x46, 0x78, 0xde, 0x12, 0xc4, 0x98, 0x60, 0x24, 0xfd, 0x3a,
+ 0xb0, 0x79, 0xc1, 0x44, 0x6f, 0x1f, 0x12, 0x96, 0xad, 0xda, 0x7d, 0x8b, 0x1b, 0xf5, 0xdd, 0x59,
+ 0xb3, 0xc6, 0x75, 0xe7, 0xc7, 0x21, 0x15, 0x97, 0xb9, 0x9a, 0xef, 0xe4, 0x9e, 0xfe, 0x93, 0x52,
+ 0x81, 0xf1, 0xab, 0xff, 0x22, 0xe4, 0x83, 0x4b, 0x15, 0x7e, 0x48, 0x3d, 0x2f, 0x17, 0x95, 0x3a,
+ 0xb0, 0x34, 0x06, 0xb0, 0x41, 0x77, 0x79, 0x35, 0x85, 0xed, 0xd6, 0xf5, 0xd1, 0x29, 0x07, 0xd8,
+ 0xbd, 0xa2, 0x0a, 0x89, 0x4c, 0x5e, 0xf6, 0xcd, 0x36, 0xc6, 0x23, 0x48, 0x0d, 0x40, 0xa3, 0xb9,
+ 0xfc, 0x38, 0x70, 0x49, 0xf8, 0x16, 0xe0, 0xd2, 0x2f, 0x05, 0xb8, 0x32, 0x21, 0xbf, 0x47, 0xaf,
+ 0x0f, 0xd9, 0xe2, 0x2b, 0xf3, 0xdc, 0x0e, 0xd6, 0x19, 0x2d, 0x68, 0x8d, 0xd2, 0x1d, 0xc8, 0xfa,
+ 0xe9, 0xb3, 0x2d, 0xfd, 0x4f, 0x7d, 0xb1, 0x2f, 0x88, 0x82, 0xd5, 0x20, 0x81, 0xcf, 0x70, 0xcf,
+ 0x8d, 0xa5, 0x17, 0x47, 0xd7, 0x81, 0x74, 0x6f, 0x16, 0x49, 0x62, 0xf8, 0xd7, 0xaf, 0x56, 0x45,
+ 0xc6, 0xfd, 0xac, 0xde, 0xd5, 0x6c, 0xdc, 0x35, 0xec, 0x73, 0x99, 0xcb, 0x93, 0xb0, 0x6e, 0x62,
+ 0x9b, 0xb8, 0x90, 0x40, 0xcd, 0x2f, 0xcb, 0x88, 0x3c, 0x6d, 0xfb, 0x83, 0x00, 0xe0, 0x81, 0x68,
+ 0x1e, 0x88, 0x25, 0xf8, 0x41, 0xac, 0x55, 0xc8, 0xbc, 0xdf, 0xd7, 0xcd, 0x7e, 0xd7, 0x9f, 0xe5,
+ 0x02, 0x23, 0xd1, 0x63, 0x77, 0x03, 0x0a, 0x2c, 0x6d, 0xb7, 0xb4, 0x56, 0x4f, 0xb5, 0xfb, 0x26,
+ 0xe6, 0x90, 0x59, 0x9e, 0x92, 0x0f, 0x1d, 0x2a, 0x7a, 0x0b, 0x2e, 0xdb, 0x6d, 0x13, 0x5b, 0x6d,
+ 0xbd, 0xd3, 0x54, 0x86, 0x37, 0x3e, 0x41, 0x27, 0xbc, 0x3a, 0xc5, 0xe0, 0xe4, 0x4b, 0xae, 0x86,
+ 0xe3, 0xe0, 0xe6, 0xff, 0x51, 0x00, 0x34, 0x5a, 0x17, 0xfa, 0x6e, 0xcf, 0xe9, 0x43, 0x58, 0xa0,
+ 0xfb, 0x4d, 0x32, 0x45, 0xf7, 0x54, 0xa6, 0xf9, 0x81, 0x7b, 0x1b, 0x40, 0xb5, 0x6d, 0x53, 0x3b,
+ 0xe9, 0x13, 0x17, 0x15, 0x1d, 0xfd, 0x94, 0x67, 0x2f, 0x65, 0x87, 0x6f, 0xf3, 0x2a, 0x37, 0x9c,
+ 0x65, 0x4f, 0xd4, 0x67, 0x3c, 0x3e, 0x85, 0xd2, 0x1e, 0xe4, 0x83, 0xb2, 0x4e, 0x0a, 0xce, 0xc6,
+ 0x10, 0x4c, 0xc1, 0xd9, 0xd5, 0x90, 0xa7, 0xe0, 0x6e, 0x02, 0x1f, 0x63, 0x85, 0x5c, 0xda, 0x90,
+ 0xfe, 0x2e, 0x40, 0xd6, 0xef, 0x7a, 0x67, 0xce, 0x92, 0x67, 0xbb, 0x35, 0x4c, 0xc9, 0x9b, 0x2f,
+ 0x43, 0x8a, 0x74, 0xf7, 0x2d, 0xdc, 0xe4, 0x27, 0x21, 0xd9, 0x52, 0xad, 0x23, 0x0b, 0x37, 0x7d,
+ 0x67, 0x2e, 0xf9, 0x2d, 0xcf, 0xdc, 0xc4, 0xe4, 0x5c, 0xfa, 0x48, 0x80, 0x94, 0x3b, 0xf9, 0x60,
+ 0x91, 0x37, 0x80, 0x23, 0xb3, 0xb5, 0x8b, 0xfa, 0x2b, 0xb3, 0xac, 0xe4, 0x1d, 0x73, 0x4b, 0xde,
+ 0xaf, 0xba, 0x99, 0x62, 0x18, 0x7e, 0xe8, 0x5f, 0x69, 0x07, 0x1c, 0xe7, 0x89, 0xf1, 0xcf, 0xf8,
+ 0x38, 0x48, 0x8a, 0x84, 0xfe, 0x07, 0x12, 0x6a, 0xc3, 0x45, 0x4d, 0xf3, 0x63, 0xe0, 0x44, 0x87,
+ 0x75, 0xbd, 0x3e, 0x28, 0x53, 0x4e, 0x99, 0x4b, 0xf0, 0x51, 0x45, 0x9d, 0x51, 0x49, 0xff, 0x4f,
+ 0xf4, 0x32, 0x9e, 0xa0, 0x1f, 0xcc, 0x03, 0x1c, 0xed, 0x3d, 0xd8, 0xdf, 0xda, 0xbe, 0xb7, 0x5d,
+ 0xdd, 0xe2, 0xb9, 0xe2, 0xd6, 0x56, 0x75, 0x4b, 0x8c, 0x12, 0x3e, 0xb9, 0xfa, 0x60, 0xff, 0xb8,
+ 0xba, 0x25, 0xc6, 0xa4, 0x32, 0xa4, 0xdd, 0xc8, 0x47, 0x9f, 0x03, 0xe8, 0x1f, 0xf0, 0xb2, 0x73,
+ 0x4c, 0x66, 0x0d, 0xb4, 0x02, 0x19, 0x3f, 0x46, 0xcd, 0xce, 0x24, 0xb9, 0xf1, 0x31, 0x6c, 0x5a,
+ 0xfa, 0x95, 0x00, 0x05, 0x57, 0x07, 0xcf, 0x7d, 0x5e, 0x85, 0xa4, 0xd1, 0x3f, 0x51, 0x1c, 0xdb,
+ 0x1d, 0xaa, 0x04, 0x38, 0x17, 0xc2, 0xfe, 0x49, 0x47, 0x6b, 0xdc, 0xc7, 0xe7, 0x3c, 0xd2, 0x26,
+ 0x8c, 0xfe, 0xc9, 0x7d, 0x66, 0xe2, 0x6c, 0x18, 0xd1, 0x09, 0xc3, 0x88, 0x0d, 0x0d, 0x03, 0xdd,
+ 0x80, 0x6c, 0x4f, 0x6f, 0x62, 0x45, 0x6d, 0x36, 0x4d, 0x6c, 0x59, 0xcc, 0x52, 0xb9, 0xe6, 0x0c,
+ 0xe9, 0x29, 0xb3, 0x0e, 0xe9, 0x6b, 0x01, 0xd0, 0x68, 0xb4, 0x47, 0x87, 0xb0, 0xe8, 0x25, 0x0c,
+ 0x4e, 0x16, 0xc2, 0x42, 0xc2, 0x5a, 0x78, 0xb6, 0x10, 0x40, 0x0d, 0xc4, 0xb3, 0x20, 0x99, 0x64,
+ 0x96, 0xcb, 0x9e, 0xab, 0x32, 0xe8, 0x7c, 0xe9, 0xa2, 0x44, 0x67, 0x5c, 0x94, 0x88, 0x8c, 0x5c,
+ 0x79, 0xb7, 0x67, 0xaa, 0x2b, 0x95, 0x0c, 0x28, 0xd6, 0x47, 0xc4, 0xf8, 0x3c, 0xc3, 0x86, 0x24,
+ 0x7c, 0x9b, 0x21, 0x49, 0x77, 0x40, 0x7c, 0xdd, 0xfd, 0x3e, 0xff, 0xd2, 0xd0, 0x30, 0x85, 0x91,
+ 0x61, 0x9e, 0x41, 0x8a, 0x78, 0x5f, 0x1a, 0x34, 0xfe, 0x0f, 0xd2, 0xee, 0xea, 0xb9, 0x2f, 0x8a,
+ 0x42, 0x97, 0x9d, 0x8f, 0xc4, 0x13, 0x41, 0xb7, 0x60, 0x91, 0xc4, 0x0d, 0xa7, 0x22, 0xcd, 0x40,
+ 0xc3, 0x28, 0xf5, 0x86, 0x05, 0xd6, 0xb1, 0xeb, 0x20, 0x5a, 0x24, 0x69, 0x11, 0x9d, 0xb8, 0xf5,
+ 0xef, 0x18, 0x00, 0xb9, 0x03, 0x0e, 0x61, 0xa7, 0x6c, 0x0f, 0x73, 0x81, 0xec, 0x4a, 0xfa, 0x71,
+ 0x14, 0x32, 0xbe, 0x82, 0x19, 0xfa, 0xef, 0x40, 0xa2, 0xb8, 0x36, 0xa9, 0xb8, 0xe6, 0xcb, 0x12,
+ 0x03, 0x13, 0x8b, 0xce, 0x3f, 0xb1, 0xb0, 0xe2, 0xa5, 0x53, 0x69, 0x8b, 0xcf, 0x5d, 0x69, 0x7b,
+ 0x16, 0x90, 0xad, 0xdb, 0x6a, 0x87, 0x04, 0x6f, 0xad, 0xd7, 0x52, 0xd8, 0x69, 0x67, 0x01, 0x44,
+ 0xa4, 0x3d, 0xc7, 0xb4, 0xe3, 0x80, 0xd0, 0xa5, 0xdf, 0x0a, 0x90, 0x72, 0x91, 0x8a, 0x79, 0x5f,
+ 0xea, 0x5c, 0x84, 0x04, 0xbf, 0x8c, 0xb3, 0xa7, 0x3a, 0xbc, 0x35, 0xb6, 0xd0, 0x58, 0x82, 0x54,
+ 0x17, 0xdb, 0x2a, 0x8d, 0x86, 0x0c, 0x05, 0x75, 0xdb, 0x8f, 0x5d, 0xea, 0xbb, 0xf5, 0x0a, 0x64,
+ 0x7c, 0xaf, 0xa1, 0x48, 0x64, 0xdd, 0xab, 0xbe, 0x21, 0x46, 0x4a, 0xc9, 0x8f, 0x3f, 0x5d, 0x8b,
+ 0xed, 0xe1, 0x0f, 0x50, 0x91, 0xb8, 0xe3, 0x4a, 0xad, 0x5a, 0xb9, 0x2f, 0x0a, 0xa5, 0xcc, 0xc7,
+ 0x9f, 0xae, 0x25, 0x65, 0x4c, 0x2b, 0x38, 0xb7, 0xee, 0x43, 0x61, 0x68, 0x47, 0x83, 0x3e, 0x1e,
+ 0x41, 0x7e, 0xeb, 0xe8, 0x60, 0x77, 0xbb, 0x52, 0xae, 0x57, 0x95, 0xe3, 0xfd, 0x7a, 0x55, 0x14,
+ 0xd0, 0x25, 0x58, 0xda, 0xdd, 0xfe, 0x41, 0xad, 0xae, 0x54, 0x76, 0xb7, 0xab, 0x7b, 0x75, 0xa5,
+ 0x5c, 0xaf, 0x97, 0x2b, 0xf7, 0xc5, 0xe8, 0xed, 0x2f, 0x01, 0x0a, 0xe5, 0xcd, 0xca, 0x76, 0xd9,
+ 0x30, 0x3a, 0x5a, 0x43, 0xa5, 0x11, 0xa3, 0x02, 0x71, 0x0a, 0x60, 0x4f, 0x7c, 0x17, 0x5d, 0x9a,
+ 0x5c, 0x96, 0x43, 0xf7, 0x60, 0x81, 0x62, 0xdb, 0x68, 0xf2, 0x43, 0xe9, 0xd2, 0x94, 0x3a, 0x1d,
+ 0x19, 0x0c, 0x3d, 0x87, 0x13, 0x5f, 0x4e, 0x97, 0x26, 0x97, 0xed, 0xd0, 0x2e, 0x24, 0x1d, 0x44,
+ 0x70, 0xda, 0x73, 0xe6, 0xd2, 0xd4, 0x5a, 0x1a, 0x99, 0x1a, 0x43, 0x56, 0x27, 0x3f, 0xaa, 0x2e,
+ 0x4d, 0x29, 0xe8, 0x21, 0x19, 0xd2, 0x1e, 0x18, 0x3e, 0xfd, 0x7d, 0x77, 0x69, 0x86, 0x02, 0x23,
+ 0x7a, 0x07, 0x72, 0x41, 0x58, 0x70, 0xb6, 0xa7, 0xd7, 0xa5, 0x19, 0x8b, 0x7f, 0x44, 0x7f, 0x10,
+ 0x23, 0x9c, 0xed, 0x29, 0x76, 0x69, 0xc6, 0x5a, 0x20, 0x7a, 0x0f, 0x16, 0x47, 0x31, 0xbc, 0xd9,
+ 0x5f, 0x66, 0x97, 0xe6, 0xa8, 0x0e, 0xa2, 0x2e, 0xa0, 0x31, 0xd8, 0xdf, 0x1c, 0x0f, 0xb5, 0x4b,
+ 0xf3, 0x14, 0x0b, 0x51, 0x13, 0x0a, 0xc3, 0x78, 0xda, 0xac, 0x0f, 0xb7, 0x4b, 0x33, 0x17, 0x0e,
+ 0xd9, 0x57, 0x82, 0xc0, 0xcf, 0xac, 0x0f, 0xb9, 0x4b, 0x33, 0xd7, 0x11, 0xd1, 0x11, 0x80, 0x0f,
+ 0x3c, 0x98, 0xe1, 0x61, 0x77, 0x69, 0x96, 0x8a, 0x22, 0x32, 0x60, 0x69, 0x1c, 0x5a, 0x30, 0xcf,
+ 0x3b, 0xef, 0xd2, 0x5c, 0x85, 0x46, 0x62, 0xcf, 0xc1, 0x7b, 0xff, 0x6c, 0xef, 0xbe, 0x4b, 0x33,
+ 0x56, 0x1c, 0x37, 0xab, 0x9f, 0x7d, 0xb3, 0x22, 0x7c, 0xfe, 0xcd, 0x8a, 0xf0, 0xf5, 0x37, 0x2b,
+ 0xc2, 0x27, 0x8f, 0x56, 0x22, 0x9f, 0x3f, 0x5a, 0x89, 0x7c, 0xf1, 0x68, 0x25, 0xf2, 0xc3, 0x67,
+ 0x5a, 0x9a, 0xdd, 0xee, 0x9f, 0xac, 0x37, 0xf4, 0xee, 0x86, 0xff, 0x0f, 0x31, 0xe3, 0xfe, 0xa3,
+ 0x73, 0x92, 0xa0, 0xe1, 0xf3, 0xce, 0x3f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xe3, 0x20, 0xa3, 0x0f,
+ 0xc3, 0x33, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -7438,13 +7421,6 @@ func (m *CommitInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) {
dAtA[i] = 0x32
}
}
- if len(m.StateSignature) > 0 {
- i -= len(m.StateSignature)
- copy(dAtA[i:], m.StateSignature)
- i = encodeVarintTypes(dAtA, i, uint64(len(m.StateSignature)))
- i--
- dAtA[i] = 0x2a
- }
if len(m.BlockSignature) > 0 {
i -= len(m.BlockSignature)
copy(dAtA[i:], m.BlockSignature)
@@ -7501,13 +7477,6 @@ func (m *ExtendedCommitInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) {
dAtA[i] = 0x32
}
}
- if len(m.StateSignature) > 0 {
- i -= len(m.StateSignature)
- copy(dAtA[i:], m.StateSignature)
- i = encodeVarintTypes(dAtA, i, uint64(len(m.StateSignature)))
- i--
- dAtA[i] = 0x2a
- }
if len(m.BlockSignature) > 0 {
i -= len(m.BlockSignature)
copy(dAtA[i:], m.BlockSignature)
@@ -9380,10 +9349,6 @@ func (m *CommitInfo) Size() (n int) {
if l > 0 {
n += 1 + l + sovTypes(uint64(l))
}
- l = len(m.StateSignature)
- if l > 0 {
- n += 1 + l + sovTypes(uint64(l))
- }
if len(m.ThresholdVoteExtensions) > 0 {
for _, e := range m.ThresholdVoteExtensions {
l = e.Size()
@@ -9410,10 +9375,6 @@ func (m *ExtendedCommitInfo) Size() (n int) {
if l > 0 {
n += 1 + l + sovTypes(uint64(l))
}
- l = len(m.StateSignature)
- if l > 0 {
- n += 1 + l + sovTypes(uint64(l))
- }
if len(m.ThresholdVoteExtensions) > 0 {
for _, e := range m.ThresholdVoteExtensions {
l = e.Size()
@@ -16208,40 +16169,6 @@ func (m *CommitInfo) Unmarshal(dAtA []byte) error {
m.BlockSignature = []byte{}
}
iNdEx = postIndex
- case 5:
- if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field StateSignature", wireType)
- }
- var byteLen int
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- return ErrIntOverflowTypes
- }
- if iNdEx >= l {
- return io.ErrUnexpectedEOF
- }
- b := dAtA[iNdEx]
- iNdEx++
- byteLen |= int(b&0x7F) << shift
- if b < 0x80 {
- break
- }
- }
- if byteLen < 0 {
- return ErrInvalidLengthTypes
- }
- postIndex := iNdEx + byteLen
- if postIndex < 0 {
- return ErrInvalidLengthTypes
- }
- if postIndex > l {
- return io.ErrUnexpectedEOF
- }
- m.StateSignature = append(m.StateSignature[:0], dAtA[iNdEx:postIndex]...)
- if m.StateSignature == nil {
- m.StateSignature = []byte{}
- }
- iNdEx = postIndex
case 6:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ThresholdVoteExtensions", wireType)
@@ -16413,40 +16340,6 @@ func (m *ExtendedCommitInfo) Unmarshal(dAtA []byte) error {
m.BlockSignature = []byte{}
}
iNdEx = postIndex
- case 5:
- if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field StateSignature", wireType)
- }
- var byteLen int
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- return ErrIntOverflowTypes
- }
- if iNdEx >= l {
- return io.ErrUnexpectedEOF
- }
- b := dAtA[iNdEx]
- iNdEx++
- byteLen |= int(b&0x7F) << shift
- if b < 0x80 {
- break
- }
- }
- if byteLen < 0 {
- return ErrInvalidLengthTypes
- }
- postIndex := iNdEx + byteLen
- if postIndex < 0 {
- return ErrInvalidLengthTypes
- }
- if postIndex > l {
- return io.ErrUnexpectedEOF
- }
- m.StateSignature = append(m.StateSignature[:0], dAtA[iNdEx:postIndex]...)
- if m.StateSignature == nil {
- m.StateSignature = []byte{}
- }
- iNdEx = postIndex
case 6:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ThresholdVoteExtensions", wireType)
diff --git a/config/config.go b/config/config.go
index 4a1edaaf19..d5fd975108 100644
--- a/config/config.go
+++ b/config/config.go
@@ -13,7 +13,6 @@ import (
"github.com/dashevo/dashd-go/btcjson"
- "github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/libs/log"
tmos "github.com/tendermint/tendermint/libs/os"
"github.com/tendermint/tendermint/types"
@@ -999,8 +998,6 @@ type ConsensusConfig struct {
QuorumType btcjson.LLMQType `mapstructure:"quorum-type"`
- AppHashSize int `mapstructure:"app-hash-size"`
-
// TODO: The following fields are all temporary overrides that should exist only
// for the duration of the v0.36 release. The below fields should be completely
// removed in the v0.37 release of Tendermint.
@@ -1058,7 +1055,6 @@ func DefaultConsensusConfig() *ConsensusConfig {
PeerGossipSleepDuration: 100 * time.Millisecond,
PeerQueryMaj23SleepDuration: 2000 * time.Millisecond,
DoubleSignCheckHeight: int64(0),
- AppHashSize: crypto.DefaultAppHashSize,
QuorumType: btcjson.LLMQType_5_60,
ProposedBlockTimeWindow: 10 * time.Second,
DontAutoPropose: false,
@@ -1071,7 +1067,6 @@ func TestConsensusConfig() *ConsensusConfig {
cfg.PeerGossipSleepDuration = 5 * time.Millisecond
cfg.PeerQueryMaj23SleepDuration = 250 * time.Millisecond
cfg.DoubleSignCheckHeight = int64(0)
- cfg.AppHashSize = crypto.DefaultAppHashSize
cfg.QuorumType = btcjson.LLMQType_5_60
return cfg
}
@@ -1165,12 +1160,14 @@ func (cfg *ConsensusConfig) DeprecatedFieldWarning() error {
return nil
}
-//-----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
// TxIndexConfig
// Remember that Event has the following structure:
// type: [
-// key: value,
-// ...
+//
+// key: value,
+// ...
+//
// ]
//
// CompositeKeys are constructed by `type.key`
diff --git a/config/toml.go b/config/toml.go
index 6619ad9726..ab02973543 100644
--- a/config/toml.go
+++ b/config/toml.go
@@ -521,9 +521,6 @@ peer-query-maj23-sleep-duration = "{{ .Consensus.PeerQueryMaj23SleepDuration }}"
# Signing parameters
quorum-type = "{{ .Consensus.QuorumType }}"
-# State parameters
-app-hash-size = "{{ .Consensus.AppHashSize }}"
-
#######################################################
### Transaction Indexer Configuration Options ###
#######################################################
diff --git a/crypto/crypto.go b/crypto/crypto.go
index 7572d2d074..44f49710d9 100644
--- a/crypto/crypto.go
+++ b/crypto/crypto.go
@@ -20,9 +20,7 @@ const (
// AddressSize is the size of a pubkey address.
AddressSize = 20
DefaultHashSize = 32
- LargeAppHashSize = DefaultHashSize
- SmallAppHashSize = 20
- DefaultAppHashSize = LargeAppHashSize
+ DefaultAppHashSize = DefaultHashSize
ProTxHashSize = DefaultHashSize
QuorumHashSize = DefaultHashSize
)
diff --git a/crypto/merkle/doc.go b/crypto/merkle/doc.go
index 865c302170..fe50b34631 100644
--- a/crypto/merkle/doc.go
+++ b/crypto/merkle/doc.go
@@ -12,20 +12,19 @@ second pre-image attacks. Hence, use this library with caution.
Otherwise you might run into similar issues as, e.g., in early Bitcoin:
https://bitcointalk.org/?topic=102395
- *
- / \
- / \
- / \
- / \
- * *
- / \ / \
- / \ / \
- / \ / \
- * * * h6
- / \ / \ / \
- h0 h1 h2 h3 h4 h5
+ *
+ / \
+ / \
+ / \
+ / \
+ * *
+ / \ / \
+ / \ / \
+ / \ / \
+ * * * h6
+ / \ / \ / \
+ h0 h1 h2 h3 h4 h5
TODO(ismail): add 2nd pre-image protection or clarify further on how we use this and why this secure.
-
*/
package merkle
diff --git a/crypto/merkle/tree.go b/crypto/merkle/tree.go
index 521192782b..896b67c595 100644
--- a/crypto/merkle/tree.go
+++ b/crypto/merkle/tree.go
@@ -53,10 +53,10 @@ func hashFromByteSlices(sha hash.Hash, items [][]byte) []byte {
//
// These preliminary results suggest:
//
-// 1. The performance of the HashFromByteSlice is pretty good
-// 2. Go has low overhead for recursive functions
-// 3. The performance of the HashFromByteSlice routine is dominated
-// by the actual hashing of data
+// 1. The performance of the HashFromByteSlice is pretty good
+// 2. Go has low overhead for recursive functions
+// 3. The performance of the HashFromByteSlice routine is dominated
+// by the actual hashing of data
//
// Although this work is in no way exhaustive, point #3 suggests that
// optimization of this routine would need to take an alternative
diff --git a/crypto/secp256k1/secp256k1.go b/crypto/secp256k1/secp256k1.go
index c520360b3c..1655472028 100644
--- a/crypto/secp256k1/secp256k1.go
+++ b/crypto/secp256k1/secp256k1.go
@@ -20,7 +20,7 @@ import (
"golang.org/x/crypto/ripemd160" //nolint:staticcheck
)
-//-------------------------------------
+// -------------------------------------
const (
PrivKeyName = "tendermint/PrivKeySecp256k1"
PubKeyName = "tendermint/PubKeySecp256k1"
@@ -198,8 +198,8 @@ func (pubKey PubKey) Equals(other crypto.PubKey) bool {
// used to reject malleable signatures
// see:
-// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93
-// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/crypto.go#L39
+// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93
+// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/crypto.go#L39
var secp256k1halfN = new(big.Int).Rsh(secp256k1.S256().N, 1)
// Sign creates an ECDSA signature on curve Secp256k1, using SHA256 on the msg.
diff --git a/dash/quorum/validator_conn_executor_test.go b/dash/quorum/validator_conn_executor_test.go
index 4a76722226..4d80019691 100644
--- a/dash/quorum/validator_conn_executor_test.go
+++ b/dash/quorum/validator_conn_executor_test.go
@@ -420,7 +420,7 @@ func TestFinalizeBlock(t *testing.T) {
require.NoError(t, err)
block := makeBlock(t, state, 1, new(types.Commit))
- blockID, err := block.BlockID()
+ blockID := block.BlockID(nil)
require.NoError(t, err)
block.NextValidatorsHash = newVals.Hash()
const round = int32(0)
diff --git a/docs/tendermint-core/state-id.md b/docs/tendermint-core/state-id.md
deleted file mode 100644
index 4069956302..0000000000
--- a/docs/tendermint-core/state-id.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# State ID
-
-## State ID definition
-
-`StateID` is a unique identifier of the most recent application state validated in consensus at the time of block generation.
-
-## State ID rationale
-
-In Dash Platform documents are returned to clients that request them. The validity of these documents is verified by checking that the root hash of the document tree is signed by the one of the platform quorums which are used as Tenderdash validator sets.
-
-Before the introduction of the `StateID` verification that the last app hash was properly signed would have required passing all the components that are used in the blockID generation to light clients. StateID should be considered a subset of the BlockID which allows for small proofs for Dash Platform clients.
-
-## State ID generation
-
-Let's define the following:
-
-* `State(height=N)` - State where `LastBlockHeight == N`
-* `StateID(height=N)` - State ID generated for `State(height=N)`
-* `Block(height=N)` - Block at `height == N`
-* `Vote(height=B, stateID=S)` - Vote for `Block(height=B)`, with state ID generated from `State(height=S)`
-* `Commit(height=B, stateID=S)` - Commit for `Block(height=B)`, with state ID generated from `State(height=S)`
-
-StateID logic works as follows:
-
-1. System is in `State(height=N-1)`
-2. New block `Block(height=N)` is proposed.
-3. Validators vote for `Block(height=N)` by creating `Vote(height=N, stateID=N-1)`; note that this vote contains state ID for `State(height=N-1)`, as this is the most recent confirmed state
-4. Block is accepted and `Commit(height=N, stateID=N-1)` is generated
-5. System state is updated to `State(height=N)`
-6. New block `Block(height=N+1)` is proposed that contains last commit `Commit(height=N, stateID=N-1)`
-
-
-```mermaid
-graph TD
- subgraph "StateID logic diagram"
-
- State["State(height=N-1)"] -->|"2. Proposal"| Block["Block(height=N)"]
- Block -->|"3. Vote for block"| Vote["Vote (height=N, stateID=N-1)"]
- Vote -->|"4. Block accepted"| Commit["Commit (height=N, stateID=N-1)"]
- Commit -->|"5. Update system state"| NewState["State (height=N)"]
- NewState -->|"6. New block proposal"| NewBlock["Block (height=N+1, stateID=N)
- with LastCommit=Commit (height=N, stateID=N-1)"]
- end
-```
-
-As a result:
-
-* verification of a vote for the block at height `N` requires information about the AppHash returned from ABCI App in response to a commit for the height `N-1`,
-* block at height `N` contains the commit referring to state ID at height `N-2`.
-
-## Commit StateID verification
-
-Commit for a block at height `N` is a part of block `N+1`. This commit requires AppHash generated after the commit of
-block `N-2`. To verify StateID, blocks `N` and `N+1` are needed.
-
-To verify StateID from a commit at height `N` :
-
-1. Fetch block `Block(Height=N+1)` which contains the commit to verify
-2. Fetch block `Block(Height=N)` which contains AppHash needed for the verification
-3. Ensure `Block(Height=N+1).LastCommit.StateID.Height == N-1`
-4. Ensure `Block(Height=N+1).LastCommit.StateID.LastAppHash == Block(Height=N).Header.AppHash`
-5. Ensure `Block(Height=N+1).LastCommit.StateSignature` is correct
diff --git a/internal/blocksync/pool.go b/internal/blocksync/pool.go
index 0ac9a124f4..faf7a22b41 100644
--- a/internal/blocksync/pool.go
+++ b/internal/blocksync/pool.go
@@ -459,6 +459,7 @@ func (pool *BlockPool) sendError(err error, peerID types.NodeID) {
}
// for debugging purposes
+//
//nolint:unused
func (pool *BlockPool) debug() string {
pool.mtx.Lock()
diff --git a/internal/blocksync/reactor.go b/internal/blocksync/reactor.go
index 7707264e85..95f7ba6fc8 100644
--- a/internal/blocksync/reactor.go
+++ b/internal/blocksync/reactor.go
@@ -537,8 +537,11 @@ func (r *Reactor) poolRoutine(ctx context.Context, stateSynced bool, blockSyncCh
var (
firstPartSetHeader = firstParts.Header()
- firstID = types.BlockID{Hash: first.Hash(), PartSetHeader: firstPartSetHeader}
- stateID = first.StateID()
+ firstID = types.BlockID{
+ Hash: first.Hash(),
+ PartSetHeader: firstPartSetHeader,
+ StateID: first.StateID().Hash(),
+ }
)
// Finally, verify the first block using the second's commit.
@@ -547,7 +550,7 @@ func (r *Reactor) poolRoutine(ctx context.Context, stateSynced bool, blockSyncCh
// first.Hash() doesn't verify the tx contents, so MakePartSet() is
// currently necessary.
// TODO(sergio): Should we also validate against the extended commit?
- err = state.Validators.VerifyCommit(chainID, firstID, stateID, first.Height, second.LastCommit)
+ err = state.Validators.VerifyCommit(chainID, firstID, first.Height, second.LastCommit)
if err == nil {
// validate the block before we persist it
diff --git a/internal/blocksync/reactor_test.go b/internal/blocksync/reactor_test.go
index 8bb6f68e45..29dae706b8 100644
--- a/internal/blocksync/reactor_test.go
+++ b/internal/blocksync/reactor_test.go
@@ -14,7 +14,6 @@ import (
abciclient "github.com/tendermint/tendermint/abci/client"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/config"
- "github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/internal/consensus"
"github.com/tendermint/tendermint/internal/eventbus"
mpmocks "github.com/tendermint/tendermint/internal/mempool/mocks"
@@ -59,7 +58,7 @@ func setup(
require.True(t, numNodes >= 1, "must specify at least one block height (nodes)")
rts := &reactorTestSuite{
- logger: log.NewNopLogger().With("module", "block_sync", "testCase", t.Name()),
+ logger: log.NewTestingLogger(t).With("module", "block_sync", "testCase", t.Name()),
network: p2ptest.MakeNetwork(ctx, t, p2ptest.NetworkOptions{NumNodes: numNodes}),
nodes: make([]types.NodeID, 0, numNodes),
reactors: make(map[types.NodeID]*Reactor, numNodes),
@@ -104,7 +103,7 @@ func makeReactor(
channelCreator p2p.ChannelCreator,
peerEvents p2p.PeerEventSubscriber) *Reactor {
- logger := log.NewNopLogger()
+ logger := log.NewTestingLogger(t)
app := proxy.New(abciclient.NewLocalClient(logger, &abci.BaseApplication{}), logger, proxy.NopMetrics())
require.NoError(t, app.Start(ctx))
@@ -185,7 +184,7 @@ func (rts *reactorTestSuite) addNode(
peerEvents := func(ctx context.Context) *p2p.PeerUpdates { return rts.peerUpdates[nodeID] }
reactor := makeReactor(ctx, t, proTxHash, nodeID, genDoc, privVal, chCreator, peerEvents)
- commit := types.NewCommit(0, 0, types.BlockID{}, types.StateID{}, nil)
+ commit := types.NewCommit(0, 0, types.BlockID{}, nil)
state, err := reactor.stateStore.Load()
require.NoError(t, err)
@@ -213,11 +212,8 @@ func makeNextBlock(ctx context.Context,
block.CoreChainLockedHeight = state.LastCoreChainLockedBlockHeight
partSet, err := block.MakePartSet(types.BlockPartSizeBytes)
require.NoError(t, err)
- blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: partSet.Header()}
- stateID := types.StateID{
- Height: block.Header.Height,
- AppHash: make([]byte, crypto.DefaultAppHashSize),
- }
+ blockID := block.BlockID(partSet)
+ require.NoError(t, err)
// Simulate a commit for the current height
vote, err := factory.MakeVote(
@@ -230,18 +226,15 @@ func makeNextBlock(ctx context.Context,
0,
2,
blockID,
- block.AppHash,
)
require.NoError(t, err)
seenCommit := types.NewCommit(
vote.Height,
vote.Round,
blockID,
- stateID,
&types.CommitSigns{
QuorumSigns: types.QuorumSigns{
BlockSign: vote.BlockSignature,
- StateSign: vote.StateSignature,
ExtensionSigns: types.MakeThresholdExtensionSigns(vote.VoteExtensions),
},
QuorumHash: state.Validators.QuorumHash,
diff --git a/internal/consensus/byzantine_test.go b/internal/consensus/byzantine_test.go
index 8df873d81d..9db03ed18e 100644
--- a/internal/consensus/byzantine_test.go
+++ b/internal/consensus/byzantine_test.go
@@ -135,14 +135,10 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
bzNodeState.CurrentRoundState = uncommittedState
if height == prevoteHeight {
- prevote1, err := bzNodeState.signVote(ctx,
- tmproto.PrevoteType,
- bzNodeState.ProposalBlock.Hash(),
- bzNodeState.ProposalBlockParts.Header(),
- )
+ prevote1, err := bzNodeState.signVote(ctx, tmproto.PrevoteType, bzNodeState.BlockID())
require.NoError(t, err)
- prevote2, err := bzNodeState.signVote(ctx, tmproto.PrevoteType, nil, types.PartSetHeader{})
+ prevote2, err := bzNodeState.signVote(ctx, tmproto.PrevoteType, types.BlockID{})
require.NoError(t, err)
// send two votes to all peers (1st to one half, 2nd to another half)
@@ -189,7 +185,7 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
case lazyNodeState.Height == lazyNodeState.state.InitialHeight:
// We're creating a proposal for the first block.
// The commit is empty, but not nil.
- commit = types.NewCommit(0, 0, types.BlockID{}, types.StateID{}, nil)
+ commit = types.NewCommit(0, 0, types.BlockID{}, nil)
case lazyNodeState.LastCommit != nil:
// Make the commit from LastCommit
commit = lazyNodeState.LastCommit
@@ -227,7 +223,9 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
}
// Make proposal
- propBlockID := types.BlockID{Hash: block.Hash(), PartSetHeader: blockParts.Header()}
+ propBlockID := block.BlockID(blockParts)
+ assert.NoError(t, err)
+
proposal := types.NewProposal(
height,
lazyNodeState.state.LastCoreChainLockedBlockHeight,
diff --git a/internal/consensus/common_test.go b/internal/consensus/common_test.go
index aad449e6b4..ed61866008 100644
--- a/internal/consensus/common_test.go
+++ b/internal/consensus/common_test.go
@@ -1,4 +1,3 @@
-// nolint: lll
package consensus
import (
@@ -127,13 +126,11 @@ func (vs *validatorStub) signVote(
ValidatorProTxHash: proTxHash,
ValidatorIndex: vs.Index,
VoteExtensions: voteExtensions,
- AppHash: appHash,
}
- stateID := vote.StateID()
v := vote.ToProto()
- if err := vs.PrivValidator.SignVote(ctx, chainID, quorumType, quorumHash, v, stateID, nil); err != nil {
+ if err := vs.PrivValidator.SignVote(ctx, chainID, quorumType, quorumHash, v, nil); err != nil {
return nil, fmt.Errorf("sign vote failed: %w", err)
}
@@ -263,7 +260,10 @@ func decideProposal(
require.NotNil(t, block, "Failed to createProposalBlock. Did you forget to add commit for previous block?")
// Make proposal
- polRound, propBlockID := validRound, types.BlockID{Hash: block.Hash(), PartSetHeader: blockParts.Header()}
+ polRound := validRound
+ propBlockID := block.BlockID(blockParts)
+ assert.NoError(t, err)
+
proposal = types.NewProposal(height, 1, round, polRound, propBlockID, block.Header.Time)
p := proposal.ToProto()
@@ -560,7 +560,7 @@ func makeState(ctx context.Context, t *testing.T, args makeStateArgs) (*State, [
args.config = configSetup(t)
}
if args.logger == nil {
- args.logger = log.NewNopLogger()
+ args.logger = consensusLogger(t)
}
c := factory.ConsensusParams()
if args.consensusParams != nil {
@@ -647,7 +647,7 @@ func ensureNewRound(t *testing.T, roundCh <-chan tmpubsub.Message, height int64,
t.Helper()
msg := ensureMessageBeforeTimeout(t, roundCh, ensureTimeout)
newRoundEvent, ok := msg.Data().(types.EventDataNewRound)
- require.True(t, ok, "expected a EventDataNewRound, got %T. Wrong subscription channel?",
+ assert.True(t, ok, "expected a EventDataNewRound, got %T. Wrong subscription channel?",
msg.Data())
assert.Equal(t, height, newRoundEvent.Height, "height")
diff --git a/internal/consensus/helper_test.go b/internal/consensus/helper_test.go
index ebed185826..6fafe834b6 100644
--- a/internal/consensus/helper_test.go
+++ b/internal/consensus/helper_test.go
@@ -183,8 +183,7 @@ func (c *ChainGenerator) generateChain(ctx context.Context, css []*State, vss []
css[0].config.DontAutoPropose = true
- blockID, err := rs.ProposalBlock.BlockID()
- require.NoError(c.t, err)
+ blockID := rs.ProposalBlock.BlockID(nil)
signAddVotes(ctx, c.t, css[0], tmproto.PrecommitType, c.cfg.ChainID(), blockID, vss[1:c.nVals]...)
ensureNewRound(c.t, newRoundCh, height+1, 0)
diff --git a/internal/consensus/invalid_test.go b/internal/consensus/invalid_test.go
index b7dc41d903..a79142c306 100644
--- a/internal/consensus/invalid_test.go
+++ b/internal/consensus/invalid_test.go
@@ -132,7 +132,9 @@ func invalidDoPrevoteFunc(
Type: tmproto.PrecommitType,
BlockID: types.BlockID{
Hash: blockHash,
- PartSetHeader: types.PartSetHeader{Total: 1, Hash: tmrand.Bytes(32)}},
+ PartSetHeader: types.PartSetHeader{Total: 1, Hash: tmrand.Bytes(32)},
+ StateID: types.RandStateID().Hash(),
+ },
}
p := precommit.ToProto()
@@ -142,12 +144,10 @@ func invalidDoPrevoteFunc(
cs.Validators.QuorumType,
cs.Validators.QuorumHash,
p,
- cs.StateID(),
log.NewNopLogger(),
)
require.NoError(t, err)
- precommit.StateSignature = p.StateSignature
precommit.BlockSignature = p.BlockSignature
cs.privValidator = nil // disable priv val so we don't do normal votes
cs.mtx.Unlock()
diff --git a/internal/consensus/msgs_test.go b/internal/consensus/msgs_test.go
index 8ca136f5ee..a072fe9ad0 100644
--- a/internal/consensus/msgs_test.go
+++ b/internal/consensus/msgs_test.go
@@ -33,9 +33,11 @@ func TestMsgToProto(t *testing.T) {
Hash: tmrand.Bytes(32),
}
pbPsh := psh.ToProto()
+ stateID := types.RandStateID()
bi := types.BlockID{
Hash: tmrand.Bytes(32),
PartSetHeader: psh,
+ StateID: stateID.Hash(),
}
pbBi := bi.ToProto()
bits := bits.NewBitArray(1)
@@ -82,7 +84,6 @@ func TestMsgToProto(t *testing.T) {
1,
2,
bi,
- make(bytes.HexBytes, crypto.DefaultAppHashSize),
)
require.NoError(t, err)
pbVote := vote.ToProto()
@@ -464,7 +465,7 @@ func TestVoteSetMaj23MessageValidateBasic(t *testing.T) {
},
}
- testCases := []struct { // nolint: maligned
+ testCases := []struct { //nolint: maligned
expectErr bool
messageRound int32
messageHeight int64
@@ -536,7 +537,7 @@ func TestVoteSetBitsMessageValidateBasic(t *testing.T) {
}
func TestNewRoundStepMessageValidateBasic(t *testing.T) {
- testCases := []struct { // nolint: maligned
+ testCases := []struct { //nolint: maligned
expectErr bool
messageRound int32
messageLastCommitRound int32
@@ -575,7 +576,7 @@ func TestNewRoundStepMessageValidateBasic(t *testing.T) {
func TestNewRoundStepMessageValidateHeight(t *testing.T) {
initialHeight := int64(10)
- testCases := []struct { // nolint: maligned
+ testCases := []struct { //nolint: maligned
expectErr bool
messageLastCommitRound int32
messageHeight int64
@@ -725,7 +726,7 @@ func TestHasVoteMessageValidateBasic(t *testing.T) {
invalidSignedMsgType tmproto.SignedMsgType = 0x03
)
- testCases := []struct { // nolint: maligned
+ testCases := []struct { //nolint: maligned
expectErr bool
messageRound int32
messageIndex int32
diff --git a/internal/consensus/pbts_test.go b/internal/consensus/pbts_test.go
index d9d97069eb..839f3d4654 100644
--- a/internal/consensus/pbts_test.go
+++ b/internal/consensus/pbts_test.go
@@ -163,7 +163,8 @@ func (p *pbtsTestHarness) observedValidatorProposerHeight(ctx context.Context, t
ensureProposalWithTimeout(t, p.ensureProposalCh, p.currentHeight, p.currentRound, nil, timeout)
rs := p.observedState.GetRoundState()
- bid := types.BlockID{Hash: rs.ProposalBlock.Hash(), PartSetHeader: rs.ProposalBlockParts.Header()}
+ bid := rs.BlockID()
+
ensurePrevote(t, p.ensureVoteCh, p.currentHeight, p.currentRound)
signAddVotes(ctx, t, p.observedState, tmproto.PrevoteType, p.chainID, bid, p.otherValidators...)
@@ -226,7 +227,9 @@ func (p *pbtsTestHarness) nextHeight(ctx context.Context, t *testing.T, proposer
require.NoError(t, err)
ps, err := b.MakePartSet(types.BlockPartSizeBytes)
require.NoError(t, err)
- bid := types.BlockID{Hash: b.Hash(), PartSetHeader: ps.Header()}
+ bid := b.BlockID(ps)
+ require.NoError(t, err)
+
coreChainLockedHeight := p.observedState.state.LastCoreChainLockedBlockHeight
prop := types.NewProposal(p.currentHeight, coreChainLockedHeight, 0, -1, bid, proposedTime)
tp := prop.ToProto()
diff --git a/internal/consensus/reactor.go b/internal/consensus/reactor.go
index b3995b96d6..e7edf39249 100644
--- a/internal/consensus/reactor.go
+++ b/internal/consensus/reactor.go
@@ -686,8 +686,8 @@ func (r *Reactor) logResult(err error, logger log.Logger, message string, keyval
return true
}
-//func (r *Reactor) gossipVotesForHeight(rs *cstypes.RoundState, prs *cstypes.PeerRoundState, ps *PeerState) bool {
-// logger := r.Logger.With("height", prs.Height).With("peer", ps.peerID)
+// func (r *Reactor) gossipVotesForHeight(rs *cstypes.RoundState, prs *cstypes.PeerRoundState, ps *PeerState) bool {
+// logger := r.Logger.With("height", prs.Height).With("peer", ps.peerID)
func (r *Reactor) gossipVotesForHeight(
ctx context.Context,
rs *cstypes.RoundState,
diff --git a/internal/consensus/replay_test.go b/internal/consensus/replay_test.go
index 16cf34d9a3..7a9bd54b8f 100644
--- a/internal/consensus/replay_test.go
+++ b/internal/consensus/replay_test.go
@@ -410,7 +410,7 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
// randomness of proposer selection
css[0].config.DontAutoPropose = true
- blockID := types.BlockID{Hash: rs.ProposalBlock.Hash(), PartSetHeader: rs.ProposalBlockParts.Header()}
+ blockID := rs.BlockID()
signAddVotes(ctx, t, css[0], tmproto.PrecommitType, sim.Config.ChainID(), blockID, vss[1:nVals]...)
ensureNewRound(t, newRoundCh, height+1, 0)
@@ -498,7 +498,7 @@ func createSignSendProposal(ctx context.Context,
propBlock, _ := css[0].CreateProposalBlock(ctx)
propBlockParts, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
- blockID := types.BlockID{Hash: propBlock.Hash(), PartSetHeader: propBlockParts.Header()}
+ blockID := propBlock.BlockID(propBlockParts)
if assertTxs != nil {
require.Equal(t, len(assertTxs), len(propBlock.Txs), "height %d", height)
for _, tx := range assertTxs {
@@ -821,7 +821,7 @@ func applyBlock(
testPartSize := types.BlockPartSizeBytes
bps, err := blk.MakePartSet(testPartSize)
require.NoError(t, err)
- blkID := types.BlockID{Hash: blk.Hash(), PartSetHeader: bps.Header()}
+ blkID := blk.BlockID(bps)
newState, err := blockExec.ApplyBlock(ctx, st, blkID, blk, commit)
require.NoError(t, err)
return newState
@@ -1113,11 +1113,10 @@ func makeBlockchainFromWAL(t *testing.T, wal WAL, genDoc *types.GenesisDoc) ([]*
case *types.Vote:
if p.Type == tmproto.PrecommitType {
thisBlockCommit = types.NewCommit(p.Height, p.Round,
- p.BlockID, p.StateID(),
+ p.BlockID,
&types.CommitSigns{
QuorumSigns: types.QuorumSigns{
BlockSign: p.BlockSignature,
- StateSign: p.StateSignature,
ExtensionSigns: types.MakeThresholdExtensionSigns(p.VoteExtensions),
},
QuorumHash: crypto.RandQuorumHash(),
@@ -1214,8 +1213,10 @@ func (bs *mockBlockStore) LoadBlockMeta(height int64) *types.BlockMeta {
block := bs.chain[height-1]
bps, err := block.MakePartSet(types.BlockPartSizeBytes)
require.NoError(bs.t, err)
+ blockID := block.BlockID(bps)
+ require.NoError(bs.t, err)
return &types.BlockMeta{
- BlockID: types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()},
+ BlockID: blockID,
Header: block.Header,
}
}
diff --git a/internal/consensus/replayer.go b/internal/consensus/replayer.go
index 4e52fc689e..98433baf89 100644
--- a/internal/consensus/replayer.go
+++ b/internal/consensus/replayer.go
@@ -375,12 +375,9 @@ func (r *BlockReplayer) publishEvents(
ucState sm.CurrentRoundState,
fbResp *abci.ResponseFinalizeBlock,
) error {
- blockID, err := block.BlockID()
- if err != nil {
- return err
- }
+ blockID := block.BlockID(nil)
es := sm.NewFullEventSet(block, blockID, ucState, fbResp, ucState.NextValidators)
- err = es.Publish(r.publisher)
+ err := es.Publish(r.publisher)
if err != nil {
r.logger.Error("failed publishing event", "err", err)
}
diff --git a/internal/consensus/state.go b/internal/consensus/state.go
index 27b8ddb390..f27671fb9b 100644
--- a/internal/consensus/state.go
+++ b/internal/consensus/state.go
@@ -6,7 +6,7 @@ import (
"encoding/json"
"errors"
"fmt"
- "io/ioutil"
+ "io"
"os"
"runtime/debug"
"sync"
@@ -1481,7 +1481,7 @@ func (cs *State) defaultDecideProposal(ctx context.Context, height int64, round
}
// Make proposal
- propBlockID := types.BlockID{Hash: block.Hash(), PartSetHeader: blockParts.Header()}
+ propBlockID := block.BlockID(blockParts)
proposal := types.NewProposal(height, block.CoreChainLockedHeight, round, cs.ValidRound, propBlockID, block.Header.Time)
proposal.SetCoreChainLockUpdate(block.CoreChainLock)
p := proposal.ToProto()
@@ -1594,7 +1594,7 @@ func (cs *State) createProposalBlock(ctx context.Context, round int32) (*types.B
case cs.Height == cs.state.InitialHeight:
// We're creating a proposal for the first block.
// The commit is empty, but not nil.
- commit = types.NewCommit(0, 0, types.BlockID{}, cs.StateID(), nil)
+ commit = types.NewCommit(0, 0, types.BlockID{}, nil)
case cs.LastCommit != nil:
// Make the commit from LastPrecommits
commit = cs.LastCommit
@@ -1667,19 +1667,19 @@ func (cs *State) defaultDoPrevote(ctx context.Context, height int64, round int32
// Check that a proposed block was not received within this round (and thus executing this from a timeout).
if cs.ProposalBlock == nil {
logger.Debug("prevote step: ProposalBlock is nil; prevoting nil")
- cs.signAddVote(ctx, tmproto.PrevoteType, nil, types.PartSetHeader{})
+ cs.signAddVote(ctx, tmproto.PrevoteType, types.BlockID{})
return
}
if cs.Proposal == nil {
logger.Debug("prevote step: did not receive proposal; prevoting nil")
- cs.signAddVote(ctx, tmproto.PrevoteType, nil, types.PartSetHeader{})
+ cs.signAddVote(ctx, tmproto.PrevoteType, types.BlockID{})
return
}
if !cs.Proposal.Timestamp.Equal(cs.ProposalBlock.Header.Time) {
logger.Debug("prevote step: proposal timestamp not equal; prevoting nil")
- cs.signAddVote(ctx, tmproto.PrevoteType, nil, types.PartSetHeader{})
+ cs.signAddVote(ctx, tmproto.PrevoteType, types.BlockID{})
return
}
@@ -1691,7 +1691,7 @@ func (cs *State) defaultDoPrevote(ctx context.Context, height int64, round int32
"received", tmtime.Canonical(cs.ProposalReceiveTime).Format(time.RFC3339Nano),
"msg_delay", sp.MessageDelay,
"precision", sp.Precision)
- cs.signAddVote(ctx, tmproto.PrevoteType, nil, types.PartSetHeader{})
+ cs.signAddVote(ctx, tmproto.PrevoteType, types.BlockID{})
return
}
@@ -1711,13 +1711,13 @@ func (cs *State) defaultDoPrevote(ctx context.Context, height int64, round int32
if errors.Is(err, sm.ErrBlockRejected) {
logger.Error("prevote step: state machine rejected a proposed block; this should not happen:"+
"the proposer may be misbehaving; prevoting nil", "err", err)
- cs.signAddVote(ctx, tmproto.PrevoteType, nil, types.PartSetHeader{})
+ cs.signAddVote(ctx, tmproto.PrevoteType, types.BlockID{})
return
}
if errors.As(err, &sm.ErrInvalidBlock{}) {
logger.Error("prevote step: consensus deems this block invalid; prevoting nil", "err", err)
- cs.signAddVote(ctx, tmproto.PrevoteType, nil, types.PartSetHeader{})
+ cs.signAddVote(ctx, tmproto.PrevoteType, types.BlockID{})
return
}
@@ -1740,15 +1740,16 @@ func (cs *State) defaultDoPrevote(ctx context.Context, height int64, round int32
we prevote nil since we are locked on a different value. Otherwise, if we're not locked on a block
or the proposal matches our locked block, we prevote the proposal.
*/
+ blockID := cs.BlockID()
if cs.Proposal.POLRound == -1 {
if cs.LockedRound == -1 {
logger.Debug("prevote step: ProposalBlock is valid and there is no locked block; prevoting the proposal")
- cs.signAddVote(ctx, tmproto.PrevoteType, cs.ProposalBlock.Hash(), cs.ProposalBlockParts.Header())
+ cs.signAddVote(ctx, tmproto.PrevoteType, blockID)
return
}
if cs.ProposalBlock.HashesTo(cs.LockedBlock.Hash()) {
logger.Debug("prevote step: ProposalBlock is valid and matches our locked block; prevoting the proposal")
- cs.signAddVote(ctx, tmproto.PrevoteType, cs.ProposalBlock.Hash(), cs.ProposalBlockParts.Header())
+ cs.signAddVote(ctx, tmproto.PrevoteType, blockID)
return
}
}
@@ -1775,12 +1776,12 @@ func (cs *State) defaultDoPrevote(ctx context.Context, height int64, round int32
if cs.LockedRound <= cs.Proposal.POLRound {
logger.Debug("prevote step: ProposalBlock is valid and received a 2/3 majority in a round later than the locked round",
"outcome", "prevoting the proposal")
- cs.signAddVote(ctx, tmproto.PrevoteType, cs.ProposalBlock.Hash(), cs.ProposalBlockParts.Header())
+ cs.signAddVote(ctx, tmproto.PrevoteType, blockID)
return
}
if cs.ProposalBlock.HashesTo(cs.LockedBlock.Hash()) {
logger.Debug("prevote step: ProposalBlock is valid and matches our locked block; prevoting the proposal")
- cs.signAddVote(ctx, tmproto.PrevoteType, cs.ProposalBlock.Hash(), cs.ProposalBlockParts.Header())
+ cs.signAddVote(ctx, tmproto.PrevoteType, blockID)
return
}
}
@@ -1790,7 +1791,7 @@ func (cs *State) defaultDoPrevote(ctx context.Context, height int64, round int32
if err != nil {
// ProposalBlock is invalid, prevote nil.
logger.Error("enterPrevote: ProposalBlock chain lock is invalid", "err", err)
- cs.signAddVote(ctx, tmproto.PrevoteType, nil, types.PartSetHeader{})
+ cs.signAddVote(ctx, tmproto.PrevoteType, types.BlockID{})
return
}
@@ -1800,14 +1801,14 @@ func (cs *State) defaultDoPrevote(ctx context.Context, height int64, round int32
if err != nil {
// ProposalBlock is invalid, prevote nil.
logger.Error("enterPrevote: ProposalBlock time is invalid", "err", err)
- cs.signAddVote(ctx, tmproto.PrevoteType, nil, types.PartSetHeader{})
+ cs.signAddVote(ctx, tmproto.PrevoteType, types.BlockID{})
return
}
}
logger.Debug("prevote step: ProposalBlock is valid but was not our locked block or " +
"did not receive a more recent majority; prevoting nil")
- cs.signAddVote(ctx, tmproto.PrevoteType, nil, types.PartSetHeader{})
+ cs.signAddVote(ctx, tmproto.PrevoteType, types.BlockID{})
}
// Enter: any +2/3 prevotes at next round.
@@ -1883,7 +1884,7 @@ func (cs *State) enterPrecommit(ctx context.Context, height int64, round int32)
logger.Debug("precommit step; no +2/3 prevotes during enterPrecommit; precommitting nil")
}
- cs.signAddVote(ctx, tmproto.PrecommitType, nil, types.PartSetHeader{})
+ cs.signAddVote(ctx, tmproto.PrecommitType, types.BlockID{})
return
}
@@ -1901,7 +1902,7 @@ func (cs *State) enterPrecommit(ctx context.Context, height int64, round int32)
// +2/3 prevoted nil. Precommit nil.
if blockID.IsNil() {
logger.Debug("precommit step: +2/3 prevoted for nil; precommitting nil")
- cs.signAddVote(ctx, tmproto.PrecommitType, nil, types.PartSetHeader{})
+ cs.signAddVote(ctx, tmproto.PrecommitType, types.BlockID{})
return
}
// At this point, +2/3 prevoted for a particular block.
@@ -1909,14 +1910,14 @@ func (cs *State) enterPrecommit(ctx context.Context, height int64, round int32)
// If we never received a proposal for this block, we must precommit nil
if cs.Proposal == nil || cs.ProposalBlock == nil {
logger.Debug("precommit step; did not receive proposal, precommitting nil")
- cs.signAddVote(ctx, tmproto.PrecommitType, nil, types.PartSetHeader{})
+ cs.signAddVote(ctx, tmproto.PrecommitType, types.BlockID{})
return
}
// If the proposal time does not match the block time, precommit nil.
if !cs.Proposal.Timestamp.Equal(cs.ProposalBlock.Header.Time) {
logger.Debug("precommit step: proposal timestamp not equal; precommitting nil")
- cs.signAddVote(ctx, tmproto.PrecommitType, nil, types.PartSetHeader{})
+ cs.signAddVote(ctx, tmproto.PrecommitType, types.BlockID{})
return
}
@@ -1929,7 +1930,7 @@ func (cs *State) enterPrecommit(ctx context.Context, height int64, round int32)
logger.Error("precommit step: failed publishing event relock", "err", err)
}
- cs.signAddVote(ctx, tmproto.PrecommitType, blockID.Hash, blockID.PartSetHeader)
+ cs.signAddVote(ctx, tmproto.PrecommitType, blockID)
return
}
@@ -1952,7 +1953,7 @@ func (cs *State) enterPrecommit(ctx context.Context, height int64, round int32)
logger.Error("precommit step: failed publishing event lock", "err", err)
}
- cs.signAddVote(ctx, tmproto.PrecommitType, blockID.Hash, blockID.PartSetHeader)
+ cs.signAddVote(ctx, tmproto.PrecommitType, blockID)
return
}
@@ -1966,7 +1967,7 @@ func (cs *State) enterPrecommit(ctx context.Context, height int64, round int32)
cs.ProposalBlockParts = types.NewPartSetFromHeader(blockID.PartSetHeader)
}
- cs.signAddVote(ctx, tmproto.PrecommitType, nil, types.PartSetHeader{})
+ cs.signAddVote(ctx, tmproto.PrecommitType, types.BlockID{})
}
// Enter: any +2/3 precommits for next round.
@@ -2244,8 +2245,6 @@ func (cs *State) verifyCommit(ctx context.Context, commit *types.Commit, peerID
return false, nil
}
- stateID := commit.StateID
-
if rs.Proposal == nil || ignoreProposalBlock {
if ignoreProposalBlock {
cs.logger.Info("Commit verified for future round", "height", commit.Height, "round", commit.Round)
@@ -2255,7 +2254,7 @@ func (cs *State) verifyCommit(ctx context.Context, commit *types.Commit, peerID
// We need to verify that it was properly signed
// This generally proves that the commit is correct
- if err := cs.Validators.VerifyCommit(cs.state.ChainID, commit.BlockID, stateID, cs.Height, commit); err != nil {
+ if err := cs.Validators.VerifyCommit(cs.state.ChainID, commit.BlockID, cs.Height, commit); err != nil {
return false, fmt.Errorf("error verifying commit: %v", err)
}
@@ -2277,7 +2276,7 @@ func (cs *State) verifyCommit(ctx context.Context, commit *types.Commit, peerID
}
// Lets verify that the threshold signature matches the current validator set
- if err := cs.Validators.VerifyCommit(cs.state.ChainID, rs.Proposal.BlockID, stateID, cs.Height, commit); err != nil {
+ if err := cs.Validators.VerifyCommit(cs.state.ChainID, rs.Proposal.BlockID, cs.Height, commit); err != nil {
return false, fmt.Errorf("error verifying commit: %v", err)
}
@@ -2403,6 +2402,7 @@ func (cs *State) applyCommit(ctx context.Context, commit *types.Commit, logger l
types.BlockID{
Hash: block.Hash(),
PartSetHeader: blockParts.Header(),
+ StateID: block.StateID().Hash(),
},
block,
commit,
@@ -2646,7 +2646,7 @@ func (cs *State) addProposalBlockPart(
}
if added && cs.ProposalBlockParts.IsComplete() {
cs.metrics.MarkBlockGossipComplete()
- bz, err := ioutil.ReadAll(cs.ProposalBlockParts.GetReader())
+ bz, err := io.ReadAll(cs.ProposalBlockParts.GetReader())
if err != nil {
return added, err
}
@@ -3009,11 +3009,11 @@ func (cs *State) addVote(
}
// CONTRACT: cs.privValidator is not nil.
+// FIXME: Looks like it is used only in tests, remove and refactor the test.
func (cs *State) signVote(
ctx context.Context,
msgType tmproto.SignedMsgType,
- hash []byte,
- header types.PartSetHeader,
+ blockID types.BlockID,
) (*types.Vote, error) {
// Flush the WAL. Otherwise, we may not recompute the same vote to sign,
// and the privValidator will refuse to sign anything.
@@ -3034,8 +3034,7 @@ func (cs *State) signVote(
Height: cs.Height,
Round: cs.Round,
Type: msgType,
- BlockID: types.BlockID{Hash: hash, PartSetHeader: header},
- AppHash: cs.RoundState.CurrentRoundState.AppHash,
+ BlockID: blockID,
}
// If the signedMessageType is for precommit,
@@ -3056,13 +3055,8 @@ func (cs *State) signVote(
ctxto, cancel := context.WithTimeout(ctx, timeout)
defer cancel()
- stateID := vote.StateID()
- if len(hash) == 0 {
- v.AppHash = nil
- }
-
err := cs.privValidator.SignVote(ctxto, cs.state.ChainID, cs.state.Validators.QuorumType, cs.state.Validators.QuorumHash,
- v, stateID, cs.logger)
+ v, cs.logger)
if err != nil {
return nil, err
}
@@ -3078,8 +3072,7 @@ func (cs *State) signVote(
func (cs *State) signAddVote(
ctx context.Context,
msgType tmproto.SignedMsgType,
- hash []byte,
- header types.PartSetHeader,
+ blockID types.BlockID,
) *types.Vote {
if cs.privValidator == nil { // the node does not have a key
return nil
@@ -3099,7 +3092,7 @@ func (cs *State) signAddVote(
// TODO: pass pubKey to signVote
start := time.Now()
- vote, err := cs.signVote(ctx, msgType, hash, header)
+ vote, err := cs.signVote(ctx, msgType, blockID)
if err != nil {
cs.logger.Error("failed signing vote", "height", cs.Height, "round", cs.Round, "vote", vote, "err", err)
return nil
@@ -3109,7 +3102,6 @@ func (cs *State) signAddVote(
"height", cs.Height,
"round", cs.Round,
"vote", vote,
- "state_id", vote.StateID(),
"quorum_hash", cs.Validators.QuorumHash,
"took", time.Since(start).String())
return vote
diff --git a/internal/consensus/state_test.go b/internal/consensus/state_test.go
index e5169f58f0..98eea1fa85 100644
--- a/internal/consensus/state_test.go
+++ b/internal/consensus/state_test.go
@@ -94,10 +94,7 @@ func TestStateProposerSelection0(t *testing.T) {
ensureNewProposal(t, proposalCh, height, round)
rs := cs1.GetRoundState()
- signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), types.BlockID{
- Hash: rs.ProposalBlock.Hash(),
- PartSetHeader: rs.ProposalBlockParts.Header(),
- }, vss[1:]...)
+ signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), rs.BlockID(), vss[1:]...)
// Wait for new round so next validator is set.
ensureNewRound(t, newRoundCh, height+1, 0)
@@ -234,7 +231,7 @@ func TestStateBadProposal(t *testing.T) {
propBlock.AppHash = stateHash
propBlockParts, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
- blockID := types.BlockID{Hash: propBlock.Hash(), PartSetHeader: propBlockParts.Header()}
+ blockID := propBlock.BlockID(propBlockParts)
proposal := types.NewProposal(vs2.Height, 1, round, -1, blockID, propBlock.Header.Time)
p := proposal.ToProto()
_, err = vs2.SignProposal(ctx, config.ChainID(), cs1.Validators.QuorumType, cs1.Validators.QuorumHash, p)
@@ -322,8 +319,8 @@ func TestStateProposalTime(t *testing.T) {
propBlock.Time = tc.blockTimeFunc(cs)
}
parSet, err := propBlock.MakePartSet(types.BlockPartSizeBytes)
- blockID := types.BlockID{Hash: propBlock.Hash(), PartSetHeader: parSet.Header()}
require.NoError(t, err)
+ blockID := propBlock.BlockID(parSet)
cs.ValidBlock = propBlock
cs.ValidBlockParts = parSet
@@ -371,7 +368,7 @@ func TestStateOversizedBlock(t *testing.T) {
propBlockParts, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
- blockID := types.BlockID{Hash: propBlock.Hash(), PartSetHeader: propBlockParts.Header()}
+ blockID := propBlock.BlockID(propBlockParts)
proposal := types.NewProposal(height, 1, round, -1, blockID, propBlock.Header.Time)
p := proposal.ToProto()
_, err = vs2.SignProposal(ctx, config.ChainID(), cs1.Validators.QuorumType,
@@ -477,7 +474,7 @@ func TestStateFullRound2(t *testing.T) {
// we should be stuck in limbo waiting for more prevotes
rs := cs1.GetRoundState()
- blockID := types.BlockID{Hash: rs.ProposalBlock.Hash(), PartSetHeader: rs.ProposalBlockParts.Header()}
+ blockID := rs.BlockID()
// prevote arrives from vs2:
signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), blockID, vs2)
@@ -531,10 +528,7 @@ func TestStateLock_NoPOL(t *testing.T) {
ensureNewProposal(t, proposalCh, height, round)
roundState := cs1.GetRoundState()
- initialBlockID := types.BlockID{
- Hash: roundState.ProposalBlock.Hash(),
- PartSetHeader: roundState.ProposalBlockParts.Header(),
- }
+ initialBlockID := roundState.BlockID()
ensurePrevote(t, voteCh, height, round) // prevote
@@ -553,10 +547,12 @@ func TestStateLock_NoPOL(t *testing.T) {
hash := make([]byte, len(initialBlockID.Hash))
copy(hash, initialBlockID.Hash)
hash[0] = (hash[0] + 1) % 255
- signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), types.BlockID{
+ blockID := types.BlockID{
Hash: hash,
PartSetHeader: initialBlockID.PartSetHeader,
- }, vs2)
+ StateID: initialBlockID.StateID,
+ }
+ signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), blockID, vs2)
ensurePrecommit(t, voteCh, height, round) // precommit
// (note we're entering precommit for a second time this round)
@@ -587,7 +583,11 @@ func TestStateLock_NoPOL(t *testing.T) {
// add a conflicting prevote from the other validator
partSet, err := rs.LockedBlock.MakePartSet(partSize)
require.NoError(t, err)
- conflictingBlockID := types.BlockID{Hash: hash, PartSetHeader: partSet.Header()}
+ conflictingBlockID := types.BlockID{
+ Hash: hash,
+ PartSetHeader: partSet.Header(),
+ StateID: rs.LockedBlock.StateID().Hash(),
+ }
signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), conflictingBlockID, vs2)
ensurePrevote(t, voteCh, height, round)
@@ -628,7 +628,11 @@ func TestStateLock_NoPOL(t *testing.T) {
validatePrevote(ctx, t, cs1, round, vss[0], rs.LockedBlock.Hash())
partSet, err = rs.ProposalBlock.MakePartSet(partSize)
require.NoError(t, err)
- newBlockID := types.BlockID{Hash: hash, PartSetHeader: partSet.Header()}
+ newBlockID := types.BlockID{
+ Hash: hash,
+ PartSetHeader: partSet.Header(),
+ StateID: rs.ProposalBlock.StateID().Hash(),
+ }
signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), newBlockID, vs2)
ensurePrevote(t, voteCh, height, round)
@@ -662,10 +666,7 @@ func TestStateLock_NoPOL(t *testing.T) {
prop, propBlock := decideProposal(ctx, t, cs2, vs2, vs2.Height, vs2.Round+1)
require.NotNil(t, propBlock, "Failed to create proposal block with vs2")
require.NotNil(t, prop, "Failed to create proposal block with vs2")
- propBlockID := types.BlockID{
- Hash: propBlock.Hash(),
- PartSetHeader: partSet.Header(),
- }
+ propBlockID := propBlock.BlockID(partSet)
incrementRound(vs2)
@@ -748,11 +749,7 @@ func TestStateLock_POLUpdateLock(t *testing.T) {
ensureNewRound(t, newRoundCh, height, round)
ensureNewProposal(t, proposalCh, height, round)
rs := cs1.GetRoundState()
- initialBlockID := types.BlockID{
- Hash: rs.ProposalBlock.Hash(),
- PartSetHeader: rs.ProposalBlockParts.Header(),
- }
-
+ initialBlockID := rs.BlockID()
ensurePrevote(t, voteCh, height, round)
signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), initialBlockID, vs2, vs3, vs4)
@@ -787,12 +784,8 @@ func TestStateLock_POLUpdateLock(t *testing.T) {
propR1, propBlockR1 := decideProposal(ctx, t, cs2, vs2, vs2.Height, vs2.Round)
propBlockR1Parts, err := propBlockR1.MakePartSet(partSize)
require.NoError(t, err)
- propBlockR1Hash := propBlockR1.Hash()
- r1BlockID := types.BlockID{
- Hash: propBlockR1Hash,
- PartSetHeader: propBlockR1Parts.Header(),
- }
- require.NotEqual(t, propBlockR1Hash, initialBlockID.Hash)
+ r1BlockID := propBlockR1.BlockID(propBlockR1Parts)
+ require.NotEqual(t, r1BlockID.Hash, initialBlockID.Hash)
err = cs1.SetProposalAndBlock(ctx, propR1, propBlockR1, propBlockR1Parts, "some peer")
require.NoError(t, err)
@@ -814,7 +807,7 @@ func TestStateLock_POLUpdateLock(t *testing.T) {
// We should now be locked on the new block and prevote it since we saw a sufficient amount
// prevote for the block.
- validatePrecommit(ctx, t, cs1, round, round, vss[0], propBlockR1Hash, propBlockR1Hash)
+ validatePrecommit(ctx, t, cs1, round, round, vss[0], r1BlockID.Hash, r1BlockID.Hash)
}
// TestStateLock_POLRelock tests that a validator updates its locked round if
@@ -853,10 +846,7 @@ func TestStateLock_POLRelock(t *testing.T) {
rs := cs1.GetRoundState()
theBlock := rs.ProposalBlock
theBlockParts := rs.ProposalBlockParts
- blockID := types.BlockID{
- Hash: rs.ProposalBlock.Hash(),
- PartSetHeader: rs.ProposalBlockParts.Header(),
- }
+ blockID := rs.BlockID()
ensurePrevote(t, voteCh, height, round)
@@ -948,10 +938,7 @@ func TestStateLock_PrevoteNilWhenLockedAndMissProposal(t *testing.T) {
ensureNewRound(t, newRoundCh, height, round)
ensureNewProposal(t, proposalCh, height, round)
rs := cs1.GetRoundState()
- blockID := types.BlockID{
- Hash: rs.ProposalBlock.Hash(),
- PartSetHeader: rs.ProposalBlockParts.Header(),
- }
+ blockID := rs.BlockID()
ensurePrevote(t, voteCh, height, round)
@@ -1033,10 +1020,7 @@ func TestStateLock_PrevoteNilWhenLockedAndDifferentProposal(t *testing.T) {
ensureNewRound(t, newRoundCh, height, round)
ensureNewProposal(t, proposalCh, height, round)
rs := cs1.GetRoundState()
- blockID := types.BlockID{
- Hash: rs.ProposalBlock.Hash(),
- PartSetHeader: rs.ProposalBlockParts.Header(),
- }
+ blockID := rs.BlockID()
ensurePrevote(t, voteCh, height, round)
@@ -1134,10 +1118,7 @@ func TestStateLock_POLDoesNotUnlock(t *testing.T) {
ensureNewProposal(t, proposalCh, height, round)
rs := cs1.GetRoundState()
- blockID := types.BlockID{
- Hash: rs.ProposalBlock.Hash(),
- PartSetHeader: rs.ProposalBlockParts.Header(),
- }
+ blockID := rs.BlockID()
ensurePrevoteMatch(t, voteCh, height, round, blockID.Hash)
@@ -1262,10 +1243,7 @@ func TestStateLock_MissingProposalWhenPOLSeenDoesNotUpdateLock(t *testing.T) {
ensureNewRound(t, newRoundCh, height, round)
ensureNewProposal(t, proposalCh, height, round)
rs := cs1.GetRoundState()
- firstBlockID := types.BlockID{
- Hash: rs.ProposalBlock.Hash(),
- PartSetHeader: rs.ProposalBlockParts.Header(),
- }
+ firstBlockID := rs.BlockID()
ensurePrevote(t, voteCh, height, round) // prevote
@@ -1297,10 +1275,8 @@ func TestStateLock_MissingProposalWhenPOLSeenDoesNotUpdateLock(t *testing.T) {
require.NotNil(t, prop, "Failed to create proposal block with vs2")
partSet, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
- secondBlockID := types.BlockID{
- Hash: propBlock.Hash(),
- PartSetHeader: partSet.Header(),
- }
+ secondBlockID := propBlock.BlockID(partSet)
+
require.NotEqual(t, secondBlockID.Hash, firstBlockID.Hash)
ensureNewRound(t, newRoundCh, height, round)
@@ -1347,10 +1323,7 @@ func TestStateLock_DoesNotLockOnOldProposal(t *testing.T) {
ensureNewRound(t, newRoundCh, height, round)
ensureNewProposal(t, proposalCh, height, round)
rs := cs1.GetRoundState()
- firstBlockID := types.BlockID{
- Hash: rs.ProposalBlock.Hash(),
- PartSetHeader: rs.ProposalBlockParts.Header(),
- }
+ firstBlockID := rs.BlockID()
ensurePrevote(t, voteCh, height, round)
@@ -1424,7 +1397,7 @@ func TestStateLock_POLSafety1(t *testing.T) {
ensurePrevoteMatch(t, voteCh, height, round, propBlock.Hash())
partSet, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
- blockID := types.BlockID{Hash: propBlock.Hash(), PartSetHeader: partSet.Header()}
+ blockID := propBlock.BlockID(partSet)
// the others sign a polka but we don't see it
prevotes := signVotes(ctx, t, tmproto.PrevoteType, config.ChainID(), blockID, cs1.state.LastAppHash,
cs1.Validators.QuorumType, cs1.Validators.QuorumHash,
@@ -1443,10 +1416,7 @@ func TestStateLock_POLSafety1(t *testing.T) {
prop, propBlock := decideProposal(ctx, t, cs2, vs2, vs2.Height, vs2.Round)
propBlockParts, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
- r2BlockID := types.BlockID{
- Hash: propBlock.Hash(),
- PartSetHeader: propBlockParts.Header(),
- }
+ r2BlockID := propBlock.BlockID(propBlockParts)
ensureNewRound(t, newRoundCh, height, round)
@@ -1530,10 +1500,9 @@ func TestStateLock_POLSafety2(t *testing.T) {
// the block for R0: gets polkad but we miss it
// (even though we signed it, shhh)
_, propBlock0 := decideProposal(ctx, t, cs1, vss[0], height, round)
- propBlockHash0 := propBlock0.Hash()
propBlockParts0, err := propBlock0.MakePartSet(partSize)
require.NoError(t, err)
- propBlockID0 := types.BlockID{Hash: propBlockHash0, PartSetHeader: propBlockParts0.Header()}
+ propBlockID0 := propBlock0.BlockID(propBlockParts0)
// the others sign a polka but we don't see it
prevotes := signVotes(ctx, t, tmproto.PrevoteType, config.ChainID(), propBlockID0, cs1.state.LastAppHash,
@@ -1544,7 +1513,7 @@ func TestStateLock_POLSafety2(t *testing.T) {
prop1, propBlock1 := decideProposal(ctx, t, cs1, vs2, vs2.Height, vs2.Round+1)
propBlockParts1, err := propBlock1.MakePartSet(partSize)
require.NoError(t, err)
- propBlockID1 := types.BlockID{Hash: propBlock1.Hash(), PartSetHeader: propBlockParts1.Header()}
+ propBlockID1 := propBlock1.BlockID(propBlockParts1)
incrementRound(vs2, vs3, vs4)
@@ -1640,10 +1609,7 @@ func TestState_PrevotePOLFromPreviousRound(t *testing.T) {
ensureNewRound(t, newRoundCh, height, round)
ensureNewProposal(t, proposalCh, height, round)
rs := cs1.GetRoundState()
- r0BlockID := types.BlockID{
- Hash: rs.ProposalBlock.Hash(),
- PartSetHeader: rs.ProposalBlockParts.Header(),
- }
+ r0BlockID := rs.BlockID()
ensurePrevote(t, voteCh, height, round)
@@ -1683,10 +1649,7 @@ func TestState_PrevotePOLFromPreviousRound(t *testing.T) {
propBlockR1Parts, err := propBlockR1.MakePartSet(partSize)
require.NoError(t, err)
- r1BlockID := types.BlockID{
- Hash: propBlockR1.Hash(),
- PartSetHeader: propBlockR1Parts.Header(),
- }
+ r1BlockID := propBlockR1.BlockID(propBlockR1Parts)
require.NotEqual(t, r1BlockID.Hash, r0BlockID.Hash)
ensureNewRound(t, newRoundCh, height, round)
@@ -1777,10 +1740,7 @@ func TestProposeValidBlock(t *testing.T) {
propBlock := rs.ProposalBlock
partSet, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
- blockID := types.BlockID{
- Hash: propBlock.Hash(),
- PartSetHeader: partSet.Header(),
- }
+ blockID := propBlock.BlockID(partSet)
ensurePrevoteMatch(t, voteCh, height, round, blockID.Hash)
@@ -1868,10 +1828,7 @@ func TestSetValidBlockOnDelayedPrevote(t *testing.T) {
propBlock := rs.ProposalBlock
partSet, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
- blockID := types.BlockID{
- Hash: propBlock.Hash(),
- PartSetHeader: partSet.Header(),
- }
+ blockID := propBlock.BlockID(partSet)
ensurePrevoteMatch(t, voteCh, height, round, blockID.Hash)
@@ -1941,10 +1898,7 @@ func TestSetValidBlockOnDelayedProposal(t *testing.T) {
prop, propBlock := decideProposal(ctx, t, cs1, vs2, vs2.Height, vs2.Round+1)
partSet, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
- blockID := types.BlockID{
- Hash: propBlock.Hash(),
- PartSetHeader: partSet.Header(),
- }
+ blockID := propBlock.BlockID(partSet)
// vs2, vs3 and vs4 send prevote for propBlock
signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), blockID, vs2, vs3, vs4)
@@ -2088,10 +2042,7 @@ func TestFinalizeBlockCalled(t *testing.T) {
if !testCase.voteNil {
nextRound = 0
nextHeight = height + 1
- blockID = types.BlockID{
- Hash: rs.ProposalBlock.Hash(),
- PartSetHeader: rs.ProposalBlockParts.Header(),
- }
+ blockID = rs.BlockID()
}
signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), blockID, vss[1:]...)
@@ -2167,10 +2118,8 @@ func TestExtendVote(t *testing.T) {
rs := cs1.GetRoundState()
- blockID := types.BlockID{
- Hash: rs.ProposalBlock.Hash(),
- PartSetHeader: rs.ProposalBlockParts.Header(),
- }
+ blockID := rs.BlockID()
+
reqExtendVoteFunc := mock.MatchedBy(func(req *abci.RequestExtendVote) bool {
return assert.Equal(t, req.Height, height) &&
assert.Equal(t, []byte(blockID.Hash), req.Hash) &&
@@ -2257,8 +2206,7 @@ func TestCorrectABCIRound(t *testing.T) {
ensureNewProposal(t, proposalCh, height, round)
rs := cs1.GetRoundState()
- blockID, err := rs.ProposalBlock.BlockID()
- require.NoError(t, err)
+ blockID := rs.BlockID()
signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), blockID, vss[1:]...)
ensurePrevoteMatch(t, voteCh, height, round, blockID.Hash)
@@ -2316,10 +2264,8 @@ func TestVerifyVoteExtensionNotCalledOnAbsentPrecommit(t *testing.T) {
ensureNewProposal(t, proposalCh, height, round)
rs := cs1.GetRoundState()
- blockID := types.BlockID{
- Hash: rs.ProposalBlock.Hash(),
- PartSetHeader: rs.ProposalBlockParts.Header(),
- }
+ blockID := rs.BlockID()
+
signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), blockID, vss...)
ensurePrevoteMatch(t, voteCh, height, round, blockID.Hash)
@@ -2423,10 +2369,8 @@ func TestPrepareProposalReceivesVoteExtensions(t *testing.T) {
ensureNewProposal(t, proposalCh, height, round)
rs := cs1.GetRoundState()
- blockID := types.BlockID{
- Hash: rs.ProposalBlock.Hash(),
- PartSetHeader: rs.ProposalBlockParts.Header(),
- }
+ blockID := rs.BlockID()
+
signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), blockID, vss[1:]...)
// create a precommit for each validator with the associated vote extension.
@@ -2618,10 +2562,7 @@ func TestEmitNewValidBlockEventOnCommitWithoutBlock(t *testing.T) {
_, propBlock := decideProposal(ctx, t, cs1, vs2, vs2.Height, vs2.Round)
partSet, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
- blockID := types.BlockID{
- Hash: propBlock.Hash(),
- PartSetHeader: partSet.Header(),
- }
+ blockID := propBlock.BlockID(partSet)
// start round in which PO is not proposer
startTestRound(ctx, cs1, height, round)
@@ -2659,10 +2600,7 @@ func TestCommitFromPreviousRound(t *testing.T) {
prop, propBlock := decideProposal(ctx, t, cs1, vs2, vs2.Height, vs2.Round)
partSet, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
- blockID := types.BlockID{
- Hash: propBlock.Hash(),
- PartSetHeader: partSet.Header(),
- }
+ blockID := propBlock.BlockID(partSet)
// start round in which PO is not proposer
startTestRound(ctx, cs1, height, round)
@@ -2730,10 +2668,7 @@ func TestStartNextHeightCorrectlyAfterTimeout(t *testing.T) {
ensureNewProposal(t, proposalCh, height, round)
rs := cs1.GetRoundState()
- blockID := types.BlockID{
- Hash: rs.ProposalBlock.Hash(),
- PartSetHeader: rs.ProposalBlockParts.Header(),
- }
+ blockID := rs.BlockID()
ensurePrevoteMatch(t, voteCh, height, round, blockID.Hash)
@@ -2794,10 +2729,7 @@ func TestResetTimeoutPrecommitUponNewHeight(t *testing.T) {
ensureNewProposal(t, proposalCh, height, round)
rs := cs1.GetRoundState()
- blockID := types.BlockID{
- Hash: rs.ProposalBlock.Hash(),
- PartSetHeader: rs.ProposalBlockParts.Header(),
- }
+ blockID := rs.BlockID()
ensurePrevoteMatch(t, voteCh, height, round, blockID.Hash)
@@ -2863,10 +2795,7 @@ func TestStateHalt1(t *testing.T) {
propBlock := rs.ProposalBlock
partSet, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
- blockID := types.BlockID{
- Hash: propBlock.Hash(),
- PartSetHeader: partSet.Header(),
- }
+ blockID := propBlock.BlockID(partSet)
ensurePrevote(t, voteCh, height, round)
@@ -2969,10 +2898,7 @@ func TestStateOutputVoteStats(t *testing.T) {
peerID, err := types.NewNodeID("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
require.NoError(t, err)
- randBytes := tmrand.Bytes(crypto.HashSize)
- blockID := types.BlockID{
- Hash: randBytes,
- }
+ blockID := cs.BlockID()
vote := signVote(ctx, t, vss[1], tmproto.PrecommitType, config.ChainID(), blockID, cs.state.LastAppHash,
cs.state.Validators.QuorumType, cs.state.Validators.QuorumHash,
@@ -3012,7 +2938,7 @@ func TestSignSameVoteTwice(t *testing.T) {
cs, vss := makeState(ctx, t, makeStateArgs{config: config, validators: 2})
randBytes := tmrand.Bytes(crypto.HashSize)
-
+ stateID := types.RandStateID()
vote := signVote(
ctx,
t,
@@ -3022,6 +2948,7 @@ func TestSignSameVoteTwice(t *testing.T) {
types.BlockID{
Hash: randBytes,
PartSetHeader: types.PartSetHeader{Total: 10, Hash: randBytes},
+ StateID: stateID.Hash(),
},
cs.state.LastAppHash,
cs.state.Validators.QuorumType,
@@ -3036,6 +2963,7 @@ func TestSignSameVoteTwice(t *testing.T) {
types.BlockID{
Hash: randBytes,
PartSetHeader: types.PartSetHeader{Total: 10, Hash: randBytes},
+ StateID: stateID.Hash(),
},
cs.state.LastAppHash,
cs.state.Validators.QuorumType,
@@ -3069,7 +2997,7 @@ func TestStateTimestamp_ProposalNotMatch(t *testing.T) {
propBlockParts, err := propBlock.MakePartSet(types.BlockPartSizeBytes)
require.NoError(t, err)
- blockID := types.BlockID{Hash: propBlock.Hash(), PartSetHeader: propBlockParts.Header()}
+ blockID := propBlock.BlockID(propBlockParts)
// Create a proposal with a timestamp that does not match the timestamp of the block.
proposal := types.NewProposal(vs2.Height, 1, round, -1, blockID, propBlock.Header.Time.Add(time.Millisecond))
@@ -3117,7 +3045,7 @@ func TestStateTimestamp_ProposalMatch(t *testing.T) {
propBlockParts, err := propBlock.MakePartSet(types.BlockPartSizeBytes)
require.NoError(t, err)
- blockID := types.BlockID{Hash: propBlock.Hash(), PartSetHeader: propBlockParts.Header()}
+ blockID := propBlock.BlockID(propBlockParts)
// Create a proposal with a timestamp that matches the timestamp of the block.
proposal := types.NewProposal(vs2.Height, 1, round, -1, blockID, propBlock.Header.Time)
diff --git a/internal/consensus/types/height_vote_set_test.go b/internal/consensus/types/height_vote_set_test.go
index d5c292edd1..11989161e3 100644
--- a/internal/consensus/types/height_vote_set_test.go
+++ b/internal/consensus/types/height_vote_set_test.go
@@ -25,7 +25,7 @@ func TestPeerCatchupRounds(t *testing.T) {
valSet, privVals := types.RandValidatorSet(10)
- stateID := types.StateID{Height: 1}
+ stateID := tmproto.StateID{Height: 1}
chainID := cfg.ChainID()
hvs := NewHeightVoteSet(chainID, 1, valSet)
@@ -67,7 +67,7 @@ func makeVoteHR(
chainID string,
quorumType btcjson.LLMQType,
quorumHash crypto.QuorumHash,
- stateID types.StateID,
+ stateID tmproto.StateID,
) *types.Vote {
privVal := privVals[valIndex]
proTxHash, err := privVal.GetProTxHash(ctx)
@@ -81,15 +81,18 @@ func makeVoteHR(
Height: height,
Round: round,
Type: tmproto.PrecommitType,
- BlockID: types.BlockID{Hash: randBytes, PartSetHeader: types.PartSetHeader{}},
+ BlockID: types.BlockID{
+ Hash: randBytes,
+ PartSetHeader: types.PartSetHeader{},
+ StateID: stateID.Hash(),
+ },
}
v := vote.ToProto()
- err = privVal.SignVote(ctx, chainID, quorumType, quorumHash, v, stateID, nil)
+ err = privVal.SignVote(ctx, chainID, quorumType, quorumHash, v, nil)
require.NoError(t, err, "Error signing vote")
vote.BlockSignature = v.BlockSignature
- vote.StateSignature = v.StateSignature
err = vote.VoteExtensions.CopySignsFromProto(v.VoteExtensionsToMap())
require.NoError(t, err)
diff --git a/internal/consensus/types/round_state.go b/internal/consensus/types/round_state.go
index 48cf91b7d0..6238dc71de 100644
--- a/internal/consensus/types/round_state.go
+++ b/internal/consensus/types/round_state.go
@@ -161,20 +161,23 @@ func (rs *RoundState) NewRoundEvent() types.EventDataNewRound {
}
}
-// CompleteProposalEvent returns information about a proposed block as an event.
-func (rs *RoundState) CompleteProposalEvent() types.EventDataCompleteProposal {
- // We must construct BlockID from ProposalBlock and ProposalBlockParts
- // cs.Proposal is not guaranteed to be set when this function is called
- blockID := types.BlockID{
- Hash: rs.ProposalBlock.Hash(),
- PartSetHeader: rs.ProposalBlockParts.Header(),
+// BlockID returns block ID from proposal or constructs new block ID from ProposalBlock and ProposalBlockParts.
+// cs.Proposal is not guaranteed to be set when this function is called
+func (rs *RoundState) BlockID() types.BlockID {
+ if rs.Proposal != nil && rs.Height == rs.Proposal.Height && rs.Round == rs.Proposal.Round {
+ return rs.Proposal.BlockID
}
+ return rs.ProposalBlock.BlockID(rs.ProposalBlockParts)
+}
+
+// CompleteProposalEvent returns information about a proposed block as an event.
+func (rs *RoundState) CompleteProposalEvent() types.EventDataCompleteProposal {
return types.EventDataCompleteProposal{
Height: rs.Height,
Round: rs.Round,
Step: rs.Step.String(),
- BlockID: blockID,
+ BlockID: rs.BlockID(),
}
}
diff --git a/internal/consensus/wal_test.go b/internal/consensus/wal_test.go
index 6a2889bc69..77fb3f7a3f 100644
--- a/internal/consensus/wal_test.go
+++ b/internal/consensus/wal_test.go
@@ -3,7 +3,7 @@ package consensus
import (
"bytes"
"context"
- "io/ioutil"
+ "math/rand"
"os"
"path/filepath"
"testing"
@@ -142,10 +142,7 @@ func TestWALWriteCommit(t *testing.T) {
logger := log.NewTestingLogger(t)
- walDir, err := ioutil.TempDir("", "wal")
- require.NoError(t, err)
- defer os.RemoveAll(walDir)
- walFile := filepath.Join(walDir, "wal")
+ walFile := filepath.Join(t.TempDir(), "wal")
wal, err := NewWAL(ctx, logger, walFile)
require.NoError(t, err)
@@ -159,20 +156,21 @@ func TestWALWriteCommit(t *testing.T) {
}()
// Prepare and write commit msg
+ height := rand.Int63()
stateID := tmtypes.RandStateID()
+ stateID.Height = uint64(height)
blockID := tmtypes.BlockID{
Hash: crypto.CRandBytes(crypto.HashSize),
PartSetHeader: tmtypes.PartSetHeader{
Total: 0,
Hash: crypto.CRandBytes(crypto.HashSize)},
+ StateID: stateID.Hash(),
}
msg := &CommitMessage{
Commit: &tmtypes.Commit{
- Height: stateID.Height,
- StateID: stateID,
+ Height: height,
BlockID: blockID,
ThresholdBlockSignature: crypto.CRandBytes(96),
- ThresholdStateSignature: crypto.CRandBytes(96),
},
}
err = wal.Write(msgInfo{
@@ -199,7 +197,7 @@ func TestWALWriteCommit(t *testing.T) {
require.True(t, ok, "expected message of type msgInfo, got %T", readMsg.Msg)
commitMsg, ok := msgInfo.Msg.(*CommitMessage)
require.True(t, ok, "expected message of type *CommitMessage, got %T", msgInfo.Msg)
- assert.EqualValues(t, stateID.Height, commitMsg.Commit.StateID.Height)
+ assert.EqualValues(t, stateID.Hash(), commitMsg.Commit.BlockID.StateID)
}
func TestWALSearchForEndHeight(t *testing.T) {
diff --git a/internal/evidence/doc.go b/internal/evidence/doc.go
index 01d99ee36b..9d3ed0c34d 100644
--- a/internal/evidence/doc.go
+++ b/internal/evidence/doc.go
@@ -3,7 +3,7 @@ Package evidence handles all evidence storage and gossiping from detection to bl
For the different types of evidence refer to the `evidence.go` file in the types package
or https://github.com/tendermint/tendermint/blob/master/spec/consensus/light-client/accountability.md.
-Gossiping
+# Gossiping
The core functionality begins with the evidence reactor (see reactor.
go) which operates both the sending and receiving of evidence.
@@ -29,7 +29,7 @@ There are two buckets that evidence can be stored in: Pending & Committed.
All evidence is proto encoded to disk.
-Proposing
+# Proposing
When a new block is being proposed (in state/execution.go#CreateProposalBlock),
`PendingEvidence(maxBytes)` is called to send up to the maxBytes of uncommitted evidence, from the evidence store,
@@ -42,12 +42,11 @@ Once the proposed evidence is submitted,
the evidence is marked as committed and is moved from the broadcasted set to the committed set.
As a result it is also removed from the concurrent list so that it is no longer gossiped.
-Minor Functionality
+# Minor Functionality
As all evidence (including POLC's) are bounded by an expiration date, those that exceed this are no longer needed
and hence pruned. Currently, only committed evidence in which a marker to the height that the evidence was committed
and hence very small is saved. All updates are made from the `Update(block, state)` function which should be called
when a new block is committed.
-
*/
package evidence
diff --git a/internal/evidence/pool.go b/internal/evidence/pool.go
index 43f62d9cba..5373d6be6c 100644
--- a/internal/evidence/pool.go
+++ b/internal/evidence/pool.go
@@ -102,11 +102,11 @@ func (evpool *Pool) PendingEvidence(maxBytes int64) ([]types.Evidence, int64) {
// Update takes both the new state and the evidence committed at that height and performs
// the following operations:
-// 1. Take any conflicting votes from consensus and use the state's LastBlockTime to form
-// DuplicateVoteEvidence and add it to the pool.
-// 2. Update the pool's state which contains evidence params relating to expiry.
-// 3. Moves pending evidence that has now been committed into the committed pool.
-// 4. Removes any expired evidence based on both height and time.
+// 1. Take any conflicting votes from consensus and use the state's LastBlockTime to form
+// DuplicateVoteEvidence and add it to the pool.
+// 2. Update the pool's state which contains evidence params relating to expiry.
+// 3. Moves pending evidence that has now been committed into the committed pool.
+// 4. Removes any expired evidence based on both height and time.
func (evpool *Pool) Update(ctx context.Context, state sm.State, ev types.EvidenceList) {
// sanity check
if state.LastBlockHeight <= evpool.state.LastBlockHeight {
diff --git a/internal/evidence/pool_test.go b/internal/evidence/pool_test.go
index 8829db599f..7e7c105738 100644
--- a/internal/evidence/pool_test.go
+++ b/internal/evidence/pool_test.go
@@ -61,7 +61,7 @@ func TestEvidencePoolBasic(t *testing.T) {
stateStore.On("LoadValidators", mock.AnythingOfType("int64")).Return(valSet, nil)
stateStore.On("Load").Return(createState(height+1, valSet), nil)
- logger := log.NewNopLogger()
+ logger := log.NewTestingLogger(t)
eventBus := eventbus.NewDefault(logger)
require.NoError(t, eventBus.Start(ctx))
@@ -96,7 +96,7 @@ func TestEvidencePoolBasic(t *testing.T) {
next := pool.EvidenceFront()
require.Equal(t, ev, next.Value.(types.Evidence))
- const evidenceBytes int64 = 640
+ const evidenceBytes int64 = 512
evs, size = pool.PendingEvidence(evidenceBytes)
require.Equal(t, 1, len(evs))
require.Equal(t, evidenceBytes, size) // check that the size of the single evidence in bytes is correct
@@ -563,11 +563,9 @@ func makeCommit(height int64, quorumHash []byte, valProTxHash []byte) *types.Com
height,
0,
types.BlockID{},
- types.StateID{Height: height},
&types.CommitSigns{
QuorumSigns: types.QuorumSigns{
BlockSign: crypto.CRandBytes(types.SignatureSize),
- StateSign: crypto.CRandBytes(types.SignatureSize),
},
QuorumHash: quorumHash,
},
diff --git a/internal/evidence/verify.go b/internal/evidence/verify.go
index 5e2aac5125..58c4c4a2d3 100644
--- a/internal/evidence/verify.go
+++ b/internal/evidence/verify.go
@@ -87,10 +87,10 @@ func (evpool *Pool) verify(ctx context.Context, evidence types.Evidence) error {
// VerifyDuplicateVote verifies DuplicateVoteEvidence against the state of full node. This involves the
// following checks:
-// - the validator is in the validator set at the height of the evidence
-// - the height, round, type and validator address of the votes must be the same
-// - the block ID's must be different
-// - The signatures must both be valid
+// - the validator is in the validator set at the height of the evidence
+// - the height, round, type and validator address of the votes must be the same
+// - the block ID's must be different
+// - The signatures must both be valid
func VerifyDuplicateVote(e *types.DuplicateVoteEvidence, chainID string, valSet *types.ValidatorSet) error {
_, val := valSet.GetByProTxHash(e.VoteA.ValidatorProTxHash)
if val == nil {
diff --git a/internal/evidence/verify_test.go b/internal/evidence/verify_test.go
index 03160172ed..e1352bf0ad 100644
--- a/internal/evidence/verify_test.go
+++ b/internal/evidence/verify_test.go
@@ -39,42 +39,38 @@ func TestVerifyDuplicateVoteEvidence(t *testing.T) {
val2 := types.NewMockPVForQuorum(quorumHash)
validator1 := val.ExtractIntoValidator(context.Background(), quorumHash)
valSet := types.NewValidatorSet([]*types.Validator{validator1}, validator1.PubKey, quorumType, quorumHash, true)
-
- blockID := makeBlockID([]byte("blockhash"), 1000, []byte("partshash"))
- blockID2 := makeBlockID([]byte("blockhash2"), 1000, []byte("partshash"))
- blockID3 := makeBlockID([]byte("blockhash"), 10000, []byte("partshash"))
- blockID4 := makeBlockID([]byte("blockhash"), 10000, []byte("partshash2"))
+ stateID := types.RandStateID()
+ blockID := makeBlockID([]byte("blockhash"), 1000, []byte("partshash"), stateID)
+ blockID2 := makeBlockID([]byte("blockhash2"), 1000, []byte("partshash"), stateID)
+ blockID3 := makeBlockID([]byte("blockhash"), 10000, []byte("partshash"), stateID)
+ blockID4 := makeBlockID([]byte("blockhash"), 10000, []byte("partshash2"), stateID)
const chainID = "mychain"
- stateID := types.RandStateID()
-
- vote1 := makeVote(ctx, t, val, chainID, 0, 10, 2, 1, blockID, quorumType, quorumHash, stateID)
+ vote1 := makeVote(ctx, t, val, chainID, 0, 10, 2, 1, blockID, quorumType, quorumHash)
v1 := vote1.ToProto()
- err := val.SignVote(ctx, chainID, quorumType, quorumHash, v1, stateID, nil)
+ err := val.SignVote(ctx, chainID, quorumType, quorumHash, v1, nil)
require.NoError(t, err)
- badVote := makeVote(ctx, t, val, chainID, 0, 10, 2, 1, blockID, quorumType, quorumHash, stateID)
+ badVote := makeVote(ctx, t, val, chainID, 0, 10, 2, 1, blockID, quorumType, quorumHash)
bv := badVote.ToProto()
- err = val2.SignVote(ctx, chainID, crypto.SmallQuorumType(), quorumHash, bv, stateID, nil)
+ err = val2.SignVote(ctx, chainID, crypto.SmallQuorumType(), quorumHash, bv, nil)
require.NoError(t, err)
vote1.BlockSignature = v1.BlockSignature
- vote1.StateSignature = v1.StateSignature
badVote.BlockSignature = bv.BlockSignature
- badVote.StateSignature = bv.StateSignature
cases := []voteData{
- {vote1, makeVote(ctx, t, val, chainID, 0, 10, 2, 1, blockID2, quorumType, quorumHash, stateID), true}, // different block ids
- {vote1, makeVote(ctx, t, val, chainID, 0, 10, 2, 1, blockID3, quorumType, quorumHash, stateID), true},
- {vote1, makeVote(ctx, t, val, chainID, 0, 10, 2, 1, blockID4, quorumType, quorumHash, stateID), true},
- {vote1, makeVote(ctx, t, val, chainID, 0, 10, 2, 1, blockID, quorumType, quorumHash, stateID), false}, // wrong block id
- {vote1, makeVote(ctx, t, val, "mychain2", 0, 10, 2, 1, blockID2, quorumType, quorumHash, stateID), false}, // wrong chain id
- {vote1, makeVote(ctx, t, val, chainID, 0, 11, 2, 1, blockID2, quorumType, quorumHash, stateID), false}, // wrong height
- {vote1, makeVote(ctx, t, val, chainID, 0, 10, 3, 1, blockID2, quorumType, quorumHash, stateID), false}, // wrong round
- {vote1, makeVote(ctx, t, val, chainID, 0, 10, 2, 2, blockID2, quorumType, quorumHash, stateID), false}, // wrong step
- {vote1, makeVote(ctx, t, val2, chainID, 0, 10, 2, 1, blockID2, quorumType, quorumHash, stateID), false}, // wrong validator
+ {vote1, makeVote(ctx, t, val, chainID, 0, 10, 2, 1, blockID2, quorumType, quorumHash), true}, // different block ids
+ {vote1, makeVote(ctx, t, val, chainID, 0, 10, 2, 1, blockID3, quorumType, quorumHash), true},
+ {vote1, makeVote(ctx, t, val, chainID, 0, 10, 2, 1, blockID4, quorumType, quorumHash), true},
+ {vote1, makeVote(ctx, t, val, chainID, 0, 10, 2, 1, blockID, quorumType, quorumHash), false}, // wrong block id
+ {vote1, makeVote(ctx, t, val, "mychain2", 0, 10, 2, 1, blockID2, quorumType, quorumHash), false}, // wrong chain id
+ {vote1, makeVote(ctx, t, val, chainID, 0, 11, 2, 1, blockID2, quorumType, quorumHash), false}, // wrong height
+ {vote1, makeVote(ctx, t, val, chainID, 0, 10, 3, 1, blockID2, quorumType, quorumHash), false}, // wrong round
+ {vote1, makeVote(ctx, t, val, chainID, 0, 10, 2, 2, blockID2, quorumType, quorumHash), false}, // wrong step
+ {vote1, makeVote(ctx, t, val2, chainID, 0, 10, 2, 1, blockID2, quorumType, quorumHash), false}, // wrong validator
// a different vote time doesn't matter
- {vote1, makeVote(ctx, t, val, chainID, 0, 10, 2, 1, blockID2, quorumType, quorumHash, stateID), true},
+ {vote1, makeVote(ctx, t, val, chainID, 0, 10, 2, 1, blockID2, quorumType, quorumHash), true},
{vote1, badVote, false}, // signed by wrong key
}
@@ -143,7 +139,7 @@ func TestVerifyDuplicateVoteEvidence(t *testing.T) {
func makeVote(
ctx context.Context,
t *testing.T, val types.PrivValidator, chainID string, valIndex int32, height int64,
- round int32, step int, blockID types.BlockID, quorumType btcjson.LLMQType, quorumHash crypto.QuorumHash, stateID types.StateID) *types.Vote {
+ round int32, step int, blockID types.BlockID, quorumType btcjson.LLMQType, quorumHash crypto.QuorumHash) *types.Vote {
proTxHash, err := val.GetProTxHash(ctx)
require.NoError(t, err)
v := &types.Vote{
@@ -156,13 +152,13 @@ func makeVote(
}
vpb := v.ToProto()
- err = val.SignVote(ctx, chainID, quorumType, quorumHash, vpb, stateID, nil)
+ err = val.SignVote(ctx, chainID, quorumType, quorumHash, vpb, nil)
require.NoError(t, err)
v.BlockSignature = vpb.BlockSignature
return v
}
-func makeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) types.BlockID {
+func makeBlockID(hash []byte, partSetSize uint32, partSetHash []byte, stateID tmproto.StateID) types.BlockID {
var (
h = make([]byte, crypto.HashSize)
psH = make([]byte, crypto.HashSize)
@@ -175,5 +171,6 @@ func makeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) types.Bloc
Total: partSetSize,
Hash: psH,
},
+ StateID: stateID.Hash(),
}
}
diff --git a/internal/inspect/doc.go b/internal/inspect/doc.go
index c53049e1a2..0d17771b58 100644
--- a/internal/inspect/doc.go
+++ b/internal/inspect/doc.go
@@ -12,23 +12,23 @@ inconsistent state so the node will not be able to start up again.
The RPC endpoints provided by the Inspector type allow for a node operator to inspect
the block store and state store to better understand what may have caused the inconsistent state.
-
The Inspector type's lifecycle is controlled by a context.Context
- ins := inspect.NewFromConfig(rpcConfig)
- ctx, cancelFunc:= context.WithCancel(context.Background())
- // Run blocks until the Inspector server is shut down.
- go ins.Run(ctx)
- ...
+ ins := inspect.NewFromConfig(rpcConfig)
+ ctx, cancelFunc:= context.WithCancel(context.Background())
+
+ // Run blocks until the Inspector server is shut down.
+ go ins.Run(ctx)
+ ...
- // calling the cancel function will stop the running inspect server
- cancelFunc()
+ // calling the cancel function will stop the running inspect server
+ cancelFunc()
Inspector serves its RPC endpoints on the address configured in the RPC configuration
- rpcConfig.ListenAddress = "tcp://127.0.0.1:26657"
- ins := inspect.NewFromConfig(rpcConfig)
- go ins.Run(ctx)
+ rpcConfig.ListenAddress = "tcp://127.0.0.1:26657"
+ ins := inspect.NewFromConfig(rpcConfig)
+ go ins.Run(ctx)
The list of available RPC endpoints can then be viewed by navigating to
http://127.0.0.1:26657/ in the web browser.
diff --git a/internal/jsontypes/jsontypes.go b/internal/jsontypes/jsontypes.go
index 69405da1b4..a04362a6b5 100644
--- a/internal/jsontypes/jsontypes.go
+++ b/internal/jsontypes/jsontypes.go
@@ -2,10 +2,10 @@
// implementations need to be stored as JSON. To do this, concrete values are
// packaged in wrapper objects having the form:
//
-// {
-// "type": "",
-// "value":
-// }
+// {
+// "type": "",
+// "value":
+// }
//
// This package provides a registry for type tag strings and functions to
// encode and decode wrapper objects.
diff --git a/internal/libs/clist/clist.go b/internal/libs/clist/clist.go
index 9a0e5bcc84..2e6f129ed1 100644
--- a/internal/libs/clist/clist.go
+++ b/internal/libs/clist/clist.go
@@ -22,7 +22,6 @@ import (
const MaxLength = int(^uint(0) >> 1)
/*
-
CElement is an element of a linked-list
Traversal from a CElement is goroutine-safe.
@@ -39,7 +38,6 @@ the for-loop. Use sync.Cond when you need serial access to the
"condition". In our case our condition is if `next != nil || removed`,
and there's no reason to serialize that condition for goroutines
waiting on NextWait() (since it's just a read operation).
-
*/
type CElement struct {
mtx sync.RWMutex
diff --git a/internal/libs/flowrate/flowrate.go b/internal/libs/flowrate/flowrate.go
index aaa54a22cc..6c77a0041f 100644
--- a/internal/libs/flowrate/flowrate.go
+++ b/internal/libs/flowrate/flowrate.go
@@ -39,10 +39,10 @@ type Monitor struct {
// weight of each sample in the exponential moving average (EMA) calculation.
// The exact formulas are:
//
-// sampleTime = currentTime - prevSampleTime
-// sampleRate = byteCount / sampleTime
-// weight = 1 - exp(-sampleTime/windowSize)
-// newRate = weight*sampleRate + (1-weight)*oldRate
+// sampleTime = currentTime - prevSampleTime
+// sampleRate = byteCount / sampleTime
+// weight = 1 - exp(-sampleTime/windowSize)
+// newRate = weight*sampleRate + (1-weight)*oldRate
//
// The default values for sampleRate and windowSize (if <= 0) are 100ms and 1s,
// respectively.
diff --git a/internal/p2p/channel.go b/internal/p2p/channel.go
index 394656632d..49a8250805 100644
--- a/internal/p2p/channel.go
+++ b/internal/p2p/channel.go
@@ -160,11 +160,10 @@ type ChannelIterator struct {
// it will never return true again.
// in general, use Next, as in:
//
-// for iter.Next(ctx) {
-// envelope := iter.Envelope()
-// // ... do things ...
-// }
-//
+// for iter.Next(ctx) {
+// envelope := iter.Envelope()
+// // ... do things ...
+// }
func (iter *ChannelIterator) Next(ctx context.Context) bool {
select {
case <-ctx.Done():
diff --git a/internal/p2p/conn/connection.go b/internal/p2p/conn/connection.go
index adc287328f..6d8b66411e 100644
--- a/internal/p2p/conn/connection.go
+++ b/internal/p2p/conn/connection.go
@@ -64,6 +64,7 @@ The byte id and the relative priorities of each `Channel` are configured upon
initialization of the connection.
There are two methods for sending messages:
+
func (m MConnection) Send(chID byte, msgBytes []byte) bool {}
`Send(chID, msgBytes)` is a blocking call that waits until `msg` is
@@ -601,7 +602,7 @@ type ChannelStatus struct {
RecentlySent int64
}
-//-----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
// ChannelID is an arbitrary channel ID.
type ChannelID uint16
diff --git a/internal/p2p/peermanager.go b/internal/p2p/peermanager.go
index cd0a63cb1f..22c5472b5c 100644
--- a/internal/p2p/peermanager.go
+++ b/internal/p2p/peermanager.go
@@ -255,27 +255,27 @@ func (o *PeerManagerOptions) optimize() {
// by the Router), only the peer lifecycle state.
//
// For an outbound connection, the flow is as follows:
-// - DialNext: return a peer address to dial, mark peer as dialing.
-// - DialFailed: report a dial failure, unmark as dialing.
-// - Dialed: report a dial success, unmark as dialing and mark as connected
-// (errors if already connected, e.g. by Accepted).
-// - Ready: report routing is ready, mark as ready and broadcast PeerStatusUp.
-// - Disconnected: report peer disconnect, unmark as connected and broadcasts
-// PeerStatusDown.
+// - DialNext: return a peer address to dial, mark peer as dialing.
+// - DialFailed: report a dial failure, unmark as dialing.
+// - Dialed: report a dial success, unmark as dialing and mark as connected
+// (errors if already connected, e.g. by Accepted).
+// - Ready: report routing is ready, mark as ready and broadcast PeerStatusUp.
+// - Disconnected: report peer disconnect, unmark as connected and broadcasts
+// PeerStatusDown.
//
// For an inbound connection, the flow is as follows:
-// - Accepted: report inbound connection success, mark as connected (errors if
-// already connected, e.g. by Dialed).
-// - Ready: report routing is ready, mark as ready and broadcast PeerStatusUp.
-// - Disconnected: report peer disconnect, unmark as connected and broadcasts
-// PeerStatusDown.
+// - Accepted: report inbound connection success, mark as connected (errors if
+// already connected, e.g. by Dialed).
+// - Ready: report routing is ready, mark as ready and broadcast PeerStatusUp.
+// - Disconnected: report peer disconnect, unmark as connected and broadcasts
+// PeerStatusDown.
//
// When evicting peers, either because peers are explicitly scheduled for
// eviction or we are connected to too many peers, the flow is as follows:
-// - EvictNext: if marked evict and connected, unmark evict and mark evicting.
-// If beyond MaxConnected, pick lowest-scored peer and mark evicting.
-// - Disconnected: unmark connected, evicting, evict, and broadcast a
-// PeerStatusDown peer update.
+// - EvictNext: if marked evict and connected, unmark evict and mark evicting.
+// If beyond MaxConnected, pick lowest-scored peer and mark evicting.
+// - Disconnected: unmark connected, evicting, evict, and broadcast a
+// PeerStatusDown peer update.
//
// If all connection slots are full (at MaxConnections), we can use up to
// MaxConnectionsUpgrade additional connections to probe any higher-scored
@@ -283,13 +283,13 @@ func (o *PeerManagerOptions) optimize() {
// connection and evict a lower-scored peer. We mark the lower-scored peer as
// upgrading[from]=to to make sure no other higher-scored peers can claim the
// same one for an upgrade. The flow is as follows:
-// - Accepted: if upgrade is possible, mark connected and add lower-scored to evict.
-// - DialNext: if upgrade is possible, mark upgrading[from]=to and dialing.
-// - DialFailed: unmark upgrading[from]=to and dialing.
-// - Dialed: unmark upgrading[from]=to and dialing, mark as connected, add
-// lower-scored to evict.
-// - EvictNext: pick peer from evict, mark as evicting.
-// - Disconnected: unmark connected, upgrading[from]=to, evict, evicting.
+// - Accepted: if upgrade is possible, mark connected and add lower-scored to evict.
+// - DialNext: if upgrade is possible, mark upgrading[from]=to and dialing.
+// - DialFailed: unmark upgrading[from]=to and dialing.
+// - Dialed: unmark upgrading[from]=to and dialing, mark as connected, add
+// lower-scored to evict.
+// - EvictNext: pick peer from evict, mark as evicting.
+// - Disconnected: unmark connected, upgrading[from]=to, evict, evicting.
type PeerManager struct {
selfID types.NodeID
options PeerManagerOptions
diff --git a/internal/p2p/router.go b/internal/p2p/router.go
index c89ef88fa6..6e5f750650 100644
--- a/internal/p2p/router.go
+++ b/internal/p2p/router.go
@@ -107,33 +107,33 @@ func (o *RouterOptions) Validate() error {
//
// On startup, three main goroutines are spawned to maintain peer connections:
//
-// dialPeers(): in a loop, calls PeerManager.DialNext() to get the next peer
-// address to dial and spawns a goroutine that dials the peer, handshakes
-// with it, and begins to route messages if successful.
+// dialPeers(): in a loop, calls PeerManager.DialNext() to get the next peer
+// address to dial and spawns a goroutine that dials the peer, handshakes
+// with it, and begins to route messages if successful.
//
-// acceptPeers(): in a loop, waits for an inbound connection via
-// Transport.Accept() and spawns a goroutine that handshakes with it and
-// begins to route messages if successful.
+// acceptPeers(): in a loop, waits for an inbound connection via
+// Transport.Accept() and spawns a goroutine that handshakes with it and
+// begins to route messages if successful.
//
-// evictPeers(): in a loop, calls PeerManager.EvictNext() to get the next
-// peer to evict, and disconnects it by closing its message queue.
+// evictPeers(): in a loop, calls PeerManager.EvictNext() to get the next
+// peer to evict, and disconnects it by closing its message queue.
//
// When a peer is connected, an outbound peer message queue is registered in
// peerQueues, and routePeer() is called to spawn off two additional goroutines:
//
-// sendPeer(): waits for an outbound message from the peerQueues queue,
-// marshals it, and passes it to the peer transport which delivers it.
+// sendPeer(): waits for an outbound message from the peerQueues queue,
+// marshals it, and passes it to the peer transport which delivers it.
//
-// receivePeer(): waits for an inbound message from the peer transport,
-// unmarshals it, and passes it to the appropriate inbound channel queue
-// in channelQueues.
+// receivePeer(): waits for an inbound message from the peer transport,
+// unmarshals it, and passes it to the appropriate inbound channel queue
+// in channelQueues.
//
// When a reactor opens a channel via OpenChannel, an inbound channel message
// queue is registered in channelQueues, and a channel goroutine is spawned:
//
-// routeChannel(): waits for an outbound message from the channel, looks
-// up the recipient peer's outbound message queue in peerQueues, and submits
-// the message to it.
+// routeChannel(): waits for an outbound message from the channel, looks
+// up the recipient peer's outbound message queue in peerQueues, and submits
+// the message to it.
//
// All channel sends in the router are blocking. It is the responsibility of the
// queue interface in peerQueues and channelQueues to prioritize and drop
diff --git a/internal/pubsub/pubsub.go b/internal/pubsub/pubsub.go
index c0ad4ae3c7..f76f3f2187 100644
--- a/internal/pubsub/pubsub.go
+++ b/internal/pubsub/pubsub.go
@@ -10,28 +10,27 @@
//
// Example:
//
-// q, err := query.New(`account.name='John'`)
-// if err != nil {
-// return err
-// }
-// sub, err := pubsub.SubscribeWithArgs(ctx, pubsub.SubscribeArgs{
-// ClientID: "johns-transactions",
-// Query: q,
-// })
-// if err != nil {
-// return err
-// }
-//
-// for {
-// next, err := sub.Next(ctx)
-// if err == pubsub.ErrTerminated {
-// return err // terminated by publisher
-// } else if err != nil {
-// return err // timed out, client unsubscribed, etc.
-// }
-// process(next)
-// }
+// q, err := query.New(`account.name='John'`)
+// if err != nil {
+// return err
+// }
+// sub, err := pubsub.SubscribeWithArgs(ctx, pubsub.SubscribeArgs{
+// ClientID: "johns-transactions",
+// Query: q,
+// })
+// if err != nil {
+// return err
+// }
//
+// for {
+// next, err := sub.Next(ctx)
+// if err == pubsub.ErrTerminated {
+// return err // terminated by publisher
+// } else if err != nil {
+// return err // timed out, client unsubscribed, etc.
+// }
+// process(next)
+// }
package pubsub
import (
diff --git a/internal/pubsub/query/query.go b/internal/pubsub/query/query.go
index 23510a75d2..cba494729a 100644
--- a/internal/pubsub/query/query.go
+++ b/internal/pubsub/query/query.go
@@ -4,12 +4,11 @@
// Query expressions describe properties of events and their attributes, using
// strings like:
//
-// abci.invoice.number = 22 AND abci.invoice.owner = 'Ivan'
+// abci.invoice.number = 22 AND abci.invoice.owner = 'Ivan'
//
// Query expressions can handle attribute values encoding numbers, strings,
// dates, and timestamps. The complete query grammar is described in the
// query/syntax package.
-//
package query
import (
@@ -207,6 +206,7 @@ func parseNumber(s string) (float64, error) {
// An entry does not exist if the combination is not valid.
//
// Disable the dupl lint for this map. The result isn't even correct.
+//
//nolint:dupl
var opTypeMap = map[syntax.Token]map[syntax.Token]func(interface{}) func(string) bool{
syntax.TContains: {
diff --git a/internal/pubsub/query/query_test.go b/internal/pubsub/query/query_test.go
index fc5fd82f00..f6affb2d92 100644
--- a/internal/pubsub/query/query_test.go
+++ b/internal/pubsub/query/query_test.go
@@ -12,14 +12,14 @@ import (
)
// Example events from the OpenAPI documentation:
-// https://github.com/tendermint/tendermint/blob/master/rpc/openapi/openapi.yaml
+//
+// https://github.com/tendermint/tendermint/blob/master/rpc/openapi/openapi.yaml
//
// Redactions:
//
// - Add an explicit "tm" event for the built-in attributes.
// - Remove Index fields (not relevant to tests).
// - Add explicit balance values (to use in tests).
-//
var apiEvents = []types.Event{
{
Type: "tm",
diff --git a/internal/pubsub/query/syntax/doc.go b/internal/pubsub/query/syntax/doc.go
index e7a9896c44..c6bedc381e 100644
--- a/internal/pubsub/query/syntax/doc.go
+++ b/internal/pubsub/query/syntax/doc.go
@@ -1,34 +1,33 @@
// Package syntax defines a scanner and parser for the Tendermint event filter
// query language. A query selects events by their types and attribute values.
//
-// Grammar
+// # Grammar
//
// The grammar of the query language is defined by the following EBNF:
//
-// query = conditions EOF
-// conditions = condition {"AND" condition}
-// condition = tag comparison
-// comparison = equal / order / contains / "EXISTS"
-// equal = "=" (date / number / time / value)
-// order = cmp (date / number / time)
-// contains = "CONTAINS" value
-// cmp = "<" / "<=" / ">" / ">="
+// query = conditions EOF
+// conditions = condition {"AND" condition}
+// condition = tag comparison
+// comparison = equal / order / contains / "EXISTS"
+// equal = "=" (date / number / time / value)
+// order = cmp (date / number / time)
+// contains = "CONTAINS" value
+// cmp = "<" / "<=" / ">" / ">="
//
// The lexical terms are defined here using RE2 regular expression notation:
//
-// // The name of an event attribute (type.value)
-// tag = #'\w+(\.\w+)*'
+// // The name of an event attribute (type.value)
+// tag = #'\w+(\.\w+)*'
//
-// // A datestamp (YYYY-MM-DD)
-// date = #'DATE \d{4}-\d{2}-\d{2}'
+// // A datestamp (YYYY-MM-DD)
+// date = #'DATE \d{4}-\d{2}-\d{2}'
//
-// // A number with optional fractional parts (0, 10, 3.25)
-// number = #'\d+(\.\d+)?'
+// // A number with optional fractional parts (0, 10, 3.25)
+// number = #'\d+(\.\d+)?'
//
-// // An RFC3339 timestamp (2021-11-23T22:04:19-09:00)
-// time = #'TIME \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}([-+]\d{2}:\d{2}|Z)'
-//
-// // A quoted literal string value ('a b c')
-// value = #'\'[^\']*\''
+// // An RFC3339 timestamp (2021-11-23T22:04:19-09:00)
+// time = #'TIME \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}([-+]\d{2}:\d{2}|Z)'
//
+// // A quoted literal string value ('a b c')
+// value = #'\'[^\']*\''
package syntax
diff --git a/internal/rpc/core/env.go b/internal/rpc/core/env.go
index 75ff14ed90..8cba589758 100644
--- a/internal/rpc/core/env.go
+++ b/internal/rpc/core/env.go
@@ -62,7 +62,7 @@ type peerManager interface {
Addresses(types.NodeID) []p2p.NodeAddress
}
-//----------------------------------------------
+// ----------------------------------------------
// Environment contains objects and interfaces used by the RPC. It is expected
// to be setup once during startup.
type Environment struct {
diff --git a/internal/state/current_round_state.go b/internal/state/current_round_state.go
index a33bb79fbf..b929511eb3 100644
--- a/internal/state/current_round_state.go
+++ b/internal/state/current_round_state.go
@@ -5,7 +5,6 @@ import (
"fmt"
abci "github.com/tendermint/tendermint/abci/types"
- "github.com/tendermint/tendermint/crypto"
tmbytes "github.com/tendermint/tendermint/libs/bytes"
tmtypes "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/tendermint/tendermint/types"
@@ -106,19 +105,6 @@ func (candidate *CurrentRoundState) UpdateFunc(state State) (State, error) {
return state, err
}
-func (candidate *CurrentRoundState) StateID() types.StateID {
- var appHash tmbytes.HexBytes
- if len(candidate.AppHash) > 0 {
- appHash = candidate.AppHash.Copy()
- } else {
- appHash = make([]byte, crypto.DefaultAppHashSize)
- }
- return types.StateID{
- Height: candidate.GetHeight(),
- AppHash: appHash,
- }
-}
-
// GetHeight returns height of current block
func (candidate *CurrentRoundState) GetHeight() int64 {
if candidate.Base.LastBlockHeight == 0 {
diff --git a/internal/state/execution.go b/internal/state/execution.go
index 6f7af2bde4..643cc44189 100644
--- a/internal/state/execution.go
+++ b/internal/state/execution.go
@@ -64,13 +64,6 @@ func BockExecWithMetrics(metrics *Metrics) func(e *BlockExecutor) {
}
}
-// BlockExecWithAppHashSize is an option function to set an app-hash size to BlockExecutor
-func BlockExecWithAppHashSize(size int) func(e *BlockExecutor) {
- return func(e *BlockExecutor) {
- e.appHashSize = size
- }
-}
-
// BlockExecWithAppClient sets application client to BlockExecutor
func BlockExecWithAppClient(appClient abciclient.Client) func(e *BlockExecutor) {
return func(e *BlockExecutor) {
@@ -141,7 +134,7 @@ func (blockExec *BlockExecutor) CreateProposalBlock(
height int64,
round int32,
state State,
- lastCommit *types.Commit,
+ commit *types.Commit,
proposerProTxHash []byte,
proposedAppVersion uint64,
) (*types.Block, CurrentRoundState, error) {
@@ -151,7 +144,10 @@ func (blockExec *BlockExecutor) CreateProposalBlock(
evidence, evSize := blockExec.evpool.PendingEvidence(state.ConsensusParams.Evidence.MaxBytes)
// Fetch a limited amount of valid txs
- maxDataBytes := types.MaxDataBytes(maxBytes, crypto.BLS12381, evSize, state.Validators.Size())
+ maxDataBytes, err := types.MaxDataBytes(maxBytes, commit, evSize)
+ if err != nil {
+ return nil, CurrentRoundState{}, fmt.Errorf("create proposal block: %w", err)
+ }
// Pass proposed app version only if it's higher than current network app version
if proposedAppVersion <= state.Version.Consensus.App {
@@ -159,7 +155,7 @@ func (blockExec *BlockExecutor) CreateProposalBlock(
}
txs := blockExec.mempool.ReapMaxBytesMaxGas(maxDataBytes, maxGas)
- block := state.MakeBlock(height, txs, lastCommit, evidence, proposerProTxHash, proposedAppVersion)
+ block := state.MakeBlock(height, txs, commit, evidence, proposerProTxHash, proposedAppVersion)
localLastCommit := buildLastCommitInfo(block, state.InitialHeight)
version := block.Version.ToProto()
@@ -355,7 +351,7 @@ func (blockExec *BlockExecutor) ValidateBlockWithRoundState(
if block.Height > state.InitialHeight {
if err := state.LastValidators.VerifyCommit(
- state.ChainID, state.LastBlockID, state.LastStateID, block.Height-1, block.LastCommit); err != nil {
+ state.ChainID, state.LastBlockID, block.Height-1, block.LastCommit); err != nil {
return fmt.Errorf("error validating block: %w", err)
}
}
@@ -578,7 +574,6 @@ func buildLastCommitInfo(block *types.Block, initialHeight int64) abci.CommitInf
Round: block.LastCommit.Round,
QuorumHash: block.LastCommit.QuorumHash,
BlockSignature: block.LastCommit.ThresholdBlockSignature,
- StateSignature: block.LastCommit.ThresholdStateSignature,
ThresholdVoteExtensions: types.ThresholdExtensionSignToProto(block.LastCommit.ThresholdVoteExtensions),
}
}
@@ -592,7 +587,7 @@ func (state State) Update(
nextVersion := state.Version
- // NOTE: the AppHash and the VoteExtension has not been populated.
+ // NOTE: LastStateIDHash, AppHash and VoteExtension has not been populated.
// It will be filled on state.Save.
newState := State{
Version: nextVersion,
@@ -600,7 +595,6 @@ func (state State) Update(
InitialHeight: state.InitialHeight,
LastBlockHeight: header.Height,
LastBlockID: blockID,
- LastStateID: types.StateID{Height: header.Height, AppHash: header.AppHash},
LastBlockTime: header.Time,
LastCoreChainLockedBlockHeight: state.LastCoreChainLockedBlockHeight,
Validators: state.Validators.Copy(),
diff --git a/internal/state/execution_test.go b/internal/state/execution_test.go
index 623efe83af..79be025598 100644
--- a/internal/state/execution_test.go
+++ b/internal/state/execution_test.go
@@ -252,7 +252,7 @@ func TestProcessProposal(t *testing.T) {
Signature: make([]byte, bls12381.SignatureSize),
}
- lastCommit := types.NewCommit(height-1, 0, types.BlockID{}, types.StateID{}, nil)
+ lastCommit := types.NewCommit(height-1, 0, types.BlockID{}, nil)
block1, err := sf.MakeBlock(state, height, lastCommit, 1)
require.NoError(t, err)
block1.SetCoreChainLock(&coreChainLockUpdate)
@@ -546,12 +546,12 @@ func TestFinalizeBlockValidatorUpdates(t *testing.T) {
1,
round,
state,
- types.NewCommit(state.LastBlockHeight, 0, state.LastBlockID, state.LastStateID, nil),
+ types.NewCommit(state.LastBlockHeight, 0, state.LastBlockID, nil),
proTxHashes[0],
1,
)
require.NoError(t, err)
- blockID, err := block.BlockID()
+ blockID := block.BlockID(nil)
require.NoError(t, err)
state, err = blockExec.FinalizeBlock(ctx, state, uncommittedState, blockID, block, new(types.Commit))
require.NoError(t, err)
@@ -685,7 +685,7 @@ func TestEmptyPrepareProposal(t *testing.T) {
eventBus,
)
proposer := state.Validators.GetByIndex(0)
- commit, _ := makeValidCommit(ctx, t, height, types.BlockID{}, types.StateID{}, state.Validators, privVals)
+ commit, _ := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
_, _, err = blockExec.CreateProposalBlock(ctx, height, 0, state, commit, proposer.ProTxHash, 0)
require.NoError(t, err)
}
@@ -741,7 +741,7 @@ func TestPrepareProposalErrorOnNonExistingRemoved(t *testing.T) {
eventBus,
)
proposer := state.Validators.GetByIndex(0)
- commit, _ := makeValidCommit(ctx, t, height, types.BlockID{}, types.StateID{}, state.Validators, privVals)
+ commit, _ := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
block, _, err := blockExec.CreateProposalBlock(ctx, height, 0, state, commit, proposer.ProTxHash, 0)
require.ErrorContains(t, err, "new transaction incorrectly marked as removed")
require.Nil(t, block)
@@ -799,7 +799,7 @@ func TestPrepareProposalRemoveTxs(t *testing.T) {
eventBus,
)
val := state.Validators.GetByIndex(0)
- commit, _ := makeValidCommit(ctx, t, height, types.BlockID{}, types.StateID{}, state.Validators, privVals)
+ commit, _ := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
block, _, err := blockExec.CreateProposalBlock(ctx, height, 0, state, commit, val.ProTxHash, 0)
require.NoError(t, err)
require.Len(t, block.Data.Txs.ToSliceOfBytes(), len(trs)-2)
@@ -860,7 +860,7 @@ func TestPrepareProposalAddedTxsIncluded(t *testing.T) {
eventBus,
)
proposer := state.Validators.GetByIndex(0)
- commit, _ := makeValidCommit(ctx, t, height, types.BlockID{}, types.StateID{}, state.Validators, privVals)
+ commit, _ := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
block, _, err := blockExec.CreateProposalBlock(ctx, height, 0, state, commit, proposer.ProTxHash, 0)
require.NoError(t, err)
@@ -920,7 +920,7 @@ func TestPrepareProposalReorderTxs(t *testing.T) {
eventBus,
)
proposer := state.Validators.GetByIndex(0)
- commit, _ := makeValidCommit(ctx, t, height, types.BlockID{}, types.StateID{}, state.Validators, privVals)
+ commit, _ := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
block, _, err := blockExec.CreateProposalBlock(ctx, height, 0, state, commit, proposer.ProTxHash, 0)
require.NoError(t, err)
for i, tx := range block.Data.Txs {
@@ -934,7 +934,11 @@ func TestPrepareProposalReorderTxs(t *testing.T) {
// TestPrepareProposalErrorOnTooManyTxs tests that the block creation logic returns
// an error if the ResponsePrepareProposal returned from the application is invalid.
func TestPrepareProposalErrorOnTooManyTxs(t *testing.T) {
- const height = 2
+ const (
+ height = 2
+ bytesPerTx int64 = 3
+ )
+
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
@@ -950,9 +954,10 @@ func TestPrepareProposalErrorOnTooManyTxs(t *testing.T) {
evpool := &mocks.EvidencePool{}
evpool.On("PendingEvidence", mock.Anything).Return([]types.Evidence{}, int64(0))
- const nValidators = 1
- var bytesPerTx int64 = 3
- maxDataBytes := types.MaxDataBytes(state.ConsensusParams.Block.MaxBytes, crypto.BLS12381, 0, nValidators)
+ commit, _ := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
+
+ maxDataBytes, err := types.MaxDataBytes(state.ConsensusParams.Block.MaxBytes, commit, 0)
+ require.NoError(t, err)
txs := factory.MakeNTxs(height, maxDataBytes/bytesPerTx+2) // +2 so that tx don't fit
mp := &mpmocks.Mempool{}
mp.On("ReapMaxBytesMaxGas", mock.Anything, mock.Anything).Return(txs)
@@ -968,7 +973,7 @@ func TestPrepareProposalErrorOnTooManyTxs(t *testing.T) {
cc := abciclient.NewLocalClient(logger, app)
proxyApp := proxy.New(cc, logger, proxy.NopMetrics())
- err := proxyApp.Start(ctx)
+ err = proxyApp.Start(ctx)
require.NoError(t, err)
blockExec := sm.NewBlockExecutor(
@@ -980,7 +985,6 @@ func TestPrepareProposalErrorOnTooManyTxs(t *testing.T) {
eventBus,
)
proposer := state.Validators.GetByIndex(0)
- commit, _ := makeValidCommit(ctx, t, height, types.BlockID{}, types.StateID{}, state.Validators, privVals)
block, _, err := blockExec.CreateProposalBlock(ctx, height, 0, state, commit, proposer.ProTxHash, 0)
require.ErrorContains(t, err, "transaction data size exceeds maximum")
@@ -1030,7 +1034,7 @@ func TestPrepareProposalErrorOnPrepareProposalError(t *testing.T) {
eventBus,
)
val := state.Validators.GetByIndex(0)
- commit, _ := makeValidCommit(ctx, t, height, types.BlockID{}, types.StateID{}, state.Validators, privVals)
+ commit, _ := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
block, _, err := blockExec.CreateProposalBlock(ctx, height, 0, state, commit, val.ProTxHash, 0)
require.Nil(t, block)
diff --git a/internal/state/helpers_test.go b/internal/state/helpers_test.go
index 78963c4001..26ca6b9109 100644
--- a/internal/state/helpers_test.go
+++ b/internal/state/helpers_test.go
@@ -1,4 +1,3 @@
-// nolint: lll
package state_test
import (
@@ -56,7 +55,7 @@ func makeAndCommitGoodBlock(
uncommittedState, err := blockExec.ProcessProposal(ctx, block, 0, state, true)
require.NoError(t, err)
// Simulate a lastCommit for this block from all validators for the next height
- commit, _ := makeValidCommit(ctx, t, height, blockID, uncommittedState.StateID(), state.Validators, privVals)
+ commit, _ := makeValidCommit(ctx, t, height, blockID, state.Validators, privVals)
state, err = blockExec.FinalizeBlock(ctx, state, uncommittedState, blockID, block, commit)
require.NoError(t, err)
@@ -76,7 +75,10 @@ func makeAndApplyGoodBlock(
block := state.MakeBlock(height, factory.MakeNTxs(height, 10), lastCommit, evidence, proposerProTxHash, proposedAppVersion)
partSet, err := block.MakePartSet(types.BlockPartSizeBytes)
require.NoError(t, err)
- blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: partSet.Header()}
+
+ blockID := block.BlockID(partSet)
+ require.NoError(t, err)
+
return state, blockID, block
}
@@ -85,7 +87,6 @@ func makeValidCommit(
t *testing.T,
height int64,
blockID types.BlockID,
- stateID types.StateID,
vals *types.ValidatorSet,
privVals map[string]types.PrivValidator,
) (*types.Commit, []*types.Vote) {
@@ -93,7 +94,7 @@ func makeValidCommit(
votes := make([]*types.Vote, vals.Size())
for i := 0; i < vals.Size(); i++ {
val := vals.GetByIndex(int32(i))
- vote, err := factory.MakeVote(ctx, privVals[val.ProTxHash.String()], vals, chainID, int32(i), height, 0, 2, blockID, stateID.AppHash)
+ vote, err := factory.MakeVote(ctx, privVals[val.ProTxHash.String()], vals, chainID, int32(i), height, 0, 2, blockID)
require.NoError(t, err)
votes[i] = vote
}
@@ -102,7 +103,6 @@ func makeValidCommit(
return types.NewCommit(
height, 0,
blockID,
- stateID,
&types.CommitSigns{
QuorumSigns: *thresholdSigns,
QuorumHash: vals.QuorumHash,
diff --git a/internal/state/rollback.go b/internal/state/rollback.go
index 731f27b1bd..9818b8da22 100644
--- a/internal/state/rollback.go
+++ b/internal/state/rollback.go
@@ -38,7 +38,6 @@ func Rollback(bs BlockStore, ss Store) (int64, []byte, error) {
// state store height is equal to blockstore height. We're good to proceed with rolling back state
rollbackHeight := invalidState.LastBlockHeight - 1
rollbackBlock := bs.LoadBlockMeta(rollbackHeight)
- commit := bs.LoadBlockCommit(rollbackHeight)
if rollbackBlock == nil {
return -1, nil, fmt.Errorf("block at height %d not found", rollbackHeight)
@@ -87,7 +86,6 @@ func Rollback(bs BlockStore, ss Store) (int64, []byte, error) {
LastBlockHeight: rollbackBlock.Header.Height,
LastBlockID: rollbackBlock.BlockID,
LastBlockTime: rollbackBlock.Header.Time,
- LastStateID: commit.StateID,
LastCoreChainLockedBlockHeight: rollbackBlock.Header.CoreChainLockedHeight,
diff --git a/internal/state/rollback_test.go b/internal/state/rollback_test.go
index f11ac0c2f6..02c939f56d 100644
--- a/internal/state/rollback_test.go
+++ b/internal/state/rollback_test.go
@@ -50,7 +50,6 @@ func TestRollback(t *testing.T) {
ResultsHash: initialState.LastResultsHash,
},
}
- commit := &types.Commit{}
nextBlock := &types.BlockMeta{
BlockID: initialState.LastBlockID,
Header: types.Header{
@@ -61,7 +60,6 @@ func TestRollback(t *testing.T) {
},
}
blockStore.On("LoadBlockMeta", height).Return(block)
- blockStore.On("LoadBlockCommit", height).Return(commit)
blockStore.On("LoadBlockMeta", nextHeight).Return(nextBlock)
blockStore.On("Height").Return(nextHeight)
diff --git a/internal/state/state.go b/internal/state/state.go
index cf4109f8b1..05b2ce1a30 100644
--- a/internal/state/state.go
+++ b/internal/state/state.go
@@ -81,9 +81,6 @@ type State struct {
LastBlockID types.BlockID
LastBlockTime time.Time
- // LastStateID contains App Hash and Height from previous state (at height-1)
- LastStateID types.StateID
-
// Last Chain Lock is the last known chain locked height in consensus
// It does not go to 0 if a block had no chain lock and should stay the same as the previous block
LastCoreChainLockedBlockHeight uint32
@@ -132,8 +129,6 @@ func (state State) Copy() State {
LastBlockID: state.LastBlockID,
LastBlockTime: state.LastBlockTime,
- LastStateID: state.LastStateID.Copy(),
-
LastCoreChainLockedBlockHeight: state.LastCoreChainLockedBlockHeight,
Validators: state.Validators.Copy(),
@@ -204,8 +199,6 @@ func (state *State) ToProto() (*tmstate.State, error) {
}
sm.Validators = vals
- sm.LastStateID = state.LastStateID.ToProto()
-
if state.LastBlockHeight >= 1 { // At Block 1 LastValidators is nil
lVals, err := state.LastValidators.ToProto()
if err != nil {
@@ -243,13 +236,6 @@ func FromProto(pb *tmstate.State) (*State, error) { //nolint:golint
state.LastBlockHeight = pb.LastBlockHeight
state.LastBlockTime = pb.LastBlockTime
- si, err := types.StateIDFromProto(&pb.LastStateID)
- if err != nil {
- return nil, err
- }
-
- state.LastStateID = *si
-
state.LastCoreChainLockedBlockHeight = pb.LastCoreChainLockedBlockHeight
vals, err := types.ValidatorSetFromProto(pb.Validators)
@@ -378,11 +364,6 @@ func MakeGenesisState(genDoc *types.GenesisDoc) (State, error) {
)
}
- stateID := types.StateID{
- Height: genDoc.InitialHeight,
- AppHash: genDoc.AppHash,
- }
-
return State{
Version: InitStateVersion,
ChainID: genDoc.ChainID,
@@ -390,7 +371,6 @@ func MakeGenesisState(genDoc *types.GenesisDoc) (State, error) {
LastBlockHeight: 0,
LastBlockID: types.BlockID{},
- LastStateID: stateID,
LastBlockTime: genDoc.GenesisTime,
LastCoreChainLockedBlockHeight: genDoc.InitialCoreChainLockedHeight,
diff --git a/internal/state/state_test.go b/internal/state/state_test.go
index 7a71d5ca3c..5ae0b05cb8 100644
--- a/internal/state/state_test.go
+++ b/internal/state/state_test.go
@@ -1,4 +1,3 @@
-// nolint: lll
package state_test
import (
@@ -23,8 +22,6 @@ import (
"github.com/tendermint/tendermint/dash/llmq"
sm "github.com/tendermint/tendermint/internal/state"
statefactory "github.com/tendermint/tendermint/internal/state/test/factory"
- tmbytes "github.com/tendermint/tendermint/libs/bytes"
- tmrand "github.com/tendermint/tendermint/libs/rand"
tmstate "github.com/tendermint/tendermint/proto/tendermint/state"
"github.com/tendermint/tendermint/types"
)
@@ -482,7 +479,7 @@ func TestProposerPriorityDoesNotGetResetToZero(t *testing.T) {
block, err := statefactory.MakeBlock(state, state.LastBlockHeight+1, new(types.Commit), 0)
require.NoError(t, err)
- blockID, err := block.BlockID()
+ blockID := block.BlockID(nil)
require.NoError(t, err)
// Any node pro tx hash should do
@@ -624,7 +621,7 @@ func TestProposerPriorityProposerAlternates(t *testing.T) {
block, err := statefactory.MakeBlock(state, state.LastBlockHeight+1, new(types.Commit), 0)
require.NoError(t, err)
- blockID, err := block.BlockID()
+ blockID := block.BlockID(nil)
require.NoError(t, err)
// no updates:
@@ -1119,33 +1116,13 @@ func TestStateProto(t *testing.T) {
}
}
-func TestState_StateID(t *testing.T) {
- vset, _ := types.RandValidatorSet(1)
-
- state := sm.State{
- LastBlockHeight: 2,
- Validators: vset,
- }
-
- want := tmbytes.HexBytes(tmrand.Bytes(32))
- changes, err := state.NewStateChangeset(context.TODO(), sm.RoundParams{AppHash: want.Copy()})
- require.NoError(t, err)
-
- stateID := changes.StateID()
- assert.Equal(t, int64(3), stateID.Height)
- assert.EqualValues(t, want, stateID.AppHash)
-
- err = stateID.ValidateBasic()
- assert.NoError(t, err, "StateID validation failed")
-}
-
func blockExecutorFunc(ctx context.Context, t *testing.T) func(prevState, state sm.State, ucState sm.CurrentRoundState) sm.State {
return func(prevState, state sm.State, ucState sm.CurrentRoundState) sm.State {
t.Helper()
block, err := statefactory.MakeBlock(prevState, prevState.LastBlockHeight+1, new(types.Commit), 0)
require.NoError(t, err)
- blockID, err := block.BlockID()
+ blockID := block.BlockID(nil)
require.NoError(t, err)
state, err = state.Update(blockID, &block.Header, &ucState)
diff --git a/internal/state/test/factory/block.go b/internal/state/test/factory/block.go
index 36f7b121a3..05a4fab9f8 100644
--- a/internal/state/test/factory/block.go
+++ b/internal/state/test/factory/block.go
@@ -84,7 +84,7 @@ func makeBlockAndPartSet(
t.Helper()
quorumSigns := &types.CommitSigns{QuorumHash: state.LastValidators.QuorumHash}
- lastCommit := types.NewCommit(height-1, 0, types.BlockID{}, state.LastStateID, quorumSigns)
+ lastCommit := types.NewCommit(height-1, 0, types.BlockID{}, quorumSigns)
if height > 1 {
vote, err := factory.MakeVote(
ctx,
@@ -93,7 +93,6 @@ func makeBlockAndPartSet(
lastBlock.Header.ChainID,
1, lastBlock.Header.Height, 0, 2,
lastBlockMeta.BlockID,
- lastBlock.AppHash,
)
require.NoError(t, err)
thresholdSigns, err := types.NewSignsRecoverer([]*types.Vote{vote}).Recover()
@@ -102,7 +101,6 @@ func makeBlockAndPartSet(
vote.Height,
vote.Round,
lastBlockMeta.BlockID,
- state.LastStateID,
&types.CommitSigns{
QuorumSigns: *thresholdSigns,
QuorumHash: state.LastValidators.QuorumHash,
diff --git a/internal/state/tx_filter.go b/internal/state/tx_filter.go
index 835ec16313..f8d2b91562 100644
--- a/internal/state/tx_filter.go
+++ b/internal/state/tx_filter.go
@@ -55,12 +55,12 @@ func TxPreCheckFromStore(store Store) mempool.PreCheckFunc {
func TxPreCheckForState(state State) mempool.PreCheckFunc {
return func(tx types.Tx) error {
- maxDataBytes := types.MaxDataBytesNoEvidence(
- state.ConsensusParams.Block.MaxBytes,
- )
+ maxDataBytes, err := types.MaxDataBytesNoEvidence(state.ConsensusParams.Block.MaxBytes)
+ if err != nil {
+ return err
+ }
return mempool.PreCheckMaxBytes(maxDataBytes)(tx)
}
-
}
// TxPostCheckFromStore returns a function to filter transactions after processing.
diff --git a/internal/state/tx_filter_test.go b/internal/state/tx_filter_test.go
index e664d18c4a..9e68ae45a2 100644
--- a/internal/state/tx_filter_test.go
+++ b/internal/state/tx_filter_test.go
@@ -1,6 +1,7 @@
package state_test
import (
+ "strconv"
"testing"
tmrand "github.com/tendermint/tendermint/libs/rand"
@@ -20,27 +21,29 @@ func TestTxFilter(t *testing.T) {
// Max size of Txs is much smaller than size of block,
// since we need to account for commits and evidence.
testCases := []struct {
- tx types.Tx
+ bytes int
isErr bool
}{
- {types.Tx(tmrand.Bytes(2120)), false},
- {types.Tx(tmrand.Bytes(2121)), true},
- {types.Tx(tmrand.Bytes(3000)), true},
+ {0, false},
+ {2153, false},
+ {2154, true},
+ {3000, true},
}
- // We get 2202 above as we have 80 more bytes in max bytes and we are using bls, so 2155 + 80 - 32 - 1 = 2202
- // The 32 is the signature difference size between edwards and bls
- // The 1 is the protobuf encoding difference because the sizes use signed integers and we are going from less
- // than 128 to over 128
-
for i, tc := range testCases {
- state, err := sm.MakeGenesisState(genDoc)
- require.NoError(t, err)
-
- f := sm.TxPreCheckForState(state)
- if tc.isErr {
- assert.NotNil(t, f(tc.tx), "#%v", i)
- } else {
- assert.Nil(t, f(tc.tx), "#%v", i)
- }
+ t.Run(strconv.Itoa(i), func(t *testing.T) {
+ state, err := sm.MakeGenesisState(genDoc)
+ require.NoError(t, err)
+ tx := types.Tx(tmrand.Bytes(tc.bytes))
+ // Read MaxDataBytes, for debugging/logging only
+ maxDataBytes, err := types.MaxDataBytes(state.ConsensusParams.Block.MaxBytes, nil, 0)
+ require.NoError(t, err)
+
+ f := sm.TxPreCheckForState(state)
+ if tc.isErr {
+ assert.NotNil(t, f(tx), "%+v, maxDataBytes:%d", tc, maxDataBytes)
+ } else {
+ assert.Nil(t, f(tx), "%+v, maxDataBytes:%d", tc, maxDataBytes)
+ }
+ })
}
}
diff --git a/internal/state/validation.go b/internal/state/validation.go
index 54817be9a6..7628612276 100644
--- a/internal/state/validation.go
+++ b/internal/state/validation.go
@@ -96,7 +96,7 @@ func validateBlock(state State, block *types.Block) error {
// state.LastStateID.String())
// LastPrecommits.Signatures length is checked in VerifyCommit.
if err := state.LastValidators.VerifyCommit(
- state.ChainID, state.LastBlockID, state.LastStateID, block.Height-1, block.LastCommit); err != nil {
+ state.ChainID, state.LastBlockID, block.Height-1, block.LastCommit); err != nil {
return fmt.Errorf("error validating block: %w", err)
}
}
diff --git a/internal/state/validation_test.go b/internal/state/validation_test.go
index 759092041c..950c7ff18b 100644
--- a/internal/state/validation_test.go
+++ b/internal/state/validation_test.go
@@ -78,7 +78,7 @@ func TestValidateBlockHeader(t *testing.T) {
})
require.NoError(t, err)
- lastCommit := types.NewCommit(0, 0, types.BlockID{}, changes.StateID(), nil)
+ lastCommit := types.NewCommit(0, 0, types.BlockID{}, nil)
// some bad values
wrongHash := crypto.Checksum([]byte("this hash is wrong"))
@@ -183,11 +183,6 @@ func TestValidateBlockCommit(t *testing.T) {
state, stateDB, privVals := makeState(t, 1, 1)
stateStore := sm.NewStore(stateDB)
- nextChainLock := &types.CoreChainLock{
- CoreBlockHeight: 100,
- CoreBlockHash: tmrand.Bytes(32),
- Signature: tmrand.Bytes(96),
- }
mp := &mpmocks.Mempool{}
mp.On("Lock").Return()
@@ -211,15 +206,12 @@ func TestValidateBlockCommit(t *testing.T) {
blockStore,
eventBus,
)
- lastCommit := types.NewCommit(0, 0, types.BlockID{}, types.StateID{}, nil)
- wrongVoteMessageSignedCommit := types.NewCommit(1, 0, types.BlockID{}, types.StateID{}, nil)
+ lastCommit := types.NewCommit(0, 0, types.BlockID{}, nil)
+ wrongVoteMessageSignedCommit := types.NewCommit(1, 0, types.BlockID{}, nil)
badPrivValQuorumHash := crypto.RandQuorumHash()
badPrivVal := types.NewMockPVForQuorum(badPrivValQuorumHash)
for height := int64(1); height < validationTestsStopHeight; height++ {
- changes, err := state.NewStateChangeset(ctx, sm.RoundParams{CoreChainLock: nextChainLock})
- require.NoError(t, err)
- stateID := changes.StateID()
proTxHash := state.Validators.GetProposer().ProTxHash
if height > 1 {
/*
@@ -235,7 +227,6 @@ func TestValidateBlockCommit(t *testing.T) {
0,
2,
state.LastBlockID,
- changes.AppHash,
)
require.NoError(t, err)
thresholdSigns, err := types.NewSignsRecoverer([]*types.Vote{wrongHeightVote}).Recover()
@@ -244,7 +235,6 @@ func TestValidateBlockCommit(t *testing.T) {
wrongHeightVote.Height,
wrongHeightVote.Round,
state.LastBlockID,
- stateID,
&types.CommitSigns{
QuorumSigns: *thresholdSigns,
QuorumHash: state.Validators.QuorumHash,
@@ -303,7 +293,6 @@ func TestValidateBlockCommit(t *testing.T) {
0,
2,
blockID,
- state.LastAppHash,
)
require.NoError(t, err, "height %d", height)
@@ -326,7 +315,6 @@ func TestValidateBlockCommit(t *testing.T) {
state.Validators.QuorumType,
badPrivValQuorumHash,
g,
- stateID,
nil,
)
require.NoError(t, err, "height %d", height)
@@ -335,13 +323,11 @@ func TestValidateBlockCommit(t *testing.T) {
state.Validators.QuorumType,
badPrivValQuorumHash,
b,
- stateID,
nil,
)
require.NoError(t, err, "height %d", height)
goodVote.BlockSignature, badVote.BlockSignature = g.BlockSignature, b.BlockSignature
- goodVote.StateSignature, badVote.StateSignature = g.StateSignature, b.StateSignature
goodVote.VoteExtensions = types.VoteExtensionsFromProto(g.VoteExtensions)
badVote.VoteExtensions = types.VoteExtensionsFromProto(b.VoteExtensions)
@@ -352,7 +338,7 @@ func TestValidateBlockCommit(t *testing.T) {
QuorumHash: state.Validators.QuorumHash,
}
wrongVoteMessageSignedCommit = types.NewCommit(goodVote.Height, goodVote.Round,
- blockID, stateID, quorumSigns)
+ blockID, quorumSigns)
}
}
@@ -399,7 +385,7 @@ func TestValidateBlockEvidence(t *testing.T) {
blockStore,
eventBus,
)
- lastCommit := types.NewCommit(0, 0, types.BlockID{}, types.StateID{}, nil)
+ lastCommit := types.NewCommit(0, 0, types.BlockID{}, nil)
for height := int64(1); height < validationTestsStopHeight; height++ {
proposerProTxHash := state.Validators.GetProposer().ProTxHash
diff --git a/internal/statesync/reactor_test.go b/internal/statesync/reactor_test.go
index aed3f7b9c0..4458f56467 100644
--- a/internal/statesync/reactor_test.go
+++ b/internal/statesync/reactor_test.go
@@ -459,7 +459,7 @@ func TestReactor_LightBlockResponse(t *testing.T) {
vals, pv := types.RandValidatorSet(1)
vote, err := factory.MakeVote(ctx, pv[0], vals, h.ChainID, 0, h.Height, 0, 2,
- blockID, h.AppHash)
+ blockID)
require.NoError(t, err)
sh := &types.SignedHeader{
@@ -467,10 +467,8 @@ func TestReactor_LightBlockResponse(t *testing.T) {
Commit: &types.Commit{
Height: h.Height,
BlockID: blockID,
- StateID: vote.StateID(),
QuorumHash: crypto.RandQuorumHash(),
ThresholdBlockSignature: vote.BlockSignature,
- ThresholdStateSignature: vote.StateSignature,
},
}
@@ -872,7 +870,8 @@ func buildLightBlockChain(ctx context.Context, t *testing.T, fromHeight, toHeigh
pk, _ := pv[0].GetPrivateKey(context.Background(), vals.QuorumHash)
privVal.UpdatePrivateKey(context.Background(), pk, vals.QuorumHash, vals.ThresholdPublicKey, height)
vals, pv, chain[height] = mockLB(ctx, t, height, blockTime, lastBlockID, vals, pv)
- lastBlockID = factory.MakeBlockIDWithHash(chain[height].Header.Hash())
+
+ lastBlockID = chain[height].Commit.BlockID
blockTime = blockTime.Add(1 * time.Minute)
}
return chain
@@ -894,10 +893,15 @@ func mockLB(ctx context.Context, t *testing.T, height int64, time time.Time, las
header.ValidatorsHash = currentVals.Hash()
header.NextValidatorsHash = nextVals.Hash()
header.ConsensusHash = types.DefaultConsensusParams().HashConsensusParams()
- lastBlockID = factory.MakeBlockIDWithHash(header.Hash())
- stateID := types.StateID{
- Height: height,
- AppHash: header.AppHash,
+ // lastBlockID = factory.MakeBlockIDWithHash(header.Hash())
+ stateID := header.StateID()
+ lastBlockID = types.BlockID{
+ Hash: header.Hash(),
+ PartSetHeader: types.PartSetHeader{
+ Total: 100,
+ Hash: factory.RandomHash(),
+ },
+ StateID: stateID.Hash(),
}
voteSet := types.NewVoteSet(factory.DefaultTestChainID, height, 0, tmproto.PrecommitType, currentVals)
commit, err := factory.MakeCommit(ctx, lastBlockID, height, 0, voteSet, currentVals, currentPrivVals, stateID)
diff --git a/internal/statesync/stateprovider.go b/internal/statesync/stateprovider.go
index 4654c61a89..6ccd553a32 100644
--- a/internal/statesync/stateprovider.go
+++ b/internal/statesync/stateprovider.go
@@ -156,7 +156,6 @@ func (s *stateProviderRPC) State(ctx context.Context, height uint64) (sm.State,
state.LastBlockHeight = lastLightBlock.Height
state.LastBlockTime = lastLightBlock.Time
state.LastBlockID = lastLightBlock.Commit.BlockID
- state.LastStateID = lastLightBlock.Commit.StateID
state.LastCoreChainLockedBlockHeight = lastLightBlock.Header.CoreChainLockedHeight
state.LastAppHash = currentLightBlock.AppHash
state.LastResultsHash = currentLightBlock.ResultsHash
@@ -298,7 +297,6 @@ func (s *stateProviderP2P) State(ctx context.Context, height uint64) (sm.State,
state.LastBlockHeight = lastLightBlock.Height
state.LastBlockTime = lastLightBlock.Time
state.LastBlockID = lastLightBlock.Commit.BlockID
- state.LastStateID = lastLightBlock.Commit.StateID
state.LastCoreChainLockedBlockHeight = lastLightBlock.Header.CoreChainLockedHeight
state.LastAppHash = currentLightBlock.AppHash
state.LastResultsHash = currentLightBlock.ResultsHash
diff --git a/internal/store/store_test.go b/internal/store/store_test.go
index 337abcdd38..58101f06b7 100644
--- a/internal/store/store_test.go
+++ b/internal/store/store_test.go
@@ -27,8 +27,14 @@ import (
// make a Commit with a single vote containing just the height and a timestamp
func makeTestCommit(state sm.State, height int64, timestamp time.Time) *types.Commit {
- blockID := types.BlockID{Hash: []byte(""), PartSetHeader: types.PartSetHeader{Hash: []byte(""), Total: 2}}
- stateID := types.RandStateID().WithHeight(height - 1)
+ blockID := types.BlockID{
+ Hash: []byte(""),
+ PartSetHeader: types.PartSetHeader{
+ Hash: []byte(""),
+ Total: 2,
+ },
+ StateID: []byte{},
+ }
goodVote := &types.Vote{
ValidatorProTxHash: crypto.RandProTxHash(),
ValidatorIndex: 0,
@@ -44,16 +50,18 @@ func makeTestCommit(state sm.State, height int64, timestamp time.Time) *types.Co
privVal := types.NewMockPVWithParams(privKey, crypto.RandProTxHash(), state.Validators.QuorumHash,
state.Validators.ThresholdPublicKey, false, false)
- _ = privVal.SignVote(context.Background(), "chainID", state.Validators.QuorumType, state.Validators.QuorumHash, g, stateID, nil)
+ _ = privVal.SignVote(context.Background(), "chainID", state.Validators.QuorumType, state.Validators.QuorumHash, g, nil)
goodVote.BlockSignature = g.BlockSignature
- goodVote.StateSignature = g.StateSignature
goodVote.VoteExtensions = types.VoteExtensionsFromProto(g.VoteExtensions)
thresholdSigns, _ := types.NewSignsRecoverer([]*types.Vote{goodVote}).Recover()
return types.NewCommit(height, 0,
- types.BlockID{Hash: []byte(""), PartSetHeader: types.PartSetHeader{Hash: []byte(""), Total: 2}},
- types.StateID{AppHash: make([]byte, 32)},
+ types.BlockID{
+ Hash: []byte(""),
+ PartSetHeader: types.PartSetHeader{Hash: []byte(""), Total: 2},
+ StateID: []byte{},
+ },
&types.CommitSigns{
QuorumSigns: *thresholdSigns,
QuorumHash: crypto.RandQuorumHash(),
@@ -113,6 +121,7 @@ func TestBlockStoreSaveLoadBlock(t *testing.T) {
ChainID: "block_test",
Time: tmtime.Now(),
ProposerProTxHash: tmrand.Bytes(crypto.DefaultHashSize),
+ ValidatorsHash: tmrand.Bytes(crypto.HashSize),
}
// End of setup, test data
@@ -148,6 +157,7 @@ func TestBlockStoreSaveLoadBlock(t *testing.T) {
Height: 5,
ChainID: "block_test",
Time: tmtime.Now(),
+ ValidatorsHash: tmrand.Bytes(crypto.DefaultHashSize),
ProposerProTxHash: tmrand.Bytes(crypto.DefaultHashSize)},
makeTestCommit(state, 5, tmtime.Now()),
),
@@ -216,6 +226,7 @@ func TestBlockStoreSaveLoadBlock(t *testing.T) {
for i, tuple := range tuples {
tuple := tuple
+
bs, db := newInMemoryBlockStore()
// SaveBlock
res, err, panicErr := doFn(func() (interface{}, error) {
diff --git a/internal/test/factory/block.go b/internal/test/factory/block.go
index ffd8b71dcb..bc8ba3a0e9 100644
--- a/internal/test/factory/block.go
+++ b/internal/test/factory/block.go
@@ -38,6 +38,7 @@ func MakeBlockIDWithHash(hash []byte) types.BlockID {
Total: 100,
Hash: RandomHash(),
},
+ StateID: types.RandStateID().Hash(),
}
}
diff --git a/internal/test/factory/commit.go b/internal/test/factory/commit.go
index c1bb0c3fba..720b8e8245 100644
--- a/internal/test/factory/commit.go
+++ b/internal/test/factory/commit.go
@@ -15,7 +15,7 @@ func MakeCommit(
voteSet *types.VoteSet,
validatorSet *types.ValidatorSet,
validators []types.PrivValidator,
- stateID types.StateID,
+ stateID tmproto.StateID,
) (*types.Commit, error) {
// all sign
for i := 0; i < len(validators); i++ {
@@ -34,10 +34,9 @@ func MakeCommit(
v := vote.ToProto()
- if err := validators[i].SignVote(ctx, voteSet.ChainID(), validatorSet.QuorumType, validatorSet.QuorumHash, v, stateID, nil); err != nil {
+ if err := validators[i].SignVote(ctx, voteSet.ChainID(), validatorSet.QuorumType, validatorSet.QuorumHash, v, nil); err != nil {
return nil, err
}
- vote.StateSignature = v.StateSignature
vote.BlockSignature = v.BlockSignature
err = vote.VoteExtensions.CopySignsFromProto(v.VoteExtensionsToMap())
if err != nil {
diff --git a/internal/test/factory/vote.go b/internal/test/factory/vote.go
index a18e68d2b5..b4f69fe84a 100644
--- a/internal/test/factory/vote.go
+++ b/internal/test/factory/vote.go
@@ -3,7 +3,6 @@ package factory
import (
"context"
- tmbytes "github.com/tendermint/tendermint/libs/bytes"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/tendermint/tendermint/types"
)
@@ -18,7 +17,6 @@ func MakeVote(
round int32,
step int,
blockID types.BlockID,
- appHash tmbytes.HexBytes,
) (*types.Vote, error) {
proTxHash, err := val.GetProTxHash(ctx)
if err != nil {
@@ -32,17 +30,15 @@ func MakeVote(
Round: round,
Type: tmproto.SignedMsgType(step),
BlockID: blockID,
- AppHash: appHash,
}
vpb := v.ToProto()
- if err := val.SignVote(ctx, chainID, valSet.QuorumType, valSet.QuorumHash, vpb, v.StateID(), nil); err != nil {
+ if err := val.SignVote(ctx, chainID, valSet.QuorumType, valSet.QuorumHash, vpb, nil); err != nil {
return nil, err
}
v.BlockSignature = vpb.BlockSignature
- v.StateSignature = vpb.StateSignature
err = v.VoteExtensions.CopySignsFromProto(vpb.VoteExtensionsToMap())
if err != nil {
return nil, err
diff --git a/libs/bytes/bytes.go b/libs/bytes/bytes.go
index 5a7998024b..9cb659b5d1 100644
--- a/libs/bytes/bytes.go
+++ b/libs/bytes/bytes.go
@@ -93,6 +93,10 @@ func (bz HexBytes) Copy() HexBytes {
return copied
}
+func (bz HexBytes) IsZero() bool {
+ return len(bz) == 0
+}
+
func (bz HexBytes) Equal(b []byte) bool {
return bytes.Equal(bz, b)
}
diff --git a/libs/bytes/marshal.go b/libs/bytes/marshal.go
new file mode 100644
index 0000000000..3e9ff39c98
--- /dev/null
+++ b/libs/bytes/marshal.go
@@ -0,0 +1,135 @@
+package bytes
+
+import (
+ "bytes"
+ "encoding/binary"
+ "fmt"
+ "io"
+ "reflect"
+ "strconv"
+ "strings"
+ "time"
+)
+
+// MarshalFixed marshals provided struct as a fixed-size buffer.
+// It processes exported struct fields in the order of their declaration.
+// At this point, it only supports the following data types:
+// * uint16
+// * int64
+// * slices
+// * fixed-size arrays
+//
+// It also supports "tmbytes" tag with the following comma-separated attributes:
+// - size=N - provide number of elements in the slice (only for slices) to be enforced;
+// if 0 or not provided, size enforcement is responsibility of the caller
+//
+// Example:
+//
+// Field []byte `tmbytes:"size=123"`
+func MarshalFixedSize(data interface{}) ([]byte, error) {
+ structure := reflect.Indirect(reflect.ValueOf(data))
+ typ := structure.Type()
+ out := bytes.NewBuffer(make([]byte, 0, typ.Size()))
+
+ for i := 0; i < typ.NumField(); i++ {
+ field := structure.Field(i)
+ field = reflect.Indirect(field)
+ fieldType := typ.Field(i)
+
+ if !fieldType.IsExported() {
+ continue
+ }
+ kind := field.Kind()
+ if kind == reflect.Slice || kind == reflect.Map {
+ if err := marshalVarSizedField(out, field, fieldType); err != nil {
+ return nil, fmt.Errorf("field %s of type %s: cannot write: %w", fieldType.Name, field.Type(), err)
+ }
+ continue
+ }
+ if kind == reflect.String {
+ s := []byte(field.String())
+ if err := marshalVarSizedField(out, reflect.ValueOf(s), fieldType); err != nil {
+ return nil, fmt.Errorf("field %s of type %s: cannot write: %w", fieldType.Name, field.Type(), err)
+ }
+ continue
+ }
+
+ switch v := field.Interface().(type) {
+ case string:
+
+ case time.Time:
+ // A Timestamp represents a point in time independent of any time zone or calendar, represented as
+ // seconds and fractions of seconds at nanosecond resolution in UTC Epoch time.
+ // See (time.Time).UnixNano() for details.
+ timestamp := v.UnixNano()
+ if err := binary.Write(out, binary.LittleEndian, timestamp); err != nil {
+ return nil, fmt.Errorf("field %s of type %s: cannot write: %w", fieldType.Name, field.Type(), err)
+ }
+ default:
+ if err := binary.Write(out, binary.LittleEndian, field.Interface()); err != nil {
+ return nil, fmt.Errorf("field %s of type %s: cannot write: %w", fieldType.Name, field.Type(), err)
+ }
+ }
+ }
+
+ return out.Bytes(), nil
+}
+
+// marshalVarSizedField marshals a field of a type with hard-to-determine size
+func marshalVarSizedField(out io.Writer, field reflect.Value, structField reflect.StructField) error {
+ // Variable-length objects MUST have size defined
+ tags, err := getTags(structField)
+ if err != nil {
+ return err
+ }
+ if tags.size != 0 && tags.size != field.Len() {
+ return fmt.Errorf("size of %s MUST be %d bytes, is %d",
+ structField.Name, tags.size, field.Len())
+ }
+ if err := binary.Write(out, binary.LittleEndian, field.Interface()); err != nil {
+ return fmt.Errorf("field %s of type %s: cannot write: %w", structField.Name, field.Type(), err)
+ }
+
+ return nil
+}
+
+func getTags(structField reflect.StructField) (tags, error) {
+ var (
+ err error
+ ret tags
+ )
+
+ structTag, ok := structField.Tag.Lookup("tmbytes")
+ if !ok {
+ return tags{}, nil
+ }
+
+ for i, tag := range strings.Split(structTag, ",") {
+ kv := strings.SplitN(tag, "=", 2)
+ if len(kv) != 2 {
+ return tags{}, fmt.Errorf("%s[%d]: invalid tag %s", structTag, i, tag)
+ }
+ key := kv[0]
+ value := kv[1]
+
+ switch key {
+ case "size":
+ ret.size, err = strconv.Atoi(value)
+ if err != nil {
+ return tags{}, fmt.Errorf("field %s tag size:\"%s\": %w", structField.Name, structTag, err)
+ }
+ default:
+ return tags{}, fmt.Errorf("unsupported tag attribute %s=%s", key, value)
+ }
+ }
+
+ return ret, nil
+}
+
+type tags struct {
+ // size represents fixed number of elements in a variable-size data type like slice.
+ // Examples:
+ // * Field1 []byte `tmbytes:"size=123"` - means Field1 should contain exactly 123 bytes
+ // * Field2 []int16 `tmbytes:"size=12"` - means Field1 should contain exactly 12 int16 elements, that is 24 bytes
+ size int
+}
diff --git a/libs/bytes/marshal_test.go b/libs/bytes/marshal_test.go
new file mode 100644
index 0000000000..40dab10a07
--- /dev/null
+++ b/libs/bytes/marshal_test.go
@@ -0,0 +1,120 @@
+package bytes
+
+import (
+ "math"
+ "reflect"
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestMarshalFixed(t *testing.T) {
+ type testCase struct {
+ Data interface{}
+ expectLen int
+ expectError string
+ }
+ testCases := []testCase{
+ {
+ Data: struct{ T time.Time }{time.Now()},
+ expectLen: 8,
+ },
+ {
+ Data: struct {
+ Field1 uint64
+ Field2 []byte `tmbytes:"size=12"`
+ Field3 uint32
+ Field4 [4]byte
+ Field5 string
+ }{0x1234567890abcdef, []byte("1234567890ab"), math.MaxUint32, [4]byte{1, 2, 3, 4}, "str"},
+ expectLen: 8 + 12 + 4 + 4 + 3,
+ expectError: "",
+ },
+ { // HexBytes
+ Data: struct {
+ Field1 uint64
+ Field2 HexBytes `tmbytes:"size=12"`
+ }{0x1234567890abcdef, []byte("1234567890ab")},
+ expectLen: 8 + 12,
+ expectError: "",
+ },
+ {
+ Data: struct {
+ Field1 uint64
+ Field2 []byte `tmbytes:"size=12"`
+ }{0x1234567890abcdef, []byte("1234567890")},
+ expectError: "size of Field2 MUST be 12 bytes, is 10",
+ }, { // marshal []uint64
+ Data: struct {
+ Field1 uint64
+ Field2 []uint64 `tmbytes:"size=3"`
+ }{0x1234567890abcdef, []uint64{math.MaxInt64, 0, math.MaxInt64}},
+ expectLen: 8 + 3*8,
+ },
+ {
+ Data: struct {
+ Field1 string
+ }{"tst\x00\x00"},
+ expectLen: 5,
+ expectError: "",
+ },
+ {
+ Data: struct {
+ Field1 string `tmbytes:"size=2"`
+ }{"Wrong len"},
+ expectLen: 5,
+ expectError: "field Field1 of type string: cannot write: size of Field1 MUST be 2 bytes, is 9",
+ },
+ {
+ Data: struct {
+ Field1 string `tmbytes:"size=8"`
+ }{"Good len"},
+ expectLen: 8,
+ expectError: "",
+ },
+ }
+ for _, tc := range testCases {
+ t.Run("", func(t *testing.T) {
+ marshaled, err := MarshalFixedSize(tc.Data)
+ if tc.expectError != "" {
+ assert.ErrorContains(t, err, tc.expectError)
+ return
+ }
+ assert.NoError(t, err)
+ assert.Len(t, marshaled, tc.expectLen)
+ // t.Logf("Marshaled: %+v", marshaled)
+ })
+ }
+}
+func TestMarshalTags(t *testing.T) {
+ type testCase struct {
+ Field1 []byte `tmbytes:"size=12"`
+ Field2 int64
+ Field3 string
+ expectSize map[string]int
+ }
+ testCases := []testCase{
+ {
+ []byte("abc"),
+ 123,
+ "def",
+ map[string]int{"Field1": 12},
+ },
+ }
+ for _, tc := range testCases {
+ t.Run("", func(t *testing.T) {
+ typ := reflect.TypeOf(tc)
+ for i := 0; i < typ.NumField(); i++ {
+ structField := typ.Field(i)
+ if !structField.IsExported() {
+ continue
+ }
+ name := structField.Name
+ tags, err := getTags(structField)
+ assert.NoError(t, err, structField.Name)
+ assert.Equal(t, tc.expectSize[name], tags.size, name)
+ }
+ })
+ }
+}
diff --git a/light/client.go b/light/client.go
index af006fb6f0..efd1ec9bad 100644
--- a/light/client.go
+++ b/light/client.go
@@ -277,7 +277,7 @@ func (c *Client) initializeAtHeight(ctx context.Context, height int64) error {
// 3) Ensure that the commit is valid based on validator set we got back.
// Todo: we will want to remove validator sets entirely from light blocks and just have quorum hashes
- err = l.ValidatorSet.VerifyCommit(c.chainID, l.Commit.BlockID, l.Commit.StateID, l.Height, l.Commit)
+ err = l.ValidatorSet.VerifyCommit(c.chainID, l.Commit.BlockID, l.Height, l.Commit)
if err != nil {
return fmt.Errorf("invalid commit: %w", err)
}
@@ -300,10 +300,10 @@ func (c *Client) initializeAtHeight(ctx context.Context, height int64) error {
// TrustedLightBlock returns a trusted light block at the given height (0 - the latest).
//
// It returns an error if:
-// - there are some issues with the trusted store, although that should not
-// happen normally;
-// - negative height is passed;
-// - header has not been verified yet and is therefore not in the store
+// - there are some issues with the trusted store, although that should not
+// happen normally;
+// - negative height is passed;
+// - header has not been verified yet and is therefore not in the store
//
// Safe for concurrent use by multiple goroutines.
func (c *Client) TrustedLightBlock(height int64) (*types.LightBlock, error) {
@@ -417,8 +417,9 @@ func (c *Client) VerifyLightBlockAtHeight(ctx context.Context, height int64, now
//
// If the header, which is older than the currently trusted header, is
// requested and the light client does not have it, VerifyHeader will perform:
-// a) verifySkipping verification if nearest trusted header is found & not expired
-// b) backwards verification in all other cases
+//
+// a) verifySkipping verification if nearest trusted header is found & not expired
+// b) backwards verification in all other cases
//
// It returns ErrOldHeaderExpired if the latest trusted header expired.
//
@@ -506,7 +507,7 @@ func (c *Client) verifyBlockWithDashCore(ctx context.Context, newLightBlock *typ
if err := c.verifyBlockSignatureWithDashCore(ctx, newLightBlock); err != nil {
return err
}
- return c.verifyStateIDSignatureWithDashCore(ctx, newLightBlock)
+ return nil
}
func (c *Client) verifyBlockSignatureWithDashCore(ctx context.Context, newLightBlock *types.LightBlock) error {
@@ -515,8 +516,10 @@ func (c *Client) verifyBlockSignatureWithDashCore(ctx context.Context, newLightB
quorumType := newLightBlock.ValidatorSet.QuorumType
protoVote := newLightBlock.Commit.GetCanonicalVote().ToProto()
-
- blockSignBytes := types.VoteBlockSignBytes(c.chainID, protoVote)
+ blockSignBytes, err := protoVote.SignBytes(c.chainID)
+ if err != nil {
+ return err
+ }
blockMessageHash := crypto.Checksum(blockSignBytes)
blockRequestID := types.VoteBlockRequestIDProto(protoVote)
@@ -540,39 +543,6 @@ func (c *Client) verifyBlockSignatureWithDashCore(ctx context.Context, newLightB
return nil
}
-// This method is called from verifyLightBlock if verification mode is dashcore,
-// verifyLightBlock in its turn is called by VerifyHeader.
-func (c *Client) verifyStateIDSignatureWithDashCore(ctx context.Context, newLightBlock *types.LightBlock) error {
- quorumHash := newLightBlock.ValidatorSet.QuorumHash
- quorumType := newLightBlock.ValidatorSet.QuorumType
-
- stateID := newLightBlock.StateID()
-
- stateSignBytes := stateID.SignBytes(c.chainID)
-
- stateMessageHash := crypto.Checksum(stateSignBytes)
- stateRequestID := stateID.SignRequestID()
- stateSignature := newLightBlock.Commit.ThresholdStateSignature
-
- stateSignatureIsValid, err := c.dashCoreRPCClient.QuorumVerify(
- quorumType,
- stateRequestID,
- stateMessageHash,
- stateSignature,
- quorumHash,
- )
-
- if err != nil {
- return err
- }
-
- if !stateSignatureIsValid {
- return fmt.Errorf("state signature is invalid")
- }
-
- return nil
-}
-
// LastTrustedHeight returns a last trusted height. -1 and nil are returned if
// there are no trusted headers.
//
@@ -654,12 +624,12 @@ func (c *Client) updateTrustedLightBlock(l *types.LightBlock) error {
// lightBlockFromPrimary retrieves the latest lightBlock from the primary provider.
// This method also handles provider behavior as follows:
//
-// 1. If the provider does not respond, it tries again
-// with a different provider
-// 2. If all providers return the same error, the light client forwards the error to
-// where the initial request came from
-// 3. If the provider provides an invalid light block, is deemed unreliable or returns
-// any other error, the primary is permanently dropped and is replaced by a witness.
+// 1. If the provider does not respond, it tries again
+// with a different provider
+// 2. If all providers return the same error, the light client forwards the error to
+// where the initial request came from
+// 3. If the provider provides an invalid light block, is deemed unreliable or returns
+// any other error, the primary is permanently dropped and is replaced by a witness.
func (c *Client) lightBlockFromPrimary(ctx context.Context) (*types.LightBlock, error) {
return c.lightBlockFromPrimaryAtHeight(ctx, 0)
}
diff --git a/light/client_test.go b/light/client_test.go
index 95cdaea504..2060bc20ec 100644
--- a/light/client_test.go
+++ b/light/client_test.go
@@ -53,10 +53,18 @@ func TestClient(t *testing.T) {
hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys))
// 3/3 signed
h2 = keys.GenSignedHeaderLastBlockID(t, chainID, 2, bTime.Add(30*time.Minute), nil, vals, vals,
- hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys), types.BlockID{Hash: h1.Hash()})
+ hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys),
+ types.BlockID{
+ Hash: h1.Hash(),
+ StateID: h1.StateID().Hash(),
+ })
// 3/3 signed
h3 = keys.GenSignedHeaderLastBlockID(t, chainID, 3, bTime.Add(1*time.Hour), nil, vals, vals,
- hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys), types.BlockID{Hash: h2.Hash()})
+ hash("app_hash"), hash("cons_hash"), hash("results_hash"), 0, len(keys),
+ types.BlockID{
+ Hash: h2.Hash(),
+ StateID: h2.StateID().Hash(),
+ })
headerSet = map[int64]*types.SignedHeader{
1: h1,
@@ -459,7 +467,11 @@ func TestClient(t *testing.T) {
// should be removed.
2: keys.GenSignedHeaderLastBlockID(t, chainID, 2, bTime.Add(30*time.Minute), nil, vals, vals,
hash("app_hash2"), hash("cons_hash"), hash("results_hash"),
- 0, len(keys), types.BlockID{Hash: h1.Hash()}),
+ 0, len(keys),
+ types.BlockID{
+ Hash: h1.Hash(),
+ StateID: h1.StateID().Hash(),
+ }),
},
map[int64]*types.ValidatorSet{
1: vals,
diff --git a/light/detector.go b/light/detector.go
index 52ec5d3ac4..3409f52257 100644
--- a/light/detector.go
+++ b/light/detector.go
@@ -15,7 +15,9 @@ import (
//
// 1: errConflictingHeaders -> there may have been an attack on this light client
// 2: errBadWitness -> the witness has either not responded, doesn't have the header or has given us an invalid one
-// Note: In the case of an invalid header we remove the witness
+//
+// Note: In the case of an invalid header we remove the witness
+//
// 3: nil -> the hashes of the two headers match
func (c *Client) compareNewHeaderWithWitness(ctx context.Context, errc chan error, h *types.SignedHeader,
witness provider.Provider, witnessIndex int) {
diff --git a/light/doc.go b/light/doc.go
index b05ffa8056..1d8f9da898 100644
--- a/light/doc.go
+++ b/light/doc.go
@@ -63,31 +63,31 @@ This package provides three major things:
Example usage:
- db, err := dbm.NewGoLevelDB("light-client-db", dbDir)
- if err != nil {
- // handle error
- }
-
- c, err := NewHTTPClient(
- chainID,
- TrustOptions{
- Period: 504 * time.Hour, // 21 days
- Height: 100,
- Hash: header.Hash(),
- },
- "http://localhost:26657",
- []string{"http://witness1:26657"},
- dbs.New(db, ""),
- )
- if err != nil {
- // handle error
- }
-
- h, err := c.TrustedHeader(100)
- if err != nil {
- // handle error
- }
- fmt.Println("header", h)
+ db, err := dbm.NewGoLevelDB("light-client-db", dbDir)
+ if err != nil {
+ // handle error
+ }
+
+ c, err := NewHTTPClient(
+ chainID,
+ TrustOptions{
+ Period: 504 * time.Hour, // 21 days
+ Height: 100,
+ Hash: header.Hash(),
+ },
+ "http://localhost:26657",
+ []string{"http://witness1:26657"},
+ dbs.New(db, ""),
+ )
+ if err != nil {
+ // handle error
+ }
+
+ h, err := c.TrustedHeader(100)
+ if err != nil {
+ // handle error
+ }
+ fmt.Println("header", h)
Check out other examples in example_test.go
diff --git a/light/helpers_test.go b/light/helpers_test.go
index 6adb2bcc7d..93f1a44a78 100644
--- a/light/helpers_test.go
+++ b/light/helpers_test.go
@@ -61,11 +61,7 @@ func (pkz privKeys) signHeader(t testing.TB, header *types.Header, valSet *types
blockID := types.BlockID{
Hash: header.Hash(),
PartSetHeader: types.PartSetHeader{Total: 1, Hash: crypto.CRandBytes(32)},
- }
-
- stateID := types.StateID{
- Height: header.Height,
- AppHash: header.AppHash,
+ StateID: header.StateID().Hash(),
}
votes := make([]*types.Vote, len(pkz))
@@ -83,7 +79,7 @@ func (pkz privKeys) signHeader(t testing.TB, header *types.Header, valSet *types
if !privateKey.PubKey().Equals(val.PubKey) {
panic("light client keys do not match")
}
- votes[i] = makeVote(t, header, valSet, val.ProTxHash, pkz[i], blockID, stateID)
+ votes[i] = makeVote(t, header, valSet, val.ProTxHash, pkz[i], blockID)
}
thresholdSigns, err := types.NewSignsRecoverer(votes).Recover()
require.NoError(t, err)
@@ -91,11 +87,11 @@ func (pkz privKeys) signHeader(t testing.TB, header *types.Header, valSet *types
QuorumSigns: *thresholdSigns,
QuorumHash: valSet.QuorumHash,
}
- return types.NewCommit(header.Height, 1, blockID, stateID, quorumSigns)
+ return types.NewCommit(header.Height, 1, blockID, quorumSigns)
}
func makeVote(t testing.TB, header *types.Header, valset *types.ValidatorSet, proTxHash crypto.ProTxHash,
- key crypto.PrivKey, blockID types.BlockID, stateID types.StateID) *types.Vote {
+ key crypto.PrivKey, blockID types.BlockID) *types.Vote {
t.Helper()
idx, val := valset.GetByProTxHash(proTxHash)
@@ -119,15 +115,7 @@ func makeVote(t testing.TB, header *types.Header, valset *types.ValidatorSet, pr
panic(err)
}
- // SignDigest the state
- stateSignID := stateID.SignID(header.ChainID, valset.QuorumType, valset.QuorumHash)
- sigState, err := key.SignDigest(stateSignID)
- if err != nil {
- panic(err)
- }
-
vote.BlockSignature = sig
- vote.StateSignature = sigState
return vote
}
@@ -136,7 +124,7 @@ func genHeader(chainID string, height int64, bTime time.Time, txs types.Txs,
valset, nextValset *types.ValidatorSet, appHash, consHash, resHash []byte) *types.Header {
return &types.Header{
- Version: version.Consensus{Block: version.BlockProtocol, App: 0},
+ Version: version.Consensus{Block: version.BlockProtocol, App: 1},
ChainID: chainID,
Height: height,
Time: bTime,
@@ -227,7 +215,11 @@ func genLightBlocksWithValidatorsRotatingEveryBlock(
currentHeader = keys.GenSignedHeaderLastBlockID(t, chainID, height, bTime.Add(time.Duration(height)*time.Minute),
nil,
vals, newVals, hash("app_hash"), hash("cons_hash"),
- hash("results_hash"), 0, len(keys), types.BlockID{Hash: lastHeader.Hash()})
+ hash("results_hash"), 0, len(keys),
+ types.BlockID{
+ Hash: lastHeader.Hash(),
+ StateID: lastHeader.StateID().Hash(),
+ })
headers[height] = currentHeader
valset[height] = vals
lastHeader = currentHeader
diff --git a/light/provider/http/http.go b/light/provider/http/http.go
index 228e28c473..c08f07ee84 100644
--- a/light/provider/http/http.go
+++ b/light/provider/http/http.go
@@ -348,6 +348,6 @@ func validateHeight(height int64) (*int64, error) {
// exponential backoff (with jitter)
// 0.5s -> 2s -> 4.5s -> 8s -> 12.5 with 1s variation
func backoffTimeout(attempt uint16) time.Duration {
- // nolint:gosec // G404: Use of weak random number generator
+ //nolint:gosec // G404: Use of weak random number generator
return time.Duration(500*attempt*attempt)*time.Millisecond + time.Duration(rand.Intn(1000))*time.Millisecond
}
diff --git a/light/rpc/client.go b/light/rpc/client.go
index 7af2432428..f7732ed7e8 100644
--- a/light/rpc/client.go
+++ b/light/rpc/client.go
@@ -29,6 +29,7 @@ import (
type KeyPathFunc func(path string, key []byte) (merkle.KeyPath, error)
// LightClient is an interface that contains functionality needed by Client from the light client.
+//
//go:generate ../../scripts/mockery_generate.sh LightClient
type LightClient interface {
ChainID() string
diff --git a/node/node_test.go b/node/node_test.go
index d2ab1d2cda..7a7b67cbab 100644
--- a/node/node_test.go
+++ b/node/node_test.go
@@ -378,7 +378,7 @@ func TestCreateProposalBlock(t *testing.T) {
)
proposedAppVersion := uint64(1)
- commit := types.NewCommit(height-1, 0, types.BlockID{}, types.StateID{}, nil)
+ commit := types.NewCommit(height-1, 0, types.BlockID{}, nil)
block, _, err := blockExec.CreateProposalBlock(
ctx,
height,
@@ -447,7 +447,9 @@ func TestMaxTxsProposalBlockSize(t *testing.T) {
)
// fill the mempool with one txs just below the maximum size
- txLength := int(types.MaxDataBytesNoEvidence(maxBytes))
+ maxDataBytes, err := types.MaxDataBytesNoEvidence(maxBytes)
+ require.NoError(t, err)
+ txLength := int(maxDataBytes)
tx := tmrand.Bytes(txLength - 4) // to account for the varint
err = mp.CheckTx(ctx, tx, nil, mempool.TxInfo{})
assert.NoError(t, err)
@@ -464,7 +466,7 @@ func TestMaxTxsProposalBlockSize(t *testing.T) {
eventBus,
)
- commit := types.NewCommit(height-1, 0, types.BlockID{}, types.StateID{}, nil)
+ commit := types.NewCommit(height-1, 0, types.BlockID{}, nil)
block, _, err := blockExec.CreateProposalBlock(
ctx,
height,
@@ -558,6 +560,7 @@ func TestMaxProposalBlockSize(t *testing.T) {
Total: math.MaxInt32,
Hash: crypto.Checksum([]byte("blockID_part_set_header_hash")),
},
+ StateID: types.RandStateID().Hash(),
}
// save the updated validator set for use by the block executor.
@@ -565,11 +568,6 @@ func TestMaxProposalBlockSize(t *testing.T) {
state.LastHeightValidatorsChanged = math.MaxInt64 - 1
require.NoError(t, stateStore.Save(state))
- stateID := types.StateID{
- Height: math.MaxInt64 - 1,
- AppHash: crypto.Checksum([]byte("app_hash")),
- }
-
timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC)
// change state in order to produce the largest accepted header
state.LastBlockID = blockID
@@ -589,10 +587,8 @@ func TestMaxProposalBlockSize(t *testing.T) {
Height: math.MaxInt64,
Round: math.MaxInt32,
BlockID: blockID,
- StateID: stateID,
QuorumHash: crypto.RandQuorumHash(),
ThresholdBlockSignature: crypto.CRandBytes(bls12381.SignatureSize),
- ThresholdStateSignature: crypto.CRandBytes(bls12381.SignatureSize),
}
block, _, err := blockExec.CreateProposalBlock(
@@ -616,9 +612,9 @@ func TestMaxProposalBlockSize(t *testing.T) {
// require that the header and commit be the max possible size
require.Equal(t, types.MaxHeaderBytes, int64(pb.Header.Size()))
- require.Equal(t, types.MaxCommitSize, int64(pb.LastCommit.Size()))
+ require.Equal(t, types.MaxCommitOverheadBytes, int64(pb.LastCommit.Size()))
// make sure that the block is less than the max possible size
- assert.Equal(t, int64(1150+cfg.Mempool.MaxTxBytes), int64(pb.Size()))
+ assert.Equal(t, int64(1072+cfg.Mempool.MaxTxBytes), int64(pb.Size()))
// because of the proto overhead we expect the part set bytes to be equal or
// less than the pb block size
assert.LessOrEqual(t, partSet.ByteSize(), int64(pb.Size()))
diff --git a/node/setup.go b/node/setup.go
index 751a1e15ba..8bf57ed0f8 100644
--- a/node/setup.go
+++ b/node/setup.go
@@ -571,7 +571,6 @@ func createBlockReplayer(n *nodeImpl) *consensus.BlockReplayer {
n.blockStore,
n.rpcEnv.EventBus,
sm.BlockExecWithLogger(logger),
- sm.BlockExecWithAppHashSize(n.config.Consensus.AppHashSize),
)
return consensus.NewBlockReplayer(
n.rpcEnv.ProxyApp,
diff --git a/privval/dash_core_signer_client.go b/privval/dash_core_signer_client.go
index b5125783a0..d27431a41c 100644
--- a/privval/dash_core_signer_client.go
+++ b/privval/dash_core_signer_client.go
@@ -242,12 +242,12 @@ func (sc *DashCoreSignerClient) GetProTxHash(ctx context.Context) (crypto.ProTxH
// SignVote requests a remote signer to sign a vote
func (sc *DashCoreSignerClient) SignVote(
ctx context.Context, chainID string, quorumType btcjson.LLMQType, quorumHash crypto.QuorumHash,
- protoVote *tmproto.Vote, stateID types.StateID, logger log.Logger) error {
+ protoVote *tmproto.Vote, logger log.Logger) error {
if len(quorumHash) != crypto.DefaultHashSize {
return fmt.Errorf("quorum hash is not the right length %s", quorumHash.String())
}
- quorumSigns, err := types.MakeQuorumSigns(chainID, quorumType, quorumHash, protoVote, stateID)
+ quorumSigns, err := types.MakeQuorumSigns(chainID, quorumType, quorumHash, protoVote)
if err != nil {
return err
}
@@ -275,30 +275,6 @@ func (sc *DashCoreSignerClient) SignVote(
protoVote.BlockSignature = qs.sign
- // Only sign the state when voting for the block
- if protoVote.BlockID.Hash != nil {
- signItem := quorumSigns.State
- resp, err := sc.quorumSignAndVerify(ctx, quorumType, quorumHash, signItem)
- if err != nil {
- return err
- }
-
- logger.Debug("signed vote state ID",
- "height", protoVote.Height,
- "round", protoVote.Round,
- "voteType", protoVote.Type,
- "quorumType", quorumType,
- "quorumHash", quorumHash,
- "proTxHash", proTxHash,
- "stateID", stateID,
- "signItem", signItem,
- "signResult", resp,
- )
-
- protoVote.StateSignature = resp.sign
-
- }
-
return sc.signVoteExtensions(ctx, quorumType, quorumHash, protoVote, quorumSigns)
}
diff --git a/privval/doc.go b/privval/doc.go
index 7695ffe9d0..63e1d071da 100644
--- a/privval/doc.go
+++ b/privval/doc.go
@@ -1,13 +1,12 @@
/*
-
Package privval provides different implementations of the types.PrivValidator.
-FilePV
+# FilePV
FilePV is the simplest implementation and developer default.
It uses one file for the private key and another to store state.
-SignerListenerEndpoint
+# SignerListenerEndpoint
SignerListenerEndpoint establishes a connection to an external process,
like a Key Management Server (KMS), using a socket.
@@ -15,15 +14,14 @@ SignerListenerEndpoint listens for the external KMS process to dial in.
SignerListenerEndpoint takes a listener, which determines the type of connection
(ie. encrypted over tcp, or unencrypted over unix).
-SignerDialerEndpoint
+# SignerDialerEndpoint
SignerDialerEndpoint is a simple wrapper around a net.Conn. It's used by both IPCVal and TCPVal.
-SignerClient
+# SignerClient
SignerClient handles remote validator connections that provide signing services.
In production, it's recommended to wrap it with RetrySignerClient to avoid
termination in case of temporary errors.
-
*/
package privval
diff --git a/privval/file.go b/privval/file.go
index cfb2c04a5c..94238eaec0 100644
--- a/privval/file.go
+++ b/privval/file.go
@@ -118,8 +118,6 @@ type FilePVLastSignState struct {
Step int8 `json:"step"`
BlockSignature []byte `json:"block_signature,omitempty"`
BlockSignBytes tmbytes.HexBytes `json:"block_sign_bytes,omitempty"`
- StateSignature []byte `json:"state_signature,omitempty"`
- StateSignBytes tmbytes.HexBytes `json:"state_sign_bytes,omitempty"`
filePath string
}
@@ -130,8 +128,6 @@ func (lss *FilePVLastSignState) reset() {
lss.Step = 0
lss.BlockSignature = nil
lss.BlockSignBytes = nil
- lss.StateSignature = nil
- lss.StateSignBytes = nil
}
// checkHRS checks the given height, round, step (HRS) against that of the
@@ -168,12 +164,7 @@ func (lss *FilePVLastSignState) checkHRS(height int64, round int32, step int8) (
}
return true, nil
}
- if lss.StateSignBytes != nil {
- if lss.StateSignature == nil {
- panic("pv: StateID Signature is nil but StateSignBytes is not!")
- }
- return true, nil
- }
+
return false, errors.New("no SignBytes found")
}
}
@@ -570,13 +561,12 @@ func (pv *FilePV) SignVote(
quorumType btcjson.LLMQType,
quorumHash crypto.QuorumHash,
vote *tmproto.Vote,
- stateID types.StateID,
logger log.Logger,
) error {
pv.mtx.RLock()
defer pv.mtx.RUnlock()
- if err := pv.signVote(ctx, chainID, quorumType, quorumHash, vote, stateID); err != nil {
+ if err := pv.signVote(ctx, chainID, quorumType, quorumHash, vote); err != nil {
return fmt.Errorf("error signing vote: %v", err)
}
return nil
@@ -667,7 +657,6 @@ func (pv *FilePV) signVote(
quorumType btcjson.LLMQType,
quorumHash crypto.QuorumHash,
vote *tmproto.Vote,
- stateID types.StateID,
) error {
step, err := voteToStep(vote)
if err != nil {
@@ -683,17 +672,7 @@ func (pv *FilePV) signVote(
return err
}
- if len(vote.BlockID.Hash) != 0 {
- // StateID should refer to previous height in order to be valid
- if stateID.Height != height {
- return fmt.Errorf("invalid height in StateID: is %d, should be %d", stateID.Height, height)
- }
- if !stateID.AppHash.Equal(vote.AppHash) {
- return fmt.Errorf("invalid AppHash in StateID: is %x, vote contains %x", stateID.AppHash, vote.AppHash)
- }
- }
-
- quorumSigns, err := types.MakeQuorumSigns(chainID, quorumType, quorumHash, vote, stateID)
+ quorumSigns, err := types.MakeQuorumSigns(chainID, quorumType, quorumHash, vote)
if err != nil {
return err
}
@@ -728,9 +707,8 @@ func (pv *FilePV) signVote(
// If they only differ by timestamp, use last timestamp and signature
// Otherwise, return error
if sameHRS {
- if bytes.Equal(quorumSigns.Block.Raw, lss.BlockSignBytes) && bytes.Equal(quorumSigns.State.Raw, lss.StateSignBytes) {
+ if bytes.Equal(quorumSigns.Block.Raw, lss.BlockSignBytes) {
vote.BlockSignature = lss.BlockSignature
- vote.StateSignature = lss.StateSignature
} else {
return errors.New("conflicting data")
}
@@ -743,14 +721,6 @@ func (pv *FilePV) signVote(
return err
}
- var sigState []byte
- if vote.BlockID.Hash != nil {
- sigState, err = privKey.SignDigest(quorumSigns.State.ID)
- if err != nil {
- return err
- }
- }
-
// if vote.BlockID.Hash == nil {
// fmt.Printf("***********we are signing NIL (%d/%d) %X signed (file) for vote %v blockSignBytes %X\n",
// vote.Height, vote.Round, sigBlock, vote, blockSignBytes)
@@ -759,13 +729,12 @@ func (pv *FilePV) signVote(
// sigBlock, vote)
// }
- err = pv.saveSigned(height, round, step, quorumSigns.Block.Raw, sigBlock, quorumSigns.State.Raw, sigState)
+ err = pv.saveSigned(height, round, step, quorumSigns.Block.Raw, sigBlock)
if err != nil {
return err
}
vote.BlockSignature = sigBlock
- vote.StateSignature = sigState
fillProtoVoteExtensionSigns(vote.VoteExtensionsToMap(), extSigns)
return nil
@@ -820,7 +789,7 @@ func (pv *FilePV) signProposal(
// pv.Key.ProTxHash,
// proposal.Height, pv.Key.PrivKey.PubKey().Bytes(), blockSignID, blockSig)
- err = pv.saveSigned(height, round, step, blockSignBytes, blockSig, nil, nil)
+ err = pv.saveSigned(height, round, step, blockSignBytes, blockSig)
if err != nil {
return nil, err
}
@@ -835,16 +804,13 @@ func (pv *FilePV) saveSigned(
step int8,
blockSignBytes []byte,
blockSig []byte,
- stateSignBytes []byte,
- stateSig []byte,
+
) error {
pv.LastSignState.Height = height
pv.LastSignState.Round = round
pv.LastSignState.Step = step
pv.LastSignState.BlockSignature = blockSig
pv.LastSignState.BlockSignBytes = blockSignBytes
- pv.LastSignState.StateSignature = stateSig
- pv.LastSignState.StateSignBytes = stateSignBytes
return pv.LastSignState.Save()
}
diff --git a/privval/file_test.go b/privval/file_test.go
index 55bcec522c..3628324fbf 100644
--- a/privval/file_test.go
+++ b/privval/file_test.go
@@ -61,12 +61,14 @@ func TestResetValidator(t *testing.T) {
height, round := int64(10), int32(1)
voteType := tmproto.PrevoteType
randBytes := tmrand.Bytes(crypto.HashSize)
- blockID := types.BlockID{Hash: randBytes, PartSetHeader: types.PartSetHeader{}}
-
- stateID := types.RandStateID().WithHeight(height)
+ blockID := types.BlockID{
+ Hash: randBytes,
+ PartSetHeader: types.PartSetHeader{},
+ StateID: types.RandStateID().Hash(),
+ }
- vote := newVote(privVal.Key.ProTxHash, 0, height, round, voteType, blockID, stateID, nil)
- err = privVal.SignVote(ctx, "mychainid", 0, quorumHash, vote.ToProto(), stateID, nil)
+ vote := newVote(privVal.Key.ProTxHash, 0, height, round, voteType, blockID, nil)
+ err = privVal.SignVote(ctx, "mychainid", 0, quorumHash, vote.ToProto(), nil)
assert.NoError(t, err, "expected no error signing vote")
// priv val after signing is not same as empty
@@ -198,51 +200,53 @@ func TestSignVote(t *testing.T) {
randbytes := tmrand.Bytes(crypto.HashSize)
randbytes2 := tmrand.Bytes(crypto.HashSize)
- block1 := types.BlockID{Hash: randbytes,
- PartSetHeader: types.PartSetHeader{Total: 5, Hash: randbytes}}
- block2 := types.BlockID{Hash: randbytes2,
- PartSetHeader: types.PartSetHeader{Total: 10, Hash: randbytes2}}
+ block1 := types.BlockID{
+ Hash: randbytes,
+ PartSetHeader: types.PartSetHeader{Total: 5, Hash: randbytes},
+ StateID: types.RandStateID().Hash(),
+ }
+ block2 := types.BlockID{
+ Hash: randbytes2,
+ PartSetHeader: types.PartSetHeader{Total: 10, Hash: randbytes2},
+ StateID: types.RandStateID().Hash(),
+ }
height, round := int64(10), int32(1)
voteType := tmproto.PrevoteType
- stateID := types.RandStateID().WithHeight(height)
-
// sign a vote for first time
- vote := newVote(privVal.Key.ProTxHash, 0, height, round, voteType, block1, stateID, nil)
+ vote := newVote(privVal.Key.ProTxHash, 0, height, round, voteType, block1, nil)
v := vote.ToProto()
quorumHash, err := privVal.GetFirstQuorumHash(ctx)
assert.NoError(t, err)
- err = privVal.SignVote(ctx, "mychainid", 0, quorumHash, v, stateID, nil)
+ err = privVal.SignVote(ctx, "mychainid", 0, quorumHash, v, nil)
assert.NoError(t, err, "expected no error signing vote")
// try to sign the same vote again; should be fine
- err = privVal.SignVote(ctx, "mychainid", 0, quorumHash, v, stateID, nil)
+ err = privVal.SignVote(ctx, "mychainid", 0, quorumHash, v, nil)
assert.NoError(t, err, "expected no error on signing same vote")
// now try some bad votes
cases := []*types.Vote{
- newVote(privVal.Key.ProTxHash, 0, height, round-1, voteType, block1, stateID, nil), // round regression
- newVote(privVal.Key.ProTxHash, 0, height-1, round, voteType, block1, stateID, nil), // height regression
- newVote(privVal.Key.ProTxHash, 0, height-2, round+4, voteType, block1, stateID, nil), // height regression and different round
- newVote(privVal.Key.ProTxHash, 0, height, round, voteType, block2, stateID, nil), // different block
+ newVote(privVal.Key.ProTxHash, 0, height, round-1, voteType, block1, nil), // round regression
+ newVote(privVal.Key.ProTxHash, 0, height-1, round, voteType, block1, nil), // height regression
+ newVote(privVal.Key.ProTxHash, 0, height-2, round+4, voteType, block1, nil), // height regression and different round
+ newVote(privVal.Key.ProTxHash, 0, height, round, voteType, block2, nil), // different block
}
for _, c := range cases {
- assert.Error(t, privVal.SignVote(ctx, "mychainid", 0, crypto.QuorumHash{}, c.ToProto(), stateID, nil),
+ assert.Error(t, privVal.SignVote(ctx, "mychainid", 0, crypto.QuorumHash{}, c.ToProto(), nil),
"expected error on signing conflicting vote")
}
// try signing a vote with a different time stamp
blockSignature := vote.BlockSignature
- stateSignature := vote.StateSignature
- err = privVal.SignVote(ctx, "mychainid", 0, quorumHash, v, stateID, nil)
+ err = privVal.SignVote(ctx, "mychainid", 0, quorumHash, v, nil)
assert.NoError(t, err)
assert.Equal(t, blockSignature, vote.BlockSignature)
- assert.Equal(t, stateSignature, vote.StateSignature)
}
func TestSignProposal(t *testing.T) {
@@ -343,22 +347,25 @@ func TestVoteExtensionsAreAlwaysSigned(t *testing.T) {
pubKey, err := privVal.GetPubKey(ctx, quorumHash)
require.NoError(t, err)
+ height, round := int64(10), int32(1)
+
+ stateID := types.RandStateID()
+ stateID.Height = uint64(height)
blockID := types.BlockID{
Hash: tmrand.Bytes(crypto.HashSize),
PartSetHeader: types.PartSetHeader{Total: 5, Hash: tmrand.Bytes(crypto.HashSize)},
+ StateID: stateID.Hash(),
}
- height, round := int64(10), int32(1)
voteType := tmproto.PrecommitType
- stateID := types.RandStateID().WithHeight(height)
exts := types.VoteExtensions{
tmproto.VoteExtensionType_DEFAULT: []types.VoteExtension{{Extension: []byte("extension")}},
}
// We initially sign this vote without an extension
- vote1 := newVote(proTxHash, 0, height, round, voteType, blockID, stateID, exts)
+ vote1 := newVote(proTxHash, 0, height, round, voteType, blockID, exts)
vpb1 := vote1.ToProto()
- err = privVal.SignVote(ctx, chainID, quorumType, quorumHash, vpb1, stateID, logger)
+ err = privVal.SignVote(ctx, chainID, quorumType, quorumHash, vpb1, logger)
assert.NoError(t, err, "expected no error signing vote")
assert.NotNil(t, vpb1.VoteExtensions[0].Signature)
@@ -374,7 +381,7 @@ func TestVoteExtensionsAreAlwaysSigned(t *testing.T) {
}
vpb2 := vote2.ToProto()
- err = privVal.SignVote(ctx, chainID, quorumType, quorumHash, vpb2, stateID, logger)
+ err = privVal.SignVote(ctx, chainID, quorumType, quorumHash, vpb2, logger)
assert.NoError(t, err, "expected no error signing same vote with manipulated vote extension")
// We need to ensure that a valid new extension signature has been created
@@ -387,10 +394,9 @@ func TestVoteExtensionsAreAlwaysSigned(t *testing.T) {
assert.False(t, pubKey.VerifySignatureDigest(extSignItem1[tmproto.VoteExtensionType_DEFAULT][0].ID, vpb2.VoteExtensions[0].Signature))
vpb2.BlockSignature = nil
- vpb2.StateSignature = nil
vpb2.VoteExtensions[0].Signature = nil
- err = privVal.SignVote(ctx, chainID, quorumType, quorumHash, vpb2, stateID, logger)
+ err = privVal.SignVote(ctx, chainID, quorumType, quorumHash, vpb2, logger)
assert.NoError(t, err, "expected no error signing same vote with manipulated timestamp and vote extension")
extSignItem3, err := types.MakeVoteExtensionSignItems(chainID, vpb2, quorumType, quorumHash)
@@ -400,7 +406,7 @@ func TestVoteExtensionsAreAlwaysSigned(t *testing.T) {
}
func newVote(proTxHash types.ProTxHash, idx int32, height int64, round int32,
- typ tmproto.SignedMsgType, blockID types.BlockID, stateID types.StateID, exts types.VoteExtensions) *types.Vote {
+ typ tmproto.SignedMsgType, blockID types.BlockID, exts types.VoteExtensions) *types.Vote {
return &types.Vote{
ValidatorProTxHash: proTxHash,
ValidatorIndex: idx,
@@ -409,7 +415,6 @@ func newVote(proTxHash types.ProTxHash, idx int32, height int64, round int32,
Type: typ,
BlockID: blockID,
VoteExtensions: exts,
- AppHash: stateID.AppHash,
}
}
diff --git a/privval/grpc/client.go b/privval/grpc/client.go
index 11f478ab11..6e1ca85e1d 100644
--- a/privval/grpc/client.go
+++ b/privval/grpc/client.go
@@ -133,13 +133,12 @@ func (sc *SignerClient) GetHeight(ctx context.Context, quorumHash crypto.QuorumH
// SignVote requests a remote signer to sign a vote
func (sc *SignerClient) SignVote(
ctx context.Context, chainID string, quorumType btcjson.LLMQType, quorumHash crypto.QuorumHash,
- vote *tmproto.Vote, stateID types.StateID, logger log.Logger) error {
+ vote *tmproto.Vote, logger log.Logger) error {
if len(quorumHash.Bytes()) != crypto.DefaultHashSize {
return fmt.Errorf("quorum hash must be 32 bytes long when signing vote")
}
- protoStateID := stateID.ToProto()
resp, err := sc.client.SignVote(ctx, &privvalproto.SignVoteRequest{ChainId: sc.chainID, Vote: vote,
- QuorumType: int32(quorumType), QuorumHash: quorumHash, StateId: &protoStateID})
+ QuorumType: int32(quorumType), QuorumHash: quorumHash})
if err != nil {
errStatus, _ := status.FromError(err)
sc.logger.Error("Client SignVote", "err", errStatus.Message())
diff --git a/privval/grpc/client_test.go b/privval/grpc/client_test.go
index e518bc3025..bed39b1c61 100644
--- a/privval/grpc/client_test.go
+++ b/privval/grpc/client_test.go
@@ -90,36 +90,43 @@ func TestSignerClient_SignVote(t *testing.T) {
hash := tmrand.Bytes(crypto.HashSize)
proTxHash := crypto.RandProTxHash()
+ stateID := types.RandStateID()
want := &types.Vote{
- Type: tmproto.PrecommitType,
- Height: 1,
- Round: 2,
- BlockID: types.BlockID{Hash: hash, PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2}},
+ Type: tmproto.PrecommitType,
+ Height: 1,
+ Round: 2,
+ BlockID: types.BlockID{
+ Hash: hash,
+ PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2},
+ StateID: stateID.Hash(),
+ },
ValidatorProTxHash: proTxHash,
ValidatorIndex: 1,
}
have := &types.Vote{
- Type: tmproto.PrecommitType,
- Height: 1,
- Round: 2,
- BlockID: types.BlockID{Hash: hash, PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2}},
+ Type: tmproto.PrecommitType,
+ Height: 1,
+ Round: 2,
+ BlockID: types.BlockID{
+ Hash: hash,
+ PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2},
+ StateID: stateID.Hash(),
+ },
ValidatorProTxHash: proTxHash,
ValidatorIndex: 1,
}
pbHave := have.ToProto()
- stateID := have.StateID()
- err = client.SignVote(ctx, chainID, btcjson.LLMQType_5_60, quorumHash, pbHave, stateID, logger)
+ err = client.SignVote(ctx, chainID, btcjson.LLMQType_5_60, quorumHash, pbHave, logger)
require.NoError(t, err)
pbWant := want.ToProto()
- require.NoError(t, mockPV.SignVote(ctx, chainID, btcjson.LLMQType_5_60, quorumHash, pbWant, stateID, logger))
+ require.NoError(t, mockPV.SignVote(ctx, chainID, btcjson.LLMQType_5_60, quorumHash, pbWant, logger))
- assert.Equal(t, pbWant.StateSignature, pbHave.StateSignature)
assert.Equal(t, pbWant.BlockSignature, pbHave.BlockSignature)
}
diff --git a/privval/grpc/server.go b/privval/grpc/server.go
index e2b968e576..0dcd1e6aa8 100644
--- a/privval/grpc/server.go
+++ b/privval/grpc/server.go
@@ -95,11 +95,7 @@ func (ss *SignerServer) GetProTxHash(ctx context.Context, req *privvalproto.ProT
func (ss *SignerServer) SignVote(ctx context.Context, req *privvalproto.SignVoteRequest) (*privvalproto.SignedVoteResponse, error) {
vote := req.Vote
- stateID, err := types.StateIDFromProto(req.StateId)
- if err != nil {
- return nil, status.Errorf(codes.NotFound, "error converting stateId when signing vote: %v", err)
- }
- err = ss.privVal.SignVote(ctx, req.ChainId, btcjson.LLMQType(req.QuorumType), req.QuorumHash, vote, *stateID, nil)
+ err := ss.privVal.SignVote(ctx, req.ChainId, btcjson.LLMQType(req.QuorumType), req.QuorumHash, vote, nil)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "error signing vote: %v", err)
}
diff --git a/privval/grpc/server_test.go b/privval/grpc/server_test.go
index 5f227a98ba..43bef79ff9 100644
--- a/privval/grpc/server_test.go
+++ b/privval/grpc/server_test.go
@@ -10,7 +10,6 @@ import (
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
- "github.com/tendermint/tendermint/internal/test/factory"
"github.com/tendermint/tendermint/libs/log"
tmrand "github.com/tendermint/tendermint/libs/rand"
tmgrpc "github.com/tendermint/tendermint/privval/grpc"
@@ -60,6 +59,7 @@ func TestSignVote(t *testing.T) {
hash := tmrand.Bytes(crypto.HashSize)
proTxHash := crypto.RandProTxHash()
+ stateID := types.RandStateID()
testCases := []struct {
name string
@@ -68,34 +68,50 @@ func TestSignVote(t *testing.T) {
err bool
}{
{name: "valid", pv: types.NewMockPV(), have: &types.Vote{
- Type: tmproto.PrecommitType,
- Height: 1,
- Round: 2,
- BlockID: types.BlockID{Hash: hash, PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2}},
+ Type: tmproto.PrecommitType,
+ Height: 1,
+ Round: 2,
+ BlockID: types.BlockID{
+ Hash: hash,
+ PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2},
+ StateID: stateID.Hash(),
+ },
ValidatorProTxHash: proTxHash,
ValidatorIndex: 1,
}, want: &types.Vote{
- Type: tmproto.PrecommitType,
- Height: 1,
- Round: 2,
- BlockID: types.BlockID{Hash: hash, PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2}},
+ Type: tmproto.PrecommitType,
+ Height: 1,
+ Round: 2,
+ BlockID: types.BlockID{
+ Hash: hash,
+ PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2},
+ StateID: stateID.Hash(),
+ },
ValidatorProTxHash: proTxHash,
ValidatorIndex: 1,
},
err: false},
{name: "invalid vote", pv: types.NewErroringMockPV(), have: &types.Vote{
- Type: tmproto.PrecommitType,
- Height: 1,
- Round: 2,
- BlockID: types.BlockID{Hash: hash, PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2}},
+ Type: tmproto.PrecommitType,
+ Height: 1,
+ Round: 2,
+ BlockID: types.BlockID{
+ Hash: hash,
+ PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2},
+ StateID: stateID.Hash(),
+ },
ValidatorProTxHash: proTxHash,
ValidatorIndex: 1,
BlockSignature: []byte("signed"),
}, want: &types.Vote{
- Type: tmproto.PrecommitType,
- Height: 1,
- Round: 2,
- BlockID: types.BlockID{Hash: hash, PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2}},
+ Type: tmproto.PrecommitType,
+ Height: 1,
+ Round: 2,
+ BlockID: types.BlockID{
+ Hash: hash,
+ PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2},
+ StateID: stateID.Hash(),
+ },
ValidatorProTxHash: proTxHash,
ValidatorIndex: 1,
BlockSignature: []byte("signed"),
@@ -118,10 +134,6 @@ func TestSignVote(t *testing.T) {
ChainId: ChainID,
QuorumType: int32(btcjson.LLMQType_5_60),
QuorumHash: quorumHash,
- StateId: &tmproto.StateID{
- Height: tc.have.Height,
- AppHash: factory.RandomHash(),
- },
}
resp, err := s.SignVote(ctx, req)
if tc.err {
@@ -129,7 +141,7 @@ func TestSignVote(t *testing.T) {
} else {
pbVote := tc.want.ToProto()
require.NoError(t, tc.pv.SignVote(ctx, ChainID, btcjson.LLMQType_5_60, quorumHash,
- pbVote, types.StateID{}, log.NewTestingLogger(t)))
+ pbVote, log.NewTestingLogger(t)))
assert.Equal(t, pbVote.BlockSignature, resp.Vote.BlockSignature)
}
diff --git a/privval/msgs_test.go b/privval/msgs_test.go
index 673f06d224..1dff3d5d54 100644
--- a/privval/msgs_test.go
+++ b/privval/msgs_test.go
@@ -6,6 +6,7 @@ import (
"time"
"github.com/gogo/protobuf/proto"
+ gogotypes "github.com/gogo/protobuf/types"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
@@ -20,6 +21,11 @@ import (
var stamp = time.Date(2019, 10, 13, 16, 14, 44, 0, time.UTC)
func exampleVote() *types.Vote {
+
+ ts, err := gogotypes.TimestampProto(time.Date(2022, 3, 4, 5, 6, 7, 8, time.UTC))
+ if err != nil {
+ panic(err)
+ }
return &types.Vote{
Type: tmproto.PrecommitType,
Height: 3,
@@ -30,6 +36,13 @@ func exampleVote() *types.Vote {
Total: 1000000,
Hash: crypto.Checksum([]byte("blockID_part_set_header_hash")),
},
+ StateID: tmproto.StateID{
+ AppVersion: types.StateIDVersion,
+ Height: 3,
+ AppHash: crypto.Checksum([]byte("apphash")),
+ CoreChainLockedHeight: 12345,
+ Time: *ts,
+ }.Hash(),
},
ValidatorProTxHash: crypto.ProTxHashFromSeedBytes([]byte("validator_pro_tx_hash")),
ValidatorIndex: 56789,
@@ -71,10 +84,6 @@ func TestPrivvalVectors(t *testing.T) {
proposal := exampleProposal()
proposalpb := proposal.ToProto()
- // State ID
- stateID := vote.StateID()
- stateIDpb := stateID.ToProto()
-
// Create a Reuseable remote error
remoteError := &privproto.RemoteSignerError{Code: 1, Description: "it's a error"}
@@ -88,8 +97,8 @@ func TestPrivvalVectors(t *testing.T) {
{"pubKey request", &privproto.PubKeyRequest{}, "0a00"},
{"pubKey response", &privproto.PubKeyResponse{PubKey: ppk, Error: nil}, "12340a32223011c7f5ac5a6d01fd9dde3840f7ebbb6a20deed6fba72a347dd66da2f8c9c977c6604b2cd2e0148206c2add9a8f5ddd74"},
{"pubKey response with error", &privproto.PubKeyResponse{PubKey: cryptoproto.PublicKey{}, Error: remoteError}, "12140a0012100801120c697427732061206572726f72"},
- {"Vote Request", &privproto.SignVoteRequest{Vote: votepb, StateId: &stateIDpb}, "1a8c010a8501080210031802224a0a208b01023386c371778ecb6368573e539afc3cc860ec3a2f614e54fe5652f4fc80122608c0843d122072db3d959635dff1bb567bedaa70573392c5159666a3f8caf11e413aac52207a3220959a8f5ef2be68d0ed3a07ed8cff85991ee7995c2ac17030f742c135f9729fbe38d5bb035a0b1209657874656e73696f6e2a021003"},
- {"Vote Response", &privproto.SignedVoteResponse{Vote: *votepb, Error: nil}, "2288010a8501080210031802224a0a208b01023386c371778ecb6368573e539afc3cc860ec3a2f614e54fe5652f4fc80122608c0843d122072db3d959635dff1bb567bedaa70573392c5159666a3f8caf11e413aac52207a3220959a8f5ef2be68d0ed3a07ed8cff85991ee7995c2ac17030f742c135f9729fbe38d5bb035a0b1209657874656e73696f6e"},
+ {"Vote Request", &privproto.SignVoteRequest{Vote: votepb}, "1aaa010aa701080210031802226c0a208b01023386c371778ecb6368573e539afc3cc860ec3a2f614e54fe5652f4fc80122608c0843d122072db3d959635dff1bb567bedaa70573392c5159666a3f8caf11e413aac52207a1a2071aa7631e86d2b19d27f0c63e41ed08e5f8d43cfbb69d35913a7731b61bbdc623220959a8f5ef2be68d0ed3a07ed8cff85991ee7995c2ac17030f742c135f9729fbe38d5bb035a0b1209657874656e73696f6e"},
+ {"Vote Response", &privproto.SignedVoteResponse{Vote: *votepb, Error: nil}, "22aa010aa701080210031802226c0a208b01023386c371778ecb6368573e539afc3cc860ec3a2f614e54fe5652f4fc80122608c0843d122072db3d959635dff1bb567bedaa70573392c5159666a3f8caf11e413aac52207a1a2071aa7631e86d2b19d27f0c63e41ed08e5f8d43cfbb69d35913a7731b61bbdc623220959a8f5ef2be68d0ed3a07ed8cff85991ee7995c2ac17030f742c135f9729fbe38d5bb035a0b1209657874656e73696f6e"},
{"Vote Response with error", &privproto.SignedVoteResponse{Vote: tmproto.Vote{}, Error: remoteError}, "22180a042202120012100801120c697427732061206572726f72"},
{"Proposal Request", &privproto.SignProposalRequest{Proposal: proposalpb}, "2a700a6e08011003180220022a4a0a208b01023386c371778ecb6368573e539afc3cc860ec3a2f614e54fe5652f4fc80122608c0843d122072db3d959635dff1bb567bedaa70573392c5159666a3f8caf11e413aac52207a320608f49a8ded053a10697427732061207369676e6174757265"},
{"Proposal Response", &privproto.SignedProposalResponse{Proposal: *proposalpb, Error: nil}, "32700a6e08011003180220022a4a0a208b01023386c371778ecb6368573e539afc3cc860ec3a2f614e54fe5652f4fc80122608c0843d122072db3d959635dff1bb567bedaa70573392c5159666a3f8caf11e413aac52207a320608f49a8ded053a10697427732061207369676e6174757265"},
diff --git a/privval/retry_signer_client.go b/privval/retry_signer_client.go
index 282f08b6b5..0789c93ba5 100644
--- a/privval/retry_signer_client.go
+++ b/privval/retry_signer_client.go
@@ -139,10 +139,10 @@ func (sc *RetrySignerClient) GetHeight(ctx context.Context, quorumHash crypto.Qu
func (sc *RetrySignerClient) SignVote(
ctx context.Context, chainID string, quorumType btcjson.LLMQType, quorumHash crypto.QuorumHash,
- vote *tmproto.Vote, stateID types.StateID, logger log.Logger) error {
+ vote *tmproto.Vote, logger log.Logger) error {
var err error
for i := 0; i < sc.retries || sc.retries == 0; i++ {
- err = sc.next.SignVote(ctx, chainID, quorumType, quorumHash, vote, stateID, nil)
+ err = sc.next.SignVote(ctx, chainID, quorumType, quorumHash, vote, nil)
if err == nil {
return nil
}
diff --git a/privval/signer_client.go b/privval/signer_client.go
index 3da58e888e..e74b01256e 100644
--- a/privval/signer_client.go
+++ b/privval/signer_client.go
@@ -184,18 +184,14 @@ func (sc *SignerClient) SignVote(
quorumType btcjson.LLMQType,
quorumHash crypto.QuorumHash,
vote *tmproto.Vote,
- stateID types.StateID,
logger log.Logger,
) error {
// fmt.Printf("--> sending request to sign vote (%d/%d) %v - %v", vote.Height, vote.Round, vote.BlockID, vote)
- stateIDProto := stateID.ToProto()
-
voteRequest := privvalproto.SignVoteRequest{
Vote: vote,
ChainId: chainID,
QuorumType: int32(quorumType),
QuorumHash: quorumHash,
- StateId: &stateIDProto,
}
response, err := sc.endpoint.SendRequest(ctx, mustWrapMsg(&voteRequest))
diff --git a/privval/signer_client_test.go b/privval/signer_client_test.go
index 3355418765..6f1a974013 100644
--- a/privval/signer_client_test.go
+++ b/privval/signer_client_test.go
@@ -193,32 +193,27 @@ func TestSignerVote(t *testing.T) {
hash := tmrand.Bytes(crypto.HashSize)
valProTxHash := tmrand.Bytes(crypto.DefaultHashSize)
- want := &types.Vote{
- Type: tmproto.PrecommitType,
- Height: 1,
- Round: 2,
- BlockID: types.BlockID{Hash: hash, PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2}},
- ValidatorProTxHash: valProTxHash,
- ValidatorIndex: 1,
- }
-
- have := &types.Vote{
- Type: tmproto.PrecommitType,
- Height: 1,
- Round: 2,
- BlockID: types.BlockID{Hash: hash, PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2}},
+ stateID := types.RandStateID()
+
+ want := types.Vote{
+ Type: tmproto.PrecommitType,
+ Height: 1,
+ Round: 2,
+ BlockID: types.BlockID{
+ Hash: hash,
+ PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2},
+ StateID: stateID.Hash(),
+ },
ValidatorProTxHash: valProTxHash,
ValidatorIndex: 1,
}
- stateID := types.RandStateID().WithHeight(want.Height - 1)
+ have := want.Copy()
- require.NoError(t, tc.mockPV.SignVote(ctx, tc.chainID, tc.quorumType, tc.quorumHash, want.ToProto(), stateID, nil))
- require.NoError(t, tc.signerClient.SignVote(ctx, tc.chainID, tc.quorumType, tc.quorumHash, have.ToProto(), stateID, nil))
+ require.NoError(t, tc.mockPV.SignVote(ctx, tc.chainID, tc.quorumType, tc.quorumHash, want.ToProto(), nil))
+ require.NoError(t, tc.signerClient.SignVote(ctx, tc.chainID, tc.quorumType, tc.quorumHash, have.ToProto(), nil))
assert.Equal(t, want.BlockSignature, have.BlockSignature)
- assert.Equal(t, want.StateSignature, have.StateSignature)
-
})
}
}
@@ -235,34 +230,29 @@ func TestSignerVoteResetDeadline(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
hash := tmrand.Bytes(crypto.HashSize)
valProTxHash := tmrand.Bytes(crypto.DefaultHashSize)
- want := &types.Vote{
- Type: tmproto.PrecommitType,
- Height: 1,
- Round: 2,
- BlockID: types.BlockID{Hash: hash, PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2}},
- ValidatorProTxHash: valProTxHash,
- ValidatorIndex: 1,
- }
+ stateID := types.RandStateID()
- have := &types.Vote{
- Type: tmproto.PrecommitType,
- Height: 1,
- Round: 2,
- BlockID: types.BlockID{Hash: hash, PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2}},
+ want := &types.Vote{
+ Type: tmproto.PrecommitType,
+ Height: 1,
+ Round: 2,
+ BlockID: types.BlockID{
+ Hash: hash,
+ PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2},
+ StateID: stateID.Hash(),
+ },
ValidatorProTxHash: valProTxHash,
ValidatorIndex: 1,
}
+ have := want.Copy()
time.Sleep(testTimeoutReadWrite2o3)
- stateID := types.RandStateID().WithHeight(want.Height - 1)
-
require.NoError(t,
- tc.mockPV.SignVote(ctx, tc.chainID, tc.quorumType, tc.quorumHash, want.ToProto(), stateID, nil))
+ tc.mockPV.SignVote(ctx, tc.chainID, tc.quorumType, tc.quorumHash, want.ToProto(), nil))
require.NoError(t,
- tc.signerClient.SignVote(ctx, tc.chainID, tc.quorumType, tc.quorumHash, have.ToProto(), stateID, nil))
+ tc.signerClient.SignVote(ctx, tc.chainID, tc.quorumType, tc.quorumHash, have.ToProto(), nil))
assert.Equal(t, want.BlockSignature, have.BlockSignature)
- assert.Equal(t, want.StateSignature, have.StateSignature)
// TODO(jleni): Clarify what is actually being tested
@@ -270,11 +260,10 @@ func TestSignerVoteResetDeadline(t *testing.T) {
time.Sleep(testTimeoutReadWrite2o3)
require.NoError(t,
- tc.mockPV.SignVote(ctx, tc.chainID, tc.quorumType, tc.quorumHash, want.ToProto(), stateID, nil))
+ tc.mockPV.SignVote(ctx, tc.chainID, tc.quorumType, tc.quorumHash, want.ToProto(), nil))
require.NoError(t,
- tc.signerClient.SignVote(ctx, tc.chainID, tc.quorumType, tc.quorumHash, have.ToProto(), stateID, nil))
+ tc.signerClient.SignVote(ctx, tc.chainID, tc.quorumType, tc.quorumHash, have.ToProto(), nil))
assert.Equal(t, want.BlockSignature, have.BlockSignature)
- assert.Equal(t, want.StateSignature, have.StateSignature)
})
}
}
@@ -293,25 +282,22 @@ func TestSignerVoteKeepAlive(t *testing.T) {
hash := tmrand.Bytes(crypto.HashSize)
valProTxHash := tmrand.Bytes(crypto.DefaultHashSize)
- want := &types.Vote{
- Type: tmproto.PrecommitType,
- Height: 1,
- Round: 2,
- BlockID: types.BlockID{Hash: hash, PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2}},
- ValidatorProTxHash: valProTxHash,
- ValidatorIndex: 1,
- }
+ stateID := types.RandStateID()
- have := &types.Vote{
- Type: tmproto.PrecommitType,
- Height: 1,
- Round: 2,
- BlockID: types.BlockID{Hash: hash, PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2}},
+ want := &types.Vote{
+ Type: tmproto.PrecommitType,
+ Height: 1,
+ Round: 2,
+ BlockID: types.BlockID{
+ Hash: hash,
+ PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2},
+ StateID: stateID.Hash(),
+ },
ValidatorProTxHash: valProTxHash,
ValidatorIndex: 1,
}
- stateID := types.RandStateID().WithHeight(want.Height - 1)
+ have := want.Copy()
// Check that even if the client does not request a
// signature for a long time. The service is still available
@@ -321,12 +307,11 @@ func TestSignerVoteKeepAlive(t *testing.T) {
time.Sleep(testTimeoutReadWrite * 3)
require.NoError(t,
- tc.mockPV.SignVote(ctx, tc.chainID, tc.quorumType, tc.quorumHash, want.ToProto(), stateID, nil))
+ tc.mockPV.SignVote(ctx, tc.chainID, tc.quorumType, tc.quorumHash, want.ToProto(), nil))
require.NoError(t,
- tc.signerClient.SignVote(ctx, tc.chainID, tc.quorumType, tc.quorumHash, have.ToProto(), stateID, nil))
+ tc.signerClient.SignVote(ctx, tc.chainID, tc.quorumType, tc.quorumHash, have.ToProto(), nil))
assert.Equal(t, want.BlockSignature, have.BlockSignature)
- assert.Equal(t, want.StateSignature, have.StateSignature)
})
}
}
@@ -347,14 +332,20 @@ func TestSignerSignProposalErrors(t *testing.T) {
tc.mockPV = types.NewErroringMockPV()
hash := tmrand.Bytes(crypto.HashSize)
+ stateID := types.RandStateID()
+
proposal := &types.Proposal{
Type: tmproto.ProposalType,
Height: 1,
CoreChainLockedHeight: 1,
Round: 2,
POLRound: 2,
- BlockID: types.BlockID{Hash: hash, PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2}},
- Signature: []byte("signature"),
+ BlockID: types.BlockID{
+ Hash: hash,
+ PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2},
+ StateID: stateID.Hash(),
+ },
+ Signature: []byte("signature"),
}
_, err := tc.signerClient.SignProposal(ctx, tc.chainID, tc.quorumType, tc.quorumHash, proposal.ToProto())
@@ -386,31 +377,32 @@ func TestSignerSignVoteErrors(t *testing.T) {
hash := tmrand.Bytes(crypto.HashSize)
valProTxHash := tmrand.Bytes(crypto.DefaultHashSize)
vote := &types.Vote{
- Type: tmproto.PrecommitType,
- Height: 1,
- Round: 2,
- BlockID: types.BlockID{Hash: hash, PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2}},
+ Type: tmproto.PrecommitType,
+ Height: 1,
+ Round: 2,
+ BlockID: types.BlockID{
+ Hash: hash,
+ PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2},
+ StateID: types.RandStateID().Hash(),
+ },
ValidatorProTxHash: valProTxHash,
ValidatorIndex: 1,
BlockSignature: []byte("signature"),
- StateSignature: []byte("stateSignature"),
}
- stateID := types.RandStateID().WithHeight(vote.Height - 1)
-
// Replace signer service privval with one that always fails
tc.signerServer.privVal = types.NewErroringMockPV()
tc.mockPV = types.NewErroringMockPV()
- err := tc.signerClient.SignVote(context.Background(), tc.chainID, tc.quorumType, tc.quorumHash, vote.ToProto(), stateID, nil)
+ err := tc.signerClient.SignVote(context.Background(), tc.chainID, tc.quorumType, tc.quorumHash, vote.ToProto(), nil)
rserr, ok := err.(*RemoteSignerError)
require.True(t, ok, "%T", err)
require.Contains(t, rserr.Error(), types.ErroringMockPVErr.Error())
- err = tc.mockPV.SignVote(ctx, tc.chainID, tc.quorumType, tc.quorumHash, vote.ToProto(), stateID, nil)
+ err = tc.mockPV.SignVote(ctx, tc.chainID, tc.quorumType, tc.quorumHash, vote.ToProto(), nil)
require.Error(t, err)
- err = tc.signerClient.SignVote(ctx, tc.chainID, tc.quorumType, tc.quorumHash, vote.ToProto(), stateID, nil)
+ err = tc.signerClient.SignVote(ctx, tc.chainID, tc.quorumType, tc.quorumHash, vote.ToProto(), nil)
require.Error(t, err)
})
}
@@ -460,9 +452,7 @@ func TestSignerUnexpectedResponse(t *testing.T) {
want := &types.Vote{Type: tmproto.PrecommitType, Height: 1}
- stateID := types.RandStateID().WithHeight(want.Height - 1)
-
- e := tc.signerClient.SignVote(ctx, tc.chainID, tc.quorumType, tc.quorumHash, want.ToProto(), stateID, nil)
+ e := tc.signerClient.SignVote(ctx, tc.chainID, tc.quorumType, tc.quorumHash, want.ToProto(), nil)
assert.EqualError(t, e, "empty response")
})
}
diff --git a/privval/signer_requestHandler.go b/privval/signer_requestHandler.go
index abb923ab09..1293948f8d 100644
--- a/privval/signer_requestHandler.go
+++ b/privval/signer_requestHandler.go
@@ -68,24 +68,8 @@ func DefaultValidationRequestHandler(
vote := r.SignVoteRequest.Vote
voteQuorumHash := r.SignVoteRequest.QuorumHash
voteQuorumType := r.SignVoteRequest.QuorumType
- stateIDProto := r.SignVoteRequest.GetStateId()
- // Convert and validate StateID
- stateID, err := types.StateIDFromProto(stateIDProto)
- if err == nil {
- err = stateID.ValidateBasic()
- }
- if err != nil {
- res = mustWrapMsg(&privvalproto.SignedVoteResponse{
- Vote: tmproto.Vote{},
- Error: &privvalproto.RemoteSignerError{
- Code: 0,
- Description: fmt.Sprintf("Cannot parse State ID: %s", err.Error())},
- })
- break
- }
-
- err = privVal.SignVote(ctx, chainID, btcjson.LLMQType(voteQuorumType), voteQuorumHash, vote, *stateID, nil)
+ err = privVal.SignVote(ctx, chainID, btcjson.LLMQType(voteQuorumType), voteQuorumHash, vote, nil)
if err != nil {
res = mustWrapMsg(&privvalproto.SignedVoteResponse{
Vote: tmproto.Vote{}, Error: &privvalproto.RemoteSignerError{Code: 0, Description: err.Error()}})
diff --git a/proto/tendermint/abci/types.proto b/proto/tendermint/abci/types.proto
index 5867b10e63..4e017d0169 100644
--- a/proto/tendermint/abci/types.proto
+++ b/proto/tendermint/abci/types.proto
@@ -419,7 +419,6 @@ message CommitInfo {
int32 round = 1;
bytes quorum_hash = 3;
bytes block_signature = 4;
- bytes state_signature = 5;
repeated tendermint.types.VoteExtension threshold_vote_extensions = 6;
}
@@ -434,7 +433,6 @@ message ExtendedCommitInfo {
// information, including vote extensions.
bytes quorum_hash = 3;
bytes block_signature = 4;
- bytes state_signature = 5;
repeated tendermint.types.VoteExtension threshold_vote_extensions = 6;
}
diff --git a/proto/tendermint/privval/types.pb.go b/proto/tendermint/privval/types.pb.go
index 58f8e1603e..540d82d094 100644
--- a/proto/tendermint/privval/types.pb.go
+++ b/proto/tendermint/privval/types.pb.go
@@ -426,11 +426,10 @@ func (m *ProTxHashResponse) GetError() *RemoteSignerError {
// SignVoteRequest is a request to sign a vote
type SignVoteRequest struct {
- Vote *types.Vote `protobuf:"bytes,1,opt,name=vote,proto3" json:"vote,omitempty"`
- ChainId string `protobuf:"bytes,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"`
- QuorumType int32 `protobuf:"varint,3,opt,name=quorum_type,json=quorumType,proto3" json:"quorum_type,omitempty"`
- QuorumHash []byte `protobuf:"bytes,4,opt,name=quorum_hash,json=quorumHash,proto3" json:"quorum_hash,omitempty"`
- StateId *types.StateID `protobuf:"bytes,5,opt,name=state_id,json=stateId,proto3" json:"state_id,omitempty"`
+ Vote *types.Vote `protobuf:"bytes,1,opt,name=vote,proto3" json:"vote,omitempty"`
+ ChainId string `protobuf:"bytes,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"`
+ QuorumType int32 `protobuf:"varint,3,opt,name=quorum_type,json=quorumType,proto3" json:"quorum_type,omitempty"`
+ QuorumHash []byte `protobuf:"bytes,4,opt,name=quorum_hash,json=quorumHash,proto3" json:"quorum_hash,omitempty"`
}
func (m *SignVoteRequest) Reset() { *m = SignVoteRequest{} }
@@ -494,13 +493,6 @@ func (m *SignVoteRequest) GetQuorumHash() []byte {
return nil
}
-func (m *SignVoteRequest) GetStateId() *types.StateID {
- if m != nil {
- return m.StateId
- }
- return nil
-}
-
// SignedVoteResponse is a response containing a signed vote or an error
type SignedVoteResponse struct {
Vote types.Vote `protobuf:"bytes,1,opt,name=vote,proto3" json:"vote"`
@@ -1042,70 +1034,68 @@ func init() {
func init() { proto.RegisterFile("tendermint/privval/types.proto", fileDescriptor_cb4e437a5328cf9c) }
var fileDescriptor_cb4e437a5328cf9c = []byte{
- // 994 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x56, 0xdd, 0x6e, 0x1b, 0x45,
- 0x14, 0xde, 0x4d, 0xec, 0xd8, 0x39, 0x76, 0x1c, 0x67, 0x12, 0x12, 0xc7, 0x2a, 0x4e, 0x58, 0xfe,
- 0xaa, 0x20, 0x6c, 0x54, 0x10, 0x12, 0x2a, 0x37, 0x4d, 0xb2, 0x62, 0x2d, 0xab, 0xb6, 0x19, 0x3b,
- 0xb4, 0xaa, 0x84, 0x56, 0xfe, 0x19, 0xd6, 0x4b, 0x63, 0xcf, 0x74, 0x67, 0x1c, 0xd5, 0xd7, 0xdc,
- 0x71, 0x85, 0xc4, 0x4b, 0x20, 0x9e, 0x80, 0x47, 0xe8, 0x65, 0x2e, 0xb9, 0x42, 0x28, 0x79, 0x11,
- 0xb4, 0xb3, 0xe3, 0xf5, 0xda, 0x5e, 0x43, 0x51, 0x40, 0xbd, 0x9b, 0x39, 0xe7, 0xcc, 0x77, 0xbe,
- 0x39, 0x3f, 0x33, 0x07, 0x4a, 0x82, 0x8c, 0xfa, 0xc4, 0x1b, 0xba, 0x23, 0x51, 0x61, 0x9e, 0x7b,
- 0x75, 0xd5, 0xb9, 0xac, 0x88, 0x09, 0x23, 0xbc, 0xcc, 0x3c, 0x2a, 0x28, 0x42, 0x33, 0x7d, 0x59,
- 0xe9, 0x8b, 0xf7, 0x22, 0x67, 0x7a, 0xde, 0x84, 0x09, 0x5a, 0x79, 0x4e, 0x26, 0xea, 0xc4, 0x9c,
- 0x56, 0x22, 0x45, 0xf1, 0x8a, 0x7b, 0x0e, 0x75, 0xa8, 0x5c, 0x56, 0xfc, 0x55, 0x20, 0x35, 0xaa,
- 0xb0, 0x83, 0xc9, 0x90, 0x0a, 0xd2, 0x72, 0x9d, 0x11, 0xf1, 0x4c, 0xcf, 0xa3, 0x1e, 0x42, 0x90,
- 0xe8, 0xd1, 0x3e, 0x29, 0xe8, 0xc7, 0xfa, 0xfd, 0x24, 0x96, 0x6b, 0x74, 0x0c, 0x99, 0x3e, 0xe1,
- 0x3d, 0xcf, 0x65, 0xc2, 0xa5, 0xa3, 0xc2, 0xda, 0xb1, 0x7e, 0x7f, 0x13, 0x47, 0x45, 0x46, 0x0d,
- 0xb6, 0x9a, 0xe3, 0x6e, 0x8d, 0x4c, 0x30, 0x79, 0x31, 0x26, 0x5c, 0xa0, 0x43, 0x48, 0xf7, 0x06,
- 0x1d, 0x77, 0x64, 0xbb, 0x7d, 0x09, 0xb5, 0x89, 0x53, 0x72, 0x5f, 0xed, 0xa3, 0x23, 0xc8, 0xbc,
- 0x18, 0x53, 0x6f, 0x3c, 0xb4, 0x07, 0x1d, 0x3e, 0x90, 0x68, 0x59, 0x0c, 0x81, 0xc8, 0xea, 0xf0,
- 0x81, 0xd1, 0x86, 0xfd, 0xf6, 0xc0, 0x23, 0x7c, 0x40, 0x2f, 0xfb, 0xff, 0x1d, 0xea, 0xc7, 0x90,
- 0x6f, 0x7a, 0xb4, 0xfd, 0xd2, 0xdf, 0xfc, 0x33, 0x9e, 0xf1, 0xa3, 0x0e, 0xb9, 0xa9, 0x73, 0xce,
- 0xe8, 0x88, 0x13, 0xf4, 0x10, 0x52, 0x6c, 0xdc, 0xb5, 0x9f, 0x93, 0x89, 0x34, 0xce, 0x3c, 0xb8,
- 0x57, 0x8e, 0xe4, 0x29, 0xc8, 0x49, 0xb9, 0x39, 0xee, 0x5e, 0xba, 0xbd, 0x1a, 0x99, 0x9c, 0x26,
- 0x5e, 0xfd, 0x71, 0xa4, 0xe1, 0x0d, 0x26, 0x41, 0xd0, 0x43, 0x48, 0x12, 0x3f, 0xc0, 0x92, 0x59,
- 0xe6, 0xc1, 0xfb, 0xe5, 0xe5, 0x14, 0x97, 0x97, 0xb2, 0x81, 0x83, 0x33, 0xc6, 0xcf, 0x3a, 0x1c,
- 0x2c, 0x85, 0xe4, 0x8d, 0xb3, 0x62, 0xb0, 0x13, 0x89, 0xa8, 0xa2, 0x53, 0x82, 0x0c, 0xf3, 0xa8,
- 0x2d, 0x5e, 0x06, 0x79, 0xd0, 0x65, 0x1e, 0x36, 0xd9, 0xd4, 0xee, 0x6e, 0x1e, 0xaf, 0x75, 0xd8,
- 0xf6, 0xc5, 0xdf, 0x50, 0x41, 0xa6, 0x39, 0x3c, 0x81, 0xc4, 0x15, 0x15, 0x44, 0x5d, 0x7e, 0x3f,
- 0x8a, 0x17, 0xb4, 0x80, 0x34, 0x96, 0x36, 0x73, 0xf9, 0x5e, 0x5b, 0x55, 0x3f, 0xfe, 0xa9, 0xc2,
- 0xba, 0x2c, 0x7f, 0x55, 0x3f, 0xed, 0x09, 0x23, 0x8b, 0x05, 0x96, 0x58, 0x2c, 0x30, 0xf4, 0x19,
- 0xa4, 0xb9, 0xe8, 0x08, 0xe2, 0x83, 0x27, 0x25, 0x99, 0xc3, 0x65, 0x32, 0x2d, 0xdf, 0xa2, 0x7a,
- 0x8e, 0x53, 0xd2, 0xb4, 0xda, 0x37, 0x7e, 0xd0, 0x01, 0xc9, 0x9b, 0xf6, 0x83, 0x4b, 0xa9, 0x30,
- 0x7e, 0xf2, 0x3a, 0xb7, 0x52, 0xc9, 0x0c, 0xee, 0x76, 0xa7, 0xc0, 0xfe, 0xaa, 0xc3, 0xae, 0x2f,
- 0x6e, 0x7a, 0x94, 0x51, 0xde, 0xb9, 0x9c, 0x06, 0xf7, 0x73, 0x48, 0x33, 0x25, 0x52, 0x54, 0x8a,
- 0xcb, 0x54, 0xc2, 0x43, 0xa1, 0xed, 0xff, 0x1a, 0x68, 0xbf, 0x1b, 0xf6, 0x83, 0x90, 0xcd, 0xe8,
- 0xaa, 0xb0, 0x7d, 0xf9, 0x6f, 0xf8, 0xaa, 0xf0, 0xcd, 0x58, 0xdf, 0x29, 0x84, 0x5b, 0x90, 0x69,
- 0xba, 0x23, 0x47, 0x45, 0xce, 0xc8, 0x41, 0x36, 0xd8, 0x06, 0xcc, 0x8c, 0xdf, 0xd2, 0x90, 0x7a,
- 0x4c, 0x38, 0xef, 0x38, 0x04, 0xd5, 0x60, 0x5b, 0xb5, 0xac, 0xed, 0x05, 0xe6, 0x8a, 0xec, 0x3b,
- 0x71, 0x1e, 0xe7, 0x9e, 0x40, 0x4b, 0xc3, 0x5b, 0x6c, 0xee, 0x4d, 0xac, 0x43, 0x7e, 0x06, 0x16,
- 0x38, 0x53, 0xfc, 0x8d, 0xbf, 0x43, 0x0b, 0x2c, 0x2d, 0x0d, 0xe7, 0xd8, 0xfc, 0x7b, 0xf2, 0x35,
- 0xec, 0x70, 0xd7, 0x19, 0xd9, 0x7e, 0x51, 0x85, 0xf4, 0xd6, 0x25, 0xe0, 0xbb, 0x71, 0x80, 0x0b,
- 0xfd, 0x68, 0x69, 0x78, 0x9b, 0x2f, 0xb4, 0xe8, 0x33, 0xd8, 0xe3, 0x32, 0x5f, 0x53, 0x50, 0x45,
- 0x33, 0x21, 0x51, 0x3f, 0x58, 0x85, 0x3a, 0xdf, 0x12, 0x96, 0x86, 0x11, 0x5f, 0x6e, 0x94, 0x6f,
- 0xe1, 0x2d, 0x49, 0x77, 0x9a, 0xc4, 0x90, 0x72, 0xd0, 0x82, 0x1f, 0xae, 0x02, 0x5f, 0xa8, 0x74,
- 0x4b, 0xc3, 0xbb, 0x3c, 0xa6, 0x01, 0xbe, 0x83, 0x82, 0xa2, 0x1e, 0x71, 0xa0, 0xe8, 0x6f, 0x48,
- 0x0f, 0x27, 0xab, 0xe9, 0x2f, 0x96, 0xa7, 0xa5, 0xe1, 0x7d, 0x1e, 0x5f, 0xb8, 0xe7, 0x90, 0x65,
- 0xee, 0xc8, 0x09, 0xd9, 0xa7, 0x24, 0xf6, 0x51, 0x6c, 0x06, 0x67, 0x55, 0x66, 0x69, 0x38, 0xc3,
- 0x66, 0x5b, 0xf4, 0x15, 0x6c, 0x29, 0x14, 0x45, 0x31, 0x2d, 0x61, 0x8e, 0x57, 0xc3, 0x84, 0xc4,
- 0xb2, 0x2c, 0xb2, 0x47, 0x17, 0xb0, 0x1b, 0x79, 0xc5, 0x43, 0x56, 0x9b, 0x12, 0xee, 0xbd, 0x58,
- 0xb8, 0x85, 0xbf, 0xd5, 0xd2, 0x70, 0x9e, 0x2d, 0xfe, 0xb7, 0x4f, 0x61, 0x6f, 0x1e, 0x56, 0xd1,
- 0x84, 0xd5, 0xfd, 0xb6, 0xf4, 0xc3, 0x58, 0x1a, 0xde, 0x61, 0x4b, 0xdf, 0x8e, 0x03, 0x87, 0x62,
- 0xfa, 0x41, 0xda, 0x8b, 0xcd, 0x95, 0x59, 0x9d, 0xa8, 0xf8, 0x41, 0xc3, 0x4f, 0x94, 0x88, 0x1f,
- 0x41, 0xbe, 0x87, 0x62, 0x9c, 0x23, 0x75, 0x91, 0xac, 0xf4, 0xf4, 0xd1, 0x6b, 0x79, 0x0a, 0xaf,
- 0x73, 0x20, 0xe2, 0x55, 0xa7, 0x49, 0x58, 0xe7, 0xe3, 0xa1, 0x61, 0x43, 0xee, 0xd1, 0x58, 0x0c,
- 0x5a, 0xae, 0x33, 0x7d, 0x40, 0xee, 0xf4, 0xe7, 0xe7, 0x61, 0x9d, 0xbb, 0x8e, 0x9a, 0x90, 0xfc,
- 0xe5, 0xc9, 0x2f, 0x3a, 0x6c, 0xc8, 0xb7, 0x8c, 0x23, 0x04, 0x39, 0x13, 0xe3, 0x06, 0x6e, 0xd9,
- 0x17, 0xf5, 0x5a, 0xbd, 0xf1, 0xa4, 0x9e, 0xd7, 0x50, 0x09, 0x8a, 0xa1, 0xcc, 0x7c, 0xda, 0x34,
- 0xcf, 0xda, 0xe6, 0xb9, 0x8d, 0xcd, 0x56, 0xb3, 0x51, 0x6f, 0x99, 0x79, 0x1d, 0x15, 0x60, 0x4f,
- 0xe9, 0xeb, 0x0d, 0xfb, 0xac, 0x51, 0xaf, 0x9b, 0x67, 0xed, 0x6a, 0xa3, 0x9e, 0x5f, 0x43, 0x6f,
- 0xc3, 0xa1, 0xd2, 0xcc, 0xc4, 0x76, 0xbb, 0xfa, 0xd8, 0x6c, 0x5c, 0xb4, 0xf3, 0xeb, 0xe8, 0x00,
- 0x76, 0x95, 0x1a, 0x9b, 0x8f, 0xce, 0x43, 0x45, 0x22, 0x82, 0xf8, 0x04, 0x57, 0xdb, 0x66, 0xa8,
- 0x49, 0x9e, 0xb6, 0x5e, 0xdd, 0x94, 0xf4, 0xeb, 0x9b, 0x92, 0xfe, 0xe7, 0x4d, 0x49, 0xff, 0xe9,
- 0xb6, 0xa4, 0x5d, 0xdf, 0x96, 0xb4, 0xdf, 0x6f, 0x4b, 0xda, 0xb3, 0x2f, 0x1c, 0x57, 0x0c, 0xc6,
- 0xdd, 0x72, 0x8f, 0x0e, 0x2b, 0xd1, 0x61, 0x38, 0x3a, 0x69, 0xfb, 0x03, 0xf0, 0xf2, 0xe8, 0xdd,
- 0xdd, 0x90, 0x9a, 0x4f, 0xff, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x69, 0x90, 0x95, 0xf9, 0x97, 0x0b,
- 0x00, 0x00,
+ // 971 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x56, 0xdd, 0x6e, 0xe3, 0x44,
+ 0x14, 0xb6, 0x37, 0x49, 0x7f, 0x4e, 0xd2, 0x34, 0x9d, 0x96, 0x36, 0x8d, 0x96, 0xb4, 0x84, 0xbf,
+ 0x55, 0x11, 0x09, 0x5a, 0x24, 0x24, 0xb4, 0xdc, 0x6c, 0x5b, 0x0b, 0x47, 0xd1, 0x26, 0x61, 0xe2,
+ 0xb2, 0xab, 0x95, 0x90, 0x95, 0x9f, 0xc1, 0x31, 0xdb, 0x78, 0x66, 0x3d, 0x76, 0xb5, 0xb9, 0xe6,
+ 0x8e, 0x2b, 0xa4, 0xbd, 0xe3, 0x09, 0x10, 0x4f, 0xc0, 0x23, 0xec, 0xe5, 0x5e, 0x72, 0x85, 0x50,
+ 0xfb, 0x22, 0xc8, 0xe3, 0x89, 0xe3, 0xc4, 0x0e, 0x2c, 0x2a, 0x88, 0x3b, 0xcf, 0x39, 0x33, 0xdf,
+ 0xf9, 0x7c, 0xbe, 0x73, 0x66, 0x0e, 0x54, 0x3d, 0xe2, 0x8c, 0x88, 0x3b, 0xb1, 0x1d, 0xaf, 0xc1,
+ 0x5c, 0xfb, 0xea, 0xaa, 0x7f, 0xd9, 0xf0, 0xa6, 0x8c, 0xf0, 0x3a, 0x73, 0xa9, 0x47, 0x11, 0x9a,
+ 0xfb, 0xeb, 0xd2, 0x5f, 0xb9, 0x1b, 0x3b, 0x33, 0x74, 0xa7, 0xcc, 0xa3, 0x8d, 0x67, 0x64, 0x2a,
+ 0x4f, 0x2c, 0x78, 0x05, 0x52, 0x1c, 0xaf, 0xb2, 0x67, 0x51, 0x8b, 0x8a, 0xcf, 0x46, 0xf0, 0x15,
+ 0x5a, 0x6b, 0x4d, 0xd8, 0xc1, 0x64, 0x42, 0x3d, 0xd2, 0xb3, 0x2d, 0x87, 0xb8, 0x9a, 0xeb, 0x52,
+ 0x17, 0x21, 0xc8, 0x0e, 0xe9, 0x88, 0x94, 0xd5, 0x63, 0xf5, 0x5e, 0x0e, 0x8b, 0x6f, 0x74, 0x0c,
+ 0xf9, 0x11, 0xe1, 0x43, 0xd7, 0x66, 0x9e, 0x4d, 0x9d, 0xf2, 0x9d, 0x63, 0xf5, 0xde, 0x26, 0x8e,
+ 0x9b, 0x6a, 0x2d, 0xd8, 0xea, 0xfa, 0x83, 0x16, 0x99, 0x62, 0xf2, 0xdc, 0x27, 0xdc, 0x43, 0x87,
+ 0xb0, 0x31, 0x1c, 0xf7, 0x6d, 0xc7, 0xb4, 0x47, 0x02, 0x6a, 0x13, 0xaf, 0x8b, 0x75, 0x73, 0x84,
+ 0x8e, 0x20, 0xff, 0xdc, 0xa7, 0xae, 0x3f, 0x31, 0xc7, 0x7d, 0x3e, 0x16, 0x68, 0x05, 0x0c, 0xa1,
+ 0x49, 0xef, 0xf3, 0x71, 0xcd, 0x80, 0x7d, 0x63, 0xec, 0x12, 0x3e, 0xa6, 0x97, 0xa3, 0x7f, 0x0f,
+ 0xf5, 0x63, 0x28, 0x75, 0x5d, 0x6a, 0xbc, 0x08, 0x16, 0x7f, 0x8f, 0x57, 0xfb, 0x41, 0x85, 0xe2,
+ 0x2c, 0x38, 0x67, 0xd4, 0xe1, 0x04, 0x3d, 0x80, 0x75, 0xe6, 0x0f, 0xcc, 0x67, 0x64, 0x2a, 0x36,
+ 0xe7, 0xef, 0xdf, 0xad, 0xc7, 0x74, 0x0a, 0x35, 0xa9, 0x77, 0xfd, 0xc1, 0xa5, 0x3d, 0x6c, 0x91,
+ 0xe9, 0x69, 0xf6, 0xd5, 0xef, 0x47, 0x0a, 0x5e, 0x63, 0x02, 0x04, 0x3d, 0x80, 0x1c, 0x09, 0x12,
+ 0x2c, 0x98, 0xe5, 0xef, 0xbf, 0x5f, 0x4f, 0x4a, 0x5c, 0x4f, 0xa8, 0x81, 0xc3, 0x33, 0xb5, 0x97,
+ 0x2a, 0x1c, 0x24, 0x52, 0xf2, 0xbf, 0xb3, 0x62, 0xb0, 0x13, 0xcb, 0xa8, 0xa4, 0x53, 0x85, 0x3c,
+ 0x73, 0xa9, 0xe9, 0xbd, 0x08, 0x75, 0x50, 0x85, 0x0e, 0x9b, 0x6c, 0xb6, 0xef, 0x76, 0x11, 0x7f,
+ 0x52, 0x61, 0x3b, 0x30, 0x7f, 0x4d, 0x3d, 0x32, 0xd3, 0xf0, 0x04, 0xb2, 0x57, 0xd4, 0x23, 0xf2,
+ 0xe7, 0xf7, 0xe3, 0x78, 0x61, 0x0b, 0x88, 0xcd, 0x62, 0xcf, 0x82, 0xde, 0x77, 0x56, 0xd5, 0x4f,
+ 0x70, 0xaa, 0x9c, 0x11, 0xe5, 0x2f, 0xeb, 0xc7, 0x98, 0x32, 0xb2, 0x5c, 0x60, 0xd9, 0x44, 0x81,
+ 0x7d, 0xaf, 0x02, 0x12, 0x9c, 0x47, 0x21, 0x3d, 0x99, 0x90, 0x4f, 0xde, 0x84, 0x9f, 0x94, 0x25,
+ 0x64, 0x79, 0xab, 0x14, 0xfd, 0xa2, 0xc2, 0x6e, 0x60, 0xee, 0xba, 0x94, 0x51, 0xde, 0xbf, 0x9c,
+ 0xa5, 0xe9, 0x33, 0xd8, 0x60, 0xd2, 0x24, 0xa9, 0x54, 0x92, 0x54, 0xa2, 0x43, 0xd1, 0xde, 0xff,
+ 0x36, 0x65, 0x2f, 0x55, 0xd8, 0x0f, 0x53, 0x36, 0xa7, 0x2b, 0xd3, 0xf6, 0xc5, 0x3f, 0xe1, 0x2b,
+ 0xd3, 0x37, 0x67, 0x7d, 0xab, 0x14, 0x6e, 0x41, 0xbe, 0x6b, 0x3b, 0x96, 0xcc, 0x5c, 0xad, 0x08,
+ 0x85, 0x70, 0x19, 0x32, 0xab, 0xfd, 0xba, 0x01, 0xeb, 0x8f, 0x08, 0xe7, 0x7d, 0x8b, 0xa0, 0x16,
+ 0x6c, 0xcb, 0xe6, 0x33, 0xdd, 0x70, 0xbb, 0x24, 0xfb, 0x4e, 0x5a, 0xc4, 0x85, 0xcb, 0x4c, 0x57,
+ 0xf0, 0x16, 0x5b, 0xb8, 0xdd, 0xda, 0x50, 0x9a, 0x83, 0x85, 0xc1, 0x24, 0xff, 0xda, 0x5f, 0xa1,
+ 0x85, 0x3b, 0x75, 0x05, 0x17, 0xd9, 0xe2, 0xcd, 0xf0, 0x15, 0xec, 0x70, 0xdb, 0x72, 0xcc, 0xa0,
+ 0xa8, 0x22, 0x7a, 0x19, 0x01, 0xf8, 0x6e, 0x1a, 0xe0, 0x52, 0x67, 0xe9, 0x0a, 0xde, 0xe6, 0x4b,
+ 0xcd, 0xf6, 0x14, 0xf6, 0xb8, 0xd0, 0x6b, 0x06, 0x2a, 0x69, 0x66, 0x05, 0xea, 0x07, 0xab, 0x50,
+ 0x17, 0x5b, 0x42, 0x57, 0x30, 0xe2, 0xc9, 0x46, 0xf9, 0x06, 0xde, 0x12, 0x74, 0x67, 0x22, 0x46,
+ 0x94, 0x73, 0x02, 0xfc, 0xc3, 0x55, 0xe0, 0x4b, 0x95, 0xae, 0x2b, 0x78, 0x97, 0xa7, 0x34, 0xc0,
+ 0xb7, 0x50, 0x96, 0xd4, 0x63, 0x01, 0x24, 0xfd, 0x35, 0x11, 0xe1, 0x64, 0x35, 0xfd, 0xe5, 0xf2,
+ 0xd4, 0x15, 0xbc, 0xcf, 0xd3, 0x0b, 0xf7, 0x1c, 0x0a, 0xcc, 0x76, 0xac, 0x88, 0xfd, 0xba, 0xc0,
+ 0x3e, 0x4a, 0x55, 0x70, 0x5e, 0x65, 0xba, 0x82, 0xf3, 0x6c, 0xbe, 0x44, 0x5f, 0xc2, 0x96, 0x44,
+ 0x91, 0x14, 0x37, 0x04, 0xcc, 0xf1, 0x6a, 0x98, 0x88, 0x58, 0x81, 0xc5, 0xd6, 0xe8, 0x02, 0x76,
+ 0x63, 0xf7, 0x71, 0xc4, 0x6a, 0x53, 0xc0, 0xbd, 0x97, 0x0a, 0xb7, 0xf4, 0x4a, 0xea, 0x0a, 0x2e,
+ 0xb1, 0xe5, 0x97, 0xf3, 0x09, 0xec, 0x2d, 0xc2, 0x4a, 0x9a, 0xb0, 0xba, 0xdf, 0x12, 0x6f, 0x85,
+ 0xae, 0xe0, 0x1d, 0x96, 0x78, 0x40, 0x2c, 0x38, 0xf4, 0x66, 0x4f, 0x9d, 0xb9, 0xdc, 0x5c, 0xf9,
+ 0xd5, 0x42, 0xa5, 0x8f, 0x0c, 0x81, 0x50, 0x5e, 0xfa, 0x30, 0xf1, 0x1d, 0x54, 0xd2, 0x02, 0xc9,
+ 0x1f, 0x29, 0x88, 0x48, 0x1f, 0xbd, 0x51, 0xa4, 0xe8, 0x77, 0x0e, 0xbc, 0x74, 0xd7, 0x69, 0x0e,
+ 0x32, 0xdc, 0x9f, 0xd4, 0x4c, 0x28, 0x3e, 0xf4, 0xbd, 0x71, 0xcf, 0xb6, 0x66, 0x17, 0xc8, 0xad,
+ 0x5e, 0xef, 0x12, 0x64, 0xb8, 0x6d, 0xc9, 0x59, 0x27, 0xf8, 0x3c, 0xf9, 0x59, 0x85, 0x35, 0x71,
+ 0x97, 0x71, 0x84, 0xa0, 0xa8, 0x61, 0xdc, 0xc1, 0x3d, 0xf3, 0xa2, 0xdd, 0x6a, 0x77, 0x1e, 0xb7,
+ 0x4b, 0x0a, 0xaa, 0x42, 0x25, 0xb2, 0x69, 0x4f, 0xba, 0xda, 0x99, 0xa1, 0x9d, 0x9b, 0x58, 0xeb,
+ 0x75, 0x3b, 0xed, 0x9e, 0x56, 0x52, 0x51, 0x19, 0xf6, 0xa4, 0xbf, 0xdd, 0x31, 0xcf, 0x3a, 0xed,
+ 0xb6, 0x76, 0x66, 0x34, 0x3b, 0xed, 0xd2, 0x1d, 0xf4, 0x36, 0x1c, 0x4a, 0xcf, 0xdc, 0x6c, 0x1a,
+ 0xcd, 0x47, 0x5a, 0xe7, 0xc2, 0x28, 0x65, 0xd0, 0x01, 0xec, 0x4a, 0x37, 0xd6, 0x1e, 0x9e, 0x47,
+ 0x8e, 0x6c, 0x0c, 0xf1, 0x31, 0x6e, 0x1a, 0x5a, 0xe4, 0xc9, 0x9d, 0xf6, 0x5e, 0x5d, 0x57, 0xd5,
+ 0xd7, 0xd7, 0x55, 0xf5, 0x8f, 0xeb, 0xaa, 0xfa, 0xe3, 0x4d, 0x55, 0x79, 0x7d, 0x53, 0x55, 0x7e,
+ 0xbb, 0xa9, 0x2a, 0x4f, 0x3f, 0xb7, 0x6c, 0x6f, 0xec, 0x0f, 0xea, 0x43, 0x3a, 0x69, 0xc4, 0xc7,
+ 0xda, 0xf8, 0xcc, 0x1c, 0x8c, 0xb2, 0xc9, 0x21, 0x7a, 0xb0, 0x26, 0x3c, 0x9f, 0xfe, 0x19, 0x00,
+ 0x00, 0xff, 0xff, 0x20, 0x29, 0xf7, 0xf6, 0x61, 0x0b, 0x00, 0x00,
}
func (m *RemoteSignerError) Marshal() (dAtA []byte, err error) {
@@ -1399,18 +1389,6 @@ func (m *SignVoteRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
- if m.StateId != nil {
- {
- size, err := m.StateId.MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintTypes(dAtA, i, uint64(size))
- }
- i--
- dAtA[i] = 0x2a
- }
if len(m.QuorumHash) > 0 {
i -= len(m.QuorumHash)
copy(dAtA[i:], m.QuorumHash)
@@ -2101,10 +2079,6 @@ func (m *SignVoteRequest) Size() (n int) {
if l > 0 {
n += 1 + l + sovTypes(uint64(l))
}
- if m.StateId != nil {
- l = m.StateId.Size()
- n += 1 + l + sovTypes(uint64(l))
- }
return n
}
@@ -3280,42 +3254,6 @@ func (m *SignVoteRequest) Unmarshal(dAtA []byte) error {
m.QuorumHash = []byte{}
}
iNdEx = postIndex
- case 5:
- if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field StateId", wireType)
- }
- var msglen int
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- return ErrIntOverflowTypes
- }
- if iNdEx >= l {
- return io.ErrUnexpectedEOF
- }
- b := dAtA[iNdEx]
- iNdEx++
- msglen |= int(b&0x7F) << shift
- if b < 0x80 {
- break
- }
- }
- if msglen < 0 {
- return ErrInvalidLengthTypes
- }
- postIndex := iNdEx + msglen
- if postIndex < 0 {
- return ErrInvalidLengthTypes
- }
- if postIndex > l {
- return io.ErrUnexpectedEOF
- }
- if m.StateId == nil {
- m.StateId = &types.StateID{}
- }
- if err := m.StateId.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
- return err
- }
- iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipTypes(dAtA[iNdEx:])
diff --git a/proto/tendermint/privval/types.proto b/proto/tendermint/privval/types.proto
index d3e4f373bb..205899ae41 100644
--- a/proto/tendermint/privval/types.proto
+++ b/proto/tendermint/privval/types.proto
@@ -58,11 +58,10 @@ message ProTxHashResponse {
// SignVoteRequest is a request to sign a vote
message SignVoteRequest {
- tendermint.types.Vote vote = 1;
- string chain_id = 2;
- int32 quorum_type = 3;
- bytes quorum_hash = 4;
- tendermint.types.StateID state_id = 5;
+ tendermint.types.Vote vote = 1;
+ string chain_id = 2;
+ int32 quorum_type = 3;
+ bytes quorum_hash = 4;
}
// SignedVoteResponse is a response containing a signed vote or an error
diff --git a/proto/tendermint/state/types.pb.go b/proto/tendermint/state/types.pb.go
index 9362e2f969..08e9f7680b 100644
--- a/proto/tendermint/state/types.pb.go
+++ b/proto/tendermint/state/types.pb.go
@@ -251,7 +251,6 @@ type State struct {
// LastBlockHeight=0 at genesis (ie. block(H=0) does not exist)
LastBlockHeight int64 `protobuf:"varint,3,opt,name=last_block_height,json=lastBlockHeight,proto3" json:"last_block_height,omitempty"`
LastBlockID types1.BlockID `protobuf:"bytes,4,opt,name=last_block_id,json=lastBlockId,proto3" json:"last_block_id"`
- LastStateID types1.StateID `protobuf:"bytes,102,opt,name=last_state_id,json=lastStateId,proto3" json:"last_state_id"`
LastBlockTime time.Time `protobuf:"bytes,5,opt,name=last_block_time,json=lastBlockTime,proto3,stdtime" json:"last_block_time"`
LastCoreChainLockedBlockHeight uint32 `protobuf:"varint,100,opt,name=last_core_chain_locked_block_height,json=lastCoreChainLockedBlockHeight,proto3" json:"last_core_chain_locked_block_height,omitempty"`
NextCoreChainLock *types1.CoreChainLock `protobuf:"bytes,101,opt,name=next_core_chain_lock,json=nextCoreChainLock,proto3" json:"next_core_chain_lock,omitempty"`
@@ -341,13 +340,6 @@ func (m *State) GetLastBlockID() types1.BlockID {
return types1.BlockID{}
}
-func (m *State) GetLastStateID() types1.StateID {
- if m != nil {
- return m.LastStateID
- }
- return types1.StateID{}
-}
-
func (m *State) GetLastBlockTime() time.Time {
if m != nil {
return m.LastBlockTime
@@ -429,59 +421,57 @@ func init() {
func init() { proto.RegisterFile("tendermint/state/types.proto", fileDescriptor_ccfacf933f22bf93) }
var fileDescriptor_ccfacf933f22bf93 = []byte{
- // 818 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0xcd, 0x6e, 0xf3, 0x44,
- 0x14, 0x8d, 0xe9, 0xf7, 0x91, 0x64, 0x52, 0x27, 0xed, 0xb4, 0x0b, 0x37, 0xa5, 0x4e, 0x08, 0x50,
- 0x45, 0x2c, 0x1c, 0x09, 0x16, 0x88, 0x0d, 0x52, 0x93, 0x0a, 0x1a, 0x51, 0x50, 0x71, 0x51, 0x17,
- 0x6c, 0xac, 0x89, 0x3d, 0x89, 0x2d, 0x1c, 0x8f, 0xe5, 0x99, 0x94, 0x9f, 0x3d, 0xfb, 0xb2, 0xe4,
- 0x39, 0x78, 0x89, 0x2e, 0xbb, 0x64, 0x55, 0x50, 0xfa, 0x22, 0x68, 0x7e, 0x6c, 0x8f, 0x93, 0x56,
- 0x2a, 0x62, 0x97, 0xb9, 0xe7, 0xdc, 0x33, 0x27, 0x67, 0xe6, 0x8e, 0xc1, 0x7b, 0x0c, 0x27, 0x01,
- 0xce, 0x96, 0x51, 0xc2, 0x46, 0x94, 0x21, 0x86, 0x47, 0xec, 0x97, 0x14, 0x53, 0x27, 0xcd, 0x08,
- 0x23, 0x70, 0xaf, 0x44, 0x1d, 0x81, 0x76, 0x0f, 0x17, 0x64, 0x41, 0x04, 0x38, 0xe2, 0xbf, 0x24,
- 0xaf, 0x7b, 0xac, 0xa9, 0xa0, 0x99, 0x1f, 0xe9, 0x22, 0x5d, 0x7d, 0x0b, 0x51, 0xaf, 0xa0, 0xc7,
- 0x5b, 0x68, 0x80, 0x68, 0xa8, 0xc0, 0xfe, 0x16, 0x78, 0x8b, 0xe2, 0x28, 0x40, 0x8c, 0x64, 0x8a,
- 0x71, 0xb2, 0xc5, 0x48, 0x51, 0x86, 0x96, 0xb9, 0xba, 0xad, 0xc1, 0xb7, 0x38, 0xa3, 0x11, 0x49,
- 0x2a, 0xbb, 0xf7, 0x16, 0x84, 0x2c, 0x62, 0x3c, 0x12, 0xab, 0xd9, 0x6a, 0x3e, 0x62, 0xd1, 0x12,
- 0x53, 0x86, 0x96, 0xa9, 0x24, 0x0c, 0xfe, 0x34, 0x80, 0x79, 0x36, 0x9e, 0x4c, 0x5d, 0x4c, 0x53,
- 0x92, 0x50, 0x4c, 0xe1, 0x37, 0xa0, 0x3d, 0x8f, 0x12, 0x14, 0x47, 0xbf, 0x62, 0x6f, 0x16, 0x13,
- 0xff, 0x47, 0xeb, 0x9d, 0xbe, 0x31, 0x6c, 0x7d, 0x72, 0xea, 0x68, 0x61, 0xf1, 0x10, 0x9c, 0xbc,
- 0xe7, 0x4b, 0x45, 0x1f, 0x73, 0xb6, 0x6b, 0xce, 0xf5, 0x25, 0xbc, 0x06, 0x7b, 0x69, 0x46, 0x7c,
- 0x4c, 0xa9, 0x97, 0x66, 0x24, 0x25, 0x14, 0xc5, 0xd6, 0x8e, 0x10, 0x1c, 0xbe, 0x28, 0x78, 0x25,
- 0x1b, 0xae, 0x14, 0xdf, 0xed, 0xa4, 0xd5, 0xc2, 0xe0, 0x37, 0x03, 0xb4, 0x6f, 0xf2, 0xa4, 0xe8,
- 0x34, 0x99, 0x13, 0x38, 0x01, 0x66, 0x91, 0x9d, 0x47, 0x31, 0xb3, 0x0c, 0xb1, 0x89, 0xad, 0x6f,
- 0x22, 0x93, 0x29, 0x1a, 0xaf, 0x31, 0x73, 0x77, 0x6f, 0xb5, 0x15, 0x74, 0xc0, 0x41, 0x8c, 0x28,
- 0xf3, 0x42, 0x1c, 0x2d, 0x42, 0xe6, 0xf9, 0x21, 0x4a, 0x16, 0x38, 0x10, 0x01, 0xec, 0xb8, 0xfb,
- 0x1c, 0xba, 0x10, 0xc8, 0x44, 0x02, 0x83, 0x3f, 0x0c, 0x70, 0x30, 0xe1, 0x8e, 0x13, 0xba, 0xa2,
- 0x57, 0xe2, 0x60, 0x84, 0x19, 0x17, 0xec, 0xf9, 0x79, 0xd9, 0x93, 0x07, 0xa6, 0xfc, 0xbc, 0xbf,
- 0xed, 0x67, 0x43, 0x60, 0xfc, 0xe6, 0xfe, 0xb1, 0x57, 0x73, 0x3b, 0x7e, 0xb5, 0xfc, 0x9f, 0xbd,
- 0x85, 0xa0, 0x7e, 0x23, 0x6f, 0x04, 0x3c, 0x03, 0xcd, 0x42, 0x4d, 0xf9, 0x38, 0xd1, 0x7d, 0xa8,
- 0x9b, 0x53, 0x3a, 0x51, 0x1e, 0xca, 0x2e, 0xd8, 0x05, 0x0d, 0x4a, 0xe6, 0xec, 0x27, 0x94, 0x61,
- 0xb1, 0x65, 0xd3, 0x2d, 0xd6, 0x83, 0xdf, 0x1b, 0xe0, 0xed, 0x35, 0x9f, 0x1e, 0xf8, 0x39, 0xa8,
- 0x2b, 0x2d, 0xb5, 0xcd, 0x91, 0xb3, 0x39, 0x61, 0x8e, 0x32, 0xa5, 0xb6, 0xc8, 0xf9, 0xf0, 0x14,
- 0x34, 0xfc, 0x10, 0x45, 0x89, 0x17, 0xc9, 0xff, 0xd4, 0x1c, 0xb7, 0xd6, 0x8f, 0xbd, 0xfa, 0x84,
- 0xd7, 0xa6, 0xe7, 0x6e, 0x5d, 0x80, 0xd3, 0x00, 0x7e, 0x04, 0xda, 0x51, 0x12, 0xb1, 0x08, 0xc5,
- 0x2a, 0x09, 0xab, 0x2d, 0x12, 0x30, 0x55, 0x55, 0x86, 0x00, 0x3f, 0x06, 0x22, 0x12, 0x79, 0x83,
- 0x73, 0xe6, 0x8e, 0x60, 0x76, 0x38, 0x20, 0x2e, 0xa7, 0xe2, 0xba, 0xc0, 0xd4, 0xb8, 0x51, 0x60,
- 0xbd, 0xd9, 0xf6, 0x2e, 0x8f, 0x4a, 0x74, 0x4d, 0xcf, 0xc7, 0x07, 0xdc, 0xfb, 0xfa, 0xb1, 0xd7,
- 0xba, 0xcc, 0xa5, 0xa6, 0xe7, 0x6e, 0xab, 0xd0, 0x9d, 0x06, 0x85, 0xa6, 0xf8, 0xcf, 0x5c, 0x73,
- 0xfe, 0x92, 0xa6, 0x48, 0x6e, 0x53, 0x53, 0x15, 0xa5, 0xa6, 0x5c, 0x04, 0xf0, 0x12, 0x74, 0x34,
- 0x9f, 0x7c, 0x92, 0xad, 0xb7, 0x42, 0xb5, 0xeb, 0xc8, 0x31, 0x77, 0xf2, 0x31, 0x77, 0xbe, 0xcf,
- 0xc7, 0x7c, 0xdc, 0xe0, 0xb2, 0x77, 0x7f, 0xf7, 0x0c, 0xd7, 0x2c, 0xfc, 0x71, 0x14, 0x7e, 0x0d,
- 0x3e, 0x10, 0x6a, 0x3e, 0xc9, 0xb0, 0x27, 0xa3, 0xe7, 0x18, 0x0e, 0xaa, 0x99, 0x05, 0x7d, 0x63,
- 0x68, 0xba, 0x36, 0xa7, 0x4e, 0x48, 0x86, 0xc5, 0x79, 0x5c, 0x0a, 0x9e, 0x1e, 0xe1, 0x0d, 0x38,
- 0x4c, 0xf0, 0xcf, 0x5b, 0x62, 0x16, 0x16, 0xfe, 0x7a, 0xcf, 0x5d, 0x7a, 0x4d, 0x4b, 0xdc, 0x05,
- 0xc3, 0xdd, 0xe7, 0x12, 0x15, 0x00, 0x7e, 0x01, 0x40, 0x31, 0xa0, 0xd4, 0xaa, 0xbf, 0x6a, 0xa4,
- 0xb5, 0x0e, 0xf8, 0x95, 0x8a, 0x4c, 0x13, 0x69, 0xbc, 0x4a, 0xa4, 0xcd, 0xdb, 0xca, 0x27, 0x06,
- 0x4e, 0x80, 0xad, 0x4f, 0x5f, 0xa9, 0x57, 0x0c, 0x62, 0x53, 0x5c, 0xae, 0xe3, 0x72, 0x10, 0xcb,
- 0x6e, 0x35, 0x92, 0xcf, 0x3e, 0x0b, 0xe0, 0x7f, 0x3e, 0x0b, 0xdf, 0x82, 0x0f, 0x2b, 0xcf, 0xc2,
- 0x86, 0x7e, 0x61, 0xaf, 0x25, 0xec, 0xf5, 0xb5, 0x77, 0xa2, 0x2a, 0x94, 0x7b, 0xcc, 0x07, 0x27,
- 0xc3, 0x74, 0x15, 0x33, 0xea, 0x85, 0x88, 0x86, 0xd6, 0x6e, 0xdf, 0x18, 0xee, 0xca, 0xc1, 0x71,
- 0x65, 0xfd, 0x02, 0xd1, 0x10, 0x1e, 0x81, 0x06, 0x4a, 0x53, 0x49, 0x31, 0x05, 0xa5, 0x8e, 0xd2,
- 0x94, 0x43, 0xe3, 0xef, 0xee, 0xd7, 0xb6, 0xf1, 0xb0, 0xb6, 0x8d, 0x7f, 0xd6, 0xb6, 0x71, 0xf7,
- 0x64, 0xd7, 0x1e, 0x9e, 0xec, 0xda, 0x5f, 0x4f, 0x76, 0xed, 0x87, 0xcf, 0x16, 0x11, 0x0b, 0x57,
- 0x33, 0xc7, 0x27, 0xcb, 0x91, 0xfe, 0x71, 0x2b, 0x7f, 0xca, 0xcf, 0xef, 0xe6, 0x87, 0x7b, 0xf6,
- 0xae, 0xa8, 0x7f, 0xfa, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0xbf, 0x4e, 0xb1, 0xd3, 0x07,
- 0x00, 0x00,
+ // 798 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0x3f, 0x6f, 0xfb, 0x44,
+ 0x18, 0x8e, 0xe9, 0xaf, 0x24, 0xb9, 0xd4, 0x49, 0x7b, 0xed, 0xe0, 0xa6, 0xd4, 0x09, 0x01, 0xaa,
+ 0x88, 0xc1, 0x91, 0x60, 0x40, 0x2c, 0x48, 0x4d, 0x2a, 0x68, 0x44, 0x41, 0xc5, 0x45, 0x1d, 0x58,
+ 0xac, 0x8b, 0x7d, 0x89, 0x2d, 0x1c, 0x9f, 0xe5, 0xbb, 0x94, 0x3f, 0x3b, 0x7b, 0x57, 0x3e, 0x07,
+ 0x33, 0x7b, 0xc7, 0x8e, 0x4c, 0x05, 0xa5, 0x5f, 0x04, 0xdd, 0x1f, 0xdb, 0xe7, 0xa4, 0x48, 0x45,
+ 0xbf, 0x2d, 0x7e, 0x9f, 0xe7, 0x7d, 0xee, 0xf1, 0x7b, 0xef, 0x13, 0x83, 0xf7, 0x18, 0x4e, 0x02,
+ 0x9c, 0x2d, 0xa3, 0x84, 0x8d, 0x28, 0x43, 0x0c, 0x8f, 0xd8, 0x2f, 0x29, 0xa6, 0x4e, 0x9a, 0x11,
+ 0x46, 0xe0, 0x7e, 0x89, 0x3a, 0x02, 0xed, 0x1e, 0x2d, 0xc8, 0x82, 0x08, 0x70, 0xc4, 0x7f, 0x49,
+ 0x5e, 0xf7, 0x44, 0x53, 0x41, 0x33, 0x3f, 0xd2, 0x45, 0xba, 0xfa, 0x11, 0xa2, 0x5e, 0x41, 0x4f,
+ 0xb6, 0xd0, 0x00, 0xd1, 0x50, 0x81, 0xfd, 0x2d, 0xf0, 0x0e, 0xc5, 0x51, 0x80, 0x18, 0xc9, 0x14,
+ 0xe3, 0x74, 0x8b, 0x91, 0xa2, 0x0c, 0x2d, 0x73, 0x75, 0x5b, 0x83, 0xef, 0x70, 0x46, 0x23, 0x92,
+ 0x54, 0x4e, 0xef, 0x2d, 0x08, 0x59, 0xc4, 0x78, 0x24, 0x9e, 0x66, 0xab, 0xf9, 0x88, 0x45, 0x4b,
+ 0x4c, 0x19, 0x5a, 0xa6, 0x92, 0x30, 0xf8, 0xc3, 0x00, 0xe6, 0xf9, 0x78, 0x32, 0x75, 0x31, 0x4d,
+ 0x49, 0x42, 0x31, 0x85, 0xdf, 0x80, 0xf6, 0x3c, 0x4a, 0x50, 0x1c, 0xfd, 0x8a, 0xbd, 0x59, 0x4c,
+ 0xfc, 0x1f, 0xad, 0x77, 0xfa, 0xc6, 0xb0, 0xf5, 0xc9, 0x99, 0xa3, 0x0d, 0x8b, 0x0f, 0xc1, 0xc9,
+ 0x7b, 0xbe, 0x54, 0xf4, 0x31, 0x67, 0xbb, 0xe6, 0x5c, 0x7f, 0x84, 0x37, 0x60, 0x3f, 0xcd, 0x88,
+ 0x8f, 0x29, 0xf5, 0xd2, 0x8c, 0xa4, 0x84, 0xa2, 0xd8, 0xda, 0x11, 0x82, 0xc3, 0xff, 0x14, 0xbc,
+ 0x96, 0x0d, 0xd7, 0x8a, 0xef, 0x76, 0xd2, 0x6a, 0x61, 0xf0, 0x9b, 0x01, 0xda, 0xb7, 0xf9, 0xa4,
+ 0xe8, 0x34, 0x99, 0x13, 0x38, 0x01, 0x66, 0x31, 0x3b, 0x8f, 0x62, 0x66, 0x19, 0xe2, 0x10, 0x5b,
+ 0x3f, 0x44, 0x4e, 0xa6, 0x68, 0xbc, 0xc1, 0xcc, 0xdd, 0xbb, 0xd3, 0x9e, 0xa0, 0x03, 0x0e, 0x63,
+ 0x44, 0x99, 0x17, 0xe2, 0x68, 0x11, 0x32, 0xcf, 0x0f, 0x51, 0xb2, 0xc0, 0x81, 0x18, 0xc0, 0x8e,
+ 0x7b, 0xc0, 0xa1, 0x4b, 0x81, 0x4c, 0x24, 0x30, 0xf8, 0xdd, 0x00, 0x87, 0x13, 0xee, 0x38, 0xa1,
+ 0x2b, 0x7a, 0x2d, 0x2e, 0x46, 0x98, 0x71, 0xc1, 0xbe, 0x9f, 0x97, 0x3d, 0x79, 0x61, 0xca, 0xcf,
+ 0xfb, 0xdb, 0x7e, 0x36, 0x04, 0xc6, 0x6f, 0x1e, 0x9e, 0x7a, 0x35, 0xb7, 0xe3, 0x57, 0xcb, 0xff,
+ 0xdb, 0x5b, 0x08, 0xea, 0xb7, 0x72, 0x23, 0xe0, 0x39, 0x68, 0x16, 0x6a, 0xca, 0xc7, 0xa9, 0xee,
+ 0x43, 0x6d, 0x4e, 0xe9, 0x44, 0x79, 0x28, 0xbb, 0x60, 0x17, 0x34, 0x28, 0x99, 0xb3, 0x9f, 0x50,
+ 0x86, 0xc5, 0x91, 0x4d, 0xb7, 0x78, 0x1e, 0xfc, 0x59, 0x07, 0xbb, 0x37, 0x3c, 0x3d, 0xf0, 0x73,
+ 0x50, 0x57, 0x5a, 0xea, 0x98, 0x63, 0x67, 0x33, 0x61, 0x8e, 0x32, 0xa5, 0x8e, 0xc8, 0xf9, 0xf0,
+ 0x0c, 0x34, 0xfc, 0x10, 0x45, 0x89, 0x17, 0xc9, 0x77, 0x6a, 0x8e, 0x5b, 0xeb, 0xa7, 0x5e, 0x7d,
+ 0xc2, 0x6b, 0xd3, 0x0b, 0xb7, 0x2e, 0xc0, 0x69, 0x00, 0x3f, 0x02, 0xed, 0x28, 0x89, 0x58, 0x84,
+ 0x62, 0x35, 0x09, 0xab, 0x2d, 0x26, 0x60, 0xaa, 0xaa, 0x1c, 0x02, 0xfc, 0x18, 0x88, 0x91, 0xc8,
+ 0x0d, 0xce, 0x99, 0x3b, 0x82, 0xd9, 0xe1, 0x80, 0x58, 0x4e, 0xc5, 0x75, 0x81, 0xa9, 0x71, 0xa3,
+ 0xc0, 0x7a, 0xb3, 0xed, 0x5d, 0x5e, 0x95, 0xe8, 0x9a, 0x5e, 0x8c, 0x0f, 0xb9, 0xf7, 0xf5, 0x53,
+ 0xaf, 0x75, 0x95, 0x4b, 0x4d, 0x2f, 0xdc, 0x56, 0xa1, 0x3b, 0x0d, 0xe0, 0x15, 0xe8, 0x68, 0x9a,
+ 0x3c, 0x75, 0xd6, 0xae, 0x50, 0xed, 0x3a, 0x32, 0x92, 0x4e, 0x1e, 0x49, 0xe7, 0xfb, 0x3c, 0x92,
+ 0xe3, 0x06, 0x97, 0xbd, 0xff, 0xbb, 0x67, 0xb8, 0x66, 0xa1, 0xc5, 0x51, 0xf8, 0x35, 0xf8, 0x40,
+ 0xa8, 0xf9, 0x24, 0xc3, 0x9e, 0x1c, 0x13, 0xc7, 0x70, 0x50, 0x7d, 0xbf, 0xa0, 0x6f, 0x0c, 0x4d,
+ 0xd7, 0xe6, 0xd4, 0x09, 0xc9, 0xb0, 0x98, 0xdd, 0x95, 0xe0, 0xe9, 0xaf, 0x7b, 0x0b, 0x8e, 0x12,
+ 0xfc, 0xf3, 0x96, 0x98, 0x85, 0x85, 0xbf, 0xde, 0x4b, 0x0b, 0xaa, 0x69, 0x89, 0x7b, 0x33, 0xdc,
+ 0x03, 0x2e, 0x51, 0x01, 0xe0, 0x17, 0x00, 0x14, 0x61, 0xa2, 0x56, 0xfd, 0x55, 0xf1, 0xd3, 0x3a,
+ 0xe0, 0x57, 0x6a, 0x64, 0x9a, 0x48, 0xe3, 0x55, 0x22, 0x6d, 0xde, 0x56, 0xfe, 0x1d, 0xc0, 0x09,
+ 0xb0, 0xf5, 0xa4, 0x94, 0x7a, 0x45, 0x68, 0x9a, 0x62, 0x11, 0x4e, 0xca, 0xd0, 0x94, 0xdd, 0x2a,
+ 0x3e, 0x2f, 0x46, 0x18, 0xbc, 0x65, 0x84, 0xbf, 0x05, 0x1f, 0x56, 0x22, 0xbc, 0xa1, 0x5f, 0xd8,
+ 0x6b, 0x09, 0x7b, 0x7d, 0x2d, 0xd3, 0x55, 0xa1, 0xdc, 0x63, 0xbe, 0xe4, 0x19, 0xa6, 0xab, 0x98,
+ 0x51, 0x2f, 0x44, 0x34, 0xb4, 0xf6, 0xfa, 0xc6, 0x70, 0x4f, 0x2e, 0xb9, 0x2b, 0xeb, 0x97, 0x88,
+ 0x86, 0xf0, 0x18, 0x34, 0x50, 0x9a, 0x4a, 0x8a, 0x29, 0x28, 0x75, 0x94, 0xa6, 0x1c, 0x1a, 0x7f,
+ 0xf7, 0xb0, 0xb6, 0x8d, 0xc7, 0xb5, 0x6d, 0xfc, 0xb3, 0xb6, 0x8d, 0xfb, 0x67, 0xbb, 0xf6, 0xf8,
+ 0x6c, 0xd7, 0xfe, 0x7a, 0xb6, 0x6b, 0x3f, 0x7c, 0xb6, 0x88, 0x58, 0xb8, 0x9a, 0x39, 0x3e, 0x59,
+ 0x8e, 0xf4, 0x0f, 0x51, 0xf9, 0x53, 0x7e, 0x2a, 0x37, 0x3f, 0xb2, 0xb3, 0x77, 0x45, 0xfd, 0xd3,
+ 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x8a, 0x73, 0x8f, 0x5e, 0x7f, 0x07, 0x00, 0x00,
}
func (m *ABCIResponses) Marshal() (dAtA []byte, err error) {
@@ -669,18 +659,6 @@ func (m *State) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
- {
- size, err := m.LastStateID.MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintTypes(dAtA, i, uint64(size))
- }
- i--
- dAtA[i] = 0x6
- i--
- dAtA[i] = 0xb2
if m.NextCoreChainLock != nil {
{
size, err := m.NextCoreChainLock.MarshalToSizedBuffer(dAtA[:i])
@@ -765,12 +743,12 @@ func (m *State) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i--
dAtA[i] = 0x3a
}
- n11, err11 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastBlockTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastBlockTime):])
- if err11 != nil {
- return 0, err11
+ n10, err10 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastBlockTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastBlockTime):])
+ if err10 != nil {
+ return 0, err10
}
- i -= n11
- i = encodeVarintTypes(dAtA, i, uint64(n11))
+ i -= n10
+ i = encodeVarintTypes(dAtA, i, uint64(n10))
i--
dAtA[i] = 0x2a
{
@@ -934,8 +912,6 @@ func (m *State) Size() (n int) {
l = m.NextCoreChainLock.Size()
n += 2 + l + sovTypes(uint64(l))
}
- l = m.LastStateID.Size()
- n += 2 + l + sovTypes(uint64(l))
return n
}
@@ -1853,39 +1829,6 @@ func (m *State) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
- case 102:
- if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field LastStateID", wireType)
- }
- var msglen int
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- return ErrIntOverflowTypes
- }
- if iNdEx >= l {
- return io.ErrUnexpectedEOF
- }
- b := dAtA[iNdEx]
- iNdEx++
- msglen |= int(b&0x7F) << shift
- if b < 0x80 {
- break
- }
- }
- if msglen < 0 {
- return ErrInvalidLengthTypes
- }
- postIndex := iNdEx + msglen
- if postIndex < 0 {
- return ErrInvalidLengthTypes
- }
- if postIndex > l {
- return io.ErrUnexpectedEOF
- }
- if err := m.LastStateID.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
- return err
- }
- iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipTypes(dAtA[iNdEx:])
diff --git a/proto/tendermint/state/types.proto b/proto/tendermint/state/types.proto
index 4bad36f396..4dedabfb59 100644
--- a/proto/tendermint/state/types.proto
+++ b/proto/tendermint/state/types.proto
@@ -48,8 +48,6 @@ message State {
int64 last_block_height = 3;
tendermint.types.BlockID last_block_id = 4
[(gogoproto.nullable) = false, (gogoproto.customname) = "LastBlockID"];
- tendermint.types.StateID last_state_id = 102
- [(gogoproto.nullable) = false, (gogoproto.customname) = "LastStateID"];
google.protobuf.Timestamp last_block_time = 5
[(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
diff --git a/proto/tendermint/types/canonical.go b/proto/tendermint/types/canonical.go
new file mode 100644
index 0000000000..281abb8089
--- /dev/null
+++ b/proto/tendermint/types/canonical.go
@@ -0,0 +1,24 @@
+package types
+
+import (
+ "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/internal/libs/protoio"
+)
+
+func (c CanonicalBlockID) signBytes() ([]byte, error) {
+ marshaled, err := protoio.MarshalDelimited(&c)
+ if err != nil {
+ return nil, err
+ }
+
+ return marshaled, nil
+}
+
+func (c CanonicalBlockID) Checksum() ([]byte, error) {
+ signBytes, err := c.signBytes()
+ if err != nil {
+ return nil, err
+ }
+
+ return crypto.Checksum(signBytes), nil
+}
diff --git a/proto/tendermint/types/canonical.pb.go b/proto/tendermint/types/canonical.pb.go
index 6524930f8f..c4e7bc9d6b 100644
--- a/proto/tendermint/types/canonical.pb.go
+++ b/proto/tendermint/types/canonical.pb.go
@@ -28,6 +28,8 @@ var _ = time.Kitchen
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
+// CanonicalBlockID is a BlockID in a canonical form, for cryptographic purposes.
+// See BlockID for more specific documentation.
type CanonicalBlockID struct {
Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"`
PartSetHeader CanonicalPartSetHeader `protobuf:"bytes,2,opt,name=part_set_header,json=partSetHeader,proto3" json:"part_set_header"`
@@ -43,16 +45,12 @@ func (m *CanonicalBlockID) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *CanonicalBlockID) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- if deterministic {
- return xxx_messageInfo_CanonicalBlockID.Marshal(b, m, deterministic)
- } else {
- b = b[:cap(b)]
- n, err := m.MarshalToSizedBuffer(b)
- if err != nil {
- return nil, err
- }
- return b[:n], nil
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
}
+ return b[:n], nil
}
func (m *CanonicalBlockID) XXX_Merge(src proto.Message) {
xxx_messageInfo_CanonicalBlockID.Merge(m, src)
@@ -95,16 +93,12 @@ func (m *CanonicalPartSetHeader) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *CanonicalPartSetHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- if deterministic {
- return xxx_messageInfo_CanonicalPartSetHeader.Marshal(b, m, deterministic)
- } else {
- b = b[:cap(b)]
- n, err := m.MarshalToSizedBuffer(b)
- if err != nil {
- return nil, err
- }
- return b[:n], nil
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
}
+ return b[:n], nil
}
func (m *CanonicalPartSetHeader) XXX_Merge(src proto.Message) {
xxx_messageInfo_CanonicalPartSetHeader.Merge(m, src)
@@ -152,16 +146,12 @@ func (m *CanonicalProposal) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *CanonicalProposal) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- if deterministic {
- return xxx_messageInfo_CanonicalProposal.Marshal(b, m, deterministic)
- } else {
- b = b[:cap(b)]
- n, err := m.MarshalToSizedBuffer(b)
- if err != nil {
- return nil, err
- }
- return b[:n], nil
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
}
+ return b[:n], nil
}
func (m *CanonicalProposal) XXX_Merge(src proto.Message) {
xxx_messageInfo_CanonicalProposal.Merge(m, src)
@@ -225,11 +215,14 @@ func (m *CanonicalProposal) GetChainID() string {
}
type CanonicalVote struct {
- Type SignedMsgType `protobuf:"varint,1,opt,name=type,proto3,enum=tendermint.types.SignedMsgType" json:"type,omitempty"`
- Height int64 `protobuf:"fixed64,2,opt,name=height,proto3" json:"height,omitempty"`
- Round int64 `protobuf:"fixed64,3,opt,name=round,proto3" json:"round,omitempty"`
- BlockID *CanonicalBlockID `protobuf:"bytes,4,opt,name=block_id,json=blockId,proto3" json:"block_id,omitempty"`
- ChainID string `protobuf:"bytes,6,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"`
+ Type SignedMsgType `protobuf:"varint,1,opt,name=type,proto3,enum=tendermint.types.SignedMsgType" json:"type,omitempty"`
+ Height int64 `protobuf:"fixed64,2,opt,name=height,proto3" json:"height,omitempty"`
+ Round int64 `protobuf:"fixed64,3,opt,name=round,proto3" json:"round,omitempty"`
+ // block_id is a checksum (sha256) of CanonicalBlockID for the block being voted on
+ BlockID []byte `protobuf:"bytes,4,opt,name=block_id,json=blockId,proto3" json:"block_id,omitempty"`
+ // state_id is a checksum (sha256) of StateID message for the block being voted on
+ StateID []byte `protobuf:"bytes,5,opt,name=state_id,json=stateId,proto3" json:"state_id,omitempty"`
+ ChainID string `protobuf:"bytes,99,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"`
}
func (m *CanonicalVote) Reset() { *m = CanonicalVote{} }
@@ -242,16 +235,12 @@ func (m *CanonicalVote) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *CanonicalVote) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- if deterministic {
- return xxx_messageInfo_CanonicalVote.Marshal(b, m, deterministic)
- } else {
- b = b[:cap(b)]
- n, err := m.MarshalToSizedBuffer(b)
- if err != nil {
- return nil, err
- }
- return b[:n], nil
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
}
+ return b[:n], nil
}
func (m *CanonicalVote) XXX_Merge(src proto.Message) {
xxx_messageInfo_CanonicalVote.Merge(m, src)
@@ -286,13 +275,20 @@ func (m *CanonicalVote) GetRound() int64 {
return 0
}
-func (m *CanonicalVote) GetBlockID() *CanonicalBlockID {
+func (m *CanonicalVote) GetBlockID() []byte {
if m != nil {
return m.BlockID
}
return nil
}
+func (m *CanonicalVote) GetStateID() []byte {
+ if m != nil {
+ return m.StateID
+ }
+ return nil
+}
+
func (m *CanonicalVote) GetChainID() string {
if m != nil {
return m.ChainID
@@ -320,16 +316,12 @@ func (m *CanonicalVoteExtension) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *CanonicalVoteExtension) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- if deterministic {
- return xxx_messageInfo_CanonicalVoteExtension.Marshal(b, m, deterministic)
- } else {
- b = b[:cap(b)]
- n, err := m.MarshalToSizedBuffer(b)
- if err != nil {
- return nil, err
- }
- return b[:n], nil
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
}
+ return b[:n], nil
}
func (m *CanonicalVoteExtension) XXX_Merge(src proto.Message) {
xxx_messageInfo_CanonicalVoteExtension.Merge(m, src)
@@ -389,42 +381,43 @@ func init() {
func init() { proto.RegisterFile("tendermint/types/canonical.proto", fileDescriptor_8d1a1a84ff7267ed) }
var fileDescriptor_8d1a1a84ff7267ed = []byte{
- // 545 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x54, 0xcf, 0x6a, 0xd4, 0x40,
- 0x1c, 0xde, 0xd9, 0x6e, 0x77, 0x93, 0x69, 0x57, 0xd7, 0xa1, 0x94, 0xb8, 0x96, 0x24, 0x44, 0x90,
- 0x78, 0x49, 0xa0, 0x3d, 0xf4, 0x9e, 0x2a, 0xb8, 0xa2, 0x58, 0xd3, 0xd2, 0x83, 0x97, 0x65, 0x36,
- 0x19, 0x93, 0x60, 0x36, 0x13, 0x92, 0x59, 0xb0, 0x17, 0x9f, 0xa1, 0x8f, 0xe3, 0x23, 0xf4, 0xd8,
- 0xa3, 0x5e, 0x56, 0xc9, 0x82, 0xcf, 0x21, 0x33, 0xc9, 0x26, 0xb1, 0x2b, 0x05, 0x11, 0x7a, 0x59,
- 0x7e, 0x7f, 0xbe, 0xf9, 0xcd, 0xf7, 0x7d, 0xbf, 0xcd, 0x40, 0x9d, 0x91, 0xc4, 0x27, 0xd9, 0x3c,
- 0x4a, 0x98, 0xcd, 0x2e, 0x53, 0x92, 0xdb, 0x1e, 0x4e, 0x68, 0x12, 0x79, 0x38, 0xb6, 0xd2, 0x8c,
- 0x32, 0x8a, 0x46, 0x0d, 0xc2, 0x12, 0x88, 0xf1, 0x5e, 0x40, 0x03, 0x2a, 0x9a, 0x36, 0x8f, 0x4a,
- 0xdc, 0xf8, 0x60, 0x63, 0x92, 0xf8, 0xad, 0xba, 0x4f, 0x36, 0xba, 0x3e, 0xce, 0xc3, 0xaa, 0xa9,
- 0x05, 0x94, 0x06, 0x31, 0xb1, 0x45, 0x36, 0x5b, 0x7c, 0xb4, 0x59, 0x34, 0x27, 0x39, 0xc3, 0xf3,
- 0xb4, 0x04, 0x18, 0x5f, 0xe0, 0xe8, 0x64, 0x4d, 0xcb, 0x89, 0xa9, 0xf7, 0x69, 0xf2, 0x02, 0x21,
- 0xd8, 0x0b, 0x71, 0x1e, 0x2a, 0x40, 0x07, 0xe6, 0xae, 0x2b, 0x62, 0x74, 0x01, 0x1f, 0xa6, 0x38,
- 0x63, 0xd3, 0x9c, 0xb0, 0x69, 0x48, 0xb0, 0x4f, 0x32, 0xa5, 0xab, 0x03, 0x73, 0xe7, 0xd0, 0xb4,
- 0x6e, 0xab, 0xb0, 0xea, 0x81, 0xa7, 0x38, 0x63, 0x67, 0x84, 0xbd, 0x12, 0x78, 0xa7, 0x77, 0xbd,
- 0xd4, 0x3a, 0xee, 0x30, 0x6d, 0x17, 0x0d, 0x07, 0xee, 0xff, 0x1d, 0x8e, 0xf6, 0xe0, 0x36, 0xa3,
- 0x0c, 0xc7, 0x82, 0xc6, 0xd0, 0x2d, 0x93, 0x9a, 0x5b, 0xb7, 0xe1, 0x66, 0x7c, 0xef, 0xc2, 0x47,
- 0xcd, 0x90, 0x8c, 0xa6, 0x34, 0xc7, 0x31, 0x3a, 0x82, 0x3d, 0x4e, 0x47, 0x1c, 0x7f, 0x70, 0xa8,
- 0x6d, 0xd2, 0x3c, 0x8b, 0x82, 0x84, 0xf8, 0x6f, 0xf3, 0xe0, 0xfc, 0x32, 0x25, 0xae, 0x00, 0xa3,
- 0x7d, 0xd8, 0x0f, 0x49, 0x14, 0x84, 0x4c, 0x5c, 0x30, 0x72, 0xab, 0x8c, 0x93, 0xc9, 0xe8, 0x22,
- 0xf1, 0x95, 0x2d, 0x51, 0x2e, 0x13, 0xf4, 0x1c, 0xca, 0x29, 0x8d, 0xa7, 0x65, 0xa7, 0xa7, 0x03,
- 0x73, 0xcb, 0xd9, 0x2d, 0x96, 0x9a, 0x74, 0xfa, 0xee, 0x8d, 0xcb, 0x6b, 0xae, 0x94, 0xd2, 0x58,
- 0x44, 0xe8, 0x35, 0x94, 0x66, 0xdc, 0xde, 0x69, 0xe4, 0x2b, 0xdb, 0xc2, 0x38, 0xe3, 0x0e, 0xe3,
- 0xaa, 0x4d, 0x38, 0x3b, 0xc5, 0x52, 0x1b, 0x54, 0x89, 0x3b, 0x10, 0x03, 0x26, 0x3e, 0x72, 0xa0,
- 0x5c, 0xaf, 0x51, 0xe9, 0x8b, 0x61, 0x63, 0xab, 0x5c, 0xb4, 0xb5, 0x5e, 0xb4, 0x75, 0xbe, 0x46,
- 0x38, 0x12, 0xf7, 0xfd, 0xea, 0x87, 0x06, 0xdc, 0xe6, 0x18, 0x7a, 0x06, 0x25, 0x2f, 0xc4, 0x51,
- 0xc2, 0xf9, 0x0c, 0x74, 0x60, 0xca, 0xe5, 0x5d, 0x27, 0xbc, 0xc6, 0xef, 0x12, 0xcd, 0x89, 0x6f,
- 0xfc, 0x02, 0x70, 0x58, 0xd3, 0xba, 0xa0, 0x8c, 0xdc, 0x87, 0xaf, 0x6d, 0xb3, 0x7a, 0xff, 0x69,
- 0x56, 0x5b, 0x68, 0xff, 0x0e, 0xa1, 0x5f, 0x41, 0xeb, 0x9f, 0xc8, 0x85, 0xbe, 0xfc, 0xcc, 0x48,
- 0x92, 0x47, 0x34, 0x41, 0x07, 0x50, 0x26, 0xeb, 0xa4, 0xfa, 0x28, 0x9a, 0xc2, 0x3f, 0x4a, 0x7b,
- 0xdc, 0xa2, 0xc3, 0xa5, 0xc9, 0x35, 0x03, 0x74, 0x5c, 0x19, 0xeb, 0x0b, 0x63, 0x9f, 0x6e, 0x2a,
- 0xfe, 0x83, 0x55, 0x63, 0xae, 0xf3, 0xfe, 0xba, 0x50, 0xc1, 0x4d, 0xa1, 0x82, 0x9f, 0x85, 0x0a,
- 0xae, 0x56, 0x6a, 0xe7, 0x66, 0xa5, 0x76, 0xbe, 0xad, 0xd4, 0xce, 0x87, 0xe3, 0x20, 0x62, 0xe1,
- 0x62, 0x66, 0x79, 0x74, 0x6e, 0xb7, 0x9f, 0x89, 0x26, 0x2c, 0x1f, 0x9b, 0xdb, 0x4f, 0xc8, 0xac,
- 0x2f, 0xea, 0x47, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x8b, 0xe1, 0x3f, 0xac, 0xc5, 0x04, 0x00,
- 0x00,
+ // 567 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x54, 0xcd, 0x6e, 0xd3, 0x40,
+ 0x10, 0xce, 0xa6, 0x69, 0xe2, 0x6c, 0x13, 0x08, 0xab, 0xaa, 0x0a, 0xa1, 0xb2, 0x23, 0x23, 0x45,
+ 0xe6, 0x62, 0x4b, 0xed, 0xa1, 0x77, 0x17, 0x24, 0x82, 0x40, 0x54, 0x4e, 0xe9, 0x81, 0x4b, 0xb4,
+ 0xb1, 0x17, 0xdb, 0xc2, 0xf1, 0x5a, 0xf6, 0x46, 0xa2, 0x17, 0x9e, 0xa1, 0x8f, 0xc3, 0x23, 0xf4,
+ 0xd8, 0x63, 0xb9, 0x04, 0xe4, 0xdc, 0x78, 0x0a, 0xb4, 0xeb, 0x5f, 0x1a, 0xa8, 0xc4, 0xa5, 0x97,
+ 0x68, 0x66, 0xbe, 0x6f, 0x67, 0xbf, 0xf9, 0x26, 0x5e, 0x38, 0x66, 0x24, 0x74, 0x48, 0xbc, 0xf4,
+ 0x43, 0x66, 0xb0, 0xcb, 0x88, 0x24, 0x86, 0x8d, 0x43, 0x1a, 0xfa, 0x36, 0x0e, 0xf4, 0x28, 0xa6,
+ 0x8c, 0xa2, 0x41, 0xc5, 0xd0, 0x05, 0x63, 0xb4, 0xef, 0x52, 0x97, 0x0a, 0xd0, 0xe0, 0x51, 0xc6,
+ 0x1b, 0x1d, 0x6e, 0x75, 0x12, 0xbf, 0x39, 0xfa, 0x6c, 0x0b, 0x75, 0x70, 0xe2, 0xe5, 0xa0, 0xe2,
+ 0x52, 0xea, 0x06, 0xc4, 0x10, 0xd9, 0x62, 0xf5, 0xc9, 0x60, 0xfe, 0x92, 0x24, 0x0c, 0x2f, 0xa3,
+ 0x8c, 0xa0, 0x7e, 0x85, 0x83, 0xd3, 0x42, 0x96, 0x19, 0x50, 0xfb, 0xf3, 0xf4, 0x25, 0x42, 0xb0,
+ 0xe5, 0xe1, 0xc4, 0x1b, 0x82, 0x31, 0xd0, 0x7a, 0x96, 0x88, 0xd1, 0x05, 0x7c, 0x1c, 0xe1, 0x98,
+ 0xcd, 0x13, 0xc2, 0xe6, 0x1e, 0xc1, 0x0e, 0x89, 0x87, 0xcd, 0x31, 0xd0, 0xf6, 0x8e, 0x34, 0xfd,
+ 0xee, 0x14, 0x7a, 0xd9, 0xf0, 0x0c, 0xc7, 0x6c, 0x46, 0xd8, 0x6b, 0xc1, 0x37, 0x5b, 0xd7, 0x6b,
+ 0xa5, 0x61, 0xf5, 0xa3, 0x7a, 0x51, 0x35, 0xe1, 0xc1, 0xdf, 0xe9, 0x68, 0x1f, 0xee, 0x32, 0xca,
+ 0x70, 0x20, 0x64, 0xf4, 0xad, 0x2c, 0x29, 0xb5, 0x35, 0x2b, 0x6d, 0xea, 0xf7, 0x26, 0x7c, 0x52,
+ 0x35, 0x89, 0x69, 0x44, 0x13, 0x1c, 0xa0, 0x63, 0xd8, 0xe2, 0x72, 0xc4, 0xf1, 0x47, 0x47, 0xca,
+ 0xb6, 0xcc, 0x99, 0xef, 0x86, 0xc4, 0x79, 0x97, 0xb8, 0xe7, 0x97, 0x11, 0xb1, 0x04, 0x19, 0x1d,
+ 0xc0, 0xb6, 0x47, 0x7c, 0xd7, 0x63, 0xe2, 0x82, 0x81, 0x95, 0x67, 0x5c, 0x4c, 0x4c, 0x57, 0xa1,
+ 0x33, 0xdc, 0x11, 0xe5, 0x2c, 0x41, 0x2f, 0x60, 0x37, 0xa2, 0xc1, 0x3c, 0x43, 0x5a, 0x63, 0xa0,
+ 0xed, 0x98, 0xbd, 0x74, 0xad, 0x48, 0x67, 0xef, 0xdf, 0x5a, 0xbc, 0x66, 0x49, 0x11, 0x0d, 0x44,
+ 0x84, 0xde, 0x40, 0x69, 0xc1, 0xed, 0x9d, 0xfb, 0xce, 0x70, 0x57, 0x18, 0xa7, 0xde, 0x63, 0x5c,
+ 0xbe, 0x09, 0x73, 0x2f, 0x5d, 0x2b, 0x9d, 0x3c, 0xb1, 0x3a, 0xa2, 0xc1, 0xd4, 0x41, 0x26, 0xec,
+ 0x96, 0x6b, 0x1c, 0xb6, 0x45, 0xb3, 0x91, 0x9e, 0x2d, 0x5a, 0x2f, 0x16, 0xad, 0x9f, 0x17, 0x0c,
+ 0x53, 0xe2, 0xbe, 0x5f, 0xfd, 0x50, 0x80, 0x55, 0x1d, 0x43, 0x13, 0x28, 0xd9, 0x1e, 0xf6, 0x43,
+ 0xae, 0xa7, 0x33, 0x06, 0x5a, 0x37, 0xbb, 0xeb, 0x94, 0xd7, 0xf8, 0x5d, 0x02, 0x9c, 0x3a, 0xea,
+ 0x2f, 0x00, 0xfb, 0xa5, 0xac, 0x0b, 0xca, 0xc8, 0x43, 0xf8, 0x3a, 0xa9, 0x99, 0xc5, 0x6d, 0xed,
+ 0xfd, 0xc3, 0x88, 0x09, 0x94, 0x12, 0x86, 0x19, 0x29, 0x4c, 0xcd, 0x79, 0x33, 0x5e, 0xe3, 0x3c,
+ 0x01, 0x66, 0xbc, 0x72, 0x58, 0xfb, 0x9e, 0x61, 0xbf, 0x81, 0xda, 0xbf, 0x91, 0x0f, 0xfb, 0xea,
+ 0x0b, 0x23, 0x61, 0xe2, 0xd3, 0x10, 0x1d, 0xc2, 0x2e, 0x29, 0x92, 0xfc, 0xc3, 0xa8, 0x0a, 0xff,
+ 0x39, 0xde, 0xd3, 0x9a, 0x1c, 0x3e, 0x5e, 0xb7, 0x54, 0x80, 0x4e, 0x72, 0x73, 0x1d, 0x61, 0xee,
+ 0xf3, 0x6d, 0x73, 0xff, 0x50, 0x55, 0x19, 0x6c, 0x7e, 0xb8, 0x4e, 0x65, 0x70, 0x93, 0xca, 0xe0,
+ 0x36, 0x95, 0xc1, 0xcf, 0x54, 0x06, 0x57, 0x1b, 0xb9, 0x71, 0xb3, 0x91, 0x1b, 0xb7, 0x1b, 0xb9,
+ 0xf1, 0xf1, 0xc4, 0xf5, 0x99, 0xb7, 0x5a, 0xe8, 0x36, 0x5d, 0x1a, 0xf5, 0xe7, 0xa2, 0x0a, 0xb3,
+ 0x47, 0xe7, 0xee, 0x53, 0xb2, 0x68, 0x8b, 0xfa, 0xf1, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc8,
+ 0x10, 0x65, 0x49, 0xcd, 0x04, 0x00, 0x00,
}
func (m *CanonicalBlockID) Marshal() (dAtA []byte, err error) {
@@ -599,17 +592,21 @@ func (m *CanonicalVote) MarshalToSizedBuffer(dAtA []byte) (int, error) {
copy(dAtA[i:], m.ChainID)
i = encodeVarintCanonical(dAtA, i, uint64(len(m.ChainID)))
i--
- dAtA[i] = 0x32
+ dAtA[i] = 0x6
+ i--
+ dAtA[i] = 0x9a
}
- if m.BlockID != nil {
- {
- size, err := m.BlockID.MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintCanonical(dAtA, i, uint64(size))
- }
+ if len(m.StateID) > 0 {
+ i -= len(m.StateID)
+ copy(dAtA[i:], m.StateID)
+ i = encodeVarintCanonical(dAtA, i, uint64(len(m.StateID)))
+ i--
+ dAtA[i] = 0x2a
+ }
+ if len(m.BlockID) > 0 {
+ i -= len(m.BlockID)
+ copy(dAtA[i:], m.BlockID)
+ i = encodeVarintCanonical(dAtA, i, uint64(len(m.BlockID)))
i--
dAtA[i] = 0x22
}
@@ -777,14 +774,18 @@ func (m *CanonicalVote) Size() (n int) {
if m.Round != 0 {
n += 9
}
- if m.BlockID != nil {
- l = m.BlockID.Size()
+ l = len(m.BlockID)
+ if l > 0 {
n += 1 + l + sovCanonical(uint64(l))
}
- l = len(m.ChainID)
+ l = len(m.StateID)
if l > 0 {
n += 1 + l + sovCanonical(uint64(l))
}
+ l = len(m.ChainID)
+ if l > 0 {
+ n += 2 + l + sovCanonical(uint64(l))
+ }
return n
}
@@ -1321,7 +1322,7 @@ func (m *CanonicalVote) Unmarshal(dAtA []byte) error {
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field BlockID", wireType)
}
- var msglen int
+ var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowCanonical
@@ -1331,29 +1332,61 @@ func (m *CanonicalVote) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
- msglen |= int(b&0x7F) << shift
+ byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
- if msglen < 0 {
+ if byteLen < 0 {
return ErrInvalidLengthCanonical
}
- postIndex := iNdEx + msglen
+ postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthCanonical
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
+ m.BlockID = append(m.BlockID[:0], dAtA[iNdEx:postIndex]...)
if m.BlockID == nil {
- m.BlockID = &CanonicalBlockID{}
+ m.BlockID = []byte{}
}
- if err := m.BlockID.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
- return err
+ iNdEx = postIndex
+ case 5:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field StateID", wireType)
+ }
+ var byteLen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowCanonical
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ byteLen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if byteLen < 0 {
+ return ErrInvalidLengthCanonical
+ }
+ postIndex := iNdEx + byteLen
+ if postIndex < 0 {
+ return ErrInvalidLengthCanonical
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.StateID = append(m.StateID[:0], dAtA[iNdEx:postIndex]...)
+ if m.StateID == nil {
+ m.StateID = []byte{}
}
iNdEx = postIndex
- case 6:
+ case 99:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ChainID", wireType)
}
diff --git a/proto/tendermint/types/canonical.proto b/proto/tendermint/types/canonical.proto
index 941ad7f243..613d72cea5 100644
--- a/proto/tendermint/types/canonical.proto
+++ b/proto/tendermint/types/canonical.proto
@@ -1,13 +1,16 @@
syntax = "proto3";
package tendermint.types;
-option go_package = "github.com/tendermint/tendermint/proto/tendermint/types";
+option go_package = "github.com/tendermint/tendermint/proto/tendermint/types";
+option (gogoproto.stable_marshaler_all) = true;
import "gogoproto/gogo.proto";
import "tendermint/types/types.proto";
import "tendermint/types/dash.proto";
import "google/protobuf/timestamp.proto";
+// CanonicalBlockID is a BlockID in a canonical form, for cryptographic purposes.
+// See BlockID for more specific documentation.
message CanonicalBlockID {
bytes hash = 1;
CanonicalPartSetHeader part_set_header = 2 [(gogoproto.nullable) = false];
@@ -29,11 +32,14 @@ message CanonicalProposal {
}
message CanonicalVote {
- SignedMsgType type = 1; // type alias for byte
- sfixed64 height = 2; // canonicalization requires fixed size encoding here
- sfixed64 round = 3; // canonicalization requires fixed size encoding here
- CanonicalBlockID block_id = 4 [(gogoproto.customname) = "BlockID"];
- string chain_id = 6 [(gogoproto.customname) = "ChainID"];
+ SignedMsgType type = 1; // type alias for byte
+ sfixed64 height = 2; // canonicalization requires fixed size encoding here
+ sfixed64 round = 3; // canonicalization requires fixed size encoding here
+ // block_id is a checksum (sha256) of CanonicalBlockID for the block being voted on
+ bytes block_id = 4 [(gogoproto.customname) = "BlockID"];
+ // state_id is a checksum (sha256) of StateID message for the block being voted on
+ bytes state_id = 5 [(gogoproto.customname) = "StateID"];
+ string chain_id = 99 [(gogoproto.customname) = "ChainID"];
}
// CanonicalVoteExtension provides us a way to serialize a vote extension from
diff --git a/proto/tendermint/types/types.go b/proto/tendermint/types/types.go
index ea8f74ad61..8670a1b1d7 100644
--- a/proto/tendermint/types/types.go
+++ b/proto/tendermint/types/types.go
@@ -1,5 +1,46 @@
package types
+import (
+ bytes "bytes"
+ "fmt"
+
+ "github.com/gogo/protobuf/types"
+
+ "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/internal/libs/protoio"
+ tmbytes "github.com/tendermint/tendermint/libs/bytes"
+)
+
+// IsZero returns true when the object is a zero-value or nil
+func (m *BlockID) IsZero() bool {
+ return m == nil || (len(m.Hash) == 0 && m.PartSetHeader.IsZero() && len(m.StateID) == 0)
+}
+
+func (m *BlockID) ToCanonicalBlockID() *CanonicalBlockID {
+ if m == nil || m.IsZero() {
+ return nil
+ }
+ cbid := CanonicalBlockID{
+ Hash: m.Hash,
+ PartSetHeader: m.PartSetHeader.ToCanonicalPartSetHeader(),
+ }
+
+ return &cbid
+}
+
+func (m *PartSetHeader) ToCanonicalPartSetHeader() CanonicalPartSetHeader {
+ if m == nil || m.IsZero() {
+ return CanonicalPartSetHeader{}
+ }
+ cps := CanonicalPartSetHeader(*m)
+ return cps
+}
+
+// IsZero returns true when the object is a zero-value or nil
+func (m *PartSetHeader) IsZero() bool {
+ return m == nil || len(m.Hash) == 0
+}
+
// VoteExtensionsToMap creates a map where a key is vote-extension type and value is the extensions grouped by type
func (m *Vote) VoteExtensionsToMap() VoteExtensions {
if m == nil {
@@ -11,3 +52,128 @@ func (m *Vote) VoteExtensionsToMap() VoteExtensions {
}
return res
}
+
+// SignBytes represent data to be signed for the given vote.
+// It's a 64-byte slice containing concatenation of:
+// * Checksum of CanonicalVote
+// * Checksum of StateID
+func (m Vote) SignBytes(chainID string) ([]byte, error) {
+ pbVote, err := m.ToCanonicalVote(chainID)
+ if err != nil {
+ return nil, err
+ }
+ return tmbytes.MarshalFixedSize(pbVote)
+}
+
+// CanonicalizeVote transforms the given Vote to a CanonicalVote, which does
+// not contain ValidatorIndex and ValidatorProTxHash fields.
+func (m Vote) ToCanonicalVote(chainID string) (CanonicalVote, error) {
+ var (
+ blockIDBytes []byte
+ stateIDBytes []byte
+ err error
+ )
+ blockID := m.BlockID.ToCanonicalBlockID()
+ if blockID != nil {
+ if blockIDBytes, err = blockID.Checksum(); err != nil {
+ return CanonicalVote{}, err
+ }
+ stateIDBytes = m.BlockID.StateID
+ } else {
+ blockIDBytes = crypto.Checksum(nil)
+ stateIDBytes = crypto.Checksum(nil)
+ }
+
+ return CanonicalVote{
+ Type: m.Type,
+ Height: m.Height, // encoded as sfixed64
+ Round: int64(m.Round), // encoded as sfixed64
+ BlockID: blockIDBytes,
+ StateID: stateIDBytes,
+ ChainID: chainID,
+ }, nil
+}
+
+func (s StateID) signBytes() ([]byte, error) {
+ marshaled, err := protoio.MarshalDelimited(&s)
+ if err != nil {
+ return nil, err
+ }
+
+ return marshaled, nil
+}
+
+// Hash calculates hash of a StateID to be used in BlockID and other places.
+// It will panic() in case of (very unlikely) error.
+func (s StateID) Hash() (bz []byte) {
+ var err error
+
+ if bz, err = s.signBytes(); err != nil {
+ panic("cannot marshal: " + err.Error())
+ }
+
+ return crypto.Checksum(bz)
+}
+
+var zeroAppHash = make([]byte, crypto.DefaultAppHashSize)
+
+func (s *StateID) IsZero() bool {
+
+ return s == nil ||
+ ((len(s.AppHash) == 0 || bytes.Equal(s.AppHash, zeroAppHash)) &&
+ s.AppVersion == 0 &&
+ s.CoreChainLockedHeight == 0 &&
+ s.Height == 0 &&
+ s.Time.Equal(types.Timestamp{}))
+}
+
+// Copy returns new StateID that is equal to this one
+func (s StateID) Copy() StateID {
+ copied := s
+ copied.AppHash = make([]byte, len(s.AppHash))
+ copy(copied.AppHash, s.AppHash)
+
+ return copied
+}
+
+func (stateID StateID) String() string {
+ return fmt.Sprintf(
+ `v%d:h=%d,cl=%d,ah=%s,t=%s`,
+ stateID.AppVersion,
+ stateID.Height,
+ stateID.CoreChainLockedHeight,
+ tmbytes.HexBytes(stateID.AppHash).ShortString(),
+ stateID.Time.String(),
+ )
+}
+
+// Equal returns true if the StateID matches the given StateID
+func (s StateID) Equal(other StateID) bool {
+ left, err := s.signBytes()
+ if err != nil {
+ panic("cannot marshal stateID: " + err.Error())
+ }
+ right, err := other.signBytes()
+ if err != nil {
+ panic("cannot marshal stateID: " + err.Error())
+ }
+
+ return bytes.Equal(left, right)
+}
+
+// ValidateBasic performs basic validation.
+func (s StateID) ValidateBasic() error {
+ if s.Time.Equal(types.Timestamp{}) {
+ return fmt.Errorf("invalid stateID time %s", s.Time.String())
+ }
+ if len(s.AppHash) != crypto.DefaultAppHashSize {
+ return fmt.Errorf(
+ "invalid apphash %X len, expected: %d, got: %d",
+ s.AppHash,
+ crypto.DefaultAppHashSize,
+ len(s.AppHash),
+ )
+ }
+
+ return nil
+}
diff --git a/proto/tendermint/types/types.pb.go b/proto/tendermint/types/types.pb.go
index e9f8aea98c..e9b10116f6 100644
--- a/proto/tendermint/types/types.pb.go
+++ b/proto/tendermint/types/types.pb.go
@@ -4,11 +4,12 @@
package types
import (
+ encoding_binary "encoding/binary"
fmt "fmt"
_ "github.com/gogo/protobuf/gogoproto"
proto "github.com/gogo/protobuf/proto"
- _ "github.com/gogo/protobuf/types"
github_com_gogo_protobuf_types "github.com/gogo/protobuf/types"
+ types "github.com/gogo/protobuf/types"
crypto "github.com/tendermint/tendermint/proto/tendermint/crypto"
version "github.com/tendermint/tendermint/proto/tendermint/version"
io "io"
@@ -215,6 +216,9 @@ func (m *Part) GetProof() crypto.Proof {
type BlockID struct {
Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"`
PartSetHeader PartSetHeader `protobuf:"bytes,2,opt,name=part_set_header,json=partSetHeader,proto3" json:"part_set_header"`
+ // state_id is a hash of fields required to validate state in light client.
+ // See types/stateid.go for details.
+ StateID []byte `protobuf:"bytes,3,opt,name=state_id,json=stateId,proto3" json:"state_id,omitempty"`
}
func (m *BlockID) Reset() { *m = BlockID{} }
@@ -264,15 +268,30 @@ func (m *BlockID) GetPartSetHeader() PartSetHeader {
return PartSetHeader{}
}
-// StateID
-type StateID struct {
- AppHash []byte `protobuf:"bytes,1,opt,name=app_hash,json=appHash,proto3" json:"app_hash,omitempty"`
- Height int64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"`
+func (m *BlockID) GetStateID() []byte {
+ if m != nil {
+ return m.StateID
+ }
+ return nil
}
-func (m *StateID) Reset() { *m = StateID{} }
-func (m *StateID) String() string { return proto.CompactTextString(m) }
-func (*StateID) ProtoMessage() {}
+// StateID represents essential information required to verify state, document and transactions.
+// It is meant to be used by light clients (like mobile apps) to verify proofs.
+type StateID struct {
+ // AppVersion used when generating the block, equals to Header.Version.App.
+ AppVersion uint64 `protobuf:"fixed64,1,opt,name=app_version,json=appVersion,proto3" json:"app_version,omitempty"`
+ // Height of block containing this state ID.
+ Height uint64 `protobuf:"fixed64,2,opt,name=height,proto3" json:"height,omitempty"`
+ // AppHash used in current block, equal to Header.AppHash. 32 bytes.
+ AppHash []byte `protobuf:"bytes,3,opt,name=app_hash,json=appHash,proto3" json:"app_hash,omitempty"`
+ // CoreChainLockedHeight for the block, equal to Header.CoreChainLockedHeight.
+ CoreChainLockedHeight uint32 `protobuf:"fixed32,4,opt,name=core_chain_locked_height,json=coreChainLockedHeight,proto3" json:"core_chain_locked_height,omitempty"`
+ // Time of the block.
+ Time types.Timestamp `protobuf:"bytes,5,opt,name=time,proto3" json:"time"`
+}
+
+func (m *StateID) Reset() { *m = StateID{} }
+func (*StateID) ProtoMessage() {}
func (*StateID) Descriptor() ([]byte, []int) {
return fileDescriptor_d3a6e55e2345de56, []int{3}
}
@@ -280,16 +299,12 @@ func (m *StateID) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *StateID) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- if deterministic {
- return xxx_messageInfo_StateID.Marshal(b, m, deterministic)
- } else {
- b = b[:cap(b)]
- n, err := m.MarshalToSizedBuffer(b)
- if err != nil {
- return nil, err
- }
- return b[:n], nil
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
}
+ return b[:n], nil
}
func (m *StateID) XXX_Merge(src proto.Message) {
xxx_messageInfo_StateID.Merge(m, src)
@@ -303,6 +318,20 @@ func (m *StateID) XXX_DiscardUnknown() {
var xxx_messageInfo_StateID proto.InternalMessageInfo
+func (m *StateID) GetAppVersion() uint64 {
+ if m != nil {
+ return m.AppVersion
+ }
+ return 0
+}
+
+func (m *StateID) GetHeight() uint64 {
+ if m != nil {
+ return m.Height
+ }
+ return 0
+}
+
func (m *StateID) GetAppHash() []byte {
if m != nil {
return m.AppHash
@@ -310,13 +339,20 @@ func (m *StateID) GetAppHash() []byte {
return nil
}
-func (m *StateID) GetHeight() int64 {
+func (m *StateID) GetCoreChainLockedHeight() uint32 {
if m != nil {
- return m.Height
+ return m.CoreChainLockedHeight
}
return 0
}
+func (m *StateID) GetTime() types.Timestamp {
+ if m != nil {
+ return m.Time
+ }
+ return types.Timestamp{}
+}
+
// Header defines the structure of a Tendermint block header.
type Header struct {
// basic block info
@@ -545,13 +581,11 @@ type Vote struct {
ValidatorProTxHash []byte `protobuf:"bytes,6,opt,name=validator_pro_tx_hash,json=validatorProTxHash,proto3" json:"validator_pro_tx_hash,omitempty"`
ValidatorIndex int32 `protobuf:"varint,7,opt,name=validator_index,json=validatorIndex,proto3" json:"validator_index,omitempty"`
BlockSignature []byte `protobuf:"bytes,8,opt,name=block_signature,json=blockSignature,proto3" json:"block_signature,omitempty"`
- StateSignature []byte `protobuf:"bytes,10,opt,name=state_signature,json=stateSignature,proto3" json:"state_signature,omitempty"`
// Vote extension provided by the application. Only valid for precommit
// messages.
// Vote extension signature by the validator if they participated in
// consensus for the associated block. Only valid for precommit messages.
VoteExtensions []*VoteExtension `protobuf:"bytes,11,rep,name=vote_extensions,json=voteExtensions,proto3" json:"vote_extensions,omitempty"`
- AppHash []byte `protobuf:"bytes,12,opt,name=app_hash,json=appHash,proto3" json:"app_hash,omitempty"`
}
func (m *Vote) Reset() { *m = Vote{} }
@@ -636,13 +670,6 @@ func (m *Vote) GetBlockSignature() []byte {
return nil
}
-func (m *Vote) GetStateSignature() []byte {
- if m != nil {
- return m.StateSignature
- }
- return nil
-}
-
func (m *Vote) GetVoteExtensions() []*VoteExtension {
if m != nil {
return m.VoteExtensions
@@ -650,23 +677,14 @@ func (m *Vote) GetVoteExtensions() []*VoteExtension {
return nil
}
-func (m *Vote) GetAppHash() []byte {
- if m != nil {
- return m.AppHash
- }
- return nil
-}
-
// Commit contains the evidence that a block was committed by a set of
// validators.
type Commit struct {
Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"`
Round int32 `protobuf:"varint,2,opt,name=round,proto3" json:"round,omitempty"`
BlockID BlockID `protobuf:"bytes,3,opt,name=block_id,json=blockId,proto3" json:"block_id"`
- StateID StateID `protobuf:"bytes,100,opt,name=state_id,json=stateId,proto3" json:"state_id"`
QuorumHash []byte `protobuf:"bytes,101,opt,name=quorum_hash,json=quorumHash,proto3" json:"quorum_hash,omitempty"`
ThresholdBlockSignature []byte `protobuf:"bytes,102,opt,name=threshold_block_signature,json=thresholdBlockSignature,proto3" json:"threshold_block_signature,omitempty"`
- ThresholdStateSignature []byte `protobuf:"bytes,103,opt,name=threshold_state_signature,json=thresholdStateSignature,proto3" json:"threshold_state_signature,omitempty"`
ThresholdVoteExtensions []*VoteExtension `protobuf:"bytes,104,rep,name=threshold_vote_extensions,json=thresholdVoteExtensions,proto3" json:"threshold_vote_extensions,omitempty"`
}
@@ -724,13 +742,6 @@ func (m *Commit) GetBlockID() BlockID {
return BlockID{}
}
-func (m *Commit) GetStateID() StateID {
- if m != nil {
- return m.StateID
- }
- return StateID{}
-}
-
func (m *Commit) GetQuorumHash() []byte {
if m != nil {
return m.QuorumHash
@@ -745,13 +756,6 @@ func (m *Commit) GetThresholdBlockSignature() []byte {
return nil
}
-func (m *Commit) GetThresholdStateSignature() []byte {
- if m != nil {
- return m.ThresholdStateSignature
- }
- return nil
-}
-
func (m *Commit) GetThresholdVoteExtensions() []*VoteExtension {
if m != nil {
return m.ThresholdVoteExtensions
@@ -1131,102 +1135,106 @@ func init() {
func init() { proto.RegisterFile("tendermint/types/types.proto", fileDescriptor_d3a6e55e2345de56) }
var fileDescriptor_d3a6e55e2345de56 = []byte{
- // 1515 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0x4f, 0x73, 0x1b, 0xc5,
- 0x12, 0xf7, 0x5a, 0xb2, 0x25, 0xb5, 0x24, 0x5b, 0xde, 0x38, 0x8e, 0xac, 0x24, 0xb2, 0x9e, 0x5e,
- 0xbd, 0x17, 0x93, 0x02, 0x39, 0x24, 0x14, 0x01, 0x0a, 0x0e, 0x96, 0xac, 0xc4, 0xaa, 0xf8, 0x8f,
- 0x58, 0x29, 0xa6, 0x80, 0xc3, 0xd6, 0x5a, 0x3b, 0x96, 0x44, 0xa4, 0x9d, 0x65, 0x77, 0x64, 0xe4,
- 0x5c, 0xb9, 0x50, 0x3e, 0xe5, 0xc4, 0xcd, 0x27, 0x38, 0xf0, 0x19, 0x38, 0xc2, 0x25, 0x27, 0x2a,
- 0x37, 0x38, 0x05, 0xca, 0xf9, 0x04, 0x7c, 0x03, 0x6a, 0x7a, 0x66, 0xb5, 0xbb, 0x92, 0x0c, 0x29,
- 0x1f, 0xb8, 0xa8, 0x76, 0xba, 0x7f, 0x3d, 0xd3, 0xd3, 0xbf, 0xdf, 0xcc, 0xb4, 0xe0, 0x06, 0x23,
- 0x96, 0x49, 0x9c, 0x7e, 0xd7, 0x62, 0x1b, 0xec, 0xc4, 0x26, 0xae, 0xf8, 0x2d, 0xd9, 0x0e, 0x65,
- 0x54, 0xcd, 0xf8, 0xde, 0x12, 0xda, 0x73, 0xcb, 0x6d, 0xda, 0xa6, 0xe8, 0xdc, 0xe0, 0x5f, 0x02,
- 0x97, 0x5b, 0x6b, 0x53, 0xda, 0xee, 0x91, 0x0d, 0x1c, 0x1d, 0x0e, 0x8e, 0x36, 0x58, 0xb7, 0x4f,
- 0x5c, 0x66, 0xf4, 0x6d, 0x09, 0xb8, 0x19, 0x58, 0xa6, 0xe5, 0x9c, 0xd8, 0x8c, 0x72, 0x2c, 0x3d,
- 0x92, 0xee, 0x7c, 0xc0, 0x7d, 0x4c, 0x1c, 0xb7, 0x4b, 0xad, 0x60, 0x1e, 0xb9, 0xc2, 0x44, 0x96,
- 0xc7, 0x46, 0xaf, 0x6b, 0x1a, 0x8c, 0x3a, 0x12, 0x71, 0x7d, 0x02, 0x61, 0x1a, 0x6e, 0x47, 0x38,
- 0x8b, 0xef, 0x43, 0xba, 0x6e, 0x38, 0xac, 0x41, 0xd8, 0x36, 0x31, 0x4c, 0xe2, 0xa8, 0xcb, 0x30,
- 0xc7, 0x28, 0x33, 0x7a, 0x59, 0xa5, 0xa0, 0xac, 0xa7, 0x35, 0x31, 0x50, 0x55, 0x88, 0x76, 0x0c,
- 0xb7, 0x93, 0x9d, 0x2d, 0x28, 0xeb, 0x29, 0x0d, 0xbf, 0x8b, 0x1d, 0x88, 0xf2, 0x50, 0x1e, 0xd1,
- 0xb5, 0x4c, 0x32, 0xf4, 0x22, 0x70, 0xc0, 0xad, 0x87, 0x27, 0x8c, 0xb8, 0x32, 0x44, 0x0c, 0xd4,
- 0x77, 0x60, 0x0e, 0x37, 0x97, 0x8d, 0x14, 0x94, 0xf5, 0xe4, 0xdd, 0x6c, 0x29, 0x50, 0x45, 0xb1,
- 0xf9, 0x52, 0x9d, 0xfb, 0xcb, 0xd1, 0xe7, 0x2f, 0xd7, 0x66, 0x34, 0x01, 0x2e, 0xf6, 0x20, 0x56,
- 0xee, 0xd1, 0xd6, 0x93, 0xda, 0xd6, 0x28, 0x11, 0xc5, 0x4f, 0x44, 0xdd, 0x85, 0x45, 0xdb, 0x70,
- 0x98, 0xee, 0x12, 0xa6, 0x77, 0x70, 0x17, 0xb8, 0x68, 0xf2, 0xee, 0x5a, 0x69, 0x9c, 0xa4, 0x52,
- 0x68, 0xb3, 0x72, 0x95, 0xb4, 0x1d, 0x34, 0x16, 0x3f, 0x84, 0x58, 0x83, 0x19, 0x8c, 0xd4, 0xb6,
- 0xd4, 0x55, 0x88, 0x1b, 0xb6, 0xad, 0x07, 0x56, 0x8c, 0x19, 0xb6, 0xbd, 0xcd, 0x17, 0x5d, 0x81,
- 0xf9, 0x0e, 0xe9, 0xb6, 0x3b, 0x0c, 0xd7, 0x8a, 0x68, 0x72, 0x54, 0xfc, 0x65, 0x0e, 0xe6, 0x65,
- 0x29, 0x3f, 0x82, 0x98, 0x64, 0x0c, 0x83, 0x93, 0x77, 0x6f, 0x06, 0xf3, 0x91, 0xae, 0x52, 0x85,
- 0x5a, 0x2e, 0xb1, 0xdc, 0x81, 0x2b, 0xb3, 0xf1, 0x62, 0xd4, 0xff, 0x43, 0xbc, 0xd5, 0x31, 0xba,
- 0x96, 0xde, 0x35, 0x71, 0x8d, 0x44, 0x39, 0x79, 0xfe, 0x72, 0x2d, 0x56, 0xe1, 0xb6, 0xda, 0x96,
- 0x16, 0x43, 0x67, 0xcd, 0x0c, 0x64, 0x12, 0x09, 0x66, 0xa2, 0xde, 0x87, 0x6c, 0x8b, 0x3a, 0x44,
- 0x17, 0x93, 0xf0, 0xfa, 0x11, 0x53, 0x97, 0x48, 0x13, 0xa9, 0xba, 0xca, 0xfd, 0x38, 0xdf, 0x0e,
- 0x7a, 0xb7, 0x45, 0xe0, 0x7b, 0x10, 0xe5, 0x22, 0xcd, 0x46, 0x31, 0xe9, 0x5c, 0x49, 0x28, 0xb8,
- 0xe4, 0x29, 0xb8, 0xd4, 0xf4, 0x14, 0x5c, 0x8e, 0xf3, 0x8c, 0x9f, 0xfd, 0xbe, 0xa6, 0x68, 0x18,
- 0xa1, 0x56, 0x20, 0xdd, 0x33, 0x5c, 0xa6, 0x1f, 0xf2, 0xd5, 0x78, 0xde, 0x73, 0x38, 0xc5, 0xea,
- 0x24, 0x0f, 0x92, 0x4f, 0xb9, 0xe7, 0x24, 0x8f, 0x12, 0x26, 0x53, 0x5d, 0x87, 0x0c, 0x4e, 0xd2,
- 0xa2, 0xfd, 0x7e, 0x97, 0x89, 0xe2, 0xcf, 0x63, 0xf1, 0x17, 0xb8, 0xbd, 0x82, 0x66, 0xe4, 0xe0,
- 0x3a, 0x24, 0x4c, 0x83, 0x19, 0x02, 0x12, 0x43, 0x48, 0x9c, 0x1b, 0xd0, 0x79, 0x0b, 0x16, 0x47,
- 0x27, 0xc1, 0x15, 0x90, 0xb8, 0x98, 0xc5, 0x37, 0x23, 0xf0, 0x0e, 0x2c, 0x5b, 0x64, 0xc8, 0xf4,
- 0x71, 0x74, 0x02, 0xd1, 0x2a, 0xf7, 0x1d, 0x84, 0x23, 0xfe, 0x07, 0x0b, 0x2d, 0x8f, 0x35, 0x81,
- 0x05, 0xc4, 0xa6, 0x47, 0x56, 0x84, 0x05, 0xd5, 0x93, 0x0c, 0xab, 0xe7, 0x3f, 0x90, 0x72, 0x88,
- 0x3b, 0xe8, 0x31, 0x19, 0x9f, 0x42, 0x77, 0x52, 0xda, 0x10, 0xf2, 0x5f, 0x48, 0x93, 0xe3, 0xae,
- 0x49, 0xac, 0x16, 0x11, 0x98, 0x34, 0x62, 0x52, 0x9e, 0x11, 0x41, 0x1b, 0xb0, 0x6c, 0x3b, 0xd4,
- 0xa6, 0x2e, 0x71, 0x74, 0xdb, 0xa1, 0x3a, 0x1b, 0x0a, 0x2c, 0x41, 0xec, 0x92, 0xe7, 0xab, 0x3b,
- 0xb4, 0x39, 0xf4, 0x36, 0x2b, 0x8d, 0xa6, 0xce, 0x93, 0xf3, 0x04, 0x7a, 0x54, 0x50, 0xd6, 0xa3,
- 0x9a, 0xea, 0xf9, 0x36, 0x6d, 0xfb, 0x40, 0x78, 0x8a, 0x59, 0x88, 0x6e, 0x19, 0xcc, 0x50, 0x33,
- 0x10, 0x61, 0x43, 0x37, 0xab, 0x14, 0x22, 0xeb, 0x29, 0x8d, 0x7f, 0x16, 0x7f, 0x8e, 0x40, 0xf4,
- 0x80, 0x32, 0xa2, 0xde, 0x83, 0x28, 0x67, 0x15, 0x55, 0xbe, 0x30, 0xed, 0xd4, 0x35, 0xba, 0x6d,
- 0x8b, 0x98, 0xbb, 0x6e, 0xbb, 0x79, 0x62, 0x13, 0x0d, 0xc1, 0x17, 0x1d, 0x20, 0x7e, 0x71, 0x38,
- 0x74, 0x60, 0x99, 0xa8, 0xe6, 0x39, 0x4d, 0x0c, 0xd4, 0x2a, 0xc4, 0x47, 0xa2, 0x8a, 0xfe, 0x93,
- 0xa8, 0x16, 0xb9, 0xa8, 0xf8, 0x59, 0x91, 0x06, 0x2d, 0x76, 0x28, 0xb5, 0xf5, 0x36, 0x5c, 0x1d,
- 0xd1, 0x1c, 0x2a, 0x98, 0x10, 0x98, 0x3a, 0x72, 0xfa, 0x15, 0x0b, 0xea, 0x48, 0x17, 0x17, 0x5d,
- 0x0c, 0x33, 0xf3, 0x75, 0x54, 0xc3, 0x1b, 0xef, 0x16, 0x2c, 0x8a, 0x14, 0xdd, 0x6e, 0xdb, 0x32,
- 0xd8, 0xc0, 0x21, 0x9e, 0xe0, 0xd0, 0xdc, 0xf0, 0xac, 0x1c, 0xe8, 0xf2, 0x0b, 0x26, 0x00, 0x14,
- 0xfa, 0x59, 0x40, 0xb3, 0x0f, 0xdc, 0x86, 0xc5, 0x63, 0xca, 0x88, 0x4e, 0x86, 0x8c, 0x58, 0x9c,
- 0x0c, 0x37, 0x9b, 0x2c, 0x44, 0xa6, 0x5f, 0x6c, 0x9c, 0x88, 0xaa, 0x87, 0xd3, 0x16, 0x8e, 0x83,
- 0x43, 0x37, 0x24, 0xc5, 0x54, 0x48, 0x8a, 0xc5, 0x1f, 0x23, 0x30, 0x2f, 0xce, 0x54, 0x80, 0x12,
- 0x65, 0x3a, 0x25, 0xb3, 0x17, 0x51, 0x12, 0xb9, 0x3c, 0x25, 0x55, 0x88, 0x8b, 0x6a, 0x74, 0x4d,
- 0xbc, 0x96, 0xa6, 0x4e, 0x23, 0x2f, 0x64, 0x7f, 0x1a, 0x69, 0xd0, 0x62, 0x18, 0x5b, 0x33, 0xd5,
- 0x35, 0x48, 0x7e, 0x39, 0xa0, 0xce, 0xa0, 0x1f, 0x3c, 0x00, 0x20, 0x4c, 0xc8, 0xe3, 0x07, 0xb0,
- 0xca, 0x3a, 0x0e, 0x71, 0x3b, 0xb4, 0x67, 0xea, 0xe3, 0x44, 0x1d, 0x21, 0xfc, 0xda, 0x08, 0x50,
- 0x0e, 0x33, 0x16, 0x8a, 0x1d, 0xe7, 0xae, 0x3d, 0x16, 0xdb, 0x08, 0x93, 0xf8, 0x79, 0x30, 0x76,
- 0x9c, 0xce, 0xce, 0xeb, 0xd1, 0xe9, 0x4f, 0x1e, 0xb2, 0xbb, 0xc5, 0x9f, 0x22, 0x10, 0xaf, 0xe3,
- 0x99, 0x35, 0x7a, 0xff, 0xc6, 0x31, 0xbc, 0x0e, 0x09, 0x9b, 0xf6, 0x74, 0xe1, 0x89, 0xa2, 0x27,
- 0x6e, 0xd3, 0x9e, 0x36, 0x21, 0x88, 0xb9, 0xcb, 0x0b, 0xa2, 0x0c, 0x89, 0x51, 0x8f, 0x84, 0xe7,
- 0xf2, 0x75, 0xdf, 0x20, 0x3f, 0x4c, 0xbd, 0x01, 0x09, 0x9f, 0x20, 0xf1, 0x32, 0xf8, 0x86, 0xcb,
- 0xbf, 0x8c, 0x4d, 0x58, 0x19, 0x0b, 0xd4, 0x07, 0xb6, 0x69, 0x30, 0x82, 0x7a, 0x9b, 0x4a, 0x64,
- 0x25, 0x38, 0x91, 0x76, 0x25, 0x34, 0xef, 0x63, 0x8c, 0x2d, 0x3a, 0x90, 0x12, 0xcc, 0xc8, 0xbe,
- 0xe1, 0x0e, 0xa7, 0x04, 0xdb, 0x18, 0x65, 0xb2, 0x4b, 0x12, 0xb3, 0x0a, 0xa4, 0x26, 0x71, 0x3c,
- 0x42, 0xbc, 0x96, 0xb2, 0xf1, 0xc9, 0x4e, 0xcb, 0x83, 0xfb, 0x35, 0x89, 0x2b, 0x7e, 0xab, 0x00,
- 0xec, 0xf0, 0x3d, 0x61, 0xf9, 0xf9, 0xc3, 0xed, 0x62, 0x0a, 0x7a, 0x68, 0xe5, 0xfc, 0x45, 0x1a,
- 0x92, 0xeb, 0xa7, 0xdc, 0x60, 0xde, 0x15, 0x48, 0xfb, 0x37, 0xa5, 0x4b, 0xbc, 0x64, 0xa6, 0x4c,
- 0x32, 0x7a, 0x4f, 0x1b, 0x84, 0x69, 0xa9, 0xe3, 0xc0, 0xa8, 0xf8, 0xa7, 0x02, 0x09, 0xcc, 0x69,
- 0x97, 0x30, 0x23, 0x24, 0x29, 0xe5, 0xf2, 0x92, 0xba, 0x09, 0xe0, 0x9d, 0xf8, 0xa7, 0x44, 0x0a,
- 0x3d, 0x21, 0x6f, 0xe5, 0xa7, 0x44, 0x7d, 0x77, 0x54, 0xf0, 0xc8, 0xdf, 0x17, 0x5c, 0xb6, 0x2b,
- 0x5e, 0xd9, 0xaf, 0x41, 0xcc, 0x1a, 0xf4, 0x75, 0xfe, 0x2c, 0x46, 0xc5, 0xe1, 0xb1, 0x06, 0xfd,
- 0xe6, 0xd0, 0x55, 0xdf, 0x82, 0x2b, 0x1d, 0xc3, 0xd5, 0xc7, 0xb4, 0x82, 0xda, 0x8a, 0x6b, 0x99,
- 0x8e, 0xe1, 0x86, 0x54, 0x51, 0xfc, 0x02, 0x62, 0xcd, 0x21, 0xf6, 0xbd, 0xfc, 0x80, 0x39, 0x94,
- 0xb2, 0x60, 0xcb, 0x19, 0xe7, 0x06, 0xbc, 0xc2, 0x54, 0x88, 0xf2, 0xf6, 0xc6, 0xeb, 0xc2, 0xf9,
- 0xb7, 0x5a, 0x7a, 0xcd, 0x8e, 0x5a, 0xf6, 0xd2, 0xb7, 0x7f, 0x55, 0x20, 0x29, 0xeb, 0xf3, 0xa0,
- 0x67, 0xb4, 0xf9, 0x8b, 0x58, 0xde, 0xd9, 0xaf, 0x3c, 0xd2, 0x6b, 0x5b, 0xfa, 0x83, 0x9d, 0xcd,
- 0x87, 0xfa, 0xe3, 0xbd, 0x47, 0x7b, 0xfb, 0x9f, 0xec, 0x65, 0x66, 0x72, 0x2b, 0xa7, 0x67, 0x05,
- 0x35, 0x80, 0x7d, 0x6c, 0x3d, 0xb1, 0xe8, 0x57, 0x16, 0x6f, 0x3a, 0xc2, 0x21, 0x9b, 0xe5, 0x46,
- 0x75, 0xaf, 0x99, 0x51, 0x72, 0x57, 0x4f, 0xcf, 0x0a, 0x4b, 0x81, 0x88, 0xcd, 0x43, 0x97, 0x58,
- 0x6c, 0x32, 0xa0, 0xb2, 0xbf, 0xbb, 0x5b, 0x6b, 0x66, 0x66, 0x27, 0x02, 0xe4, 0x43, 0xf4, 0x06,
- 0x2c, 0x85, 0x03, 0xf6, 0x6a, 0x3b, 0x99, 0x48, 0x4e, 0x3d, 0x3d, 0x2b, 0x2c, 0x04, 0xd0, 0x7b,
- 0xdd, 0x5e, 0x2e, 0xfe, 0xcd, 0x77, 0xf9, 0x99, 0x1f, 0xbe, 0xcf, 0x2b, 0xb7, 0xbf, 0x9e, 0x85,
- 0x74, 0xe8, 0x86, 0x53, 0xdf, 0x84, 0x6b, 0x8d, 0xda, 0xc3, 0xbd, 0xea, 0x96, 0xbe, 0xdb, 0x78,
- 0xa8, 0x37, 0x3f, 0xad, 0x57, 0x03, 0xbb, 0x5b, 0x3c, 0x3d, 0x2b, 0x24, 0xe5, 0x96, 0x2e, 0x42,
- 0xd7, 0xb5, 0xea, 0xc1, 0x7e, 0xb3, 0x9a, 0x51, 0x04, 0xba, 0xee, 0x10, 0x7e, 0x81, 0x23, 0xfa,
- 0x0e, 0xac, 0x4e, 0x41, 0x8f, 0x36, 0xb6, 0x74, 0x7a, 0x56, 0x48, 0xd7, 0x1d, 0x22, 0x8e, 0x1b,
- 0x46, 0xdc, 0x86, 0x95, 0xf1, 0x08, 0x09, 0x8f, 0xe4, 0x16, 0x4e, 0xcf, 0x0a, 0x50, 0xf1, 0xb1,
- 0x25, 0xc8, 0x4e, 0xce, 0xbe, 0x5f, 0xdf, 0x6f, 0x6c, 0xee, 0x64, 0x0a, 0xb9, 0xcc, 0xe9, 0x59,
- 0x21, 0xe5, 0x5d, 0xfb, 0x1c, 0xef, 0x57, 0xa1, 0xfc, 0xf1, 0xf3, 0xf3, 0xbc, 0xf2, 0xe2, 0x3c,
- 0xaf, 0xfc, 0x71, 0x9e, 0x57, 0x9e, 0xbd, 0xca, 0xcf, 0xbc, 0x78, 0x95, 0x9f, 0xf9, 0xed, 0x55,
- 0x7e, 0xe6, 0xb3, 0xfb, 0xed, 0x2e, 0xeb, 0x0c, 0x0e, 0x4b, 0x2d, 0xda, 0xdf, 0x08, 0xfe, 0x25,
- 0xf4, 0x3f, 0xc5, 0x9f, 0xd7, 0xf1, 0xbf, 0x8b, 0x87, 0xf3, 0x68, 0xbf, 0xf7, 0x57, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0xd2, 0x73, 0xe2, 0x03, 0x11, 0x0f, 0x00, 0x00,
+ // 1570 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0x4f, 0x6f, 0xdb, 0x46,
+ 0x16, 0x17, 0x2d, 0xd9, 0x92, 0x9e, 0x24, 0x5b, 0x66, 0x6c, 0x47, 0x56, 0x12, 0x89, 0xab, 0xc5,
+ 0x6e, 0xbc, 0xc1, 0xae, 0x9c, 0x4d, 0x82, 0xcd, 0x6e, 0x80, 0x3d, 0x58, 0xb2, 0x13, 0x0b, 0xf1,
+ 0x1f, 0x2d, 0xa5, 0x78, 0xd1, 0xf6, 0x40, 0xd0, 0xe2, 0x58, 0x64, 0x23, 0x71, 0x58, 0x72, 0xe4,
+ 0xca, 0x39, 0x15, 0xe8, 0x25, 0xf0, 0x29, 0x87, 0x22, 0xc8, 0xc5, 0x40, 0x83, 0xf6, 0xd0, 0x6f,
+ 0xd0, 0x7b, 0x4f, 0x39, 0x15, 0xb9, 0xb5, 0x87, 0xc2, 0x2d, 0x9c, 0x4f, 0xd0, 0x4f, 0xd0, 0x62,
+ 0xfe, 0x50, 0xa4, 0xfe, 0x38, 0x09, 0x7c, 0xe8, 0x45, 0xe0, 0xbc, 0xf7, 0x7b, 0x33, 0x6f, 0x7e,
+ 0xef, 0x37, 0x6f, 0x46, 0x70, 0x95, 0x20, 0xdb, 0x40, 0x6e, 0xd7, 0xb2, 0xc9, 0x2a, 0x39, 0x72,
+ 0x90, 0xc7, 0x7f, 0xcb, 0x8e, 0x8b, 0x09, 0x96, 0xb3, 0x81, 0xb7, 0xcc, 0xec, 0xf9, 0x85, 0x36,
+ 0x6e, 0x63, 0xe6, 0x5c, 0xa5, 0x5f, 0x1c, 0x97, 0x2f, 0xb6, 0x31, 0x6e, 0x77, 0xd0, 0x2a, 0x1b,
+ 0xed, 0xf7, 0x0e, 0x56, 0x89, 0xd5, 0x45, 0x1e, 0xd1, 0xbb, 0x8e, 0x00, 0x5c, 0x0b, 0x2d, 0xd3,
+ 0x72, 0x8f, 0x1c, 0x82, 0x29, 0x16, 0x1f, 0x08, 0x77, 0x21, 0xe4, 0x3e, 0x44, 0xae, 0x67, 0x61,
+ 0x3b, 0x9c, 0x47, 0xfe, 0xca, 0x58, 0x96, 0x86, 0xee, 0x99, 0xc2, 0xa9, 0x8c, 0x39, 0x0f, 0xf5,
+ 0x8e, 0x65, 0xe8, 0x04, 0xbb, 0x1c, 0x51, 0xfa, 0x0f, 0x64, 0xea, 0xba, 0x4b, 0x1a, 0x88, 0x6c,
+ 0x22, 0xdd, 0x40, 0xae, 0xbc, 0x00, 0xd3, 0x04, 0x13, 0xbd, 0x93, 0x93, 0x14, 0x69, 0x25, 0xa3,
+ 0xf2, 0x81, 0x2c, 0x43, 0xcc, 0xd4, 0x3d, 0x33, 0x37, 0xa5, 0x48, 0x2b, 0x69, 0x95, 0x7d, 0x97,
+ 0x4c, 0x88, 0xd1, 0x50, 0x1a, 0x61, 0xd9, 0x06, 0xea, 0xfb, 0x11, 0x6c, 0x40, 0xad, 0xfb, 0x47,
+ 0x04, 0x79, 0x22, 0x84, 0x0f, 0xe4, 0x3b, 0x30, 0xcd, 0x36, 0x97, 0x8b, 0x2a, 0xd2, 0x4a, 0xea,
+ 0x56, 0xae, 0x1c, 0x62, 0x91, 0x6f, 0xbe, 0x5c, 0xa7, 0xfe, 0x4a, 0xec, 0xd5, 0x69, 0x31, 0xa2,
+ 0x72, 0x70, 0xe9, 0x0b, 0x09, 0xe2, 0x95, 0x0e, 0x6e, 0x3d, 0xae, 0xad, 0x0f, 0x32, 0x91, 0x82,
+ 0x4c, 0xe4, 0x6d, 0x98, 0x73, 0x74, 0x97, 0x68, 0x1e, 0x22, 0x9a, 0xc9, 0xb6, 0xc1, 0x56, 0x4d,
+ 0xdd, 0x2a, 0x96, 0x47, 0xab, 0x54, 0x1e, 0xda, 0xad, 0x58, 0x26, 0xe3, 0x0c, 0x51, 0xf0, 0x57,
+ 0x48, 0x78, 0x44, 0x27, 0x48, 0xb3, 0x0c, 0x96, 0x67, 0xba, 0x92, 0x3a, 0x3b, 0x2d, 0xc6, 0x1b,
+ 0xd4, 0x56, 0x5b, 0x57, 0xe3, 0xcc, 0x59, 0x33, 0x4a, 0xcf, 0xa7, 0xc0, 0x37, 0xca, 0xab, 0x90,
+ 0xd2, 0x1d, 0x47, 0x13, 0x15, 0x62, 0xd9, 0xcd, 0x54, 0x66, 0xcf, 0x4e, 0x8b, 0xb0, 0xe6, 0x38,
+ 0x7b, 0xdc, 0xaa, 0x82, 0x3e, 0xf8, 0x96, 0x97, 0x60, 0xc6, 0x44, 0x56, 0xdb, 0x24, 0x2c, 0xd5,
+ 0x19, 0x55, 0x8c, 0xe8, 0xe2, 0x74, 0x22, 0xb6, 0xc7, 0xd0, 0xe2, 0x6b, 0x8e, 0xb3, 0xa9, 0x7b,
+ 0xa6, 0x1a, 0xd7, 0xf9, 0x87, 0xac, 0x42, 0xae, 0x85, 0x5d, 0xa4, 0xb5, 0x4c, 0xdd, 0xb2, 0x35,
+ 0x4a, 0x0e, 0x32, 0x34, 0x31, 0x63, 0x4c, 0x91, 0x56, 0xe2, 0x95, 0xe5, 0xb3, 0xd3, 0xe2, 0x62,
+ 0x15, 0xbb, 0xa8, 0x4a, 0x21, 0x5b, 0x0c, 0xb1, 0xc9, 0x00, 0xea, 0x62, 0x6b, 0x92, 0x59, 0xbe,
+ 0x03, 0x31, 0xaa, 0xce, 0xdc, 0x34, 0x23, 0x2f, 0x5f, 0xe6, 0xd2, 0x2d, 0xfb, 0xd2, 0x2d, 0x37,
+ 0x7d, 0xe9, 0x0a, 0xde, 0x18, 0xfa, 0x5e, 0xf6, 0xc5, 0x97, 0xc5, 0xc8, 0xd3, 0x97, 0x45, 0xe9,
+ 0xc5, 0xcb, 0xa2, 0xf4, 0xd9, 0x4f, 0x4a, 0xa4, 0xf4, 0xfd, 0x34, 0xcc, 0x08, 0x2e, 0xff, 0x0b,
+ 0xf1, 0x30, 0x27, 0xa9, 0x5b, 0xd7, 0xc2, 0x25, 0x11, 0xae, 0x72, 0x15, 0xdb, 0x1e, 0xb2, 0xbd,
+ 0x9e, 0x27, 0x26, 0xf6, 0x63, 0x28, 0x1b, 0x7c, 0x83, 0x96, 0xc1, 0x78, 0x4a, 0x72, 0x36, 0x58,
+ 0xea, 0xb4, 0x14, 0xcc, 0x59, 0x33, 0x42, 0x6c, 0x52, 0xce, 0xa2, 0x03, 0x36, 0xef, 0xbe, 0x85,
+ 0x25, 0x83, 0xc9, 0xf5, 0x1c, 0x2a, 0xfe, 0x2d, 0xa8, 0x88, 0xbd, 0x93, 0x8a, 0x04, 0xcd, 0xf8,
+ 0xd9, 0xcf, 0x45, 0x89, 0xd3, 0x21, 0x57, 0x21, 0xd3, 0xd1, 0x3d, 0xa2, 0xed, 0xd3, 0xd5, 0x68,
+ 0xde, 0x9c, 0xcd, 0xe5, 0x71, 0x29, 0x0a, 0x49, 0x8b, 0x3d, 0xa7, 0x68, 0x14, 0x37, 0x19, 0xf2,
+ 0x0a, 0x64, 0xd9, 0x24, 0x2d, 0xdc, 0xed, 0x5a, 0x84, 0xab, 0x61, 0x86, 0x29, 0x7e, 0x96, 0xda,
+ 0xab, 0xcc, 0xcc, 0x74, 0x70, 0x05, 0x92, 0x86, 0x4e, 0x74, 0x0e, 0x89, 0x33, 0x48, 0x82, 0x1a,
+ 0x98, 0xf3, 0x3a, 0xcc, 0x0d, 0x0e, 0xbc, 0xc7, 0x21, 0x09, 0x3e, 0x4b, 0x60, 0x66, 0xc0, 0x9b,
+ 0xb0, 0x60, 0xa3, 0x3e, 0xd1, 0x46, 0xd1, 0x49, 0x86, 0x96, 0xa9, 0x6f, 0x6f, 0x38, 0xe2, 0x2f,
+ 0x30, 0xdb, 0xf2, 0xab, 0xc6, 0xb1, 0xc0, 0xb0, 0x99, 0x81, 0x95, 0xc1, 0x96, 0x43, 0x72, 0x4e,
+ 0x31, 0xc0, 0x40, 0xc1, 0x7f, 0x82, 0xb4, 0x8b, 0xbc, 0x5e, 0x87, 0x88, 0xf8, 0x34, 0x73, 0xa7,
+ 0x84, 0x8d, 0x41, 0xfe, 0x0c, 0x19, 0x74, 0x68, 0x19, 0xc8, 0x6e, 0x21, 0x8e, 0xc9, 0x30, 0x4c,
+ 0xda, 0x37, 0x32, 0xd0, 0x2a, 0x2c, 0x38, 0x2e, 0x76, 0xb0, 0x87, 0x5c, 0xcd, 0x71, 0xb1, 0x46,
+ 0xfa, 0x1c, 0x8b, 0x18, 0x76, 0xde, 0xf7, 0xd5, 0x5d, 0xdc, 0xec, 0xfb, 0x9b, 0x15, 0x46, 0x43,
+ 0x0b, 0x1f, 0xda, 0x03, 0x45, 0x5a, 0x89, 0xa9, 0xb2, 0xef, 0x0b, 0x0e, 0x6e, 0x29, 0x07, 0xb1,
+ 0x75, 0x9d, 0xe8, 0x72, 0x16, 0xa2, 0xa4, 0xef, 0xe5, 0x24, 0x25, 0xba, 0x92, 0x56, 0xe9, 0x67,
+ 0xe9, 0xb7, 0x29, 0x88, 0xed, 0x61, 0x82, 0xe4, 0xdb, 0x10, 0xa3, 0x55, 0x65, 0x2a, 0x9f, 0x9d,
+ 0xd4, 0x78, 0x1a, 0x56, 0xdb, 0x46, 0xc6, 0xb6, 0xd7, 0x6e, 0x1e, 0x39, 0x48, 0x65, 0xe0, 0x91,
+ 0x26, 0x10, 0xc8, 0x76, 0x01, 0xa6, 0x5d, 0xdc, 0xb3, 0x79, 0xfb, 0x99, 0x56, 0xf9, 0x40, 0xde,
+ 0x80, 0xc4, 0x40, 0x54, 0xb1, 0x77, 0x89, 0x6a, 0x8e, 0x8a, 0x8a, 0x9e, 0x15, 0x61, 0x50, 0xe3,
+ 0xfb, 0x42, 0x5b, 0xff, 0x84, 0xc5, 0x41, 0x99, 0x87, 0x08, 0xe3, 0x02, 0x93, 0x07, 0xce, 0x80,
+ 0xb1, 0xb0, 0x8e, 0x34, 0xde, 0xec, 0xe3, 0x2c, 0xb3, 0x40, 0x47, 0x35, 0xd6, 0xf5, 0xaf, 0xc3,
+ 0x1c, 0x4f, 0xd1, 0xb3, 0xda, 0xb6, 0x4e, 0x7a, 0x2e, 0xf2, 0x05, 0xc7, 0xcc, 0x0d, 0xdf, 0x2a,
+ 0x6f, 0xc2, 0xdc, 0x21, 0x26, 0x48, 0x43, 0x7d, 0x82, 0x6c, 0xca, 0xb1, 0x97, 0x4b, 0x29, 0xd1,
+ 0xc9, 0x2d, 0x9b, 0xf2, 0xbb, 0xe1, 0xe3, 0xd4, 0xd9, 0xc3, 0xf0, 0xd0, 0x2b, 0x7d, 0x3b, 0x05,
+ 0x33, 0xfc, 0x3c, 0x84, 0xe8, 0x94, 0x26, 0xd3, 0x39, 0x75, 0x1e, 0x9d, 0xd1, 0x8b, 0xd3, 0x59,
+ 0x84, 0xd4, 0x27, 0x3d, 0xec, 0xf6, 0xba, 0x61, 0xd5, 0x01, 0x37, 0x31, 0xf2, 0xee, 0xc1, 0x32,
+ 0x31, 0x5d, 0xe4, 0x99, 0xb8, 0x63, 0x68, 0xa3, 0xec, 0x1c, 0x30, 0xf8, 0xe5, 0x01, 0xa0, 0x32,
+ 0x4c, 0xd3, 0x47, 0xe1, 0xd8, 0x51, 0xc2, 0xcc, 0xf7, 0x23, 0x2c, 0x98, 0x7c, 0x6f, 0x98, 0xb9,
+ 0xef, 0xa2, 0x90, 0xa8, 0x33, 0xb1, 0xeb, 0x9d, 0x3f, 0x42, 0xbf, 0x57, 0x20, 0xe9, 0xe0, 0x8e,
+ 0xc6, 0x3d, 0x31, 0xe6, 0x49, 0x38, 0xb8, 0xa3, 0x8e, 0x55, 0x63, 0xfa, 0xe2, 0xd5, 0xa8, 0x40,
+ 0x72, 0xf0, 0xc0, 0x62, 0x82, 0x7e, 0xdf, 0xe6, 0x1d, 0x84, 0xc9, 0x57, 0x21, 0x19, 0x14, 0x88,
+ 0xb7, 0xd4, 0xc0, 0x70, 0xf1, 0x2b, 0xa5, 0x09, 0x4b, 0x23, 0x81, 0x5a, 0xcf, 0x31, 0x74, 0x82,
+ 0x98, 0x66, 0x26, 0x16, 0x72, 0xe8, 0xf6, 0x56, 0x2f, 0x0d, 0xcd, 0xfb, 0x88, 0xc5, 0x96, 0x5c,
+ 0x48, 0xf3, 0xca, 0x88, 0x0b, 0xf7, 0x26, 0x2d, 0x09, 0x7b, 0x02, 0x49, 0xe3, 0x4f, 0x2c, 0x3e,
+ 0x2b, 0x47, 0xaa, 0x02, 0x47, 0x23, 0xf8, 0x35, 0x23, 0x1e, 0x4d, 0xb9, 0x49, 0x79, 0x50, 0xbf,
+ 0x2a, 0x70, 0xa5, 0xe7, 0x12, 0xc0, 0x16, 0xdd, 0x13, 0xa3, 0x9f, 0xde, 0x78, 0x1e, 0x4b, 0x41,
+ 0x1b, 0x5a, 0xb9, 0x70, 0x9e, 0x86, 0xc4, 0xfa, 0x69, 0x2f, 0x9c, 0x77, 0x15, 0x32, 0x41, 0x8b,
+ 0xf1, 0x90, 0x9f, 0xcc, 0x84, 0x49, 0x06, 0x17, 0x51, 0x03, 0x11, 0x35, 0x7d, 0x18, 0x1a, 0x95,
+ 0x7e, 0x95, 0x20, 0xc9, 0x72, 0xda, 0x46, 0x44, 0x1f, 0x92, 0x94, 0x74, 0x71, 0x49, 0x5d, 0x03,
+ 0xf0, 0x4f, 0xed, 0x13, 0x24, 0x84, 0x9e, 0x14, 0xed, 0xec, 0x09, 0x92, 0xff, 0x35, 0x20, 0x3c,
+ 0xfa, 0x76, 0xc2, 0xc5, 0x3d, 0xef, 0xd3, 0x7e, 0x19, 0xe2, 0x76, 0xaf, 0xab, 0xd1, 0xfb, 0x24,
+ 0xc6, 0x0f, 0x8f, 0xdd, 0xeb, 0x36, 0xfb, 0x9e, 0xfc, 0x0f, 0xb8, 0x64, 0xea, 0x9e, 0x36, 0xa2,
+ 0x15, 0xa6, 0xad, 0x84, 0x9a, 0x35, 0x75, 0x6f, 0x48, 0x15, 0xa5, 0x8f, 0x21, 0xde, 0xec, 0xb3,
+ 0x47, 0x33, 0x3d, 0x60, 0x2e, 0xc6, 0xe2, 0xb9, 0xc0, 0x1f, 0xc8, 0x09, 0x6a, 0x60, 0x6d, 0x48,
+ 0x86, 0x18, 0x7d, 0x17, 0xf8, 0x4f, 0x78, 0xfa, 0x2d, 0x97, 0xdf, 0xf3, 0x39, 0x2e, 0x1e, 0xe2,
+ 0x37, 0x7e, 0x90, 0x20, 0x25, 0xf8, 0xb9, 0xdf, 0xd1, 0xdb, 0xf4, 0x2a, 0xa9, 0x6c, 0xed, 0x56,
+ 0x1f, 0x6a, 0xb5, 0x75, 0xed, 0xfe, 0xd6, 0xda, 0x03, 0xed, 0xd1, 0xce, 0xc3, 0x9d, 0xdd, 0xff,
+ 0xef, 0x64, 0x23, 0xf9, 0xa5, 0xe3, 0x13, 0x45, 0x0e, 0x61, 0x1f, 0xd9, 0x8f, 0x6d, 0xfc, 0xa9,
+ 0x4d, 0x6f, 0xeb, 0xe1, 0x90, 0xb5, 0x4a, 0x63, 0x63, 0xa7, 0x99, 0x95, 0xf2, 0x8b, 0xc7, 0x27,
+ 0xca, 0x7c, 0x28, 0x62, 0x6d, 0xdf, 0x43, 0x36, 0x19, 0x0f, 0xa8, 0xee, 0x6e, 0x6f, 0xd7, 0x9a,
+ 0xd9, 0xa9, 0xb1, 0x00, 0x71, 0x0b, 0xfc, 0x0d, 0xe6, 0x87, 0x03, 0x76, 0x6a, 0x5b, 0xd9, 0x68,
+ 0x5e, 0x3e, 0x3e, 0x51, 0x66, 0x43, 0xe8, 0x1d, 0xab, 0x93, 0x4f, 0x3c, 0xfd, 0xaa, 0x10, 0xf9,
+ 0xe6, 0xeb, 0x82, 0x74, 0xe3, 0xf3, 0x29, 0xc8, 0x0c, 0x75, 0x38, 0xf9, 0xef, 0x70, 0xb9, 0x51,
+ 0x7b, 0xb0, 0xb3, 0xb1, 0xae, 0x6d, 0x37, 0x1e, 0x68, 0xcd, 0x0f, 0xea, 0x1b, 0xa1, 0xdd, 0xcd,
+ 0x1d, 0x9f, 0x28, 0x29, 0xb1, 0xa5, 0xf3, 0xd0, 0x75, 0x75, 0x63, 0x6f, 0xb7, 0xb9, 0x91, 0x95,
+ 0x38, 0xba, 0xee, 0x22, 0xda, 0xc0, 0x19, 0xfa, 0x26, 0x2c, 0x4f, 0x40, 0x0f, 0x36, 0x36, 0x7f,
+ 0x7c, 0xa2, 0x64, 0xea, 0x2e, 0xe2, 0xc7, 0x8d, 0x45, 0xdc, 0x80, 0xa5, 0xd1, 0x08, 0x01, 0x8f,
+ 0xe6, 0x67, 0x8f, 0x4f, 0x14, 0xa8, 0x06, 0xd8, 0x32, 0xe4, 0xc6, 0x67, 0xdf, 0xad, 0xef, 0x36,
+ 0xd6, 0xb6, 0xb2, 0x4a, 0x3e, 0x7b, 0x7c, 0xa2, 0xa4, 0xfd, 0xb6, 0x4f, 0xf1, 0x01, 0x0b, 0x95,
+ 0xff, 0xbd, 0x3a, 0x2b, 0x48, 0xaf, 0xcf, 0x0a, 0xd2, 0x2f, 0x67, 0x05, 0xe9, 0xd9, 0x9b, 0x42,
+ 0xe4, 0xf5, 0x9b, 0x42, 0xe4, 0xc7, 0x37, 0x85, 0xc8, 0x87, 0x77, 0xdb, 0x16, 0x31, 0x7b, 0xfb,
+ 0xe5, 0x16, 0xee, 0xae, 0x86, 0xff, 0x54, 0x06, 0x9f, 0xfc, 0x9f, 0xef, 0xe8, 0x1f, 0xce, 0xfd,
+ 0x19, 0x66, 0xbf, 0xfd, 0x7b, 0x00, 0x00, 0x00, 0xff, 0xff, 0x2c, 0x9a, 0x8a, 0x54, 0x4e, 0x0f,
+ 0x00, 0x00,
}
func (m *PartSetHeader) Marshal() (dAtA []byte, err error) {
@@ -1329,6 +1337,13 @@ func (m *BlockID) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
+ if len(m.StateID) > 0 {
+ i -= len(m.StateID)
+ copy(dAtA[i:], m.StateID)
+ i = encodeVarintTypes(dAtA, i, uint64(len(m.StateID)))
+ i--
+ dAtA[i] = 0x1a
+ }
{
size, err := m.PartSetHeader.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
@@ -1369,17 +1384,40 @@ func (m *StateID) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
- if m.Height != 0 {
- i = encodeVarintTypes(dAtA, i, uint64(m.Height))
+ {
+ size, err := m.Time.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintTypes(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x2a
+ if m.CoreChainLockedHeight != 0 {
+ i -= 4
+ encoding_binary.LittleEndian.PutUint32(dAtA[i:], uint32(m.CoreChainLockedHeight))
i--
- dAtA[i] = 0x10
+ dAtA[i] = 0x25
}
if len(m.AppHash) > 0 {
i -= len(m.AppHash)
copy(dAtA[i:], m.AppHash)
i = encodeVarintTypes(dAtA, i, uint64(len(m.AppHash)))
i--
- dAtA[i] = 0xa
+ dAtA[i] = 0x1a
+ }
+ if m.Height != 0 {
+ i -= 8
+ encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(m.Height))
+ i--
+ dAtA[i] = 0x11
+ }
+ if m.AppVersion != 0 {
+ i -= 8
+ encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(m.AppVersion))
+ i--
+ dAtA[i] = 0x9
}
return len(dAtA) - i, nil
}
@@ -1493,12 +1531,12 @@ func (m *Header) MarshalToSizedBuffer(dAtA []byte) (int, error) {
}
i--
dAtA[i] = 0x2a
- n4, err4 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):])
- if err4 != nil {
- return 0, err4
+ n5, err5 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):])
+ if err5 != nil {
+ return 0, err5
}
- i -= n4
- i = encodeVarintTypes(dAtA, i, uint64(n4))
+ i -= n5
+ i = encodeVarintTypes(dAtA, i, uint64(n5))
i--
dAtA[i] = 0x22
if m.Height != 0 {
@@ -1578,13 +1616,6 @@ func (m *Vote) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
- if len(m.AppHash) > 0 {
- i -= len(m.AppHash)
- copy(dAtA[i:], m.AppHash)
- i = encodeVarintTypes(dAtA, i, uint64(len(m.AppHash)))
- i--
- dAtA[i] = 0x62
- }
if len(m.VoteExtensions) > 0 {
for iNdEx := len(m.VoteExtensions) - 1; iNdEx >= 0; iNdEx-- {
{
@@ -1599,13 +1630,6 @@ func (m *Vote) MarshalToSizedBuffer(dAtA []byte) (int, error) {
dAtA[i] = 0x5a
}
}
- if len(m.StateSignature) > 0 {
- i -= len(m.StateSignature)
- copy(dAtA[i:], m.StateSignature)
- i = encodeVarintTypes(dAtA, i, uint64(len(m.StateSignature)))
- i--
- dAtA[i] = 0x52
- }
if len(m.BlockSignature) > 0 {
i -= len(m.BlockSignature)
copy(dAtA[i:], m.BlockSignature)
@@ -1689,15 +1713,6 @@ func (m *Commit) MarshalToSizedBuffer(dAtA []byte) (int, error) {
dAtA[i] = 0xc2
}
}
- if len(m.ThresholdStateSignature) > 0 {
- i -= len(m.ThresholdStateSignature)
- copy(dAtA[i:], m.ThresholdStateSignature)
- i = encodeVarintTypes(dAtA, i, uint64(len(m.ThresholdStateSignature)))
- i--
- dAtA[i] = 0x6
- i--
- dAtA[i] = 0xba
- }
if len(m.ThresholdBlockSignature) > 0 {
i -= len(m.ThresholdBlockSignature)
copy(dAtA[i:], m.ThresholdBlockSignature)
@@ -1716,18 +1731,6 @@ func (m *Commit) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i--
dAtA[i] = 0xaa
}
- {
- size, err := m.StateID.MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintTypes(dAtA, i, uint64(size))
- }
- i--
- dAtA[i] = 0x6
- i--
- dAtA[i] = 0xa2
{
size, err := m.BlockID.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
@@ -2105,6 +2108,10 @@ func (m *BlockID) Size() (n int) {
}
l = m.PartSetHeader.Size()
n += 1 + l + sovTypes(uint64(l))
+ l = len(m.StateID)
+ if l > 0 {
+ n += 1 + l + sovTypes(uint64(l))
+ }
return n
}
@@ -2114,13 +2121,21 @@ func (m *StateID) Size() (n int) {
}
var l int
_ = l
+ if m.AppVersion != 0 {
+ n += 9
+ }
+ if m.Height != 0 {
+ n += 9
+ }
l = len(m.AppHash)
if l > 0 {
n += 1 + l + sovTypes(uint64(l))
}
- if m.Height != 0 {
- n += 1 + sovTypes(uint64(m.Height))
+ if m.CoreChainLockedHeight != 0 {
+ n += 5
}
+ l = m.Time.Size()
+ n += 1 + l + sovTypes(uint64(l))
return n
}
@@ -2231,20 +2246,12 @@ func (m *Vote) Size() (n int) {
if l > 0 {
n += 1 + l + sovTypes(uint64(l))
}
- l = len(m.StateSignature)
- if l > 0 {
- n += 1 + l + sovTypes(uint64(l))
- }
if len(m.VoteExtensions) > 0 {
for _, e := range m.VoteExtensions {
l = e.Size()
n += 1 + l + sovTypes(uint64(l))
}
}
- l = len(m.AppHash)
- if l > 0 {
- n += 1 + l + sovTypes(uint64(l))
- }
return n
}
@@ -2262,8 +2269,6 @@ func (m *Commit) Size() (n int) {
}
l = m.BlockID.Size()
n += 1 + l + sovTypes(uint64(l))
- l = m.StateID.Size()
- n += 2 + l + sovTypes(uint64(l))
l = len(m.QuorumHash)
if l > 0 {
n += 2 + l + sovTypes(uint64(l))
@@ -2272,10 +2277,6 @@ func (m *Commit) Size() (n int) {
if l > 0 {
n += 2 + l + sovTypes(uint64(l))
}
- l = len(m.ThresholdStateSignature)
- if l > 0 {
- n += 2 + l + sovTypes(uint64(l))
- }
if len(m.ThresholdVoteExtensions) > 0 {
for _, e := range m.ThresholdVoteExtensions {
l = e.Size()
@@ -2739,6 +2740,40 @@ func (m *BlockID) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field StateID", wireType)
+ }
+ var byteLen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowTypes
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ byteLen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if byteLen < 0 {
+ return ErrInvalidLengthTypes
+ }
+ postIndex := iNdEx + byteLen
+ if postIndex < 0 {
+ return ErrInvalidLengthTypes
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.StateID = append(m.StateID[:0], dAtA[iNdEx:postIndex]...)
+ if m.StateID == nil {
+ m.StateID = []byte{}
+ }
+ iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipTypes(dAtA[iNdEx:])
@@ -2790,6 +2825,26 @@ func (m *StateID) Unmarshal(dAtA []byte) error {
}
switch fieldNum {
case 1:
+ if wireType != 1 {
+ return fmt.Errorf("proto: wrong wireType = %d for field AppVersion", wireType)
+ }
+ m.AppVersion = 0
+ if (iNdEx + 8) > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.AppVersion = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:]))
+ iNdEx += 8
+ case 2:
+ if wireType != 1 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType)
+ }
+ m.Height = 0
+ if (iNdEx + 8) > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Height = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:]))
+ iNdEx += 8
+ case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field AppHash", wireType)
}
@@ -2823,11 +2878,21 @@ func (m *StateID) Unmarshal(dAtA []byte) error {
m.AppHash = []byte{}
}
iNdEx = postIndex
- case 2:
- if wireType != 0 {
- return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType)
+ case 4:
+ if wireType != 5 {
+ return fmt.Errorf("proto: wrong wireType = %d for field CoreChainLockedHeight", wireType)
}
- m.Height = 0
+ m.CoreChainLockedHeight = 0
+ if (iNdEx + 4) > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.CoreChainLockedHeight = uint32(encoding_binary.LittleEndian.Uint32(dAtA[iNdEx:]))
+ iNdEx += 4
+ case 5:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Time", wireType)
+ }
+ var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
@@ -2837,11 +2902,25 @@ func (m *StateID) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
- m.Height |= int64(b&0x7F) << shift
+ msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
+ if msglen < 0 {
+ return ErrInvalidLengthTypes
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthTypes
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if err := m.Time.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipTypes(dAtA[iNdEx:])
@@ -3695,40 +3774,6 @@ func (m *Vote) Unmarshal(dAtA []byte) error {
m.BlockSignature = []byte{}
}
iNdEx = postIndex
- case 10:
- if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field StateSignature", wireType)
- }
- var byteLen int
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- return ErrIntOverflowTypes
- }
- if iNdEx >= l {
- return io.ErrUnexpectedEOF
- }
- b := dAtA[iNdEx]
- iNdEx++
- byteLen |= int(b&0x7F) << shift
- if b < 0x80 {
- break
- }
- }
- if byteLen < 0 {
- return ErrInvalidLengthTypes
- }
- postIndex := iNdEx + byteLen
- if postIndex < 0 {
- return ErrInvalidLengthTypes
- }
- if postIndex > l {
- return io.ErrUnexpectedEOF
- }
- m.StateSignature = append(m.StateSignature[:0], dAtA[iNdEx:postIndex]...)
- if m.StateSignature == nil {
- m.StateSignature = []byte{}
- }
- iNdEx = postIndex
case 11:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field VoteExtensions", wireType)
@@ -3763,40 +3808,6 @@ func (m *Vote) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
- case 12:
- if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field AppHash", wireType)
- }
- var byteLen int
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- return ErrIntOverflowTypes
- }
- if iNdEx >= l {
- return io.ErrUnexpectedEOF
- }
- b := dAtA[iNdEx]
- iNdEx++
- byteLen |= int(b&0x7F) << shift
- if b < 0x80 {
- break
- }
- }
- if byteLen < 0 {
- return ErrInvalidLengthTypes
- }
- postIndex := iNdEx + byteLen
- if postIndex < 0 {
- return ErrInvalidLengthTypes
- }
- if postIndex > l {
- return io.ErrUnexpectedEOF
- }
- m.AppHash = append(m.AppHash[:0], dAtA[iNdEx:postIndex]...)
- if m.AppHash == nil {
- m.AppHash = []byte{}
- }
- iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipTypes(dAtA[iNdEx:])
@@ -3918,39 +3929,6 @@ func (m *Commit) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
- case 100:
- if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field StateID", wireType)
- }
- var msglen int
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- return ErrIntOverflowTypes
- }
- if iNdEx >= l {
- return io.ErrUnexpectedEOF
- }
- b := dAtA[iNdEx]
- iNdEx++
- msglen |= int(b&0x7F) << shift
- if b < 0x80 {
- break
- }
- }
- if msglen < 0 {
- return ErrInvalidLengthTypes
- }
- postIndex := iNdEx + msglen
- if postIndex < 0 {
- return ErrInvalidLengthTypes
- }
- if postIndex > l {
- return io.ErrUnexpectedEOF
- }
- if err := m.StateID.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
- return err
- }
- iNdEx = postIndex
case 101:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field QuorumHash", wireType)
@@ -4019,40 +3997,6 @@ func (m *Commit) Unmarshal(dAtA []byte) error {
m.ThresholdBlockSignature = []byte{}
}
iNdEx = postIndex
- case 103:
- if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field ThresholdStateSignature", wireType)
- }
- var byteLen int
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- return ErrIntOverflowTypes
- }
- if iNdEx >= l {
- return io.ErrUnexpectedEOF
- }
- b := dAtA[iNdEx]
- iNdEx++
- byteLen |= int(b&0x7F) << shift
- if b < 0x80 {
- break
- }
- }
- if byteLen < 0 {
- return ErrInvalidLengthTypes
- }
- postIndex := iNdEx + byteLen
- if postIndex < 0 {
- return ErrInvalidLengthTypes
- }
- if postIndex > l {
- return io.ErrUnexpectedEOF
- }
- m.ThresholdStateSignature = append(m.ThresholdStateSignature[:0], dAtA[iNdEx:postIndex]...)
- if m.ThresholdStateSignature == nil {
- m.ThresholdStateSignature = []byte{}
- }
- iNdEx = postIndex
case 104:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ThresholdVoteExtensions", wireType)
diff --git a/proto/tendermint/types/types.proto b/proto/tendermint/types/types.proto
index 342a6fcc7b..06996615bd 100644
--- a/proto/tendermint/types/types.proto
+++ b/proto/tendermint/types/types.proto
@@ -7,8 +7,8 @@ import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
import "tendermint/crypto/proof.proto";
import "tendermint/version/types.proto";
-import "tendermint/types/validator.proto";
import "tendermint/types/dash.proto";
+import "tendermint/types/validator.proto";
// BlockIdFlag indicates which BlockID the signature is for
enum BlockIDFlag {
@@ -60,12 +60,29 @@ message Part {
message BlockID {
bytes hash = 1;
PartSetHeader part_set_header = 2 [(gogoproto.nullable) = false];
+ // state_id is a hash of fields required to validate state in light client.
+ // See types/stateid.go for details.
+ bytes state_id = 3 [(gogoproto.customname) = "StateID"];
}
-// StateID
+// StateID represents essential information required to verify state, document and transactions.
+// It is meant to be used by light clients (like mobile apps) to verify proofs.
message StateID {
- bytes app_hash = 1;
- int64 height = 2;
+ option (gogoproto.stable_marshaler) = true;
+ option (gogoproto.marshaler) = true;
+ option (gogoproto.stringer) = false;
+ option (gogoproto.goproto_stringer) = false;
+
+ // AppVersion used when generating the block, equals to Header.Version.App.
+ fixed64 app_version = 1 [(gogoproto.customname) = "AppVersion"];
+ // Height of block containing this state ID.
+ fixed64 height = 2;
+ // AppHash used in current block, equal to Header.AppHash. 32 bytes.
+ bytes app_hash = 3 [(gogoproto.customname) = "AppHash"];
+ // CoreChainLockedHeight for the block, equal to Header.CoreChainLockedHeight.
+ fixed32 core_chain_locked_height = 4 [(gogoproto.customname) = "CoreChainLockedHeight"];
+ // Time of the block.
+ google.protobuf.Timestamp time = 5 [(gogoproto.nullable) = false];
}
// --------------------------------
@@ -124,15 +141,12 @@ message Vote {
bytes validator_pro_tx_hash = 6;
int32 validator_index = 7;
bytes block_signature = 8;
- bytes state_signature = 10;
// Vote extension provided by the application. Only valid for precommit
// messages.
// Vote extension signature by the validator if they participated in
// consensus for the associated block. Only valid for precommit messages.
repeated VoteExtension vote_extensions = 11;
-
- bytes app_hash = 12;
}
// Commit contains the evidence that a block was committed by a set of
@@ -141,10 +155,8 @@ message Commit {
int64 height = 1;
int32 round = 2;
BlockID block_id = 3 [(gogoproto.nullable) = false, (gogoproto.customname) = "BlockID"];
- StateID state_id = 100 [(gogoproto.nullable) = false, (gogoproto.customname) = "StateID"];
bytes quorum_hash = 101;
bytes threshold_block_signature = 102;
- bytes threshold_state_signature = 103;
repeated VoteExtension threshold_vote_extensions = 104;
}
diff --git a/proto/tendermint/types/types_test.go b/proto/tendermint/types/types_test.go
new file mode 100644
index 0000000000..9414c9d8bf
--- /dev/null
+++ b/proto/tendermint/types/types_test.go
@@ -0,0 +1,167 @@
+package types
+
+import (
+ "strconv"
+ "testing"
+ time "time"
+
+ gogotypes "github.com/gogo/protobuf/types"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/internal/libs/protoio"
+ "github.com/tendermint/tendermint/libs/rand"
+)
+
+func TestVoteSignBytes(t *testing.T) {
+ const (
+ height = 1
+ round = 2
+ )
+ h := rand.Bytes(crypto.HashSize)
+ stateID := StateID{
+ AppVersion: 2,
+ Height: height,
+ AppHash: h,
+ CoreChainLockedHeight: 1,
+ Time: *gogotypes.TimestampNow(),
+ }
+ sidHash := stateID.Hash()
+ v := Vote{
+ Type: PrecommitType,
+ Height: height,
+ Round: round,
+ BlockID: BlockID{
+ Hash: h,
+ PartSetHeader: PartSetHeader{Total: 1, Hash: h},
+ StateID: sidHash,
+ },
+ }
+ const chainID = "some-chain"
+ sb, err := v.SignBytes(chainID)
+ require.NoError(t, err)
+ assert.Len(t, sb, 4+8+8+32+32+len(chainID)) // type(4) + height(8) + round(8) + blockID(32) + stateID(32)
+}
+
+func TestStateID_Equals(t *testing.T) {
+ tests := []struct {
+ state1 StateID
+ state2 StateID
+ equal bool
+ }{
+ {
+ StateID{
+ AppVersion: 12,
+ Height: 123,
+ AppHash: []byte("12345678901234567890123456789012"),
+ CoreChainLockedHeight: 12,
+ Time: *mustTimestamp(time.Date(2019, 1, 2, 3, 4, 5, 6, time.UTC)),
+ },
+ StateID{
+ AppVersion: 12,
+ Height: 123,
+ AppHash: []byte("12345678901234567890123456789012"),
+ CoreChainLockedHeight: 12,
+ Time: *mustTimestamp(time.Date(2019, 1, 2, 3, 4, 5, 6, time.UTC)),
+ },
+ true,
+ },
+ {
+ StateID{
+ AppVersion: 12,
+ Height: 123,
+ AppHash: []byte("12345678901234567890123456789012"),
+ CoreChainLockedHeight: 12,
+ Time: *mustTimestamp(time.Date(2019, 1, 2, 3, 4, 5, 6, time.UTC)),
+ },
+ StateID{
+ AppVersion: 12,
+ Height: 124,
+ AppHash: []byte("12345678901234567890123456789012"),
+ CoreChainLockedHeight: 12,
+ Time: *mustTimestamp(time.Date(2019, 1, 2, 3, 4, 5, 6, time.UTC)),
+ },
+ false,
+ },
+ {
+ StateID{
+ AppVersion: 12,
+ Height: 123,
+ AppHash: []byte("12345678901234567890123456789012"),
+ CoreChainLockedHeight: 12,
+ Time: *mustTimestamp(time.Date(2019, 1, 2, 3, 4, 5, 6, time.UTC)),
+ },
+ StateID{
+ AppVersion: 12,
+ Height: 123,
+ AppHash: []byte("12345678901234567890123456789021"),
+ CoreChainLockedHeight: 12,
+ Time: *mustTimestamp(time.Date(2019, 1, 2, 3, 4, 5, 6, time.UTC)),
+ },
+ false,
+ },
+ }
+ //nolint:scopelint
+ for tcID, tc := range tests {
+ t.Run(strconv.Itoa(tcID), func(t *testing.T) {
+ assert.Equal(t, tc.equal, tc.state1.Equal(tc.state2))
+ })
+ }
+}
+
+func TestStateIDIsZero(t *testing.T) {
+ type testCase struct {
+ StateID
+ expectZero bool
+ }
+ testCases := []testCase{
+ {
+ expectZero: true,
+ },
+ {
+ StateID: StateID{Time: *gogotypes.TimestampNow()},
+ expectZero: false,
+ },
+ }
+ for _, tc := range testCases {
+ t.Run("", func(t *testing.T) {
+ assert.Equal(t, tc.expectZero, tc.IsZero())
+ })
+ }
+}
+
+// TestStateIDSignBytes ensures that state ID is correctly encoded as bytes for signing.
+func TestStateIDSignBytes(t *testing.T) {
+ testCases := []StateID{
+ {
+ AppHash: rand.Bytes(32),
+ },
+ {
+ AppVersion: 1234,
+ Height: 1,
+ AppHash: rand.Bytes(32),
+ CoreChainLockedHeight: 123,
+ Time: *mustTimestamp(time.Date(2022, 3, 4, 5, 6, 7, 8, time.UTC)),
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run("", func(t *testing.T) {
+ bz, err := tc.signBytes()
+ require.NoError(t, err)
+ stateID := StateID{}
+ err = protoio.UnmarshalDelimited(bz, &stateID)
+ require.NoError(t, err)
+ assert.Equal(t, tc, stateID)
+ })
+ }
+}
+
+func mustTimestamp(t time.Time) *gogotypes.Timestamp {
+ ts, err := gogotypes.TimestampProto(t)
+ if err != nil {
+ panic(err)
+ }
+ return ts
+}
diff --git a/rpc/client/evidence_test.go b/rpc/client/evidence_test.go
index 3d240e51c8..f585680d1b 100644
--- a/rpc/client/evidence_test.go
+++ b/rpc/client/evidence_test.go
@@ -18,7 +18,7 @@ import (
func newEvidence(t *testing.T, val *privval.FilePV,
vote *types.Vote, vote2 *types.Vote,
- chainID string, stateID types.StateID,
+ chainID string,
quorumType btcjson.LLMQType,
quorumHash crypto.QuorumHash,
timestamp time.Time,
@@ -38,12 +38,6 @@ func newEvidence(t *testing.T, val *privval.FilePV,
vote2.BlockSignature, err = privKey.SignDigest(types.VoteBlockSignID(chainID, v2, quorumType, quorumHash))
require.NoError(t, err)
- vote.StateSignature, err = privKey.SignDigest(stateID.SignID(chainID, quorumType, quorumHash))
- require.NoError(t, err)
-
- vote2.StateSignature, err = privKey.SignDigest(stateID.SignID(chainID, quorumType, quorumHash))
- require.NoError(t, err)
-
validator := types.NewValidator(privKey.PubKey(), types.DefaultDashVotingPower, val.Key.ProTxHash, "")
valSet := types.NewValidatorSet([]*types.Validator{validator}, validator.PubKey, quorumType, quorumHash, true)
@@ -60,10 +54,14 @@ func makeEvidences(
quorumHash crypto.QuorumHash,
timestamp time.Time,
) (correct *types.DuplicateVoteEvidence, fakes []*types.DuplicateVoteEvidence) {
+ const height = int64(1)
+ stateID := types.RandStateID()
+ stateID.Height = uint64(height)
+
vote := types.Vote{
ValidatorProTxHash: val.Key.ProTxHash,
ValidatorIndex: 0,
- Height: 1,
+ Height: height,
Round: 0,
Type: tmproto.PrevoteType,
BlockID: types.BlockID{
@@ -72,14 +70,13 @@ func makeEvidences(
Total: 1000,
Hash: crypto.Checksum([]byte("partset")),
},
+ StateID: stateID.Hash(),
},
}
- stateID := types.RandStateID().WithHeight(vote.Height - 1)
-
vote2 := vote
vote2.BlockID.Hash = crypto.Checksum([]byte("blockhash2"))
- correct = newEvidence(t, val, &vote, &vote2, chainID, stateID, quorumType, quorumHash, timestamp)
+ correct = newEvidence(t, val, &vote, &vote2, chainID, quorumType, quorumHash, timestamp)
fakes = make([]*types.DuplicateVoteEvidence, 0)
@@ -87,34 +84,34 @@ func makeEvidences(
{
v := vote2
v.ValidatorProTxHash = []byte("some_pro_tx_hash")
- fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID, stateID, quorumType, quorumHash, timestamp))
+ fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID, quorumType, quorumHash, timestamp))
}
// different height
{
v := vote2
v.Height = vote.Height + 1
- fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID, stateID, quorumType, quorumHash, timestamp))
+ fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID, quorumType, quorumHash, timestamp))
}
// different round
{
v := vote2
v.Round = vote.Round + 1
- fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID, stateID, quorumType, quorumHash, timestamp))
+ fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID, quorumType, quorumHash, timestamp))
}
// different type
{
v := vote2
v.Type = tmproto.PrecommitType
- fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID, stateID, quorumType, quorumHash, timestamp))
+ fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID, quorumType, quorumHash, timestamp))
}
// exactly same vote
{
v := vote
- fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID, stateID, quorumType, quorumHash, timestamp))
+ fakes = append(fakes, newEvidence(t, val, &vote, &v, chainID, quorumType, quorumHash, timestamp))
}
return correct, fakes
diff --git a/rpc/client/examples_test.go b/rpc/client/examples_test.go
index 38282232c3..7cb2f795af 100644
--- a/rpc/client/examples_test.go
+++ b/rpc/client/examples_test.go
@@ -46,7 +46,7 @@ func TestHTTPSimple(t *testing.T) {
// Create a transaction
k := []byte("name")
v := []byte("satoshi")
- tx := append(k, append([]byte("="), v...)...) // nolint:gocritic
+ tx := append(k, append([]byte("="), v...)...) //nolint:gocritic
// Broadcast the transaction and wait for it to commit (rather use
// c.BroadcastTxSync though in production).
@@ -101,11 +101,11 @@ func TestHTTPBatching(t *testing.T) {
// Create our two transactions
k1 := []byte("firstName")
v1 := []byte("satoshi")
- tx1 := append(k1, append([]byte("="), v1...)...) // nolint:gocritic
+ tx1 := append(k1, append([]byte("="), v1...)...) //nolint:gocritic
k2 := []byte("lastName")
v2 := []byte("nakamoto")
- tx2 := append(k2, append([]byte("="), v2...)...) // nolint:gocritic
+ tx2 := append(k2, append([]byte("="), v2...)...) //nolint:gocritic
txs := [][]byte{tx1, tx2}
diff --git a/rpc/client/http/http.go b/rpc/client/http/http.go
index 4bc29b63f3..c8d7b0bdba 100644
--- a/rpc/client/http/http.go
+++ b/rpc/client/http/http.go
@@ -34,24 +34,24 @@ the example for more details.
Example:
- c, err := New("http://192.168.1.10:26657")
- if err != nil {
- // handle error
- }
-
- // call Start/Stop if you're subscribing to events
- err = c.Start()
- if err != nil {
- // handle error
- }
- defer c.Stop()
-
- res, err := c.Status()
- if err != nil {
- // handle error
- }
-
- // handle result
+ c, err := New("http://192.168.1.10:26657")
+ if err != nil {
+ // handle error
+ }
+
+ // call Start/Stop if you're subscribing to events
+ err = c.Start()
+ if err != nil {
+ // handle error
+ }
+ defer c.Stop()
+
+ res, err := c.Status()
+ if err != nil {
+ // handle error
+ }
+
+ // handle result
*/
type HTTP struct {
remote string
diff --git a/rpc/client/mock/client.go b/rpc/client/mock/client.go
index 56bb83a664..bca155f744 100644
--- a/rpc/client/mock/client.go
+++ b/rpc/client/mock/client.go
@@ -41,7 +41,6 @@ var _ client.Client = Client{}
// Call is used by recorders to save a call and response.
// It can also be used to configure mock responses.
-//
type Call struct {
Name string
Args interface{}
diff --git a/rpc/jsonrpc/doc.go b/rpc/jsonrpc/doc.go
index 58b522861b..04da303f26 100644
--- a/rpc/jsonrpc/doc.go
+++ b/rpc/jsonrpc/doc.go
@@ -1,7 +1,7 @@
// HTTP RPC server supporting calls via uri params, jsonrpc over HTTP, and jsonrpc over
// websockets
//
-// Client Requests
+// # Client Requests
//
// Suppose we want to expose the rpc function `HelloWorld(name string, num int)`.
//
@@ -9,12 +9,12 @@
//
// As a GET request, it would have URI encoded parameters, and look like:
//
-// curl 'http://localhost:8008/hello_world?name="my_world"&num=5'
+// curl 'http://localhost:8008/hello_world?name="my_world"&num=5'
//
// Note the `'` around the url, which is just so bash doesn't ignore the quotes in `"my_world"`.
// This should also work:
//
-// curl http://localhost:8008/hello_world?name=\"my_world\"&num=5
+// curl http://localhost:8008/hello_world?name=\"my_world\"&num=5
//
// A GET request to `/` returns a list of available endpoints.
// For those which take arguments, the arguments will be listed in order, with `_` where the actual value should be.
@@ -23,20 +23,19 @@
//
// As a POST request, we use JSONRPC. For instance, the same request would have this as the body:
//
-// {
-// "jsonrpc": "2.0",
-// "id": "anything",
-// "method": "hello_world",
-// "params": {
-// "name": "my_world",
-// "num": 5
-// }
-// }
+// {
+// "jsonrpc": "2.0",
+// "id": "anything",
+// "method": "hello_world",
+// "params": {
+// "name": "my_world",
+// "num": 5
+// }
+// }
//
// With the above saved in file `data.json`, we can make the request with
//
-// curl --data @data.json http://localhost:8008
-//
+// curl --data @data.json http://localhost:8008
//
// WebSocket (JSONRPC)
//
@@ -44,42 +43,42 @@
// Websocket connections are available at their own endpoint, typically `/websocket`,
// though this is configurable when starting the server.
//
-// Server Definition
+// # Server Definition
//
// Define some types and routes:
//
-// type ResultStatus struct {
-// Value string
-// }
+// type ResultStatus struct {
+// Value string
+// }
//
// Define some routes
//
-// var Routes = map[string]*rpcserver.RPCFunc{
-// "status": rpcserver.NewRPCFunc(Status),
-// }
+// var Routes = map[string]*rpcserver.RPCFunc{
+// "status": rpcserver.NewRPCFunc(Status),
+// }
//
// An rpc function:
//
-// func Status(v string) (*ResultStatus, error) {
-// return &ResultStatus{v}, nil
-// }
+// func Status(v string) (*ResultStatus, error) {
+// return &ResultStatus{v}, nil
+// }
//
// Now start the server:
//
-// mux := http.NewServeMux()
-// rpcserver.RegisterRPCFuncs(mux, Routes)
-// wm := rpcserver.NewWebsocketManager(Routes)
-// mux.HandleFunc("/websocket", wm.WebsocketHandler)
-// logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
-// listener, err := rpc.Listen("0.0.0.0:8080", rpcserver.Config{})
-// if err != nil { panic(err) }
-// go rpcserver.Serve(listener, mux, logger)
+// mux := http.NewServeMux()
+// rpcserver.RegisterRPCFuncs(mux, Routes)
+// wm := rpcserver.NewWebsocketManager(Routes)
+// mux.HandleFunc("/websocket", wm.WebsocketHandler)
+// logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
+// listener, err := rpc.Listen("0.0.0.0:8080", rpcserver.Config{})
+// if err != nil { panic(err) }
+// go rpcserver.Serve(listener, mux, logger)
//
// Note that unix sockets are supported as well (eg. `/path/to/socket` instead of `0.0.0.0:8008`)
// Now see all available endpoints by sending a GET request to `0.0.0.0:8008`.
// Each route is available as a GET request, as a JSONRPCv2 POST request, and via JSONRPCv2 over websockets.
//
-// Examples
+// # Examples
//
// - [Tendermint](https://github.com/tendermint/tendermint/blob/master/rpc/core/routes.go)
package jsonrpc
diff --git a/rpc/jsonrpc/server/rpc_func.go b/rpc/jsonrpc/server/rpc_func.go
index 947f8be5b7..818ebb42e1 100644
--- a/rpc/jsonrpc/server/rpc_func.go
+++ b/rpc/jsonrpc/server/rpc_func.go
@@ -140,10 +140,10 @@ func (rf *RPCFunc) adjustParams(data []byte) (json.RawMessage, error) {
// NewRPCFunc constructs an RPCFunc for f, which must be a function whose type
// signature matches one of these schemes:
//
-// func(context.Context) error
-// func(context.Context) (R, error)
-// func(context.Context, *T) error
-// func(context.Context, *T) (R, error)
+// func(context.Context) error
+// func(context.Context) (R, error)
+// func(context.Context, *T) error
+// func(context.Context, *T) (R, error)
//
// for an arbitrary struct type T and type R. NewRPCFunc will panic if f does
// not have one of these forms. A newly-constructed RPCFunc has a default
diff --git a/rpc/jsonrpc/types/types.go b/rpc/jsonrpc/types/types.go
index 0c0500bf0b..ded68bea2a 100644
--- a/rpc/jsonrpc/types/types.go
+++ b/rpc/jsonrpc/types/types.go
@@ -301,7 +301,6 @@ func (ci *CallInfo) RemoteAddr() string {
//----------------------------------------
// SOCKETS
-//
// Determine if its a unix or tcp socket.
// If tcp, must specify the port; `0.0.0.0` will return incorrectly as "unix" since there's no port
// TODO: deprecate
diff --git a/scripts/keymigrate/migrate.go b/scripts/keymigrate/migrate.go
index 2c5873427e..02ad486c7b 100644
--- a/scripts/keymigrate/migrate.go
+++ b/scripts/keymigrate/migrate.go
@@ -523,7 +523,7 @@ func convertEvidence(key keyID, newPrefix int64) ([]byte, error) {
// so checking the one-byte prefix alone is not enough to distinguish them.
// Legacy evidence keys are suffixed with a string of the format:
//
-// "%0.16X/%X"
+// "%0.16X/%X"
//
// where the first element is the height and the second is the hash. Thus, we
// check
diff --git a/scripts/metricsgen/metricsgen_test.go b/scripts/metricsgen/metricsgen_test.go
index a925b591d1..f3c97854de 100644
--- a/scripts/metricsgen/metricsgen_test.go
+++ b/scripts/metricsgen/metricsgen_test.go
@@ -6,13 +6,13 @@ import (
"go/parser"
"go/token"
"io"
- "io/ioutil"
"os"
"path"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
+
metricsgen "github.com/tendermint/tendermint/scripts/metricsgen"
)
@@ -38,7 +38,7 @@ func TestSimpleTemplate(t *testing.T) {
}
func TestFromData(t *testing.T) {
- infos, err := ioutil.ReadDir(testDataDir)
+ infos, err := os.ReadDir(testDataDir)
if err != nil {
t.Fatalf("unable to open file %v", err)
}
@@ -67,12 +67,12 @@ func TestFromData(t *testing.T) {
if _, err := parser.ParseFile(token.NewFileSet(), outFile, nil, parser.AllErrors); err != nil {
t.Fatalf("unable to parse generated file %s: %v", outFile, err)
}
- bNew, err := ioutil.ReadFile(outFile)
+ bNew, err := os.ReadFile(outFile)
if err != nil {
t.Fatalf("unable to read generated file %s: %v", outFile, err)
}
goldenFile := path.Join(dirName, "metrics.gen.go")
- bOld, err := ioutil.ReadFile(goldenFile)
+ bOld, err := os.ReadFile(goldenFile)
if err != nil {
t.Fatalf("unable to read file %s: %v", goldenFile, err)
}
diff --git a/spec/abci++/api.md b/spec/abci++/api.md
index f74c3b153f..3d4c1d35a6 100644
--- a/spec/abci++/api.md
+++ b/spec/abci++/api.md
@@ -87,7 +87,6 @@
| round | [int32](#int32) | | |
| quorum_hash | [bytes](#bytes) | | |
| block_signature | [bytes](#bytes) | | |
-| state_signature | [bytes](#bytes) | | |
| threshold_vote_extensions | [tendermint.types.VoteExtension](#tendermint-types-VoteExtension) | repeated | |
@@ -183,7 +182,6 @@ to the application.
| round | [int32](#int32) | | The round at which the block proposer decided in the previous height. |
| quorum_hash | [bytes](#bytes) | | List of validators' addresses in the last validator set with their voting information, including vote extensions. |
| block_signature | [bytes](#bytes) | | |
-| state_signature | [bytes](#bytes) | | |
| threshold_vote_extensions | [tendermint.types.VoteExtension](#tendermint-types-VoteExtension) | repeated | |
@@ -345,7 +343,7 @@ Extends a vote with application-side injection
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| txs | [bytes](#bytes) | repeated | List of transactions committed as part of the block. |
-| decided_last_commit | [CommitInfo](#tendermint-abci-CommitInfo) | | Info about the last commit, obtained from the block that was just decided. |
+| commit | [CommitInfo](#tendermint-abci-CommitInfo) | | Info about the current commit |
| misbehavior | [Misbehavior](#tendermint-abci-Misbehavior) | repeated | List of information about validators that acted incorrectly. |
| hash | [bytes](#bytes) | | The block header's hash. Present for convenience (can be derived from the block header). |
| height | [int64](#int64) | | The height of the finalized block. |
diff --git a/spec/consensus/signing.md b/spec/consensus/signing.md
index 907a5a01af..33ec7085d9 100644
--- a/spec/consensus/signing.md
+++ b/spec/consensus/signing.md
@@ -48,35 +48,47 @@ BlockID is the structure used to represent the block:
```go
type BlockID struct {
- Hash []byte
- PartsHeader PartSetHeader
+ Hash []byte
+ PartSetHeader PartSetHeader
+ StateID []byte
}
type PartSetHeader struct {
Hash []byte
Total int
}
+
+type StateID struct {
+ AppVersion uint64
+ Height uint64
+ AppHash []byte
+ CoreChainLockedHeight uint32
+ Time int64
+}
```
To be included in a valid vote or proposal, BlockID must either represent a `nil` block, or a complete one.
-We introduce two methods, `BlockID.IsZero()` and `BlockID.IsComplete()` for these cases, respectively.
+We introduce two methods, `BlockID.IsNil()` and `BlockID.IsComplete()` for these cases, respectively.
-`BlockID.IsZero()` returns true for BlockID `b` if each of the following
+`BlockID.IsNil()` returns true for BlockID `b` if each of the following
are true:
```go
b.Hash == nil
b.PartsHeader.Total == 0
b.PartsHeader.Hash == nil
+b.StateID == nil
```
`BlockID.IsComplete()` returns true for BlockID `b` if each of the following
are true:
```go
+
len(b.Hash) == 32
b.PartsHeader.Total > 0
len(b.PartsHeader.Hash) == 32
+len(b.StateID) == 32
```
## Proposals
@@ -111,16 +123,51 @@ non-negative round, a POLRound not less than -1, and a complete BlockID.
## Votes
-The structure of a vote for signing looks like:
+Sign bytes for votes are defined as `CanonicalVote` struct.
+
+`CanonicalVoteID` is a sha256 checksum of `CanonicalVote` encoded using **protobuf encoding**:
```go
-type CanonicalVote struct {
- Type SignedMsgType // type alias for byte
- Height int64 `binary:"fixed64"`
- Round int64 `binary:"fixed64"`
- BlockID BlockID
- Timestamp time.Time
- ChainID string
+message CanonicalVote {
+ SignedMsgType type = 1; // type alias for byte
+ sfixed64 height = 2;
+ sfixed64 round = 3;
+ // block_id is a checksum (sha256) of CanonicalBlockID for the block being voted on
+ bytes block_id = 4 [(gogoproto.customname) = "BlockID"];
+ // state_id is a checksum (sha256) of StateID for the block being voted on
+ bytes state_id = 5 [(gogoproto.customname) = "StateID"];
+ string chain_id = 99 [(gogoproto.customname) = "ChainID"];
+}
+```
+
+`block_id` is a sha256 checksum of Protobuf-encoded [`CanonicalBlockID` message:
+
+```go
+message CanonicalBlockID {
+ bytes hash = 1;
+ CanonicalPartSetHeader part_set_header = 2 [(gogoproto.nullable) = false];
+}
+
+message CanonicalPartSetHeader {
+ uint32 total = 1;
+ bytes hash = 2;
+}
+```
+
+`state_id` is a sha256 checksum of Protobuf-encoded [`StateID` message](../../proto/tendermint/types/types.proto#L70-L80):
+
+```go
+message StateID {
+ // AppVersion used when generating the block, equals to Header.Version.App.
+ fixed64 app_version = 1 [(gogoproto.customname) = "AppVersion"];
+ // Height of block containing this state ID.
+ fixed64 height = 2;
+ // AppHash used in current block, equal to Header.AppHash. 32 bytes.
+ bytes app_hash = 3 [(gogoproto.customname) = "AppHash"];
+ // CoreChainLockedHeight for the block, equal to Header.CoreChainLockedHeight.
+ fixed32 core_chain_locked_height = 4 [(gogoproto.customname) = "CoreChainLockedHeight"];
+ // Time of the block.
+ google.protobuf.Timestamp time = 5 [(gogoproto.nullable) = false];
}
```
@@ -130,13 +177,42 @@ A vote is valid if each of the following lines evaluates to true for vote `v`:
v.Type == 0x1 || v.Type == 0x2
v.Height > 0
v.Round >= 0
-v.BlockID.IsZero() || v.BlockID.IsComplete()
+v.BlockID.IsNil() || v.BlockID.IsComplete()
```
In other words, a vote is valid for signing if it contains the type of a Prevote
or Precommit (0x1 or 0x2, respectively), has a positive, non-zero height, a
non-negative round, and an empty or valid BlockID.
+### Block signature verification on light client
+
+Block signature is threshold-recovered signature of commit votes.
+
+In a typical light client use case, light client wants to verify
+app state using vote signature. Data needed to do the verification is:
+
+* Chain ID
+* Commit information:
+ * Type (constant, always Commit)
+ * Height
+ * Round
+* Hash of CanonicalBlockID
+* State ID data:
+ * AppVersion
+ * Height
+ * AppHash
+ * CoreChainLockedHeight
+ * Time
+
+Verification algorithm can be described as follows:
+
+1. Build `StateID` message and encode it using Protobuf encoding.
+2. Calculate checksum (SHA256) of encoded `StateID`.
+3. Retrieve or calculate SHA256 checksum of `CanonicalBlockID`
+4. Build `CanonicalVote` message and encode it using Protobuf.
+5. Calculate SHA256 checksum of encoded `CanonicalVote`.
+6. Verify that block signature matches calculated checksum.
+
## Invalid Votes and Proposals
Votes and proposals which do not satisfy the above rules are considered invalid.
@@ -196,16 +272,16 @@ v.Height == s.Height && v.Round == s.Round && v.Step == 0x2 && s.Step != 0x2
In other words, a vote should only be signed if it's:
-- at a higher height
-- at a higher round for the same height
-- a prevote for the same height and round where we haven't signed a prevote or precommit (but have signed a proposal)
-- a precommit for the same height and round where we haven't signed a precommit (but have signed a proposal and/or a prevote)
+* at a higher height
+* at a higher round for the same height
+* a prevote for the same height and round where we haven't signed a prevote or precommit (but have signed a proposal)
+* a precommit for the same height and round where we haven't signed a precommit (but have signed a proposal and/or a prevote)
This means that once a validator signs a prevote for a given height and round, the only other message it can sign for that height and round is a precommit.
And once a validator signs a precommit for a given height and round, it must not sign any other message for that same height and round.
-Note this includes votes for `nil`, ie. where `BlockID.IsZero()` is true. If a
-signer has already signed a vote where `BlockID.IsZero()` is true, it cannot
+Note this includes votes for `nil`, ie. where `BlockID.IsNil()` is true. If a
+signer has already signed a vote where `BlockID.IsNil()` is true, it cannot
sign another vote with the same type for the same height and round where
`BlockID.IsComplete()` is true. Thus only a single vote of a particular type
(ie. 0x01 or 0x02) can be signed for the same height and round.
diff --git a/spec/core/encoding.md b/spec/core/encoding.md
index c137575d78..5cc95b84d6 100644
--- a/spec/core/encoding.md
+++ b/spec/core/encoding.md
@@ -270,7 +270,7 @@ For instance, an ED25519 PubKey would look like:
Where the `"value"` is the base64 encoding of the raw pubkey bytes, and the
`"type"` is the type name for Ed25519 pubkeys.
-### Signed Messages
+## Signed Messages
Signed messages (eg. votes, proposals) in the consensus are encoded using protobuf.
diff --git a/test/e2e/node/config.go b/test/e2e/node/config.go
index 345d33f279..b2e1b24ffe 100644
--- a/test/e2e/node/config.go
+++ b/test/e2e/node/config.go
@@ -1,4 +1,4 @@
-//nolint: goconst
+// nolint: goconst
package main
import (
diff --git a/test/e2e/pkg/mockcoreserver/expect.go b/test/e2e/pkg/mockcoreserver/expect.go
index 0a8de921dc..f7630b366a 100644
--- a/test/e2e/pkg/mockcoreserver/expect.go
+++ b/test/e2e/pkg/mockcoreserver/expect.go
@@ -5,7 +5,7 @@ import (
"context"
"errors"
"fmt"
- "io/ioutil"
+ "io"
"log"
"net/http"
"net/url"
@@ -25,7 +25,7 @@ func BodyShouldBeSame(v interface{}) ExpectFunc {
log.Panicf("unsupported type %q", t)
}
return func(req *http.Request) error {
- buf, err := ioutil.ReadAll(req.Body)
+ buf, err := io.ReadAll(req.Body)
if err != nil {
return err
}
@@ -33,7 +33,7 @@ func BodyShouldBeSame(v interface{}) ExpectFunc {
if err != nil {
return err
}
- req.Body = ioutil.NopCloser(bytes.NewBuffer(buf))
+ req.Body = io.NopCloser(bytes.NewBuffer(buf))
if !bytes.Equal(body, buf) {
return fmt.Errorf(
"the request body retried by URL %s is not equal\nexpected: %s\nactual: %s",
@@ -113,11 +113,11 @@ func JRPCParamsEmpty() ExpectFunc {
// Debug is a debug JRPC request handler
func Debug() ExpectFunc {
return func(req *http.Request) error {
- buf, err := ioutil.ReadAll(req.Body)
+ buf, err := io.ReadAll(req.Body)
if err != nil {
return err
}
- req.Body = ioutil.NopCloser(bytes.NewBuffer(buf))
+ req.Body = io.NopCloser(bytes.NewBuffer(buf))
return nil
}
}
diff --git a/test/e2e/pkg/mockcoreserver/server.go b/test/e2e/pkg/mockcoreserver/server.go
index 824a7187fe..84ebeccda8 100644
--- a/test/e2e/pkg/mockcoreserver/server.go
+++ b/test/e2e/pkg/mockcoreserver/server.go
@@ -5,7 +5,7 @@ import (
"context"
"encoding/json"
"fmt"
- "io/ioutil"
+ "io"
"log"
"net"
"net/http"
@@ -126,7 +126,7 @@ func (s *JRPCServer) Start() {
s.guard.Lock()
defer s.guard.Unlock()
jReq := btcjson.Request{}
- buf, err := ioutil.ReadAll(req.Body)
+ buf, err := io.ReadAll(req.Body)
if err != nil {
return fmt.Errorf("unable to decode jRPC request: %v", err)
}
@@ -134,7 +134,7 @@ func (s *JRPCServer) Start() {
if err != nil {
return err
}
- req.Body = ioutil.NopCloser(bytes.NewBuffer(buf))
+ req.Body = io.NopCloser(bytes.NewBuffer(buf))
mustUnmarshal(buf, &jReq)
call, err := s.findCall(jReq)
if err != nil {
diff --git a/test/e2e/pkg/mockcoreserver/server_test.go b/test/e2e/pkg/mockcoreserver/server_test.go
index 2ce57208cd..390f1a37e3 100644
--- a/test/e2e/pkg/mockcoreserver/server_test.go
+++ b/test/e2e/pkg/mockcoreserver/server_test.go
@@ -3,7 +3,7 @@ package mockcoreserver
import (
"context"
"encoding/hex"
- "io/ioutil"
+ "io"
"net/http"
"net/url"
"testing"
@@ -58,7 +58,7 @@ func TestServer(t *testing.T) {
Respond(JSONBody(tc.e), JSONContentType())
resp, err := http.Get(tc.url)
require.NoError(t, err)
- data, err := ioutil.ReadAll(resp.Body)
+ data, err := io.ReadAll(resp.Body)
_ = resp.Body.Close()
assert.NoError(t, err)
s := ""
diff --git a/test/e2e/runner/evidence.go b/test/e2e/runner/evidence.go
index c013496f39..bb5e4c35f7 100644
--- a/test/e2e/runner/evidence.go
+++ b/test/e2e/runner/evidence.go
@@ -12,8 +12,12 @@ import (
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/internal/test/factory"
+ tmbytes "github.com/tendermint/tendermint/libs/bytes"
+ tmrand "github.com/tendermint/tendermint/libs/rand"
+
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/privval"
+ tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
e2e "github.com/tendermint/tendermint/test/e2e/pkg"
"github.com/tendermint/tendermint/types"
)
@@ -159,12 +163,11 @@ func generateDuplicateVoteEvidence(
if err != nil {
return nil, err
}
- stateID := types.RandStateID()
- voteA, err := factory.MakeVote(ctx, privVal, vals, chainID, valIdx, height, 0, 2, makeRandomBlockID(), stateID.AppHash)
+ voteA, err := factory.MakeVote(ctx, privVal, vals, chainID, valIdx, height, 0, 2, makeRandomBlockID())
if err != nil {
return nil, err
}
- voteB, err := factory.MakeVote(ctx, privVal, vals, chainID, valIdx, height, 0, 2, makeRandomBlockID(), stateID.AppHash)
+ voteB, err := factory.MakeVote(ctx, privVal, vals, chainID, valIdx, height, 0, 2, makeRandomBlockID())
if err != nil {
return nil, err
}
@@ -203,21 +206,16 @@ func readPrivKey(keyFilePath string, quorumHash crypto.QuorumHash) (crypto.PrivK
}
func makeRandomBlockID() types.BlockID {
- return makeBlockID(crypto.CRandBytes(crypto.HashSize), 100, crypto.CRandBytes(crypto.HashSize))
+ return makeBlockID(tmrand.Bytes(crypto.HashSize), 100, tmrand.Bytes(crypto.HashSize), types.RandStateID())
}
-func makeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) types.BlockID {
- var (
- h = make([]byte, crypto.HashSize)
- psH = make([]byte, crypto.HashSize)
- )
- copy(h, hash)
- copy(psH, partSetHash)
+func makeBlockID(hash tmbytes.HexBytes, partSetSize uint32, partSetHash tmbytes.HexBytes, stateID tmproto.StateID) types.BlockID {
return types.BlockID{
- Hash: h,
+ Hash: hash.Copy(),
PartSetHeader: types.PartSetHeader{
Total: partSetSize,
- Hash: psH,
+ Hash: partSetHash.Copy(),
},
+ StateID: stateID.Hash(),
}
}
diff --git a/test/e2e/runner/setup.go b/test/e2e/runner/setup.go
index 5580d4d3bd..ce497c0057 100644
--- a/test/e2e/runner/setup.go
+++ b/test/e2e/runner/setup.go
@@ -219,7 +219,6 @@ func MakeConfig(node *e2e.Node) (*config.Config, error) {
cfg.RPC.ListenAddress = "tcp://0.0.0.0:26657"
cfg.RPC.PprofListenAddress = ":6060"
cfg.P2P.ExternalAddress = fmt.Sprintf("tcp://%v", node.AddressP2P(false))
- cfg.Consensus.AppHashSize = crypto.DefaultAppHashSize
cfg.P2P.QueueType = node.QueueType
cfg.DBBackend = node.Database
cfg.StateSync.DiscoveryTime = 5 * time.Second
@@ -437,9 +436,9 @@ func UpdateConfigStateSync(node *e2e.Node, height int64, hash []byte) error {
if err != nil {
return err
}
- bz = regexp.MustCompile(`(?m)^trust-height =.*`).ReplaceAll(bz, []byte(fmt.Sprintf(`trust-height = %v`, height)))
+ bz = regexp.MustCompile(`(?m)^trust-height =.*`).ReplaceAll(bz, []byte(fmt.Sprintf(`trust-height = %v`, height-1)))
bz = regexp.MustCompile(`(?m)^trust-hash =.*`).ReplaceAll(bz, []byte(fmt.Sprintf(`trust-hash = "%X"`, hash)))
- // nolint: gosec
+ //nolint: gosec
// G306: Expect WriteFile permissions to be 0600 or less
return os.WriteFile(cfgPath, bz, 0644)
}
diff --git a/test/e2e/tests/block_test.go b/test/e2e/tests/block_test.go
index 5ccd3a8159..3ecbd8c001 100644
--- a/test/e2e/tests/block_test.go
+++ b/test/e2e/tests/block_test.go
@@ -53,8 +53,8 @@ func TestBlock_Header(t *testing.T) {
// validate StateID from last commit
if prevBlock != nil {
- assert.EqualValues(t, block.Height-1, block.LastCommit.StateID.Height)
- assert.EqualValues(t, prevBlock.Header.AppHash, block.LastCommit.StateID.AppHash)
+ stateID := prevBlock.Header.StateID()
+ assert.EqualValues(t, stateID.Hash(), block.LastCommit.BlockID.StateID)
}
prevBlock = resp.Block
diff --git a/types/block.go b/types/block.go
index 1aa5435121..372dff09eb 100644
--- a/types/block.go
+++ b/types/block.go
@@ -31,9 +31,8 @@ const (
// MaxHeaderBytes is a maximum header size.
// NOTE: Because app hash can be of arbitrary size, the header is therefore not
// capped in size and thus this number should be seen as a soft max
- MaxHeaderBytes int64 = 646
+ MaxHeaderBytes int64 = 680
MaxCoreChainLockSize int64 = 132
- MaxCommitSize int64 = 374
// MaxOverheadForBlock - maximum overhead to encode a block (up to
// MaxBlockSizeBytes in size) not including it's parts except Data.
@@ -57,11 +56,6 @@ type Block struct {
LastCommit *Commit `json:"last_commit"`
}
-// StateID returns a state ID of this block
-func (b *Block) StateID() StateID {
- return StateID{Height: b.Height, AppHash: b.AppHash}
-}
-
// SetTxs updates Data (in particular the transactions) and DataHash
func (b *Block) SetTxs(txs []Tx) {
b.Data = Data{Txs: txs}
@@ -69,13 +63,36 @@ func (b *Block) SetTxs(txs []Tx) {
b.fillHeader()
}
-// BlockID returns a block ID of this block
-func (b *Block) BlockID() (BlockID, error) {
- parSet, err := b.MakePartSet(BlockPartSizeBytes)
- if err != nil {
- return BlockID{}, err
+// BlockID returns a block ID of this block.
+// BlockID of a nil block is zero-value (BlockID{})
+// If partSet is nil, new partSet will be created
+func (b *Block) BlockID(partSet *PartSet) BlockID {
+ var err error
+
+ if b == nil {
+ return BlockID{}
+ }
+
+ blockHash := b.Hash()
+ // cannot calculate block hash, so we return nil block ID
+ if len(blockHash) == 0 {
+ return BlockID{}
}
- return BlockID{Hash: b.Hash(), PartSetHeader: parSet.Header()}, nil
+
+ if partSet == nil {
+ partSet, err = b.MakePartSet(BlockPartSizeBytes)
+ if err != nil {
+ panic("cannot make part set: " + err.Error())
+ }
+ }
+
+ blockID := BlockID{
+ Hash: blockHash,
+ PartSetHeader: partSet.Header(),
+ StateID: b.Header.StateID().Hash(),
+ }
+
+ return blockID
}
// ValidateBasic performs basic validation that doesn't involve state data.
@@ -319,49 +336,40 @@ func BlockFromProto(bp *tmproto.Block) (*Block, error) {
//-----------------------------------------------------------------------------
// MaxDataBytes returns the maximum size of block's data.
-//
-// XXX: Panics on negative result.
-
-func MaxDataBytes(maxBytes int64, keyType crypto.KeyType, evidenceBytes int64, valsCount int) int64 {
+// If `commit` is nil, it is assumed to use `MaxCommitOverheadBytes`
+func MaxDataBytes(maxBytes int64, commit *Commit, evidenceBytes int64) (int64, error) {
+ lastCommitSize := MaxCommitOverheadBytes
+ if commit != nil {
+ lastCommitSize = int64(commit.ToProto().Size())
+ }
maxDataBytes := maxBytes -
MaxOverheadForBlock -
MaxHeaderBytes -
MaxCoreChainLockSize -
- MaxCommitOverheadBytes -
+ lastCommitSize -
evidenceBytes
if maxDataBytes < 0 {
- panic(fmt.Sprintf(
- "Negative MaxDataBytes. Block.MaxBytes=%d is too small to accommodate header&lastCommit&evidence=%d",
+ return maxDataBytes, fmt.Errorf(
+ "block MaxBytes (%d) is too small to accommodate "+
+ "header (%d) + lastCommit (%d) + core chain lock (%d) + evidence (%d), need %d more bytes",
maxBytes,
- -(maxDataBytes - maxBytes),
- ))
+ MaxOverheadForBlock+MaxHeaderBytes,
+ lastCommitSize,
+ +MaxCoreChainLockSize,
+ evidenceBytes,
+ -maxDataBytes,
+ )
}
- return maxDataBytes
+ return maxDataBytes, nil
}
// MaxDataBytesNoEvidence returns the maximum size of block's data when
-// evidence count is unknown. MaxEvidencePerBlock will be used for the size
-// of evidence.
-//
-// XXX: Panics on negative result.
-func MaxDataBytesNoEvidence(maxBytes int64) int64 {
- maxDataBytes := maxBytes -
- MaxOverheadForBlock -
- MaxHeaderBytes -
- MaxCoreChainLockSize -
- MaxCommitOverheadBytes
+// no evidence is used.
+func MaxDataBytesNoEvidence(maxBytes int64) (int64, error) {
+ return MaxDataBytes(maxBytes, nil, 0)
- if maxDataBytes < 0 {
- panic(fmt.Sprintf(
- "Negative MaxDataBytesUnknownEvidence. Block.MaxBytes=%d is too small to accommodate header&lastCommit&evidence=%d",
- maxBytes,
- -(maxDataBytes - maxBytes),
- ))
- }
-
- return maxDataBytes
}
// MakeBlock returns a new block with an empty header, except what can be
@@ -504,6 +512,29 @@ func (h Header) ValidateBasic() error {
return nil
}
+// StateID returns a state ID of this block
+func (h *Header) StateID() tmproto.StateID {
+ var appHash []byte
+ if len(h.AppHash) != 0 {
+ appHash = h.AppHash.Copy()
+ } else {
+ appHash = make([]byte, crypto.DefaultAppHashSize)
+ }
+
+ ts, err := gogotypes.TimestampProto(h.Time)
+ if err != nil || ts == nil {
+ panic("cannot convert time " + h.Time.String() + " to Timesstamp: " + err.Error())
+ }
+
+ return tmproto.StateID{
+ AppVersion: h.Version.App,
+ Height: uint64(h.Height),
+ AppHash: appHash,
+ CoreChainLockedHeight: h.CoreChainLockedHeight,
+ Time: *ts,
+ }
+}
+
// Hash returns the hash of the header.
// It computes a Merkle tree from the header fields
// ordered as they appear in the Header.
@@ -669,9 +700,10 @@ const (
)
const (
- // MaxCommitOverheadBytes is the max size of commit -> 82 for BlockID, 34 for StateID, 8 for Height, 4 for Round.
- // 96 for Block signature, 96 for State Signature and -> 3 bytes overhead
- MaxCommitOverheadBytes int64 = 329
+ // MaxCommitOverheadBytes is the max size of commit, with overhead but without vote extensions:
+ // (110+2) for BlockID, (8+2) for Height, (4+2) for Round,
+ // (32+3) for QuorumHash, (96+3) for Block signature.
+ MaxCommitOverheadBytes int64 = (110 + 2) + (8 + 2) + (4 + 2) + (32 + 3) + (96 + 3) + 0
)
//-------------------------------------
@@ -686,10 +718,8 @@ type Commit struct {
Height int64 `json:"height"`
Round int32 `json:"round"`
BlockID BlockID `json:"block_id"`
- StateID StateID `json:"state_id"`
QuorumHash crypto.QuorumHash `json:"quorum_hash"`
ThresholdBlockSignature []byte `json:"threshold_block_signature"`
- ThresholdStateSignature []byte `json:"threshold_state_signature"`
// ThresholdVoteExtensions keeps the list of recovered threshold signatures for vote-extensions
ThresholdVoteExtensions []ThresholdExtensionSign `json:"threshold_vote_extensions"`
@@ -700,12 +730,11 @@ type Commit struct {
}
// NewCommit returns a new Commit.
-func NewCommit(height int64, round int32, blockID BlockID, stateID StateID, commitSigns *CommitSigns) *Commit {
+func NewCommit(height int64, round int32, blockID BlockID, commitSigns *CommitSigns) *Commit {
commit := &Commit{
Height: height,
Round: round,
BlockID: blockID,
- StateID: stateID,
}
if commitSigns != nil {
commitSigns.CopyToCommit(commit)
@@ -719,7 +748,6 @@ func (commit *Commit) ToCommitInfo() types.CommitInfo {
Round: commit.Round,
QuorumHash: commit.QuorumHash,
BlockSignature: commit.ThresholdBlockSignature,
- StateSignature: commit.ThresholdStateSignature,
ThresholdVoteExtensions: ThresholdExtensionSignToProto(commit.ThresholdVoteExtensions),
}
}
@@ -756,7 +784,11 @@ func (commit *Commit) VoteBlockRequestID() []byte {
func (commit *Commit) CanonicalVoteVerifySignBytes(chainID string) []byte {
voteCanonical := commit.GetCanonicalVote()
vCanonical := voteCanonical.ToProto()
- return VoteBlockSignBytes(chainID, vCanonical)
+ bz, err := vCanonical.SignBytes(chainID)
+ if err != nil {
+ panic(fmt.Errorf("canonical vote sign bytes: %w", err))
+ }
+ return bz
}
// CanonicalVoteVerifySignID returns the signID bytes of the Canonical Vote that is threshold signed.
@@ -814,13 +846,6 @@ func (commit *Commit) ValidateBasic() error {
len(commit.ThresholdBlockSignature),
)
}
- if len(commit.ThresholdStateSignature) != SignatureSize {
- return fmt.Errorf(
- "state threshold signature is wrong size (wanted: %d, received: %d)",
- SignatureSize,
- len(commit.ThresholdStateSignature),
- )
- }
}
return nil
}
@@ -839,10 +864,7 @@ func (commit *Commit) Hash() tmbytes.HexBytes {
return nil
}
if commit.hash == nil {
- bs := make([][]byte, 2)
- bs[0] = commit.ThresholdBlockSignature
- bs[1] = commit.ThresholdStateSignature
- commit.hash = merkle.HashFromByteSlices(bs)
+ commit.hash = crypto.Checksum(commit.ThresholdBlockSignature)
}
return commit.hash
}
@@ -855,14 +877,12 @@ func (commit *Commit) String() string {
return "nil-Commit"
}
return fmt.Sprintf(
- `Commit{H: %d, R: %d, BlockID: %v, StateID: %v, QuorumHash %v, BlockSignature: %v, StateSignature: %v}#%v`,
+ `Commit{H: %d, R: %d, BlockID: %v, QuorumHash %v, BlockSignature: %v}#%v`,
commit.Height,
commit.Round,
commit.BlockID,
- commit.StateID,
commit.QuorumHash,
base64.StdEncoding.EncodeToString(commit.ThresholdBlockSignature),
- base64.StdEncoding.EncodeToString(commit.ThresholdStateSignature),
commit.hash)
}
@@ -875,16 +895,12 @@ func (commit *Commit) StringIndented(indent string) string {
%s Height: %d
%s Round: %d
%s BlockID: %v
-%s StateID: %v
%s BlockSignature: %v
-%s StateSignature: %v
%s}#%v`,
indent, commit.Height,
indent, commit.Round,
indent, commit.BlockID,
- indent, commit.StateID,
indent, base64.StdEncoding.EncodeToString(commit.ThresholdBlockSignature),
- indent, base64.StdEncoding.EncodeToString(commit.ThresholdStateSignature),
indent, commit.hash)
}
@@ -894,9 +910,7 @@ func (commit *Commit) MarshalZerologObject(e *zerolog.Event) {
e.Int64("height", commit.Height)
e.Int32("round", commit.Round)
e.Str("BlockID.Hash", commit.BlockID.Hash.String())
- e.Str("StateID", commit.StateID.String())
e.Str("BlockSignature", hex.EncodeToString(commit.ThresholdBlockSignature))
- e.Str("StateSignature", hex.EncodeToString(commit.ThresholdStateSignature))
}
}
@@ -911,9 +925,7 @@ func (commit *Commit) ToProto() *tmproto.Commit {
c.Height = commit.Height
c.Round = commit.Round
c.BlockID = commit.BlockID.ToProto()
- c.StateID = commit.StateID.ToProto()
- c.ThresholdStateSignature = commit.ThresholdStateSignature
c.ThresholdBlockSignature = commit.ThresholdBlockSignature
c.ThresholdVoteExtensions = ThresholdExtensionSignToProto(commit.ThresholdVoteExtensions)
c.QuorumHash = commit.QuorumHash
@@ -937,20 +949,13 @@ func CommitFromProto(cp *tmproto.Commit) (*Commit, error) {
return nil, err
}
- si, err := StateIDFromProto(&cp.StateID)
- if err != nil {
- return nil, err
- }
-
commit.QuorumHash = cp.QuorumHash
commit.ThresholdBlockSignature = cp.ThresholdBlockSignature
- commit.ThresholdStateSignature = cp.ThresholdStateSignature
commit.ThresholdVoteExtensions = ThresholdExtensionSignFromProto(cp.ThresholdVoteExtensions)
commit.Height = cp.Height
commit.Round = cp.Round
commit.BlockID = *bi
- commit.StateID = *si
return commit, commit.ValidateBasic()
}
@@ -1040,12 +1045,14 @@ func DataFromProto(dp *tmproto.Data) (Data, error) {
type BlockID struct {
Hash tmbytes.HexBytes `json:"hash"`
PartSetHeader PartSetHeader `json:"parts"`
+ StateID tmbytes.HexBytes `json:"state_id"`
}
// Equals returns true if the BlockID matches the given BlockID
func (blockID BlockID) Equals(other BlockID) bool {
return bytes.Equal(blockID.Hash, other.Hash) &&
- blockID.PartSetHeader.Equals(other.PartSetHeader)
+ blockID.PartSetHeader.Equals(other.PartSetHeader) &&
+ blockID.StateID.Equal(other.StateID)
}
// Key returns a machine-readable string representation of the BlockID
@@ -1056,7 +1063,9 @@ func (blockID BlockID) Key() string {
panic(err)
}
- return fmt.Sprint(string(blockID.Hash), string(bz))
+ stateID := blockID.StateID
+
+ return string(blockID.Hash) + string(bz) + string(stateID)
}
// ValidateBasic performs basic validation.
@@ -1068,30 +1077,54 @@ func (blockID BlockID) ValidateBasic() error {
if err := blockID.PartSetHeader.ValidateBasic(); err != nil {
return fmt.Errorf("wrong PartSetHeader: %w", err)
}
+
+ if len(blockID.Hash) != 0 && len(blockID.StateID) != crypto.HashSize {
+ return fmt.Errorf("expected state ID len: %d, actual: %d", crypto.HashSize, len(blockID.StateID))
+ }
+
return nil
}
+func (blockID BlockID) Copy() BlockID {
+ return BlockID{
+ PartSetHeader: PartSetHeader{
+ Total: blockID.PartSetHeader.Total,
+ Hash: blockID.PartSetHeader.Hash.Copy(),
+ },
+ Hash: blockID.Hash.Copy(),
+ StateID: blockID.StateID.Copy(),
+ }
+}
+
// IsNil returns true if this is the BlockID of a nil block.
func (blockID BlockID) IsNil() bool {
return len(blockID.Hash) == 0 &&
- blockID.PartSetHeader.IsZero()
+ blockID.PartSetHeader.IsZero() &&
+ blockID.StateID.IsZero()
}
// IsComplete returns true if this is a valid BlockID of a non-nil block.
func (blockID BlockID) IsComplete() bool {
return len(blockID.Hash) == crypto.HashSize &&
blockID.PartSetHeader.Total > 0 &&
- len(blockID.PartSetHeader.Hash) == crypto.HashSize
+ len(blockID.PartSetHeader.Hash) == crypto.HashSize &&
+ len(blockID.StateID) == crypto.HashSize
}
// String returns a human readable string representation of the BlockID.
//
// 1. hash
// 2. part set header
+// 3. state ID hash
//
// See PartSetHeader#String
func (blockID BlockID) String() string {
- return fmt.Sprintf(`%v:%v`, blockID.Hash, blockID.PartSetHeader)
+
+ stateIDHash := blockID.StateID
+ if len(stateIDHash) > 6 {
+ stateIDHash = stateIDHash[:6]
+ }
+ return fmt.Sprintf(`%v:%v:%X`, blockID.Hash, blockID.PartSetHeader, stateIDHash)
}
// ToProto converts BlockID to protobuf
@@ -1103,6 +1136,7 @@ func (blockID *BlockID) ToProto() tmproto.BlockID {
return tmproto.BlockID{
Hash: blockID.Hash,
PartSetHeader: blockID.PartSetHeader.ToProto(),
+ StateID: blockID.StateID,
}
}
@@ -1121,12 +1155,9 @@ func BlockIDFromProto(bID *tmproto.BlockID) (*BlockID, error) {
blockID.PartSetHeader = *ph
blockID.Hash = bID.Hash
+ if bID.StateID != nil {
+ blockID.StateID = bID.StateID
+ }
return blockID, blockID.ValidateBasic()
}
-
-// ProtoBlockIDIsNil is similar to the IsNil function on BlockID, but for the
-// Protobuf representation.
-func ProtoBlockIDIsNil(bID *tmproto.BlockID) bool {
- return len(bID.Hash) == 0 && ProtoPartSetHeaderIsZero(&bID.PartSetHeader)
-}
diff --git a/types/block_meta.go b/types/block_meta.go
index 8f23425411..0a0c9b49f4 100644
--- a/types/block_meta.go
+++ b/types/block_meta.go
@@ -21,8 +21,10 @@ type BlockMeta struct {
// NewBlockMeta returns a new BlockMeta.
func NewBlockMeta(block *Block, blockParts *PartSet) *BlockMeta {
+ blockID := block.BlockID(blockParts)
+
return &BlockMeta{
- BlockID: BlockID{block.Hash(), blockParts.Header()},
+ BlockID: blockID,
BlockSize: block.Size(),
Header: block.Header,
HasCoreChainLock: block.CoreChainLock != nil,
diff --git a/types/block_meta_test.go b/types/block_meta_test.go
index 0ce90c40b4..6379177bf0 100644
--- a/types/block_meta_test.go
+++ b/types/block_meta_test.go
@@ -11,7 +11,11 @@ import (
func TestBlockMeta_ToProto(t *testing.T) {
h := MakeRandHeader()
- bi := BlockID{Hash: h.Hash(), PartSetHeader: PartSetHeader{Total: 123, Hash: tmrand.Bytes(crypto.HashSize)}}
+ bi := BlockID{
+ Hash: h.Hash(),
+ PartSetHeader: PartSetHeader{Total: 123, Hash: tmrand.Bytes(crypto.HashSize)},
+ StateID: RandStateID().Hash(),
+ }
bm := &BlockMeta{
BlockID: bi,
@@ -48,7 +52,11 @@ 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(crypto.HashSize)}}
+ bi := BlockID{
+ Hash: h.Hash(),
+ PartSetHeader: PartSetHeader{Total: 123, Hash: tmrand.Bytes(crypto.HashSize)},
+ StateID: RandStateID().Hash(),
+ }
bi2 := BlockID{Hash: tmrand.Bytes(crypto.HashSize),
PartSetHeader: PartSetHeader{Total: 123, Hash: tmrand.Bytes(crypto.HashSize)}}
bi3 := BlockID{Hash: []byte("incorrect hash"),
diff --git a/types/block_test.go b/types/block_test.go
index 14585a1a6d..583f752314 100644
--- a/types/block_test.go
+++ b/types/block_test.go
@@ -4,14 +4,12 @@ import (
// it is ok to use math/rand here: we do not need a cryptographically secure random
// number generator here and we can run the tests a bit faster
"context"
- "crypto/rand"
"encoding/hex"
"fmt"
"math"
mrand "math/rand"
"os"
"reflect"
- "strconv"
"testing"
"time"
@@ -43,12 +41,11 @@ func TestBlockAddEvidence(t *testing.T) {
lastID := makeBlockIDRandom()
h := int64(3)
- stateID := RandStateID().WithHeight(h - 2)
coreChainLock := NewMockChainLock(1)
voteSet, valSet, vals := randVoteSet(ctx, t, h-1, 1, tmproto.PrecommitType, 10)
- commit, err := makeCommit(ctx, lastID, stateID, h-1, 1, voteSet, vals)
+ commit, err := makeCommit(ctx, lastID, h-1, 1, voteSet, vals)
require.NoError(t, err)
ev, err := NewMockDuplicateVoteEvidenceWithValidator(ctx, h, time.Now(), vals[0], "block-test-chain", valSet.QuorumType,
@@ -74,10 +71,8 @@ func TestBlockValidateBasic(t *testing.T) {
lastID := makeBlockIDRandom()
h := int64(3)
- stateID := RandStateID().WithHeight(h - 2)
-
voteSet, valSet, vals := randVoteSet(ctx, t, h-1, 1, tmproto.PrecommitType, 10)
- commit, err := makeCommit(ctx, lastID, stateID, h-1, 1, voteSet, vals)
+ commit, err := makeCommit(ctx, lastID, h-1, 1, voteSet, vals)
require.NoError(t, err)
ev, err := NewMockDuplicateVoteEvidenceWithValidator(ctx, h, time.Now(), vals[0], "block-test-chain", valSet.QuorumType,
@@ -121,7 +116,7 @@ func TestBlockValidateBasic(t *testing.T) {
blk.LastCommit = nil
}, true},
{"Invalid LastCommit", func(blk *Block) {
- blk.LastCommit = NewCommit(-1, 0, *voteSet.maj23, StateID{}, nil)
+ blk.LastCommit = NewCommit(-1, 0, *voteSet.maj23, nil)
}, true},
{"Invalid Evidence", func(blk *Block) {
emptyEv := &DuplicateVoteEvidence{}
@@ -169,10 +164,9 @@ func TestBlockMakePartSetWithEvidence(t *testing.T) {
lastID := makeBlockIDRandom()
h := int64(3)
- stateID := RandStateID().WithHeight(h - 2)
voteSet, valSet, vals := randVoteSet(ctx, t, h-1, 1, tmproto.PrecommitType, 10)
- commit, err := makeCommit(ctx, lastID, stateID, h-1, 1, voteSet, vals)
+ commit, err := makeCommit(ctx, lastID, h-1, 1, voteSet, vals)
require.NoError(t, err)
ev, err := NewMockDuplicateVoteEvidenceWithValidator(ctx, h, time.Now(), vals[0], "block-test-chain", valSet.QuorumType,
@@ -180,12 +174,10 @@ func TestBlockMakePartSetWithEvidence(t *testing.T) {
require.NoError(t, err)
evList := []Evidence{ev}
- partSet, err := MakeBlock(h, []Tx{Tx("Hello World")}, commit, evList).MakePartSet(512)
+ partSet, err := MakeBlock(h, []Tx{Tx("Hello World :)")}, commit, evList).MakePartSet(512)
require.NoError(t, err)
- // The part set can be either 3 or 4 parts, this is because of variance in sizes due to the non second part of
- // timestamps marshaling to different sizes
- assert.True(t, partSet.Total() == 3)
+ assert.EqualValues(t, 3, partSet.Total())
}
func TestBlockHashesTo(t *testing.T) {
@@ -196,10 +188,9 @@ func TestBlockHashesTo(t *testing.T) {
lastID := makeBlockIDRandom()
h := int64(3)
- stateID := RandStateID().WithHeight(h - 2)
voteSet, valSet, vals := randVoteSet(ctx, t, h-1, 1, tmproto.PrecommitType, 10)
- commit, err := makeCommit(ctx, lastID, stateID, h-1, 1, voteSet, vals)
+ commit, err := makeCommit(ctx, lastID, h-1, 1, voteSet, vals)
require.NoError(t, err)
ev, err := NewMockDuplicateVoteEvidenceWithValidator(ctx, h, time.Now(), vals[0], "block-test-chain", valSet.QuorumType,
@@ -233,34 +224,30 @@ func TestBlockString(t *testing.T) {
}
func makeBlockIDRandom() BlockID {
- var (
- 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
- return BlockID{blockHash, PartSetHeader{123, partSetHash}}
+ return BlockID{
+ Hash: tmrand.Bytes(crypto.HashSize),
+ PartSetHeader: PartSetHeader{123, tmrand.Bytes(crypto.HashSize)},
+ StateID: RandStateID().Hash(),
+ }
}
-func makeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) BlockID {
- var (
- h = make([]byte, crypto.HashSize)
- psH = make([]byte, crypto.HashSize)
- )
- copy(h, hash)
- copy(psH, partSetHash)
+func makeBlockID(hash tmbytes.HexBytes, partSetSize uint32, partSetHash tmbytes.HexBytes, stateID tmbytes.HexBytes) BlockID {
+ if stateID == nil {
+ stateID = RandStateID().Hash()
+ }
return BlockID{
- Hash: h,
+ Hash: hash.Copy(),
PartSetHeader: PartSetHeader{
Total: partSetSize,
- Hash: psH,
+ Hash: partSetHash.Copy(),
},
+ StateID: stateID.Copy(),
}
}
var nilBytes []byte
-// This follows RFC-6962, i.e. `echo -n '' | sha256sum`
+// This follows RFC-6962, i.e. `echo -n "" | sha256sum`
var emptyBytes = []byte{0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b,
0x78, 0x52, 0xb8, 0x55}
@@ -281,10 +268,9 @@ func TestCommit(t *testing.T) {
lastID := makeBlockIDRandom()
h := int64(3)
- stateID := RandStateID().WithHeight(h - 2)
voteSet, _, vals := randVoteSet(ctx, t, h-1, 1, tmproto.PrecommitType, 10)
- commit, err := makeCommit(ctx, lastID, stateID, h-1, 1, voteSet, vals)
+ commit, err := makeCommit(ctx, lastID, h-1, 1, voteSet, vals)
require.NoError(t, err)
assert.Equal(t, h-1, commit.Height)
@@ -292,7 +278,6 @@ func TestCommit(t *testing.T) {
assert.Equal(t, tmproto.PrecommitType, tmproto.SignedMsgType(commit.Type()))
require.NotNil(t, commit.ThresholdBlockSignature)
- require.NotNil(t, commit.ThresholdStateSignature)
// TODO replace an assertion with a correct one
//assert.Equal(t, voteWithoutExtension(voteSet.GetByIndex(0)), commit.GetByIndex(0))
assert.True(t, commit.IsCommit())
@@ -307,7 +292,6 @@ func TestCommitValidateBasic(t *testing.T) {
}{
{"Random Commit", func(com *Commit) {}, false},
{"Incorrect block signature", func(com *Commit) { com.ThresholdBlockSignature = []byte{0} }, true},
- {"Incorrect state signature", func(com *Commit) { com.ThresholdStateSignature = []byte{0} }, true},
{"Incorrect height", func(com *Commit) { com.Height = int64(-100) }, true},
{"Incorrect round", func(com *Commit) { com.Round = -100 }, true},
}
@@ -316,9 +300,10 @@ func TestCommitValidateBasic(t *testing.T) {
t.Run(tc.testName, func(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
- stateID := RandStateID().WithHeight(height - 1)
- com := randCommit(ctx, t, stateID)
+ stateID := RandStateID()
+ stateID.Height = uint64(height - 1)
+ com := randCommit(ctx, t, height-1, stateID)
tc.malleateCommit(com)
assert.Equal(t, tc.expectErr, com.ValidateBasic() != nil, "Validate Basic had an unexpected result")
@@ -337,66 +322,87 @@ func TestMaxCommitBytes(t *testing.T) {
Total: math.MaxInt32,
Hash: crypto.Checksum([]byte("blockID_part_set_header_hash")),
},
+ StateID: RandStateID().Hash(),
},
- StateID: StateID{
- AppHash: crypto.Checksum([]byte("stateID_hash")),
- },
+ QuorumHash: crypto.Checksum([]byte("QuorumHash")),
ThresholdBlockSignature: crypto.CRandBytes(SignatureSize),
- ThresholdStateSignature: crypto.CRandBytes(SignatureSize),
}
+ bIDProto := commit.BlockID.ToProto()
+ assert.Equal(t, 110, bIDProto.Size(), "blockID size")
+
pb := commit.ToProto()
pbSize := int64(pb.Size())
assert.EqualValues(t, MaxCommitOverheadBytes, pbSize)
-
- pb = commit.ToProto()
-
- assert.EqualValues(t, MaxCommitOverheadBytes, int64(pb.Size()))
}
func TestHeaderHash(t *testing.T) {
+ ts, err := gogotypes.TimestampProto(time.Date(2022, 3, 4, 5, 6, 7, 8, time.UTC))
+ require.NoError(t, err)
+
testCases := []struct {
desc string
header *Header
expectHash tmbytes.HexBytes
}{
- {"Generates expected hash", &Header{
- Version: version.Consensus{Block: 1, App: 2},
- ChainID: "chainId",
- Height: 3,
- CoreChainLockedHeight: 1,
- Time: time.Date(2019, 10, 13, 16, 14, 44, 0, time.UTC),
- 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")),
- ResultsHash: crypto.Checksum([]byte("last_results_hash")),
- EvidenceHash: crypto.Checksum([]byte("evidence_hash")),
- ProposerProTxHash: crypto.ProTxHashFromSeedBytes([]byte("proposer_pro_tx_hash")),
- ProposedAppVersion: 1,
- }, hexBytesFromString(t, "74EEFDA2F09ACE19D46DE191EC2745CE14B42F7DE48AF86E6D65B17939B08D3E")},
- {"nil header yields nil", nil, nil},
- {"nil ValidatorsHash yields nil", &Header{
- Version: version.Consensus{Block: 1, App: 2},
- ChainID: "chainId",
- Height: 3,
- CoreChainLockedHeight: 1,
- Time: time.Date(2019, 10, 13, 16, 14, 44, 0, time.UTC),
- 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: crypto.Checksum([]byte("next_validators_hash")),
- ConsensusHash: crypto.Checksum([]byte("consensus_hash")),
- AppHash: crypto.Checksum([]byte("app_hash")),
- ResultsHash: crypto.Checksum([]byte("results_hash")),
- EvidenceHash: crypto.Checksum([]byte("evidence_hash")),
- ProposerProTxHash: crypto.ProTxHashFromSeedBytes([]byte("proposer_pro_tx_hash")),
- ProposedAppVersion: 1,
- }, nil},
+ {
+ desc: "Generates expected hash", header: &Header{
+ Version: version.Consensus{Block: 1, App: 2},
+ ChainID: "chainId",
+ Height: 3,
+ CoreChainLockedHeight: 1,
+ Time: time.Date(2019, 10, 13, 16, 14, 44, 0, time.UTC),
+ LastBlockID: makeBlockID(
+ make([]byte, crypto.HashSize),
+ 6, make([]byte, crypto.HashSize),
+ tmproto.StateID{
+ AppVersion: StateIDVersion,
+ Height: 3,
+ AppHash: crypto.Checksum([]byte("app_hash")),
+ CoreChainLockedHeight: 1,
+ Time: *ts,
+ }.Hash(),
+ ),
+ 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")),
+ ResultsHash: crypto.Checksum([]byte("last_results_hash")),
+ EvidenceHash: crypto.Checksum([]byte("evidence_hash")),
+ ProposerProTxHash: crypto.ProTxHashFromSeedBytes([]byte("proposer_pro_tx_hash")),
+ ProposedAppVersion: 1,
+ },
+ expectHash: hexBytesFromString(t, "891099982E9BC6035675DE94726BB0ADB8AE49E0277C67C7911BAC145119065A"),
+ },
+ {
+ "nil header yields nil",
+ nil,
+ nil,
+ },
+ {
+ "nil ValidatorsHash yields nil",
+ &Header{
+ Version: version.Consensus{Block: 1, App: 2},
+ ChainID: "chainId",
+ Height: 3,
+ CoreChainLockedHeight: 1,
+ Time: time.Date(2019, 10, 13, 16, 14, 44, 0, time.UTC),
+ LastBlockID: makeBlockID(make([]byte, crypto.HashSize), 6, make([]byte, crypto.HashSize), RandStateID().Hash()),
+ LastCommitHash: crypto.Checksum([]byte("last_commit_hash")),
+ DataHash: crypto.Checksum([]byte("data_hash")),
+ ValidatorsHash: nil,
+ NextValidatorsHash: crypto.Checksum([]byte("next_validators_hash")),
+ ConsensusHash: crypto.Checksum([]byte("consensus_hash")),
+ AppHash: crypto.Checksum([]byte("app_hash")),
+ ResultsHash: crypto.Checksum([]byte("results_hash")),
+ EvidenceHash: crypto.Checksum([]byte("evidence_hash")),
+ ProposerProTxHash: crypto.ProTxHashFromSeedBytes([]byte("proposer_pro_tx_hash")),
+ ProposedAppVersion: 1,
+ },
+ nil,
+ },
}
for _, tc := range testCases {
tcRun := tc
@@ -465,7 +471,7 @@ func TestMaxHeaderBytes(t *testing.T) {
ChainID: maxChainID,
Height: math.MaxInt64,
Time: timestamp,
- LastBlockID: makeBlockID(make([]byte, crypto.HashSize), math.MaxInt32, make([]byte, crypto.HashSize)),
+ LastBlockID: makeBlockID(make([]byte, crypto.HashSize), math.MaxInt32, make([]byte, crypto.HashSize), RandStateID().Hash()),
LastCommitHash: crypto.Checksum([]byte("last_commit_hash")),
DataHash: crypto.Checksum([]byte("data_hash")),
ValidatorsHash: crypto.Checksum([]byte("validators_hash")),
@@ -485,12 +491,17 @@ func TestMaxHeaderBytes(t *testing.T) {
assert.EqualValues(t, MaxHeaderBytes, int64(len(bz)))
}
-func randCommit(ctx context.Context, t *testing.T, stateID StateID) *Commit {
+func randCommit(ctx context.Context, t *testing.T, height int64, stateID tmproto.StateID) *Commit {
t.Helper()
- lastID := makeBlockIDRandom()
- height := stateID.Height
+
+ blockID := makeBlockID(
+ tmrand.Bytes(crypto.HashSize),
+ 123,
+ tmrand.Bytes(crypto.HashSize),
+ stateID.Hash(),
+ )
voteSet, _, vals := randVoteSet(ctx, t, height, 1, tmproto.PrecommitType, 10)
- commit, err := makeCommit(ctx, lastID, stateID, height, 1, voteSet, vals)
+ commit, err := makeCommit(ctx, blockID, height, 1, voteSet, vals)
require.NoError(t, err)
@@ -507,37 +518,40 @@ func hexBytesFromString(t *testing.T, s string) tmbytes.HexBytes {
}
func TestBlockMaxDataBytes(t *testing.T) {
+ ctx := context.Background()
+ height := int64(math.MaxInt64)
+ stateID := RandStateID()
+ stateID.Height = uint64(height)
+ commit := randCommit(ctx, t, height, stateID)
+ require.NotNil(t, commit)
+
testCases := []struct {
maxBytes int64
- keyType crypto.KeyType
- valsCount int
+ lastCommit *Commit
evidenceBytes int64
- panics bool
+ expectError bool
result int64
}{
- 0: {-10, crypto.BLS12381, 1, 0, true, 0},
- 1: {10, crypto.BLS12381, 1, 0, true, 0},
- 2: {1114, crypto.BLS12381, 1, 0, true, 0},
- 3: {1118, crypto.BLS12381, 1, 0, false, 0},
- 4: {1119, crypto.BLS12381, 1, 0, false, 1},
- 5: {1119, crypto.BLS12381, 2, 0, false, 1},
- 6: {1218, crypto.BLS12381, 2, 100, false, 0},
+ 0: {-10, commit, 1, true, 0},
+ 1: {10, commit, 1, true, 0},
+ 2: {1189, commit, 1, true, 0},
+ 3: {1189, commit, 0, false, 0},
+ 4: {1190, commit, 0, false, 1},
+ 5: {1190, commit, 1, false, 0},
+ 6: {1190, commit, 2, true, 0},
+ 7: {1191, commit, 2, false, 0},
+ 8: {1218, commit, 2, false, 27},
}
// An extra 33 bytes (32 for sig, 1 for proto encoding are needed for BLS compared to edwards per validator
for i, tc := range testCases {
- tcRun := tc
- j := i
- t.Run(fmt.Sprintf("%d", tcRun.maxBytes), func(t *testing.T) {
- if tcRun.panics {
- assert.Panics(t, func() {
- MaxDataBytes(tcRun.maxBytes, tcRun.keyType, tcRun.evidenceBytes, tcRun.valsCount)
- }, "#%v", j)
+ t.Run(fmt.Sprintf("%d:%d_%d", i, tc.maxBytes, tc.evidenceBytes), func(t *testing.T) {
+ maxDataBytes, err := MaxDataBytes(tc.maxBytes, tc.lastCommit, tc.evidenceBytes)
+ if tc.expectError {
+ assert.Error(t, err, "#%+v, %d", tc, maxDataBytes)
} else {
- assert.Equal(t,
- tcRun.result,
- MaxDataBytes(tcRun.maxBytes, tcRun.keyType, tcRun.evidenceBytes, tcRun.valsCount),
- "#%v", j)
+ require.NoError(t, err)
+ assert.Equal(t, tc.result, maxDataBytes, "#%+v", tc)
}
})
}
@@ -545,40 +559,37 @@ func TestBlockMaxDataBytes(t *testing.T) {
func TestBlockMaxDataBytesNoEvidence(t *testing.T) {
testCases := []struct {
- maxBytes int64
- maxEvidence uint32
- keyType crypto.KeyType
- valsCount int
- panics bool
- result int64
+ maxBytes int64
+ errs bool
+ result int64
}{
- 0: {-10, 1, crypto.BLS12381, 1, true, 0},
- 1: {10, 1, crypto.BLS12381, 1, true, 0},
- 2: {1114, 1, crypto.BLS12381, 1, true, 0},
- 3: {1118, 1, crypto.BLS12381, 1, false, 0},
- 4: {1119, 1, crypto.BLS12381, 1, false, 1},
+ 0: {-10, true, 0},
+ 1: {10, true, 0},
+ 2: {1084, true, 0},
+ 3: {1085, false, 0},
+ 4: {1086, false, 1},
+ 5: {1119, false, 1119 - 1085},
}
for i, tc := range testCases {
- tcRun := tc
- j := i
- t.Run(fmt.Sprintf("%d", tcRun.maxBytes), func(t *testing.T) {
- if tcRun.panics {
- assert.Panics(t, func() {
- MaxDataBytesNoEvidence(tcRun.maxBytes)
- }, "#%v", j)
+ t.Run(fmt.Sprintf("%d:%d", i, tc.maxBytes), func(t *testing.T) {
+ maxDataBytes, err := MaxDataBytesNoEvidence(tc.maxBytes)
+ if tc.errs {
+ assert.Error(t, err, "%+v (%d)", tc, maxDataBytes)
} else {
- assert.Equal(t,
- tcRun.result,
- MaxDataBytesNoEvidence(tcRun.maxBytes),
- "#%v", j)
+ require.NoError(t, err)
+ assert.Equal(t, tc.result, maxDataBytes, "%+v", tc)
}
})
}
}
func TestCommitToVoteSetWithVotesForNilBlock(t *testing.T) {
- blockID := makeBlockID([]byte("blockhash"), 1000, []byte("partshash"))
+ blockID := makeBlockID(
+ []byte("blockhash"),
+ 1000, []byte("partshash"),
+ RandStateID().Hash(),
+ )
const (
height = int64(3)
@@ -589,8 +600,6 @@ func TestCommitToVoteSetWithVotesForNilBlock(t *testing.T) {
defer cancel()
// all votes below use height - 1
- stateID := RandStateID().WithHeight(height - 1)
-
type commitVoteTest struct {
blockIDs []BlockID
numVotes []int // must sum to numValidators
@@ -617,7 +626,6 @@ func TestCommitToVoteSetWithVotesForNilBlock(t *testing.T) {
Round: round,
Type: tmproto.PrecommitType,
BlockID: tc.blockIDs[n],
- AppHash: stateID.AppHash.Copy(),
}
added, err := signAddVote(ctx, vals[vi], vote, voteSet)
@@ -631,7 +639,7 @@ func TestCommitToVoteSetWithVotesForNilBlock(t *testing.T) {
if tc.valid {
commit := voteSet.MakeCommit() // panics without > 2/3 valid votes
assert.NotNil(t, commit)
- err := valSet.VerifyCommit(voteSet.ChainID(), blockID, stateID, height-1, commit)
+ err := valSet.VerifyCommit(voteSet.ChainID(), blockID, height-1, commit)
assert.NoError(t, err)
} else {
assert.Panics(t, func() { voteSet.MakeCommit() })
@@ -641,11 +649,12 @@ func TestCommitToVoteSetWithVotesForNilBlock(t *testing.T) {
func TestBlockIDValidateBasic(t *testing.T) {
validBlockID := BlockID{
- Hash: tmbytes.HexBytes{},
+ Hash: tmrand.Bytes(crypto.HashSize),
PartSetHeader: PartSetHeader{
Total: 1,
- Hash: tmbytes.HexBytes{},
+ Hash: tmrand.Bytes(crypto.HashSize),
},
+ StateID: tmproto.StateID{}.Hash(),
}
invalidBlockID := BlockID{
@@ -654,27 +663,69 @@ func TestBlockIDValidateBasic(t *testing.T) {
Total: 1,
Hash: []byte{0},
},
+ StateID: []byte("too short"),
}
testCases := []struct {
testName string
blockIDHash tmbytes.HexBytes
blockIDPartSetHeader PartSetHeader
+ blockIDStateID tmbytes.HexBytes
expectErr bool
}{
- {"Valid BlockID", validBlockID.Hash, validBlockID.PartSetHeader, false},
- {"Invalid BlockID", invalidBlockID.Hash, validBlockID.PartSetHeader, true},
- {"Invalid BlockID", validBlockID.Hash, invalidBlockID.PartSetHeader, true},
+ {
+ testName: "Valid NIL BlockID",
+ blockIDHash: []byte{},
+ blockIDPartSetHeader: PartSetHeader{
+ Total: 0,
+ Hash: []byte{},
+ },
+ blockIDStateID: tmproto.StateID{}.Hash(),
+ expectErr: false,
+ },
+ {
+ testName: "Valid BlockID",
+ blockIDHash: validBlockID.Hash,
+ blockIDPartSetHeader: validBlockID.PartSetHeader,
+ blockIDStateID: validBlockID.StateID,
+ expectErr: false,
+ },
+ {
+ testName: "Invalid Hash",
+ blockIDHash: invalidBlockID.Hash,
+ blockIDPartSetHeader: validBlockID.PartSetHeader,
+ blockIDStateID: validBlockID.StateID,
+ expectErr: true,
+ },
+ {
+ testName: "Invalid PartSetHeader",
+ blockIDHash: validBlockID.Hash,
+ blockIDPartSetHeader: invalidBlockID.PartSetHeader,
+ blockIDStateID: validBlockID.StateID,
+ expectErr: true,
+ },
+ {
+ testName: "Invalid StateID",
+ blockIDHash: validBlockID.Hash,
+ blockIDPartSetHeader: validBlockID.PartSetHeader,
+ blockIDStateID: invalidBlockID.StateID,
+ expectErr: true,
+ },
}
- for _, tc := range testCases {
- tcRun := tc
+ for _, tcRun := range testCases {
t.Run(tcRun.testName, func(t *testing.T) {
blockID := BlockID{
Hash: tcRun.blockIDHash,
PartSetHeader: tcRun.blockIDPartSetHeader,
+ StateID: tcRun.blockIDStateID,
+ }
+ err := blockID.ValidateBasic()
+ if tcRun.expectErr {
+ assert.Error(t, err)
+ } else {
+ assert.NoError(t, err)
}
- assert.Equal(t, tcRun.expectErr, blockID.ValidateBasic() != nil, "Validate Basic had an unexpected result")
})
}
}
@@ -684,8 +735,9 @@ func TestBlockProtoBuf(t *testing.T) {
defer cancel()
h := mrand.Int63()
- stateID := RandStateID().WithHeight(h - 1)
- c1 := randCommit(ctx, t, stateID)
+ stateID := RandStateID()
+ stateID.Height = uint64(h - 1)
+ c1 := randCommit(ctx, t, h-1, stateID)
b1 := MakeBlock(h, []Tx{Tx([]byte{1})}, &Commit{}, []Evidence{})
b1.ProposerProTxHash = tmrand.Bytes(crypto.DefaultHashSize)
@@ -818,7 +870,12 @@ func TestHeaderProto(t *testing.T) {
}
func TestBlockIDProtoBuf(t *testing.T) {
- blockID := makeBlockID([]byte("hash"), 2, []byte("part_set_hash"))
+ blockID := makeBlockID(
+ crypto.Checksum([]byte("hash")),
+ 2,
+ crypto.Checksum([]byte("part_set_hash")),
+ RandStateID().Hash(),
+ )
testCases := []struct {
msg string
bid1 *BlockID
@@ -845,11 +902,10 @@ func TestSignedHeaderProtoBuf(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
- stateID := RandStateID()
-
- commit := randCommit(ctx, t, stateID)
-
h := MakeRandHeader()
+ stateID := RandStateID()
+ stateID.Height = uint64(h.Height)
+ commit := randCommit(ctx, t, h.Height, stateID)
sh := SignedHeader{Header: &h, Commit: commit}
@@ -878,17 +934,22 @@ func TestSignedHeaderProtoBuf(t *testing.T) {
func TestBlockIDEquals(t *testing.T) {
var (
- blockID = makeBlockID([]byte("hash"), 2, []byte("part_set_hash"))
- blockIDDuplicate = makeBlockID([]byte("hash"), 2, []byte("part_set_hash"))
- blockIDDifferent = makeBlockID([]byte("different_hash"), 2, []byte("part_set_hash"))
- blockIDEmpty = BlockID{}
+ stateID1 = RandStateID().Hash()
+ stateID2 = RandStateID().Hash()
+ blockID = makeBlockID([]byte("hash"), 2, []byte("part_set_hash"), stateID1)
+ blockIDDuplicate = makeBlockID([]byte("hash"), 2, []byte("part_set_hash"), stateID1)
+ blockIDDifferentHash = makeBlockID([]byte("different_hash"), 2, []byte("part_set_hash"), stateID1)
+ blockIDDifferentStateID = makeBlockID([]byte("hash"), 2, []byte("part_set_hash"), stateID2)
+
+ blockIDEmpty = BlockID{}
)
assert.True(t, blockID.Equals(blockIDDuplicate))
- assert.False(t, blockID.Equals(blockIDDifferent))
+ assert.False(t, blockID.Equals(blockIDDifferentHash))
assert.False(t, blockID.Equals(blockIDEmpty))
assert.True(t, blockIDEmpty.Equals(blockIDEmpty)) //nolint: gocritic
- assert.False(t, blockIDEmpty.Equals(blockIDDifferent))
+ assert.False(t, blockIDEmpty.Equals(blockIDDifferentHash))
+ assert.False(t, blockIDEmpty.Equals(blockIDDifferentStateID))
}
// StateID tests
@@ -904,37 +965,6 @@ func TestStateID_Copy(t *testing.T) {
assert.NotEqual(t, state1, state2)
}
-func TestStateID_Equals(t *testing.T) {
- tests := []struct {
- state1 StateID
- state2 StateID
- equal bool
- }{
- {RandStateID(), RandStateID(), false},
- {
- StateID{12, []byte("12345678901234567890123456789012")},
- StateID{12, []byte("12345678901234567890123456789012")},
- true,
- },
- {
- StateID{11, []byte("12345678901234567890123456789012")},
- StateID{12, []byte("12345678901234567890123456789012")},
- false,
- },
- {
- StateID{12, []byte("12345678901234567890123456789012")},
- StateID{12, []byte("1234567890123456789012345678901")},
- false,
- },
- }
- //nolint:scopelint
- for tcID, tc := range tests {
- t.Run(strconv.Itoa(tcID), func(t *testing.T) {
- assert.Equal(t, tc.equal, tc.state1.Equals(tc.state2))
- })
- }
-}
-
func TestHeader_ValidateBasic(t *testing.T) {
testCases := []struct {
name string
@@ -1011,6 +1041,7 @@ func TestHeader_ValidateBasic(t *testing.T) {
PartSetHeader: PartSetHeader{
Hash: make([]byte, crypto.HashSize),
},
+ StateID: RandStateID().Hash(),
},
LastCommitHash: make([]byte, crypto.HashSize+1),
},
@@ -1027,6 +1058,7 @@ func TestHeader_ValidateBasic(t *testing.T) {
PartSetHeader: PartSetHeader{
Hash: make([]byte, crypto.HashSize),
},
+ StateID: RandStateID().Hash(),
},
LastCommitHash: make([]byte, crypto.HashSize),
DataHash: make([]byte, crypto.HashSize+1),
@@ -1044,6 +1076,7 @@ func TestHeader_ValidateBasic(t *testing.T) {
PartSetHeader: PartSetHeader{
Hash: make([]byte, crypto.HashSize),
},
+ StateID: RandStateID().Hash(),
},
LastCommitHash: make([]byte, crypto.HashSize),
DataHash: make([]byte, crypto.HashSize),
@@ -1062,6 +1095,7 @@ func TestHeader_ValidateBasic(t *testing.T) {
PartSetHeader: PartSetHeader{
Hash: make([]byte, crypto.HashSize),
},
+ StateID: RandStateID().Hash(),
},
LastCommitHash: make([]byte, crypto.HashSize),
DataHash: make([]byte, crypto.HashSize),
@@ -1082,6 +1116,7 @@ func TestHeader_ValidateBasic(t *testing.T) {
PartSetHeader: PartSetHeader{
Hash: make([]byte, crypto.HashSize),
},
+ StateID: RandStateID().Hash(),
},
LastCommitHash: make([]byte, crypto.HashSize),
DataHash: make([]byte, crypto.HashSize),
@@ -1102,6 +1137,7 @@ func TestHeader_ValidateBasic(t *testing.T) {
PartSetHeader: PartSetHeader{
Hash: make([]byte, crypto.HashSize),
},
+ StateID: RandStateID().Hash(),
},
LastCommitHash: make([]byte, crypto.HashSize),
DataHash: make([]byte, crypto.HashSize),
@@ -1123,6 +1159,7 @@ func TestHeader_ValidateBasic(t *testing.T) {
PartSetHeader: PartSetHeader{
Hash: make([]byte, crypto.HashSize),
},
+ StateID: RandStateID().Hash(),
},
LastCommitHash: make([]byte, crypto.HashSize),
DataHash: make([]byte, crypto.HashSize),
@@ -1145,6 +1182,7 @@ func TestHeader_ValidateBasic(t *testing.T) {
PartSetHeader: PartSetHeader{
Hash: make([]byte, crypto.HashSize),
},
+ StateID: RandStateID().Hash(),
},
LastCommitHash: make([]byte, crypto.HashSize),
DataHash: make([]byte, crypto.HashSize),
@@ -1169,6 +1207,7 @@ func TestHeader_ValidateBasic(t *testing.T) {
PartSetHeader: PartSetHeader{
Hash: make([]byte, crypto.HashSize),
},
+ StateID: RandStateID().Hash(),
},
LastCommitHash: make([]byte, crypto.HashSize),
DataHash: make([]byte, crypto.HashSize),
@@ -1199,35 +1238,42 @@ func TestHeader_ValidateBasic(t *testing.T) {
}
func TestStateID_ValidateBasic(t *testing.T) {
- type fields struct {
- Height int64
- LastAppHash tmbytes.HexBytes
- }
+
tests := []struct {
name string
- fields fields
- wantErr bool
+ stateID tmproto.StateID
+ wantErr string
}{
- {name: "negative height", fields: fields{-1, nil}, wantErr: true},
- {name: "zero height - allowed for genesis block", fields: fields{0, nil}, wantErr: false},
- {name: "nil apphash", fields: fields{12, nil}, wantErr: false},
- {name: "empty apphash", fields: fields{12, []byte{}}, wantErr: false},
- {name: "apphash too short", fields: fields{12, []byte{0x1, 0x2, 0x3}}, wantErr: true},
- {name: "apphash too short 2", fields: fields{12, tmrand.Bytes(crypto.SmallAppHashSize - 1)}, wantErr: true},
- {name: "apphash small", fields: fields{12, tmrand.Bytes(crypto.SmallAppHashSize)}, wantErr: false},
- {name: "apphash default", fields: fields{12, tmrand.Bytes(crypto.DefaultAppHashSize)}, wantErr: false},
- {name: "apphash large", fields: fields{12, tmrand.Bytes(crypto.LargeAppHashSize)}, wantErr: false},
- {name: "apphash too large", fields: fields{12, tmrand.Bytes(crypto.LargeAppHashSize + 1)}, wantErr: true},
+ {
+ name: "zero height - allowed for genesis block",
+ stateID: tmproto.StateID{
+ AppVersion: StateIDVersion,
+ Height: 0,
+ AppHash: tmrand.Bytes(crypto.DefaultAppHashSize),
+ Time: *gogotypes.TimestampNow(),
+ },
+ wantErr: "",
+ },
+ {
+ name: "apphash default",
+ stateID: tmproto.StateID{
+ AppVersion: StateIDVersion,
+ Height: 12,
+ AppHash: tmrand.Bytes(crypto.DefaultAppHashSize),
+ Time: *gogotypes.TimestampNow(),
+ },
+ wantErr: "",
+ },
}
- //nolint:scopelint
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- stateID := StateID{
- Height: tt.fields.Height,
- AppHash: tt.fields.LastAppHash,
- }
- if err := stateID.ValidateBasic(); (err != nil) != tt.wantErr {
- t.Errorf("StateID.ValidateBasic() error = %v, wantErr %v", err, tt.wantErr)
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ stateID := tc.stateID
+ err := stateID.ValidateBasic()
+ if tc.wantErr == "" {
+ assert.NoError(t, err)
+ } else {
+ assert.ErrorContains(t, err, tc.wantErr)
}
})
}
@@ -1271,26 +1317,9 @@ func TestCommit_ValidateBasic(t *testing.T) {
},
},
ThresholdBlockSignature: make([]byte, bls12381.SignatureSize+1),
- ThresholdStateSignature: make([]byte, bls12381.SignatureSize),
},
true, "block threshold signature is wrong size",
},
- {
- "invalid state signature",
- &Commit{
- Height: 1,
- Round: 1,
- BlockID: BlockID{
- Hash: make([]byte, crypto.HashSize),
- PartSetHeader: PartSetHeader{
- Hash: make([]byte, crypto.HashSize),
- },
- },
- ThresholdBlockSignature: make([]byte, bls12381.SignatureSize),
- ThresholdStateSignature: make([]byte, bls12381.SignatureSize+1),
- },
- true, "state threshold signature is wrong size",
- },
{
"valid commit",
&Commit{
@@ -1303,7 +1332,6 @@ func TestCommit_ValidateBasic(t *testing.T) {
},
},
ThresholdBlockSignature: make([]byte, bls12381.SignatureSize),
- ThresholdStateSignature: make([]byte, bls12381.SignatureSize),
},
false, "",
},
@@ -1324,14 +1352,6 @@ func TestCommit_ValidateBasic(t *testing.T) {
}
}
-func TestStateID_WithHeight(t *testing.T) {
- stateID := RandStateID()
- height := stateID.Height
- stateIDWithHeight := stateID.WithHeight(height + 1)
-
- assert.Equal(t, height, stateIDWithHeight.Height-1)
-}
-
func TestHeaderHashVector(t *testing.T) {
chainID := "test"
h := Header{
diff --git a/types/canonical.go b/types/canonical.go
index cc1ff42d75..dabca9da7f 100644
--- a/types/canonical.go
+++ b/types/canonical.go
@@ -15,29 +15,6 @@ const TimeFormat = time.RFC3339Nano
//-----------------------------------
// Canonicalize the structs
-func CanonicalizeBlockID(bid tmproto.BlockID) *tmproto.CanonicalBlockID {
- rbid, err := BlockIDFromProto(&bid)
- if err != nil {
- panic(err)
- }
- var cbid *tmproto.CanonicalBlockID
- if rbid == nil || rbid.IsNil() {
- cbid = nil
- } else {
- cbid = &tmproto.CanonicalBlockID{
- Hash: bid.Hash,
- PartSetHeader: CanonicalizePartSetHeader(bid.PartSetHeader),
- }
- }
-
- return cbid
-}
-
-// CanonicalizeVote transforms the given PartSetHeader to a CanonicalPartSetHeader.
-func CanonicalizePartSetHeader(psh tmproto.PartSetHeader) tmproto.CanonicalPartSetHeader {
- return tmproto.CanonicalPartSetHeader(psh)
-}
-
// CanonicalizeVote transforms the given Proposal to a CanonicalProposal.
func CanonicalizeProposal(chainID string, proposal *tmproto.Proposal) tmproto.CanonicalProposal {
return tmproto.CanonicalProposal{
@@ -45,24 +22,12 @@ func CanonicalizeProposal(chainID string, proposal *tmproto.Proposal) tmproto.Ca
Height: proposal.Height, // encoded as sfixed64
Round: int64(proposal.Round), // encoded as sfixed64
POLRound: int64(proposal.PolRound),
- BlockID: CanonicalizeBlockID(proposal.BlockID),
+ BlockID: proposal.BlockID.ToCanonicalBlockID(),
Timestamp: proposal.Timestamp,
ChainID: chainID,
}
}
-// CanonicalizeVote transforms the given Vote to a CanonicalVote, which does
-// not contain ValidatorIndex and ValidatorProTxHash fields.
-func CanonicalizeVote(chainID string, vote *tmproto.Vote) tmproto.CanonicalVote {
- return tmproto.CanonicalVote{
- Type: vote.Type,
- Height: vote.Height, // encoded as sfixed64
- Round: int64(vote.Round), // encoded as sfixed64
- BlockID: CanonicalizeBlockID(vote.BlockID),
- ChainID: chainID,
- }
-}
-
// CanonicalizeVoteExtension extracts the vote extension from the given vote
// and constructs a CanonicalizeVoteExtension struct, whose representation in
// bytes is what is signed in order to produce the vote extension's signature.
diff --git a/types/canonical_test.go b/types/canonical_test.go
index 2ccb80ff71..97f50638d9 100644
--- a/types/canonical_test.go
+++ b/types/canonical_test.go
@@ -11,14 +11,25 @@ import (
func TestCanonicalizeBlockID(t *testing.T) {
randhash := tmrand.Bytes(crypto.HashSize)
- block1 := tmproto.BlockID{Hash: randhash,
- PartSetHeader: tmproto.PartSetHeader{Total: 5, Hash: randhash}}
- block2 := tmproto.BlockID{Hash: randhash,
- PartSetHeader: tmproto.PartSetHeader{Total: 10, Hash: randhash}}
- cblock1 := tmproto.CanonicalBlockID{Hash: randhash,
- PartSetHeader: tmproto.CanonicalPartSetHeader{Total: 5, Hash: randhash}}
- cblock2 := tmproto.CanonicalBlockID{Hash: randhash,
- PartSetHeader: tmproto.CanonicalPartSetHeader{Total: 10, Hash: randhash}}
+ stateID := RandStateID()
+ block1 := tmproto.BlockID{
+ Hash: randhash,
+ PartSetHeader: tmproto.PartSetHeader{Total: 5, Hash: randhash},
+ StateID: stateID.Hash(),
+ }
+ block2 := tmproto.BlockID{
+ Hash: randhash,
+ PartSetHeader: tmproto.PartSetHeader{Total: 10, Hash: randhash},
+ StateID: stateID.Hash(),
+ }
+ cblock1 := tmproto.CanonicalBlockID{
+ Hash: randhash,
+ PartSetHeader: tmproto.CanonicalPartSetHeader{Total: 5, Hash: randhash},
+ }
+ cblock2 := tmproto.CanonicalBlockID{
+ Hash: randhash,
+ PartSetHeader: tmproto.CanonicalPartSetHeader{Total: 10, Hash: randhash},
+ }
tests := []struct {
name string
@@ -31,7 +42,7 @@ func TestCanonicalizeBlockID(t *testing.T) {
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
- if got := CanonicalizeBlockID(tt.args); !reflect.DeepEqual(got, tt.want) {
+ if got := tt.args.ToCanonicalBlockID(); !reflect.DeepEqual(got, tt.want) {
t.Errorf("CanonicalizeBlockID() = %v, want %v", got, tt.want)
}
})
diff --git a/types/evidence.go b/types/evidence.go
index b081005dcc..df8f0e3e00 100644
--- a/types/evidence.go
+++ b/types/evidence.go
@@ -495,21 +495,17 @@ func NewMockDuplicateVoteEvidenceWithValidator(
panic(err)
}
- stateID := RandStateID().WithHeight(height - 1)
-
proTxHash, _ := pv.GetProTxHash(ctx)
val := NewValidator(pubKey, DefaultDashVotingPower, proTxHash, "")
voteA := makeMockVote(height, 0, 0, proTxHash, randBlockID())
vA := voteA.ToProto()
- _ = pv.SignVote(context.Background(), chainID, quorumType, quorumHash, vA, stateID, nil)
+ _ = pv.SignVote(context.Background(), chainID, quorumType, quorumHash, vA, nil)
voteA.BlockSignature = vA.BlockSignature
- voteA.StateSignature = vA.StateSignature
voteB := makeMockVote(height, 0, 0, proTxHash, randBlockID())
vB := voteB.ToProto()
- _ = pv.SignVote(ctx, chainID, quorumType, quorumHash, vB, stateID, nil)
+ _ = pv.SignVote(ctx, chainID, quorumType, quorumHash, vB, nil)
voteB.BlockSignature = vB.BlockSignature
- voteB.StateSignature = vB.StateSignature
return NewDuplicateVoteEvidence(
voteA,
voteB,
@@ -524,18 +520,14 @@ func NewMockDuplicateVoteEvidenceWithPrivValInValidatorSet(height int64, time ti
quorumHash crypto.QuorumHash) (*DuplicateVoteEvidence, error) {
proTxHash, _ := pv.GetProTxHash(context.Background())
- stateID := RandStateID().WithHeight(height - 1)
-
voteA := makeMockVote(height, 0, 0, proTxHash, randBlockID())
vA := voteA.ToProto()
- _ = pv.SignVote(context.Background(), chainID, quorumType, quorumHash, vA, stateID, nil)
+ _ = pv.SignVote(context.Background(), chainID, quorumType, quorumHash, vA, nil)
voteA.BlockSignature = vA.BlockSignature
- voteA.StateSignature = vA.StateSignature
voteB := makeMockVote(height, 0, 0, proTxHash, randBlockID())
vB := voteB.ToProto()
- _ = pv.SignVote(context.Background(), chainID, quorumType, quorumHash, vB, stateID, nil)
+ _ = pv.SignVote(context.Background(), chainID, quorumType, quorumHash, vB, nil)
voteB.BlockSignature = vB.BlockSignature
- voteB.StateSignature = vB.StateSignature
return NewDuplicateVoteEvidence(voteA, voteB, time, valSet)
}
@@ -558,5 +550,6 @@ func randBlockID() BlockID {
Total: 1,
Hash: tmrand.Bytes(crypto.HashSize),
},
+ StateID: RandStateID().Hash(),
}
}
diff --git a/types/evidence_test.go b/types/evidence_test.go
index 94a6723008..245cf06450 100644
--- a/types/evidence_test.go
+++ b/types/evidence_test.go
@@ -8,6 +8,7 @@ import (
"time"
"github.com/dashevo/dashd-go/btcjson"
+ "github.com/gogo/protobuf/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -73,15 +74,23 @@ func randomDuplicateVoteEvidence(ctx context.Context, t *testing.T) *DuplicateVo
t.Helper()
quorumHash := crypto.RandQuorumHash()
val := NewMockPVForQuorum(quorumHash)
- blockID := makeBlockID([]byte("blockhash"), 1000, []byte("partshash"))
- blockID2 := makeBlockID([]byte("blockhash2"), 1000, []byte("partshash"))
+ stateID := RandStateID()
+ blockID := makeBlockID(
+ []byte("blockhash"),
+ 1000, []byte("partshash"),
+ stateID.Hash(),
+ )
+ blockID2 := makeBlockID(
+ []byte("blockhash2"),
+ 1000, []byte("partshash"),
+ stateID.Hash(),
+ )
quorumType := btcjson.LLMQType_5_60
const chainID = "mychain"
const height = int64(10)
- stateID := RandStateID().WithHeight(height - 1)
return &DuplicateVoteEvidence{
- VoteA: makeVote(ctx, t, val, chainID, 0, height, 2, 1, quorumType, quorumHash, blockID, stateID),
- VoteB: makeVote(ctx, t, val, chainID, 0, height, 2, 1, quorumType, quorumHash, blockID2, stateID),
+ VoteA: makeVote(ctx, t, val, chainID, 0, height, 2, 1, quorumType, quorumHash, blockID),
+ VoteB: makeVote(ctx, t, val, chainID, 0, height, 2, 1, quorumType, quorumHash, blockID2),
TotalVotingPower: 3 * DefaultDashVotingPower,
ValidatorPower: DefaultDashVotingPower,
Timestamp: defaultVoteTime,
@@ -104,8 +113,19 @@ func TestDuplicateVoteEvidence(t *testing.T) {
func TestDuplicateVoteEvidenceValidation(t *testing.T) {
quorumHash := crypto.RandQuorumHash()
val := NewMockPVForQuorum(quorumHash)
- blockID := makeBlockID(crypto.Checksum([]byte("blockhash")), math.MaxInt32, crypto.Checksum([]byte("partshash")))
- blockID2 := makeBlockID(crypto.Checksum([]byte("blockhash2")), math.MaxInt32, crypto.Checksum([]byte("partshash")))
+ stateID := RandStateID()
+ blockID := makeBlockID(
+ crypto.Checksum([]byte("blockhash")),
+ math.MaxInt32,
+ crypto.Checksum([]byte("partshash")),
+ stateID.Hash(),
+ )
+ blockID2 := makeBlockID(
+ crypto.Checksum([]byte("blockhash2")),
+ math.MaxInt32,
+ crypto.Checksum([]byte("partshash")),
+ stateID.Hash(),
+ )
quorumType := btcjson.LLMQType_5_60
const chainID = "mychain"
@@ -127,8 +147,7 @@ func TestDuplicateVoteEvidenceValidation(t *testing.T) {
{"Invalid vote type", func(ev *DuplicateVoteEvidence) {
ev.VoteA = makeVote(
ctx, t, val, chainID, math.MaxInt32, math.MaxInt64, math.MaxInt32, 0, quorumType,
- quorumHash, blockID2, RandStateID().WithHeight(math.MaxInt64-1),
- )
+ quorumHash, blockID2)
}, true},
{"Invalid vote order", func(ev *DuplicateVoteEvidence) {
swap := ev.VoteA.Copy()
@@ -140,11 +159,10 @@ func TestDuplicateVoteEvidenceValidation(t *testing.T) {
tc := tc
t.Run(tc.testName, func(t *testing.T) {
const height int64 = math.MaxInt64
- stateID := RandStateID().WithHeight(height - 1)
vote1 := makeVote(ctx, t, val, chainID, math.MaxInt32, height, math.MaxInt32, 0x02, quorumType,
- quorumHash, blockID, stateID)
+ quorumHash, blockID)
vote2 := makeVote(ctx, t, val, chainID, math.MaxInt32, height, math.MaxInt32, 0x02, quorumType,
- quorumHash, blockID2, stateID)
+ quorumHash, blockID2)
thresholdPublicKey, err := val.GetThresholdPublicKey(context.Background(), quorumHash)
assert.NoError(t, err)
valSet := NewValidatorSet(
@@ -152,7 +170,12 @@ func TestDuplicateVoteEvidenceValidation(t *testing.T) {
ev, err := NewDuplicateVoteEvidence(vote1, vote2, defaultVoteTime, valSet)
require.NoError(t, err)
tc.malleateEvidence(ev)
- assert.Equal(t, tc.expectErr, ev.ValidateBasic() != nil, "Validate Basic had an unexpected result")
+ err = ev.ValidateBasic()
+ if tc.expectErr {
+ assert.Error(t, err, "Validate Basic had an unexpected result")
+ } else {
+ assert.NoError(t, err)
+ }
})
}
}
@@ -179,7 +202,6 @@ func makeVote(
quorumType btcjson.LLMQType,
quorumHash crypto.QuorumHash,
blockID BlockID,
- stateID StateID,
) *Vote {
proTxHash, err := val.GetProTxHash(ctx)
require.NoError(t, err)
@@ -193,10 +215,9 @@ func makeVote(
}
vpb := v.ToProto()
- err = val.SignVote(ctx, chainID, quorumType, quorumHash, vpb, stateID, nil)
+ err = val.SignVote(ctx, chainID, quorumType, quorumHash, vpb, nil)
require.NoError(t, err)
v.BlockSignature = vpb.BlockSignature
- v.StateSignature = vpb.StateSignature
return v
}
@@ -207,15 +228,15 @@ func TestEvidenceProto(t *testing.T) {
// -------- Votes --------
quorumHash := crypto.RandQuorumHash()
val := NewMockPVForQuorum(quorumHash)
- blockID := makeBlockID(crypto.Checksum([]byte("blockhash")), math.MaxInt32, crypto.Checksum([]byte("partshash")))
- blockID2 := makeBlockID(crypto.Checksum([]byte("blockhash2")), math.MaxInt32, crypto.Checksum([]byte("partshash")))
+ stateID := RandStateID().Hash()
+ blockID := makeBlockID(crypto.Checksum([]byte("blockhash")), math.MaxInt32, crypto.Checksum([]byte("partshash")), stateID)
+ blockID2 := makeBlockID(crypto.Checksum([]byte("blockhash2")), math.MaxInt32, crypto.Checksum([]byte("partshash")), stateID)
quorumType := btcjson.LLMQType_5_60
const chainID = "mychain"
var height int64 = math.MaxInt64
- stateID := RandStateID().WithHeight(height - 1)
- v := makeVote(ctx, t, val, chainID, math.MaxInt32, height, 1, 0x01, quorumType, quorumHash, blockID, stateID)
- v2 := makeVote(ctx, t, val, chainID, math.MaxInt32, height, 2, 0x01, quorumType, quorumHash, blockID2, stateID)
+ v := makeVote(ctx, t, val, chainID, math.MaxInt32, height, 1, 0x01, quorumType, quorumHash, blockID)
+ v2 := makeVote(ctx, t, val, chainID, math.MaxInt32, height, 2, 0x01, quorumType, quorumHash, blockID2)
tests := []struct {
testName string
@@ -259,16 +280,22 @@ func TestEvidenceVectors(t *testing.T) {
val := NewMockPVForQuorum(quorumHash)
val.ProTxHash = make([]byte, crypto.ProTxHashSize)
key := bls12381.GenPrivKeyFromSecret([]byte("it's a secret")) // deterministic key
+ ts, err := types.TimestampProto(time.Date(2022, 1, 2, 3, 4, 5, 6, time.UTC))
+ require.NoError(t, err)
+ stateID := tmproto.StateID{
+ AppVersion: StateIDVersion,
+ Height: 1,
+ AppHash: make([]byte, crypto.DefaultAppHashSize),
+ CoreChainLockedHeight: 1,
+ Time: *ts,
+ }.Hash()
val.UpdatePrivateKey(context.Background(), key, quorumHash, key.PubKey(), 10)
- blockID := makeBlockID(crypto.Checksum([]byte("blockhash")), math.MaxInt32, crypto.Checksum([]byte("partshash")))
- blockID2 := makeBlockID(crypto.Checksum([]byte("blockhash2")), math.MaxInt32, crypto.Checksum([]byte("partshash")))
+ blockID := makeBlockID(crypto.Checksum([]byte("blockhash")), math.MaxInt32, crypto.Checksum([]byte("partshash")), stateID)
+ blockID2 := makeBlockID(crypto.Checksum([]byte("blockhash2")), math.MaxInt32, crypto.Checksum([]byte("partshash")), stateID)
+
const chainID = "mychain"
- stateID := StateID{
- Height: 100,
- AppHash: make([]byte, crypto.HashSize),
- }
- v := makeVote(ctx, t, val, chainID, math.MaxInt32, math.MaxInt64, 1, 0x01, quorumType, quorumHash, blockID, stateID)
- v2 := makeVote(ctx, t, val, chainID, math.MaxInt32, math.MaxInt64, 2, 0x01, quorumType, quorumHash, blockID2, stateID)
+ v := makeVote(ctx, t, val, chainID, math.MaxInt32, math.MaxInt64, 1, 0x01, quorumType, quorumHash, blockID)
+ v2 := makeVote(ctx, t, val, chainID, math.MaxInt32, math.MaxInt64, 2, 0x01, quorumType, quorumHash, blockID2)
testCases := []struct {
testName string
@@ -277,7 +304,7 @@ func TestEvidenceVectors(t *testing.T) {
}{
{"duplicateVoteEvidence",
EvidenceList{&DuplicateVoteEvidence{VoteA: v2, VoteB: v}},
- "24d8bc379db8ef7f4406b8532df92ddebc50142bfe8518e39b3ea4a35804fb8f",
+ "610e41b91c9aaadee89241219d3000a6dfc54a5abf232264d4fda3b0d3b6f51c",
},
}
diff --git a/types/genesis.go b/types/genesis.go
index c131879e0d..38676e5875 100644
--- a/types/genesis.go
+++ b/types/genesis.go
@@ -153,7 +153,7 @@ func (genDoc *GenesisDoc) SaveAs(file string) error {
return err
}
- return os.WriteFile(file, genDocBytes, 0644) // nolint:gosec
+ return os.WriteFile(file, genDocBytes, 0644) //nolint:gosec
}
// ValidatorHash returns the hash of the validator set contained in the GenesisDoc
@@ -218,9 +218,9 @@ func (genDoc *GenesisDoc) ValidateAndComplete() error {
if lenVals > 0 && len(genDoc.ThresholdPublicKey.Bytes()) != bls12381.PubKeySize {
return fmt.Errorf("the threshold public key must be 48 bytes for BLS")
}
- if lenVals > 0 && len(genDoc.QuorumHash.Bytes()) < crypto.SmallAppHashSize {
- return fmt.Errorf("the quorum hash must be base64-encoded and at least %d bytes long, is %d bytes (%d Validator(s))",
- crypto.SmallAppHashSize,
+ if lenVals > 0 && len(genDoc.QuorumHash.Bytes()) != crypto.QuorumHashSize {
+ return fmt.Errorf("the quorum hash must be base64-encoded and %d bytes long, is %d bytes (%d Validator(s))",
+ crypto.QuorumHashSize,
len(genDoc.QuorumHash.Bytes()),
len(genDoc.Validators))
}
diff --git a/types/genesis_test.go b/types/genesis_test.go
index 86a2049209..49174a23fb 100644
--- a/types/genesis_test.go
+++ b/types/genesis_test.go
@@ -120,7 +120,7 @@ func TestGenesisBad(t *testing.T) {
"pro_tx_hash":"51BF39CC1F41B9FC63DFA5B1EDF3F0CA3AD5CAFAE4B12B4FE9263B08BB50C45F"
}],
"threshold_public_key":{"type": "tendermint/PubKeyBLS12381","value":"F5BjXeh0DppqaxX7a3LzoWr6CXPZcZeba6VHYdbiUCxQ23b00mFD8FRZpCz9Ug1E"}
- }`), "the quorum hash must be base64-encoded and at least 20 bytes long"},
+ }`), "the quorum hash must be base64-encoded and 32 bytes long"},
{ // quorum_hash too short
[]byte(`{
"genesis_time": "0001-01-01T00:00:00Z",
@@ -136,7 +136,7 @@ func TestGenesisBad(t *testing.T) {
}],
"threshold_public_key":{"type": "tendermint/PubKeyBLS12381","value":"F5BjXeh0DppqaxX7a3LzoWr6CXPZcZeba6VHYdbiUCxQ23b00mFD8FRZpCz9Ug1E"},
"quorum_hash": "MDEyMzQ1Njc4OTAxMjM0NTY3OA=="
- }`), "the quorum hash must be base64-encoded and at least 20 bytes long, is 19 byte"},
+ }`), "the quorum hash must be base64-encoded and 32 bytes long, is 19 byte"},
{ // validator power is not an int
jsonBlob: []byte(`{
"chain_id":"mychain",
diff --git a/types/light.go b/types/light.go
index c1496d2416..0197a41294 100644
--- a/types/light.go
+++ b/types/light.go
@@ -48,10 +48,12 @@ func (lb LightBlock) ValidateBasic(chainID string) error {
if err := lb.ValidatorSet.ValidateBasic(); err != nil {
return fmt.Errorf("invalid validator set: %w", err)
}
+
// Validate StateID height
- if lb.Commit.StateID.Height != lb.Height {
- return fmt.Errorf("invalid commit stateID height %d for light block height %d",
- lb.Commit.StateID.Height, lb.Height)
+ stateID := lb.StateID().Hash()
+
+ if !lb.Commit.BlockID.StateID.Equal(stateID) {
+ return fmt.Errorf("invalid commit state id hash %X != %X for light block", lb.Commit.BlockID.StateID, stateID)
}
// make sure the validator set is consistent with the header
@@ -65,12 +67,11 @@ func (lb LightBlock) ValidateBasic(chainID string) error {
}
// StateID() returns StateID for a given light block
-func (lb LightBlock) StateID() StateID {
- if lb.Commit == nil {
- panic("Cannot read state of a block without commit")
+func (lb LightBlock) StateID() tmproto.StateID {
+ if lb.SignedHeader == nil || lb.SignedHeader.Header == nil {
+ panic("Cannot read state of a block without header")
}
-
- return lb.Commit.StateID.Copy()
+ return lb.SignedHeader.Header.StateID()
}
// String returns a string representation of the LightBlock
diff --git a/types/light_test.go b/types/light_test.go
index e9ac747267..72a275bc4b 100644
--- a/types/light_test.go
+++ b/types/light_test.go
@@ -3,7 +3,7 @@ package types
import (
"context"
"math"
- "reflect"
+ "math/rand"
"testing"
"time"
@@ -18,10 +18,9 @@ func TestLightBlockValidateBasic(t *testing.T) {
defer cancel()
header := MakeRandHeader()
- stateID := RandStateID()
- commit := randCommit(ctx, t, stateID)
+ height := header.Height
+ commit := randCommit(ctx, t, header.Height, header.StateID())
vals, _ := RandValidatorSet(5)
- header.Height = commit.Height
header.LastBlockID = commit.BlockID
header.ValidatorsHash = vals.Hash()
header.Version.Block = version.BlockProtocol
@@ -39,34 +38,57 @@ func TestLightBlockValidateBasic(t *testing.T) {
name string
sh *SignedHeader
vals *ValidatorSet
- expectErr bool
+ expectErr string
}{
- {"valid light block", sh, vals, false},
- {"hashes don't match", sh, vals2, true},
- {"invalid validator set", sh, vals3, true},
- {"invalid signed header", &SignedHeader{Header: &header, Commit: randCommit(ctx, t, stateID)}, vals, true},
+ {
+ name: "valid light block",
+ sh: sh,
+ vals: vals,
+ },
+ {
+ name: "hashes don't match",
+ sh: sh,
+ vals: vals2,
+ expectErr: "expected validator hash of header to match validator set hash",
+ },
+ {
+ name: "invalid validator set",
+ sh: sh,
+ vals: vals3,
+ expectErr: "invalid validator set",
+ },
+ {
+ name: "invalid signed header",
+ sh: &SignedHeader{
+ Header: &header,
+ Commit: randCommit(ctx, t, height, header.StateID()),
+ },
+ vals: vals,
+ expectErr: "invalid signed header: commit signs block",
+ },
}
for _, tc := range testCases {
- lightBlock := LightBlock{
- SignedHeader: tc.sh,
- ValidatorSet: tc.vals,
- }
- err := lightBlock.ValidateBasic(header.ChainID)
- if tc.expectErr {
- assert.Error(t, err, tc.name)
- } else {
- assert.NoError(t, err, tc.name)
- }
+ t.Run(tc.name, func(t *testing.T) {
+ lightBlock := LightBlock{
+ SignedHeader: tc.sh,
+ ValidatorSet: tc.vals,
+ }
+ err := lightBlock.ValidateBasic(header.ChainID)
+ if tc.expectErr != "" {
+ assert.ErrorContains(t, err, tc.expectErr, tc.name)
+ } else {
+ assert.NoError(t, err, tc.name)
+ }
+ })
}
-
}
func TestLightBlockProtobuf(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
header := MakeRandHeader()
- commit := randCommit(ctx, t, RandStateID())
+ commit := randCommit(ctx, t, header.Height, RandStateID())
vals, _ := RandValidatorSet(5)
header.Height = commit.Height
header.LastBlockID = commit.BlockID
@@ -121,8 +143,8 @@ func TestLightBlockProtobuf(t *testing.T) {
func TestSignedHeaderValidateBasic(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
-
- commit := randCommit(ctx, t, RandStateID())
+ height := rand.Int63()
+ commit := randCommit(ctx, t, height, RandStateID())
chainID := "𠜎"
timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC)
@@ -176,49 +198,3 @@ func TestSignedHeaderValidateBasic(t *testing.T) {
})
}
}
-
-func TestLightBlock_StateID(t *testing.T) {
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- tests := []struct {
- name string
- commit *Commit
- want StateID
- shouldPanic bool
- }{
- {
- "State ID OK",
- randCommit(ctx, t, StateID{12, []byte("12345678901234567890123456789012")}),
- StateID{12, []byte("12345678901234567890123456789012")},
- false,
- },
- {
- "Short app hash",
- randCommit(ctx, t, StateID{12, []byte("12345678901234567890")}),
- StateID{12, []byte("12345678901234567890")},
- false,
- },
- {
- "Nil app hash",
- randCommit(ctx, t, StateID{12, nil}),
- StateID{12, []byte{}},
- false,
- },
- }
- // nolint:scopelint
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- lb := LightBlock{
- SignedHeader: &SignedHeader{Commit: tt.commit},
- }
- if got := lb.StateID(); !reflect.DeepEqual(got, tt.want) {
- t.Errorf("LightBlock.StateID() = %v, want %v", got, tt.want)
- }
- })
- }
-}
-func TestLightBlock_StateID_nocommit(t *testing.T) {
- lb := LightBlock{}
- assert.Panics(t, func() { lb.StateID() })
-}
diff --git a/types/part_set.go b/types/part_set.go
index d9341b61ff..9bf36279f7 100644
--- a/types/part_set.go
+++ b/types/part_set.go
@@ -145,12 +145,6 @@ func PartSetHeaderFromProto(ppsh *tmproto.PartSetHeader) (*PartSetHeader, error)
return psh, psh.ValidateBasic()
}
-// ProtoPartSetHeaderIsZero is similar to the IsZero function for
-// PartSetHeader, but for the Protobuf representation.
-func ProtoPartSetHeaderIsZero(ppsh *tmproto.PartSetHeader) bool {
- return ppsh.Total == 0 && len(ppsh.Hash) == 0
-}
-
//-------------------------------------
type PartSet struct {
diff --git a/types/priv_validator.go b/types/priv_validator.go
index bf06254b18..e7c01e0ffa 100644
--- a/types/priv_validator.go
+++ b/types/priv_validator.go
@@ -51,7 +51,7 @@ type PrivValidator interface {
SignVote(
ctx context.Context, chainID string, quorumType btcjson.LLMQType, quorumHash crypto.QuorumHash,
- vote *tmproto.Vote, stateID StateID, logger log.Logger) error
+ vote *tmproto.Vote, logger log.Logger) error
SignProposal(
ctx context.Context, chainID string, quorumType btcjson.LLMQType, quorumHash crypto.QuorumHash,
proposal *tmproto.Proposal) (tmbytes.HexBytes, error)
@@ -249,7 +249,6 @@ func (pv *MockPV) SignVote(
quorumType btcjson.LLMQType,
quorumHash crypto.QuorumHash,
vote *tmproto.Vote,
- stateID StateID,
logger log.Logger) error {
pv.mtx.Lock()
defer pv.mtx.Unlock()
@@ -272,15 +271,6 @@ func (pv *MockPV) SignVote(
}
vote.BlockSignature = blockSignature
- if vote.BlockID.Hash != nil {
- stateSignID := stateID.SignID(useChainID, quorumType, quorumHash)
- stateSignature, err := privKey.SignDigest(stateSignID)
- if err != nil {
- return err
- }
- vote.StateSignature = stateSignature
- }
-
if vote.Type != tmproto.PrecommitType {
if len(vote.VoteExtensions) > 0 {
return errors.New("unexpected vote extension - vote extensions are only allowed in precommits")
@@ -398,7 +388,7 @@ func (pv *ErroringMockPV) GetPubKey(ctx context.Context, quorumHash crypto.Quoru
// SignVote Implements PrivValidator.
func (pv *ErroringMockPV) SignVote(
ctx context.Context, chainID string, quorumType btcjson.LLMQType, quorumHash crypto.QuorumHash,
- vote *tmproto.Vote, stateID StateID, logger log.Logger) error {
+ vote *tmproto.Vote, logger log.Logger) error {
return ErroringMockPVErr
}
diff --git a/types/proposal_test.go b/types/proposal_test.go
index d398b61dc2..e7d59f69fc 100644
--- a/types/proposal_test.go
+++ b/types/proposal_test.go
@@ -9,6 +9,7 @@ import (
"github.com/dashevo/dashd-go/btcjson"
"github.com/gogo/protobuf/proto"
+ "github.com/gogo/protobuf/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -27,11 +28,25 @@ func getTestProposal(t testing.TB) *Proposal {
stamp, err := time.Parse(TimeFormat, "2018-02-11T07:09:22.765Z")
require.NoError(t, err)
+ ts, err := types.TimestampProto(stamp)
+ require.NoError(t, err)
+
+ stateID := tmproto.StateID{
+ AppVersion: StateIDVersion,
+ Height: 12345,
+ AppHash: []byte("12345678901234567890123456789012"),
+ CoreChainLockedHeight: math.MaxUint32,
+ Time: *ts,
+ }
+
return &Proposal{
Height: 12345,
Round: 23456,
- BlockID: BlockID{Hash: []byte("--June_15_2020_amino_was_removed"),
- PartSetHeader: PartSetHeader{Total: 111, Hash: []byte("--June_15_2020_amino_was_removed")}},
+ BlockID: BlockID{
+ Hash: []byte("--June_15_2020_amino_was_removed"),
+ PartSetHeader: PartSetHeader{Total: 111, Hash: []byte("--June_15_2020_amino_was_removed")},
+ StateID: stateID.Hash(),
+ },
POLRound: -1,
Timestamp: stamp,
@@ -51,10 +66,8 @@ func TestProposalSignable(t *testing.T) {
func TestProposalString(t *testing.T) {
str := getTestProposal(t).String()
- expected := `Proposal{12345/23456 (2D2D4A756E655F31355F323032305F616D696E6F5F7761735F72656D6F766564:111:2D2D4A756E65, -1) 000000000000 @ 2018-02-11T07:09:22.765Z}`
- if str != expected {
- t.Errorf("got unexpected string for Proposal. Expected:\n%v\nGot:\n%v", expected, str)
- }
+ expected := `Proposal{12345/23456 (2D2D4A756E655F31355F323032305F616D696E6F5F7761735F72656D6F766564:111:2D2D4A756E65:D8A08898004B, -1) 000000000000 @ 2018-02-11T07:09:22.765Z}`
+ assert.Equal(t, expected, str)
}
func TestProposalVerifySignature(t *testing.T) {
@@ -68,7 +81,11 @@ func TestProposalVerifySignature(t *testing.T) {
prop := NewProposal(
4, 1, 2, 2,
- BlockID{tmrand.Bytes(crypto.HashSize), PartSetHeader{777, tmrand.Bytes(crypto.HashSize)}},
+ BlockID{
+ tmrand.Bytes(crypto.HashSize),
+ PartSetHeader{777, tmrand.Bytes(crypto.HashSize)},
+ RandStateID().Hash(),
+ },
tmtime.Now(),
)
p := prop.ToProto()
@@ -211,7 +228,10 @@ func TestProposalValidateBasic(t *testing.T) {
{"Invalid Round", func(p *Proposal) { p.Round = -1 }, true},
{"Invalid POLRound", func(p *Proposal) { p.POLRound = -2 }, true},
{"Invalid BlockId", func(p *Proposal) {
- p.BlockID = BlockID{[]byte{1, 2, 3}, PartSetHeader{111, []byte("blockparts")}}
+ p.BlockID = BlockID{
+ []byte{1, 2, 3},
+ PartSetHeader{111, []byte("blockparts")},
+ RandStateID().Hash()}
}, true},
{"Invalid Signature", func(p *Proposal) {
p.Signature = make([]byte, 0)
@@ -220,7 +240,12 @@ func TestProposalValidateBasic(t *testing.T) {
p.Signature = make([]byte, SignatureSize+1)
}, true},
}
- blockID := makeBlockID(crypto.Checksum([]byte("blockhash")), math.MaxInt32, crypto.Checksum([]byte("partshash")))
+ blockID := makeBlockID(
+ crypto.Checksum([]byte("blockhash")),
+ math.MaxInt32,
+ crypto.Checksum([]byte("partshash")),
+ nil,
+ )
for _, tc := range testCases {
tc := tc
@@ -242,7 +267,19 @@ func TestProposalValidateBasic(t *testing.T) {
}
func TestProposalProtoBuf(t *testing.T) {
- proposal := NewProposal(1, 1, 2, 3, makeBlockID([]byte("hash"), 2, []byte("part_set_hash")), tmtime.Now())
+ proposal := NewProposal(
+ 1,
+ 1,
+ 2,
+ 3,
+ makeBlockID(
+ crypto.Checksum([]byte("hash")),
+ 2,
+ crypto.Checksum([]byte("part_set_hash")),
+ nil,
+ ),
+ tmtime.Now(),
+ )
proposal.Signature = []byte("sig")
proposal2 := NewProposal(1, 1, 2, 3, BlockID{}, tmtime.Now())
diff --git a/types/quorum.go b/types/quorum.go
index 11df51bf4b..a8a66a86f7 100644
--- a/types/quorum.go
+++ b/types/quorum.go
@@ -18,14 +18,12 @@ type CommitSigns struct {
func (c *CommitSigns) CopyToCommit(commit *Commit) {
commit.QuorumHash = c.QuorumHash
commit.ThresholdBlockSignature = c.BlockSign
- commit.ThresholdStateSignature = c.StateSign
commit.ThresholdVoteExtensions = c.ExtensionSigns
}
// QuorumSigns holds all created signatures, block, state and for each recovered vote-extensions
type QuorumSigns struct {
BlockSign []byte
- StateSign []byte
ExtensionSigns []ThresholdExtensionSign
}
@@ -33,7 +31,6 @@ type QuorumSigns struct {
func NewQuorumSignsFromCommit(commit *Commit) QuorumSigns {
return QuorumSigns{
BlockSign: commit.ThresholdBlockSignature,
- StateSign: commit.ThresholdStateSignature,
ExtensionSigns: commit.ThresholdVoteExtensions,
}
}
@@ -112,7 +109,6 @@ func MakeThresholdVoteExtensions(extensions []VoteExtension, thresholdSigs [][]b
type QuorumSingsVerifier struct {
QuorumSignData
shouldVerifyBlock bool
- shouldVerifyState bool
shouldVerifyVoteExtensions bool
logger log.Logger
}
@@ -131,18 +127,10 @@ func WithVerifyBlock(shouldVerify bool) func(*QuorumSingsVerifier) {
}
}
-// WithVerifyState sets a flag that tells QuorumSingsVerifier to verify stateID signature or not
-func WithVerifyState(shouldVerify bool) func(*QuorumSingsVerifier) {
- return func(verifier *QuorumSingsVerifier) {
- verifier.shouldVerifyState = shouldVerify
- }
-}
-
// WithVerifyReachedQuorum sets a flag that tells QuorumSingsVerifier to verify
// vote-extension and stateID signatures or not
func WithVerifyReachedQuorum(quorumReached bool) func(*QuorumSingsVerifier) {
return func(verifier *QuorumSingsVerifier) {
- verifier.shouldVerifyState = quorumReached
verifier.shouldVerifyVoteExtensions = quorumReached
}
}
@@ -160,7 +148,6 @@ func NewQuorumSignsVerifier(quorumData QuorumSignData, opts ...func(*QuorumSings
verifier := &QuorumSingsVerifier{
QuorumSignData: quorumData,
shouldVerifyBlock: true,
- shouldVerifyState: true,
shouldVerifyVoteExtensions: true,
logger: log.NewNopLogger(),
}
@@ -176,10 +163,6 @@ func (q *QuorumSingsVerifier) Verify(pubKey crypto.PubKey, signs QuorumSigns) er
if err != nil {
return err
}
- err = q.verifyState(pubKey, signs)
- if err != nil {
- return err
- }
return q.verifyVoteExtensions(pubKey, signs)
}
@@ -198,22 +181,6 @@ func (q *QuorumSingsVerifier) verifyBlock(pubKey crypto.PubKey, signs QuorumSign
return nil
}
-func (q *QuorumSingsVerifier) verifyState(pubKey crypto.PubKey, signs QuorumSigns) error {
- if !q.shouldVerifyState {
- return nil
- }
- if !pubKey.VerifySignatureDigest(q.State.ID, signs.StateSign) {
- return fmt.Errorf(
- "threshold state signature is invalid: (raw=%X, signID=%X, pubkey=%s): %w",
- q.State.Raw,
- q.State.ID,
- pubKey.HexString(),
- ErrVoteInvalidStateSignature,
- )
- }
- return nil
-}
-
func (q *QuorumSingsVerifier) verifyVoteExtensions(
pubKey crypto.PubKey,
signs QuorumSigns,
diff --git a/types/quorum_sign_data.go b/types/quorum_sign_data.go
index ff3756fa4e..272b4401a4 100644
--- a/types/quorum_sign_data.go
+++ b/types/quorum_sign_data.go
@@ -19,7 +19,6 @@ var (
// QuorumSignData holds data which is necessary for signing and verification block, state, and each vote-extension in a list
type QuorumSignData struct {
Block SignItem
- State SignItem
Extensions map[types.VoteExtensionType][]SignItem
}
@@ -58,10 +57,6 @@ func MakeQuorumSignsWithVoteSet(voteSet *VoteSet, vote *types.Vote) (QuorumSignD
voteSet.valSet.QuorumType,
voteSet.valSet.QuorumHash,
vote,
- StateID{
- Height: vote.Height,
- AppHash: vote.AppHash,
- },
)
}
@@ -72,11 +67,9 @@ func MakeQuorumSigns(
quorumType btcjson.LLMQType,
quorumHash crypto.QuorumHash,
protoVote *types.Vote,
- stateID StateID,
) (QuorumSignData, error) {
quorumSign := QuorumSignData{
Block: MakeBlockSignItem(chainID, protoVote, quorumType, quorumHash),
- State: MakeStateSignItem(chainID, stateID, quorumType, quorumHash),
}
var err error
quorumSign.Extensions, err = MakeVoteExtensionSignItems(chainID, protoVote, quorumType, quorumHash)
@@ -89,14 +82,10 @@ func MakeQuorumSigns(
// MakeBlockSignItem creates SignItem struct for a block
func MakeBlockSignItem(chainID string, vote *types.Vote, quorumType btcjson.LLMQType, quorumHash []byte) SignItem {
reqID := voteHeightRoundRequestID("dpbvote", vote.Height, vote.Round)
- raw := VoteBlockSignBytes(chainID, vote)
- return NewSignItem(quorumType, quorumHash, reqID, raw)
-}
-
-// MakeStateSignItem creates SignItem struct for a state
-func MakeStateSignItem(chainID string, stateID StateID, quorumType btcjson.LLMQType, quorumHash []byte) SignItem {
- reqID := stateID.SignRequestID()
- raw := stateID.SignBytes(chainID)
+ raw, err := vote.SignBytes(chainID)
+ if err != nil {
+ panic(fmt.Errorf("block sign item: %w", err))
+ }
return NewSignItem(quorumType, quorumHash, reqID, raw)
}
diff --git a/types/quorum_sign_data_test.go b/types/quorum_sign_data_test.go
index e143c40677..d5d55c2f24 100644
--- a/types/quorum_sign_data_test.go
+++ b/types/quorum_sign_data_test.go
@@ -29,51 +29,23 @@ func TestMakeBlockSignID(t *testing.T) {
quorumHash: mustHexDecode("6A12D9CF7091D69072E254B297AEF15997093E480FDE295E09A7DE73B31CEEDD"),
want: newSignItem(
"C8F2E1FE35DE03AC94F76191F59CAD1BA1F7A3C63742B7125990D996315001CC",
- "CE3AA8C6C6E32F54430C703F198E7E810DFBC7680EBCB549D61B9EBE49530339",
- "1A080211E903000000000000320D646173682D706C6174666F726D",
+ "DA25B746781DDF47B5D736F30B1D9D0CC86981EEC67CBE255265C4361DEF8C2E",
+ "02000000E9030000000000000000000000000000E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B"+
+ "7852B855E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855646173682D706C6174666F726D",
),
- wantHash: mustHexDecode("4BEAC39C516BEB1FDEBC569C0468B91D999050CA47B4AA12AFA825CD4E7EDAB3"),
+ wantHash: mustHexDecode("0CA3D5F42BDFED0C4FDE7E6DE0F046CC76CDA6CEE734D65E8B2EE0E375D4C57D"),
},
}
for i, tc := range testCases {
- t.Run(fmt.Sprintf("test-case #%d", i), func(t *testing.T) {
+ t.Run(fmt.Sprintf("test-case %d", i), func(t *testing.T) {
signItem := MakeBlockSignItem(chainID, tc.vote.ToProto(), btcjson.LLMQType_5_60, tc.quorumHash)
+ t.Logf("hash %X id %X raw %X reqID %X", signItem.Hash, signItem.ID, signItem.Raw, signItem.ReqID)
require.Equal(t, tc.want, signItem)
require.Equal(t, tc.wantHash, signItem.Hash)
})
}
}
-func TestMakeStateSignID(t *testing.T) {
- const chainID = "dash-platform"
- testCases := []struct {
- stateID StateID
- quorumHash []byte
- want SignItem
- wantHash []byte
- }{
- {
- stateID: StateID{
- Height: 1001,
- AppHash: mustHexDecode("524F1D03D1D81E94A099042736D40BD9681B867321443FF58A4568E274DBD83B"),
- },
- quorumHash: mustHexDecode("6A12D9CF7091D69072E254B297AEF15997093E480FDE295E09A7DE73B31CEEDD"),
- want: newSignItem(
- "76D44F9A90D4B7974B3F6CA1A36D203F5163BCDE4A62095E5A0BF65AC94C35C0",
- "8DE1C69FE4F9E89E7BAB5329CF97BD109ECD4E2D04F0B1B41653B1F02A765BA8",
- "E903000000000000524F1D03D1D81E94A099042736D40BD9681B867321443FF58A4568E274DBD83B",
- ),
- wantHash: mustHexDecode("85944D1C7755EDCDA86815CC69CF3961E5AAC5F6CB214B256EA5907195603ED4"),
- },
- }
- for i, tc := range testCases {
- t.Run(fmt.Sprintf("test-case #%d", i), func(t *testing.T) {
- signItem := MakeStateSignItem(chainID, tc.stateID, btcjson.LLMQType_5_60, tc.quorumHash)
- require.Equal(t, tc.want, signItem)
- })
- }
-}
-
func TestMakeVoteExtensionSignsData(t *testing.T) {
const chainID = "dash-platform"
testCases := []struct {
diff --git a/types/signs_recoverer.go b/types/signs_recoverer.go
index 53733ddc1d..77a4088ba5 100644
--- a/types/signs_recoverer.go
+++ b/types/signs_recoverer.go
@@ -44,7 +44,6 @@ func (v *SignsRecoverer) Recover() (*QuorumSigns, error) {
thresholdSigns := &QuorumSigns{}
recoverFuncs := []func(signs *QuorumSigns) error{
v.recoverBlockSig,
- v.recoverStateSig,
v.recoverVoteExtensionSigs,
}
for _, fn := range recoverFuncs {
@@ -71,7 +70,6 @@ func (v *SignsRecoverer) addVoteSigs(vote *Vote) {
return
}
v.blockSigs = append(v.blockSigs, vote.BlockSignature)
- v.stateSigs = append(v.stateSigs, vote.StateSignature)
v.validatorProTxHashes = append(v.validatorProTxHashes, vote.ValidatorProTxHash)
v.addVoteExtensions(vote.VoteExtensions)
}
@@ -87,18 +85,6 @@ func (v *SignsRecoverer) addVoteExtensions(voteExtensions VoteExtensions) {
}
}
-func (v *SignsRecoverer) recoverStateSig(thresholdSigns *QuorumSigns) error {
- if !v.quorumReached {
- return nil
- }
- var err error
- thresholdSigns.StateSign, err = bls12381.RecoverThresholdSignatureFromShares(v.stateSigs, v.validatorProTxHashes)
- if err != nil {
- return fmt.Errorf("error recovering threshold state sig: %w", err)
- }
- return nil
-}
-
func (v *SignsRecoverer) recoverBlockSig(thresholdSigns *QuorumSigns) error {
var err error
thresholdSigns.BlockSign, err = bls12381.RecoverThresholdSignatureFromShares(v.blockSigs, v.validatorProTxHashes)
diff --git a/types/signs_recoverer_test.go b/types/signs_recoverer_test.go
index 8463b7f730..0df694e287 100644
--- a/types/signs_recoverer_test.go
+++ b/types/signs_recoverer_test.go
@@ -19,8 +19,7 @@ func TestSigsRecoverer(t *testing.T) {
height = 1000
chainID = "dash-platform"
)
- stateID := RandStateID().WithHeight(height - 1)
- blockID := makeBlockID([]byte("blockhash"), 1000, []byte("partshash"))
+ blockID := makeBlockID([]byte("blockhash"), 1000, []byte("partshash"), nil)
quorumType := crypto.SmallQuorumType()
quorumHash := crypto.RandQuorumHash()
testCases := []struct {
@@ -59,7 +58,7 @@ func TestSigsRecoverer(t *testing.T) {
for i, vote := range tc.votes {
protoVote := vote.ToProto()
pvs[i] = NewMockPV(GenKeysForQuorumHash(quorumHash), UseProTxHash(vote.ValidatorProTxHash))
- err := pvs[i].SignVote(ctx, chainID, quorumType, quorumHash, protoVote, stateID, nil)
+ err := pvs[i].SignVote(ctx, chainID, quorumType, quorumHash, protoVote, nil)
require.NoError(t, err)
err = vote.PopulateSignsFromProto(protoVote)
require.NoError(t, err)
@@ -69,7 +68,7 @@ func TestSigsRecoverer(t *testing.T) {
IDs = append(IDs, vote.ValidatorProTxHash)
}
- quorumSigns, err := MakeQuorumSigns(chainID, quorumType, quorumHash, tc.votes[0].ToProto(), stateID)
+ quorumSigns, err := MakeQuorumSigns(chainID, quorumType, quorumHash, tc.votes[0].ToProto())
require.NoError(t, err)
thresholdPubKey, err := bls12381.RecoverThresholdPublicKeyFromPublicKeys(pubKeys, IDs)
@@ -92,8 +91,7 @@ func TestSigsRecoverer_UsingVoteSet(t *testing.T) {
height = 1000
n = 4
)
- stateID := RandStateID().WithHeight(height)
- blockID := makeBlockID([]byte("blockhash"), 1000, []byte("partshash"))
+ blockID := makeBlockID([]byte("blockhash"), 1000, []byte("partshash"), nil)
vals, pvs := RandValidatorSet(n)
quorumType := crypto.SmallQuorumType()
quorumHash, err := pvs[0].GetFirstQuorumHash(ctx)
@@ -109,14 +107,13 @@ func TestSigsRecoverer_UsingVoteSet(t *testing.T) {
Round: 0,
Type: tmproto.PrecommitType,
BlockID: blockID,
- AppHash: stateID.AppHash,
VoteExtensions: mockVoteExtensions(t,
tmproto.VoteExtensionType_DEFAULT, "default",
tmproto.VoteExtensionType_THRESHOLD_RECOVER, "threshold",
),
}
vpb := votes[i].ToProto()
- err = pvs[i].SignVote(ctx, chainID, quorumType, quorumHash, vpb, stateID, nil)
+ err = pvs[i].SignVote(ctx, chainID, quorumType, quorumHash, vpb, nil)
require.NoError(t, err)
err = votes[i].PopulateSignsFromProto(vpb)
require.NoError(t, err)
diff --git a/types/stateid.go b/types/stateid.go
deleted file mode 100644
index b77b5fe0de..0000000000
--- a/types/stateid.go
+++ /dev/null
@@ -1,160 +0,0 @@
-package types
-
-import (
- "bytes"
- "crypto/sha256"
- "encoding/binary"
- "errors"
- "fmt"
- "strconv"
-
- "github.com/dashevo/dashd-go/btcjson"
-
- "github.com/tendermint/tendermint/crypto"
- tmbytes "github.com/tendermint/tendermint/libs/bytes"
- tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
-)
-
-// This file contains implementation of StateID logic.
-
-//--------------------------------------------------------------------------------
-
-// StateID
-// TODO: Move to separate file
-type StateID struct {
- // Height of current block (the one containing state ID signature)
- Height int64 `json:"height"`
- // AppHash used in current block (the one containing state ID signature)
- AppHash tmbytes.HexBytes `json:"last_app_hash"`
-}
-
-// Copy returns new StateID that is equal to this one
-func (stateID StateID) Copy() StateID {
- appHash := make([]byte, len(stateID.AppHash))
- if copy(appHash, stateID.AppHash) != len(stateID.AppHash) {
- panic("Cannot copy LastAppHash, this should never happen. Out of memory???")
- }
-
- return StateID{
- Height: stateID.Height,
- AppHash: appHash,
- }
-}
-
-// Equals returns true if the StateID matches the given StateID
-func (stateID StateID) Equals(other StateID) bool {
- return stateID.Height == other.Height &&
- bytes.Equal(stateID.AppHash, other.AppHash)
-}
-
-// Key returns a machine-readable string representation of the StateID
-func (stateID StateID) Key() string {
- return strconv.FormatInt(stateID.Height, 36) + string(stateID.AppHash)
-}
-
-// ValidateBasic performs basic validation.
-func (stateID StateID) ValidateBasic() error {
- // LastAppHash can be empty in case of genesis block.
- if err := ValidateAppHash(stateID.AppHash); err != nil {
- return fmt.Errorf("wrong app Hash")
- }
-
- if stateID.Height < 0 {
- return fmt.Errorf("stateID height is not valid: %d < 0", stateID.Height)
- }
-
- return nil
-}
-
-// SignBytes returns bytes that should be signed
-// TODO why we don't simply use stateID.Marshal() ?
-func (stateID StateID) SignBytes(chainID string) []byte {
- bz := make([]byte, 8)
- binary.LittleEndian.PutUint64(bz, uint64(stateID.Height))
-
- appHash := stateID.AppHash
- if len(appHash) == 0 {
- appHash = make([]byte, crypto.DefaultAppHashSize)
- }
-
- bz = append(bz, appHash...)
- return bz
-}
-
-// SignID returns signing session data that will be signed to get threshold signature share.
-// See DIP-0007
-func (stateID StateID) SignID(chainID string, quorumType btcjson.LLMQType, quorumHash []byte) []byte {
-
- stateSignBytes := stateID.SignBytes(chainID)
-
- if stateSignBytes == nil {
- return nil
- }
-
- stateMessageHash := sha256.Sum256(stateSignBytes)
-
- stateRequestID := stateID.SignRequestID()
-
- stateSignID := crypto.SignID(
- quorumType,
- tmbytes.Reverse(quorumHash),
- tmbytes.Reverse(stateRequestID),
- tmbytes.Reverse(stateMessageHash[:]),
- )
-
- return stateSignID
-
-}
-
-func (stateID StateID) SignRequestID() []byte {
- requestIDMessage := []byte("dpsvote")
- heightByteArray := make([]byte, 8)
-
- binary.LittleEndian.PutUint64(heightByteArray, uint64(stateID.Height))
-
- requestIDMessage = append(requestIDMessage, heightByteArray...)
-
- hash := sha256.Sum256(requestIDMessage)
- return hash[:]
-}
-
-// String returns a human readable string representation of the StateID.
-//
-// 1. hash
-//
-func (stateID StateID) String() string {
- return fmt.Sprintf(`%d:%v`, stateID.Height, stateID.AppHash)
-}
-
-// ToProto converts StateID to protobuf
-func (stateID StateID) ToProto() tmproto.StateID {
- return tmproto.StateID{
- AppHash: stateID.AppHash,
- Height: stateID.Height,
- }
-}
-
-// WithHeight returns new copy of stateID with height set to provided value.
-// It is a convenience method used in tests.
-// Note that this is Last Height from state, so it will be (height-1) for Vote.
-func (stateID StateID) WithHeight(height int64) StateID {
- ret := stateID.Copy()
- ret.Height = height
-
- return ret
-}
-
-// FromProto sets a protobuf BlockID to the given pointer.
-// It returns an error if the block id is invalid.
-func StateIDFromProto(sID *tmproto.StateID) (*StateID, error) {
- if sID == nil {
- return nil, errors.New("nil StateID")
- }
-
- stateID := new(StateID)
-
- stateID.AppHash = sID.AppHash
- stateID.Height = sID.Height
-
- return stateID, stateID.ValidateBasic()
-}
diff --git a/types/test_util.go b/types/test_util.go
index c0e085a363..bf045e2027 100644
--- a/types/test_util.go
+++ b/types/test_util.go
@@ -5,22 +5,28 @@ import (
"fmt"
"math/rand"
+ gogotypes "github.com/gogo/protobuf/types"
+
"github.com/tendermint/tendermint/crypto"
tmrand "github.com/tendermint/tendermint/libs/rand"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
)
-func RandStateID() StateID {
- return StateID{
- Height: rand.Int63(), // nolint:gosec
- AppHash: tmrand.Bytes(crypto.HashSize),
+const StateIDVersion = 1
+
+func RandStateID() tmproto.StateID {
+ return tmproto.StateID{
+ Height: uint64(rand.Int63()), //nolint:gosec
+ AppHash: tmrand.Bytes(crypto.DefaultAppHashSize),
+ AppVersion: StateIDVersion,
+ CoreChainLockedHeight: rand.Uint32(), //nolint:gosec
+ Time: *gogotypes.TimestampNow(),
}
}
func makeCommit(
ctx context.Context,
blockID BlockID,
- stateID StateID,
height int64,
round int32,
voteSet *VoteSet,
@@ -40,7 +46,6 @@ func makeCommit(
Round: round,
Type: tmproto.PrecommitType,
BlockID: blockID,
- AppHash: stateID.AppHash,
VoteExtensions: VoteExtensions{
tmproto.VoteExtensionType_DEFAULT: []VoteExtension{{Extension: []byte("default")}},
tmproto.VoteExtensionType_THRESHOLD_RECOVER: []VoteExtension{{Extension: []byte("threshold")}},
@@ -58,15 +63,9 @@ func makeCommit(
// signAddVote signs a vote using StateID configured inside voteSet, and adds it to that voteSet
func signAddVote(ctx context.Context, privVal PrivValidator, vote *Vote, voteSet *VoteSet) (signed bool, err error) {
- stateID := vote.StateID()
- return signAddVoteForStateID(ctx, privVal, vote, voteSet, stateID)
-}
-
-func signAddVoteForStateID(ctx context.Context, privVal PrivValidator, vote *Vote, voteSet *VoteSet,
- stateID StateID) (signed bool, err error) {
v := vote.ToProto()
err = privVal.SignVote(ctx, voteSet.ChainID(), voteSet.valSet.QuorumType, voteSet.valSet.QuorumHash,
- v, stateID, nil)
+ v, nil)
if err != nil {
return false, err
}
diff --git a/types/utils.go b/types/utils.go
index cec47e2028..60e82fe3fd 100644
--- a/types/utils.go
+++ b/types/utils.go
@@ -4,9 +4,9 @@ import "reflect"
// Go lacks a simple and safe way to see if something is a typed nil.
// See:
-// - https://dave.cheney.net/2017/08/09/typed-nils-in-go-2
-// - https://groups.google.com/forum/#!topic/golang-nuts/wnH302gBa4I/discussion
-// - https://github.com/golang/go/issues/21538
+// - https://dave.cheney.net/2017/08/09/typed-nils-in-go-2
+// - https://groups.google.com/forum/#!topic/golang-nuts/wnH302gBa4I/discussion
+// - https://github.com/golang/go/issues/21538
func isTypedNil(o interface{}) bool {
rv := reflect.ValueOf(o)
switch rv.Kind() {
diff --git a/types/validation.go b/types/validation.go
index 0bdc6e1b92..ead891db87 100644
--- a/types/validation.go
+++ b/types/validation.go
@@ -20,15 +20,10 @@ func ValidateHash(h []byte) error {
return nil
}
-// ValidateAppHash returns an error if the hash is not empty, but its
-// size != tmhash.Size.
+// ValidateAppHash returns an error if the app hash size is invalid.
func ValidateAppHash(h []byte) error {
- if len(h) > 0 && (len(h) < crypto.SmallAppHashSize || len(h) > crypto.LargeAppHashSize) {
- return fmt.Errorf("expected size to be at between %d and %d bytes, got %d bytes",
- crypto.SmallAppHashSize,
- crypto.LargeAppHashSize,
- len(h),
- )
+ if len(h) != crypto.DefaultAppHashSize {
+ return fmt.Errorf("expected size to be %d bytes, got %d bytes", crypto.DefaultAppHashSize, len(h))
}
return nil
}
diff --git a/types/validation_test.go b/types/validation_test.go
index 14de6d002b..49235242a2 100644
--- a/types/validation_test.go
+++ b/types/validation_test.go
@@ -31,66 +31,65 @@ func TestValidatorSet_VerifyCommit_All(t *testing.T) {
vote.ValidatorProTxHash = proTxHash
v := vote.ToProto()
- stateID := RandStateID().WithHeight(v.Height - 1)
-
- quorumSigns, err := MakeQuorumSigns(chainID, btcjson.LLMQType_5_60, quorumHash, v, stateID)
+ quorumSigns, err := MakeQuorumSigns(chainID, btcjson.LLMQType_5_60, quorumHash, v)
require.NoError(t, err)
blockSig, err := privKey.SignDigest(quorumSigns.Block.ID)
require.NoError(t, err)
- stateSig, err := privKey.SignDigest(quorumSigns.State.ID)
- require.NoError(t, err)
vote.BlockSignature = blockSig
- vote.StateSignature = stateSig
commit := NewCommit(vote.Height,
vote.Round,
vote.BlockID,
- stateID,
&CommitSigns{
QuorumSigns: QuorumSigns{
BlockSign: blockSig,
- StateSign: stateSig,
},
QuorumHash: quorumHash,
},
)
vote2 := *vote
- blockSig2, err := privKey.SignDigest(VoteBlockSignBytes("EpsilonEridani", v))
+ signBytes, err := v.SignBytes("EpsilonEridani")
require.NoError(t, err)
- stateSig2, err := privKey.SignDigest(stateID.SignBytes("EpsilonEridani"))
+ blockSig2, err := privKey.SignDigest(signBytes)
require.NoError(t, err)
vote2.BlockSignature = blockSig2
- vote2.StateSignature = stateSig2
testCases := []struct {
description string
chainID string
blockID BlockID
- stateID StateID
height int64
commit *Commit
expErr bool
}{
- {"good", chainID, vote.BlockID, stateID, vote.Height, commit, false},
-
- {"threshold block signature is invalid", "EpsilonEridani", vote.BlockID, stateID, vote.Height, commit, true},
- {"wrong block ID", chainID, makeBlockIDRandom(), stateID, vote.Height, commit, true},
- {"wrong height", chainID, vote.BlockID, stateID, vote.Height - 1, commit, true},
-
- {"threshold block signature is invalid", chainID, vote.BlockID, stateID, vote.Height,
- NewCommit(vote.Height, vote.Round, vote.BlockID, stateID, &CommitSigns{QuorumHash: quorumHash}), true},
+ {"good", chainID, vote.BlockID, vote.Height, commit, false},
+
+ {"threshold block signature is invalid", "EpsilonEridani", vote.BlockID, vote.Height, commit, true},
+ {"wrong block ID", chainID, makeBlockIDRandom(), vote.Height, commit, true},
+ {
+ description: "invalid commit -- wrong block ID",
+ chainID: chainID,
+ blockID: BlockID{
+ Hash: vote.BlockID.Hash.Copy(),
+ PartSetHeader: vote.BlockID.PartSetHeader,
+ StateID: RandStateID().Hash(),
+ },
+ height: vote.Height,
+ commit: commit,
+ expErr: true,
+ },
+ {"wrong height", chainID, vote.BlockID, vote.Height - 1, commit, true},
- {"threshold state signature is invalid", chainID, vote.BlockID, stateID, vote.Height,
- NewCommit(vote.Height, vote.Round, vote.BlockID, stateID,
- &CommitSigns{QuorumHash: quorumHash, QuorumSigns: QuorumSigns{BlockSign: vote.BlockSignature}}), true},
+ {"threshold block signature is invalid", chainID, vote.BlockID, vote.Height,
+ NewCommit(vote.Height, vote.Round, vote.BlockID, &CommitSigns{QuorumHash: quorumHash}), true},
- {"threshold block signature is invalid", chainID, vote.BlockID, stateID, vote.Height,
- NewCommit(vote.Height, vote.Round, vote.BlockID, stateID,
+ {"threshold block signature is invalid", chainID, vote.BlockID, vote.Height,
+ NewCommit(vote.Height, vote.Round, vote.BlockID,
&CommitSigns{
QuorumHash: quorumHash,
- QuorumSigns: QuorumSigns{BlockSign: vote2.BlockSignature, StateSign: vote2.StateSignature},
+ QuorumSigns: QuorumSigns{BlockSign: vote2.BlockSignature},
},
), true},
}
@@ -98,7 +97,7 @@ func TestValidatorSet_VerifyCommit_All(t *testing.T) {
for _, tc := range testCases {
tc := tc
t.Run(tc.description, func(t *testing.T) {
- err := vset.VerifyCommit(tc.chainID, tc.blockID, tc.stateID, tc.height, tc.commit)
+ err := vset.VerifyCommit(tc.chainID, tc.blockID, tc.height, tc.commit)
if tc.expErr {
if assert.Error(t, err, "VerifyCommit") {
assert.Contains(t, err.Error(), tc.description, "VerifyCommit")
@@ -121,20 +120,18 @@ func TestValidatorSet_VerifyCommit_CheckThresholdSignatures(t *testing.T) {
h = int64(3)
)
blockID := makeBlockIDRandom()
- stateID := RandStateID().WithHeight(h)
voteSet, valSet, vals := randVoteSet(ctx, t, h, 0, tmproto.PrecommitType, 4)
- commit, err := makeCommit(ctx, blockID, stateID, h, 0, voteSet, vals)
+ commit, err := makeCommit(ctx, blockID, h, 0, voteSet, vals)
require.NoError(t, err)
// malleate threshold sigs signature
vote := voteSet.GetByIndex(3)
v := vote.ToProto()
- err = vals[3].SignVote(ctx, "CentaurusA", valSet.QuorumType, valSet.QuorumHash, v, stateID, nil)
+ err = vals[3].SignVote(ctx, "CentaurusA", valSet.QuorumType, valSet.QuorumHash, v, nil)
require.NoError(t, err)
commit.ThresholdBlockSignature = v.BlockSignature
- commit.ThresholdStateSignature = v.StateSignature
- err = valSet.VerifyCommit(chainID, blockID, stateID, h, commit)
+ err = valSet.VerifyCommit(chainID, blockID, h, commit)
if assert.Error(t, err) {
assert.Contains(t, err.Error(), "threshold block signature is invalid")
}
@@ -143,8 +140,7 @@ func TestValidatorSet_VerifyCommit_CheckThresholdSignatures(t *testing.T) {
thresholdSigns, err := recoverer.Recover()
require.NoError(t, err)
commit.ThresholdBlockSignature = thresholdSigns.BlockSign
- commit.ThresholdStateSignature = thresholdSigns.StateSign
commit.ThresholdVoteExtensions = thresholdSigns.ExtensionSigns
- err = valSet.VerifyCommit(chainID, blockID, stateID, h, commit)
+ err = valSet.VerifyCommit(chainID, blockID, h, commit)
require.NoError(t, err)
}
diff --git a/types/validator_address.go b/types/validator_address.go
index 15ba9b5a03..3fb3b6faed 100644
--- a/types/validator_address.go
+++ b/types/validator_address.go
@@ -143,7 +143,7 @@ func (va ValidatorAddress) NetAddress() (*NetAddress, error) {
// It will panic in (very unlikely) case of error.
func RandValidatorAddress() ValidatorAddress {
nodeID := tmrand.Bytes(20)
- port := rand.Int()%math.MaxUint16 + 1 // nolint
+ port := rand.Int()%math.MaxUint16 + 1 //nolint:gosec
addr, err := ParseValidatorAddress(fmt.Sprintf("tcp://%x@127.0.0.1:%d", nodeID, port))
if err != nil {
panic(fmt.Sprintf("cannot generate random validator address: %s", err))
diff --git a/types/validator_set.go b/types/validator_set.go
index c10e1778c3..d2ca78f364 100644
--- a/types/validator_set.go
+++ b/types/validator_set.go
@@ -892,7 +892,7 @@ func (vals *ValidatorSet) UpdateWithChangeSet(
// application that depends on the LastCommitInfo sent in BeginBlock, which
// includes which validators signed. For instance, Gaia incentivizes proposers
// with a bonus for including more than +2/3 of the signatures.
-func (vals *ValidatorSet) VerifyCommit(chainID string, blockID BlockID, stateID StateID,
+func (vals *ValidatorSet) VerifyCommit(chainID string, blockID BlockID,
height int64, commit *Commit) error {
// Validate Height and BlockID.
@@ -904,13 +904,8 @@ func (vals *ValidatorSet) VerifyCommit(chainID string, blockID BlockID, stateID
blockID, commit.BlockID)
}
- if !stateID.Equals(commit.StateID) {
- return fmt.Errorf("invalid commit -- wrong state ID: want %v, got %v",
- stateID, commit.StateID)
- }
-
canonVote := commit.GetCanonicalVote()
- quorumSigns, err := MakeQuorumSigns(chainID, vals.QuorumType, vals.QuorumHash, canonVote.ToProto(), stateID)
+ quorumSigns, err := MakeQuorumSigns(chainID, vals.QuorumType, vals.QuorumHash, canonVote.ToProto())
if err != nil {
return err
}
diff --git a/types/validator_set_test.go b/types/validator_set_test.go
index 4625f2dd7d..f7c7253a09 100644
--- a/types/validator_set_test.go
+++ b/types/validator_set_test.go
@@ -1,4 +1,3 @@
-// nolint: lll
package types
import (
@@ -696,7 +695,7 @@ func addValidatorsToValidatorSet(vals *ValidatorSet, testValList []testVal) ([]*
combinedProTxHashes = append(combinedProTxHashes, addedProTxHashes...)
if len(combinedProTxHashes) > 0 {
rVals, _ := GenerateValidatorSet(NewValSetParam(combinedProTxHashes))
- rValidators := append(rVals.Validators, removedVals...) // nolint:gocritic
+ rValidators := append(rVals.Validators, removedVals...) //nolint:gocritic
return rValidators, rVals.ThresholdPublicKey
}
return removedVals, nil
@@ -1415,13 +1414,12 @@ func BenchmarkValidatorSet_VerifyCommit_Ed25519(b *testing.B) {
b.Run(fmt.Sprintf("valset size %d", n), func(b *testing.B) {
b.ReportAllocs()
// generate n validators
- stateID := RandStateID()
voteSet, valSet, vals := randVoteSet(ctx, b, h, 0, tmproto.PrecommitType, n)
// create a commit with n validators
- commit, err := makeCommit(ctx, blockID, stateID, h, 0, voteSet, vals)
+ commit, err := makeCommit(ctx, blockID, h, 0, voteSet, vals)
require.NoError(b, err)
for i := 0; i < b.N/n; i++ {
- err = valSet.VerifyCommit(chainID, blockID, stateID, h, commit)
+ err = valSet.VerifyCommit(chainID, blockID, h, commit)
assert.NoError(b, err)
}
})
diff --git a/types/vote.go b/types/vote.go
index f762a14372..7867e3e331 100644
--- a/types/vote.go
+++ b/types/vote.go
@@ -63,7 +63,7 @@ type ErrVoteConflictingVotes struct {
}
func (err *ErrVoteConflictingVotes) Error() string {
- return fmt.Sprintf("conflicting votes from validator %X", err.VoteA.ValidatorProTxHash)
+ return fmt.Sprintf("conflicting votes from validator %X: \nA: %+v\nB: %+v", err.VoteA.ValidatorProTxHash, err.VoteA, err.VoteB)
}
func NewConflictingVoteError(vote1, vote2 *Vote) *ErrVoteConflictingVotes {
@@ -88,9 +88,7 @@ type Vote struct {
ValidatorProTxHash ProTxHash `json:"validator_pro_tx_hash"`
ValidatorIndex int32 `json:"validator_index"`
BlockSignature tmbytes.HexBytes `json:"block_signature"`
- StateSignature tmbytes.HexBytes `json:"state_signature"`
VoteExtensions VoteExtensions `json:"vote_extensions"`
- AppHash tmbytes.HexBytes `json:"app_hash"`
}
// VoteFromProto attempts to convert the given serialization (Protobuf) type to
@@ -110,30 +108,10 @@ func VoteFromProto(pv *tmproto.Vote) (*Vote, error) {
ValidatorProTxHash: pv.ValidatorProTxHash,
ValidatorIndex: pv.ValidatorIndex,
BlockSignature: pv.BlockSignature,
- StateSignature: pv.StateSignature,
VoteExtensions: VoteExtensionsFromProto(pv.VoteExtensions),
- AppHash: pv.AppHash,
}, nil
}
-// VoteBlockSignBytes returns the proto-encoding of the canonicalized Vote, for
-// signing. Panics is the marshaling fails.
-//
-// The encoded Protobuf message is varint length-prefixed (using MarshalDelimited)
-// for backwards-compatibility with the Amino encoding, due to e.g. hardware
-// devices that rely on this encoding.
-//
-// See CanonicalizeVote
-func VoteBlockSignBytes(chainID string, vote *tmproto.Vote) []byte {
- pb := CanonicalizeVote(chainID, vote)
- bz, err := protoio.MarshalDelimited(&pb)
- if err != nil {
- panic(err)
- }
-
- return bz
-}
-
// VoteExtensionSignBytes returns the proto-encoding of the canonicalized vote
// extension for signing. Panics if the marshaling fails.
//
@@ -159,21 +137,20 @@ func VoteBlockSignID(chainID string, vote *tmproto.Vote, quorumType btcjson.LLMQ
return signID.ID
}
+// Copy creates a deep copy of the vote
func (vote *Vote) Copy() *Vote {
+ if vote == nil {
+ return nil
+ }
+
voteCopy := *vote
- return &voteCopy
-}
-// StateID generates state ID for this vote
-func (vote *Vote) StateID() StateID {
- if len(vote.BlockID.Hash) == 0 {
- return StateID{}
- }
+ voteCopy.BlockID = vote.BlockID.Copy()
+ voteCopy.ValidatorProTxHash = vote.ValidatorProTxHash.Copy()
+ voteCopy.BlockSignature = vote.BlockSignature.Copy()
+ voteCopy.VoteExtensions = vote.VoteExtensions.Copy()
- return StateID{
- Height: vote.Height,
- AppHash: vote.AppHash,
- }
+ return &voteCopy
}
// String returns a string representation of Vote.
@@ -208,7 +185,7 @@ func (vote *Vote) String() string {
blockHashString = fmt.Sprintf("%X", tmbytes.Fingerprint(vote.BlockID.Hash))
}
- return fmt.Sprintf("Vote{%v:%X %v/%02d/%v(%s) %X %X %X %s}",
+ return fmt.Sprintf("Vote{%v:%X %v/%02d/%v(%s) %X %X}",
vote.ValidatorIndex,
tmbytes.Fingerprint(vote.ValidatorProTxHash),
vote.Height,
@@ -216,9 +193,7 @@ func (vote *Vote) String() string {
typeString,
blockHashString,
tmbytes.Fingerprint(vote.BlockSignature),
- tmbytes.Fingerprint(vote.StateSignature),
vote.VoteExtensions.Fingerprint(),
- vote.AppHash.ShortString(),
)
}
@@ -232,9 +207,8 @@ func (vote *Vote) VerifyWithExtension(
quorumHash crypto.QuorumHash,
pubKey crypto.PubKey,
proTxHash ProTxHash,
- stateID StateID,
) error {
- quorumSignData, err := MakeQuorumSigns(chainID, quorumType, quorumHash, vote.ToProto(), stateID)
+ quorumSignData, err := MakeQuorumSigns(chainID, quorumType, quorumHash, vote.ToProto())
if err != nil {
return err
}
@@ -251,16 +225,17 @@ func (vote *Vote) Verify(
quorumHash []byte,
pubKey crypto.PubKey,
proTxHash crypto.ProTxHash,
- stateID StateID,
+ stateID tmproto.StateID,
) error {
err := vote.verifyBasic(proTxHash, pubKey)
if err != nil {
return err
}
- quorumSignData, err := MakeQuorumSigns(chainID, quorumType, quorumHash, vote.ToProto(), stateID)
+ quorumSignData, err := MakeQuorumSigns(chainID, quorumType, quorumHash, vote.ToProto())
if err != nil {
return err
}
+
return vote.verifySign(pubKey, quorumSignData, WithVerifyExtensions(false))
}
@@ -272,10 +247,6 @@ func (vote *Vote) verifyBasic(proTxHash ProTxHash, pubKey crypto.PubKey) error {
return ErrVoteInvalidValidatorPubKeySize
}
- // we must verify the stateID but only if the blockID isn't nil
- if vote.BlockID.Hash == nil && vote.StateSignature != nil {
- return ErrVoteStateSignatureShouldBeNil
- }
return nil
}
@@ -285,14 +256,13 @@ func (vote *Vote) VerifyExtensionSign(chainID string, pubKey crypto.PubKey, quor
if vote.Type != tmproto.PrecommitType || vote.BlockID.IsNil() {
return nil
}
- quorumSignData, err := MakeQuorumSigns(chainID, quorumType, quorumHash, vote.ToProto(), StateID{})
+ quorumSignData, err := MakeQuorumSigns(chainID, quorumType, quorumHash, vote.ToProto())
if err != nil {
return err
}
verifier := NewQuorumSignsVerifier(
quorumSignData,
WithVerifyBlock(false),
- WithVerifyState(false),
)
return verifier.Verify(pubKey, vote.makeQuorumSigns())
}
@@ -304,7 +274,7 @@ func (vote *Vote) verifySign(
) error {
verifier := NewQuorumSignsVerifier(
quorumSignData,
- append(opts, WithVerifyState(vote.BlockID.Hash != nil))...,
+ opts...,
)
return verifier.Verify(pubKey, vote.makeQuorumSigns())
}
@@ -312,7 +282,6 @@ func (vote *Vote) verifySign(
func (vote *Vote) makeQuorumSigns() QuorumSigns {
return QuorumSigns{
BlockSign: vote.BlockSignature,
- StateSign: vote.StateSignature,
ExtensionSigns: MakeThresholdExtensionSigns(vote.VoteExtensions),
}
}
@@ -363,14 +332,6 @@ func (vote *Vote) ValidateBasic() error {
return fmt.Errorf("block signature is too big (max: %d)", SignatureSize)
}
- if vote.BlockID.Hash != nil && len(vote.StateSignature) == 0 {
- return errors.New("state signature is missing for a block not voting nil")
- }
-
- if len(vote.StateSignature) > SignatureSize {
- return fmt.Errorf("state signature is too big (max: %d)", SignatureSize)
- }
-
// We should only ever see vote extensions in precommits.
if vote.Type != tmproto.PrecommitType || (vote.Type == tmproto.PrecommitType && vote.BlockID.IsNil()) {
if !vote.VoteExtensions.IsEmpty() {
@@ -425,9 +386,7 @@ func (vote *Vote) ToProto() *tmproto.Vote {
ValidatorProTxHash: vote.ValidatorProTxHash,
ValidatorIndex: vote.ValidatorIndex,
BlockSignature: vote.BlockSignature,
- StateSignature: vote.StateSignature,
VoteExtensions: voteExtensions,
- AppHash: vote.AppHash,
}
}
@@ -441,8 +400,6 @@ func (vote *Vote) MarshalZerologObject(e *zerolog.Event) {
e.Str("type", vote.Type.String())
e.Str("block_id", vote.BlockID.String())
e.Str("block_signature", vote.BlockSignature.ShortString())
- e.Str("state_signature", vote.StateSignature.ShortString())
- e.Str("apphash", vote.AppHash.ShortString())
e.Str("val_proTxHash", vote.ValidatorProTxHash.ShortString())
e.Int32("val_index", vote.ValidatorIndex)
e.Bool("nil", vote.BlockID.IsNil())
diff --git a/types/vote_dash.go b/types/vote_dash.go
index 08d24e3220..b8fc4363d8 100644
--- a/types/vote_dash.go
+++ b/types/vote_dash.go
@@ -5,14 +5,12 @@ import tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
// PopulateSignsFromProto updates the signatures of the current Vote with values are taken from the Vote's protobuf
func (vote *Vote) PopulateSignsFromProto(pv *tmproto.Vote) error {
vote.BlockSignature = pv.BlockSignature
- vote.StateSignature = pv.StateSignature
return vote.VoteExtensions.CopySignsFromProto(pv.VoteExtensionsToMap())
}
// PopulateSignsToProto updates the signatures of the given protobuf Vote entity with values are taken from the current Vote's
func (vote *Vote) PopulateSignsToProto(pv *tmproto.Vote) error {
pv.BlockSignature = vote.BlockSignature
- pv.StateSignature = vote.StateSignature
return vote.VoteExtensions.CopySignsToProto(pv.VoteExtensionsToMap())
}
diff --git a/types/vote_extension.go b/types/vote_extension.go
index e6ed74fa89..4ddcbb3fcf 100644
--- a/types/vote_extension.go
+++ b/types/vote_extension.go
@@ -164,6 +164,19 @@ func VoteExtensionsFromProto(pve []*tmproto.VoteExtension) VoteExtensions {
return voteExtensions
}
+// Copy creates a deep copy of VoteExtensions
+func (e VoteExtensions) Copy() VoteExtensions {
+ copied := make(VoteExtensions, len(e))
+ for extType, extensions := range e {
+ copied[extType] = make([]VoteExtension, len(extensions))
+ for k, v := range extensions {
+ copied[extType][k] = v.Clone()
+ }
+ }
+
+ return copied
+}
+
// CopySignsFromProto copies the signatures from VoteExtensions's protobuf into the current VoteExtension state
func (e VoteExtensions) CopySignsFromProto(src tmproto.VoteExtensions) error {
return e.copySigns(src, func(a *tmproto.VoteExtension, b *VoteExtension) {
diff --git a/types/vote_set.go b/types/vote_set.go
index 3b936da076..e9b6edb207 100644
--- a/types/vote_set.go
+++ b/types/vote_set.go
@@ -69,7 +69,6 @@ type VoteSet struct {
// dash fields
thresholdBlockSig []byte // If a 2/3 majority is seen, recover the block sig
- thresholdStateSig []byte // If a 2/3 majority is seen, recover the state sig
thresholdVoteExtSigs []ThresholdExtensionSign // If a 2/3 majority is seen, recover the vote extension sigs
}
@@ -206,8 +205,7 @@ func (voteSet *VoteSet) addVote(vote *Vote) (added bool, err error) {
// If we already know of this vote, return false.
if existing, ok := voteSet.getVote(valIndex, blockKey); ok {
- if bytes.Equal(existing.BlockSignature, vote.BlockSignature) &&
- bytes.Equal(existing.StateSignature, vote.StateSignature) {
+ if bytes.Equal(existing.BlockSignature, vote.BlockSignature) {
return false, nil // duplicate
}
return false, fmt.Errorf(
@@ -222,12 +220,11 @@ func (voteSet *VoteSet) addVote(vote *Vote) (added bool, err error) {
voteSet.valSet.QuorumHash,
val.PubKey,
val.ProTxHash,
- vote.StateID(),
)
if err != nil {
return false, ErrInvalidVoteSignature(
- fmt.Errorf("failed to verify vote with ChainID %s and PubKey %s ProTxHash %s StateID %s: %w",
- voteSet.chainID, val.PubKey, val.ProTxHash, vote.StateID(), err))
+ fmt.Errorf("failed to verify vote with ChainID %s and PubKey %s ProTxHash %s: %w",
+ voteSet.chainID, val.PubKey, val.ProTxHash, err))
}
quorumSigns, err := MakeQuorumSignsWithVoteSet(voteSet, vote.ToProto())
@@ -350,7 +347,6 @@ func (voteSet *VoteSet) recoverThresholdSignsAndVerify(blockVotes *blockVotes, q
// there is only 1 validator
vote := blockVotes.votes[0]
voteSet.thresholdBlockSig = vote.BlockSignature
- voteSet.thresholdStateSig = vote.StateSignature
voteSet.thresholdVoteExtSigs = MakeThresholdVoteExtensions(
vote.VoteExtensions[tmproto.VoteExtensionType_THRESHOLD_RECOVER],
vote.GetVoteExtensionsSigns(tmproto.VoteExtensionType_THRESHOLD_RECOVER),
@@ -379,7 +375,6 @@ func (voteSet *VoteSet) recoverThresholdSigns(blockVotes *blockVotes) error {
return err
}
voteSet.thresholdBlockSig = thresholdSigns.BlockSign
- voteSet.thresholdStateSig = thresholdSigns.StateSign
voteSet.thresholdVoteExtSigs = thresholdSigns.ExtensionSigns
return nil
}
@@ -722,27 +717,10 @@ func (voteSet *VoteSet) MakeCommit() *Commit {
panic("Cannot MakeCommit() unless a thresholdBlockSig has been created")
}
- if voteSet.thresholdStateSig == nil {
- panic("Cannot MakeCommit() unless a thresholdStateSig has been created")
- }
-
- // find a first vote to take height and app-hash for stateID
- stateID := StateID{}
- if len(voteSet.votes) > 0 {
- for _, vote := range voteSet.votes {
- if vote == nil {
- continue
- }
- stateID = vote.StateID()
- break
- }
- }
-
return NewCommit(
voteSet.GetHeight(),
voteSet.GetRound(),
*voteSet.maj23,
- stateID,
voteSet.makeCommitSigns(),
)
}
@@ -751,7 +729,6 @@ func (voteSet *VoteSet) makeCommitSigns() *CommitSigns {
return &CommitSigns{
QuorumSigns: QuorumSigns{
BlockSign: voteSet.thresholdBlockSig,
- StateSign: voteSet.thresholdStateSig,
ExtensionSigns: voteSet.thresholdVoteExtSigs,
},
QuorumHash: voteSet.valSet.QuorumHash,
@@ -761,7 +738,6 @@ func (voteSet *VoteSet) makeCommitSigns() *CommitSigns {
func (voteSet *VoteSet) makeQuorumSigns() QuorumSigns {
return QuorumSigns{
BlockSign: voteSet.thresholdBlockSig,
- StateSign: voteSet.thresholdStateSig,
ExtensionSigns: voteSet.thresholdVoteExtSigs,
}
}
diff --git a/types/vote_set_test.go b/types/vote_set_test.go
index 6c8498e7ff..9b60f15aaa 100644
--- a/types/vote_set_test.go
+++ b/types/vote_set_test.go
@@ -7,8 +7,10 @@ import (
"sort"
"strconv"
"testing"
+ "time"
"github.com/dashevo/dashd-go/btcjson"
+ "github.com/gogo/protobuf/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -40,7 +42,7 @@ func TestVoteSet_AddVote_Good(t *testing.T) {
Height: height,
Round: round,
Type: tmproto.PrevoteType,
- BlockID: BlockID{nil, PartSetHeader{}},
+ BlockID: BlockID{},
}
_, err = signAddVote(ctx, val0, vote, voteSet)
require.NoError(t, err)
@@ -64,7 +66,7 @@ func TestVoteSet_AddVote_Bad(t *testing.T) {
Height: height,
Round: round,
Type: tmproto.PrevoteType,
- BlockID: BlockID{nil, PartSetHeader{}},
+ BlockID: BlockID{nil, PartSetHeader{}, RandStateID().Hash()},
}
// val0 votes for nil.
@@ -124,86 +126,6 @@ func TestVoteSet_AddVote_Bad(t *testing.T) {
}
-// TestVoteSet_AddVote_StateID checks if state signature is verified correctly when adding votes to voteSet
-func TestVoteSet_AddVote_StateID(t *testing.T) {
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- height, round := int64(10), int32(0)
-
- appHash := tmrand.Bytes(crypto.DefaultAppHashSize)
- correctStateID := StateID{
- Height: height,
- AppHash: appHash,
- }
- wrongStateID := RandStateID().WithHeight(height)
-
- testCases := []struct {
- name string
- voteSetStateID StateID
- wrongStateID StateID
- shouldFail bool
- }{
- {"correct", correctStateID, correctStateID, false},
- {"wrong apphash", correctStateID, wrongStateID, true},
- {"too low height", correctStateID, correctStateID.WithHeight(height - 5), true},
- {"too high height", correctStateID, correctStateID.WithHeight(height + 5), true},
- }
- //nolint:scopelint
- for _, tc := range testCases {
- t.Run(tc.name, func(t *testing.T) {
- voteSet, _, privValidators := randVoteSet(ctx, t, height, round, tmproto.PrevoteType, 10)
-
- val0 := privValidators[0]
- val0ProTxHash, err := val0.GetProTxHash(ctx)
- require.NoError(t, err)
-
- val1 := privValidators[1]
- val1ProTxHash, err := val1.GetProTxHash(ctx)
- require.NoError(t, err)
-
- assert.Nil(t, voteSet.GetByProTxHash(val0ProTxHash))
- assert.False(t, voteSet.BitArray().GetIndex(0))
- majorityBlockID, ok := voteSet.TwoThirdsMajority()
- assert.False(t, ok || !majorityBlockID.IsNil(), "there should be no 2/3 majority")
- blockID := randBlockID()
- vote1 := &Vote{
- ValidatorProTxHash: val0ProTxHash,
- ValidatorIndex: 0, // since privValidators are in order
- Height: height,
- Round: round,
- Type: tmproto.PrevoteType,
- BlockID: blockID,
- AppHash: appHash,
- }
- _, err = signAddVote(ctx, val0, vote1, voteSet)
- require.NoError(t, err)
-
- vote2 := &Vote{
- ValidatorProTxHash: val1ProTxHash,
- ValidatorIndex: 1, // since privValidators are in order
- Height: height,
- Round: round,
- Type: tmproto.PrevoteType,
- BlockID: blockID,
- AppHash: appHash,
- }
- _, err = signAddVoteForStateID(ctx, val1, vote2, voteSet, tc.wrongStateID)
- if tc.shouldFail {
- require.Error(t, err)
- assert.Contains(t, err.Error(), "threshold state signature is invalid")
- } else {
- require.NoError(t, err)
- }
-
- assert.NotNil(t, voteSet.GetByProTxHash(val0ProTxHash))
- assert.True(t, voteSet.BitArray().GetIndex(0))
- majorityBlockID, ok = voteSet.TwoThirdsMajority()
- assert.False(t, ok || !majorityBlockID.IsNil(), "there should be no 2/3 majority")
- })
- }
-}
-
func TestVoteSet_2_3Majority(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
@@ -217,7 +139,7 @@ func TestVoteSet_2_3Majority(t *testing.T) {
Height: height,
Round: round,
Type: tmproto.PrevoteType,
- BlockID: BlockID{nil, PartSetHeader{}},
+ BlockID: BlockID{},
}
// 6 out of 10 voted for nil.
for i := int32(0); i < 6; i++ {
@@ -261,6 +183,7 @@ func TestVoteSet_2_3MajorityRedux(t *testing.T) {
voteSet, _, privValidators := randVoteSet(ctx, t, height, round, tmproto.PrevoteType, 100)
blockHash := crypto.CRandBytes(32)
+ stateID := RandStateID()
blockPartsTotal := uint32(123)
blockPartSetHeader := PartSetHeader{blockPartsTotal, crypto.CRandBytes(32)}
@@ -270,7 +193,7 @@ func TestVoteSet_2_3MajorityRedux(t *testing.T) {
Height: height,
Round: round,
Type: tmproto.PrevoteType,
- BlockID: BlockID{blockHash, blockPartSetHeader},
+ BlockID: BlockID{blockHash, blockPartSetHeader, stateID.Hash()},
}
// 66 out of 100 voted for nil.
@@ -343,7 +266,7 @@ func TestVoteSet_2_3MajorityRedux(t *testing.T) {
_, err = signAddVote(ctx, privValidators[70], vote, voteSet)
require.NoError(t, err)
blockID, ok = voteSet.TwoThirdsMajority()
- assert.True(t, ok && blockID.Equals(BlockID{blockHash, blockPartSetHeader}),
+ assert.True(t, ok && blockID.Equals(BlockID{blockHash, blockPartSetHeader, stateID.Hash()}),
"there should be 2/3 majority")
}
}
@@ -363,7 +286,7 @@ func TestVoteSet_Conflicts(t *testing.T) {
Height: height,
Round: round,
Type: tmproto.PrevoteType,
- BlockID: BlockID{nil, PartSetHeader{}},
+ BlockID: BlockID{},
}
val0ProTxHash, err := privValidators[0].GetProTxHash(ctx)
@@ -387,19 +310,20 @@ func TestVoteSet_Conflicts(t *testing.T) {
}
// start tracking blockHash1
- err = voteSet.SetPeerMaj23("peerA", BlockID{blockHash1, PartSetHeader{}}, height, round)
+ blockID := withBlockHash(voteProto, blockHash1).BlockID
+ err = voteSet.SetPeerMaj23("peerA", blockID, height, round)
require.NoError(t, err)
// val0 votes again for blockHash1.
{
vote := withValidator(voteProto, val0ProTxHash, 0)
added, err := signAddVote(ctx, privValidators[0], withBlockHash(vote, blockHash1), voteSet)
- assert.True(t, added, "called SetPeerMaj23()")
+ assert.True(t, added, "called SetPeerMaj23(), err=%s", err)
assert.Error(t, err, "conflicting vote")
}
// attempt tracking blockHash2, should fail because already set for peerA.
- err = voteSet.SetPeerMaj23("peerA", BlockID{blockHash2, PartSetHeader{}}, height, round)
+ err = voteSet.SetPeerMaj23("peerA", BlockID{Hash: blockHash2, PartSetHeader: PartSetHeader{}}, height, round)
require.Error(t, err)
// val0 votes again for blockHash1.
@@ -449,7 +373,7 @@ func TestVoteSet_Conflicts(t *testing.T) {
}
// now attempt tracking blockHash1
- err = voteSet.SetPeerMaj23("peerB", BlockID{blockHash1, PartSetHeader{}}, height, round)
+ err = voteSet.SetPeerMaj23("peerB", BlockID{Hash: blockHash1, PartSetHeader: PartSetHeader{}}, height, round)
require.NoError(t, err)
// val2 votes for blockHash1.
@@ -482,6 +406,7 @@ func TestVoteSet_MakeCommit(t *testing.T) {
height, round := int64(1), int32(0)
voteSet, _, privValidators := randVoteSet(ctx, t, height, round, tmproto.PrecommitType, 10)
blockHash, blockPartSetHeader := crypto.CRandBytes(32), PartSetHeader{123, crypto.CRandBytes(32)}
+ stateID := RandStateID()
voteProto := &Vote{
ValidatorProTxHash: nil,
@@ -489,7 +414,7 @@ func TestVoteSet_MakeCommit(t *testing.T) {
Height: height,
Round: round,
Type: tmproto.PrecommitType,
- BlockID: BlockID{blockHash, blockPartSetHeader},
+ BlockID: BlockID{blockHash, blockPartSetHeader, stateID.Hash()},
}
// 6 out of 10 voted for some block.
@@ -594,8 +519,9 @@ func TestVoteSet_LLMQType_50_60(t *testing.T) {
"need at least %d validators", tt.threshold+3)
blockHash := crypto.CRandBytes(32)
+ stateID := RandStateID()
blockPartSetHeader := PartSetHeader{uint32(123), crypto.CRandBytes(32)}
- votedBlock := BlockID{blockHash, blockPartSetHeader}
+ votedBlock := BlockID{blockHash, blockPartSetHeader, stateID.Hash()}
// below threshold
for i := 0; i < tt.threshold-1; i++ {
@@ -731,10 +657,19 @@ func withType(vote *Vote, signedMsgType byte) *Vote {
return vote
}
-// Convenience: Return new vote with different blockHash
+// Convenience: Return new vote with different blockHash and state ID
func withBlockHash(vote *Vote, blockHash []byte) *Vote {
vote = vote.Copy()
vote.BlockID.Hash = blockHash
+
+ ts, _ := types.TimestampProto(time.Date(2022, 1, 2, 3, 4, 5, 6, time.UTC))
+ vote.BlockID.StateID = tmproto.StateID{
+ AppVersion: StateIDVersion,
+ Height: uint64(vote.Height),
+ AppHash: blockHash,
+ CoreChainLockedHeight: 1,
+ Time: *ts,
+ }.Hash()
return vote
}
diff --git a/types/vote_test.go b/types/vote_test.go
index 7479877482..d94a31a904 100644
--- a/types/vote_test.go
+++ b/types/vote_test.go
@@ -12,21 +12,21 @@ import (
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/bls12381"
- "github.com/tendermint/tendermint/internal/libs/protoio"
"github.com/tendermint/tendermint/libs/log"
+ "github.com/tendermint/tendermint/libs/rand"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
)
const (
//nolint: lll
- preCommitTestStr = `Vote{56789:959A8F5EF2BE 12345/02/Precommit(8B01023386C3) 000000000000 000000000000 000000000000 000000}`
+ preCommitTestStr = `Vote{56789:959A8F5EF2BE 12345/02/Precommit(8B01023386C3) 000000000000 000000000000}`
//nolint: lll
- preVoteTestStr = `Vote{56789:959A8F5EF2BE 12345/02/Prevote(8B01023386C3) 000000000000 000000000000 000000000000 000000}`
+ preVoteTestStr = `Vote{56789:959A8F5EF2BE 12345/02/Prevote(8B01023386C3) 000000000000 000000000000}`
)
var (
- // nolint: lll
- nilVoteTestStr = fmt.Sprintf(`Vote{56789:959A8F5EF2BE 12345/02/Precommit(%s) 000000000000 000000000000 000000000000 000000}`, nilVoteStr)
+ //nolint: lll
+ nilVoteTestStr = fmt.Sprintf(`Vote{56789:959A8F5EF2BE 12345/02/Precommit(%s) 000000000000 000000000000}`, nilVoteStr)
)
func examplePrevote(t *testing.T) *Vote {
@@ -56,26 +56,25 @@ func exampleVote(tb testing.TB, t byte) *Vote {
Total: 1000000,
Hash: crypto.Checksum([]byte("blockID_part_set_header_hash")),
},
+ StateID: RandStateID().Hash(),
},
ValidatorProTxHash: crypto.ProTxHashFromSeedBytes([]byte("validator_pro_tx_hash")),
ValidatorIndex: 56789,
- AppHash: make([]byte, crypto.DefaultAppHashSize),
}
}
func TestVoteSignable(t *testing.T) {
vote := examplePrecommit(t)
v := vote.ToProto()
- signBytes := VoteBlockSignBytes("test_chain_id", v)
- pb := CanonicalizeVote("test_chain_id", v)
- expected, err := protoio.MarshalDelimited(&pb)
+ signBytes, err := v.SignBytes("test_chain_id")
require.NoError(t, err)
+ assert.NotEmpty(t, signBytes)
- require.Equal(t, expected, signBytes, "Got unexpected sign bytes for Vote.")
+ hash := crypto.Checksum(signBytes)
+ assert.Len(t, hash, crypto.DefaultHashSize)
}
func TestVoteSignBytesTestVectors(t *testing.T) {
-
tests := []struct {
chainID string
vote *Vote
@@ -83,58 +82,85 @@ func TestVoteSignBytesTestVectors(t *testing.T) {
}{
0: {
"", &Vote{},
- // NOTE: Height and Round are skipped here. This case needs to be considered while parsing.
- []byte{0x0},
+ []byte{
+ 0x0, 0x0, 0x0, 0x0, // Type, 4 bytes
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // Height, 8 bytes
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // Round, 8 bytes
+
+ 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, // BlockID, bytes 1-8
+ 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, // BlockID, bytes 9-16
+ 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, // BlockID, bytes 16-24
+ 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, // BlockID, bytes 25-32
+
+ 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, // StateID, bytes 1-8
+ 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, // StateID, bytes 9-16
+ 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, // StateID, bytes 17-24
+ 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, // StateID, bytes 25-32
+ // empty ChainID
+ },
},
// with proper (fixed size) height and round (PreCommit):
1: {
- "", &Vote{Height: 1, Round: 1, Type: tmproto.PrecommitType},
+ "", &Vote{Height: 1, Round: 3, Type: tmproto.PrecommitType},
[]byte{
- 0x14, // 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
+ 0x2, 0x0, 0x0, 0x0, // Type, 4 bytes
+ 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // Height, 8 bytes
+ 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // Round, 8 bytes
+ // Block ID, 32 bytes
+ 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
+ 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
+ 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
+ 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
+ // State ID, 32 bytes
+ 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
+ 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
+ 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
+ 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
+ // Empty Chain ID
},
},
// with proper (fixed size) height and round (PreVote):
2: {
"", &Vote{Height: 1, Round: 1, Type: tmproto.PrevoteType},
[]byte{
- 0x14, // length
- 0x8, // (field_number << 3) | wire_type
- 0x1, // PrevoteType
- 0x11, // (field_number << 3) | wire_type
+ 0x1, 0x0, 0x0, 0x0, // 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
+ // block id
+ 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
+ 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
+ 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
+ 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
+ // state id
+ 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
+ 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
+ 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
+ 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
},
},
3: {
"", &Vote{Height: 1, Round: 1},
[]byte{
- 0x12, // length
- 0x11, // (field_number << 3) | wire_type
+ 0x0, 0x0, 0x0, 0x0, // 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
+ 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, //round
+ // block id
+ 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
+ 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
+ 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
+ 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
+ // state id
+ 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
+ 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
+ 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
+ 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
},
},
// containing non-empty chain_id:
4: {
"test_chain_id", &Vote{Height: 1, Round: 1},
[]byte{
- 0x21, // 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:
- // (field_number << 3) | wire_type
- 0x32,
- 0xd, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64}, // chainID
+ 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64},
},
// containing vote extension
5: {
@@ -146,54 +172,39 @@ func TestVoteSignBytesTestVectors(t *testing.T) {
},
},
[]byte{
- 0x21, // 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
- // remaning fields:
- // (field_number << 3) | wire_type
- 0x32,
- 0xd, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, // chainID
- }, // chainID
- },
- }
- for i, tc := range tests {
- v := tc.vote.ToProto()
- got := VoteBlockSignBytes(tc.chainID, v)
- assert.Equal(t, len(tc.want), len(got), "test case #%v: got unexpected sign bytes length for Vote.", i)
- assert.Equal(t, tc.want, got, "test case #%v: got unexpected sign bytes for Vote.", i)
- }
-}
-
-func TestVoteStateSignBytesTestVectors(t *testing.T) {
- tests := []struct {
- chainID string
- height int64
- apphash []byte
- want []byte
- }{
- 0: {
- "", 1, []byte("12345678901234567890123456789012"),
- // NOTE: Height and Round are skipped here. This case needs to be considered while parsing.
- []byte{0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
- 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
- 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32},
+ 0x0, 0x0, 0x0, 0x0, //type
+ 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, //height
+ 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, //round
+ // block id
+ 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
+ 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
+ 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
+ 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
+ //state id
+ 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
+ 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
+ 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
+ 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
+ // remaining 13 bytes are chain id
+ 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x68, 0x61,
+ 0x69, 0x6e, 0x5f, 0x69, 0x64,
+ },
},
}
for i, tc := range tests {
- sid := StateID{
- Height: tc.height,
- AppHash: tc.apphash,
- }
- got := sid.SignBytes(tc.chainID)
- assert.Equal(t, len(tc.want), len(got), "test case #%v: got unexpected sign bytes length for Vote.", i)
- assert.Equal(t, tc.want, got, "test case #%v: got unexpected sign bytes for Vote.", i)
+ t.Run("", func(t *testing.T) {
+ v := tc.vote.ToProto()
+ got, err := v.SignBytes(tc.chainID)
+ assert.NoError(t, err)
+ assert.Len(t, got, len(tc.want), "test case #%v: got unexpected sign bytes length for Vote.", i)
+ assert.Equal(t, tc.want, got, "test case #%v: got unexpected sign bytes for Vote: %X", i, got)
+ })
}
}
func TestVoteProposalNotEq(t *testing.T) {
- cv := CanonicalizeVote("", &tmproto.Vote{Height: 1, Round: 1})
+ cv, err := tmproto.Vote{Height: 1, Round: 1}.ToCanonicalVote("")
+ require.NoError(t, err)
p := CanonicalizeProposal("", &tmproto.Proposal{Height: 1, Round: 1})
vb, err := proto.Marshal(&cv)
require.NoError(t, err)
@@ -203,49 +214,85 @@ func TestVoteProposalNotEq(t *testing.T) {
}
func TestVoteVerifySignature(t *testing.T) {
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
+ type testCase struct {
+ name string
+ modify func(*tmproto.Vote)
+ expectValid bool
+ }
+ testCases := []testCase{
+ {
+ name: "correct",
+ modify: func(v *tmproto.Vote) {},
+ expectValid: true,
+ },
+ {
+ name: "wrong state id",
+ modify: func(v *tmproto.Vote) {
+ v.BlockID.StateID[0] = ^v.BlockID.StateID[0]
+ },
+ expectValid: false,
+ },
+ {
+ name: "wrong block hash",
+ modify: func(v *tmproto.Vote) {
+ v.BlockID.Hash[0] = ^v.BlockID.Hash[0]
+ },
+ expectValid: false,
+ },
+ {
+ name: "wrong block signature",
+ modify: func(v *tmproto.Vote) {
+ v.BlockSignature[0] = ^v.BlockSignature[0]
+ },
+ expectValid: false,
+ },
+ }
- quorumHash := crypto.RandQuorumHash()
- privVal := NewMockPVForQuorum(quorumHash)
- pubkey, err := privVal.GetPubKey(context.Background(), quorumHash)
- require.NoError(t, err)
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
- vote := examplePrecommit(t)
- v := vote.ToProto()
- stateID := RandStateID().WithHeight(vote.Height - 1)
- quorumType := btcjson.LLMQType_5_60
- signID := VoteBlockSignID("test_chain_id", v, quorumType, quorumHash)
- signStateID := stateID.SignID("test_chain_id", quorumType, quorumHash)
+ quorumHash := crypto.RandQuorumHash()
+ privVal := NewMockPVForQuorum(quorumHash)
+ pubkey, err := privVal.GetPubKey(context.Background(), quorumHash)
+ require.NoError(t, err)
- // sign it
- err = privVal.SignVote(ctx, "test_chain_id", quorumType, quorumHash, v, stateID, nil)
- require.NoError(t, err)
+ vote := examplePrecommit(t)
+ v := vote.ToProto()
+ quorumType := btcjson.LLMQType_5_60
+ signID := VoteBlockSignID("test_chain_id", v, quorumType, quorumHash)
- // verify the same vote
- valid := pubkey.VerifySignatureDigest(signID, v.BlockSignature)
- require.True(t, valid)
+ // sign it
+ err = privVal.SignVote(ctx, "test_chain_id", quorumType, quorumHash, v, nil)
+ require.NoError(t, err)
- // verify the same vote
- valid = pubkey.VerifySignatureDigest(signStateID, v.StateSignature)
- require.True(t, valid)
+ // verify the same vote
+ valid := pubkey.VerifySignatureDigest(signID, v.BlockSignature)
+ require.True(t, valid)
- // serialize, deserialize and verify again....
- precommit := new(tmproto.Vote)
- bs, err := proto.Marshal(v)
- require.NoError(t, err)
- err = proto.Unmarshal(bs, precommit)
- require.NoError(t, err)
+ // serialize, deserialize and verify again....
+ precommit := new(tmproto.Vote)
+ bs, err := proto.Marshal(v)
+ require.NoError(t, err)
+ err = proto.Unmarshal(bs, precommit)
+ require.NoError(t, err)
- // verify the transmitted vote
- newSignID := VoteBlockSignID("test_chain_id", precommit, quorumType, quorumHash)
- newSignStateID := stateID.SignID("test_chain_id", quorumType, quorumHash)
- require.Equal(t, string(signID), string(newSignID))
- require.Equal(t, string(signStateID), string(newSignStateID))
- valid = pubkey.VerifySignatureDigest(newSignID, precommit.BlockSignature)
- require.True(t, valid)
- valid = pubkey.VerifySignatureDigest(newSignStateID, precommit.StateSignature)
- require.True(t, valid)
+ // verify the transmitted vote
+ if tc.modify != nil {
+ tc.modify(precommit)
+ }
+ newSignID := VoteBlockSignID("test_chain_id", precommit, quorumType, quorumHash)
+ valid = pubkey.VerifySignatureDigest(newSignID, precommit.BlockSignature)
+
+ if tc.expectValid {
+ assert.True(t, valid)
+ assert.Equal(t, string(signID), string(newSignID))
+ } else {
+ assert.False(t, valid)
+ }
+ })
+ }
}
// TestVoteExtension tests that the vote verification behaves correctly in each case
@@ -294,10 +341,8 @@ func TestVoteExtension(t *testing.T) {
require.NoError(t, err)
pk, err := privVal.GetPubKey(ctx, quorumHash)
require.NoError(t, err)
- blk := Block{}
- blockID, err := blk.BlockID()
- require.NoError(t, err)
- stateID := RandStateID().WithHeight(height - 1)
+ blockID := makeBlockID(rand.Bytes(crypto.HashSize), 1, rand.Bytes(crypto.HashSize), nil)
+
vote := &Vote{
ValidatorProTxHash: proTxHash,
ValidatorIndex: 0,
@@ -308,10 +353,9 @@ func TestVoteExtension(t *testing.T) {
VoteExtensions: tc.extensions,
}
v := vote.ToProto()
- err = privVal.SignVote(ctx, "test_chain_id", btcjson.LLMQType_5_60, quorumHash, v, stateID, logger)
+ err = privVal.SignVote(ctx, "test_chain_id", btcjson.LLMQType_5_60, quorumHash, v, logger)
require.NoError(t, err)
vote.BlockSignature = v.BlockSignature
- vote.StateSignature = v.StateSignature
if tc.includeSignature {
protoExtensionsMap := v.VoteExtensionsToMap()
for et, extensions := range protoExtensionsMap {
@@ -320,7 +364,7 @@ func TestVoteExtension(t *testing.T) {
}
}
}
- err = vote.VerifyWithExtension("test_chain_id", btcjson.LLMQType_5_60, quorumHash, pk, proTxHash, stateID)
+ err = vote.VerifyWithExtension("test_chain_id", btcjson.LLMQType_5_60, quorumHash, pk, proTxHash)
if tc.expectError {
require.Error(t, err)
} else {
@@ -368,7 +412,8 @@ func TestVoteVerify(t *testing.T) {
vote := examplePrevote(t)
vote.ValidatorProTxHash = proTxHash
- stateID := RandStateID().WithHeight(vote.Height - 1)
+ stateID := RandStateID()
+ stateID.Height = uint64(vote.Height - 1)
pubKey := bls12381.GenPrivKey().PubKey()
err = vote.Verify("test_chain_id", quorumType, quorumHash, pubKey, crypto.RandProTxHash(), stateID)
@@ -423,13 +468,12 @@ func signVote(
quorumType btcjson.LLMQType,
quorumHash crypto.QuorumHash,
vote *Vote,
- stateID StateID,
logger log.Logger,
) {
t.Helper()
v := vote.ToProto()
- require.NoError(t, pv.SignVote(ctx, chainID, quorumType, quorumHash, v, stateID, logger))
+ require.NoError(t, pv.SignVote(ctx, chainID, quorumType, quorumHash, v, logger))
err := vote.PopulateSignsFromProto(v)
require.NoError(t, err)
}
@@ -455,10 +499,7 @@ func TestValidVotes(t *testing.T) {
for _, tc := range testCases {
quorumHash := crypto.RandQuorumHash()
privVal := NewMockPVForQuorum(quorumHash)
-
- v := tc.vote.ToProto()
- stateID := RandStateID().WithHeight(v.Height - 1)
- signVote(ctx, t, privVal, "test_chain_id", 0, quorumHash, tc.vote, stateID, nil)
+ signVote(ctx, t, privVal, "test_chain_id", 0, quorumHash, tc.vote, nil)
tc.malleateVote(tc.vote)
require.NoError(t, tc.vote.ValidateBasic(), "ValidateBasic for %s", tc.name)
}
@@ -474,26 +515,30 @@ func TestInvalidVotes(t *testing.T) {
}{
{"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 block hash", func(v *Vote) { v.BlockID.Hash = v.BlockID.Hash[:crypto.DefaultHashSize-1] }},
+ {"invalid state ID", func(v *Vote) { v.BlockID.StateID = v.BlockID.StateID[:crypto.DefaultAppHashSize-1] }},
+ {"invalid block parts hash", func(v *Vote) { v.BlockID.PartSetHeader.Hash = v.BlockID.PartSetHeader.Hash[:crypto.DefaultHashSize-1] }},
+ {"invalid block parts total", func(v *Vote) { v.BlockID.PartSetHeader.Total = 0 }},
{"Invalid ProTxHash", func(v *Vote) { v.ValidatorProTxHash = make([]byte, 1) }},
{"Invalid ValidatorIndex", func(v *Vote) { v.ValidatorIndex = -1 }},
{"Invalid Signature", func(v *Vote) { v.BlockSignature = nil }},
{"Too big Signature", func(v *Vote) { v.BlockSignature = make([]byte, SignatureSize+1) }},
}
+ quorumHash := crypto.RandQuorumHash()
+ privVal := NewMockPVForQuorum(quorumHash)
+
for _, tc := range testCases {
- quorumHash := crypto.RandQuorumHash()
- privVal := NewMockPVForQuorum(quorumHash)
- prevote := examplePrevote(t)
- v := prevote.ToProto()
- stateID := RandStateID().WithHeight(v.Height - 1)
- signVote(ctx, t, privVal, "test_chain_id", 0, quorumHash, prevote, stateID, nil)
- tc.malleateVote(prevote)
- require.Error(t, prevote.ValidateBasic(), "ValidateBasic for %s in invalid prevote", tc.name)
+ t.Run(tc.name, func(t *testing.T) {
+ prevote := examplePrevote(t)
+ signVote(ctx, t, privVal, "test_chain_id", 0, quorumHash, prevote, nil)
+ tc.malleateVote(prevote)
+ require.Error(t, prevote.ValidateBasic(), "ValidateBasic for %s in invalid prevote", tc.name)
- precommit := examplePrecommit(t)
- signVote(ctx, t, privVal, "test_chain_id", 0, quorumHash, precommit, stateID, nil)
- tc.malleateVote(precommit)
- require.Error(t, precommit.ValidateBasic(), "ValidateBasic for %s in invalid precommit", tc.name)
+ precommit := examplePrecommit(t)
+ signVote(ctx, t, privVal, "test_chain_id", 0, quorumHash, precommit, nil)
+ tc.malleateVote(precommit)
+ require.Error(t, precommit.ValidateBasic(), "ValidateBasic for %s in invalid precommit", tc.name)
+ })
}
}
@@ -523,9 +568,7 @@ func TestInvalidPrevotes(t *testing.T) {
}
for _, tc := range testCases {
prevote := examplePrevote(t)
- v := prevote.ToProto()
- stateID := RandStateID().WithHeight(v.Height - 1)
- signVote(ctx, t, privVal, "test_chain_id", 0, quorumHash, prevote, stateID, nil)
+ signVote(ctx, t, privVal, "test_chain_id", 0, quorumHash, prevote, nil)
tc.malleateVote(prevote)
require.Error(t, prevote.ValidateBasic(), "ValidateBasic for %s", tc.name)
}
@@ -563,9 +606,7 @@ func TestInvalidPrecommitExtensions(t *testing.T) {
for i, tc := range testCases {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
precommit := examplePrecommit(t)
- v := precommit.ToProto()
- stateID := RandStateID().WithHeight(v.Height - 1)
- signVote(ctx, t, privVal, "test_chain_id", 0, quorumHash, precommit, stateID, nil)
+ signVote(ctx, t, privVal, "test_chain_id", 0, quorumHash, precommit, nil)
tc.malleateVote(precommit)
// ValidateBasic ensures that vote extensions, if present, are well formed
require.Error(t, precommit.ValidateBasic(), "ValidateBasic for %s", tc.name)
@@ -582,10 +623,8 @@ func TestVoteProtobuf(t *testing.T) {
privVal := NewMockPVForQuorum(quorumHash)
vote := examplePrecommit(t)
v := vote.ToProto()
- stateID := RandStateID().WithHeight(v.Height - 1)
- err := privVal.SignVote(ctx, "test_chain_id", 0, quorumHash, v, stateID, nil)
+ err := privVal.SignVote(ctx, "test_chain_id", 0, quorumHash, v, nil)
vote.BlockSignature = v.BlockSignature
- vote.StateSignature = v.StateSignature
require.NoError(t, err)
testCases := []struct {
@@ -626,7 +665,9 @@ func BenchmarkVoteSignBytes(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
- sink = VoteBlockSignBytes("test_chain_id", protoVote)
+ var err error
+ sink, err = protoVote.SignBytes("test_chain_id")
+ require.NoError(b, err)
}
if sink == nil {