Merge branch 'master' into marko/bringbackdocs

This commit is contained in:
M. J. Fromberger
2022-04-21 07:31:58 -07:00
committed by GitHub
128 changed files with 2692 additions and 2259 deletions
+3 -3
View File
@@ -24,7 +24,7 @@ jobs:
with:
go-version: "1.17"
- uses: actions/checkout@v3
- uses: technote-space/get-diff-action@v6.0.1
- uses: technote-space/get-diff-action@v6
with:
PATTERNS: |
**/**.go
@@ -45,7 +45,7 @@ jobs:
with:
go-version: "1.17"
- uses: actions/checkout@v3
- uses: technote-space/get-diff-action@v6.0.1
- uses: technote-space/get-diff-action@v6
with:
PATTERNS: |
**/**.go
@@ -67,7 +67,7 @@ jobs:
with:
go-version: "1.17"
- uses: actions/checkout@v3
- uses: technote-space/get-diff-action@v6.0.1
- uses: technote-space/get-diff-action@v6
with:
PATTERNS: |
**/**.go
+1 -1
View File
@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: technote-space/get-diff-action@v6.0.1
- uses: technote-space/get-diff-action@v6
with:
PATTERNS: |
docs/architecture/**
+1 -1
View File
@@ -18,7 +18,7 @@ jobs:
with:
go-version: '1.17'
- uses: actions/checkout@v3
- uses: technote-space/get-diff-action@v6.0.1
- uses: technote-space/get-diff-action@v6
with:
PATTERNS: |
**/**.go
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
- uses: actions/setup-go@v3
with:
go-version: '^1.17'
- uses: technote-space/get-diff-action@v6.0.1
- uses: technote-space/get-diff-action@v6
with:
PATTERNS: |
**/**.go
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: technote-space/get-diff-action@v6.0.1
- uses: technote-space/get-diff-action@v6
with:
PATTERNS: |
**/**.md
+2 -2
View File
@@ -20,7 +20,7 @@ jobs:
with:
go-version: "1.17"
- uses: actions/checkout@v3
- uses: technote-space/get-diff-action@v6.0.1
- uses: technote-space/get-diff-action@v6
with:
PATTERNS: |
**/**.go
@@ -42,7 +42,7 @@ jobs:
needs: tests
steps:
- uses: actions/checkout@v3
- uses: technote-space/get-diff-action@v6.0.1
- uses: technote-space/get-diff-action@v6
with:
PATTERNS: |
**/**.go
+17 -3
View File
@@ -52,6 +52,9 @@ func dialerFunc(ctx context.Context, addr string) (net.Conn, error) {
}
func (cli *grpcClient) OnStart(ctx context.Context) error {
timer := time.NewTimer(0)
defer timer.Stop()
RETRY_LOOP:
for {
conn, err := grpc.Dial(cli.addr,
@@ -63,8 +66,13 @@ RETRY_LOOP:
return err
}
cli.logger.Error(fmt.Sprintf("abci.grpcClient failed to connect to %v. Retrying...\n", cli.addr), "err", err)
time.Sleep(time.Second * dialRetryIntervalSeconds)
continue RETRY_LOOP
timer.Reset(time.Second * dialRetryIntervalSeconds)
select {
case <-ctx.Done():
return ctx.Err()
case <-timer.C:
continue RETRY_LOOP
}
}
cli.logger.Info("Dialed server. Waiting for echo.", "addr", cli.addr)
@@ -82,7 +90,13 @@ RETRY_LOOP:
}
cli.logger.Error("Echo failed", "err", err)
time.Sleep(time.Second * echoRetryIntervalSeconds)
timer.Reset(time.Second * echoRetryIntervalSeconds)
select {
case <-ctx.Done():
return ctx.Err()
case <-timer.C:
continue ENSURE_CONNECTED
}
}
cli.client = client
+58 -65
View File
@@ -64,6 +64,8 @@ func (cli *socketClient) OnStart(ctx context.Context) error {
err error
conn net.Conn
)
timer := time.NewTimer(0)
defer timer.Stop()
for {
conn, err = tmnet.Connect(cli.addr)
@@ -73,8 +75,15 @@ func (cli *socketClient) OnStart(ctx context.Context) error {
}
cli.logger.Error(fmt.Sprintf("abci.socketClient failed to connect to %v. Retrying after %vs...",
cli.addr, dialRetryIntervalSeconds), "err", err)
time.Sleep(time.Second * dialRetryIntervalSeconds)
continue
timer.Reset(time.Second * dialRetryIntervalSeconds)
select {
case <-ctx.Done():
return ctx.Err()
case <-timer.C:
continue
}
}
cli.conn = conn
@@ -90,11 +99,7 @@ func (cli *socketClient) OnStop() {
if cli.conn != nil {
cli.conn.Close()
}
// this timeout is arbitrary.
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
cli.drainQueue(ctx)
cli.drainQueue()
}
// Error returns an error if the client was stopped abruptly.
@@ -113,12 +118,6 @@ func (cli *socketClient) sendRequestsRoutine(ctx context.Context, conn io.Writer
case <-ctx.Done():
return
case reqres := <-cli.reqQueue:
if ctx.Err() != nil {
return
}
cli.willSendReq(reqres)
if err := types.WriteMessage(reqres.Request, bw); err != nil {
cli.stopForError(fmt.Errorf("write to buffer: %w", err))
return
@@ -162,6 +161,11 @@ func (cli *socketClient) recvResponseRoutine(ctx context.Context, conn io.Reader
func (cli *socketClient) willSendReq(reqres *requestAndResponse) {
cli.mtx.Lock()
defer cli.mtx.Unlock()
if !cli.IsRunning() {
return
}
cli.reqSent.PushBack(reqres)
}
@@ -189,6 +193,47 @@ func (cli *socketClient) didRecvResponse(res *types.Response) error {
//----------------------------------------
func (cli *socketClient) doRequest(ctx context.Context, req *types.Request) (*types.Response, error) {
if !cli.IsRunning() {
return nil, errors.New("client has stopped")
}
reqres := makeReqRes(req)
cli.willSendReq(reqres)
select {
case cli.reqQueue <- reqres:
case <-ctx.Done():
return nil, fmt.Errorf("can't queue req: %w", ctx.Err())
}
select {
case <-reqres.signal:
if err := cli.Error(); err != nil {
return nil, err
}
return reqres.Response, nil
case <-ctx.Done():
return nil, ctx.Err()
}
}
// drainQueue marks as complete and discards all remaining pending requests
// from the queue.
func (cli *socketClient) drainQueue() {
cli.mtx.Lock()
defer cli.mtx.Unlock()
// mark all in-flight messages as resolved (they will get cli.Error())
for req := cli.reqSent.Front(); req != nil; req = req.Next() {
reqres := req.Value.(*requestAndResponse)
reqres.markDone()
}
}
//----------------------------------------
func (cli *socketClient) Flush(ctx context.Context) error {
_, err := cli.doRequest(ctx, types.ToRequestFlush())
if err != nil {
@@ -319,58 +364,6 @@ func (cli *socketClient) FinalizeBlock(ctx context.Context, req types.RequestFin
//----------------------------------------
func (cli *socketClient) doRequest(ctx context.Context, req *types.Request) (*types.Response, error) {
reqres := makeReqRes(req)
select {
case cli.reqQueue <- reqres:
case <-ctx.Done():
return nil, fmt.Errorf("can't queue req: %w", ctx.Err())
}
select {
case <-reqres.signal:
if err := cli.Error(); err != nil {
return nil, err
}
return reqres.Response, nil
case <-ctx.Done():
return nil, ctx.Err()
}
}
// drainQueue marks as complete and discards all remaining pending requests
// from the queue.
func (cli *socketClient) drainQueue(ctx context.Context) {
cli.mtx.Lock()
defer cli.mtx.Unlock()
// mark all in-flight messages as resolved (they will get cli.Error())
for req := cli.reqSent.Front(); req != nil; req = req.Next() {
reqres := req.Value.(*requestAndResponse)
reqres.markDone()
}
// Mark all queued messages as resolved.
//
// TODO(creachadair): We can't simply range the channel, because it is never
// closed, and the writer continues to add work.
// See https://github.com/tendermint/tendermint/issues/6996.
for {
select {
case <-ctx.Done():
return
case reqres := <-cli.reqQueue:
reqres.markDone()
default:
return
}
}
}
//----------------------------------------
func resMatchesReq(req *types.Request, res *types.Response) (ok bool) {
switch req.Value.(type) {
case *types.Request_Echo:
@@ -1,14 +1,11 @@
package kvstore
import (
"bytes"
dbm "github.com/tendermint/tm-db"
"github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
cryptoproto "github.com/tendermint/tendermint/proto/tendermint/crypto"
ptypes "github.com/tendermint/tendermint/proto/tendermint/types"
)
const (
@@ -45,34 +42,3 @@ func (app *PersistentKVStoreApplication) OfferSnapshot(req types.RequestOfferSna
func (app *PersistentKVStoreApplication) ApplySnapshotChunk(req types.RequestApplySnapshotChunk) types.ResponseApplySnapshotChunk {
return types.ResponseApplySnapshotChunk{Result: types.ResponseApplySnapshotChunk_ABORT}
}
func (app *PersistentKVStoreApplication) ExtendVote(req types.RequestExtendVote) types.ResponseExtendVote {
return types.ResponseExtendVote{VoteExtension: ConstructVoteExtension(req.Vote.ValidatorAddress)}
}
func (app *PersistentKVStoreApplication) VerifyVoteExtension(req types.RequestVerifyVoteExtension) types.ResponseVerifyVoteExtension {
return types.RespondVerifyVoteExtension(app.verifyExtension(req.Vote.ValidatorAddress, req.Vote.VoteExtension))
}
// -----------------------------
func ConstructVoteExtension(valAddr []byte) *ptypes.VoteExtension {
return &ptypes.VoteExtension{
AppDataToSign: valAddr,
AppDataSelfAuthenticating: valAddr,
}
}
func (app *PersistentKVStoreApplication) verifyExtension(valAddr []byte, ext *ptypes.VoteExtension) bool {
if ext == nil {
return false
}
canonical := ConstructVoteExtension(valAddr)
if !bytes.Equal(canonical.AppDataToSign, ext.AppDataToSign) {
return false
}
if !bytes.Equal(canonical.AppDataSelfAuthenticating, ext.AppDataSelfAuthenticating) {
return false
}
return true
}
-11
View File
@@ -5,8 +5,6 @@ import (
"encoding/json"
"github.com/gogo/protobuf/jsonpb"
types "github.com/tendermint/tendermint/proto/tendermint/types"
)
const (
@@ -157,15 +155,6 @@ var _ jsonRoundTripper = (*EventAttribute)(nil)
// -----------------------------------------------
// construct Result data
func RespondExtendVote(appDataToSign, appDataSelfAuthenticating []byte) ResponseExtendVote {
return ResponseExtendVote{
VoteExtension: &types.VoteExtension{
AppDataToSign: appDataToSign,
AppDataSelfAuthenticating: appDataSelfAuthenticating,
},
}
}
func RespondVerifyVoteExtension(ok bool) ResponseVerifyVoteExtension {
status := ResponseVerifyVoteExtension_REJECT
if ok {
+474 -308
View File
@@ -1521,7 +1521,8 @@ func (m *RequestProcessProposal) GetProposerAddress() []byte {
// Extends a vote with application-side injection
type RequestExtendVote struct {
Vote *types1.Vote `protobuf:"bytes,1,opt,name=vote,proto3" json:"vote,omitempty"`
Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"`
Height int64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"`
}
func (m *RequestExtendVote) Reset() { *m = RequestExtendVote{} }
@@ -1557,16 +1558,26 @@ func (m *RequestExtendVote) XXX_DiscardUnknown() {
var xxx_messageInfo_RequestExtendVote proto.InternalMessageInfo
func (m *RequestExtendVote) GetVote() *types1.Vote {
func (m *RequestExtendVote) GetHash() []byte {
if m != nil {
return m.Vote
return m.Hash
}
return nil
}
func (m *RequestExtendVote) GetHeight() int64 {
if m != nil {
return m.Height
}
return 0
}
// Verify the vote extension
type RequestVerifyVoteExtension struct {
Vote *types1.Vote `protobuf:"bytes,1,opt,name=vote,proto3" json:"vote,omitempty"`
Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"`
ValidatorAddress []byte `protobuf:"bytes,2,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"`
Height int64 `protobuf:"varint,3,opt,name=height,proto3" json:"height,omitempty"`
VoteExtension []byte `protobuf:"bytes,4,opt,name=vote_extension,json=voteExtension,proto3" json:"vote_extension,omitempty"`
}
func (m *RequestVerifyVoteExtension) Reset() { *m = RequestVerifyVoteExtension{} }
@@ -1602,9 +1613,30 @@ func (m *RequestVerifyVoteExtension) XXX_DiscardUnknown() {
var xxx_messageInfo_RequestVerifyVoteExtension proto.InternalMessageInfo
func (m *RequestVerifyVoteExtension) GetVote() *types1.Vote {
func (m *RequestVerifyVoteExtension) GetHash() []byte {
if m != nil {
return m.Vote
return m.Hash
}
return nil
}
func (m *RequestVerifyVoteExtension) GetValidatorAddress() []byte {
if m != nil {
return m.ValidatorAddress
}
return nil
}
func (m *RequestVerifyVoteExtension) GetHeight() int64 {
if m != nil {
return m.Height
}
return 0
}
func (m *RequestVerifyVoteExtension) GetVoteExtension() []byte {
if m != nil {
return m.VoteExtension
}
return nil
}
@@ -3131,7 +3163,7 @@ func (m *ResponseProcessProposal) GetConsensusParamUpdates() *types1.ConsensusPa
}
type ResponseExtendVote struct {
VoteExtension *types1.VoteExtension `protobuf:"bytes,1,opt,name=vote_extension,json=voteExtension,proto3" json:"vote_extension,omitempty"`
VoteExtension []byte `protobuf:"bytes,1,opt,name=vote_extension,json=voteExtension,proto3" json:"vote_extension,omitempty"`
}
func (m *ResponseExtendVote) Reset() { *m = ResponseExtendVote{} }
@@ -3167,7 +3199,7 @@ func (m *ResponseExtendVote) XXX_DiscardUnknown() {
var xxx_messageInfo_ResponseExtendVote proto.InternalMessageInfo
func (m *ResponseExtendVote) GetVoteExtension() *types1.VoteExtension {
func (m *ResponseExtendVote) GetVoteExtension() []byte {
if m != nil {
return m.VoteExtension
}
@@ -3354,8 +3386,14 @@ func (m *CommitInfo) GetVotes() []VoteInfo {
return nil
}
// ExtendedCommitInfo is similar to CommitInfo except that it is only used in
// the PrepareProposal request such that Tendermint can provide vote extensions
// to the application.
type ExtendedCommitInfo struct {
Round int32 `protobuf:"varint,1,opt,name=round,proto3" json:"round,omitempty"`
// The round at which the block proposer decided in the previous height.
Round int32 `protobuf:"varint,1,opt,name=round,proto3" json:"round,omitempty"`
// List of validators' addresses in the last validator set with their voting
// information, including vote extensions.
Votes []ExtendedVoteInfo `protobuf:"bytes,2,rep,name=votes,proto3" json:"votes"`
}
@@ -3908,10 +3946,14 @@ func (m *VoteInfo) GetSignedLastBlock() bool {
return false
}
// ExtendedVoteInfo
type ExtendedVoteInfo struct {
Validator Validator `protobuf:"bytes,1,opt,name=validator,proto3" json:"validator"`
SignedLastBlock bool `protobuf:"varint,2,opt,name=signed_last_block,json=signedLastBlock,proto3" json:"signed_last_block,omitempty"`
VoteExtension []byte `protobuf:"bytes,3,opt,name=vote_extension,json=voteExtension,proto3" json:"vote_extension,omitempty"`
// The validator that sent the vote.
Validator Validator `protobuf:"bytes,1,opt,name=validator,proto3" json:"validator"`
// Indicates whether the validator signed the last block, allowing for rewards based on validator availability.
SignedLastBlock bool `protobuf:"varint,2,opt,name=signed_last_block,json=signedLastBlock,proto3" json:"signed_last_block,omitempty"`
// Non-deterministic extension provided by the sending validator's application.
VoteExtension []byte `protobuf:"bytes,3,opt,name=vote_extension,json=voteExtension,proto3" json:"vote_extension,omitempty"`
}
func (m *ExtendedVoteInfo) Reset() { *m = ExtendedVoteInfo{} }
@@ -4193,223 +4235,224 @@ func init() {
func init() { proto.RegisterFile("tendermint/abci/types.proto", fileDescriptor_252557cfdd89a31a) }
var fileDescriptor_252557cfdd89a31a = []byte{
// 3451 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5b, 0x4b, 0x73, 0x23, 0xd5,
0xf5, 0xd7, 0xfb, 0x71, 0x64, 0x3d, 0x7c, 0x6d, 0x06, 0x8d, 0x98, 0xb1, 0x87, 0x9e, 0x02, 0x66,
0x06, 0xf0, 0xf0, 0x9f, 0xf9, 0x0f, 0x0c, 0x01, 0x42, 0xd9, 0xb2, 0x8c, 0x3c, 0xe3, 0xb1, 0x4d,
0x5b, 0x36, 0x45, 0x42, 0xa6, 0x69, 0xa9, 0xaf, 0xad, 0x66, 0x24, 0x75, 0xd3, 0xdd, 0x32, 0x32,
0xcb, 0x50, 0x6c, 0xa8, 0x54, 0x85, 0x4d, 0x2a, 0xc9, 0x82, 0x5d, 0x52, 0x95, 0x7c, 0x83, 0xac,
0xb2, 0xca, 0x82, 0x45, 0x16, 0xac, 0x92, 0x54, 0x16, 0x24, 0x05, 0xbb, 0x7c, 0x81, 0xec, 0x92,
0xd4, 0x7d, 0xf4, 0x53, 0x6a, 0xa9, 0xc5, 0x00, 0x55, 0xa9, 0xb0, 0xd3, 0x3d, 0x7d, 0xce, 0xe9,
0xbe, 0xf7, 0x9e, 0x7b, 0x1e, 0xbf, 0x73, 0x05, 0x8f, 0x59, 0x78, 0xa0, 0x60, 0xa3, 0xaf, 0x0e,
0xac, 0xeb, 0x72, 0xbb, 0xa3, 0x5e, 0xb7, 0xce, 0x74, 0x6c, 0xae, 0xe9, 0x86, 0x66, 0x69, 0xa8,
0xec, 0x3e, 0x5c, 0x23, 0x0f, 0x6b, 0x17, 0x3d, 0xdc, 0x1d, 0xe3, 0x4c, 0xb7, 0xb4, 0xeb, 0xba,
0xa1, 0x69, 0xc7, 0x8c, 0xbf, 0x76, 0xc1, 0xf3, 0x98, 0xea, 0xf1, 0x6a, 0xf3, 0x3d, 0xe5, 0xc2,
0x0f, 0xf0, 0x99, 0xfd, 0xf4, 0xe2, 0x98, 0xac, 0x2e, 0x1b, 0x72, 0xdf, 0x7e, 0xbc, 0x7a, 0xa2,
0x69, 0x27, 0x3d, 0x7c, 0x9d, 0x8e, 0xda, 0xc3, 0xe3, 0xeb, 0x96, 0xda, 0xc7, 0xa6, 0x25, 0xf7,
0x75, 0xce, 0xb0, 0x7c, 0xa2, 0x9d, 0x68, 0xf4, 0xe7, 0x75, 0xf2, 0x8b, 0x51, 0x85, 0x7f, 0x03,
0x64, 0x45, 0xfc, 0xee, 0x10, 0x9b, 0x16, 0xba, 0x01, 0x29, 0xdc, 0xe9, 0x6a, 0xd5, 0xf8, 0xa5,
0xf8, 0x95, 0xc2, 0x8d, 0x0b, 0x6b, 0x81, 0xc9, 0xad, 0x71, 0xbe, 0x46, 0xa7, 0xab, 0x35, 0x63,
0x22, 0xe5, 0x45, 0xb7, 0x20, 0x7d, 0xdc, 0x1b, 0x9a, 0xdd, 0x6a, 0x82, 0x0a, 0x5d, 0x0c, 0x13,
0xda, 0x22, 0x4c, 0xcd, 0x98, 0xc8, 0xb8, 0xc9, 0xab, 0xd4, 0xc1, 0xb1, 0x56, 0x4d, 0x4e, 0x7f,
0xd5, 0xf6, 0xe0, 0x98, 0xbe, 0x8a, 0xf0, 0xa2, 0x0d, 0x00, 0x75, 0xa0, 0x5a, 0x52, 0xa7, 0x2b,
0xab, 0x83, 0x6a, 0x8a, 0x4a, 0x3e, 0x1e, 0x2e, 0xa9, 0x5a, 0x75, 0xc2, 0xd8, 0x8c, 0x89, 0x79,
0xd5, 0x1e, 0x90, 0xcf, 0x7d, 0x77, 0x88, 0x8d, 0xb3, 0x6a, 0x7a, 0xfa, 0xe7, 0xbe, 0x4e, 0x98,
0xc8, 0xe7, 0x52, 0x6e, 0xb4, 0x0d, 0x85, 0x36, 0x3e, 0x51, 0x07, 0x52, 0xbb, 0xa7, 0x75, 0x1e,
0x54, 0x33, 0x54, 0x58, 0x08, 0x13, 0xde, 0x20, 0xac, 0x1b, 0x84, 0x73, 0x23, 0x51, 0x8d, 0x37,
0x63, 0x22, 0xb4, 0x1d, 0x0a, 0x7a, 0x19, 0x72, 0x9d, 0x2e, 0xee, 0x3c, 0x90, 0xac, 0x51, 0x35,
0x4b, 0xf5, 0xac, 0x86, 0xe9, 0xa9, 0x13, 0xbe, 0xd6, 0xa8, 0x19, 0x13, 0xb3, 0x1d, 0xf6, 0x13,
0x6d, 0x01, 0x28, 0xb8, 0xa7, 0x9e, 0x62, 0x83, 0xc8, 0xe7, 0xa6, 0xaf, 0xc1, 0x26, 0xe3, 0x6c,
0x8d, 0xf8, 0x67, 0xe4, 0x15, 0x9b, 0x80, 0xea, 0x90, 0xc7, 0x03, 0x85, 0x4f, 0x27, 0x4f, 0xd5,
0x5c, 0x0a, 0xdd, 0xef, 0x81, 0xe2, 0x9d, 0x4c, 0x0e, 0xf3, 0x31, 0xba, 0x0d, 0x99, 0x8e, 0xd6,
0xef, 0xab, 0x56, 0x15, 0xa8, 0x86, 0x95, 0xd0, 0x89, 0x50, 0xae, 0x66, 0x4c, 0xe4, 0xfc, 0x68,
0x17, 0x4a, 0x3d, 0xd5, 0xb4, 0x24, 0x73, 0x20, 0xeb, 0x66, 0x57, 0xb3, 0xcc, 0x6a, 0x81, 0x6a,
0x78, 0x22, 0x4c, 0xc3, 0x8e, 0x6a, 0x5a, 0x07, 0x36, 0x73, 0x33, 0x26, 0x16, 0x7b, 0x5e, 0x02,
0xd1, 0xa7, 0x1d, 0x1f, 0x63, 0xc3, 0x51, 0x58, 0x5d, 0x98, 0xae, 0x6f, 0x8f, 0x70, 0xdb, 0xf2,
0x44, 0x9f, 0xe6, 0x25, 0xa0, 0x1f, 0xc2, 0x52, 0x4f, 0x93, 0x15, 0x47, 0x9d, 0xd4, 0xe9, 0x0e,
0x07, 0x0f, 0xaa, 0x45, 0xaa, 0xf4, 0x6a, 0xe8, 0x47, 0x6a, 0xb2, 0x62, 0xab, 0xa8, 0x13, 0x81,
0x66, 0x4c, 0x5c, 0xec, 0x05, 0x89, 0xe8, 0x3e, 0x2c, 0xcb, 0xba, 0xde, 0x3b, 0x0b, 0x6a, 0x2f,
0x51, 0xed, 0xd7, 0xc2, 0xb4, 0xaf, 0x13, 0x99, 0xa0, 0x7a, 0x24, 0x8f, 0x51, 0x51, 0x0b, 0x2a,
0xba, 0x81, 0x75, 0xd9, 0xc0, 0x92, 0x6e, 0x68, 0xba, 0x66, 0xca, 0xbd, 0x6a, 0x99, 0xea, 0x7e,
0x2a, 0x4c, 0xf7, 0x3e, 0xe3, 0xdf, 0xe7, 0xec, 0xcd, 0x98, 0x58, 0xd6, 0xfd, 0x24, 0xa6, 0x55,
0xeb, 0x60, 0xd3, 0x74, 0xb5, 0x56, 0x66, 0x69, 0xa5, 0xfc, 0x7e, 0xad, 0x3e, 0x12, 0x6a, 0x40,
0x01, 0x8f, 0x88, 0xb8, 0x74, 0xaa, 0x59, 0xb8, 0xba, 0x38, 0xfd, 0x60, 0x35, 0x28, 0xeb, 0x91,
0x66, 0x61, 0x72, 0xa8, 0xb0, 0x33, 0x42, 0x32, 0x3c, 0x72, 0x8a, 0x0d, 0xf5, 0xf8, 0x8c, 0xaa,
0x91, 0xe8, 0x13, 0x53, 0xd5, 0x06, 0x55, 0x44, 0x15, 0x3e, 0x1d, 0xa6, 0xf0, 0x88, 0x0a, 0x11,
0x15, 0x0d, 0x5b, 0xa4, 0x19, 0x13, 0x97, 0x4e, 0xc7, 0xc9, 0xc4, 0xc4, 0x8e, 0xd5, 0x81, 0xdc,
0x53, 0xdf, 0xc7, 0xfc, 0xd8, 0x2c, 0x4d, 0x37, 0xb1, 0x2d, 0xce, 0x4d, 0xcf, 0x0a, 0x31, 0xb1,
0x63, 0x2f, 0x61, 0x23, 0x0b, 0xe9, 0x53, 0xb9, 0x37, 0xc4, 0xc2, 0x53, 0x50, 0xf0, 0x38, 0x56,
0x54, 0x85, 0x6c, 0x1f, 0x9b, 0xa6, 0x7c, 0x82, 0xa9, 0x1f, 0xce, 0x8b, 0xf6, 0x50, 0x28, 0xc1,
0x82, 0xd7, 0x99, 0x0a, 0x1f, 0xc7, 0x1d, 0x49, 0xe2, 0x27, 0x89, 0xe4, 0x29, 0x36, 0xe8, 0xb4,
0xb9, 0x24, 0x1f, 0xa2, 0xcb, 0x50, 0xa4, 0x9f, 0x2c, 0xd9, 0xcf, 0x89, 0xb3, 0x4e, 0x89, 0x0b,
0x94, 0x78, 0xc4, 0x99, 0x56, 0xa1, 0xa0, 0xdf, 0xd0, 0x1d, 0x96, 0x24, 0x65, 0x01, 0xfd, 0x86,
0x6e, 0x33, 0x3c, 0x0e, 0x0b, 0x64, 0x7e, 0x0e, 0x47, 0x8a, 0xbe, 0xa4, 0x40, 0x68, 0x9c, 0x45,
0xf8, 0x63, 0x02, 0x2a, 0x41, 0x07, 0x8c, 0x6e, 0x43, 0x8a, 0xc4, 0x22, 0x1e, 0x56, 0x6a, 0x6b,
0x2c, 0x50, 0xad, 0xd9, 0x81, 0x6a, 0xad, 0x65, 0x07, 0xaa, 0x8d, 0xdc, 0xa7, 0x9f, 0xaf, 0xc6,
0x3e, 0xfe, 0xdb, 0x6a, 0x5c, 0xa4, 0x12, 0xe8, 0x3c, 0xf1, 0x95, 0xb2, 0x3a, 0x90, 0x54, 0x85,
0x7e, 0x72, 0x9e, 0x38, 0x42, 0x59, 0x1d, 0x6c, 0x2b, 0x68, 0x07, 0x2a, 0x1d, 0x6d, 0x60, 0xe2,
0x81, 0x39, 0x34, 0x25, 0x16, 0x08, 0x79, 0x30, 0xf1, 0xb9, 0x43, 0x16, 0x5e, 0xeb, 0x36, 0xe7,
0x3e, 0x65, 0x14, 0xcb, 0x1d, 0x3f, 0x81, 0xb8, 0xd5, 0x53, 0xb9, 0xa7, 0x2a, 0xb2, 0xa5, 0x19,
0x66, 0x35, 0x75, 0x29, 0x39, 0xd1, 0x1f, 0x1e, 0xd9, 0x2c, 0x87, 0xba, 0x22, 0x5b, 0x78, 0x23,
0x45, 0x3e, 0x57, 0xf4, 0x48, 0xa2, 0x27, 0xa1, 0x2c, 0xeb, 0xba, 0x64, 0x5a, 0xb2, 0x85, 0xa5,
0xf6, 0x99, 0x85, 0x4d, 0x1a, 0x68, 0x16, 0xc4, 0xa2, 0xac, 0xeb, 0x07, 0x84, 0xba, 0x41, 0x88,
0xe8, 0x09, 0x28, 0x91, 0x98, 0xa4, 0xca, 0x3d, 0xa9, 0x8b, 0xd5, 0x93, 0xae, 0x45, 0x43, 0x4a,
0x52, 0x2c, 0x72, 0x6a, 0x93, 0x12, 0x05, 0xc5, 0xd9, 0x71, 0x1a, 0x8f, 0x10, 0x82, 0x94, 0x22,
0x5b, 0x32, 0x5d, 0xc9, 0x05, 0x91, 0xfe, 0x26, 0x34, 0x5d, 0xb6, 0xba, 0x7c, 0x7d, 0xe8, 0x6f,
0x74, 0x0e, 0x32, 0x5c, 0x6d, 0x92, 0xaa, 0xe5, 0x23, 0xb4, 0x0c, 0x69, 0xdd, 0xd0, 0x4e, 0x31,
0xdd, 0xba, 0x9c, 0xc8, 0x06, 0xc2, 0x07, 0x09, 0x58, 0x1c, 0x8b, 0x5c, 0x44, 0x6f, 0x57, 0x36,
0xbb, 0xf6, 0xbb, 0xc8, 0x6f, 0xf4, 0x3c, 0xd1, 0x2b, 0x2b, 0xd8, 0xe0, 0xd1, 0xbe, 0x3a, 0xbe,
0xd4, 0x4d, 0xfa, 0x9c, 0x2f, 0x0d, 0xe7, 0x46, 0x77, 0xa1, 0xd2, 0x93, 0x4d, 0x4b, 0x62, 0xde,
0x5f, 0xf2, 0x44, 0xfe, 0xc7, 0xc6, 0x16, 0x99, 0xc5, 0x0a, 0x62, 0xd0, 0x5c, 0x49, 0x89, 0x88,
0xba, 0x54, 0x74, 0x08, 0xcb, 0xed, 0xb3, 0xf7, 0xe5, 0x81, 0xa5, 0x0e, 0xb0, 0x34, 0xb6, 0x6b,
0xe3, 0xa9, 0xc4, 0x3d, 0xd5, 0x6c, 0xe3, 0xae, 0x7c, 0xaa, 0x6a, 0xf6, 0x67, 0x2d, 0x39, 0xf2,
0xce, 0x8e, 0x9a, 0x82, 0x08, 0x25, 0x7f, 0xd8, 0x45, 0x25, 0x48, 0x58, 0x23, 0x3e, 0xff, 0x84,
0x35, 0x42, 0xcf, 0x41, 0x8a, 0xcc, 0x91, 0xce, 0xbd, 0x34, 0xe1, 0x45, 0x5c, 0xae, 0x75, 0xa6,
0x63, 0x91, 0x72, 0x0a, 0x82, 0x73, 0x1a, 0x9c, 0x50, 0x1c, 0xd4, 0x2a, 0x5c, 0x85, 0x72, 0x20,
0xce, 0x7a, 0xb6, 0x2f, 0xee, 0xdd, 0x3e, 0xa1, 0x0c, 0x45, 0x5f, 0x40, 0x15, 0xce, 0xc1, 0xf2,
0xa4, 0xf8, 0x28, 0x74, 0x1d, 0xba, 0x2f, 0xce, 0xa1, 0x5b, 0x90, 0x73, 0x02, 0x24, 0x3b, 0x8d,
0xe7, 0xc7, 0x66, 0x61, 0x33, 0x8b, 0x0e, 0x2b, 0x39, 0x86, 0xc4, 0xaa, 0xa9, 0x39, 0x24, 0xe8,
0x87, 0x67, 0x65, 0x5d, 0x6f, 0xca, 0x66, 0x57, 0x78, 0x1b, 0xaa, 0x61, 0xc1, 0x2f, 0x30, 0x8d,
0x94, 0x63, 0x85, 0xe7, 0x20, 0x73, 0xac, 0x19, 0x7d, 0xd9, 0xa2, 0xca, 0x8a, 0x22, 0x1f, 0x11,
0xeb, 0x64, 0x81, 0x30, 0x49, 0xc9, 0x6c, 0x20, 0x48, 0x70, 0x3e, 0x34, 0x00, 0x12, 0x11, 0x75,
0xa0, 0x60, 0xb6, 0x9e, 0x45, 0x91, 0x0d, 0x5c, 0x45, 0xec, 0x63, 0xd9, 0x80, 0xbc, 0xd6, 0xa4,
0x73, 0xa5, 0xfa, 0xf3, 0x22, 0x1f, 0x09, 0xbf, 0x4d, 0xc2, 0xb9, 0xc9, 0x61, 0x10, 0x5d, 0x82,
0x85, 0xbe, 0x3c, 0x92, 0xac, 0x11, 0x3f, 0xcb, 0x6c, 0x3b, 0xa0, 0x2f, 0x8f, 0x5a, 0x23, 0x76,
0x90, 0x2b, 0x90, 0xb4, 0x46, 0x66, 0x35, 0x71, 0x29, 0x79, 0x65, 0x41, 0x24, 0x3f, 0xd1, 0x21,
0x2c, 0xf6, 0xb4, 0x8e, 0xdc, 0x93, 0x3c, 0x16, 0xcf, 0x8d, 0xfd, 0xf2, 0xd8, 0x62, 0xb3, 0x80,
0x86, 0x95, 0x31, 0xa3, 0x2f, 0x53, 0x1d, 0x3b, 0x8e, 0xe5, 0x7f, 0x43, 0x56, 0xef, 0xd9, 0xa3,
0xb4, 0xcf, 0x53, 0xd8, 0x3e, 0x3b, 0x33, 0xb7, 0xcf, 0x7e, 0x0e, 0x96, 0x07, 0x78, 0x64, 0x79,
0xbe, 0x91, 0x19, 0x4e, 0x96, 0xee, 0x05, 0x22, 0xcf, 0xdc, 0xf7, 0x13, 0x1b, 0x42, 0x57, 0x69,
0x66, 0xa1, 0x6b, 0x26, 0x36, 0x24, 0x59, 0x51, 0x0c, 0x6c, 0x9a, 0x34, 0xb3, 0x5d, 0xa0, 0xe9,
0x02, 0xa5, 0xaf, 0x33, 0xb2, 0xf0, 0x4b, 0xef, 0x5e, 0xf9, 0x33, 0x09, 0xbe, 0x13, 0x71, 0x77,
0x27, 0x0e, 0x60, 0x99, 0xcb, 0x2b, 0xbe, 0xcd, 0x48, 0x44, 0xf5, 0x3c, 0xc8, 0x16, 0x8f, 0xb0,
0x0f, 0xc9, 0x87, 0xdb, 0x07, 0xdb, 0xdb, 0xa6, 0x3c, 0xde, 0xf6, 0xbf, 0x6c, 0x6f, 0x5e, 0x75,
0xa2, 0x88, 0x9b, 0xa6, 0xa1, 0x6b, 0x90, 0xa2, 0x89, 0x1d, 0xf3, 0x36, 0xe7, 0xc6, 0xe3, 0x05,
0xe1, 0x12, 0x29, 0x8f, 0xd0, 0x84, 0x5a, 0x78, 0x5a, 0x36, 0x97, 0xa6, 0x9f, 0x25, 0x1d, 0x07,
0xe8, 0xcb, 0xc2, 0x26, 0x18, 0xc9, 0xeb, 0xb0, 0xa4, 0xe0, 0x8e, 0xaa, 0x7c, 0x55, 0x1b, 0x59,
0xe4, 0xd2, 0xdf, 0x99, 0x48, 0x04, 0x13, 0xf9, 0x73, 0x01, 0x72, 0x22, 0x36, 0x75, 0x92, 0x7d,
0xa1, 0x0d, 0xc8, 0xe3, 0x51, 0x07, 0xeb, 0x96, 0x9d, 0xb0, 0x4e, 0x4e, 0xfc, 0x19, 0x77, 0xc3,
0xe6, 0x24, 0x65, 0xac, 0x23, 0x86, 0x6e, 0x72, 0xc4, 0x22, 0x1c, 0x7c, 0xe0, 0xe2, 0x5e, 0xc8,
0xe2, 0x79, 0x1b, 0xb2, 0x48, 0x86, 0x56, 0xad, 0x4c, 0x2a, 0x80, 0x59, 0xdc, 0xe4, 0x98, 0x45,
0x6a, 0xc6, 0xcb, 0x7c, 0xa0, 0x45, 0xdd, 0x07, 0x5a, 0xa4, 0x67, 0x4c, 0x33, 0x04, 0xb5, 0x78,
0xde, 0x46, 0x2d, 0x32, 0x33, 0xbe, 0x38, 0x00, 0x5b, 0xdc, 0xf1, 0xc3, 0x16, 0xd9, 0x90, 0x28,
0x64, 0x4b, 0x4f, 0xc5, 0x2d, 0x5e, 0xf1, 0xe0, 0x16, 0xb9, 0x50, 0xc0, 0x80, 0x29, 0x9a, 0x00,
0x5c, 0xbc, 0xe6, 0x03, 0x2e, 0xf2, 0x33, 0xd6, 0x61, 0x0a, 0x72, 0xb1, 0xe9, 0x45, 0x2e, 0x20,
0x14, 0x00, 0xe1, 0xfb, 0x1e, 0x06, 0x5d, 0xbc, 0xe8, 0x40, 0x17, 0x85, 0x50, 0x0c, 0x86, 0xcf,
0x25, 0x88, 0x5d, 0xec, 0x8d, 0x61, 0x17, 0x0c, 0x6b, 0x78, 0x32, 0x54, 0xc5, 0x0c, 0xf0, 0x62,
0x6f, 0x0c, 0xbc, 0x28, 0xce, 0x50, 0x38, 0x03, 0xbd, 0x78, 0x6b, 0x32, 0x7a, 0x11, 0x8e, 0x2f,
0xf0, 0xcf, 0x8c, 0x06, 0x5f, 0x48, 0x21, 0xf0, 0x45, 0x39, 0xb4, 0xd4, 0x66, 0xea, 0x23, 0xe3,
0x17, 0x87, 0x13, 0xf0, 0x0b, 0x86, 0x34, 0x5c, 0x09, 0x55, 0x1e, 0x01, 0xc0, 0x38, 0x9c, 0x00,
0x60, 0x2c, 0xce, 0x54, 0x3b, 0x13, 0xc1, 0xd8, 0xf2, 0x23, 0x18, 0x68, 0xc6, 0x19, 0x0b, 0x85,
0x30, 0xda, 0x61, 0x10, 0x06, 0x83, 0x19, 0x9e, 0x09, 0xd5, 0x38, 0x07, 0x86, 0xb1, 0x37, 0x86,
0x61, 0x2c, 0xcf, 0xb0, 0xb4, 0xa8, 0x20, 0xc6, 0x55, 0x12, 0xfc, 0x03, 0xae, 0x9a, 0xe4, 0xe1,
0xd8, 0x30, 0x34, 0x83, 0xc3, 0x11, 0x6c, 0x20, 0x5c, 0x21, 0x45, 0xad, 0xeb, 0x96, 0xa7, 0x00,
0x1e, 0xb4, 0xde, 0xf1, 0xb8, 0x62, 0xe1, 0x77, 0x71, 0x57, 0x96, 0xd6, 0x82, 0xde, 0x82, 0x38,
0xcf, 0x0b, 0x62, 0x0f, 0x0c, 0x92, 0xf0, 0xc3, 0x20, 0xab, 0x50, 0x20, 0x75, 0x4c, 0x00, 0xe1,
0x90, 0x75, 0x07, 0xe1, 0xb8, 0x06, 0x8b, 0x34, 0x09, 0x60, 0x60, 0x09, 0x8f, 0xac, 0x29, 0x1a,
0x59, 0xcb, 0xe4, 0x01, 0x5b, 0x05, 0x16, 0x62, 0x9f, 0x85, 0x25, 0x0f, 0xaf, 0x53, 0x1f, 0xb1,
0x72, 0xbf, 0xe2, 0x70, 0xaf, 0xf3, 0x42, 0xe9, 0x0f, 0x71, 0x77, 0x85, 0x5c, 0x68, 0x64, 0x12,
0x8a, 0x11, 0xff, 0x9a, 0x50, 0x8c, 0xc4, 0x57, 0x46, 0x31, 0xbc, 0xf5, 0x5e, 0xd2, 0x5f, 0xef,
0xfd, 0x33, 0xee, 0xee, 0x89, 0x83, 0x49, 0x74, 0x34, 0x05, 0xf3, 0x0a, 0x8c, 0xfe, 0x26, 0x69,
0x56, 0x4f, 0x3b, 0xe1, 0x75, 0x16, 0xf9, 0x49, 0xb8, 0x9c, 0xd8, 0x99, 0xe7, 0xa1, 0xd1, 0x29,
0xde, 0x58, 0xee, 0xc2, 0x8b, 0xb7, 0x0a, 0x24, 0x1f, 0x60, 0x16, 0xe9, 0x16, 0x44, 0xf2, 0x93,
0xf0, 0x51, 0x23, 0xe3, 0x39, 0x08, 0x1b, 0xa0, 0xdb, 0x90, 0xa7, 0x9d, 0x15, 0x49, 0xd3, 0x4d,
0x1e, 0x90, 0x7c, 0xe9, 0x1a, 0x6b, 0xa0, 0xac, 0xed, 0x13, 0x9e, 0x3d, 0xdd, 0x14, 0x73, 0x3a,
0xff, 0xe5, 0x49, 0x9a, 0xf2, 0xbe, 0xa4, 0xe9, 0x02, 0xe4, 0xc9, 0xd7, 0x9b, 0xba, 0xdc, 0xc1,
0x34, 0xb2, 0xe4, 0x45, 0x97, 0x20, 0xdc, 0x07, 0x34, 0x1e, 0x27, 0x51, 0x13, 0x32, 0xf8, 0x14,
0x0f, 0x2c, 0x96, 0x53, 0x06, 0xf2, 0x52, 0x56, 0xe2, 0x91, 0xc7, 0x1b, 0x55, 0xb2, 0xc8, 0xff,
0xf8, 0x7c, 0xb5, 0xc2, 0xb8, 0x9f, 0xd1, 0xfa, 0xaa, 0x85, 0xfb, 0xba, 0x75, 0x26, 0x72, 0x79,
0xe1, 0xaf, 0x09, 0x28, 0x07, 0xe2, 0xe7, 0xc4, 0xb5, 0xb5, 0x4d, 0x3e, 0xe1, 0xc1, 0x80, 0xa2,
0xad, 0xf7, 0x45, 0x80, 0x13, 0xd9, 0x94, 0xde, 0x93, 0x07, 0x16, 0x56, 0xf8, 0xa2, 0xe7, 0x4f,
0x64, 0xf3, 0x0d, 0x4a, 0x20, 0xbb, 0x4e, 0x1e, 0x0f, 0x4d, 0xac, 0x70, 0x34, 0x2a, 0x7b, 0x22,
0x9b, 0x87, 0x26, 0x56, 0x3c, 0xb3, 0xcc, 0x3e, 0xdc, 0x2c, 0xfd, 0x6b, 0x9c, 0x0b, 0xac, 0xb1,
0xa7, 0x44, 0xcf, 0x7b, 0x4b, 0x74, 0x54, 0x83, 0x9c, 0x6e, 0xa8, 0x9a, 0xa1, 0x5a, 0x67, 0x74,
0x63, 0x92, 0xa2, 0x33, 0x46, 0x97, 0xa1, 0xd8, 0xc7, 0x7d, 0x5d, 0xd3, 0x7a, 0x12, 0x73, 0x36,
0x05, 0x2a, 0xba, 0xc0, 0x89, 0x0d, 0xea, 0x73, 0x3e, 0x4c, 0xb8, 0xa7, 0xcf, 0x85, 0x62, 0xbe,
0xde, 0xe5, 0x5d, 0x99, 0xb0, 0xbc, 0x1e, 0x0a, 0x99, 0x44, 0x60, 0x7d, 0x9d, 0xf1, 0xb7, 0xb5,
0xc0, 0xc2, 0x4f, 0x28, 0x3e, 0xeb, 0xcf, 0x8d, 0xd0, 0x01, 0x2c, 0x3a, 0x87, 0x5f, 0x1a, 0x52,
0xa7, 0x60, 0x9b, 0x73, 0x54, 0xef, 0x51, 0x39, 0xf5, 0x93, 0x4d, 0xf4, 0x26, 0x3c, 0x1a, 0xf0,
0x6c, 0x8e, 0xea, 0x44, 0x54, 0x07, 0xf7, 0x88, 0xdf, 0xc1, 0xd9, 0xaa, 0xdd, 0xc5, 0x4a, 0x3e,
0xe4, 0x99, 0xdb, 0x86, 0x92, 0x3f, 0xcd, 0x9b, 0xb8, 0xfd, 0x97, 0xa1, 0x68, 0x60, 0x4b, 0x56,
0x07, 0x92, 0x0f, 0x54, 0x5d, 0x60, 0x44, 0x0e, 0xd5, 0xee, 0xc3, 0x23, 0x13, 0xd3, 0x3d, 0xf4,
0x02, 0xe4, 0xdd, 0x4c, 0x91, 0xad, 0xea, 0x14, 0xd0, 0xcd, 0xe5, 0x15, 0x7e, 0x1f, 0x77, 0x55,
0xfa, 0x61, 0xbc, 0x06, 0x64, 0x0c, 0x6c, 0x0e, 0x7b, 0x0c, 0x58, 0x2b, 0xdd, 0x78, 0x36, 0x5a,
0xa2, 0x48, 0xa8, 0xc3, 0x9e, 0x25, 0x72, 0x61, 0xe1, 0x3e, 0x64, 0x18, 0x05, 0x15, 0x20, 0x7b,
0xb8, 0x7b, 0x77, 0x77, 0xef, 0x8d, 0xdd, 0x4a, 0x0c, 0x01, 0x64, 0xd6, 0xeb, 0xf5, 0xc6, 0x7e,
0xab, 0x12, 0x47, 0x79, 0x48, 0xaf, 0x6f, 0xec, 0x89, 0xad, 0x4a, 0x82, 0x90, 0xc5, 0xc6, 0x9d,
0x46, 0xbd, 0x55, 0x49, 0xa2, 0x45, 0x28, 0xb2, 0xdf, 0xd2, 0xd6, 0x9e, 0x78, 0x6f, 0xbd, 0x55,
0x49, 0x79, 0x48, 0x07, 0x8d, 0xdd, 0xcd, 0x86, 0x58, 0x49, 0x0b, 0xff, 0x07, 0xe7, 0x43, 0x53,
0x4b, 0x17, 0xa3, 0x8b, 0x7b, 0x30, 0x3a, 0xe1, 0x17, 0x09, 0xa8, 0x85, 0xe7, 0x8b, 0xe8, 0x4e,
0x60, 0xe2, 0x37, 0xe6, 0x48, 0x36, 0x03, 0xb3, 0x47, 0x4f, 0x40, 0xc9, 0xc0, 0xc7, 0xd8, 0xea,
0x74, 0x59, 0xfe, 0xca, 0x02, 0x66, 0x51, 0x2c, 0x72, 0x2a, 0x15, 0x32, 0x19, 0xdb, 0x3b, 0xb8,
0x63, 0x49, 0xcc, 0x17, 0x31, 0xa3, 0xcb, 0x13, 0x36, 0x42, 0x3d, 0x60, 0x44, 0xe1, 0xed, 0xb9,
0xd6, 0x32, 0x0f, 0x69, 0xb1, 0xd1, 0x12, 0xdf, 0xac, 0x24, 0x11, 0x82, 0x12, 0xfd, 0x29, 0x1d,
0xec, 0xae, 0xef, 0x1f, 0x34, 0xf7, 0xc8, 0x5a, 0x2e, 0x41, 0xd9, 0x5e, 0x4b, 0x9b, 0x98, 0x16,
0xfe, 0x94, 0x80, 0x47, 0x43, 0xb2, 0x5d, 0x74, 0x1b, 0xc0, 0x1a, 0x49, 0x06, 0xee, 0x68, 0x86,
0x12, 0x6e, 0x64, 0xad, 0x91, 0x48, 0x39, 0xc4, 0xbc, 0xc5, 0x7f, 0x99, 0x53, 0xa0, 0x5d, 0xf4,
0x32, 0x57, 0x4a, 0x66, 0x65, 0x1f, 0xb5, 0x8b, 0x13, 0x10, 0x4c, 0xdc, 0x21, 0x8a, 0xe9, 0xda,
0x52, 0xc5, 0x94, 0x1f, 0xdd, 0x9b, 0xe4, 0x54, 0x22, 0x36, 0x56, 0xe6, 0x73, 0x27, 0xe9, 0x87,
0x73, 0x27, 0xc2, 0xaf, 0x92, 0xde, 0x85, 0xf5, 0x27, 0xf7, 0x7b, 0x90, 0x31, 0x2d, 0xd9, 0x1a,
0x9a, 0xdc, 0xe0, 0x5e, 0x88, 0x5a, 0x29, 0xac, 0xd9, 0x3f, 0x0e, 0xa8, 0xb8, 0xc8, 0xd5, 0x7c,
0xb7, 0xde, 0xa6, 0x70, 0x0b, 0x4a, 0xfe, 0xc5, 0x09, 0x3f, 0x32, 0xae, 0xcf, 0x49, 0x08, 0x6f,
0xb9, 0xf9, 0x97, 0x07, 0x5f, 0xdc, 0x82, 0x52, 0xa0, 0x5c, 0x8a, 0x8f, 0xd7, 0xf3, 0x2e, 0x3e,
0xe8, 0x94, 0x42, 0x62, 0xf1, 0xd4, 0x3b, 0x14, 0x7e, 0x1d, 0x87, 0xc7, 0xa6, 0x14, 0x54, 0xe8,
0xf5, 0x80, 0x21, 0xbc, 0x38, 0x4f, 0x39, 0xb6, 0xc6, 0x68, 0x7e, 0x53, 0x10, 0x6e, 0xc2, 0x82,
0x97, 0x1e, 0x6d, 0x15, 0x7e, 0x9a, 0x74, 0x83, 0x82, 0x1f, 0xda, 0xfc, 0xda, 0x32, 0xd1, 0x80,
0x21, 0x26, 0xe6, 0x34, 0xc4, 0x89, 0xd9, 0x44, 0xf2, 0x9b, 0xcb, 0x26, 0x52, 0x0f, 0x99, 0x4d,
0x78, 0x4f, 0x64, 0xda, 0x7f, 0x22, 0xc7, 0x02, 0x7f, 0x66, 0x42, 0xe0, 0x7f, 0x13, 0xc0, 0xd3,
0x9c, 0x5c, 0x86, 0xb4, 0xa1, 0x0d, 0x07, 0x0a, 0x35, 0x93, 0xb4, 0xc8, 0x06, 0xe8, 0x16, 0xa4,
0x89, 0xb9, 0xd9, 0x8b, 0x39, 0xee, 0x9a, 0x89, 0xb9, 0x78, 0x40, 0x65, 0xc6, 0x2d, 0xa8, 0x80,
0xc6, 0x1b, 0x44, 0x21, 0xaf, 0x78, 0xc5, 0xff, 0x8a, 0xc7, 0x43, 0x5b, 0x4d, 0x93, 0x5f, 0xf5,
0x3e, 0xa4, 0xa9, 0x79, 0x90, 0x04, 0x88, 0x36, 0x39, 0x79, 0x45, 0x4d, 0x7e, 0xa3, 0x1f, 0x01,
0xc8, 0x96, 0x65, 0xa8, 0xed, 0xa1, 0xfb, 0x82, 0xd5, 0xc9, 0xe6, 0xb5, 0x6e, 0xf3, 0x6d, 0x5c,
0xe0, 0x76, 0xb6, 0xec, 0x8a, 0x7a, 0x6c, 0xcd, 0xa3, 0x50, 0xd8, 0x85, 0x92, 0x5f, 0xd6, 0xae,
0x01, 0xd9, 0x37, 0xf8, 0x6b, 0x40, 0x56, 0xd2, 0xf3, 0x1a, 0xd0, 0xa9, 0x20, 0x93, 0xac, 0x9f,
0x4d, 0x07, 0xc2, 0xbf, 0xe2, 0xb0, 0xe0, 0xb5, 0xce, 0xff, 0xb5, 0x32, 0x4a, 0xf8, 0x30, 0x0e,
0x39, 0x67, 0xf2, 0x21, 0xcd, 0x64, 0x77, 0xed, 0x12, 0xde, 0xd6, 0x29, 0xeb, 0x4e, 0x27, 0x9d,
0x9e, 0xf7, 0x4b, 0x4e, 0xc6, 0x15, 0x86, 0x7a, 0x7b, 0x57, 0xda, 0x6e, 0xfb, 0xf3, 0x04, 0xf3,
0xe7, 0xfc, 0x3b, 0x48, 0xaa, 0x81, 0xbe, 0x07, 0x19, 0xb9, 0xe3, 0x60, 0xfd, 0xa5, 0x09, 0xe0,
0xaf, 0xcd, 0xba, 0xd6, 0x1a, 0xad, 0x53, 0x4e, 0x91, 0x4b, 0xf0, 0xaf, 0x4a, 0x38, 0x3d, 0xf3,
0x57, 0x89, 0x5e, 0xc6, 0xe3, 0x77, 0x9b, 0x25, 0x80, 0xc3, 0xdd, 0x7b, 0x7b, 0x9b, 0xdb, 0x5b,
0xdb, 0x8d, 0x4d, 0x9e, 0x73, 0x6d, 0x6e, 0x36, 0x36, 0x2b, 0x09, 0xc2, 0x27, 0x36, 0xee, 0xed,
0x1d, 0x35, 0x36, 0x2b, 0x49, 0xe1, 0x25, 0xc8, 0x3b, 0xae, 0x07, 0x55, 0x21, 0x6b, 0xf7, 0x2d,
0xe2, 0xdc, 0x01, 0xb0, 0x21, 0xbd, 0x2f, 0xa1, 0xbd, 0xc7, 0x3b, 0xc6, 0x49, 0x91, 0x0d, 0x04,
0x05, 0xca, 0x01, 0xbf, 0x85, 0x5e, 0x82, 0xac, 0x3e, 0x6c, 0x4b, 0xb6, 0xd1, 0x06, 0xba, 0x3c,
0x36, 0x14, 0x31, 0x6c, 0xf7, 0xd4, 0xce, 0x5d, 0x7c, 0x66, 0x2f, 0x93, 0x3e, 0x6c, 0xdf, 0x65,
0xb6, 0xcd, 0xde, 0x92, 0xf0, 0xbe, 0xe5, 0xc7, 0x71, 0xc8, 0xd9, 0x67, 0x15, 0x7d, 0x1f, 0xf2,
0x8e, 0x4f, 0x74, 0xee, 0xd1, 0x84, 0x3a, 0x53, 0xae, 0xdf, 0x15, 0x41, 0xd7, 0x60, 0xd1, 0x54,
0x4f, 0x06, 0x76, 0x93, 0x8b, 0x61, 0x7f, 0x09, 0x7a, 0x68, 0xca, 0xec, 0xc1, 0x8e, 0x0d, 0x58,
0xdd, 0x49, 0xe5, 0x92, 0x95, 0xd4, 0x9d, 0x54, 0x2e, 0x55, 0x49, 0x93, 0xb0, 0x58, 0x09, 0x3a,
0x8e, 0x6f, 0xf3, 0x63, 0x48, 0xfa, 0x1d, 0x88, 0xef, 0xcc, 0x36, 0x03, 0xe1, 0xfb, 0x83, 0x04,
0x14, 0x3c, 0x6d, 0x34, 0xf4, 0xff, 0x1e, 0x2f, 0x56, 0x9a, 0x10, 0x77, 0x3c, 0xbc, 0xee, 0x75,
0x0d, 0xff, 0xc4, 0x12, 0xf3, 0x4f, 0x2c, 0xec, 0xda, 0x8d, 0xdd, 0x8d, 0x4b, 0xcd, 0xdd, 0x8d,
0x7b, 0x06, 0x90, 0xa5, 0x59, 0x72, 0x4f, 0x3a, 0xd5, 0x2c, 0x75, 0x70, 0x22, 0x31, 0x3b, 0x61,
0x3e, 0xa7, 0x42, 0x9f, 0x1c, 0xd1, 0x07, 0xfb, 0x8e, 0xc9, 0x38, 0x45, 0xe2, 0xbc, 0xb7, 0x2f,
0xce, 0x41, 0x86, 0xd7, 0x41, 0xec, 0xfa, 0x05, 0x1f, 0x4d, 0x6c, 0x3b, 0xd6, 0x20, 0xd7, 0xc7,
0x96, 0x4c, 0x1d, 0x28, 0x8b, 0x99, 0xce, 0xf8, 0xda, 0x8b, 0x50, 0xf0, 0x5c, 0x84, 0x21, 0x3e,
0x75, 0xb7, 0xf1, 0x46, 0x25, 0x56, 0xcb, 0x7e, 0xf4, 0xc9, 0xa5, 0xe4, 0x2e, 0x7e, 0x8f, 0x1c,
0x37, 0xb1, 0x51, 0x6f, 0x36, 0xea, 0x77, 0x2b, 0xf1, 0x5a, 0xe1, 0xa3, 0x4f, 0x2e, 0x65, 0x45,
0x4c, 0xbb, 0x44, 0xd7, 0xee, 0x42, 0x39, 0xb0, 0x31, 0xfe, 0xd3, 0x8d, 0xa0, 0xb4, 0x79, 0xb8,
0xbf, 0xb3, 0x5d, 0x5f, 0x6f, 0x35, 0xa4, 0xa3, 0xbd, 0x56, 0xa3, 0x12, 0x47, 0x8f, 0xc2, 0xd2,
0xce, 0xf6, 0x6b, 0xcd, 0x96, 0x54, 0xdf, 0xd9, 0x6e, 0xec, 0xb6, 0xa4, 0xf5, 0x56, 0x6b, 0xbd,
0x7e, 0xb7, 0x92, 0xb8, 0xf1, 0x9b, 0x02, 0x94, 0xd7, 0x37, 0xea, 0xdb, 0xa4, 0x12, 0x54, 0x3b,
0x32, 0xf5, 0x15, 0x75, 0x48, 0x51, 0xc8, 0x79, 0xea, 0xd5, 0xe6, 0xda, 0xf4, 0x36, 0x22, 0xda,
0x82, 0x34, 0x45, 0xa3, 0xd1, 0xf4, 0xbb, 0xce, 0xb5, 0x19, 0x7d, 0x45, 0xf2, 0x31, 0xf4, 0x38,
0x4d, 0xbd, 0xfc, 0x5c, 0x9b, 0xde, 0x66, 0x44, 0x3b, 0x90, 0xb5, 0xc1, 0xc2, 0x59, 0xd7, 0x88,
0x6b, 0x33, 0xfb, 0x75, 0x64, 0x6a, 0x0c, 0xd4, 0x9d, 0x7e, 0x2f, 0xba, 0x36, 0xa3, 0x01, 0x89,
0xb6, 0x21, 0xc3, 0xf1, 0x94, 0x19, 0x57, 0x82, 0x6b, 0xb3, 0xfa, 0x6e, 0x48, 0x84, 0xbc, 0x0b,
0x97, 0xcf, 0xbe, 0xed, 0x5d, 0x8b, 0xd0, 0x5b, 0x45, 0xf7, 0xa1, 0xe8, 0xc7, 0x68, 0xa2, 0x5d,
0x3b, 0xae, 0x45, 0xec, 0xf0, 0x11, 0xfd, 0x7e, 0xc0, 0x26, 0xda, 0x35, 0xe4, 0x5a, 0xc4, 0x86,
0x1f, 0x7a, 0x07, 0x16, 0xc7, 0x01, 0x95, 0xe8, 0xb7, 0x92, 0x6b, 0x73, 0xb4, 0x00, 0x51, 0x1f,
0xd0, 0x04, 0x20, 0x66, 0x8e, 0x4b, 0xca, 0xb5, 0x79, 0x3a, 0x82, 0x48, 0x81, 0x72, 0x10, 0xdc,
0x88, 0x7a, 0x69, 0xb9, 0x16, 0xb9, 0x3b, 0xc8, 0xde, 0xe2, 0xaf, 0xf4, 0xa3, 0x5e, 0x62, 0xae,
0x45, 0x6e, 0x16, 0xa2, 0x43, 0x00, 0x4f, 0xa5, 0x1a, 0xe1, 0x52, 0x73, 0x2d, 0x4a, 0xdb, 0x10,
0xe9, 0xb0, 0x34, 0xa9, 0x42, 0x9d, 0xe7, 0x8e, 0x73, 0x6d, 0xae, 0x6e, 0x22, 0xb1, 0x67, 0x7f,
0xad, 0x19, 0xed, 0xce, 0x73, 0x2d, 0x62, 0x5b, 0x71, 0xa3, 0xf1, 0xe9, 0x17, 0x2b, 0xf1, 0xcf,
0xbe, 0x58, 0x89, 0xff, 0xfd, 0x8b, 0x95, 0xf8, 0xc7, 0x5f, 0xae, 0xc4, 0x3e, 0xfb, 0x72, 0x25,
0xf6, 0x97, 0x2f, 0x57, 0x62, 0x3f, 0x78, 0xfa, 0x44, 0xb5, 0xba, 0xc3, 0xf6, 0x5a, 0x47, 0xeb,
0x5f, 0xf7, 0xfe, 0xfd, 0x65, 0xd2, 0x5f, 0x72, 0xda, 0x19, 0x1a, 0x50, 0x6f, 0xfe, 0x27, 0x00,
0x00, 0xff, 0xff, 0xc7, 0x45, 0xe7, 0x5f, 0xb2, 0x33, 0x00, 0x00,
// 3459 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5b, 0x4b, 0x93, 0x1b, 0xd5,
0xf5, 0x97, 0x5a, 0xef, 0xa3, 0xd1, 0x63, 0xee, 0x0c, 0x46, 0x16, 0xf6, 0x8c, 0x69, 0x97, 0xc1,
0x36, 0x30, 0xe6, 0x3f, 0xfe, 0x1b, 0x4c, 0x0c, 0xa1, 0x66, 0x34, 0x32, 0x1a, 0x7b, 0x3c, 0x33,
0xf4, 0x68, 0x4c, 0x91, 0x87, 0x9b, 0x96, 0xfa, 0xce, 0xa8, 0xb1, 0xa4, 0x6e, 0xba, 0x5b, 0x83,
0x86, 0x65, 0x28, 0x36, 0x54, 0xaa, 0xc2, 0x26, 0x95, 0xa4, 0x2a, 0xec, 0x92, 0xaa, 0xe4, 0x1b,
0x64, 0x95, 0x55, 0x16, 0x2c, 0xb2, 0x60, 0x95, 0xa4, 0xb2, 0x20, 0x29, 0xd8, 0xe5, 0x0b, 0x64,
0x97, 0xa4, 0xee, 0xa3, 0x5f, 0x52, 0xb7, 0x1e, 0x18, 0xa8, 0x4a, 0x85, 0x9d, 0xfa, 0xf4, 0x39,
0xa7, 0xef, 0xe3, 0xdc, 0xf3, 0xf8, 0x9d, 0x2b, 0x78, 0xc2, 0xc6, 0x7d, 0x15, 0x9b, 0x3d, 0xad,
0x6f, 0x5f, 0x53, 0x5a, 0x6d, 0xed, 0x9a, 0x7d, 0x6a, 0x60, 0x6b, 0xcd, 0x30, 0x75, 0x5b, 0x47,
0x25, 0xef, 0xe5, 0x1a, 0x79, 0x59, 0x3d, 0xef, 0xe3, 0x6e, 0x9b, 0xa7, 0x86, 0xad, 0x5f, 0x33,
0x4c, 0x5d, 0x3f, 0x62, 0xfc, 0xd5, 0x73, 0xbe, 0xd7, 0x54, 0x8f, 0x5f, 0x5b, 0xe0, 0x2d, 0x17,
0x7e, 0x88, 0x4f, 0x9d, 0xb7, 0xe7, 0xc7, 0x64, 0x0d, 0xc5, 0x54, 0x7a, 0xce, 0xeb, 0xd5, 0x63,
0x5d, 0x3f, 0xee, 0xe2, 0x6b, 0xf4, 0xa9, 0x35, 0x38, 0xba, 0x66, 0x6b, 0x3d, 0x6c, 0xd9, 0x4a,
0xcf, 0xe0, 0x0c, 0xcb, 0xc7, 0xfa, 0xb1, 0x4e, 0x7f, 0x5e, 0x23, 0xbf, 0x18, 0x55, 0xfc, 0x37,
0x40, 0x46, 0xc2, 0xef, 0x0c, 0xb0, 0x65, 0xa3, 0x75, 0x48, 0xe2, 0x76, 0x47, 0xaf, 0xc4, 0x2f,
0xc4, 0x2f, 0xe7, 0xd7, 0xcf, 0xad, 0x8d, 0x4c, 0x6e, 0x8d, 0xf3, 0xd5, 0xdb, 0x1d, 0xbd, 0x11,
0x93, 0x28, 0x2f, 0xba, 0x01, 0xa9, 0xa3, 0xee, 0xc0, 0xea, 0x54, 0x04, 0x2a, 0x74, 0x3e, 0x4a,
0xe8, 0x36, 0x61, 0x6a, 0xc4, 0x24, 0xc6, 0x4d, 0x3e, 0xa5, 0xf5, 0x8f, 0xf4, 0x4a, 0x62, 0xf2,
0xa7, 0xb6, 0xfb, 0x47, 0xf4, 0x53, 0x84, 0x17, 0x6d, 0x02, 0x68, 0x7d, 0xcd, 0x96, 0xdb, 0x1d,
0x45, 0xeb, 0x57, 0x92, 0x54, 0xf2, 0xc9, 0x68, 0x49, 0xcd, 0xae, 0x11, 0xc6, 0x46, 0x4c, 0xca,
0x69, 0xce, 0x03, 0x19, 0xee, 0x3b, 0x03, 0x6c, 0x9e, 0x56, 0x52, 0x93, 0x87, 0xfb, 0x3a, 0x61,
0x22, 0xc3, 0xa5, 0xdc, 0x68, 0x1b, 0xf2, 0x2d, 0x7c, 0xac, 0xf5, 0xe5, 0x56, 0x57, 0x6f, 0x3f,
0xac, 0xa4, 0xa9, 0xb0, 0x18, 0x25, 0xbc, 0x49, 0x58, 0x37, 0x09, 0xe7, 0xa6, 0x50, 0x89, 0x37,
0x62, 0x12, 0xb4, 0x5c, 0x0a, 0x7a, 0x19, 0xb2, 0xed, 0x0e, 0x6e, 0x3f, 0x94, 0xed, 0x61, 0x25,
0x43, 0xf5, 0xac, 0x46, 0xe9, 0xa9, 0x11, 0xbe, 0xe6, 0xb0, 0x11, 0x93, 0x32, 0x6d, 0xf6, 0x13,
0xdd, 0x06, 0x50, 0x71, 0x57, 0x3b, 0xc1, 0x26, 0x91, 0xcf, 0x4e, 0x5e, 0x83, 0x2d, 0xc6, 0xd9,
0x1c, 0xf2, 0x61, 0xe4, 0x54, 0x87, 0x80, 0x6a, 0x90, 0xc3, 0x7d, 0x95, 0x4f, 0x27, 0x47, 0xd5,
0x5c, 0x88, 0xdc, 0xef, 0xbe, 0xea, 0x9f, 0x4c, 0x16, 0xf3, 0x67, 0x74, 0x13, 0xd2, 0x6d, 0xbd,
0xd7, 0xd3, 0xec, 0x0a, 0x50, 0x0d, 0x2b, 0x91, 0x13, 0xa1, 0x5c, 0x8d, 0x98, 0xc4, 0xf9, 0xd1,
0x2e, 0x14, 0xbb, 0x9a, 0x65, 0xcb, 0x56, 0x5f, 0x31, 0xac, 0x8e, 0x6e, 0x5b, 0x95, 0x3c, 0xd5,
0x70, 0x29, 0x4a, 0xc3, 0x8e, 0x66, 0xd9, 0x07, 0x0e, 0x73, 0x23, 0x26, 0x15, 0xba, 0x7e, 0x02,
0xd1, 0xa7, 0x1f, 0x1d, 0x61, 0xd3, 0x55, 0x58, 0x59, 0x98, 0xac, 0x6f, 0x8f, 0x70, 0x3b, 0xf2,
0x44, 0x9f, 0xee, 0x27, 0xa0, 0xef, 0xc3, 0x52, 0x57, 0x57, 0x54, 0x57, 0x9d, 0xdc, 0xee, 0x0c,
0xfa, 0x0f, 0x2b, 0x05, 0xaa, 0xf4, 0x4a, 0xe4, 0x20, 0x75, 0x45, 0x75, 0x54, 0xd4, 0x88, 0x40,
0x23, 0x26, 0x2d, 0x76, 0x47, 0x89, 0xe8, 0x01, 0x2c, 0x2b, 0x86, 0xd1, 0x3d, 0x1d, 0xd5, 0x5e,
0xa4, 0xda, 0xaf, 0x46, 0x69, 0xdf, 0x20, 0x32, 0xa3, 0xea, 0x91, 0x32, 0x46, 0x45, 0x4d, 0x28,
0x1b, 0x26, 0x36, 0x14, 0x13, 0xcb, 0x86, 0xa9, 0x1b, 0xba, 0xa5, 0x74, 0x2b, 0x25, 0xaa, 0xfb,
0xe9, 0x28, 0xdd, 0xfb, 0x8c, 0x7f, 0x9f, 0xb3, 0x37, 0x62, 0x52, 0xc9, 0x08, 0x92, 0x98, 0x56,
0xbd, 0x8d, 0x2d, 0xcb, 0xd3, 0x5a, 0x9e, 0xa6, 0x95, 0xf2, 0x07, 0xb5, 0x06, 0x48, 0xa8, 0x0e,
0x79, 0x3c, 0x24, 0xe2, 0xf2, 0x89, 0x6e, 0xe3, 0xca, 0xe2, 0xe4, 0x83, 0x55, 0xa7, 0xac, 0xf7,
0x75, 0x1b, 0x93, 0x43, 0x85, 0xdd, 0x27, 0xa4, 0xc0, 0x63, 0x27, 0xd8, 0xd4, 0x8e, 0x4e, 0xa9,
0x1a, 0x99, 0xbe, 0xb1, 0x34, 0xbd, 0x5f, 0x41, 0x54, 0xe1, 0x33, 0x51, 0x0a, 0xef, 0x53, 0x21,
0xa2, 0xa2, 0xee, 0x88, 0x34, 0x62, 0xd2, 0xd2, 0xc9, 0x38, 0x99, 0x98, 0xd8, 0x91, 0xd6, 0x57,
0xba, 0xda, 0x7b, 0x98, 0x1f, 0x9b, 0xa5, 0xc9, 0x26, 0x76, 0x9b, 0x73, 0xd3, 0xb3, 0x42, 0x4c,
0xec, 0xc8, 0x4f, 0xd8, 0xcc, 0x40, 0xea, 0x44, 0xe9, 0x0e, 0xb0, 0xf8, 0x34, 0xe4, 0x7d, 0x8e,
0x15, 0x55, 0x20, 0xd3, 0xc3, 0x96, 0xa5, 0x1c, 0x63, 0xea, 0x87, 0x73, 0x92, 0xf3, 0x28, 0x16,
0x61, 0xc1, 0xef, 0x4c, 0xc5, 0x8f, 0xe2, 0xae, 0x24, 0xf1, 0x93, 0x44, 0xf2, 0x04, 0x9b, 0x74,
0xda, 0x5c, 0x92, 0x3f, 0xa2, 0x8b, 0x50, 0xa0, 0x43, 0x96, 0x9d, 0xf7, 0xc4, 0x59, 0x27, 0xa5,
0x05, 0x4a, 0xbc, 0xcf, 0x99, 0x56, 0x21, 0x6f, 0xac, 0x1b, 0x2e, 0x4b, 0x82, 0xb2, 0x80, 0xb1,
0x6e, 0x38, 0x0c, 0x4f, 0xc2, 0x02, 0x99, 0x9f, 0xcb, 0x91, 0xa4, 0x1f, 0xc9, 0x13, 0x1a, 0x67,
0x11, 0xff, 0x28, 0x40, 0x79, 0xd4, 0x01, 0xa3, 0x9b, 0x90, 0x24, 0xb1, 0x88, 0x87, 0x95, 0xea,
0x1a, 0x0b, 0x54, 0x6b, 0x4e, 0xa0, 0x5a, 0x6b, 0x3a, 0x81, 0x6a, 0x33, 0xfb, 0xc9, 0x67, 0xab,
0xb1, 0x8f, 0xfe, 0xb6, 0x1a, 0x97, 0xa8, 0x04, 0x3a, 0x4b, 0x7c, 0xa5, 0xa2, 0xf5, 0x65, 0x4d,
0xa5, 0x43, 0xce, 0x11, 0x47, 0xa8, 0x68, 0xfd, 0x6d, 0x15, 0xed, 0x40, 0xb9, 0xad, 0xf7, 0x2d,
0xdc, 0xb7, 0x06, 0x96, 0xcc, 0x02, 0x21, 0x0f, 0x26, 0x01, 0x77, 0xc8, 0xc2, 0x6b, 0xcd, 0xe1,
0xdc, 0xa7, 0x8c, 0x52, 0xa9, 0x1d, 0x24, 0x10, 0xb7, 0x7a, 0xa2, 0x74, 0x35, 0x55, 0xb1, 0x75,
0xd3, 0xaa, 0x24, 0x2f, 0x24, 0x42, 0xfd, 0xe1, 0x7d, 0x87, 0xe5, 0xd0, 0x50, 0x15, 0x1b, 0x6f,
0x26, 0xc9, 0x70, 0x25, 0x9f, 0x24, 0x7a, 0x0a, 0x4a, 0x8a, 0x61, 0xc8, 0x96, 0xad, 0xd8, 0x58,
0x6e, 0x9d, 0xda, 0xd8, 0xa2, 0x81, 0x66, 0x41, 0x2a, 0x28, 0x86, 0x71, 0x40, 0xa8, 0x9b, 0x84,
0x88, 0x2e, 0x41, 0x91, 0xc4, 0x24, 0x4d, 0xe9, 0xca, 0x1d, 0xac, 0x1d, 0x77, 0x6c, 0x1a, 0x52,
0x12, 0x52, 0x81, 0x53, 0x1b, 0x94, 0x28, 0xaa, 0xee, 0x8e, 0xd3, 0x78, 0x84, 0x10, 0x24, 0x55,
0xc5, 0x56, 0xe8, 0x4a, 0x2e, 0x48, 0xf4, 0x37, 0xa1, 0x19, 0x8a, 0xdd, 0xe1, 0xeb, 0x43, 0x7f,
0xa3, 0x33, 0x90, 0xe6, 0x6a, 0x13, 0x54, 0x2d, 0x7f, 0x42, 0xcb, 0x90, 0x32, 0x4c, 0xfd, 0x04,
0xd3, 0xad, 0xcb, 0x4a, 0xec, 0x41, 0x7c, 0x5f, 0x80, 0xc5, 0xb1, 0xc8, 0x45, 0xf4, 0x76, 0x14,
0xab, 0xe3, 0x7c, 0x8b, 0xfc, 0x46, 0x2f, 0x10, 0xbd, 0x8a, 0x8a, 0x4d, 0x1e, 0xed, 0x2b, 0xe3,
0x4b, 0xdd, 0xa0, 0xef, 0xf9, 0xd2, 0x70, 0x6e, 0x74, 0x17, 0xca, 0x5d, 0xc5, 0xb2, 0x65, 0xe6,
0xfd, 0x65, 0x5f, 0xe4, 0x7f, 0x62, 0x6c, 0x91, 0x59, 0xac, 0x20, 0x06, 0xcd, 0x95, 0x14, 0x89,
0xa8, 0x47, 0x45, 0x87, 0xb0, 0xdc, 0x3a, 0x7d, 0x4f, 0xe9, 0xdb, 0x5a, 0x1f, 0xcb, 0x63, 0xbb,
0x36, 0x9e, 0x4a, 0xdc, 0xd3, 0xac, 0x16, 0xee, 0x28, 0x27, 0x9a, 0xee, 0x0c, 0x6b, 0xc9, 0x95,
0x77, 0x77, 0xd4, 0x12, 0x25, 0x28, 0x06, 0xc3, 0x2e, 0x2a, 0x82, 0x60, 0x0f, 0xf9, 0xfc, 0x05,
0x7b, 0x88, 0x9e, 0x87, 0x24, 0x99, 0x23, 0x9d, 0x7b, 0x31, 0xe4, 0x43, 0x5c, 0xae, 0x79, 0x6a,
0x60, 0x89, 0x72, 0x8a, 0xa2, 0x7b, 0x1a, 0xdc, 0x50, 0x3c, 0xaa, 0x55, 0xbc, 0x02, 0xa5, 0x91,
0x38, 0xeb, 0xdb, 0xbe, 0xb8, 0x7f, 0xfb, 0xc4, 0x12, 0x14, 0x02, 0x01, 0x55, 0x3c, 0x03, 0xcb,
0x61, 0xf1, 0x51, 0xec, 0xb8, 0xf4, 0x40, 0x9c, 0x43, 0x37, 0x20, 0xeb, 0x06, 0x48, 0x76, 0x1a,
0xcf, 0x8e, 0xcd, 0xc2, 0x61, 0x96, 0x5c, 0x56, 0x72, 0x0c, 0x89, 0x55, 0x53, 0x73, 0x10, 0xe8,
0xc0, 0x33, 0x8a, 0x61, 0x34, 0x14, 0xab, 0x23, 0xbe, 0x05, 0x95, 0xa8, 0xe0, 0x37, 0x32, 0x8d,
0xa4, 0x6b, 0x85, 0x67, 0x20, 0x7d, 0xa4, 0x9b, 0x3d, 0xc5, 0xa6, 0xca, 0x0a, 0x12, 0x7f, 0x22,
0xd6, 0xc9, 0x02, 0x61, 0x82, 0x92, 0xd9, 0x83, 0x28, 0xc3, 0xd9, 0xc8, 0x00, 0x48, 0x44, 0xb4,
0xbe, 0x8a, 0xd9, 0x7a, 0x16, 0x24, 0xf6, 0xe0, 0x29, 0x62, 0x83, 0x65, 0x0f, 0xe4, 0xb3, 0x16,
0x9d, 0x2b, 0xd5, 0x9f, 0x93, 0xf8, 0x93, 0xf8, 0xdb, 0x04, 0x9c, 0x09, 0x0f, 0x83, 0xe8, 0x02,
0x2c, 0xf4, 0x94, 0xa1, 0x6c, 0x0f, 0xf9, 0x59, 0x66, 0xdb, 0x01, 0x3d, 0x65, 0xd8, 0x1c, 0xb2,
0x83, 0x5c, 0x86, 0x84, 0x3d, 0xb4, 0x2a, 0xc2, 0x85, 0xc4, 0xe5, 0x05, 0x89, 0xfc, 0x44, 0x87,
0xb0, 0xd8, 0xd5, 0xdb, 0x4a, 0x57, 0xf6, 0x59, 0x3c, 0x37, 0xf6, 0x8b, 0x63, 0x8b, 0xcd, 0x02,
0x1a, 0x56, 0xc7, 0x8c, 0xbe, 0x44, 0x75, 0xec, 0xb8, 0x96, 0xff, 0x35, 0x59, 0xbd, 0x6f, 0x8f,
0x52, 0x01, 0x4f, 0xe1, 0xf8, 0xec, 0xf4, 0xdc, 0x3e, 0xfb, 0x79, 0x58, 0xee, 0xe3, 0xa1, 0xed,
0x1b, 0x23, 0x33, 0x9c, 0x0c, 0xdd, 0x0b, 0x44, 0xde, 0x79, 0xdf, 0x27, 0x36, 0x84, 0xae, 0xd0,
0xcc, 0xc2, 0xd0, 0x2d, 0x6c, 0xca, 0x8a, 0xaa, 0x9a, 0xd8, 0xb2, 0x68, 0x66, 0xbb, 0x40, 0xd3,
0x05, 0x4a, 0xdf, 0x60, 0x64, 0xf1, 0x17, 0xfe, 0xbd, 0x0a, 0x66, 0x12, 0x7c, 0x27, 0xe2, 0xde,
0x4e, 0x1c, 0xc0, 0x32, 0x97, 0x57, 0x03, 0x9b, 0x21, 0xcc, 0xea, 0x79, 0x90, 0x23, 0x3e, 0xc3,
0x3e, 0x24, 0x1e, 0x6d, 0x1f, 0x1c, 0x6f, 0x9b, 0xf4, 0x79, 0xdb, 0xff, 0xb2, 0xbd, 0x79, 0xd5,
0x8d, 0x22, 0x5e, 0x9a, 0x16, 0x1a, 0x45, 0xbc, 0x79, 0x09, 0x01, 0xf7, 0xf6, 0xcb, 0x38, 0x54,
0xa3, 0xf3, 0xb2, 0x50, 0x55, 0xcf, 0xc0, 0xa2, 0x3b, 0x17, 0x77, 0x7c, 0xec, 0xd4, 0x97, 0xdd,
0x17, 0x7c, 0x80, 0x91, 0x51, 0xf1, 0x12, 0x14, 0x47, 0xb2, 0x46, 0xb6, 0x0b, 0x85, 0x13, 0xff,
0xf7, 0xc5, 0x9f, 0x26, 0x5c, 0xaf, 0x1a, 0x48, 0xed, 0x42, 0x2c, 0xef, 0x75, 0x58, 0x52, 0x71,
0x5b, 0x53, 0xbf, 0xac, 0xe1, 0x2d, 0x72, 0xe9, 0x6f, 0xed, 0x6e, 0x06, 0xbb, 0xfb, 0x73, 0x1e,
0xb2, 0x12, 0xb6, 0x0c, 0x92, 0xd2, 0xa1, 0x4d, 0xc8, 0xe1, 0x61, 0x1b, 0x1b, 0xb6, 0x93, 0x05,
0x87, 0x57, 0x13, 0x8c, 0xbb, 0xee, 0x70, 0x92, 0xda, 0xd8, 0x15, 0x43, 0xd7, 0x39, 0x0c, 0x12,
0x8d, 0x68, 0x70, 0x71, 0x3f, 0x0e, 0xf2, 0x82, 0x83, 0x83, 0x24, 0x22, 0x4b, 0x61, 0x26, 0x35,
0x02, 0x84, 0x5c, 0xe7, 0x40, 0x48, 0x72, 0xca, 0xc7, 0x02, 0x48, 0x48, 0x2d, 0x80, 0x84, 0xa4,
0xa6, 0x4c, 0x33, 0x02, 0x0a, 0x79, 0xc1, 0x81, 0x42, 0xd2, 0x53, 0x46, 0x3c, 0x82, 0x85, 0xdc,
0x09, 0x62, 0x21, 0x99, 0x88, 0xd0, 0xe6, 0x48, 0x4f, 0x04, 0x43, 0x5e, 0xf1, 0x81, 0x21, 0xd9,
0x48, 0x14, 0x82, 0x29, 0x0a, 0x41, 0x43, 0x5e, 0x0b, 0xa0, 0x21, 0xb9, 0x29, 0xeb, 0x30, 0x01,
0x0e, 0xd9, 0xf2, 0xc3, 0x21, 0x10, 0x89, 0xaa, 0xf0, 0x7d, 0x8f, 0xc2, 0x43, 0x5e, 0x72, 0xf1,
0x90, 0x7c, 0x24, 0xb0, 0xc3, 0xe7, 0x32, 0x0a, 0x88, 0xec, 0x8d, 0x01, 0x22, 0x0c, 0xc0, 0x78,
0x2a, 0x52, 0xc5, 0x14, 0x44, 0x64, 0x6f, 0x0c, 0x11, 0x29, 0x4c, 0x51, 0x38, 0x05, 0x12, 0xf9,
0x41, 0x38, 0x24, 0x12, 0x0d, 0x5a, 0xf0, 0x61, 0xce, 0x86, 0x89, 0xc8, 0x11, 0x98, 0x48, 0x29,
0xb2, 0x7e, 0x67, 0xea, 0x67, 0x06, 0x45, 0x0e, 0x43, 0x40, 0x11, 0x06, 0x5f, 0x5c, 0x8e, 0x54,
0x3e, 0x03, 0x2a, 0x72, 0x18, 0x82, 0x8a, 0x2c, 0x4e, 0x55, 0x3b, 0x15, 0x16, 0xb9, 0x1d, 0x84,
0x45, 0xd0, 0x94, 0x33, 0x16, 0x89, 0x8b, 0xb4, 0xa2, 0x70, 0x11, 0x86, 0x5d, 0x3c, 0x1b, 0xa9,
0x71, 0x0e, 0x60, 0x64, 0x6f, 0x0c, 0x18, 0x59, 0x9e, 0x62, 0x69, 0xb3, 0x22, 0x23, 0x57, 0x48,
0x46, 0x31, 0xe2, 0xaa, 0x49, 0x72, 0x8f, 0x4d, 0x53, 0x37, 0x39, 0xc6, 0xc1, 0x1e, 0xc4, 0xcb,
0xa4, 0x52, 0xf6, 0xdc, 0xf2, 0x04, 0x14, 0x85, 0x16, 0x51, 0x3e, 0x57, 0x2c, 0xfe, 0x2e, 0xee,
0xc9, 0xd2, 0x02, 0xd3, 0x5f, 0x65, 0xe7, 0x78, 0x95, 0xed, 0xc3, 0x56, 0x84, 0x20, 0xb6, 0xb2,
0x0a, 0x79, 0x52, 0x1c, 0x8d, 0xc0, 0x26, 0x8a, 0xe1, 0xc2, 0x26, 0x57, 0x61, 0x91, 0x26, 0x01,
0x0c, 0x81, 0xe1, 0x91, 0x35, 0x49, 0x23, 0x6b, 0x89, 0xbc, 0x60, 0xab, 0xc0, 0x42, 0xec, 0x73,
0xb0, 0xe4, 0xe3, 0x75, 0x8b, 0x2e, 0x86, 0x21, 0x94, 0x5d, 0xee, 0x0d, 0x5e, 0x7d, 0xfd, 0x21,
0xee, 0xad, 0x90, 0x87, 0xb7, 0x84, 0x41, 0x23, 0xf1, 0xaf, 0x08, 0x1a, 0x11, 0xbe, 0x34, 0x34,
0xe2, 0x2f, 0x22, 0x13, 0xc1, 0x22, 0xf2, 0x9f, 0x71, 0x6f, 0x4f, 0x5c, 0xa0, 0xa3, 0xad, 0xab,
0x98, 0x97, 0x75, 0xf4, 0x37, 0x49, 0xb3, 0xba, 0xfa, 0x31, 0x2f, 0xde, 0xc8, 0x4f, 0xc2, 0xe5,
0xc6, 0xce, 0x1c, 0x0f, 0x8d, 0x6e, 0x45, 0xc8, 0x72, 0x17, 0x5e, 0x11, 0x96, 0x21, 0xf1, 0x10,
0xb3, 0x48, 0xb7, 0x20, 0x91, 0x9f, 0x84, 0x8f, 0x1a, 0x19, 0xcf, 0x41, 0xd8, 0x03, 0xba, 0x09,
0x39, 0xda, 0xae, 0x91, 0x75, 0xc3, 0xe2, 0x01, 0x29, 0x90, 0xae, 0xb1, 0xae, 0xcc, 0xda, 0x3e,
0xe1, 0xd9, 0x33, 0x2c, 0x29, 0x6b, 0xf0, 0x5f, 0xbe, 0xa4, 0x29, 0x17, 0x48, 0x9a, 0xce, 0x41,
0x8e, 0x8c, 0xde, 0x32, 0x94, 0x36, 0xa6, 0x91, 0x25, 0x27, 0x79, 0x04, 0xf1, 0x01, 0xa0, 0xf1,
0x38, 0x89, 0x1a, 0x90, 0xc6, 0x27, 0xb8, 0x6f, 0xb3, 0x9c, 0x32, 0xbf, 0x7e, 0x66, 0xbc, 0x6e,
0x24, 0xaf, 0x37, 0x2b, 0x64, 0x91, 0xff, 0xf1, 0xd9, 0x6a, 0x99, 0x71, 0x3f, 0xab, 0xf7, 0x34,
0x1b, 0xf7, 0x0c, 0xfb, 0x54, 0xe2, 0xf2, 0xe2, 0x5f, 0x05, 0x28, 0x8d, 0xc4, 0xcf, 0xd0, 0xb5,
0x75, 0x4c, 0x5e, 0xf0, 0x01, 0x4b, 0xb3, 0xad, 0xf7, 0x79, 0x80, 0x63, 0xc5, 0x92, 0xdf, 0x55,
0xfa, 0x36, 0x56, 0xf9, 0xa2, 0xe7, 0x8e, 0x15, 0xeb, 0x0d, 0x4a, 0x20, 0xbb, 0x4e, 0x5e, 0x0f,
0x2c, 0xac, 0x72, 0x88, 0x2b, 0x73, 0xac, 0x58, 0x87, 0x16, 0x56, 0x7d, 0xb3, 0xcc, 0x3c, 0xda,
0x2c, 0x83, 0x6b, 0x9c, 0x1d, 0x59, 0x63, 0x5f, 0xdd, 0x9f, 0xf3, 0xd7, 0xfd, 0xa8, 0x0a, 0x59,
0xc3, 0xd4, 0x74, 0x53, 0xb3, 0x4f, 0xe9, 0xc6, 0x24, 0x24, 0xf7, 0x19, 0x5d, 0x84, 0x42, 0x0f,
0xf7, 0x0c, 0x5d, 0xef, 0xca, 0xcc, 0xd9, 0xe4, 0xa9, 0xe8, 0x02, 0x27, 0xd6, 0xa9, 0xcf, 0xf9,
0x40, 0xf0, 0x4e, 0x9f, 0x87, 0xef, 0x7c, 0xb5, 0xcb, 0xbb, 0x12, 0xb2, 0xbc, 0x3e, 0x0a, 0x99,
0xc4, 0xc8, 0xfa, 0xba, 0xcf, 0xdf, 0xd4, 0x02, 0x8b, 0x3f, 0xa6, 0xa0, 0x6f, 0x30, 0x37, 0x42,
0x07, 0xfe, 0xca, 0x6c, 0x40, 0x9d, 0x82, 0x63, 0xce, 0xb3, 0x7a, 0x0f, 0xaf, 0x82, 0x63, 0x64,
0x0b, 0xbd, 0x09, 0x8f, 0x8f, 0x78, 0x36, 0x57, 0xb5, 0x30, 0xab, 0x83, 0x7b, 0x2c, 0xe8, 0xe0,
0x1c, 0xd5, 0xde, 0x62, 0x25, 0x1e, 0xf1, 0xcc, 0x6d, 0x43, 0x31, 0x98, 0xe6, 0x85, 0x6e, 0xff,
0x45, 0x28, 0x98, 0xd8, 0x56, 0xb4, 0xbe, 0x1c, 0xa8, 0x49, 0x17, 0x18, 0x91, 0xe3, 0xbf, 0xfb,
0xf0, 0x58, 0x68, 0xba, 0x87, 0x5e, 0x84, 0x9c, 0x97, 0x29, 0xb2, 0x55, 0x9d, 0x80, 0xe4, 0x79,
0xbc, 0xe2, 0xef, 0xe3, 0x9e, 0xca, 0x20, 0x36, 0x58, 0x87, 0xb4, 0x89, 0xad, 0x41, 0x97, 0xa1,
0x75, 0xc5, 0xf5, 0xe7, 0x66, 0x4b, 0x14, 0x09, 0x75, 0xd0, 0xb5, 0x25, 0x2e, 0x2c, 0x3e, 0x80,
0x34, 0xa3, 0xa0, 0x3c, 0x64, 0x0e, 0x77, 0xef, 0xee, 0xee, 0xbd, 0xb1, 0x5b, 0x8e, 0x21, 0x80,
0xf4, 0x46, 0xad, 0x56, 0xdf, 0x6f, 0x96, 0xe3, 0x28, 0x07, 0xa9, 0x8d, 0xcd, 0x3d, 0xa9, 0x59,
0x16, 0x08, 0x59, 0xaa, 0xdf, 0xa9, 0xd7, 0x9a, 0xe5, 0x04, 0x5a, 0x84, 0x02, 0xfb, 0x2d, 0xdf,
0xde, 0x93, 0xee, 0x6d, 0x34, 0xcb, 0x49, 0x1f, 0xe9, 0xa0, 0xbe, 0xbb, 0x55, 0x97, 0xca, 0x29,
0xf1, 0xff, 0xe0, 0x6c, 0x64, 0x6a, 0xe9, 0x01, 0x7f, 0x71, 0x1f, 0xf0, 0x27, 0xfe, 0x5c, 0x80,
0x6a, 0x74, 0xbe, 0x88, 0xee, 0x8c, 0x4c, 0x7c, 0x7d, 0x8e, 0x64, 0x73, 0x64, 0xf6, 0xe8, 0x12,
0x14, 0x4d, 0x7c, 0x84, 0xed, 0x76, 0x87, 0xe5, 0xaf, 0x2c, 0x60, 0x16, 0xa4, 0x02, 0xa7, 0x52,
0x21, 0x8b, 0xb1, 0xbd, 0x8d, 0xdb, 0xb6, 0xcc, 0x7c, 0x11, 0x33, 0xba, 0x1c, 0x61, 0x23, 0xd4,
0x03, 0x46, 0x14, 0xdf, 0x9a, 0x6b, 0x2d, 0x73, 0x90, 0x92, 0xea, 0x4d, 0xe9, 0xcd, 0x72, 0x02,
0x21, 0x28, 0xd2, 0x9f, 0xf2, 0xc1, 0xee, 0xc6, 0xfe, 0x41, 0x63, 0x8f, 0xac, 0xe5, 0x12, 0x94,
0x9c, 0xb5, 0x74, 0x88, 0x29, 0xf1, 0x4f, 0x02, 0x3c, 0x1e, 0x91, 0xed, 0xa2, 0x9b, 0x00, 0xf6,
0x50, 0x36, 0x71, 0x5b, 0x37, 0xd5, 0x68, 0x23, 0x6b, 0x0e, 0x25, 0xca, 0x21, 0xe5, 0x6c, 0xfe,
0xcb, 0x9a, 0x80, 0x17, 0xa3, 0x97, 0xb9, 0x52, 0x32, 0x2b, 0xe7, 0xa8, 0x9d, 0x0f, 0x81, 0x45,
0x71, 0x9b, 0x28, 0xa6, 0x6b, 0x4b, 0x15, 0x53, 0x7e, 0x74, 0x2f, 0xcc, 0xa9, 0xcc, 0xd8, 0xad,
0x99, 0xcf, 0x9d, 0xa4, 0x1e, 0xcd, 0x9d, 0x88, 0xbf, 0x4a, 0xf8, 0x17, 0x36, 0x98, 0xdc, 0xef,
0x41, 0xda, 0xb2, 0x15, 0x7b, 0x60, 0x71, 0x83, 0x7b, 0x71, 0xd6, 0x4a, 0x61, 0xcd, 0xf9, 0x71,
0x40, 0xc5, 0x25, 0xae, 0xe6, 0xdb, 0xf5, 0xb6, 0xc4, 0x1b, 0x50, 0x0c, 0x2e, 0x4e, 0xf4, 0x91,
0xf1, 0x7c, 0x8e, 0x20, 0xde, 0xf2, 0xf2, 0x2f, 0x1f, 0x68, 0x39, 0x0e, 0x08, 0xc6, 0xc3, 0x00,
0xc1, 0x5f, 0xc7, 0xe1, 0x89, 0x09, 0xf5, 0x12, 0x7a, 0x7d, 0x64, 0x9f, 0x5f, 0x9a, 0xa7, 0xda,
0x5a, 0x63, 0xb4, 0xe0, 0x4e, 0x8b, 0xd7, 0x61, 0xc1, 0x4f, 0x9f, 0x6d, 0x92, 0x3f, 0x49, 0x78,
0x3e, 0x3f, 0x88, 0x5c, 0x7e, 0x65, 0x89, 0xe6, 0x88, 0x9d, 0x09, 0x73, 0xda, 0x59, 0x68, 0xb2,
0x90, 0xf8, 0xfa, 0x92, 0x85, 0xe4, 0x23, 0x26, 0x0b, 0xfe, 0x03, 0x97, 0x0a, 0x1e, 0xb8, 0xb1,
0xb8, 0x9e, 0x0e, 0x89, 0xeb, 0x6f, 0x02, 0xf8, 0x1a, 0x9a, 0xcb, 0x90, 0x32, 0xf5, 0x41, 0x5f,
0xa5, 0x66, 0x92, 0x92, 0xd8, 0x03, 0xba, 0x01, 0x29, 0x62, 0x6e, 0xce, 0x62, 0x8e, 0x7b, 0x5e,
0x62, 0x2e, 0x3e, 0xcc, 0x98, 0x71, 0x8b, 0x1a, 0xa0, 0xf1, 0xa6, 0x52, 0xc4, 0x27, 0x5e, 0x09,
0x7e, 0xe2, 0xc9, 0xc8, 0xf6, 0x54, 0xf8, 0xa7, 0xde, 0x83, 0x14, 0x35, 0x0f, 0x92, 0xdf, 0xd0,
0xc6, 0x28, 0x2f, 0x98, 0xc9, 0x6f, 0xf4, 0x43, 0x00, 0xc5, 0xb6, 0x4d, 0xad, 0x35, 0xf0, 0x3e,
0xb0, 0x1a, 0x6e, 0x5e, 0x1b, 0x0e, 0xdf, 0xe6, 0x39, 0x6e, 0x67, 0xcb, 0x9e, 0xa8, 0xcf, 0xd6,
0x7c, 0x0a, 0xc5, 0x5d, 0x28, 0x06, 0x65, 0x9d, 0x12, 0x8f, 0x8d, 0x21, 0x58, 0xe2, 0xb1, 0x8a,
0x9d, 0x97, 0x78, 0x6e, 0x81, 0x98, 0x60, 0x3d, 0x70, 0xfa, 0x20, 0xfe, 0x2b, 0x0e, 0x0b, 0x7e,
0xeb, 0xfc, 0x5f, 0xab, 0x92, 0xc4, 0x0f, 0xe2, 0x90, 0x75, 0x27, 0x1f, 0xd1, 0x80, 0xf6, 0xd6,
0x4e, 0xf0, 0xb7, 0x5b, 0x59, 0x47, 0x3b, 0xe1, 0xf6, 0xc9, 0x6f, 0xb9, 0x09, 0x55, 0x14, 0xa8,
0xed, 0x5f, 0x69, 0xe7, 0xaa, 0x00, 0xcf, 0x1f, 0x7f, 0xc6, 0xc7, 0x41, 0x32, 0x09, 0xf4, 0x1d,
0x48, 0x2b, 0x6d, 0x17, 0xca, 0x2f, 0x86, 0x60, 0xbb, 0x0e, 0xeb, 0x5a, 0x73, 0xb8, 0x41, 0x39,
0x25, 0x2e, 0xc1, 0x47, 0x25, 0xb8, 0x7d, 0xf6, 0x57, 0x89, 0x5e, 0xc6, 0x13, 0x74, 0x9b, 0x45,
0x80, 0xc3, 0xdd, 0x7b, 0x7b, 0x5b, 0xdb, 0xb7, 0xb7, 0xeb, 0x5b, 0x3c, 0xa5, 0xda, 0xda, 0xaa,
0x6f, 0x95, 0x05, 0xc2, 0x27, 0xd5, 0xef, 0xed, 0xdd, 0xaf, 0x6f, 0x95, 0x13, 0xe2, 0x2d, 0xc8,
0xb9, 0xae, 0x07, 0x55, 0x20, 0xe3, 0xb4, 0x25, 0xe2, 0xdc, 0x01, 0xf0, 0x2e, 0xd3, 0x32, 0xa4,
0x0c, 0xfd, 0x5d, 0xde, 0x65, 0x4e, 0x48, 0xec, 0x41, 0x54, 0xa1, 0x34, 0xe2, 0xb7, 0xd0, 0x2d,
0xc8, 0x18, 0x83, 0x96, 0xec, 0x18, 0xed, 0x48, 0x13, 0xc7, 0x41, 0x1a, 0x06, 0xad, 0xae, 0xd6,
0xbe, 0x8b, 0x4f, 0x9d, 0x65, 0x32, 0x06, 0xad, 0xbb, 0xcc, 0xb6, 0xd9, 0x57, 0x04, 0xff, 0x57,
0x7e, 0x14, 0x87, 0xac, 0x73, 0x56, 0xd1, 0x77, 0x21, 0xe7, 0xfa, 0x44, 0xf7, 0xee, 0x4d, 0xa4,
0x33, 0xe5, 0xfa, 0x3d, 0x11, 0x74, 0x15, 0x16, 0x2d, 0xed, 0xb8, 0xef, 0xf4, 0xb0, 0x18, 0xb4,
0x27, 0xd0, 0x43, 0x53, 0x62, 0x2f, 0x76, 0x1c, 0x3c, 0xea, 0x4e, 0x32, 0x9b, 0x28, 0x27, 0xef,
0x24, 0xb3, 0xc9, 0x72, 0x8a, 0x84, 0xc5, 0xf2, 0xa8, 0xe3, 0xf8, 0x26, 0x07, 0x13, 0x12, 0xbe,
0x13, 0x61, 0xe1, 0xfb, 0x7d, 0x01, 0xf2, 0xbe, 0x2e, 0x19, 0xfa, 0x7f, 0x9f, 0x17, 0x2b, 0x86,
0xc4, 0x1d, 0x1f, 0xaf, 0x77, 0xc5, 0x23, 0x38, 0x31, 0x61, 0xfe, 0x89, 0x45, 0x35, 0x25, 0x9d,
0x66, 0x5b, 0x72, 0xee, 0x66, 0xdb, 0xb3, 0x80, 0x6c, 0xdd, 0x56, 0xba, 0xf2, 0x89, 0x6e, 0x6b,
0xfd, 0x63, 0x99, 0xd9, 0x09, 0xf3, 0x39, 0x65, 0xfa, 0xe6, 0x3e, 0x7d, 0xb1, 0xef, 0x9a, 0x8c,
0x5b, 0x03, 0xce, 0x7b, 0x63, 0xe3, 0x0c, 0xa4, 0x79, 0x99, 0xc3, 0xae, 0x6c, 0xf0, 0xa7, 0xd0,
0xae, 0x62, 0x15, 0xb2, 0x3d, 0x6c, 0x2b, 0xd4, 0x81, 0xb2, 0x98, 0xe9, 0x3e, 0x5f, 0x7d, 0x09,
0xf2, 0xbe, 0xcb, 0x33, 0xc4, 0xa7, 0xee, 0xd6, 0xdf, 0x28, 0xc7, 0xaa, 0x99, 0x0f, 0x3f, 0xbe,
0x90, 0xd8, 0xc5, 0xef, 0x92, 0xe3, 0x26, 0xd5, 0x6b, 0x8d, 0x7a, 0xed, 0x6e, 0x39, 0x5e, 0xcd,
0x7f, 0xf8, 0xf1, 0x85, 0x8c, 0x84, 0x69, 0x13, 0xe8, 0xea, 0x5d, 0x28, 0x8d, 0x6c, 0x4c, 0xf0,
0x74, 0x23, 0x28, 0x6e, 0x1d, 0xee, 0xef, 0x6c, 0xd7, 0x36, 0x9a, 0x75, 0xf9, 0xfe, 0x5e, 0xb3,
0x5e, 0x8e, 0xa3, 0xc7, 0x61, 0x69, 0x67, 0xfb, 0xb5, 0x46, 0x53, 0xae, 0xed, 0x6c, 0xd7, 0x77,
0x9b, 0xf2, 0x46, 0xb3, 0xb9, 0x51, 0xbb, 0x5b, 0x16, 0xd6, 0x7f, 0x93, 0x87, 0xd2, 0xc6, 0x66,
0x6d, 0x9b, 0x14, 0x7a, 0x5a, 0x5b, 0xa1, 0xbe, 0xa2, 0x06, 0x49, 0x8a, 0x28, 0x4f, 0xbc, 0x0e,
0x5d, 0x9d, 0xdc, 0x25, 0x44, 0xb7, 0x21, 0x45, 0xc1, 0x66, 0x34, 0xf9, 0x7e, 0x74, 0x75, 0x4a,
0xdb, 0x90, 0x0c, 0x86, 0x1e, 0xa7, 0x89, 0x17, 0xa6, 0xab, 0x93, 0xbb, 0x88, 0x68, 0x07, 0x32,
0x0e, 0x16, 0x38, 0xed, 0xea, 0x71, 0x75, 0x6a, 0x3b, 0x8e, 0x4c, 0x8d, 0x61, 0xb6, 0x93, 0xef,
0x52, 0x57, 0xa7, 0xf4, 0x17, 0xd1, 0x36, 0xa4, 0x39, 0x5c, 0x32, 0xe5, 0x1a, 0x71, 0x75, 0x5a,
0x5b, 0x0d, 0x49, 0x90, 0xf3, 0xd0, 0xf0, 0xe9, 0x37, 0xc4, 0xab, 0x33, 0xb4, 0x4e, 0xd1, 0x03,
0x28, 0x04, 0x21, 0x98, 0xd9, 0xae, 0x2a, 0x57, 0x67, 0x6c, 0xe0, 0x11, 0xfd, 0x41, 0x3c, 0x66,
0xb6, 0xab, 0xcb, 0xd5, 0x19, 0xfb, 0x79, 0xe8, 0x6d, 0x58, 0x1c, 0xc7, 0x4b, 0x66, 0xbf, 0xc9,
0x5c, 0x9d, 0xa3, 0xc3, 0x87, 0x7a, 0x80, 0x42, 0x70, 0x96, 0x39, 0x2e, 0x36, 0x57, 0xe7, 0x69,
0xf8, 0x21, 0x15, 0x4a, 0xa3, 0xd8, 0xc5, 0xac, 0x17, 0x9d, 0xab, 0x33, 0x37, 0xff, 0xd8, 0x57,
0x82, 0x85, 0xfc, 0xac, 0x17, 0x9f, 0xab, 0x33, 0xf7, 0x02, 0xd1, 0x21, 0x80, 0xaf, 0x10, 0x9d,
0xe1, 0x22, 0x74, 0x75, 0x96, 0xae, 0x20, 0x32, 0x60, 0x29, 0xac, 0x42, 0x9d, 0xe7, 0x5e, 0x74,
0x75, 0xae, 0x66, 0x21, 0xb1, 0xe7, 0x60, 0xad, 0x39, 0xdb, 0x3d, 0xe9, 0xea, 0x8c, 0x5d, 0xc3,
0xcd, 0xfa, 0x27, 0x9f, 0xaf, 0xc4, 0x3f, 0xfd, 0x7c, 0x25, 0xfe, 0xf7, 0xcf, 0x57, 0xe2, 0x1f,
0x7d, 0xb1, 0x12, 0xfb, 0xf4, 0x8b, 0x95, 0xd8, 0x5f, 0xbe, 0x58, 0x89, 0x7d, 0xef, 0x99, 0x63,
0xcd, 0xee, 0x0c, 0x5a, 0x6b, 0x6d, 0xbd, 0x77, 0xcd, 0xff, 0x97, 0x99, 0xb0, 0xbf, 0xf1, 0xb4,
0xd2, 0x34, 0xa0, 0x5e, 0xff, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x97, 0x52, 0xf8, 0x77, 0xe6,
0x33, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -6222,15 +6265,15 @@ func (m *RequestExtendVote) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if m.Vote != nil {
{
size, err := m.Vote.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintTypes(dAtA, i, uint64(size))
}
if m.Height != 0 {
i = encodeVarintTypes(dAtA, i, uint64(m.Height))
i--
dAtA[i] = 0x10
}
if len(m.Hash) > 0 {
i -= len(m.Hash)
copy(dAtA[i:], m.Hash)
i = encodeVarintTypes(dAtA, i, uint64(len(m.Hash)))
i--
dAtA[i] = 0xa
}
@@ -6257,15 +6300,29 @@ func (m *RequestVerifyVoteExtension) MarshalToSizedBuffer(dAtA []byte) (int, err
_ = i
var l int
_ = l
if m.Vote != nil {
{
size, err := m.Vote.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintTypes(dAtA, i, uint64(size))
}
if len(m.VoteExtension) > 0 {
i -= len(m.VoteExtension)
copy(dAtA[i:], m.VoteExtension)
i = encodeVarintTypes(dAtA, i, uint64(len(m.VoteExtension)))
i--
dAtA[i] = 0x22
}
if m.Height != 0 {
i = encodeVarintTypes(dAtA, i, uint64(m.Height))
i--
dAtA[i] = 0x18
}
if len(m.ValidatorAddress) > 0 {
i -= len(m.ValidatorAddress)
copy(dAtA[i:], m.ValidatorAddress)
i = encodeVarintTypes(dAtA, i, uint64(len(m.ValidatorAddress)))
i--
dAtA[i] = 0x12
}
if len(m.Hash) > 0 {
i -= len(m.Hash)
copy(dAtA[i:], m.Hash)
i = encodeVarintTypes(dAtA, i, uint64(len(m.Hash)))
i--
dAtA[i] = 0xa
}
@@ -6306,12 +6363,12 @@ func (m *RequestFinalizeBlock) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i--
dAtA[i] = 0x3a
}
n31, err31 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):])
if err31 != nil {
return 0, err31
n29, err29 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):])
if err29 != nil {
return 0, err29
}
i -= n31
i = encodeVarintTypes(dAtA, i, uint64(n31))
i -= n29
i = encodeVarintTypes(dAtA, i, uint64(n29))
i--
dAtA[i] = 0x32
if m.Height != 0 {
@@ -7541,20 +7598,20 @@ func (m *ResponseApplySnapshotChunk) MarshalToSizedBuffer(dAtA []byte) (int, err
}
}
if len(m.RefetchChunks) > 0 {
dAtA57 := make([]byte, len(m.RefetchChunks)*10)
var j56 int
dAtA55 := make([]byte, len(m.RefetchChunks)*10)
var j54 int
for _, num := range m.RefetchChunks {
for num >= 1<<7 {
dAtA57[j56] = uint8(uint64(num)&0x7f | 0x80)
dAtA55[j54] = uint8(uint64(num)&0x7f | 0x80)
num >>= 7
j56++
j54++
}
dAtA57[j56] = uint8(num)
j56++
dAtA55[j54] = uint8(num)
j54++
}
i -= j56
copy(dAtA[i:], dAtA57[:j56])
i = encodeVarintTypes(dAtA, i, uint64(j56))
i -= j54
copy(dAtA[i:], dAtA55[:j54])
i = encodeVarintTypes(dAtA, i, uint64(j54))
i--
dAtA[i] = 0x12
}
@@ -7745,15 +7802,10 @@ func (m *ResponseExtendVote) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if m.VoteExtension != nil {
{
size, err := m.VoteExtension.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintTypes(dAtA, i, uint64(size))
}
if len(m.VoteExtension) > 0 {
i -= len(m.VoteExtension)
copy(dAtA[i:], m.VoteExtension)
i = encodeVarintTypes(dAtA, i, uint64(len(m.VoteExtension)))
i--
dAtA[i] = 0xa
}
@@ -8408,12 +8460,12 @@ func (m *Misbehavior) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i--
dAtA[i] = 0x28
}
n66, err66 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):])
if err66 != nil {
return 0, err66
n63, err63 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):])
if err63 != nil {
return 0, err63
}
i -= n66
i = encodeVarintTypes(dAtA, i, uint64(n66))
i -= n63
i = encodeVarintTypes(dAtA, i, uint64(n63))
i--
dAtA[i] = 0x22
if m.Height != 0 {
@@ -9064,10 +9116,13 @@ func (m *RequestExtendVote) Size() (n int) {
}
var l int
_ = l
if m.Vote != nil {
l = m.Vote.Size()
l = len(m.Hash)
if l > 0 {
n += 1 + l + sovTypes(uint64(l))
}
if m.Height != 0 {
n += 1 + sovTypes(uint64(m.Height))
}
return n
}
@@ -9077,8 +9132,19 @@ func (m *RequestVerifyVoteExtension) Size() (n int) {
}
var l int
_ = l
if m.Vote != nil {
l = m.Vote.Size()
l = len(m.Hash)
if l > 0 {
n += 1 + l + sovTypes(uint64(l))
}
l = len(m.ValidatorAddress)
if l > 0 {
n += 1 + l + sovTypes(uint64(l))
}
if m.Height != 0 {
n += 1 + sovTypes(uint64(m.Height))
}
l = len(m.VoteExtension)
if l > 0 {
n += 1 + l + sovTypes(uint64(l))
}
return n
@@ -9788,8 +9854,8 @@ func (m *ResponseExtendVote) Size() (n int) {
}
var l int
_ = l
if m.VoteExtension != nil {
l = m.VoteExtension.Size()
l = len(m.VoteExtension)
if l > 0 {
n += 1 + l + sovTypes(uint64(l))
}
return n
@@ -13029,9 +13095,9 @@ func (m *RequestExtendVote) Unmarshal(dAtA []byte) error {
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Vote", wireType)
return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType)
}
var msglen int
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
@@ -13041,28 +13107,45 @@ func (m *RequestExtendVote) 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 ErrInvalidLengthTypes
}
postIndex := iNdEx + msglen
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthTypes
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Vote == nil {
m.Vote = &types1.Vote{}
}
if err := m.Vote.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
m.Hash = append(m.Hash[:0], dAtA[iNdEx:postIndex]...)
if m.Hash == nil {
m.Hash = []byte{}
}
iNdEx = postIndex
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType)
}
m.Height = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Height |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipTypes(dAtA[iNdEx:])
@@ -13115,9 +13198,9 @@ func (m *RequestVerifyVoteExtension) Unmarshal(dAtA []byte) error {
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Vote", wireType)
return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType)
}
var msglen int
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
@@ -13127,26 +13210,111 @@ func (m *RequestVerifyVoteExtension) 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 ErrInvalidLengthTypes
}
postIndex := iNdEx + msglen
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthTypes
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Vote == nil {
m.Vote = &types1.Vote{}
m.Hash = append(m.Hash[:0], dAtA[iNdEx:postIndex]...)
if m.Hash == nil {
m.Hash = []byte{}
}
if err := m.Vote.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ValidatorAddress", 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.ValidatorAddress = append(m.ValidatorAddress[:0], dAtA[iNdEx:postIndex]...)
if m.ValidatorAddress == nil {
m.ValidatorAddress = []byte{}
}
iNdEx = postIndex
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType)
}
m.Height = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Height |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field VoteExtension", 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.VoteExtension = append(m.VoteExtension[:0], dAtA[iNdEx:postIndex]...)
if m.VoteExtension == nil {
m.VoteExtension = []byte{}
}
iNdEx = postIndex
default:
@@ -16926,7 +17094,7 @@ func (m *ResponseExtendVote) Unmarshal(dAtA []byte) error {
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field VoteExtension", wireType)
}
var msglen int
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
@@ -16936,26 +17104,24 @@ func (m *ResponseExtendVote) 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 ErrInvalidLengthTypes
}
postIndex := iNdEx + msglen
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthTypes
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.VoteExtension = append(m.VoteExtension[:0], dAtA[iNdEx:postIndex]...)
if m.VoteExtension == nil {
m.VoteExtension = &types1.VoteExtension{}
}
if err := m.VoteExtension.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
m.VoteExtension = []byte{}
}
iNdEx = postIndex
default:
+1 -1
View File
@@ -42,7 +42,7 @@ require (
github.com/creachadair/taskgroup v0.3.2
github.com/golangci/golangci-lint v1.45.2
github.com/google/go-cmp v0.5.7
github.com/vektra/mockery/v2 v2.10.6
github.com/vektra/mockery/v2 v2.11.0
gotest.tools v2.2.0+incompatible
)
+2 -2
View File
@@ -1055,8 +1055,8 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC
github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus=
github.com/valyala/quicktemplate v1.7.0/go.mod h1:sqKJnoaOF88V07vkO+9FL8fb9uZg/VPSJnLYn+LmLk8=
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
github.com/vektra/mockery/v2 v2.10.6 h1:iLVqC9FozavYx27ZwfXipuizLBN8YzXlh9x5fufk48w=
github.com/vektra/mockery/v2 v2.10.6/go.mod h1:8vf4KDDUptfkyypzdHLuE7OE2xA7Gdt60WgIS8PgD+U=
github.com/vektra/mockery/v2 v2.11.0 h1:9NkC3urGvJS9B0ve5aTbFjksbO9f/u5cZFgCTVJ30jg=
github.com/vektra/mockery/v2 v2.11.0/go.mod h1:8vf4KDDUptfkyypzdHLuE7OE2xA7Gdt60WgIS8PgD+U=
github.com/viki-org/dnscache v0.0.0-20130720023526-c70c1f23c5d8/go.mod h1:dniwbG03GafCjFohMDmz6Zc6oCuiqgH6tGNyXTkHzXE=
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
+3 -3
View File
@@ -359,7 +359,7 @@ func (r *Reactor) SwitchToBlockSync(ctx context.Context, state sm.State) error {
go r.requestRoutine(ctx, bsCh)
go r.poolRoutine(ctx, true, bsCh)
if err := r.PublishStatus(ctx, types.EventDataBlockSyncStatus{
if err := r.PublishStatus(types.EventDataBlockSyncStatus{
Complete: false,
Height: state.LastBlockHeight,
}); err != nil {
@@ -609,11 +609,11 @@ func (r *Reactor) GetRemainingSyncTime() time.Duration {
return time.Duration(int64(remain * float64(time.Second)))
}
func (r *Reactor) PublishStatus(ctx context.Context, event types.EventDataBlockSyncStatus) error {
func (r *Reactor) PublishStatus(event types.EventDataBlockSyncStatus) error {
if r.eventBus == nil {
return errors.New("event bus is not configured")
}
return r.eventBus.PublishEventBlockSyncStatus(ctx, event)
return r.eventBus.PublishEventBlockSyncStatus(event)
}
// atomicBool is an atomic Boolean, safe for concurrent use by multiple
+4 -5
View File
@@ -50,7 +50,6 @@ func setup(
genDoc *types.GenesisDoc,
privVal types.PrivValidator,
maxBlockHeights []int64,
chBuf uint,
) *reactorTestSuite {
t.Helper()
@@ -228,7 +227,7 @@ func TestReactor_AbruptDisconnect(t *testing.T) {
genDoc := factory.GenesisDoc(cfg, time.Now(), valSet.Validators, factory.ConsensusParams())
maxBlockHeight := int64(64)
rts := setup(ctx, t, genDoc, privVals[0], []int64{maxBlockHeight, 0}, 0)
rts := setup(ctx, t, genDoc, privVals[0], []int64{maxBlockHeight, 0})
require.Equal(t, maxBlockHeight, rts.reactors[rts.nodes[0]].store.Height())
@@ -268,7 +267,7 @@ func TestReactor_SyncTime(t *testing.T) {
genDoc := factory.GenesisDoc(cfg, time.Now(), valSet.Validators, factory.ConsensusParams())
maxBlockHeight := int64(101)
rts := setup(ctx, t, genDoc, privVals[0], []int64{maxBlockHeight, 0}, 0)
rts := setup(ctx, t, genDoc, privVals[0], []int64{maxBlockHeight, 0})
require.Equal(t, maxBlockHeight, rts.reactors[rts.nodes[0]].store.Height())
rts.start(ctx, t)
@@ -296,7 +295,7 @@ func TestReactor_NoBlockResponse(t *testing.T) {
genDoc := factory.GenesisDoc(cfg, time.Now(), valSet.Validators, factory.ConsensusParams())
maxBlockHeight := int64(65)
rts := setup(ctx, t, genDoc, privVals[0], []int64{maxBlockHeight, 0}, 0)
rts := setup(ctx, t, genDoc, privVals[0], []int64{maxBlockHeight, 0})
require.Equal(t, maxBlockHeight, rts.reactors[rts.nodes[0]].store.Height())
@@ -348,7 +347,7 @@ func TestReactor_BadBlockStopsPeer(t *testing.T) {
valSet, privVals := factory.ValidatorSet(ctx, t, 1, 30)
genDoc := factory.GenesisDoc(cfg, time.Now(), valSet.Validators, factory.ConsensusParams())
rts := setup(ctx, t, genDoc, privVals[0], []int64{maxBlockHeight, 0, 0, 0, 0}, 1000)
rts := setup(ctx, t, genDoc, privVals[0], []int64{maxBlockHeight, 0, 0, 0, 0})
require.Equal(t, maxBlockHeight, rts.reactors[rts.nodes[0]].store.Height())
+2 -2
View File
@@ -96,7 +96,7 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
// Make State
blockExec := sm.NewBlockExecutor(stateStore, log.NewNopLogger(), proxyAppConnCon, mempool, evpool, blockStore, eventBus, sm.NopMetrics())
cs, err := NewState(ctx, logger, thisConfig.Consensus, stateStore, blockExec, blockStore, mempool, evpool, eventBus)
cs, err := NewState(logger, thisConfig.Consensus, stateStore, blockExec, blockStore, mempool, evpool, eventBus)
require.NoError(t, err)
// set private validator
pv := privVals[i]
@@ -203,7 +203,7 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
proposerAddr := lazyNodeState.privValidatorPubKey.Address()
block, err := lazyNodeState.blockExec.CreateProposalBlock(
ctx, lazyNodeState.Height, lazyNodeState.state, commit, proposerAddr, nil)
ctx, lazyNodeState.Height, lazyNodeState.state, commit, proposerAddr, lazyNodeState.LastCommit.GetVotes())
require.NoError(t, err)
blockParts, err := block.MakePartSet(types.BlockPartSizeBytes)
require.NoError(t, err)
+29 -30
View File
@@ -112,7 +112,8 @@ func (vs *validatorStub) signVote(
ctx context.Context,
voteType tmproto.SignedMsgType,
chainID string,
blockID types.BlockID) (*types.Vote, error) {
blockID types.BlockID,
voteExtension []byte) (*types.Vote, error) {
pubKey, err := vs.PrivValidator.GetPubKey(ctx)
if err != nil {
@@ -120,28 +121,30 @@ func (vs *validatorStub) signVote(
}
vote := &types.Vote{
ValidatorIndex: vs.Index,
ValidatorAddress: pubKey.Address(),
Type: voteType,
Height: vs.Height,
Round: vs.Round,
Timestamp: vs.clock.Now(),
Type: voteType,
BlockID: blockID,
VoteExtension: types.VoteExtensionFromProto(kvstore.ConstructVoteExtension(pubKey.Address())),
Timestamp: vs.clock.Now(),
ValidatorAddress: pubKey.Address(),
ValidatorIndex: vs.Index,
Extension: voteExtension,
}
v := vote.ToProto()
if err := vs.PrivValidator.SignVote(ctx, chainID, v); err != nil {
if err = vs.PrivValidator.SignVote(ctx, chainID, v); err != nil {
return nil, fmt.Errorf("sign vote failed: %w", err)
}
// ref: signVote in FilePV, the vote should use the privious vote info when the sign data is the same.
// ref: signVote in FilePV, the vote should use the previous vote info when the sign data is the same.
if signDataIsEqual(vs.lastVote, v) {
v.Signature = vs.lastVote.Signature
v.Timestamp = vs.lastVote.Timestamp
v.ExtensionSignature = vs.lastVote.ExtensionSignature
}
vote.Signature = v.Signature
vote.Timestamp = v.Timestamp
vote.ExtensionSignature = v.ExtensionSignature
return vote, err
}
@@ -155,13 +158,9 @@ func signVote(
chainID string,
blockID types.BlockID) *types.Vote {
v, err := vs.signVote(ctx, voteType, chainID, blockID)
v, err := vs.signVote(ctx, voteType, chainID, blockID, []byte("extension"))
require.NoError(t, err, "failed to sign vote")
// TODO: remove hardcoded vote extension.
// currently set for abci/examples/kvstore/persistent_kvstore.go
v.VoteExtension = types.VoteExtensionFromProto(kvstore.ConstructVoteExtension(v.ValidatorAddress))
vs.lastVote = v
return v
@@ -351,18 +350,19 @@ func validatePrecommit(
require.True(t, bytes.Equal(vote.BlockID.Hash, votedBlockHash), "Expected precommit to be for proposal block")
}
rs := cs.GetRoundState()
if lockedBlockHash == nil {
require.False(t, cs.LockedRound != lockRound || cs.LockedBlock != nil,
require.False(t, rs.LockedRound != lockRound || rs.LockedBlock != nil,
"Expected to be locked on nil at round %d. Got locked at round %d with block %v",
lockRound,
cs.LockedRound,
cs.LockedBlock)
rs.LockedRound,
rs.LockedBlock)
} else {
require.False(t, cs.LockedRound != lockRound || !bytes.Equal(cs.LockedBlock.Hash(), lockedBlockHash),
require.False(t, rs.LockedRound != lockRound || !bytes.Equal(rs.LockedBlock.Hash(), lockedBlockHash),
"Expected block to be locked on round %d, got %d. Got locked block %X, expected %X",
lockRound,
cs.LockedRound,
cs.LockedBlock.Hash(),
rs.LockedRound,
rs.LockedBlock.Hash(),
lockedBlockHash)
}
}
@@ -491,8 +491,7 @@ func newStateWithConfigAndBlockStore(
require.NoError(t, eventBus.Start(ctx))
blockExec := sm.NewBlockExecutor(stateStore, logger, proxyAppConnCon, mempool, evpool, blockStore, eventBus, sm.NopMetrics())
cs, err := NewState(ctx,
logger.With("module", "consensus"),
cs, err := NewState(logger.With("module", "consensus"),
thisConfig.Consensus,
stateStore,
blockExec,
@@ -731,10 +730,9 @@ func ensureVoteMatch(t *testing.T, voteCh <-chan tmpubsub.Message, height int64,
msg.Data())
vote := voteEvent.Vote
require.Equal(t, height, vote.Height)
require.Equal(t, round, vote.Round)
require.Equal(t, voteType, vote.Type)
require.Equal(t, height, vote.Height, "expected height %d, but got %d", height, vote.Height)
require.Equal(t, round, vote.Round, "expected round %d, but got %d", round, vote.Round)
require.Equal(t, voteType, vote.Type, "expected type %s, but got %s", voteType, vote.Type)
if hash == nil {
require.Nil(t, vote.BlockID.Hash, "Expected prevote to be for nil, got %X", vote.BlockID.Hash)
} else {
@@ -742,6 +740,7 @@ func ensureVoteMatch(t *testing.T, voteCh <-chan tmpubsub.Message, height int64,
}
}
}
func ensureVote(t *testing.T, voteCh <-chan tmpubsub.Message, height int64, round int32, voteType tmproto.SignedMsgType) {
t.Helper()
msg := ensureMessageBeforeTimeout(t, voteCh, ensureTimeout)
@@ -750,10 +749,9 @@ func ensureVote(t *testing.T, voteCh <-chan tmpubsub.Message, height int64, roun
msg.Data())
vote := voteEvent.Vote
require.Equal(t, height, vote.Height)
require.Equal(t, round, vote.Round)
require.Equal(t, voteType, vote.Type)
require.Equal(t, height, vote.Height, "expected height %d, but got %d", height, vote.Height)
require.Equal(t, round, vote.Round, "expected round %d, but got %d", round, vote.Round)
require.Equal(t, voteType, vote.Type, "expected type %s, but got %s", voteType, vote.Type)
}
func ensureNewEventOnChannel(t *testing.T, ch <-chan tmpubsub.Message) {
@@ -987,5 +985,6 @@ func signDataIsEqual(v1 *types.Vote, v2 *tmproto.Vote) bool {
v1.Height == v2.GetHeight() &&
v1.Round == v2.Round &&
bytes.Equal(v1.ValidatorAddress.Bytes(), v2.GetValidatorAddress()) &&
v1.ValidatorIndex == v2.GetValidatorIndex()
v1.ValidatorIndex == v2.GetValidatorIndex() &&
bytes.Equal(v1.Extension, v2.Extension)
}
+2 -7
View File
@@ -357,11 +357,6 @@ func TestConsMsgsVectors(t *testing.T) {
}
pbProposal := proposal.ToProto()
ext := types.VoteExtension{
AppDataToSign: []byte("signed"),
AppDataSelfAuthenticating: []byte("auth"),
}
v := &types.Vote{
ValidatorAddress: []byte("add_more_exclamation"),
ValidatorIndex: 1,
@@ -370,7 +365,7 @@ func TestConsMsgsVectors(t *testing.T) {
Timestamp: date,
Type: tmproto.PrecommitType,
BlockID: bi,
VoteExtension: ext,
Extension: []byte("extension"),
}
vpb := v.ToProto()
@@ -407,7 +402,7 @@ func TestConsMsgsVectors(t *testing.T) {
"2a36080110011a3008011204746573741a26080110011a206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d"},
{"Vote", &tmcons.Message{Sum: &tmcons.Message_Vote{
Vote: &tmcons.Vote{Vote: vpb}}},
"3280010a7e0802100122480a206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d1224080112206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d2a0608c0b89fdc0532146164645f6d6f72655f6578636c616d6174696f6e38014a0e0a067369676e6564120461757468"},
"327b0a790802100122480a206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d1224080112206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d2a0608c0b89fdc0532146164645f6d6f72655f6578636c616d6174696f6e38014a09657874656e73696f6e"},
{"HasVote", &tmcons.Message{Sum: &tmcons.Message_HasVote{
HasVote: &tmcons.HasVote{Height: 1, Round: 1, Type: tmproto.PrevoteType, Index: 1}}},
"3a080801100118012001"},
+7 -7
View File
@@ -210,7 +210,7 @@ func (r *Reactor) OnStart(ctx context.Context) error {
// leak the goroutine when stopping the reactor.
go r.peerStatsRoutine(ctx, peerUpdates)
r.subscribeToBroadcastEvents(chBundle.state)
r.subscribeToBroadcastEvents(ctx, chBundle.state)
if !r.WaitSync() {
if err := r.state.Start(ctx); err != nil {
@@ -260,7 +260,7 @@ func (r *Reactor) SwitchToConsensus(ctx context.Context, state sm.State, skipWAL
// NOTE: The line below causes broadcastNewRoundStepRoutine() to broadcast a
// NewRoundStepMessage.
r.state.updateToState(ctx, state)
r.state.updateToState(state)
if err := r.state.Start(ctx); err != nil {
panic(fmt.Sprintf(`failed to start consensus state: %v
@@ -284,7 +284,7 @@ conR:
}
d := types.EventDataBlockSyncStatus{Complete: true, Height: state.LastBlockHeight}
if err := r.eventBus.PublishEventBlockSyncStatus(ctx, d); err != nil {
if err := r.eventBus.PublishEventBlockSyncStatus(d); err != nil {
r.logger.Error("failed to emit the blocksync complete event", "err", err)
}
}
@@ -344,13 +344,13 @@ func (r *Reactor) broadcastHasVoteMessage(ctx context.Context, vote *types.Vote,
// subscribeToBroadcastEvents subscribes for new round steps and votes using the
// internal pubsub defined in the consensus state to broadcast them to peers
// upon receiving.
func (r *Reactor) subscribeToBroadcastEvents(stateCh *p2p.Channel) {
func (r *Reactor) subscribeToBroadcastEvents(ctx context.Context, stateCh *p2p.Channel) {
onStopCh := r.state.getOnStopCh()
err := r.state.evsw.AddListenerForEvent(
listenerIDConsensus,
types.EventNewRoundStepValue,
func(ctx context.Context, data tmevents.EventData) error {
func(data tmevents.EventData) error {
if err := r.broadcastNewRoundStepMessage(ctx, data.(*cstypes.RoundState), stateCh); err != nil {
return err
}
@@ -371,7 +371,7 @@ func (r *Reactor) subscribeToBroadcastEvents(stateCh *p2p.Channel) {
err = r.state.evsw.AddListenerForEvent(
listenerIDConsensus,
types.EventValidBlockValue,
func(ctx context.Context, data tmevents.EventData) error {
func(data tmevents.EventData) error {
return r.broadcastNewValidBlockMessage(ctx, data.(*cstypes.RoundState), stateCh)
},
)
@@ -382,7 +382,7 @@ func (r *Reactor) subscribeToBroadcastEvents(stateCh *p2p.Channel) {
err = r.state.evsw.AddListenerForEvent(
listenerIDConsensus,
types.EventVoteValue,
func(ctx context.Context, data tmevents.EventData) error {
func(data tmevents.EventData) error {
return r.broadcastHasVoteMessage(ctx, data.(*types.Vote), stateCh)
},
)
+1 -1
View File
@@ -505,7 +505,7 @@ func TestReactorWithEvidence(t *testing.T) {
blockExec := sm.NewBlockExecutor(stateStore, log.NewNopLogger(), proxyAppConnCon, mempool, evpool, blockStore, eventBus, sm.NopMetrics())
cs, err := NewState(ctx, logger.With("validator", i, "module", "consensus"),
cs, err := NewState(logger.With("validator", i, "module", "consensus"),
thisConfig.Consensus, stateStore, blockExec, blockStore, mempool, evpool2, eventBus)
require.NoError(t, err)
cs.SetPrivValidator(ctx, pv)
+1 -1
View File
@@ -429,7 +429,7 @@ func (h *Handshaker) ReplayBlocks(
if err != nil {
return nil, err
}
mockApp, err := newMockProxyApp(ctx, h.logger, appHash, abciResponses)
mockApp, err := newMockProxyApp(h.logger, appHash, abciResponses)
if err != nil {
return nil, err
}
+2 -2
View File
@@ -145,7 +145,7 @@ func (pb *playback) replayReset(ctx context.Context, count int, newStepSub event
pb.cs.Stop()
pb.cs.Wait()
newCS, err := NewState(ctx, pb.cs.logger, pb.cs.config, pb.stateStore, pb.cs.blockExec,
newCS, err := NewState(pb.cs.logger, pb.cs.config, pb.stateStore, pb.cs.blockExec,
pb.cs.blockStore, pb.cs.txNotifier, pb.cs.evpool, pb.cs.eventBus)
if err != nil {
return err
@@ -350,7 +350,7 @@ func newConsensusStateForReplay(
mempool, evpool := emptyMempool{}, sm.EmptyEvidencePool{}
blockExec := sm.NewBlockExecutor(stateStore, logger, proxyApp, mempool, evpool, blockStore, eventBus, sm.NopMetrics())
consensusState, err := NewState(ctx, logger, csConfig, stateStore, blockExec,
consensusState, err := NewState(logger, csConfig, stateStore, blockExec,
blockStore, mempool, evpool, eventBus)
if err != nil {
return nil, err
-1
View File
@@ -57,7 +57,6 @@ func (emptyMempool) CloseWAL() {}
// the real app.
func newMockProxyApp(
ctx context.Context,
logger log.Logger,
appHash []byte,
abciResponses *tmstate.ABCIResponses,
+41 -43
View File
@@ -194,7 +194,6 @@ func SkipStateStoreBootstrap(sm *State) {
// NewState returns a new State.
func NewState(
ctx context.Context,
logger log.Logger,
cfg *config.ConsensusConfig,
store sm.Store,
@@ -240,7 +239,7 @@ func NewState(
// node-fragments gracefully while letting the nodes
// themselves avoid this.
if !cs.skipBootstrapping {
if err := cs.updateStateFromStore(ctx); err != nil {
if err := cs.updateStateFromStore(); err != nil {
return nil, err
}
}
@@ -248,7 +247,7 @@ func NewState(
return cs, nil
}
func (cs *State) updateStateFromStore(ctx context.Context) error {
func (cs *State) updateStateFromStore() error {
if cs.initialStatePopulated {
return nil
}
@@ -265,7 +264,7 @@ func (cs *State) updateStateFromStore(ctx context.Context) error {
cs.reconstructLastCommit(state)
}
cs.updateToState(ctx, state)
cs.updateToState(state)
cs.initialStatePopulated = true
return nil
@@ -393,7 +392,7 @@ func (cs *State) LoadCommit(height int64) *types.Commit {
// OnStart loads the latest state via the WAL, and starts the timeout and
// receive routines.
func (cs *State) OnStart(ctx context.Context) error {
if err := cs.updateStateFromStore(ctx); err != nil {
if err := cs.updateStateFromStore(); err != nil {
return err
}
@@ -718,7 +717,7 @@ func (cs *State) reconstructLastCommit(state sm.State) {
// Updates State and increments height to match that of state.
// The round becomes 0 and cs.Step becomes cstypes.RoundStepNewHeight.
func (cs *State) updateToState(ctx context.Context, state sm.State) {
func (cs *State) updateToState(state sm.State) {
if cs.CommitRound > -1 && 0 < cs.Height && cs.Height != state.LastBlockHeight {
panic(fmt.Sprintf(
"updateToState() expected state height of %v but found %v",
@@ -753,7 +752,7 @@ func (cs *State) updateToState(ctx context.Context, state sm.State) {
"new_height", state.LastBlockHeight+1,
"old_height", cs.state.LastBlockHeight+1,
)
cs.newStep(ctx)
cs.newStep()
return
}
}
@@ -823,10 +822,10 @@ func (cs *State) updateToState(ctx context.Context, state sm.State) {
cs.state = state
// Finally, broadcast RoundState
cs.newStep(ctx)
cs.newStep()
}
func (cs *State) newStep(ctx context.Context) {
func (cs *State) newStep() {
rs := cs.RoundStateEvent()
if err := cs.wal.Write(rs); err != nil {
cs.logger.Error("failed writing to WAL", "err", err)
@@ -836,11 +835,11 @@ func (cs *State) newStep(ctx context.Context) {
// newStep is called by updateToState in NewState before the eventBus is set!
if cs.eventBus != nil {
if err := cs.eventBus.PublishEventNewRoundStep(ctx, rs); err != nil {
if err := cs.eventBus.PublishEventNewRoundStep(rs); err != nil {
cs.logger.Error("failed publishing new round step", "err", err)
}
cs.evsw.FireEvent(ctx, types.EventNewRoundStepValue, &cs.RoundState)
cs.evsw.FireEvent(types.EventNewRoundStepValue, &cs.RoundState)
}
}
@@ -923,7 +922,6 @@ func (cs *State) receiveRoutine(ctx context.Context, maxSteps int) {
if err := cs.wal.Write(mi); err != nil {
cs.logger.Error("failed writing to WAL", "err", err)
}
// handles proposals, block parts, votes
// may generate internal events (votes, complete proposals, 2/3 majorities)
cs.handleMsg(ctx, mi)
@@ -977,7 +975,7 @@ func (cs *State) handleMsg(ctx context.Context, mi msgInfo) {
case *BlockPartMessage:
// if the proposal is complete, we'll enterPrevote or tryFinalizeCommit
added, err = cs.addProposalBlockPart(ctx, msg, peerID)
added, err = cs.addProposalBlockPart(msg, peerID)
// We unlock here to yield to any routines that need to read the the RoundState.
// Previously, this code held the lock from the point at which the final block
@@ -1083,21 +1081,21 @@ func (cs *State) handleTimeout(
cs.enterPropose(ctx, ti.Height, 0)
case cstypes.RoundStepPropose:
if err := cs.eventBus.PublishEventTimeoutPropose(ctx, cs.RoundStateEvent()); err != nil {
if err := cs.eventBus.PublishEventTimeoutPropose(cs.RoundStateEvent()); err != nil {
cs.logger.Error("failed publishing timeout propose", "err", err)
}
cs.enterPrevote(ctx, ti.Height, ti.Round)
case cstypes.RoundStepPrevoteWait:
if err := cs.eventBus.PublishEventTimeoutWait(ctx, cs.RoundStateEvent()); err != nil {
if err := cs.eventBus.PublishEventTimeoutWait(cs.RoundStateEvent()); err != nil {
cs.logger.Error("failed publishing timeout wait", "err", err)
}
cs.enterPrecommit(ctx, ti.Height, ti.Round)
case cstypes.RoundStepPrecommitWait:
if err := cs.eventBus.PublishEventTimeoutWait(ctx, cs.RoundStateEvent()); err != nil {
if err := cs.eventBus.PublishEventTimeoutWait(cs.RoundStateEvent()); err != nil {
cs.logger.Error("failed publishing timeout wait", "err", err)
}
@@ -1200,7 +1198,7 @@ func (cs *State) enterNewRound(ctx context.Context, height int64, round int32) {
cs.Votes.SetRound(r) // also track next round (round+1) to allow round-skipping
cs.TriggeredTimeoutPrecommit = false
if err := cs.eventBus.PublishEventNewRound(ctx, cs.NewRoundEvent()); err != nil {
if err := cs.eventBus.PublishEventNewRound(cs.NewRoundEvent()); err != nil {
cs.logger.Error("failed publishing new round", "err", err)
}
// Wait for txs to be available in the mempool
@@ -1263,7 +1261,7 @@ func (cs *State) enterPropose(ctx context.Context, height int64, round int32) {
defer func() {
// Done enterPropose:
cs.updateRoundStep(round, cstypes.RoundStepPropose)
cs.newStep(ctx)
cs.newStep()
// If we have the whole proposal + POL, then goto Prevote now.
// else, we'll enterPrevote when the rest of the proposal is received (in AddProposalBlockPart),
@@ -1455,7 +1453,7 @@ func (cs *State) enterPrevote(ctx context.Context, height int64, round int32) {
defer func() {
// Done enterPrevote:
cs.updateRoundStep(round, cstypes.RoundStepPrevote)
cs.newStep(ctx)
cs.newStep()
}()
logger.Debug("entering prevote step", "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step))
@@ -1606,7 +1604,7 @@ func (cs *State) defaultDoPrevote(ctx context.Context, height int64, round int32
}
// Enter: any +2/3 prevotes at next round.
func (cs *State) enterPrevoteWait(ctx context.Context, height int64, round int32) {
func (cs *State) enterPrevoteWait(height int64, round int32) {
logger := cs.logger.With("height", height, "round", round)
if cs.Height != height || round < cs.Round || (cs.Round == round && cstypes.RoundStepPrevoteWait <= cs.Step) {
@@ -1629,7 +1627,7 @@ func (cs *State) enterPrevoteWait(ctx context.Context, height int64, round int32
defer func() {
// Done enterPrevoteWait:
cs.updateRoundStep(round, cstypes.RoundStepPrevoteWait)
cs.newStep(ctx)
cs.newStep()
}()
// Wait for some more prevotes; enterPrecommit
@@ -1657,7 +1655,7 @@ func (cs *State) enterPrecommit(ctx context.Context, height int64, round int32)
defer func() {
// Done enterPrecommit:
cs.updateRoundStep(round, cstypes.RoundStepPrecommit)
cs.newStep(ctx)
cs.newStep()
}()
// check for a polka
@@ -1676,7 +1674,7 @@ func (cs *State) enterPrecommit(ctx context.Context, height int64, round int32)
}
// At this point +2/3 prevoted for a particular block or nil.
if err := cs.eventBus.PublishEventPolka(ctx, cs.RoundStateEvent()); err != nil {
if err := cs.eventBus.PublishEventPolka(cs.RoundStateEvent()); err != nil {
logger.Error("failed publishing polka", "err", err)
}
@@ -1713,7 +1711,7 @@ func (cs *State) enterPrecommit(ctx context.Context, height int64, round int32)
logger.Debug("precommit step: +2/3 prevoted locked block; relocking")
cs.LockedRound = round
if err := cs.eventBus.PublishEventRelock(ctx, cs.RoundStateEvent()); err != nil {
if err := cs.eventBus.PublishEventRelock(cs.RoundStateEvent()); err != nil {
logger.Error("precommit step: failed publishing event relock", "err", err)
}
@@ -1736,7 +1734,7 @@ func (cs *State) enterPrecommit(ctx context.Context, height int64, round int32)
cs.LockedBlock = cs.ProposalBlock
cs.LockedBlockParts = cs.ProposalBlockParts
if err := cs.eventBus.PublishEventLock(ctx, cs.RoundStateEvent()); err != nil {
if err := cs.eventBus.PublishEventLock(cs.RoundStateEvent()); err != nil {
logger.Error("precommit step: failed publishing event lock", "err", err)
}
@@ -1758,7 +1756,7 @@ func (cs *State) enterPrecommit(ctx context.Context, height int64, round int32)
}
// Enter: any +2/3 precommits for next round.
func (cs *State) enterPrecommitWait(ctx context.Context, height int64, round int32) {
func (cs *State) enterPrecommitWait(height int64, round int32) {
logger := cs.logger.With("height", height, "round", round)
if cs.Height != height || round < cs.Round || (cs.Round == round && cs.TriggeredTimeoutPrecommit) {
@@ -1782,7 +1780,7 @@ func (cs *State) enterPrecommitWait(ctx context.Context, height int64, round int
defer func() {
// Done enterPrecommitWait:
cs.TriggeredTimeoutPrecommit = true
cs.newStep(ctx)
cs.newStep()
}()
// wait for some more precommits; enterNewRound
@@ -1809,7 +1807,7 @@ func (cs *State) enterCommit(ctx context.Context, height int64, commitRound int3
cs.updateRoundStep(cs.Round, cstypes.RoundStepCommit)
cs.CommitRound = commitRound
cs.CommitTime = tmtime.Now()
cs.newStep(ctx)
cs.newStep()
// Maybe finalize immediately.
cs.tryFinalizeCommit(ctx, height)
@@ -1844,11 +1842,11 @@ func (cs *State) enterCommit(ctx context.Context, height int64, commitRound int3
cs.metrics.MarkBlockGossipStarted()
cs.ProposalBlockParts = types.NewPartSetFromHeader(blockID.PartSetHeader)
if err := cs.eventBus.PublishEventValidBlock(ctx, cs.RoundStateEvent()); err != nil {
if err := cs.eventBus.PublishEventValidBlock(cs.RoundStateEvent()); err != nil {
logger.Error("failed publishing valid block", "err", err)
}
cs.evsw.FireEvent(ctx, types.EventValidBlockValue, &cs.RoundState)
cs.evsw.FireEvent(types.EventValidBlockValue, &cs.RoundState)
}
}
}
@@ -1975,7 +1973,7 @@ func (cs *State) finalizeCommit(ctx context.Context, height int64) {
cs.RecordMetrics(height, block)
// NewHeightStep!
cs.updateToState(ctx, stateCopy)
cs.updateToState(stateCopy)
// Private validator might have changed it's key pair => refetch pubkey.
if err := cs.updatePrivValidatorPubKey(ctx); err != nil {
@@ -2130,7 +2128,6 @@ func (cs *State) defaultSetProposal(proposal *types.Proposal, recvTime time.Time
// Asynchronously triggers either enterPrevote (before we timeout of propose) or tryFinalizeCommit,
// once we have the full block.
func (cs *State) addProposalBlockPart(
ctx context.Context,
msg *BlockPartMessage,
peerID types.NodeID,
) (added bool, err error) {
@@ -2196,7 +2193,7 @@ func (cs *State) addProposalBlockPart(
// NOTE: it's possible to receive complete proposal blocks for future rounds without having the proposal
cs.logger.Info("received complete proposal block", "height", cs.ProposalBlock.Height, "hash", cs.ProposalBlock.Hash())
if err := cs.eventBus.PublishEventCompleteProposal(ctx, cs.CompleteProposalEvent()); err != nil {
if err := cs.eventBus.PublishEventCompleteProposal(cs.CompleteProposalEvent()); err != nil {
cs.logger.Error("failed publishing event complete proposal", "err", err)
}
}
@@ -2315,11 +2312,11 @@ func (cs *State) addVote(
}
cs.logger.Debug("added vote to last precommits", "last_commit", cs.LastCommit.StringShort())
if err := cs.eventBus.PublishEventVote(ctx, types.EventDataVote{Vote: vote}); err != nil {
if err := cs.eventBus.PublishEventVote(types.EventDataVote{Vote: vote}); err != nil {
return added, err
}
cs.evsw.FireEvent(ctx, types.EventVoteValue, vote)
cs.evsw.FireEvent(types.EventVoteValue, vote)
// if we can skip timeoutCommit and have all the votes now,
if cs.bypassCommitTimeout() && cs.LastCommit.HasAll() {
@@ -2352,10 +2349,10 @@ func (cs *State) addVote(
return
}
if err := cs.eventBus.PublishEventVote(ctx, types.EventDataVote{Vote: vote}); err != nil {
if err := cs.eventBus.PublishEventVote(types.EventDataVote{Vote: vote}); err != nil {
return added, err
}
cs.evsw.FireEvent(ctx, types.EventVoteValue, vote)
cs.evsw.FireEvent(types.EventVoteValue, vote)
switch vote.Type {
case tmproto.PrevoteType:
@@ -2390,8 +2387,8 @@ func (cs *State) addVote(
cs.ProposalBlockParts = types.NewPartSetFromHeader(blockID.PartSetHeader)
}
cs.evsw.FireEvent(ctx, types.EventValidBlockValue, &cs.RoundState)
if err := cs.eventBus.PublishEventValidBlock(ctx, cs.RoundStateEvent()); err != nil {
cs.evsw.FireEvent(types.EventValidBlockValue, &cs.RoundState)
if err := cs.eventBus.PublishEventValidBlock(cs.RoundStateEvent()); err != nil {
return added, err
}
}
@@ -2408,7 +2405,7 @@ func (cs *State) addVote(
if ok && (cs.isProposalComplete() || blockID.IsNil()) {
cs.enterPrecommit(ctx, height, vote.Round)
} else if prevotes.HasTwoThirdsAny() {
cs.enterPrevoteWait(ctx, height, vote.Round)
cs.enterPrevoteWait(height, vote.Round)
}
case cs.Proposal != nil && 0 <= cs.Proposal.POLRound && cs.Proposal.POLRound == vote.Round:
@@ -2439,11 +2436,11 @@ func (cs *State) addVote(
cs.enterNewRound(ctx, cs.Height, 0)
}
} else {
cs.enterPrecommitWait(ctx, height, vote.Round)
cs.enterPrecommitWait(height, vote.Round)
}
} else if cs.Round <= vote.Round && precommits.HasTwoThirdsAny() {
cs.enterNewRound(ctx, height, vote.Round)
cs.enterPrecommitWait(ctx, height, vote.Round)
cs.enterPrecommitWait(height, vote.Round)
}
default:
@@ -2494,7 +2491,7 @@ func (cs *State) signVote(
if err != nil {
return nil, err
}
vote.VoteExtension = ext
vote.Extension = ext
default:
timeout = time.Second
}
@@ -2506,6 +2503,7 @@ func (cs *State) signVote(
err := cs.privValidator.SignVote(ctxto, cs.state.ChainID, v)
vote.Signature = v.Signature
vote.ExtensionSignature = v.ExtensionSignature
vote.Timestamp = v.Timestamp
return vote, err
+241
View File
@@ -2015,6 +2015,235 @@ func TestFinalizeBlockCalled(t *testing.T) {
}
}
// TestExtendVoteCalled tests that the vote extension methods are called at the
// correct point in the consensus algorithm.
func TestExtendVoteCalled(t *testing.T) {
config := configSetup(t)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
m := abcimocks.NewBaseMock()
m.On("ProcessProposal", mock.Anything).Return(abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT})
m.On("ExtendVote", mock.Anything).Return(abci.ResponseExtendVote{
VoteExtension: []byte("extension"),
})
m.On("VerifyVoteExtension", mock.Anything).Return(abci.ResponseVerifyVoteExtension{
Status: abci.ResponseVerifyVoteExtension_ACCEPT,
})
m.On("FinalizeBlock", mock.Anything).Return(abci.ResponseFinalizeBlock{}).Maybe()
cs1, vss := makeState(ctx, t, makeStateArgs{config: config, application: m})
height, round := cs1.Height, cs1.Round
proposalCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryCompleteProposal)
newRoundCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryNewRound)
pv1, err := cs1.privValidator.GetPubKey(ctx)
require.NoError(t, err)
addr := pv1.Address()
voteCh := subscribeToVoter(ctx, t, cs1, addr)
startTestRound(ctx, cs1, cs1.Height, round)
ensureNewRound(t, newRoundCh, height, round)
ensureNewProposal(t, proposalCh, height, round)
m.AssertNotCalled(t, "ExtendVote", mock.Anything)
rs := cs1.GetRoundState()
blockID := types.BlockID{
Hash: rs.ProposalBlock.Hash(),
PartSetHeader: rs.ProposalBlockParts.Header(),
}
signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), blockID, vss[1:]...)
ensurePrevoteMatch(t, voteCh, height, round, blockID.Hash)
ensurePrecommit(t, voteCh, height, round)
m.AssertCalled(t, "ExtendVote", abci.RequestExtendVote{
Height: height,
Hash: blockID.Hash,
})
m.AssertCalled(t, "VerifyVoteExtension", abci.RequestVerifyVoteExtension{
Hash: blockID.Hash,
ValidatorAddress: addr,
Height: height,
VoteExtension: []byte("extension"),
})
signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), blockID, vss[1:]...)
ensureNewRound(t, newRoundCh, height+1, 0)
m.AssertExpectations(t)
// Only 3 of the vote extensions are seen, as consensus proceeds as soon as the +2/3 threshold
// is observed by the consensus engine.
for _, pv := range vss[:3] {
pv, err := pv.GetPubKey(ctx)
require.NoError(t, err)
addr := pv.Address()
m.AssertCalled(t, "VerifyVoteExtension", abci.RequestVerifyVoteExtension{
Hash: blockID.Hash,
ValidatorAddress: addr,
Height: height,
VoteExtension: []byte("extension"),
})
}
}
// TestVerifyVoteExtensionNotCalledOnAbsentPrecommit tests that the VerifyVoteExtension
// method is not called for a validator's vote that is never delivered.
func TestVerifyVoteExtensionNotCalledOnAbsentPrecommit(t *testing.T) {
config := configSetup(t)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
m := abcimocks.NewBaseMock()
m.On("ProcessProposal", mock.Anything).Return(abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT})
m.On("ExtendVote", mock.Anything).Return(abci.ResponseExtendVote{
VoteExtension: []byte("extension"),
})
m.On("VerifyVoteExtension", mock.Anything).Return(abci.ResponseVerifyVoteExtension{
Status: abci.ResponseVerifyVoteExtension_ACCEPT,
})
m.On("FinalizeBlock", mock.Anything).Return(abci.ResponseFinalizeBlock{}).Maybe()
cs1, vss := makeState(ctx, t, makeStateArgs{config: config, application: m})
height, round := cs1.Height, cs1.Round
proposalCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryCompleteProposal)
newRoundCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryNewRound)
pv1, err := cs1.privValidator.GetPubKey(ctx)
require.NoError(t, err)
addr := pv1.Address()
voteCh := subscribeToVoter(ctx, t, cs1, addr)
startTestRound(ctx, cs1, cs1.Height, round)
ensureNewRound(t, newRoundCh, height, round)
ensureNewProposal(t, proposalCh, height, round)
rs := cs1.GetRoundState()
blockID := types.BlockID{
Hash: rs.ProposalBlock.Hash(),
PartSetHeader: rs.ProposalBlockParts.Header(),
}
signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), blockID, vss[2:]...)
ensurePrevoteMatch(t, voteCh, height, round, blockID.Hash)
ensurePrecommit(t, voteCh, height, round)
m.AssertCalled(t, "ExtendVote", abci.RequestExtendVote{
Height: height,
Hash: blockID.Hash,
})
m.AssertCalled(t, "VerifyVoteExtension", abci.RequestVerifyVoteExtension{
Hash: blockID.Hash,
ValidatorAddress: addr,
Height: height,
VoteExtension: []byte("extension"),
})
signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), blockID, vss[2:]...)
ensureNewRound(t, newRoundCh, height+1, 0)
m.AssertExpectations(t)
// vss[1] did not issue a precommit for the block, ensure that a vote extension
// for its address was not sent to the application.
pv, err := vss[1].GetPubKey(ctx)
require.NoError(t, err)
addr = pv.Address()
m.AssertNotCalled(t, "VerifyVoteExtension", abci.RequestVerifyVoteExtension{
Hash: blockID.Hash,
ValidatorAddress: addr,
Height: height,
VoteExtension: []byte("extension"),
})
}
// TestPrepareProposalReceivesVoteExtensions tests that the PrepareProposal method
// is called with the vote extensions from the previous height. The test functions
// be completing a consensus height with a mock application as the proposer. The
// test then proceeds to fail sever rounds of consensus until the mock application
// is the proposer again and ensures that the mock application receives the set of
// vote extensions from the previous consensus instance.
func TestPrepareProposalReceivesVoteExtensions(t *testing.T) {
config := configSetup(t)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// create a list of vote extensions, one for each validator.
voteExtensions := [][]byte{
[]byte("extension 0"),
[]byte("extension 1"),
[]byte("extension 2"),
[]byte("extension 3"),
}
m := abcimocks.NewBaseMock()
m.On("ExtendVote", mock.Anything).Return(abci.ResponseExtendVote{
VoteExtension: voteExtensions[0],
})
m.On("PrepareProposal", mock.Anything).Return(abci.ResponsePrepareProposal{}).Once()
cs1, vss := makeState(ctx, t, makeStateArgs{config: config, application: m})
height, round := cs1.Height, cs1.Round
newRoundCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryNewRound)
proposalCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryCompleteProposal)
pv1, err := cs1.privValidator.GetPubKey(ctx)
require.NoError(t, err)
addr := pv1.Address()
voteCh := subscribeToVoter(ctx, t, cs1, addr)
startTestRound(ctx, cs1, height, round)
ensureNewRound(t, newRoundCh, height, round)
ensureNewProposal(t, proposalCh, height, round)
rs := cs1.GetRoundState()
blockID := types.BlockID{
Hash: rs.ProposalBlock.Hash(),
PartSetHeader: rs.ProposalBlockParts.Header(),
}
signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), blockID, vss[1:]...)
// create a precommit for each validator with the associated vote extension.
for i, vs := range vss[1:] {
signAddPrecommitWithExtension(ctx, t, cs1, config.ChainID(), blockID, voteExtensions[i+1], vs)
}
ensurePrevote(t, voteCh, height, round)
// ensure that the height is committed.
ensurePrecommitMatch(t, voteCh, height, round, blockID.Hash)
incrementHeight(vss[1:]...)
height++
round = 0
ensureNewRound(t, newRoundCh, height, round)
incrementRound(vss[1:]...)
incrementRound(vss[1:]...)
incrementRound(vss[1:]...)
round = 3
// capture the prepare proposal request.
rpp := abci.RequestPrepareProposal{}
m.On("PrepareProposal", mock.MatchedBy(func(r abci.RequestPrepareProposal) bool {
rpp = r
return true
})).Return(abci.ResponsePrepareProposal{})
signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), types.BlockID{}, vss[1:]...)
ensureNewRound(t, newRoundCh, height, round)
ensureNewProposal(t, proposalCh, height, round)
// ensure that the proposer received the list of vote extensions from the
// previous height.
for i := range vss {
require.Equal(t, rpp.LocalLastCommit.Votes[i].VoteExtension, voteExtensions[i])
}
}
// 4 vals, 3 Nil Precommits at P0
// What we want:
// P0 waits for timeoutPrecommit before starting next round
@@ -2719,3 +2948,15 @@ func subscribe(
}()
return ch
}
func signAddPrecommitWithExtension(ctx context.Context,
t *testing.T,
cs *State,
chainID string,
blockID types.BlockID,
extension []byte,
stub *validatorStub) {
v, err := stub.signVote(ctx, tmproto.PrecommitType, chainID, blockID, extension)
require.NoError(t, err, "failed to sign vote")
addVotes(cs, v)
}
@@ -88,6 +88,7 @@ func makeVoteHR(
require.NoError(t, err, "Error signing vote")
vote.Signature = v.Signature
vote.ExtensionSignature = v.ExtensionSignature
return vote
}
+1 -1
View File
@@ -81,7 +81,7 @@ func WALGenerateNBlocks(ctx context.Context, t *testing.T, logger log.Logger, wr
mempool := emptyMempool{}
evpool := sm.EmptyEvidencePool{}
blockExec := sm.NewBlockExecutor(stateStore, log.NewNopLogger(), proxyApp, mempool, evpool, blockStore, eventBus, sm.NopMetrics())
consensusState, err := NewState(ctx, logger, cfg.Consensus, stateStore, blockExec, blockStore, mempool, evpool, eventBus)
consensusState, err := NewState(logger, cfg.Consensus, stateStore, blockExec, blockStore, mempool, evpool, eventBus)
if err != nil {
t.Fatal(err)
}
+38 -38
View File
@@ -66,7 +66,7 @@ func (b *EventBus) Observe(ctx context.Context, observe func(tmpubsub.Message) e
return b.pubsub.Observe(ctx, observe, queries...)
}
func (b *EventBus) Publish(ctx context.Context, eventValue string, eventData types.EventData) error {
func (b *EventBus) Publish(eventValue string, eventData types.EventData) error {
tokens := strings.Split(types.EventTypeKey, ".")
event := abci.Event{
Type: tokens[0],
@@ -78,19 +78,19 @@ func (b *EventBus) Publish(ctx context.Context, eventValue string, eventData typ
},
}
return b.pubsub.PublishWithEvents(ctx, eventData, []abci.Event{event})
return b.pubsub.PublishWithEvents(eventData, []abci.Event{event})
}
func (b *EventBus) PublishEventNewBlock(ctx context.Context, data types.EventDataNewBlock) error {
func (b *EventBus) PublishEventNewBlock(data types.EventDataNewBlock) error {
events := data.ResultFinalizeBlock.Events
// add Tendermint-reserved new block event
events = append(events, types.EventNewBlock)
return b.pubsub.PublishWithEvents(ctx, data, events)
return b.pubsub.PublishWithEvents(data, events)
}
func (b *EventBus) PublishEventNewBlockHeader(ctx context.Context, data types.EventDataNewBlockHeader) error {
func (b *EventBus) PublishEventNewBlockHeader(data types.EventDataNewBlockHeader) error {
// no explicit deadline for publishing events
events := data.ResultFinalizeBlock.Events
@@ -98,33 +98,33 @@ func (b *EventBus) PublishEventNewBlockHeader(ctx context.Context, data types.Ev
// add Tendermint-reserved new block header event
events = append(events, types.EventNewBlockHeader)
return b.pubsub.PublishWithEvents(ctx, data, events)
return b.pubsub.PublishWithEvents(data, events)
}
func (b *EventBus) PublishEventNewEvidence(ctx context.Context, evidence types.EventDataNewEvidence) error {
return b.Publish(ctx, types.EventNewEvidenceValue, evidence)
func (b *EventBus) PublishEventNewEvidence(evidence types.EventDataNewEvidence) error {
return b.Publish(types.EventNewEvidenceValue, evidence)
}
func (b *EventBus) PublishEventVote(ctx context.Context, data types.EventDataVote) error {
return b.Publish(ctx, types.EventVoteValue, data)
func (b *EventBus) PublishEventVote(data types.EventDataVote) error {
return b.Publish(types.EventVoteValue, data)
}
func (b *EventBus) PublishEventValidBlock(ctx context.Context, data types.EventDataRoundState) error {
return b.Publish(ctx, types.EventValidBlockValue, data)
func (b *EventBus) PublishEventValidBlock(data types.EventDataRoundState) error {
return b.Publish(types.EventValidBlockValue, data)
}
func (b *EventBus) PublishEventBlockSyncStatus(ctx context.Context, data types.EventDataBlockSyncStatus) error {
return b.Publish(ctx, types.EventBlockSyncStatusValue, data)
func (b *EventBus) PublishEventBlockSyncStatus(data types.EventDataBlockSyncStatus) error {
return b.Publish(types.EventBlockSyncStatusValue, data)
}
func (b *EventBus) PublishEventStateSyncStatus(ctx context.Context, data types.EventDataStateSyncStatus) error {
return b.Publish(ctx, types.EventStateSyncStatusValue, data)
func (b *EventBus) PublishEventStateSyncStatus(data types.EventDataStateSyncStatus) error {
return b.Publish(types.EventStateSyncStatusValue, data)
}
// PublishEventTx publishes tx event with events from Result. Note it will add
// predefined keys (EventTypeKey, TxHashKey). Existing events with the same keys
// will be overwritten.
func (b *EventBus) PublishEventTx(ctx context.Context, data types.EventDataTx) error {
func (b *EventBus) PublishEventTx(data types.EventDataTx) error {
events := data.Result.Events
// add Tendermint-reserved events
@@ -152,45 +152,45 @@ func (b *EventBus) PublishEventTx(ctx context.Context, data types.EventDataTx) e
},
})
return b.pubsub.PublishWithEvents(ctx, data, events)
return b.pubsub.PublishWithEvents(data, events)
}
func (b *EventBus) PublishEventNewRoundStep(ctx context.Context, data types.EventDataRoundState) error {
return b.Publish(ctx, types.EventNewRoundStepValue, data)
func (b *EventBus) PublishEventNewRoundStep(data types.EventDataRoundState) error {
return b.Publish(types.EventNewRoundStepValue, data)
}
func (b *EventBus) PublishEventTimeoutPropose(ctx context.Context, data types.EventDataRoundState) error {
return b.Publish(ctx, types.EventTimeoutProposeValue, data)
func (b *EventBus) PublishEventTimeoutPropose(data types.EventDataRoundState) error {
return b.Publish(types.EventTimeoutProposeValue, data)
}
func (b *EventBus) PublishEventTimeoutWait(ctx context.Context, data types.EventDataRoundState) error {
return b.Publish(ctx, types.EventTimeoutWaitValue, data)
func (b *EventBus) PublishEventTimeoutWait(data types.EventDataRoundState) error {
return b.Publish(types.EventTimeoutWaitValue, data)
}
func (b *EventBus) PublishEventNewRound(ctx context.Context, data types.EventDataNewRound) error {
return b.Publish(ctx, types.EventNewRoundValue, data)
func (b *EventBus) PublishEventNewRound(data types.EventDataNewRound) error {
return b.Publish(types.EventNewRoundValue, data)
}
func (b *EventBus) PublishEventCompleteProposal(ctx context.Context, data types.EventDataCompleteProposal) error {
return b.Publish(ctx, types.EventCompleteProposalValue, data)
func (b *EventBus) PublishEventCompleteProposal(data types.EventDataCompleteProposal) error {
return b.Publish(types.EventCompleteProposalValue, data)
}
func (b *EventBus) PublishEventPolka(ctx context.Context, data types.EventDataRoundState) error {
return b.Publish(ctx, types.EventPolkaValue, data)
func (b *EventBus) PublishEventPolka(data types.EventDataRoundState) error {
return b.Publish(types.EventPolkaValue, data)
}
func (b *EventBus) PublishEventRelock(ctx context.Context, data types.EventDataRoundState) error {
return b.Publish(ctx, types.EventRelockValue, data)
func (b *EventBus) PublishEventRelock(data types.EventDataRoundState) error {
return b.Publish(types.EventRelockValue, data)
}
func (b *EventBus) PublishEventLock(ctx context.Context, data types.EventDataRoundState) error {
return b.Publish(ctx, types.EventLockValue, data)
func (b *EventBus) PublishEventLock(data types.EventDataRoundState) error {
return b.Publish(types.EventLockValue, data)
}
func (b *EventBus) PublishEventValidatorSetUpdates(ctx context.Context, data types.EventDataValidatorSetUpdates) error {
return b.Publish(ctx, types.EventValidatorSetUpdatesValue, data)
func (b *EventBus) PublishEventValidatorSetUpdates(data types.EventDataValidatorSetUpdates) error {
return b.Publish(types.EventValidatorSetUpdatesValue, data)
}
func (b *EventBus) PublishEventEvidenceValidated(ctx context.Context, evidence types.EventDataEvidenceValidated) error {
return b.Publish(ctx, types.EventEvidenceValidatedValue, evidence)
func (b *EventBus) PublishEventEvidenceValidated(evidence types.EventDataEvidenceValidated) error {
return b.Publish(types.EventEvidenceValidatedValue, evidence)
}
+22 -22
View File
@@ -55,7 +55,7 @@ func TestEventBusPublishEventTx(t *testing.T) {
assert.Equal(t, result, edt.Result)
}()
err = eventBus.PublishEventTx(ctx, types.EventDataTx{
err = eventBus.PublishEventTx(types.EventDataTx{
TxResult: abci.TxResult{
Height: 1,
Index: 0,
@@ -112,7 +112,7 @@ func TestEventBusPublishEventNewBlock(t *testing.T) {
assert.Equal(t, resultFinalizeBlock, edt.ResultFinalizeBlock)
}()
err = eventBus.PublishEventNewBlock(ctx, types.EventDataNewBlock{
err = eventBus.PublishEventNewBlock(types.EventDataNewBlock{
Block: block,
BlockID: blockID,
ResultFinalizeBlock: resultFinalizeBlock,
@@ -223,7 +223,7 @@ func TestEventBusPublishEventTxDuplicateKeys(t *testing.T) {
}
}()
assert.NoError(t, eventBus.PublishEventTx(ctx, types.EventDataTx{
assert.NoError(t, eventBus.PublishEventTx(types.EventDataTx{
TxResult: abci.TxResult{
Height: 1,
Index: 0,
@@ -280,7 +280,7 @@ func TestEventBusPublishEventNewBlockHeader(t *testing.T) {
assert.Equal(t, resultFinalizeBlock, edt.ResultFinalizeBlock)
}()
err = eventBus.PublishEventNewBlockHeader(ctx, types.EventDataNewBlockHeader{
err = eventBus.PublishEventNewBlockHeader(types.EventDataNewBlockHeader{
Header: block.Header,
ResultFinalizeBlock: resultFinalizeBlock,
})
@@ -322,7 +322,7 @@ func TestEventBusPublishEventEvidenceValidated(t *testing.T) {
assert.Equal(t, int64(1), edt.Height)
}()
err = eventBus.PublishEventEvidenceValidated(ctx, types.EventDataEvidenceValidated{
err = eventBus.PublishEventEvidenceValidated(types.EventDataEvidenceValidated{
Evidence: ev,
Height: int64(1),
})
@@ -364,7 +364,7 @@ func TestEventBusPublishEventNewEvidence(t *testing.T) {
assert.Equal(t, int64(4), edt.Height)
}()
err = eventBus.PublishEventNewEvidence(ctx, types.EventDataNewEvidence{
err = eventBus.PublishEventNewEvidence(types.EventDataNewEvidence{
Evidence: ev,
Height: 4,
})
@@ -408,22 +408,22 @@ func TestEventBusPublish(t *testing.T) {
}
}()
require.NoError(t, eventBus.Publish(ctx, types.EventNewBlockHeaderValue,
require.NoError(t, eventBus.Publish(types.EventNewBlockHeaderValue,
types.EventDataNewBlockHeader{}))
require.NoError(t, eventBus.PublishEventNewBlock(ctx, types.EventDataNewBlock{}))
require.NoError(t, eventBus.PublishEventNewBlockHeader(ctx, types.EventDataNewBlockHeader{}))
require.NoError(t, eventBus.PublishEventVote(ctx, types.EventDataVote{}))
require.NoError(t, eventBus.PublishEventNewRoundStep(ctx, types.EventDataRoundState{}))
require.NoError(t, eventBus.PublishEventTimeoutPropose(ctx, types.EventDataRoundState{}))
require.NoError(t, eventBus.PublishEventTimeoutWait(ctx, types.EventDataRoundState{}))
require.NoError(t, eventBus.PublishEventNewRound(ctx, types.EventDataNewRound{}))
require.NoError(t, eventBus.PublishEventCompleteProposal(ctx, types.EventDataCompleteProposal{}))
require.NoError(t, eventBus.PublishEventPolka(ctx, types.EventDataRoundState{}))
require.NoError(t, eventBus.PublishEventRelock(ctx, types.EventDataRoundState{}))
require.NoError(t, eventBus.PublishEventLock(ctx, types.EventDataRoundState{}))
require.NoError(t, eventBus.PublishEventValidatorSetUpdates(ctx, types.EventDataValidatorSetUpdates{}))
require.NoError(t, eventBus.PublishEventBlockSyncStatus(ctx, types.EventDataBlockSyncStatus{}))
require.NoError(t, eventBus.PublishEventStateSyncStatus(ctx, types.EventDataStateSyncStatus{}))
require.NoError(t, eventBus.PublishEventNewBlock(types.EventDataNewBlock{}))
require.NoError(t, eventBus.PublishEventNewBlockHeader(types.EventDataNewBlockHeader{}))
require.NoError(t, eventBus.PublishEventVote(types.EventDataVote{}))
require.NoError(t, eventBus.PublishEventNewRoundStep(types.EventDataRoundState{}))
require.NoError(t, eventBus.PublishEventTimeoutPropose(types.EventDataRoundState{}))
require.NoError(t, eventBus.PublishEventTimeoutWait(types.EventDataRoundState{}))
require.NoError(t, eventBus.PublishEventNewRound(types.EventDataNewRound{}))
require.NoError(t, eventBus.PublishEventCompleteProposal(types.EventDataCompleteProposal{}))
require.NoError(t, eventBus.PublishEventPolka(types.EventDataRoundState{}))
require.NoError(t, eventBus.PublishEventRelock(types.EventDataRoundState{}))
require.NoError(t, eventBus.PublishEventLock(types.EventDataRoundState{}))
require.NoError(t, eventBus.PublishEventValidatorSetUpdates(types.EventDataValidatorSetUpdates{}))
require.NoError(t, eventBus.PublishEventBlockSyncStatus(types.EventDataBlockSyncStatus{}))
require.NoError(t, eventBus.PublishEventStateSyncStatus(types.EventDataStateSyncStatus{}))
require.GreaterOrEqual(t, <-count, numEventsExpected)
}
@@ -505,7 +505,7 @@ func benchmarkEventBus(numClients int, randQueries bool, randEvents bool, b *tes
eventValue = randEventValue()
}
err := eventBus.Publish(ctx, eventValue, types.EventDataString("Gamora"))
err := eventBus.Publish(eventValue, types.EventDataString("Gamora"))
if err != nil {
b.Error(err)
}
+1 -1
View File
@@ -338,7 +338,7 @@ func (evpool *Pool) addPendingEvidence(ctx context.Context, ev types.Evidence) e
return nil
}
return evpool.eventBus.PublishEventEvidenceValidated(ctx, types.EventDataEvidenceValidated{
return evpool.eventBus.PublishEventEvidenceValidated(types.EventDataEvidenceValidated{
Evidence: ev,
Height: ev.Height(),
})
+7 -7
View File
@@ -46,7 +46,7 @@ type reactorTestSuite struct {
numStateStores int
}
func setup(ctx context.Context, t *testing.T, stateStores []sm.Store, chBuf uint) *reactorTestSuite {
func setup(ctx context.Context, t *testing.T, stateStores []sm.Store) *reactorTestSuite {
t.Helper()
pID := make([]byte, 16)
@@ -245,7 +245,7 @@ func TestReactorMultiDisconnect(t *testing.T) {
stateDB1 := initializeValidatorState(ctx, t, val, height)
stateDB2 := initializeValidatorState(ctx, t, val, height)
rts := setup(ctx, t, []sm.Store{stateDB1, stateDB2}, 20)
rts := setup(ctx, t, []sm.Store{stateDB1, stateDB2})
primary := rts.nodes[0]
secondary := rts.nodes[1]
@@ -290,7 +290,7 @@ func TestReactorBroadcastEvidence(t *testing.T) {
stateDBs[i] = initializeValidatorState(ctx, t, val, height)
}
rts := setup(ctx, t, stateDBs, 0)
rts := setup(ctx, t, stateDBs)
rts.start(ctx, t)
@@ -348,7 +348,7 @@ func TestReactorBroadcastEvidence_Lagging(t *testing.T) {
stateDB1 := initializeValidatorState(ctx, t, val, height1)
stateDB2 := initializeValidatorState(ctx, t, val, height2)
rts := setup(ctx, t, []sm.Store{stateDB1, stateDB2}, 100)
rts := setup(ctx, t, []sm.Store{stateDB1, stateDB2})
rts.start(ctx, t)
primary := rts.nodes[0]
@@ -382,7 +382,7 @@ func TestReactorBroadcastEvidence_Pending(t *testing.T) {
stateDB1 := initializeValidatorState(ctx, t, val, height)
stateDB2 := initializeValidatorState(ctx, t, val, height)
rts := setup(ctx, t, []sm.Store{stateDB1, stateDB2}, 100)
rts := setup(ctx, t, []sm.Store{stateDB1, stateDB2})
primary := rts.nodes[0]
secondary := rts.nodes[1]
@@ -423,7 +423,7 @@ func TestReactorBroadcastEvidence_Committed(t *testing.T) {
stateDB1 := initializeValidatorState(ctx, t, val, height)
stateDB2 := initializeValidatorState(ctx, t, val, height)
rts := setup(ctx, t, []sm.Store{stateDB1, stateDB2}, 0)
rts := setup(ctx, t, []sm.Store{stateDB1, stateDB2})
primary := rts.nodes[0]
secondary := rts.nodes[1]
@@ -482,7 +482,7 @@ func TestReactorBroadcastEvidence_FullyConnected(t *testing.T) {
stateDBs[i] = initializeValidatorState(ctx, t, val, height)
}
rts := setup(ctx, t, stateDBs, 0)
rts := setup(ctx, t, stateDBs)
rts.start(ctx, t)
evList := createEvidenceList(ctx, t, rts.pools[rts.network.RandomNode().NodeID], val, numEvidence)
+1 -1
View File
@@ -25,7 +25,7 @@ func BenchmarkTxMempool_CheckTx(b *testing.B) {
// setup the cache and the mempool number for hitting GetEvictableTxs during the
// benchmark. 5000 is the current default mempool size in the TM config.
txmp := setup(ctx, b, client, 10000)
txmp := setup(b, client, 10000)
txmp.config.Size = 5000
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
+12 -12
View File
@@ -72,7 +72,7 @@ func (app *application) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx {
}
}
func setup(ctx context.Context, t testing.TB, app abciclient.Client, cacheSize int, options ...TxMempoolOption) *TxMempool {
func setup(t testing.TB, app abciclient.Client, cacheSize int, options ...TxMempoolOption) *TxMempool {
t.Helper()
logger := log.NewNopLogger()
@@ -131,7 +131,7 @@ func TestTxMempool_TxsAvailable(t *testing.T) {
}
t.Cleanup(client.Wait)
txmp := setup(ctx, t, client, 0)
txmp := setup(t, client, 0)
txmp.EnableTxsAvailable()
ensureNoTxFire := func() {
@@ -194,7 +194,7 @@ func TestTxMempool_Size(t *testing.T) {
}
t.Cleanup(client.Wait)
txmp := setup(ctx, t, client, 0)
txmp := setup(t, client, 0)
txs := checkTxs(ctx, t, txmp, 100, 0)
require.Equal(t, len(txs), txmp.Size())
require.Equal(t, int64(5690), txmp.SizeBytes())
@@ -227,7 +227,7 @@ func TestTxMempool_Flush(t *testing.T) {
}
t.Cleanup(client.Wait)
txmp := setup(ctx, t, client, 0)
txmp := setup(t, client, 0)
txs := checkTxs(ctx, t, txmp, 100, 0)
require.Equal(t, len(txs), txmp.Size())
require.Equal(t, int64(5690), txmp.SizeBytes())
@@ -261,7 +261,7 @@ func TestTxMempool_ReapMaxBytesMaxGas(t *testing.T) {
}
t.Cleanup(client.Wait)
txmp := setup(ctx, t, client, 0)
txmp := setup(t, client, 0)
tTxs := checkTxs(ctx, t, txmp, 100, 0) // all txs request 1 gas unit
require.Equal(t, len(tTxs), txmp.Size())
require.Equal(t, int64(5690), txmp.SizeBytes())
@@ -320,7 +320,7 @@ func TestTxMempool_ReapMaxTxs(t *testing.T) {
}
t.Cleanup(client.Wait)
txmp := setup(ctx, t, client, 0)
txmp := setup(t, client, 0)
tTxs := checkTxs(ctx, t, txmp, 100, 0)
require.Equal(t, len(tTxs), txmp.Size())
require.Equal(t, int64(5690), txmp.SizeBytes())
@@ -377,7 +377,7 @@ func TestTxMempool_CheckTxExceedsMaxSize(t *testing.T) {
t.Fatal(err)
}
t.Cleanup(client.Wait)
txmp := setup(ctx, t, client, 0)
txmp := setup(t, client, 0)
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
tx := make([]byte, txmp.config.MaxTxBytes+1)
@@ -403,7 +403,7 @@ func TestTxMempool_CheckTxSamePeer(t *testing.T) {
}
t.Cleanup(client.Wait)
txmp := setup(ctx, t, client, 100)
txmp := setup(t, client, 100)
peerID := uint16(1)
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
@@ -427,7 +427,7 @@ func TestTxMempool_CheckTxSameSender(t *testing.T) {
}
t.Cleanup(client.Wait)
txmp := setup(ctx, t, client, 100)
txmp := setup(t, client, 100)
peerID := uint16(1)
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
@@ -458,7 +458,7 @@ func TestTxMempool_ConcurrentTxs(t *testing.T) {
}
t.Cleanup(client.Wait)
txmp := setup(ctx, t, client, 100)
txmp := setup(t, client, 100)
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
checkTxDone := make(chan struct{})
@@ -531,7 +531,7 @@ func TestTxMempool_ExpiredTxs_NumBlocks(t *testing.T) {
}
t.Cleanup(client.Wait)
txmp := setup(ctx, t, client, 500)
txmp := setup(t, client, 500)
txmp.height = 100
txmp.config.TTLNumBlocks = 10
@@ -612,7 +612,7 @@ func TestTxMempool_CheckTxPostCheckError(t *testing.T) {
postCheckFn := func(_ types.Tx, _ *abci.ResponseCheckTx) error {
return testCase.err
}
txmp := setup(ctx, t, client, 0, WithPostCheck(postCheckFn))
txmp := setup(t, client, 0, WithPostCheck(postCheckFn))
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
tx := make([]byte, txmp.config.MaxTxBytes-1)
_, err := rng.Read(tx)
+1 -1
View File
@@ -68,7 +68,7 @@ func setupReactors(ctx context.Context, t *testing.T, logger log.Logger, numNode
require.NoError(t, client.Start(ctx))
t.Cleanup(client.Wait)
mempool := setup(ctx, t, client, 0)
mempool := setup(t, client, 0)
rts.mempools[nodeID] = mempool
rts.peerChans[nodeID] = make(chan p2p.PeerUpdate, chBuf)
+2 -2
View File
@@ -228,7 +228,7 @@ func TestDeriveSecretsAndChallengeGolden(t *testing.T) {
goldenFilepath := filepath.Join("testdata", t.Name()+".golden")
if *update {
t.Logf("Updating golden test vector file %s", goldenFilepath)
data := createGoldenTestVectors(t)
data := createGoldenTestVectors()
require.NoError(t, os.WriteFile(goldenFilepath, []byte(data), 0644))
}
f, err := os.Open(goldenFilepath)
@@ -306,7 +306,7 @@ func readLots(t *testing.T, wg *sync.WaitGroup, conn io.Reader, n int) {
// Creates the data for a test vector file.
// The file format is:
// Hex(diffie_hellman_secret), loc_is_least, Hex(recvSecret), Hex(sendSecret), Hex(challenge)
func createGoldenTestVectors(t *testing.T) string {
func createGoldenTestVectors() string {
data := ""
for i := 0; i < 32; i++ {
randSecretVector := tmrand.Bytes(32)
+2 -1
View File
@@ -26,6 +26,7 @@ func newConnTracker(max uint, window time.Duration) connectionTracker {
cache: make(map[string]uint),
lastConnect: make(map[string]time.Time),
max: max,
window: window,
}
}
@@ -43,7 +44,7 @@ func (rat *connTrackerImpl) AddConn(addr net.IP) error {
if num := rat.cache[address]; num >= rat.max {
return fmt.Errorf("%q has %d connections [max=%d]", address, num, rat.max)
} else if num == 0 {
// if there is already at least connection, check to
// if there is already at least one connection, check to
// see if it was established before within the window,
// and error if so.
if last := rat.lastConnect[address]; time.Since(last) < rat.window {
+11
View File
@@ -70,4 +70,15 @@ func TestConnTracker(t *testing.T) {
}
require.Equal(t, 10, ct.Len())
})
t.Run("Window", func(t *testing.T) {
const window = 100 * time.Millisecond
ct := newConnTracker(10, window)
ip := randLocalIPv4()
require.NoError(t, ct.AddConn(ip))
ct.RemoveConn(ip)
require.Error(t, ct.AddConn(ip))
time.Sleep(window)
require.NoError(t, ct.AddConn(ip))
})
}
+3 -3
View File
@@ -151,14 +151,14 @@ func TestReactorErrorsOnReceivingTooManyPeers(t *testing.T) {
defer cancel()
r := setupSingle(ctx, t)
peer := p2p.NodeAddress{Protocol: p2p.MemoryProtocol, NodeID: randomNodeID(t)}
peer := p2p.NodeAddress{Protocol: p2p.MemoryProtocol, NodeID: randomNodeID()}
added, err := r.manager.Add(peer)
require.NoError(t, err)
require.True(t, added)
addresses := make([]p2pproto.PexAddress, 101)
for i := 0; i < len(addresses); i++ {
nodeAddress := p2p.NodeAddress{Protocol: p2p.MemoryProtocol, NodeID: randomNodeID(t)}
nodeAddress := p2p.NodeAddress{Protocol: p2p.MemoryProtocol, NodeID: randomNodeID()}
addresses[i] = p2pproto.PexAddress{
URL: nodeAddress.String(),
}
@@ -730,6 +730,6 @@ func newNodeID(t *testing.T, id string) types.NodeID {
return nodeID
}
func randomNodeID(t *testing.T) types.NodeID {
func randomNodeID() types.NodeID {
return types.NodeIDFromPubKey(ed25519.GenPrivKey().PubKey())
}
+1 -1
View File
@@ -29,6 +29,6 @@ func TestExample(t *testing.T) {
Attributes: []abci.EventAttribute{{Key: "name", Value: "John"}},
},
}
require.NoError(t, s.PublishWithEvents(ctx, pubstring("Tombstone"), events))
require.NoError(t, s.PublishWithEvents(pubstring("Tombstone"), events))
sub.mustReceive(ctx, pubstring("Tombstone"))
}
+6 -8
View File
@@ -287,16 +287,16 @@ func (s *Server) NumClientSubscriptions(clientID string) int {
}
// Publish publishes the given message. An error will be returned to the caller
// if the context is canceled.
func (s *Server) Publish(ctx context.Context, msg types.EventData) error {
return s.publish(ctx, msg, []abci.Event{})
// if the pubsub server has shut down.
func (s *Server) Publish(msg types.EventData) error {
return s.publish(msg, []abci.Event{})
}
// PublishWithEvents publishes the given message with the set of events. The set
// is matched with clients queries. If there is a match, the message is sent to
// the client.
func (s *Server) PublishWithEvents(ctx context.Context, msg types.EventData, events []abci.Event) error {
return s.publish(ctx, msg, events)
func (s *Server) PublishWithEvents(msg types.EventData, events []abci.Event) error {
return s.publish(msg, events)
}
// OnStop implements part of the Service interface. It is a no-op.
@@ -309,15 +309,13 @@ func (s *Server) Wait() { <-s.exited; s.BaseService.Wait() }
// OnStart implements Service.OnStart by starting the server.
func (s *Server) OnStart(ctx context.Context) error { s.run(ctx); return nil }
func (s *Server) publish(ctx context.Context, data types.EventData, events []abci.Event) error {
func (s *Server) publish(data types.EventData, events []abci.Event) error {
s.pubs.RLock()
defer s.pubs.RUnlock()
select {
case <-s.done:
return ErrServerStopped
case <-ctx.Done():
return ctx.Err()
case s.queue <- item{
Data: data,
Events: events,
+32 -21
View File
@@ -42,7 +42,7 @@ func TestSubscribeWithArgs(t *testing.T) {
require.Equal(t, 1, s.NumClients())
require.Equal(t, 1, s.NumClientSubscriptions(clientID))
require.NoError(t, s.Publish(ctx, pubstring("Ka-Zar")))
require.NoError(t, s.Publish(pubstring("Ka-Zar")))
sub.mustReceive(ctx, pubstring("Ka-Zar"))
})
t.Run("PositiveLimit", func(t *testing.T) {
@@ -51,7 +51,7 @@ func TestSubscribeWithArgs(t *testing.T) {
Query: query.All,
Limit: 10,
}))
require.NoError(t, s.Publish(ctx, pubstring("Aggamon")))
require.NoError(t, s.Publish(pubstring("Aggamon")))
sub.mustReceive(ctx, pubstring("Aggamon"))
})
}
@@ -72,7 +72,7 @@ func TestObserver(t *testing.T) {
}))
const input = pubstring("Lions and tigers and bears, oh my!")
require.NoError(t, s.Publish(ctx, input))
require.NoError(t, s.Publish(input))
<-done
require.Equal(t, got, input)
}
@@ -106,9 +106,9 @@ func TestPublishDoesNotBlock(t *testing.T) {
go func() {
defer close(published)
require.NoError(t, s.Publish(ctx, pubstring("Quicksilver")))
require.NoError(t, s.Publish(ctx, pubstring("Asylum")))
require.NoError(t, s.Publish(ctx, pubstring("Ivan")))
require.NoError(t, s.Publish(pubstring("Quicksilver")))
require.NoError(t, s.Publish(pubstring("Asylum")))
require.NoError(t, s.Publish(pubstring("Ivan")))
}()
select {
@@ -149,9 +149,9 @@ func TestSlowSubscriber(t *testing.T) {
Query: query.All,
}))
require.NoError(t, s.Publish(ctx, pubstring("Fat Cobra")))
require.NoError(t, s.Publish(ctx, pubstring("Viper")))
require.NoError(t, s.Publish(ctx, pubstring("Black Panther")))
require.NoError(t, s.Publish(pubstring("Fat Cobra")))
require.NoError(t, s.Publish(pubstring("Viper")))
require.NoError(t, s.Publish(pubstring("Black Panther")))
// We had capacity for one item, so we should get that item, but after that
// the subscription should have been terminated by the publisher.
@@ -176,7 +176,7 @@ func TestDifferentClients(t *testing.T) {
Attributes: []abci.EventAttribute{{Key: "type", Value: "NewBlock"}},
}}
require.NoError(t, s.PublishWithEvents(ctx, pubstring("Iceman"), events))
require.NoError(t, s.PublishWithEvents(pubstring("Iceman"), events))
sub1.mustReceive(ctx, pubstring("Iceman"))
sub2 := newTestSub(t).must(s.SubscribeWithArgs(ctx, pubsub.SubscribeArgs{
@@ -195,7 +195,7 @@ func TestDifferentClients(t *testing.T) {
},
}
require.NoError(t, s.PublishWithEvents(ctx, pubstring("Ultimo"), events))
require.NoError(t, s.PublishWithEvents(pubstring("Ultimo"), events))
sub1.mustReceive(ctx, pubstring("Ultimo"))
sub2.mustReceive(ctx, pubstring("Ultimo"))
@@ -210,7 +210,7 @@ func TestDifferentClients(t *testing.T) {
Attributes: []abci.EventAttribute{{Key: "type", Value: "NewRoundStep"}},
}}
require.NoError(t, s.PublishWithEvents(ctx, pubstring("Valeria Richards"), events))
require.NoError(t, s.PublishWithEvents(pubstring("Valeria Richards"), events))
sub3.mustTimeOut(ctx, 100*time.Millisecond)
}
@@ -259,7 +259,7 @@ func TestSubscribeDuplicateKeys(t *testing.T) {
},
}
require.NoError(t, s.PublishWithEvents(ctx, pubstring("Iceman"), events))
require.NoError(t, s.PublishWithEvents(pubstring("Iceman"), events))
if tc.expected != nil {
sub.mustReceive(ctx, tc.expected)
@@ -288,7 +288,7 @@ func TestClientSubscribesTwice(t *testing.T) {
Query: q,
}))
require.NoError(t, s.PublishWithEvents(ctx, pubstring("Goblin Queen"), events))
require.NoError(t, s.PublishWithEvents(pubstring("Goblin Queen"), events))
sub1.mustReceive(ctx, pubstring("Goblin Queen"))
// Subscribing a second time with the same client ID and query fails.
@@ -302,7 +302,7 @@ func TestClientSubscribesTwice(t *testing.T) {
}
// The attempt to re-subscribe does not disrupt the existing sub.
require.NoError(t, s.PublishWithEvents(ctx, pubstring("Spider-Man"), events))
require.NoError(t, s.PublishWithEvents(pubstring("Spider-Man"), events))
sub1.mustReceive(ctx, pubstring("Spider-Man"))
}
@@ -325,7 +325,7 @@ func TestUnsubscribe(t *testing.T) {
}))
// Publishing should still work.
require.NoError(t, s.Publish(ctx, pubstring("Nick Fury")))
require.NoError(t, s.Publish(pubstring("Nick Fury")))
// The unsubscribed subscriber should report as such.
sub.mustFail(ctx, pubsub.ErrUnsubscribed)
@@ -373,7 +373,7 @@ func TestResubscribe(t *testing.T) {
sub := newTestSub(t).must(s.SubscribeWithArgs(ctx, args))
require.NoError(t, s.Publish(ctx, pubstring("Cable")))
require.NoError(t, s.Publish(pubstring("Cable")))
sub.mustReceive(ctx, pubstring("Cable"))
}
@@ -394,7 +394,7 @@ func TestUnsubscribeAll(t *testing.T) {
}))
require.NoError(t, s.UnsubscribeAll(ctx, clientID))
require.NoError(t, s.Publish(ctx, pubstring("Nick Fury")))
require.NoError(t, s.Publish(pubstring("Nick Fury")))
sub1.mustFail(ctx, pubsub.ErrUnsubscribed)
sub2.mustFail(ctx, pubsub.ErrUnsubscribed)
@@ -410,13 +410,24 @@ func TestBufferCapacity(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
require.NoError(t, s.Publish(ctx, pubstring("Nighthawk")))
require.NoError(t, s.Publish(ctx, pubstring("Sage")))
require.NoError(t, s.Publish(pubstring("Nighthawk")))
require.NoError(t, s.Publish(pubstring("Sage")))
ctx, cancel = context.WithTimeout(ctx, 100*time.Millisecond)
defer cancel()
require.ErrorIs(t, s.Publish(ctx, pubstring("Ironclad")), context.DeadlineExceeded)
sig := make(chan struct{})
go func() { defer close(sig); _ = s.Publish(pubstring("Ironclad")) }()
select {
case <-sig:
t.Fatal("should not fire")
case <-ctx.Done():
return
}
}
func newTestServer(ctx context.Context, t testing.TB, logger log.Logger) *pubsub.Server {
+46 -19
View File
@@ -7,6 +7,7 @@ import (
abciclient "github.com/tendermint/tendermint/abci/client"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/encoding"
"github.com/tendermint/tendermint/crypto/merkle"
"github.com/tendermint/tendermint/internal/eventbus"
@@ -291,34 +292,38 @@ func (blockExec *BlockExecutor) ApplyBlock(
// Events are fired after everything else.
// NOTE: if we crash between Commit and Save, events wont be fired during replay
fireEvents(ctx, blockExec.logger, blockExec.eventBus, block, blockID, finalizeBlockResponse, validatorUpdates)
fireEvents(blockExec.logger, blockExec.eventBus, block, blockID, finalizeBlockResponse, validatorUpdates)
return state, nil
}
func (blockExec *BlockExecutor) ExtendVote(ctx context.Context, vote *types.Vote) (types.VoteExtension, error) {
func (blockExec *BlockExecutor) ExtendVote(ctx context.Context, vote *types.Vote) ([]byte, error) {
req := abci.RequestExtendVote{
Vote: vote.ToProto(),
Hash: vote.BlockID.Hash,
Height: vote.Height,
}
resp, err := blockExec.appClient.ExtendVote(ctx, req)
if err != nil {
return types.VoteExtension{}, err
panic(fmt.Errorf("ExtendVote call failed: %w", err))
}
return types.VoteExtensionFromProto(resp.VoteExtension), nil
return resp.VoteExtension, nil
}
func (blockExec *BlockExecutor) VerifyVoteExtension(ctx context.Context, vote *types.Vote) error {
req := abci.RequestVerifyVoteExtension{
Vote: vote.ToProto(),
Hash: vote.BlockID.Hash,
ValidatorAddress: vote.ValidatorAddress,
Height: vote.Height,
VoteExtension: vote.Extension,
}
resp, err := blockExec.appClient.VerifyVoteExtension(ctx, req)
if err != nil {
return err
panic(fmt.Errorf("VerifyVoteExtension call failed: %w", err))
}
if resp.IsErr() {
if !resp.IsOK() {
return types.ErrVoteInvalidExtension
}
@@ -417,16 +422,39 @@ func buildLastCommitInfo(block *types.Block, store Store, initialHeight int64) a
}
}
// extendedCommitInfo expects a CommitInfo struct along with all of the
// original votes relating to that commit, including their vote extensions. The
// order of votes does not matter.
func extendedCommitInfo(c abci.CommitInfo, votes []*types.Vote) abci.ExtendedCommitInfo {
if len(c.Votes) != len(votes) {
panic(fmt.Sprintf("extendedCommitInfo: number of votes from commit differ from the number of votes supplied (%d != %d)", len(c.Votes), len(votes)))
}
votesByVal := make(map[string]*types.Vote)
for _, vote := range votes {
if vote != nil {
valAddr := vote.ValidatorAddress.String()
if _, ok := votesByVal[valAddr]; ok {
panic(fmt.Sprintf("extendedCommitInfo: found duplicate vote for validator with address %s", valAddr))
}
votesByVal[valAddr] = vote
}
}
vs := make([]abci.ExtendedVoteInfo, len(c.Votes))
for i := range vs {
var ext []byte
// votes[i] will be nil if c.Votes[i].SignedLastBlock is false
if c.Votes[i].SignedLastBlock {
valAddr := crypto.Address(c.Votes[i].Validator.Address).String()
vote, ok := votesByVal[valAddr]
if !ok || vote == nil {
panic(fmt.Sprintf("extendedCommitInfo: validator with address %s signed last block, but could not find vote for it", valAddr))
}
ext = vote.Extension
}
vs[i] = abci.ExtendedVoteInfo{
Validator: c.Votes[i].Validator,
SignedLastBlock: c.Votes[i].SignedLastBlock,
/*
TODO: Include vote extensions information when implementing vote extensions.
VoteExtension: []byte{},
*/
VoteExtension: ext,
}
}
return abci.ExtendedCommitInfo{
@@ -530,7 +558,6 @@ func (state State) Update(
// Fire TxEvent for every tx.
// NOTE: if Tendermint crashes before commit, some or all of these events may be published again.
func fireEvents(
ctx context.Context,
logger log.Logger,
eventBus types.BlockEventPublisher,
block *types.Block,
@@ -538,7 +565,7 @@ func fireEvents(
finalizeBlockResponse *abci.ResponseFinalizeBlock,
validatorUpdates []*types.Validator,
) {
if err := eventBus.PublishEventNewBlock(ctx, types.EventDataNewBlock{
if err := eventBus.PublishEventNewBlock(types.EventDataNewBlock{
Block: block,
BlockID: blockID,
ResultFinalizeBlock: *finalizeBlockResponse,
@@ -546,7 +573,7 @@ func fireEvents(
logger.Error("failed publishing new block", "err", err)
}
if err := eventBus.PublishEventNewBlockHeader(ctx, types.EventDataNewBlockHeader{
if err := eventBus.PublishEventNewBlockHeader(types.EventDataNewBlockHeader{
Header: block.Header,
NumTxs: int64(len(block.Txs)),
ResultFinalizeBlock: *finalizeBlockResponse,
@@ -556,7 +583,7 @@ func fireEvents(
if len(block.Evidence) != 0 {
for _, ev := range block.Evidence {
if err := eventBus.PublishEventNewEvidence(ctx, types.EventDataNewEvidence{
if err := eventBus.PublishEventNewEvidence(types.EventDataNewEvidence{
Evidence: ev,
Height: block.Height,
}); err != nil {
@@ -572,7 +599,7 @@ func fireEvents(
}
for i, tx := range block.Data.Txs {
if err := eventBus.PublishEventTx(ctx, types.EventDataTx{
if err := eventBus.PublishEventTx(types.EventDataTx{
TxResult: abci.TxResult{
Height: block.Height,
Index: uint32(i),
@@ -585,7 +612,7 @@ func fireEvents(
}
if len(finalizeBlockResponse.ValidatorUpdates) > 0 {
if err := eventBus.PublishEventValidatorSetUpdates(ctx,
if err := eventBus.PublishEventValidatorSetUpdates(
types.EventDataValidatorSetUpdates{ValidatorUpdates: validatorUpdates}); err != nil {
logger.Error("failed publishing event", "err", err)
}
@@ -644,7 +671,7 @@ func ExecCommitBlock(
}
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
fireEvents(ctx, be.logger, be.eventBus, block, blockID, finalizeBlockResponse, validatorUpdates)
fireEvents(be.logger, be.eventBus, block, blockID, finalizeBlockResponse, validatorUpdates)
}
// Commit block, get hash back
+14 -14
View File
@@ -654,8 +654,8 @@ func TestEmptyPrepareProposal(t *testing.T) {
sm.NopMetrics(),
)
pa, _ := state.Validators.GetByIndex(0)
commit := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
_, err = blockExec.CreateProposalBlock(ctx, height, state, commit, pa, nil)
commit, votes := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
_, err = blockExec.CreateProposalBlock(ctx, height, state, commit, pa, votes)
require.NoError(t, err)
}
@@ -709,8 +709,8 @@ func TestPrepareProposalErrorOnNonExistingRemoved(t *testing.T) {
sm.NopMetrics(),
)
pa, _ := state.Validators.GetByIndex(0)
commit := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, nil)
commit, votes := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, votes)
require.Nil(t, block)
require.ErrorContains(t, err, "new transaction incorrectly marked as removed")
@@ -765,8 +765,8 @@ func TestPrepareProposalRemoveTxs(t *testing.T) {
sm.NopMetrics(),
)
pa, _ := state.Validators.GetByIndex(0)
commit := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, nil)
commit, votes := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, votes)
require.NoError(t, err)
require.Len(t, block.Data.Txs.ToSliceOfBytes(), len(trs)-2)
@@ -824,8 +824,8 @@ func TestPrepareProposalAddedTxsIncluded(t *testing.T) {
sm.NopMetrics(),
)
pa, _ := state.Validators.GetByIndex(0)
commit := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, nil)
commit, votes := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, votes)
require.NoError(t, err)
require.Equal(t, txs[0], block.Data.Txs[0])
@@ -880,8 +880,8 @@ func TestPrepareProposalReorderTxs(t *testing.T) {
sm.NopMetrics(),
)
pa, _ := state.Validators.GetByIndex(0)
commit := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, nil)
commit, votes := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, votes)
require.NoError(t, err)
for i, tx := range block.Data.Txs {
require.Equal(t, types.Tx(trs[i].Tx), tx)
@@ -940,9 +940,9 @@ func TestPrepareProposalErrorOnTooManyTxs(t *testing.T) {
sm.NopMetrics(),
)
pa, _ := state.Validators.GetByIndex(0)
commit := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
commit, votes := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, nil)
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, votes)
require.Nil(t, block)
require.ErrorContains(t, err, "transaction data size exceeds maximum")
@@ -992,9 +992,9 @@ func TestPrepareProposalErrorOnPrepareProposalError(t *testing.T) {
sm.NopMetrics(),
)
pa, _ := state.Validators.GetByIndex(0)
commit := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
commit, votes := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, nil)
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, votes)
require.Nil(t, block)
require.ErrorContains(t, err, "an injected error")
+7 -5
View File
@@ -46,7 +46,7 @@ func makeAndCommitGoodBlock(
state, blockID := makeAndApplyGoodBlock(ctx, t, state, height, lastCommit, proposerAddr, blockExec, evidence)
// Simulate a lastCommit for this block from all validators for the next height
commit := makeValidCommit(ctx, t, height, blockID, state.Validators, privVals)
commit, _ := makeValidCommit(ctx, t, height, blockID, state.Validators, privVals)
return state, blockID, commit
}
@@ -82,17 +82,19 @@ func makeValidCommit(
blockID types.BlockID,
vals *types.ValidatorSet,
privVals map[string]types.PrivValidator,
) *types.Commit {
) (*types.Commit, []*types.Vote) {
t.Helper()
sigs := make([]types.CommitSig, 0)
sigs := make([]types.CommitSig, vals.Size())
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.Address.String()], chainID, int32(i), height, 0, 2, blockID, time.Now())
require.NoError(t, err)
sigs = append(sigs, vote.CommitSig())
sigs[i] = vote.CommitSig()
votes[i] = vote
}
return types.NewCommit(height, 0, blockID, sigs)
return types.NewCommit(height, 0, blockID, sigs), votes
}
func makeState(t *testing.T, nVals, height int) (sm.State, dbm.DB, map[string]types.PrivValidator) {
@@ -54,8 +54,7 @@ func TestIndexerServiceIndexesBlocks(t *testing.T) {
assert.False(t, indexer.IndexingEnabled([]indexer.EventSink{}))
// event sink setup
pool, err := setupDB(t)
assert.NoError(t, err)
pool := setupDB(t)
store := dbm.NewMemDB()
eventSinks := []indexer.EventSink{kv.NewEventSink(store), pSink}
@@ -71,7 +70,7 @@ func TestIndexerServiceIndexesBlocks(t *testing.T) {
t.Cleanup(service.Wait)
// publish block with txs
err = eventBus.PublishEventNewBlockHeader(ctx, types.EventDataNewBlockHeader{
err = eventBus.PublishEventNewBlockHeader(types.EventDataNewBlockHeader{
Header: types.Header{Height: 1},
NumTxs: int64(2),
})
@@ -82,7 +81,7 @@ func TestIndexerServiceIndexesBlocks(t *testing.T) {
Tx: types.Tx("foo"),
Result: abci.ExecTxResult{Code: 0},
}
err = eventBus.PublishEventTx(ctx, types.EventDataTx{TxResult: *txResult1})
err = eventBus.PublishEventTx(types.EventDataTx{TxResult: *txResult1})
require.NoError(t, err)
txResult2 := &abci.TxResult{
Height: 1,
@@ -90,7 +89,7 @@ func TestIndexerServiceIndexesBlocks(t *testing.T) {
Tx: types.Tx("bar"),
Result: abci.ExecTxResult{Code: 0},
}
err = eventBus.PublishEventTx(ctx, types.EventDataTx{TxResult: *txResult2})
err = eventBus.PublishEventTx(types.EventDataTx{TxResult: *txResult2})
require.NoError(t, err)
time.Sleep(100 * time.Millisecond)
@@ -133,7 +132,7 @@ func resetDB(t *testing.T) {
assert.NoError(t, err)
}
func setupDB(t *testing.T) (*dockertest.Pool, error) {
func setupDB(t *testing.T) *dockertest.Pool {
t.Helper()
pool, err := dockertest.NewPool(os.Getenv("DOCKER_URL"))
assert.NoError(t, err)
@@ -187,7 +186,7 @@ func setupDB(t *testing.T) (*dockertest.Pool, error) {
err = migrator.Apply(psqldb, sm)
assert.NoError(t, err)
return pool, nil
return pool
}
func teardown(t *testing.T, pool *dockertest.Pool) error {
+2 -2
View File
@@ -333,7 +333,7 @@ func (r *Reactor) OnStop() {
// of historical blocks before participating in consensus
func (r *Reactor) Sync(ctx context.Context) (sm.State, error) {
if r.eventBus != nil {
if err := r.eventBus.PublishEventStateSyncStatus(ctx, types.EventDataStateSyncStatus{
if err := r.eventBus.PublishEventStateSyncStatus(types.EventDataStateSyncStatus{
Complete: false,
Height: r.initialHeight,
}); err != nil {
@@ -387,7 +387,7 @@ func (r *Reactor) Sync(ctx context.Context) (sm.State, error) {
}
if r.eventBus != nil {
if err := r.eventBus.PublishEventStateSyncStatus(ctx, types.EventDataStateSyncStatus{
if err := r.eventBus.PublishEventStateSyncStatus(types.EventDataStateSyncStatus{
Complete: true,
Height: state.LastBlockHeight,
}); err != nil {
+2 -2
View File
@@ -379,7 +379,7 @@ func (s *stateProviderP2P) consensusParams(ctx context.Context, height int64) (t
}
wg.Add(1)
go func(p *BlockProvider, peer types.NodeID) {
go func(peer types.NodeID) {
defer wg.Done()
timer := time.NewTimer(0)
@@ -424,7 +424,7 @@ func (s *stateProviderP2P) consensusParams(ctx context.Context, height int64) (t
}
}
}(p, peer)
}(peer)
}
sig := make(chan struct{})
go func() { wg.Wait(); close(sig) }()
+4 -5
View File
@@ -17,7 +17,6 @@ import (
"github.com/tendermint/tendermint/crypto"
sm "github.com/tendermint/tendermint/internal/state"
"github.com/tendermint/tendermint/internal/state/test/factory"
"github.com/tendermint/tendermint/libs/log"
tmrand "github.com/tendermint/tendermint/libs/rand"
tmtime "github.com/tendermint/tendermint/libs/time"
"github.com/tendermint/tendermint/types"
@@ -46,7 +45,7 @@ func makeTestCommit(height int64, timestamp time.Time) *types.Commit {
commitSigs)
}
func makeStateAndBlockStore(dir string, logger log.Logger) (sm.State, *BlockStore, cleanupFunc, error) {
func makeStateAndBlockStore(dir string) (sm.State, *BlockStore, cleanupFunc, error) {
cfg, err := config.ResetTestRoot(dir, "blockchain_reactor_test")
if err != nil {
return sm.State{}, nil, nil, err
@@ -81,7 +80,7 @@ func TestMain(m *testing.M) {
}
var cleanup cleanupFunc
state, _, cleanup, err = makeStateAndBlockStore(dir, log.NewNopLogger())
state, _, cleanup, err = makeStateAndBlockStore(dir)
if err != nil {
stdlog.Fatal(err)
}
@@ -103,7 +102,7 @@ func TestMain(m *testing.M) {
// TODO: This test should be simplified ...
func TestBlockStoreSaveLoadBlock(t *testing.T) {
state, bs, cleanup, err := makeStateAndBlockStore(t.TempDir(), log.NewNopLogger())
state, bs, cleanup, err := makeStateAndBlockStore(t.TempDir())
defer cleanup()
require.NoError(t, err)
require.Equal(t, bs.Base(), int64(0), "initially the base should be zero")
@@ -492,7 +491,7 @@ func TestLoadBlockMeta(t *testing.T) {
}
func TestBlockFetchAtHeight(t *testing.T) {
state, bs, cleanup, err := makeStateAndBlockStore(t.TempDir(), log.NewNopLogger())
state, bs, cleanup, err := makeStateAndBlockStore(t.TempDir())
defer cleanup()
require.NoError(t, err)
require.Equal(t, bs.Height(), int64(0), "initially the height should be zero")
+1
View File
@@ -31,6 +31,7 @@ func MakeCommit(ctx context.Context, blockID types.BlockID, height int64, round
return nil, err
}
vote.Signature = v.Signature
vote.ExtensionSignature = v.ExtensionSignature
if _, err := voteSet.AddVote(vote); err != nil {
return nil, err
}
+8 -12
View File
@@ -13,25 +13,25 @@ import (
tmprotobits "github.com/tendermint/tendermint/proto/tendermint/libs/bits"
)
func randBitArray(bits int) (*BitArray, []byte) {
func randBitArray(bits int) *BitArray {
src := tmrand.Bytes((bits + 7) / 8)
bA := NewBitArray(bits)
for i := 0; i < len(src); i++ {
for j := 0; j < 8; j++ {
if i*8+j >= bits {
return bA, src
return bA
}
setBit := src[i]&(1<<uint(j)) > 0
bA.SetIndex(i*8+j, setBit)
}
}
return bA, src
return bA
}
func TestAnd(t *testing.T) {
bA1, _ := randBitArray(51)
bA2, _ := randBitArray(31)
bA1 := randBitArray(51)
bA2 := randBitArray(31)
bA3 := bA1.And(bA2)
var bNil *BitArray
@@ -54,9 +54,8 @@ func TestAnd(t *testing.T) {
}
func TestOr(t *testing.T) {
bA1, _ := randBitArray(51)
bA2, _ := randBitArray(31)
bA1 := randBitArray(51)
bA2 := randBitArray(31)
bA3 := bA1.Or(bA2)
bNil := (*BitArray)(nil)
@@ -191,10 +190,7 @@ func TestEmptyFull(t *testing.T) {
}
func TestUpdateNeverPanics(t *testing.T) {
newRandBitArray := func(n int) *BitArray {
ba, _ := randBitArray(n)
return ba
}
newRandBitArray := func(n int) *BitArray { return randBitArray(n) }
pairs := []struct {
a, b *BitArray
}{
+6 -7
View File
@@ -2,7 +2,6 @@
package events
import (
"context"
"sync"
)
@@ -20,7 +19,7 @@ type Eventable interface {
//
// FireEvent fires an event with the given name and data.
type Fireable interface {
FireEvent(ctx context.Context, eventValue string, data EventData)
FireEvent(eventValue string, data EventData)
}
// EventSwitch is the interface for synchronous pubsub, where listeners
@@ -62,7 +61,7 @@ func (evsw *eventSwitch) AddListenerForEvent(listenerID, eventValue string, cb E
return nil
}
func (evsw *eventSwitch) FireEvent(ctx context.Context, event string, data EventData) {
func (evsw *eventSwitch) FireEvent(event string, data EventData) {
// Get the eventCell
evsw.mtx.RLock()
eventCell := evsw.eventCells[event]
@@ -73,12 +72,12 @@ func (evsw *eventSwitch) FireEvent(ctx context.Context, event string, data Event
}
// Fire event for all listeners in eventCell
eventCell.fireEvent(ctx, data)
eventCell.fireEvent(data)
}
//-----------------------------------------------------------------------------
type EventCallback func(ctx context.Context, data EventData) error
type EventCallback func(data EventData) error
// eventCell handles keeping track of listener callbacks for a given event.
type eventCell struct {
@@ -98,7 +97,7 @@ func (cell *eventCell) addListener(listenerID string, cb EventCallback) {
cell.listeners[listenerID] = cb
}
func (cell *eventCell) fireEvent(ctx context.Context, data EventData) {
func (cell *eventCell) fireEvent(data EventData) {
cell.mtx.RLock()
eventCallbacks := make([]EventCallback, 0, len(cell.listeners))
for _, cb := range cell.listeners {
@@ -107,7 +106,7 @@ func (cell *eventCell) fireEvent(ctx context.Context, data EventData) {
cell.mtx.RUnlock()
for _, cb := range eventCallbacks {
if err := cb(ctx, data); err != nil {
if err := cb(data); err != nil {
// should we log or abort here?
continue
}
+24 -19
View File
@@ -7,6 +7,7 @@ import (
"testing"
"time"
"github.com/fortytw2/leaktest"
"github.com/stretchr/testify/require"
)
@@ -20,7 +21,7 @@ func TestAddListenerForEventFireOnce(t *testing.T) {
messages := make(chan EventData)
require.NoError(t, evsw.AddListenerForEvent("listener", "event",
func(ctx context.Context, data EventData) error {
func(data EventData) error {
select {
case messages <- data:
return nil
@@ -28,7 +29,7 @@ func TestAddListenerForEventFireOnce(t *testing.T) {
return ctx.Err()
}
}))
go evsw.FireEvent(ctx, "event", "data")
go evsw.FireEvent("event", "data")
received := <-messages
if received != "data" {
t.Errorf("message received does not match: %v", received)
@@ -48,7 +49,7 @@ func TestAddListenerForEventFireMany(t *testing.T) {
numbers := make(chan uint64, 4)
// subscribe one listener for one event
require.NoError(t, evsw.AddListenerForEvent("listener", "event",
func(ctx context.Context, data EventData) error {
func(data EventData) error {
select {
case numbers <- data.(uint64):
return nil
@@ -75,6 +76,8 @@ func TestAddListenerForDifferentEvents(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
t.Cleanup(leaktest.Check(t))
evsw := NewEventSwitch()
doneSum := make(chan uint64)
@@ -84,7 +87,7 @@ func TestAddListenerForDifferentEvents(t *testing.T) {
numbers := make(chan uint64, 4)
// subscribe one listener to three events
require.NoError(t, evsw.AddListenerForEvent("listener", "event1",
func(ctx context.Context, data EventData) error {
func(data EventData) error {
select {
case numbers <- data.(uint64):
return nil
@@ -93,7 +96,7 @@ func TestAddListenerForDifferentEvents(t *testing.T) {
}
}))
require.NoError(t, evsw.AddListenerForEvent("listener", "event2",
func(ctx context.Context, data EventData) error {
func(data EventData) error {
select {
case numbers <- data.(uint64):
return nil
@@ -102,7 +105,7 @@ func TestAddListenerForDifferentEvents(t *testing.T) {
}
}))
require.NoError(t, evsw.AddListenerForEvent("listener", "event3",
func(ctx context.Context, data EventData) error {
func(data EventData) error {
select {
case numbers <- data.(uint64):
return nil
@@ -135,6 +138,8 @@ func TestAddDifferentListenerForDifferentEvents(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
t.Cleanup(leaktest.Check(t))
evsw := NewEventSwitch()
doneSum1 := make(chan uint64)
@@ -146,7 +151,7 @@ func TestAddDifferentListenerForDifferentEvents(t *testing.T) {
numbers2 := make(chan uint64, 4)
// subscribe two listener to three events
require.NoError(t, evsw.AddListenerForEvent("listener1", "event1",
func(ctx context.Context, data EventData) error {
func(data EventData) error {
select {
case numbers1 <- data.(uint64):
return nil
@@ -155,7 +160,7 @@ func TestAddDifferentListenerForDifferentEvents(t *testing.T) {
}
}))
require.NoError(t, evsw.AddListenerForEvent("listener1", "event2",
func(ctx context.Context, data EventData) error {
func(data EventData) error {
select {
case numbers1 <- data.(uint64):
return nil
@@ -164,7 +169,7 @@ func TestAddDifferentListenerForDifferentEvents(t *testing.T) {
}
}))
require.NoError(t, evsw.AddListenerForEvent("listener1", "event3",
func(ctx context.Context, data EventData) error {
func(data EventData) error {
select {
case numbers1 <- data.(uint64):
return nil
@@ -173,7 +178,7 @@ func TestAddDifferentListenerForDifferentEvents(t *testing.T) {
}
}))
require.NoError(t, evsw.AddListenerForEvent("listener2", "event2",
func(ctx context.Context, data EventData) error {
func(data EventData) error {
select {
case numbers2 <- data.(uint64):
return nil
@@ -182,7 +187,7 @@ func TestAddDifferentListenerForDifferentEvents(t *testing.T) {
}
}))
require.NoError(t, evsw.AddListenerForEvent("listener2", "event3",
func(ctx context.Context, data EventData) error {
func(data EventData) error {
select {
case numbers2 <- data.(uint64):
return nil
@@ -238,7 +243,7 @@ func TestManageListenersAsync(t *testing.T) {
numbers2 := make(chan uint64, 4)
// subscribe two listener to three events
require.NoError(t, evsw.AddListenerForEvent("listener1", "event1",
func(ctx context.Context, data EventData) error {
func(data EventData) error {
select {
case numbers1 <- data.(uint64):
return nil
@@ -247,7 +252,7 @@ func TestManageListenersAsync(t *testing.T) {
}
}))
require.NoError(t, evsw.AddListenerForEvent("listener1", "event2",
func(ctx context.Context, data EventData) error {
func(data EventData) error {
select {
case numbers1 <- data.(uint64):
return nil
@@ -256,7 +261,7 @@ func TestManageListenersAsync(t *testing.T) {
}
}))
require.NoError(t, evsw.AddListenerForEvent("listener1", "event3",
func(ctx context.Context, data EventData) error {
func(data EventData) error {
select {
case numbers1 <- data.(uint64):
return nil
@@ -265,7 +270,7 @@ func TestManageListenersAsync(t *testing.T) {
}
}))
require.NoError(t, evsw.AddListenerForEvent("listener2", "event1",
func(ctx context.Context, data EventData) error {
func(data EventData) error {
select {
case numbers2 <- data.(uint64):
return nil
@@ -274,7 +279,7 @@ func TestManageListenersAsync(t *testing.T) {
}
}))
require.NoError(t, evsw.AddListenerForEvent("listener2", "event2",
func(ctx context.Context, data EventData) error {
func(data EventData) error {
select {
case numbers2 <- data.(uint64):
return nil
@@ -283,7 +288,7 @@ func TestManageListenersAsync(t *testing.T) {
}
}))
require.NoError(t, evsw.AddListenerForEvent("listener2", "event3",
func(ctx context.Context, data EventData) error {
func(data EventData) error {
select {
case numbers2 <- data.(uint64):
return nil
@@ -303,7 +308,7 @@ func TestManageListenersAsync(t *testing.T) {
eventNumber := r1.Intn(3) + 1
go evsw.AddListenerForEvent(fmt.Sprintf("listener%v", listenerNumber), //nolint:errcheck // ignore for tests
fmt.Sprintf("event%v", eventNumber),
func(context.Context, EventData) error { return nil })
func(EventData) error { return nil })
}
}
addListenersStress()
@@ -358,7 +363,7 @@ func fireEvents(ctx context.Context, evsw Fireable, event string, doneChan chan
break
}
evsw.FireEvent(ctx, event, i)
evsw.FireEvent(event, i)
sentSum += i
}
+3 -3
View File
@@ -69,7 +69,7 @@ func BenchmarkSequence(b *testing.B) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
headers, vals, _ := genLightBlocksWithKeys(b, chainID, 1000, 100, 1, bTime)
headers, vals, _ := genLightBlocksWithKeys(b, 1000, 100, 1, bTime)
benchmarkFullNode := newProviderBenchmarkImpl(headers, vals)
genesisBlock, _ := benchmarkFullNode.LightBlock(ctx, 1)
@@ -106,7 +106,7 @@ func BenchmarkBisection(b *testing.B) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
headers, vals, _ := genLightBlocksWithKeys(b, chainID, 1000, 100, 1, bTime)
headers, vals, _ := genLightBlocksWithKeys(b, 1000, 100, 1, bTime)
benchmarkFullNode := newProviderBenchmarkImpl(headers, vals)
genesisBlock, _ := benchmarkFullNode.LightBlock(ctx, 1)
@@ -142,7 +142,7 @@ func BenchmarkBackwards(b *testing.B) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
headers, vals, _ := genLightBlocksWithKeys(b, chainID, 1000, 100, 1, bTime)
headers, vals, _ := genLightBlocksWithKeys(b, 1000, 100, 1, bTime)
benchmarkFullNode := newProviderBenchmarkImpl(headers, vals)
trustedBlock, _ := benchmarkFullNode.LightBlock(ctx, 0)
+2 -2
View File
@@ -387,7 +387,7 @@ func TestClient(t *testing.T) {
// the appropriate range
numBlocks := int64(300)
mockHeaders, mockVals, _ := genLightBlocksWithKeys(t, chainID, numBlocks, 101, 2, bTime)
mockHeaders, mockVals, _ := genLightBlocksWithKeys(t, numBlocks, 101, 2, bTime)
lastBlock := &types.LightBlock{SignedHeader: mockHeaders[numBlocks], ValidatorSet: mockVals[numBlocks]}
mockNode := &provider_mocks.Provider{}
@@ -773,7 +773,7 @@ func TestClient(t *testing.T) {
logger := log.NewNopLogger()
{
headers, vals, _ := genLightBlocksWithKeys(t, chainID, 9, 3, 0, bTime)
headers, vals, _ := genLightBlocksWithKeys(t, 9, 3, 0, bTime)
delete(headers, 1)
delete(headers, 2)
delete(vals, 1)
+10 -10
View File
@@ -35,7 +35,7 @@ func TestLightClientAttackEvidence_Lunatic(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
witnessHeaders, witnessValidators, chainKeys := genLightBlocksWithKeys(t, chainID, latestHeight, valSize, 2, bTime)
witnessHeaders, witnessValidators, chainKeys := genLightBlocksWithKeys(t, latestHeight, valSize, 2, bTime)
forgedKeys := chainKeys[divergenceHeight-1].ChangeKeys(3) // we change 3 out of the 5 validators (still 2/5 remain)
forgedVals := forgedKeys.ToValidators(2, 0)
@@ -153,7 +153,7 @@ func TestLightClientAttackEvidence_Equivocation(t *testing.T) {
// validators don't change in this network (however we still use a map just for convenience)
primaryValidators = make(map[int64]*types.ValidatorSet, testCase.latestHeight)
)
witnessHeaders, witnessValidators, chainKeys := genLightBlocksWithKeys(t, chainID,
witnessHeaders, witnessValidators, chainKeys := genLightBlocksWithKeys(t,
testCase.latestHeight+1, valSize, 2, bTime)
for height := int64(1); height <= testCase.latestHeight; height++ {
if height < testCase.divergenceHeight {
@@ -250,7 +250,7 @@ func TestLightClientAttackEvidence_ForwardLunatic(t *testing.T) {
defer cancel()
logger := log.NewNopLogger()
witnessHeaders, witnessValidators, chainKeys := genLightBlocksWithKeys(t, chainID, latestHeight, valSize, 2, bTime)
witnessHeaders, witnessValidators, chainKeys := genLightBlocksWithKeys(t, latestHeight, valSize, 2, bTime)
for _, unusedHeader := range []int64{3, 5, 6, 8} {
delete(witnessHeaders, unusedHeader)
}
@@ -401,13 +401,13 @@ func TestClientDivergentTraces1(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
headers, vals, _ := genLightBlocksWithKeys(t, chainID, 1, 5, 2, bTime)
headers, vals, _ := genLightBlocksWithKeys(t, 1, 5, 2, bTime)
mockPrimary := mockNodeFromHeadersAndVals(headers, vals)
mockPrimary.On("ID").Return("mockPrimary")
firstBlock, err := mockPrimary.LightBlock(ctx, 1)
require.NoError(t, err)
headers, vals, _ = genLightBlocksWithKeys(t, chainID, 1, 5, 2, bTime)
headers, vals, _ = genLightBlocksWithKeys(t, 1, 5, 2, bTime)
mockWitness := mockNodeFromHeadersAndVals(headers, vals)
mockWitness.On("ID").Return("mockWitness")
@@ -439,7 +439,7 @@ func TestClientDivergentTraces2(t *testing.T) {
defer cancel()
logger := log.NewNopLogger()
headers, vals, _ := genLightBlocksWithKeys(t, chainID, 2, 5, 2, bTime)
headers, vals, _ := genLightBlocksWithKeys(t, 2, 5, 2, bTime)
mockPrimaryNode := mockNodeFromHeadersAndVals(headers, vals)
mockPrimaryNode.On("ID").Return("mockPrimaryNode")
@@ -485,7 +485,7 @@ func TestClientDivergentTraces3(t *testing.T) {
logger := log.NewNopLogger()
//
primaryHeaders, primaryVals, _ := genLightBlocksWithKeys(t, chainID, 2, 5, 2, bTime)
primaryHeaders, primaryVals, _ := genLightBlocksWithKeys(t, 2, 5, 2, bTime)
mockPrimary := mockNodeFromHeadersAndVals(primaryHeaders, primaryVals)
mockPrimary.On("ID").Return("mockPrimary")
@@ -495,7 +495,7 @@ func TestClientDivergentTraces3(t *testing.T) {
firstBlock, err := mockPrimary.LightBlock(ctx, 1)
require.NoError(t, err)
mockHeaders, mockVals, _ := genLightBlocksWithKeys(t, chainID, 2, 5, 2, bTime)
mockHeaders, mockVals, _ := genLightBlocksWithKeys(t, 2, 5, 2, bTime)
mockHeaders[1] = primaryHeaders[1]
mockVals[1] = primaryVals[1]
mockWitness := mockNodeFromHeadersAndVals(mockHeaders, mockVals)
@@ -530,7 +530,7 @@ func TestClientDivergentTraces4(t *testing.T) {
logger := log.NewNopLogger()
//
primaryHeaders, primaryVals, _ := genLightBlocksWithKeys(t, chainID, 2, 5, 2, bTime)
primaryHeaders, primaryVals, _ := genLightBlocksWithKeys(t, 2, 5, 2, bTime)
mockPrimary := mockNodeFromHeadersAndVals(primaryHeaders, primaryVals)
mockPrimary.On("ID").Return("mockPrimary")
@@ -540,7 +540,7 @@ func TestClientDivergentTraces4(t *testing.T) {
firstBlock, err := mockPrimary.LightBlock(ctx, 1)
require.NoError(t, err)
witnessHeaders, witnessVals, _ := genLightBlocksWithKeys(t, chainID, 2, 5, 2, bTime)
witnessHeaders, witnessVals, _ := genLightBlocksWithKeys(t, 2, 5, 2, bTime)
primaryHeaders[2] = witnessHeaders[2]
primaryVals[2] = witnessVals[2]
mockWitness := mockNodeFromHeadersAndVals(primaryHeaders, primaryVals)
-1
View File
@@ -160,7 +160,6 @@ func (pkz privKeys) ChangeKeys(delta int) privKeys {
// NOTE: Expected to have a large validator set size ~ 100 validators.
func genLightBlocksWithKeys(
t testing.TB,
chainID string,
numBlocks int64,
valSize int,
valVariation float32,
+40 -19
View File
@@ -29,6 +29,7 @@ import (
rpccore "github.com/tendermint/tendermint/internal/rpc/core"
sm "github.com/tendermint/tendermint/internal/state"
"github.com/tendermint/tendermint/internal/state/indexer"
"github.com/tendermint/tendermint/internal/state/indexer/sink"
"github.com/tendermint/tendermint/internal/statesync"
"github.com/tendermint/tendermint/internal/store"
"github.com/tendermint/tendermint/libs/log"
@@ -168,15 +169,19 @@ func makeNode(
Metrics: nodeMetrics.eventlog,
})
if err != nil {
return nil, fmt.Errorf("initializing event log: %w", err)
return nil, combineCloseError(fmt.Errorf("initializing event log: %w", err), makeCloser(closers))
}
}
indexerService, eventSinks, err := createIndexerService(
cfg, dbProvider, eventBus, logger, genDoc.ChainID, nodeMetrics.indexer)
eventSinks, err := sink.EventSinksFromConfig(cfg, dbProvider, genDoc.ChainID)
if err != nil {
return nil, combineCloseError(err, makeCloser(closers))
}
indexerService := indexer.NewService(indexer.ServiceArgs{
Sinks: eventSinks,
EventBus: eventBus,
Logger: logger.With("module", "txindex"),
Metrics: nodeMetrics.indexer,
})
privValidator, err := createPrivval(ctx, logger, cfg, genDoc, filePrivval)
if err != nil {
@@ -260,11 +265,8 @@ func makeNode(
node.rpcEnv.EvidencePool = evPool
node.evPool = evPool
mpReactor, mp, err := createMempoolReactor(logger, cfg, proxyApp, stateStore, nodeMetrics.mempool,
mpReactor, mp := createMempoolReactor(logger, cfg, proxyApp, stateStore, nodeMetrics.mempool,
peerManager.Subscribe, node.router.OpenChannel, peerManager.GetHeight)
if err != nil {
return nil, combineCloseError(err, makeCloser(closers))
}
node.rpcEnv.Mempool = mp
node.services = append(node.services, mpReactor)
@@ -292,16 +294,32 @@ func makeNode(
blockSync := !onlyValidatorIsUs(state, pubKey)
waitSync := stateSync || blockSync
csReactor, csState, err := createConsensusReactor(ctx,
cfg, stateStore, blockExec, blockStore, mp, evPool,
privValidator, nodeMetrics.consensus, waitSync, eventBus,
peerManager, node.router.OpenChannel, logger,
csState, err := consensus.NewState(logger.With("module", "consensus"),
cfg.Consensus,
stateStore,
blockExec,
blockStore,
mp,
evPool,
eventBus,
consensus.StateMetrics(nodeMetrics.consensus),
consensus.SkipStateStoreBootstrap,
)
if err != nil {
return nil, combineCloseError(err, makeCloser(closers))
}
node.services = append(node.services, csReactor)
node.rpcEnv.ConsensusState = csState
csReactor := consensus.NewReactor(
logger,
csState,
node.router.OpenChannel,
peerManager.Subscribe,
eventBus,
waitSync,
nodeMetrics.consensus,
)
node.services = append(node.services, csReactor)
node.rpcEnv.ConsensusReactor = csReactor
// Create the blockchain reactor. Note, we do not start block sync if we're
@@ -370,6 +388,9 @@ func makeNode(
))
if cfg.Mode == config.ModeValidator {
if privValidator != nil {
csState.SetPrivValidator(ctx, privValidator)
}
node.rpcEnv.PubKey = pubKey
}
@@ -423,7 +444,7 @@ func (n *nodeImpl) OnStart(ctx context.Context) error {
// Start Internal Services
if n.config.RPC.PprofListenAddress != "" {
rpcCtx, rpcCancel := context.WithCancel(ctx)
signal := make(chan struct{})
srv := &http.Server{Addr: n.config.RPC.PprofListenAddress, Handler: nil}
go func() {
select {
@@ -431,7 +452,7 @@ func (n *nodeImpl) OnStart(ctx context.Context) error {
sctx, scancel := context.WithTimeout(context.Background(), time.Second)
defer scancel()
_ = srv.Shutdown(sctx)
case <-rpcCtx.Done():
case <-signal:
}
}()
@@ -440,7 +461,7 @@ func (n *nodeImpl) OnStart(ctx context.Context) error {
if err := srv.ListenAndServe(); err != nil {
n.logger.Error("pprof server error", "err", err)
rpcCancel()
close(signal)
}
}()
}
@@ -562,21 +583,21 @@ func (n *nodeImpl) startPrometheusServer(ctx context.Context, addr string) *http
),
}
promCtx, promCancel := context.WithCancel(ctx)
signal := make(chan struct{})
go func() {
select {
case <-ctx.Done():
sctx, scancel := context.WithTimeout(context.Background(), time.Second)
defer scancel()
_ = srv.Shutdown(sctx)
case <-promCtx.Done():
case <-signal:
}
}()
go func() {
if err := srv.ListenAndServe(); err != nil {
n.logger.Error("Prometheus HTTP server ListenAndServe", "err", err)
promCancel()
close(signal)
}
}()
+15 -7
View File
@@ -28,6 +28,7 @@ import (
"github.com/tendermint/tendermint/internal/pubsub"
sm "github.com/tendermint/tendermint/internal/state"
"github.com/tendermint/tendermint/internal/state/indexer"
"github.com/tendermint/tendermint/internal/state/indexer/sink"
"github.com/tendermint/tendermint/internal/store"
"github.com/tendermint/tendermint/internal/test/factory"
"github.com/tendermint/tendermint/libs/log"
@@ -454,7 +455,8 @@ func TestMaxProposalBlockSize(t *testing.T) {
err = proxyApp.Start(ctx)
require.NoError(t, err)
state, stateDB, _ := state(t, types.MaxVotesCount, int64(1))
state, stateDB, privVals := state(t, types.MaxVotesCount, int64(1))
stateStore := sm.NewStore(stateDB)
blockStore := store.NewBlockStore(dbm.NewMemDB())
const maxBytes int64 = 1024 * 1024 * 2
@@ -537,17 +539,25 @@ func TestMaxProposalBlockSize(t *testing.T) {
BlockID: blockID,
}
votes := make([]*types.Vote, types.MaxVotesCount)
// add maximum amount of signatures to a single commit
for i := 0; i < types.MaxVotesCount; i++ {
pubKey, err := privVals[i].GetPubKey(ctx)
require.NoError(t, err)
votes[i] = &types.Vote{
ValidatorAddress: pubKey.Address(),
}
commit.Signatures = append(commit.Signatures, cs)
}
block, err := blockExec.CreateProposalBlock(
ctx,
math.MaxInt64,
state, commit,
state,
commit,
proposerAddr,
nil,
votes,
)
require.NoError(t, err)
partSet, err := block.MakePartSet(types.BlockPartSizeBytes)
@@ -627,11 +637,9 @@ func TestNodeSetEventSink(t *testing.T) {
genDoc, err := types.GenesisDocFromFile(cfg.GenesisFile())
require.NoError(t, err)
indexService, eventSinks, err := createIndexerService(cfg,
config.DefaultDBProvider, eventBus, logger, genDoc.ChainID,
indexer.NopMetrics())
eventSinks, err := sink.EventSinksFromConfig(cfg, config.DefaultDBProvider, genDoc.ChainID)
require.NoError(t, err)
t.Cleanup(indexService.Wait)
return eventSinks
}
cleanup := func(ns service.Service) func() {
+4 -85
View File
@@ -23,7 +23,6 @@ import (
"github.com/tendermint/tendermint/internal/p2p/pex"
sm "github.com/tendermint/tendermint/internal/state"
"github.com/tendermint/tendermint/internal/state/indexer"
"github.com/tendermint/tendermint/internal/state/indexer/sink"
"github.com/tendermint/tendermint/internal/statesync"
"github.com/tendermint/tendermint/internal/store"
"github.com/tendermint/tendermint/libs/log"
@@ -95,29 +94,6 @@ func initDBs(
return blockStore, stateDB, makeCloser(closers), nil
}
func createIndexerService(
cfg *config.Config,
dbProvider config.DBProvider,
eventBus *eventbus.EventBus,
logger log.Logger,
chainID string,
metrics *indexer.Metrics,
) (*indexer.Service, []indexer.EventSink, error) {
eventSinks, err := sink.EventSinksFromConfig(cfg, dbProvider, chainID)
if err != nil {
return nil, nil, err
}
indexerService := indexer.NewService(indexer.ServiceArgs{
Sinks: eventSinks,
EventBus: eventBus,
Logger: logger.With("module", "txindex"),
Metrics: metrics,
})
return indexerService, eventSinks, nil
}
func logNodeStartupInfo(state sm.State, pubKey crypto.PubKey, logger log.Logger, mode string) {
// Log the version info.
logger.Info("Version info",
@@ -172,7 +148,7 @@ func createMempoolReactor(
peerEvents p2p.PeerEventSubscriber,
chCreator p2p.ChannelCreator,
peerHeight func(types.NodeID) int64,
) (service.Service, mempool.Mempool, error) {
) (service.Service, mempool.Mempool) {
logger = logger.With("module", "mempool")
mp := mempool.NewTxMempool(
@@ -197,7 +173,7 @@ func createMempoolReactor(
mp.EnableTxsAvailable()
}
return reactor, mp, nil
return reactor, mp
}
func createEvidenceReactor(
@@ -215,70 +191,13 @@ func createEvidenceReactor(
if err != nil {
return nil, nil, func() error { return nil }, fmt.Errorf("unable to initialize evidence db: %w", err)
}
dbCloser := evidenceDB.Close
logger = logger.With("module", "evidence")
evidencePool := evidence.NewPool(logger, evidenceDB, store, blockStore, metrics, eventBus)
evidenceReactor := evidence.NewReactor(logger, chCreator, peerEvents, evidencePool)
evidenceReactor := evidence.NewReactor(
logger,
chCreator,
peerEvents,
evidencePool,
)
return evidenceReactor, evidencePool, dbCloser, nil
}
func createConsensusReactor(
ctx context.Context,
cfg *config.Config,
store sm.Store,
blockExec *sm.BlockExecutor,
blockStore sm.BlockStore,
mp mempool.Mempool,
evidencePool *evidence.Pool,
privValidator types.PrivValidator,
csMetrics *consensus.Metrics,
waitSync bool,
eventBus *eventbus.EventBus,
peerManager *p2p.PeerManager,
chCreator p2p.ChannelCreator,
logger log.Logger,
) (*consensus.Reactor, *consensus.State, error) {
logger = logger.With("module", "consensus")
consensusState, err := consensus.NewState(ctx,
logger,
cfg.Consensus,
store,
blockExec,
blockStore,
mp,
evidencePool,
eventBus,
consensus.StateMetrics(csMetrics),
consensus.SkipStateStoreBootstrap,
)
if err != nil {
return nil, nil, err
}
if privValidator != nil && cfg.Mode == config.ModeValidator {
consensusState.SetPrivValidator(ctx, privValidator)
}
reactor := consensus.NewReactor(
logger,
consensusState,
chCreator,
peerManager.Subscribe,
eventBus,
waitSync,
csMetrics,
)
return reactor, consensusState, nil
return evidenceReactor, evidencePool, evidenceDB.Close, nil
}
func createPeerManager(
+29 -8
View File
@@ -117,6 +117,14 @@ type FilePVLastSignState struct {
filePath string
}
func (lss *FilePVLastSignState) reset() {
lss.Height = 0
lss.Round = 0
lss.Step = 0
lss.Signature = nil
lss.SignBytes = nil
}
// checkHRS checks the given height, round, step (HRS) against that of the
// FilePVLastSignState. It returns an error if the arguments constitute a regression,
// or if they match but the SignBytes are empty.
@@ -328,12 +336,7 @@ func (pv *FilePV) Save() error {
// Reset resets all fields in the FilePV.
// NOTE: Unsafe!
func (pv *FilePV) Reset() error {
var sig []byte
pv.LastSignState.Height = 0
pv.LastSignState.Round = 0
pv.LastSignState.Step = 0
pv.LastSignState.Signature = sig
pv.LastSignState.SignBytes = nil
pv.LastSignState.reset()
return pv.Save()
}
@@ -369,6 +372,12 @@ func (pv *FilePV) signVote(chainID string, vote *tmproto.Vote) error {
}
signBytes := types.VoteSignBytes(chainID, vote)
extSignBytes := types.VoteExtensionSignBytes(chainID, vote)
// We always sign the vote extension. See below for details.
extSig, err := pv.Key.PrivKey.Sign(extSignBytes)
if err != nil {
return err
}
// We might crash before writing to the wal,
// causing us to try to re-sign for the same HRS.
@@ -379,6 +388,8 @@ func (pv *FilePV) signVote(chainID string, vote *tmproto.Vote) error {
if bytes.Equal(signBytes, lss.SignBytes) {
vote.Signature = lss.Signature
} else {
// Compares the canonicalized votes (i.e. without vote extensions
// or vote extension signatures).
timestamp, ok, err := checkVotesOnlyDifferByTimestamp(lss.SignBytes, signBytes)
if err != nil {
return err
@@ -390,6 +401,12 @@ func (pv *FilePV) signVote(chainID string, vote *tmproto.Vote) error {
vote.Timestamp = timestamp
vote.Signature = lss.Signature
}
// Vote extensions are non-deterministic, so it's possible that an
// application may have created a different extension. We therefore
// always re-sign the vote extension.
vote.ExtensionSignature = extSig
return nil
}
@@ -402,6 +419,8 @@ func (pv *FilePV) signVote(chainID string, vote *tmproto.Vote) error {
return err
}
vote.Signature = sig
vote.ExtensionSignature = extSig
return nil
}
@@ -453,8 +472,10 @@ func (pv *FilePV) saveSigned(height int64, round int32, step int8, signBytes []b
//-----------------------------------------------------------------------------------------
// returns the timestamp from the lastSignBytes.
// returns true if the only difference in the votes is their timestamp.
// Returns the timestamp from the lastSignBytes.
// Returns true if the only difference in the votes is their timestamp.
// Performs these checks on the canonical votes (excluding the vote extension
// and vote extension signatures).
func checkVotesOnlyDifferByTimestamp(lastSignBytes, newSignBytes []byte) (time.Time, bool, error) {
var lastVote, newVote tmproto.CanonicalVote
if err := protoio.UnmarshalDelimited(lastSignBytes, &lastVote); err != nil {
+91 -41
View File
@@ -21,20 +21,14 @@ import (
)
func TestGenLoadValidator(t *testing.T) {
tempKeyFile, err := os.CreateTemp(t.TempDir(), "priv_validator_key_")
require.NoError(t, err)
tempStateFile, err := os.CreateTemp(t.TempDir(), "priv_validator_state_")
require.NoError(t, err)
privVal, err := GenFilePV(tempKeyFile.Name(), tempStateFile.Name(), "")
require.NoError(t, err)
privVal, tempKeyFileName, tempStateFileName := newTestFilePV(t)
height := int64(100)
privVal.LastSignState.Height = height
require.NoError(t, privVal.Save())
addr := privVal.GetAddress()
privVal, err = LoadFilePV(tempKeyFile.Name(), tempStateFile.Name())
privVal, err := LoadFilePV(tempKeyFileName, tempStateFileName)
assert.NoError(t, err)
assert.Equal(t, addr, privVal.GetAddress(), "expected privval addr to be the same")
assert.Equal(t, height, privVal.LastSignState.Height, "expected privval.LastHeight to have been saved")
@@ -44,14 +38,8 @@ func TestResetValidator(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
tempKeyFile, err := os.CreateTemp(t.TempDir(), "priv_validator_key_")
require.NoError(t, err)
tempStateFile, err := os.CreateTemp(t.TempDir(), "priv_validator_state_")
require.NoError(t, err)
privVal, err := GenFilePV(tempKeyFile.Name(), tempStateFile.Name(), "")
require.NoError(t, err)
emptyState := FilePVLastSignState{filePath: tempStateFile.Name()}
privVal, _, tempStateFileName := newTestFilePV(t)
emptyState := FilePVLastSignState{filePath: tempStateFileName}
// new priv val has empty state
assert.Equal(t, privVal.LastSignState, emptyState)
@@ -61,8 +49,8 @@ func TestResetValidator(t *testing.T) {
voteType := tmproto.PrevoteType
randBytes := tmrand.Bytes(tmhash.Size)
blockID := types.BlockID{Hash: randBytes, PartSetHeader: types.PartSetHeader{}}
vote := newVote(privVal.Key.Address, 0, height, round, voteType, blockID)
err = privVal.SignVote(ctx, "mychainid", vote.ToProto())
vote := newVote(privVal.Key.Address, 0, height, round, voteType, blockID, nil)
err := privVal.SignVote(ctx, "mychainid", vote.ToProto())
assert.NoError(t, err, "expected no error signing vote")
// priv val after signing is not same as empty
@@ -160,13 +148,7 @@ func TestSignVote(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
tempKeyFile, err := os.CreateTemp(t.TempDir(), "priv_validator_key_")
require.NoError(t, err)
tempStateFile, err := os.CreateTemp(t.TempDir(), "priv_validator_state_")
require.NoError(t, err)
privVal, err := GenFilePV(tempKeyFile.Name(), tempStateFile.Name(), "")
require.NoError(t, err)
privVal, _, _ := newTestFilePV(t)
randbytes := tmrand.Bytes(tmhash.Size)
randbytes2 := tmrand.Bytes(tmhash.Size)
@@ -180,10 +162,10 @@ func TestSignVote(t *testing.T) {
voteType := tmproto.PrevoteType
// sign a vote for first time
vote := newVote(privVal.Key.Address, 0, height, round, voteType, block1)
vote := newVote(privVal.Key.Address, 0, height, round, voteType, block1, nil)
v := vote.ToProto()
err = privVal.SignVote(ctx, "mychainid", v)
err := privVal.SignVote(ctx, "mychainid", v)
assert.NoError(t, err, "expected no error signing vote")
// try to sign the same vote again; should be fine
@@ -192,10 +174,10 @@ func TestSignVote(t *testing.T) {
// now try some bad votes
cases := []*types.Vote{
newVote(privVal.Key.Address, 0, height, round-1, voteType, block1), // round regression
newVote(privVal.Key.Address, 0, height-1, round, voteType, block1), // height regression
newVote(privVal.Key.Address, 0, height-2, round+4, voteType, block1), // height regression and different round
newVote(privVal.Key.Address, 0, height, round, voteType, block2), // different block
newVote(privVal.Key.Address, 0, height, round-1, voteType, block1, nil), // round regression
newVote(privVal.Key.Address, 0, height-1, round, voteType, block1, nil), // height regression
newVote(privVal.Key.Address, 0, height-2, round+4, voteType, block1, nil), // height regression and different round
newVote(privVal.Key.Address, 0, height, round, voteType, block2, nil), // different block
}
for _, c := range cases {
@@ -215,13 +197,7 @@ func TestSignProposal(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
tempKeyFile, err := os.CreateTemp(t.TempDir(), "priv_validator_key_")
require.NoError(t, err)
tempStateFile, err := os.CreateTemp(t.TempDir(), "priv_validator_state_")
require.NoError(t, err)
privVal, err := GenFilePV(tempKeyFile.Name(), tempStateFile.Name(), "")
require.NoError(t, err)
privVal, _, _ := newTestFilePV(t)
randbytes := tmrand.Bytes(tmhash.Size)
randbytes2 := tmrand.Bytes(tmhash.Size)
@@ -237,7 +213,7 @@ func TestSignProposal(t *testing.T) {
proposal := newProposal(height, round, block1, ts)
pbp := proposal.ToProto()
err = privVal.SignProposal(ctx, "mychainid", pbp)
err := privVal.SignProposal(ctx, "mychainid", pbp)
assert.NoError(t, err, "expected no error signing proposal")
// try to sign the same proposal again; should be fine
@@ -278,7 +254,7 @@ func TestDifferByTimestamp(t *testing.T) {
{
voteType := tmproto.PrevoteType
blockID := types.BlockID{Hash: randbytes, PartSetHeader: types.PartSetHeader{}}
vote := newVote(privVal.Key.Address, 0, height, round, voteType, blockID)
vote := newVote(privVal.Key.Address, 0, height, round, voteType, blockID, nil)
v := vote.ToProto()
err := privVal.SignVote(ctx, "mychainid", v)
require.NoError(t, err, "expected no error signing vote")
@@ -300,8 +276,69 @@ func TestDifferByTimestamp(t *testing.T) {
}
}
func TestVoteExtensionsAreAlwaysSigned(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
privVal, _, _ := newTestFilePV(t)
pubKey, err := privVal.GetPubKey(ctx)
assert.NoError(t, err)
block := types.BlockID{
Hash: tmrand.Bytes(tmhash.Size),
PartSetHeader: types.PartSetHeader{Total: 5, Hash: tmrand.Bytes(tmhash.Size)},
}
height, round := int64(10), int32(1)
voteType := tmproto.PrecommitType
// We initially sign this vote without an extension
vote1 := newVote(privVal.Key.Address, 0, height, round, voteType, block, nil)
vpb1 := vote1.ToProto()
err = privVal.SignVote(ctx, "mychainid", vpb1)
assert.NoError(t, err, "expected no error signing vote")
assert.NotNil(t, vpb1.ExtensionSignature)
vesb1 := types.VoteExtensionSignBytes("mychainid", vpb1)
assert.True(t, pubKey.VerifySignature(vesb1, vpb1.ExtensionSignature))
// We duplicate this vote precisely, including its timestamp, but change
// its extension
vote2 := vote1.Copy()
vote2.Extension = []byte("new extension")
vpb2 := vote2.ToProto()
err = privVal.SignVote(ctx, "mychainid", vpb2)
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
// that validates against the vote extension sign bytes with the new
// extension, and does not validate against the vote extension sign bytes
// with the old extension.
vesb2 := types.VoteExtensionSignBytes("mychainid", vpb2)
assert.True(t, pubKey.VerifySignature(vesb2, vpb2.ExtensionSignature))
assert.False(t, pubKey.VerifySignature(vesb1, vpb2.ExtensionSignature))
// We now manipulate the timestamp of the vote with the extension, as per
// TestDifferByTimestamp
expectedTimestamp := vpb2.Timestamp
vpb2.Timestamp = vpb2.Timestamp.Add(time.Millisecond)
vpb2.Signature = nil
vpb2.ExtensionSignature = nil
err = privVal.SignVote(ctx, "mychainid", vpb2)
assert.NoError(t, err, "expected no error signing same vote with manipulated timestamp and vote extension")
assert.Equal(t, expectedTimestamp, vpb2.Timestamp)
vesb3 := types.VoteExtensionSignBytes("mychainid", vpb2)
assert.True(t, pubKey.VerifySignature(vesb3, vpb2.ExtensionSignature))
assert.False(t, pubKey.VerifySignature(vesb1, vpb2.ExtensionSignature))
}
func newVote(addr types.Address, idx int32, height int64, round int32,
typ tmproto.SignedMsgType, blockID types.BlockID) *types.Vote {
typ tmproto.SignedMsgType, blockID types.BlockID, extension []byte) *types.Vote {
return &types.Vote{
ValidatorAddress: addr,
ValidatorIndex: idx,
@@ -310,6 +347,7 @@ func newVote(addr types.Address, idx int32, height int64, round int32,
Type: typ,
Timestamp: tmtime.Now(),
BlockID: blockID,
Extension: extension,
}
}
@@ -321,3 +359,15 @@ func newProposal(height int64, round int32, blockID types.BlockID, t time.Time)
Timestamp: t,
}
}
func newTestFilePV(t *testing.T) (*FilePV, string, string) {
tempKeyFile, err := os.CreateTemp(t.TempDir(), "priv_validator_key_")
require.NoError(t, err)
tempStateFile, err := os.CreateTemp(t.TempDir(), "priv_validator_state_")
require.NoError(t, err)
privVal, err := GenFilePV(tempKeyFile.Name(), tempStateFile.Name(), "")
require.NoError(t, err)
return privVal, tempKeyFile.Name(), tempStateFile.Name()
}
+8 -17
View File
@@ -22,23 +22,14 @@ var stamp = time.Date(2019, 10, 13, 16, 14, 44, 0, time.UTC)
func exampleVote() *types.Vote {
return &types.Vote{
Type: tmproto.SignedMsgType(1),
Height: 3,
Round: 2,
Timestamp: stamp,
BlockID: types.BlockID{
Hash: tmhash.Sum([]byte("blockID_hash")),
PartSetHeader: types.PartSetHeader{
Total: 1000000,
Hash: tmhash.Sum([]byte("blockID_part_set_header_hash")),
},
},
Type: tmproto.PrecommitType,
Height: 3,
Round: 2,
BlockID: types.BlockID{Hash: tmhash.Sum([]byte("blockID_hash")), PartSetHeader: types.PartSetHeader{Total: 1000000, Hash: tmhash.Sum([]byte("blockID_part_set_header_hash"))}},
Timestamp: stamp,
ValidatorAddress: crypto.AddressHash([]byte("validator_address")),
ValidatorIndex: 56789,
VoteExtension: types.VoteExtension{
AppDataToSign: []byte("app_data_signed"),
AppDataSelfAuthenticating: []byte("app_data_self_authenticating"),
},
Extension: []byte("extension"),
}
}
@@ -87,8 +78,8 @@ func TestPrivvalVectors(t *testing.T) {
{"pubKey request", &privproto.PubKeyRequest{}, "0a00"},
{"pubKey response", &privproto.PubKeyResponse{PubKey: ppk, Error: nil}, "12240a220a20556a436f1218d30942efe798420f51dc9b6a311b929c578257457d05c5fcf230"},
{"pubKey response with error", &privproto.PubKeyResponse{PubKey: cryptoproto.PublicKey{}, Error: remoteError}, "12140a0012100801120c697427732061206572726f72"},
{"Vote Request", &privproto.SignVoteRequest{Vote: votepb}, "1aa8010aa501080110031802224a0a208b01023386c371778ecb6368573e539afc3cc860ec3a2f614e54fe5652f4fc80122608c0843d122072db3d959635dff1bb567bedaa70573392c5159666a3f8caf11e413aac52207a2a0608f49a8ded0532146af1f4111082efb388211bc72c55bcd61e9ac3d538d5bb034a2f0a0f6170705f646174615f7369676e6564121c6170705f646174615f73656c665f61757468656e7469636174696e67"},
{"Vote Response", &privproto.SignedVoteResponse{Vote: *votepb, Error: nil}, "22a8010aa501080110031802224a0a208b01023386c371778ecb6368573e539afc3cc860ec3a2f614e54fe5652f4fc80122608c0843d122072db3d959635dff1bb567bedaa70573392c5159666a3f8caf11e413aac52207a2a0608f49a8ded0532146af1f4111082efb388211bc72c55bcd61e9ac3d538d5bb034a2f0a0f6170705f646174615f7369676e6564121c6170705f646174615f73656c665f61757468656e7469636174696e67"},
{"Vote Request", &privproto.SignVoteRequest{Vote: votepb}, "1a81010a7f080210031802224a0a208b01023386c371778ecb6368573e539afc3cc860ec3a2f614e54fe5652f4fc80122608c0843d122072db3d959635dff1bb567bedaa70573392c5159666a3f8caf11e413aac52207a2a0608f49a8ded0532146af1f4111082efb388211bc72c55bcd61e9ac3d538d5bb034a09657874656e73696f6e"},
{"Vote Response", &privproto.SignedVoteResponse{Vote: *votepb, Error: nil}, "2281010a7f080210031802224a0a208b01023386c371778ecb6368573e539afc3cc860ec3a2f614e54fe5652f4fc80122608c0843d122072db3d959635dff1bb567bedaa70573392c5159666a3f8caf11e413aac52207a2a0608f49a8ded0532146af1f4111082efb388211bc72c55bcd61e9ac3d538d5bb034a09657874656e73696f6e"},
{"Vote Response with error", &privproto.SignedVoteResponse{Vote: tmproto.Vote{}, Error: remoteError}, "22250a11220212002a0b088092b8c398feffffff0112100801120c697427732061206572726f72"},
{"Proposal Request", &privproto.SignProposalRequest{Proposal: proposalpb}, "2a700a6e08011003180220022a4a0a208b01023386c371778ecb6368573e539afc3cc860ec3a2f614e54fe5652f4fc80122608c0843d122072db3d959635dff1bb567bedaa70573392c5159666a3f8caf11e413aac52207a320608f49a8ded053a10697427732061207369676e6174757265"},
{"Proposal Response", &privproto.SignedProposalResponse{Proposal: *proposalpb, Error: nil}, "32700a6e08011003180220022a4a0a208b01023386c371778ecb6368573e539afc3cc860ec3a2f614e54fe5652f4fc80122608c0843d122072db3d959635dff1bb567bedaa70573392c5159666a3f8caf11e413aac52207a320608f49a8ded053a10697427732061207369676e6174757265"},
+10 -14
View File
@@ -384,7 +384,10 @@ message CommitInfo {
}
message ExtendedCommitInfo {
int32 round = 1;
// The round at which the block proposer decided in the previous height.
int32 round = 1;
// List of validators' addresses in the last validator set with their voting
// information, including vote extensions.
repeated ExtendedVoteInfo votes = 2 [(gogoproto.nullable) = false];
}
@@ -465,19 +468,12 @@ message VoteInfo {
// ExtendedVoteInfo
message ExtendedVoteInfo {
Validator validator = 1 [(gogoproto.nullable) = false];
bool signed_last_block = 2;
bytes vote_extension = 3;
}
// CanonicalVoteExtension
// TODO: move this to core Tendermint data structures
message CanonicalVoteExtension {
bytes extension = 1;
int64 height = 2;
int32 round = 3;
string chain_id = 4;
bytes address = 5;
// The validator that sent the vote.
Validator validator = 1 [(gogoproto.nullable) = false];
// Indicates whether the validator signed the last block, allowing for rewards based on validator availability.
bool signed_last_block = 2;
// Non-deterministic extension provided by the sending validator's application.
bytes vote_extension = 3;
}
+21 -7
View File
@@ -153,12 +153,16 @@ message RequestProcessProposal {
// Extends a vote with application-side injection
message RequestExtendVote {
types.Vote vote = 1;
bytes hash = 1;
int64 height = 2;
}
// Verify the vote extension
message RequestVerifyVoteExtension {
types.Vote vote = 1;
bytes hash = 1;
bytes validator_address = 2;
int64 height = 3;
bytes vote_extension = 4;
}
message RequestFinalizeBlock {
@@ -348,7 +352,7 @@ message ResponseProcessProposal {
}
message ResponseExtendVote {
tendermint.types.VoteExtension vote_extension = 1;
bytes vote_extension = 1;
}
message ResponseVerifyVoteExtension {
@@ -379,8 +383,14 @@ message CommitInfo {
repeated VoteInfo votes = 2 [(gogoproto.nullable) = false];
}
// ExtendedCommitInfo is similar to CommitInfo except that it is only used in
// the PrepareProposal request such that Tendermint can provide vote extensions
// to the application.
message ExtendedCommitInfo {
int32 round = 1;
// The round at which the block proposer decided in the previous height.
int32 round = 1;
// List of validators' addresses in the last validator set with their voting
// information, including vote extensions.
repeated ExtendedVoteInfo votes = 2 [(gogoproto.nullable) = false];
}
@@ -461,10 +471,14 @@ message VoteInfo {
reserved 4; // Placeholder for app_signed_extension in v0.37
}
// ExtendedVoteInfo
message ExtendedVoteInfo {
Validator validator = 1 [(gogoproto.nullable) = false];
bool signed_last_block = 2;
bytes vote_extension = 3;
// The validator that sent the vote.
Validator validator = 1 [(gogoproto.nullable) = false];
// Indicates whether the validator signed the last block, allowing for rewards based on validator availability.
bool signed_last_block = 2;
// Non-deterministic extension provided by the sending validator's application.
bytes vote_extension = 3;
}
enum MisbehaviorType {
+292 -73
View File
@@ -225,13 +225,12 @@ 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"`
Timestamp time.Time `protobuf:"bytes,5,opt,name=timestamp,proto3,stdtime" json:"timestamp"`
ChainID string `protobuf:"bytes,6,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"`
VoteExtension *VoteExtensionToSign `protobuf:"bytes,7,opt,name=vote_extension,json=voteExtension,proto3" json:"vote_extension,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"`
BlockID *CanonicalBlockID `protobuf:"bytes,4,opt,name=block_id,json=blockId,proto3" json:"block_id,omitempty"`
Timestamp time.Time `protobuf:"bytes,5,opt,name=timestamp,proto3,stdtime" json:"timestamp"`
ChainID string `protobuf:"bytes,6,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"`
}
func (m *CanonicalVote) Reset() { *m = CanonicalVote{} }
@@ -309,57 +308,121 @@ func (m *CanonicalVote) GetChainID() string {
return ""
}
func (m *CanonicalVote) GetVoteExtension() *VoteExtensionToSign {
// CanonicalVoteExtension provides us a way to serialize a vote extension from
// a particular validator such that we can sign over those serialized bytes.
type CanonicalVoteExtension struct {
Extension []byte `protobuf:"bytes,1,opt,name=extension,proto3" json:"extension,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"`
ChainId string `protobuf:"bytes,4,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"`
}
func (m *CanonicalVoteExtension) Reset() { *m = CanonicalVoteExtension{} }
func (m *CanonicalVoteExtension) String() string { return proto.CompactTextString(m) }
func (*CanonicalVoteExtension) ProtoMessage() {}
func (*CanonicalVoteExtension) Descriptor() ([]byte, []int) {
return fileDescriptor_8d1a1a84ff7267ed, []int{4}
}
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
}
}
func (m *CanonicalVoteExtension) XXX_Merge(src proto.Message) {
xxx_messageInfo_CanonicalVoteExtension.Merge(m, src)
}
func (m *CanonicalVoteExtension) XXX_Size() int {
return m.Size()
}
func (m *CanonicalVoteExtension) XXX_DiscardUnknown() {
xxx_messageInfo_CanonicalVoteExtension.DiscardUnknown(m)
}
var xxx_messageInfo_CanonicalVoteExtension proto.InternalMessageInfo
func (m *CanonicalVoteExtension) GetExtension() []byte {
if m != nil {
return m.VoteExtension
return m.Extension
}
return nil
}
func (m *CanonicalVoteExtension) GetHeight() int64 {
if m != nil {
return m.Height
}
return 0
}
func (m *CanonicalVoteExtension) GetRound() int64 {
if m != nil {
return m.Round
}
return 0
}
func (m *CanonicalVoteExtension) GetChainId() string {
if m != nil {
return m.ChainId
}
return ""
}
func init() {
proto.RegisterType((*CanonicalBlockID)(nil), "tendermint.types.CanonicalBlockID")
proto.RegisterType((*CanonicalPartSetHeader)(nil), "tendermint.types.CanonicalPartSetHeader")
proto.RegisterType((*CanonicalProposal)(nil), "tendermint.types.CanonicalProposal")
proto.RegisterType((*CanonicalVote)(nil), "tendermint.types.CanonicalVote")
proto.RegisterType((*CanonicalVoteExtension)(nil), "tendermint.types.CanonicalVoteExtension")
}
func init() { proto.RegisterFile("tendermint/types/canonical.proto", fileDescriptor_8d1a1a84ff7267ed) }
var fileDescriptor_8d1a1a84ff7267ed = []byte{
// 522 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x94, 0x3f, 0x6f, 0xd3, 0x40,
0x18, 0xc6, 0xe3, 0xd4, 0x49, 0x9c, 0x4b, 0x53, 0xc2, 0xa9, 0xaa, 0xac, 0x08, 0xd9, 0x96, 0x25,
0x90, 0x59, 0x6c, 0x29, 0x1d, 0xd8, 0x5d, 0x90, 0x08, 0x2a, 0xa2, 0x5c, 0xa3, 0x0e, 0x2c, 0xd6,
0xc5, 0x3e, 0x6c, 0x0b, 0xc7, 0x67, 0xd9, 0x97, 0x8a, 0x2e, 0x7c, 0x86, 0x7e, 0xac, 0x8e, 0x1d,
0x61, 0x09, 0xc8, 0xf9, 0x12, 0x8c, 0xe8, 0xce, 0x49, 0x1c, 0x25, 0xc0, 0x02, 0xea, 0x12, 0xbd,
0x7f, 0x1e, 0xbf, 0xef, 0xa3, 0xdf, 0xab, 0x1c, 0x30, 0x18, 0x49, 0x03, 0x92, 0xcf, 0xe2, 0x94,
0x39, 0xec, 0x26, 0x23, 0x85, 0xe3, 0xe3, 0x94, 0xa6, 0xb1, 0x8f, 0x13, 0x3b, 0xcb, 0x29, 0xa3,
0x70, 0x50, 0x2b, 0x6c, 0xa1, 0x18, 0x1e, 0x87, 0x34, 0xa4, 0xa2, 0xe9, 0xf0, 0xa8, 0xd2, 0x0d,
0x9f, 0xec, 0x4d, 0x12, 0xbf, 0xab, 0xae, 0x1e, 0x52, 0x1a, 0x26, 0xc4, 0x11, 0xd9, 0x74, 0xfe,
0xd1, 0x61, 0xf1, 0x8c, 0x14, 0x0c, 0xcf, 0xb2, 0x4a, 0x60, 0x7e, 0x01, 0x83, 0xb3, 0xf5, 0x66,
0x37, 0xa1, 0xfe, 0xa7, 0xf1, 0x4b, 0x08, 0x81, 0x1c, 0xe1, 0x22, 0x52, 0x25, 0x43, 0xb2, 0x0e,
0x91, 0x88, 0xe1, 0x15, 0x78, 0x94, 0xe1, 0x9c, 0x79, 0x05, 0x61, 0x5e, 0x44, 0x70, 0x40, 0x72,
0xb5, 0x69, 0x48, 0x56, 0x6f, 0x64, 0xd9, 0xbb, 0x46, 0xed, 0xcd, 0xc0, 0x0b, 0x9c, 0xb3, 0x4b,
0xc2, 0x5e, 0x0b, 0xbd, 0x2b, 0xdf, 0x2d, 0xf4, 0x06, 0xea, 0x67, 0xdb, 0x45, 0xd3, 0x05, 0x27,
0xbf, 0x97, 0xc3, 0x63, 0xd0, 0x62, 0x94, 0xe1, 0x44, 0xd8, 0xe8, 0xa3, 0x2a, 0xd9, 0x78, 0x6b,
0xd6, 0xde, 0xcc, 0x6f, 0x4d, 0xf0, 0xb8, 0x1e, 0x92, 0xd3, 0x8c, 0x16, 0x38, 0x81, 0xa7, 0x40,
0xe6, 0x76, 0xc4, 0xe7, 0x47, 0x23, 0x7d, 0xdf, 0xe6, 0x65, 0x1c, 0xa6, 0x24, 0x78, 0x5b, 0x84,
0x93, 0x9b, 0x8c, 0x20, 0x21, 0x86, 0x27, 0xa0, 0x1d, 0x91, 0x38, 0x8c, 0x98, 0x58, 0x30, 0x40,
0xab, 0x8c, 0x9b, 0xc9, 0xe9, 0x3c, 0x0d, 0xd4, 0x03, 0x51, 0xae, 0x12, 0xf8, 0x1c, 0x74, 0x33,
0x9a, 0x78, 0x55, 0x47, 0x36, 0x24, 0xeb, 0xc0, 0x3d, 0x2c, 0x17, 0xba, 0x72, 0xf1, 0xee, 0x1c,
0xf1, 0x1a, 0x52, 0x32, 0x9a, 0x88, 0x08, 0xbe, 0x01, 0xca, 0x94, 0xe3, 0xf5, 0xe2, 0x40, 0x6d,
0x09, 0x70, 0xe6, 0x5f, 0xc0, 0xad, 0x2e, 0xe1, 0xf6, 0xca, 0x85, 0xde, 0x59, 0x25, 0xa8, 0x23,
0x06, 0x8c, 0x03, 0xe8, 0x82, 0xee, 0xe6, 0x8c, 0x6a, 0x5b, 0x0c, 0x1b, 0xda, 0xd5, 0xa1, 0xed,
0xf5, 0xa1, 0xed, 0xc9, 0x5a, 0xe1, 0x2a, 0x9c, 0xfb, 0xed, 0x77, 0x5d, 0x42, 0xf5, 0x67, 0xf0,
0x19, 0x50, 0xfc, 0x08, 0xc7, 0x29, 0xf7, 0xd3, 0x31, 0x24, 0xab, 0x5b, 0xed, 0x3a, 0xe3, 0x35,
0xbe, 0x4b, 0x34, 0xc7, 0x81, 0xf9, 0xb3, 0x09, 0xfa, 0x1b, 0x5b, 0x57, 0x94, 0x91, 0x87, 0xe0,
0xba, 0x0d, 0x4b, 0xfe, 0x9f, 0xb0, 0x5a, 0xff, 0x0e, 0xab, 0xfd, 0x67, 0x58, 0xf0, 0x1c, 0x1c,
0x5d, 0x53, 0x46, 0x3c, 0xf2, 0x99, 0x91, 0xb4, 0x88, 0x69, 0x2a, 0xd0, 0xf6, 0x46, 0x4f, 0xf7,
0xdd, 0x73, 0x94, 0xaf, 0xd6, 0xb2, 0x09, 0xe5, 0xcc, 0x50, 0xff, 0x7a, 0xbb, 0xe8, 0xbe, 0xbf,
0x2b, 0x35, 0xe9, 0xbe, 0xd4, 0xa4, 0x1f, 0xa5, 0x26, 0xdd, 0x2e, 0xb5, 0xc6, 0xfd, 0x52, 0x6b,
0x7c, 0x5d, 0x6a, 0x8d, 0x0f, 0x2f, 0xc2, 0x98, 0x45, 0xf3, 0xa9, 0xed, 0xd3, 0x99, 0xb3, 0xfd,
0xf7, 0xaf, 0xc3, 0xea, 0x99, 0xd8, 0x7d, 0x1a, 0xa6, 0x6d, 0x51, 0x3f, 0xfd, 0x15, 0x00, 0x00,
0xff, 0xff, 0x4e, 0x61, 0xcb, 0xc4, 0x7f, 0x04, 0x00, 0x00,
// 523 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x54, 0xc1, 0x6e, 0xd3, 0x40,
0x10, 0x8d, 0x53, 0x27, 0xb1, 0xb7, 0x0d, 0x84, 0x55, 0x55, 0x99, 0xa8, 0xb2, 0x2d, 0x1f, 0x90,
0xb9, 0xd8, 0x52, 0x7b, 0xe0, 0xee, 0x82, 0x44, 0x10, 0x88, 0xe2, 0x56, 0x3d, 0x70, 0x89, 0x36,
0xf6, 0x62, 0x5b, 0x38, 0xde, 0x95, 0xbd, 0x91, 0xe8, 0x05, 0x7e, 0xa1, 0xdf, 0xc1, 0x97, 0xf4,
0xd8, 0x23, 0x5c, 0x02, 0x72, 0x7e, 0x04, 0xed, 0xda, 0xb1, 0xad, 0x16, 0x55, 0x42, 0x20, 0x2e,
0xd1, 0xcc, 0x9b, 0xb7, 0x33, 0x4f, 0x6f, 0xe2, 0x01, 0x26, 0xc3, 0x59, 0x88, 0xf3, 0x65, 0x92,
0x31, 0x97, 0x5d, 0x52, 0x5c, 0xb8, 0x01, 0xca, 0x48, 0x96, 0x04, 0x28, 0x75, 0x68, 0x4e, 0x18,
0x81, 0x93, 0x96, 0xe1, 0x08, 0xc6, 0x74, 0x3f, 0x22, 0x11, 0x11, 0x45, 0x97, 0x47, 0x15, 0x6f,
0x7a, 0x78, 0xa7, 0x93, 0xf8, 0xad, 0xab, 0x46, 0x44, 0x48, 0x94, 0x62, 0x57, 0x64, 0x8b, 0xd5,
0x07, 0x97, 0x25, 0x4b, 0x5c, 0x30, 0xb4, 0xa4, 0x15, 0xc1, 0xfa, 0x0c, 0x26, 0x27, 0xdb, 0xc9,
0x5e, 0x4a, 0x82, 0x8f, 0xb3, 0xe7, 0x10, 0x02, 0x39, 0x46, 0x45, 0xac, 0x49, 0xa6, 0x64, 0xef,
0xf9, 0x22, 0x86, 0x17, 0xe0, 0x21, 0x45, 0x39, 0x9b, 0x17, 0x98, 0xcd, 0x63, 0x8c, 0x42, 0x9c,
0x6b, 0x7d, 0x53, 0xb2, 0x77, 0x8f, 0x6c, 0xe7, 0xb6, 0x50, 0xa7, 0x69, 0x78, 0x8a, 0x72, 0x76,
0x86, 0xd9, 0x4b, 0xc1, 0xf7, 0xe4, 0xeb, 0xb5, 0xd1, 0xf3, 0xc7, 0xb4, 0x0b, 0x5a, 0x1e, 0x38,
0xf8, 0x3d, 0x1d, 0xee, 0x83, 0x01, 0x23, 0x0c, 0xa5, 0x42, 0xc6, 0xd8, 0xaf, 0x92, 0x46, 0x5b,
0xbf, 0xd5, 0x66, 0x7d, 0xef, 0x83, 0x47, 0x6d, 0x93, 0x9c, 0x50, 0x52, 0xa0, 0x14, 0x1e, 0x03,
0x99, 0xcb, 0x11, 0xcf, 0x1f, 0x1c, 0x19, 0x77, 0x65, 0x9e, 0x25, 0x51, 0x86, 0xc3, 0x37, 0x45,
0x74, 0x7e, 0x49, 0xb1, 0x2f, 0xc8, 0xf0, 0x00, 0x0c, 0x63, 0x9c, 0x44, 0x31, 0x13, 0x03, 0x26,
0x7e, 0x9d, 0x71, 0x31, 0x39, 0x59, 0x65, 0xa1, 0xb6, 0x23, 0xe0, 0x2a, 0x81, 0x4f, 0x81, 0x4a,
0x49, 0x3a, 0xaf, 0x2a, 0xb2, 0x29, 0xd9, 0x3b, 0xde, 0x5e, 0xb9, 0x36, 0x94, 0xd3, 0xb7, 0xaf,
0x7d, 0x8e, 0xf9, 0x0a, 0x25, 0xa9, 0x88, 0xe0, 0x2b, 0xa0, 0x2c, 0xb8, 0xbd, 0xf3, 0x24, 0xd4,
0x06, 0xc2, 0x38, 0xeb, 0x1e, 0xe3, 0xea, 0x4d, 0x78, 0xbb, 0xe5, 0xda, 0x18, 0xd5, 0x89, 0x3f,
0x12, 0x0d, 0x66, 0x21, 0xf4, 0x80, 0xda, 0xac, 0x51, 0x1b, 0x8a, 0x66, 0x53, 0xa7, 0x5a, 0xb4,
0xb3, 0x5d, 0xb4, 0x73, 0xbe, 0x65, 0x78, 0x0a, 0xf7, 0xfd, 0xea, 0x87, 0x21, 0xf9, 0xed, 0x33,
0xf8, 0x04, 0x28, 0x41, 0x8c, 0x92, 0x8c, 0xeb, 0x19, 0x99, 0x92, 0xad, 0x56, 0xb3, 0x4e, 0x38,
0xc6, 0x67, 0x89, 0xe2, 0x2c, 0xb4, 0xbe, 0xf6, 0xc1, 0xb8, 0x91, 0x75, 0x41, 0x18, 0xfe, 0x1f,
0xbe, 0x76, 0xcd, 0x92, 0xff, 0xa5, 0x59, 0x83, 0xbf, 0x37, 0x6b, 0x78, 0x8f, 0x59, 0x5f, 0x3a,
0x7f, 0x66, 0xee, 0xd5, 0x8b, 0x4f, 0x0c, 0x67, 0x45, 0x42, 0x32, 0x78, 0x08, 0x54, 0xbc, 0x4d,
0xea, 0xef, 0xaa, 0x05, 0xfe, 0xd0, 0x9d, 0xc7, 0x1d, 0x35, 0xdc, 0x1d, 0xb5, 0x11, 0xe0, 0xbd,
0xbb, 0x2e, 0x75, 0xe9, 0xa6, 0xd4, 0xa5, 0x9f, 0xa5, 0x2e, 0x5d, 0x6d, 0xf4, 0xde, 0xcd, 0x46,
0xef, 0x7d, 0xdb, 0xe8, 0xbd, 0xf7, 0xcf, 0xa2, 0x84, 0xc5, 0xab, 0x85, 0x13, 0x90, 0xa5, 0xdb,
0xbd, 0x18, 0x6d, 0x58, 0x5d, 0x96, 0xdb, 0xd7, 0x64, 0x31, 0x14, 0xf8, 0xf1, 0xaf, 0x00, 0x00,
0x00, 0xff, 0xff, 0x2b, 0x89, 0x89, 0x5b, 0xb2, 0x04, 0x00, 0x00,
}
func (m *CanonicalBlockID) Marshal() (dAtA []byte, err error) {
@@ -529,18 +592,6 @@ func (m *CanonicalVote) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if m.VoteExtension != nil {
{
size, err := m.VoteExtension.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintCanonical(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x3a
}
if len(m.ChainID) > 0 {
i -= len(m.ChainID)
copy(dAtA[i:], m.ChainID)
@@ -548,12 +599,12 @@ func (m *CanonicalVote) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i--
dAtA[i] = 0x32
}
n5, err5 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):])
if err5 != nil {
return 0, err5
n4, err4 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):])
if err4 != nil {
return 0, err4
}
i -= n5
i = encodeVarintCanonical(dAtA, i, uint64(n5))
i -= n4
i = encodeVarintCanonical(dAtA, i, uint64(n4))
i--
dAtA[i] = 0x2a
if m.BlockID != nil {
@@ -588,6 +639,55 @@ func (m *CanonicalVote) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
func (m *CanonicalVoteExtension) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *CanonicalVoteExtension) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *CanonicalVoteExtension) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.ChainId) > 0 {
i -= len(m.ChainId)
copy(dAtA[i:], m.ChainId)
i = encodeVarintCanonical(dAtA, i, uint64(len(m.ChainId)))
i--
dAtA[i] = 0x22
}
if m.Round != 0 {
i -= 8
encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(m.Round))
i--
dAtA[i] = 0x19
}
if m.Height != 0 {
i -= 8
encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(m.Height))
i--
dAtA[i] = 0x11
}
if len(m.Extension) > 0 {
i -= len(m.Extension)
copy(dAtA[i:], m.Extension)
i = encodeVarintCanonical(dAtA, i, uint64(len(m.Extension)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func encodeVarintCanonical(dAtA []byte, offset int, v uint64) int {
offset -= sovCanonical(v)
base := offset
@@ -686,8 +786,27 @@ func (m *CanonicalVote) Size() (n int) {
if l > 0 {
n += 1 + l + sovCanonical(uint64(l))
}
if m.VoteExtension != nil {
l = m.VoteExtension.Size()
return n
}
func (m *CanonicalVoteExtension) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Extension)
if l > 0 {
n += 1 + l + sovCanonical(uint64(l))
}
if m.Height != 0 {
n += 9
}
if m.Round != 0 {
n += 9
}
l = len(m.ChainId)
if l > 0 {
n += 1 + l + sovCanonical(uint64(l))
}
return n
@@ -1297,11 +1416,61 @@ func (m *CanonicalVote) Unmarshal(dAtA []byte) error {
}
m.ChainID = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 7:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field VoteExtension", wireType)
default:
iNdEx = preIndex
skippy, err := skipCanonical(dAtA[iNdEx:])
if err != nil {
return err
}
var msglen int
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthCanonical
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *CanonicalVoteExtension) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowCanonical
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: CanonicalVoteExtension: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: CanonicalVoteExtension: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Extension", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowCanonical
@@ -1311,27 +1480,77 @@ 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
}
if m.VoteExtension == nil {
m.VoteExtension = &VoteExtensionToSign{}
m.Extension = append(m.Extension[:0], dAtA[iNdEx:postIndex]...)
if m.Extension == nil {
m.Extension = []byte{}
}
if err := m.VoteExtension.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
iNdEx = postIndex
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 = int64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:]))
iNdEx += 8
case 3:
if wireType != 1 {
return fmt.Errorf("proto: wrong wireType = %d for field Round", wireType)
}
m.Round = 0
if (iNdEx + 8) > l {
return io.ErrUnexpectedEOF
}
m.Round = int64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:]))
iNdEx += 8
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowCanonical
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthCanonical
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthCanonical
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.ChainId = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
+9
View File
@@ -35,3 +35,12 @@ message CanonicalVote {
google.protobuf.Timestamp timestamp = 5 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
string chain_id = 6 [(gogoproto.customname) = "ChainID"];
}
// CanonicalVoteExtension provides us a way to serialize a vote extension from
// a particular validator such that we can sign over those serialized bytes.
message CanonicalVoteExtension {
bytes extension = 1;
sfixed64 height = 2;
sfixed64 round = 3;
string chain_id = 4;
}
+153 -566
View File
@@ -466,15 +466,22 @@ func (m *Data) GetTxs() [][]byte {
// Vote represents a prevote, precommit, or commit vote from validators for
// consensus.
type Vote struct {
Type SignedMsgType `protobuf:"varint,1,opt,name=type,proto3,enum=tendermint.types.SignedMsgType" json:"type,omitempty"`
Height int64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"`
Round int32 `protobuf:"varint,3,opt,name=round,proto3" json:"round,omitempty"`
BlockID BlockID `protobuf:"bytes,4,opt,name=block_id,json=blockId,proto3" json:"block_id"`
Timestamp time.Time `protobuf:"bytes,5,opt,name=timestamp,proto3,stdtime" json:"timestamp"`
ValidatorAddress []byte `protobuf:"bytes,6,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"`
ValidatorIndex int32 `protobuf:"varint,7,opt,name=validator_index,json=validatorIndex,proto3" json:"validator_index,omitempty"`
Signature []byte `protobuf:"bytes,8,opt,name=signature,proto3" json:"signature,omitempty"`
VoteExtension *VoteExtension `protobuf:"bytes,9,opt,name=vote_extension,json=voteExtension,proto3" json:"vote_extension,omitempty"`
Type SignedMsgType `protobuf:"varint,1,opt,name=type,proto3,enum=tendermint.types.SignedMsgType" json:"type,omitempty"`
Height int64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"`
Round int32 `protobuf:"varint,3,opt,name=round,proto3" json:"round,omitempty"`
BlockID BlockID `protobuf:"bytes,4,opt,name=block_id,json=blockId,proto3" json:"block_id"`
Timestamp time.Time `protobuf:"bytes,5,opt,name=timestamp,proto3,stdtime" json:"timestamp"`
ValidatorAddress []byte `protobuf:"bytes,6,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"`
ValidatorIndex int32 `protobuf:"varint,7,opt,name=validator_index,json=validatorIndex,proto3" json:"validator_index,omitempty"`
// Vote signature by the validator if they participated in consensus for the
// associated block.
Signature []byte `protobuf:"bytes,8,opt,name=signature,proto3" json:"signature,omitempty"`
// Vote extension provided by the application. Only valid for precommit
// messages.
Extension []byte `protobuf:"bytes,9,opt,name=extension,proto3" json:"extension,omitempty"`
// Vote extension signature by the validator if they participated in
// consensus for the associated block.
ExtensionSignature []byte `protobuf:"bytes,10,opt,name=extension_signature,json=extensionSignature,proto3" json:"extension_signature,omitempty"`
}
func (m *Vote) Reset() { *m = Vote{} }
@@ -566,108 +573,16 @@ func (m *Vote) GetSignature() []byte {
return nil
}
func (m *Vote) GetVoteExtension() *VoteExtension {
func (m *Vote) GetExtension() []byte {
if m != nil {
return m.VoteExtension
return m.Extension
}
return nil
}
// VoteExtension is app-defined additional information to the validator votes.
type VoteExtension struct {
AppDataToSign []byte `protobuf:"bytes,1,opt,name=app_data_to_sign,json=appDataToSign,proto3" json:"app_data_to_sign,omitempty"`
AppDataSelfAuthenticating []byte `protobuf:"bytes,2,opt,name=app_data_self_authenticating,json=appDataSelfAuthenticating,proto3" json:"app_data_self_authenticating,omitempty"`
}
func (m *VoteExtension) Reset() { *m = VoteExtension{} }
func (m *VoteExtension) String() string { return proto.CompactTextString(m) }
func (*VoteExtension) ProtoMessage() {}
func (*VoteExtension) Descriptor() ([]byte, []int) {
return fileDescriptor_d3a6e55e2345de56, []int{6}
}
func (m *VoteExtension) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *VoteExtension) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_VoteExtension.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *VoteExtension) XXX_Merge(src proto.Message) {
xxx_messageInfo_VoteExtension.Merge(m, src)
}
func (m *VoteExtension) XXX_Size() int {
return m.Size()
}
func (m *VoteExtension) XXX_DiscardUnknown() {
xxx_messageInfo_VoteExtension.DiscardUnknown(m)
}
var xxx_messageInfo_VoteExtension proto.InternalMessageInfo
func (m *VoteExtension) GetAppDataToSign() []byte {
func (m *Vote) GetExtensionSignature() []byte {
if m != nil {
return m.AppDataToSign
}
return nil
}
func (m *VoteExtension) GetAppDataSelfAuthenticating() []byte {
if m != nil {
return m.AppDataSelfAuthenticating
}
return nil
}
// VoteExtensionToSign is a subset of VoteExtension that is signed by the validators private key.
// VoteExtensionToSign is extracted from an existing VoteExtension.
type VoteExtensionToSign struct {
AppDataToSign []byte `protobuf:"bytes,1,opt,name=app_data_to_sign,json=appDataToSign,proto3" json:"app_data_to_sign,omitempty"`
}
func (m *VoteExtensionToSign) Reset() { *m = VoteExtensionToSign{} }
func (m *VoteExtensionToSign) String() string { return proto.CompactTextString(m) }
func (*VoteExtensionToSign) ProtoMessage() {}
func (*VoteExtensionToSign) Descriptor() ([]byte, []int) {
return fileDescriptor_d3a6e55e2345de56, []int{7}
}
func (m *VoteExtensionToSign) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *VoteExtensionToSign) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_VoteExtensionToSign.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *VoteExtensionToSign) XXX_Merge(src proto.Message) {
xxx_messageInfo_VoteExtensionToSign.Merge(m, src)
}
func (m *VoteExtensionToSign) XXX_Size() int {
return m.Size()
}
func (m *VoteExtensionToSign) XXX_DiscardUnknown() {
xxx_messageInfo_VoteExtensionToSign.DiscardUnknown(m)
}
var xxx_messageInfo_VoteExtensionToSign proto.InternalMessageInfo
func (m *VoteExtensionToSign) GetAppDataToSign() []byte {
if m != nil {
return m.AppDataToSign
return m.ExtensionSignature
}
return nil
}
@@ -685,7 +600,7 @@ func (m *Commit) Reset() { *m = Commit{} }
func (m *Commit) String() string { return proto.CompactTextString(m) }
func (*Commit) ProtoMessage() {}
func (*Commit) Descriptor() ([]byte, []int) {
return fileDescriptor_d3a6e55e2345de56, []int{8}
return fileDescriptor_d3a6e55e2345de56, []int{6}
}
func (m *Commit) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -744,18 +659,17 @@ func (m *Commit) GetSignatures() []CommitSig {
// CommitSig is a part of the Vote included in a Commit.
type CommitSig struct {
BlockIdFlag BlockIDFlag `protobuf:"varint,1,opt,name=block_id_flag,json=blockIdFlag,proto3,enum=tendermint.types.BlockIDFlag" json:"block_id_flag,omitempty"`
ValidatorAddress []byte `protobuf:"bytes,2,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"`
Timestamp time.Time `protobuf:"bytes,3,opt,name=timestamp,proto3,stdtime" json:"timestamp"`
Signature []byte `protobuf:"bytes,4,opt,name=signature,proto3" json:"signature,omitempty"`
VoteExtension *VoteExtensionToSign `protobuf:"bytes,5,opt,name=vote_extension,json=voteExtension,proto3" json:"vote_extension,omitempty"`
BlockIdFlag BlockIDFlag `protobuf:"varint,1,opt,name=block_id_flag,json=blockIdFlag,proto3,enum=tendermint.types.BlockIDFlag" json:"block_id_flag,omitempty"`
ValidatorAddress []byte `protobuf:"bytes,2,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"`
Timestamp time.Time `protobuf:"bytes,3,opt,name=timestamp,proto3,stdtime" json:"timestamp"`
Signature []byte `protobuf:"bytes,4,opt,name=signature,proto3" json:"signature,omitempty"`
}
func (m *CommitSig) Reset() { *m = CommitSig{} }
func (m *CommitSig) String() string { return proto.CompactTextString(m) }
func (*CommitSig) ProtoMessage() {}
func (*CommitSig) Descriptor() ([]byte, []int) {
return fileDescriptor_d3a6e55e2345de56, []int{9}
return fileDescriptor_d3a6e55e2345de56, []int{7}
}
func (m *CommitSig) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -812,13 +726,6 @@ func (m *CommitSig) GetSignature() []byte {
return nil
}
func (m *CommitSig) GetVoteExtension() *VoteExtensionToSign {
if m != nil {
return m.VoteExtension
}
return nil
}
type Proposal struct {
Type SignedMsgType `protobuf:"varint,1,opt,name=type,proto3,enum=tendermint.types.SignedMsgType" json:"type,omitempty"`
Height int64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"`
@@ -833,7 +740,7 @@ func (m *Proposal) Reset() { *m = Proposal{} }
func (m *Proposal) String() string { return proto.CompactTextString(m) }
func (*Proposal) ProtoMessage() {}
func (*Proposal) Descriptor() ([]byte, []int) {
return fileDescriptor_d3a6e55e2345de56, []int{10}
return fileDescriptor_d3a6e55e2345de56, []int{8}
}
func (m *Proposal) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -920,7 +827,7 @@ func (m *SignedHeader) Reset() { *m = SignedHeader{} }
func (m *SignedHeader) String() string { return proto.CompactTextString(m) }
func (*SignedHeader) ProtoMessage() {}
func (*SignedHeader) Descriptor() ([]byte, []int) {
return fileDescriptor_d3a6e55e2345de56, []int{11}
return fileDescriptor_d3a6e55e2345de56, []int{9}
}
func (m *SignedHeader) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -972,7 +879,7 @@ func (m *LightBlock) Reset() { *m = LightBlock{} }
func (m *LightBlock) String() string { return proto.CompactTextString(m) }
func (*LightBlock) ProtoMessage() {}
func (*LightBlock) Descriptor() ([]byte, []int) {
return fileDescriptor_d3a6e55e2345de56, []int{12}
return fileDescriptor_d3a6e55e2345de56, []int{10}
}
func (m *LightBlock) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1026,7 +933,7 @@ func (m *BlockMeta) Reset() { *m = BlockMeta{} }
func (m *BlockMeta) String() string { return proto.CompactTextString(m) }
func (*BlockMeta) ProtoMessage() {}
func (*BlockMeta) Descriptor() ([]byte, []int) {
return fileDescriptor_d3a6e55e2345de56, []int{13}
return fileDescriptor_d3a6e55e2345de56, []int{11}
}
func (m *BlockMeta) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1095,7 +1002,7 @@ func (m *TxProof) Reset() { *m = TxProof{} }
func (m *TxProof) String() string { return proto.CompactTextString(m) }
func (*TxProof) ProtoMessage() {}
func (*TxProof) Descriptor() ([]byte, []int) {
return fileDescriptor_d3a6e55e2345de56, []int{14}
return fileDescriptor_d3a6e55e2345de56, []int{12}
}
func (m *TxProof) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1154,8 +1061,6 @@ func init() {
proto.RegisterType((*Header)(nil), "tendermint.types.Header")
proto.RegisterType((*Data)(nil), "tendermint.types.Data")
proto.RegisterType((*Vote)(nil), "tendermint.types.Vote")
proto.RegisterType((*VoteExtension)(nil), "tendermint.types.VoteExtension")
proto.RegisterType((*VoteExtensionToSign)(nil), "tendermint.types.VoteExtensionToSign")
proto.RegisterType((*Commit)(nil), "tendermint.types.Commit")
proto.RegisterType((*CommitSig)(nil), "tendermint.types.CommitSig")
proto.RegisterType((*Proposal)(nil), "tendermint.types.Proposal")
@@ -1168,96 +1073,91 @@ func init() {
func init() { proto.RegisterFile("tendermint/types/types.proto", fileDescriptor_d3a6e55e2345de56) }
var fileDescriptor_d3a6e55e2345de56 = []byte{
// 1423 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0x4f, 0x6f, 0xdb, 0x64,
0x18, 0xaf, 0x13, 0xb7, 0x49, 0x9e, 0xc4, 0x6d, 0xfa, 0xd2, 0x6d, 0x69, 0xb6, 0xa6, 0x91, 0xd1,
0x58, 0x37, 0x50, 0x3a, 0x3a, 0xc4, 0x9f, 0x03, 0xa0, 0x24, 0xcd, 0xb6, 0x68, 0x6d, 0x1a, 0x9c,
0x6c, 0x08, 0x2e, 0x96, 0x93, 0xbc, 0x4d, 0xcc, 0x1c, 0xdb, 0xb2, 0xdf, 0x94, 0x76, 0x9f, 0x00,
0xf5, 0xb4, 0x13, 0xb7, 0x9e, 0xe0, 0x80, 0xc4, 0x05, 0x89, 0x2f, 0x80, 0x38, 0xed, 0xb8, 0x1b,
0x9c, 0x06, 0xea, 0x24, 0x3e, 0x07, 0x7a, 0xff, 0xc4, 0xb1, 0x9b, 0x86, 0x4d, 0xd5, 0xc4, 0x25,
0xf2, 0xfb, 0x3c, 0xbf, 0xe7, 0xff, 0xcf, 0x8f, 0xdf, 0xc0, 0x35, 0x82, 0xed, 0x1e, 0xf6, 0x86,
0xa6, 0x4d, 0x36, 0xc9, 0x91, 0x8b, 0x7d, 0xfe, 0x5b, 0x72, 0x3d, 0x87, 0x38, 0x28, 0x3b, 0xd1,
0x96, 0x98, 0x3c, 0xbf, 0xd2, 0x77, 0xfa, 0x0e, 0x53, 0x6e, 0xd2, 0x27, 0x8e, 0xcb, 0xaf, 0xf7,
0x1d, 0xa7, 0x6f, 0xe1, 0x4d, 0x76, 0xea, 0x8c, 0xf6, 0x37, 0x89, 0x39, 0xc4, 0x3e, 0x31, 0x86,
0xae, 0x00, 0xac, 0x85, 0xc2, 0x74, 0xbd, 0x23, 0x97, 0x38, 0x14, 0xeb, 0xec, 0x0b, 0x75, 0x21,
0xa4, 0x3e, 0xc0, 0x9e, 0x6f, 0x3a, 0x76, 0x38, 0x8f, 0x7c, 0x71, 0x2a, 0xcb, 0x03, 0xc3, 0x32,
0x7b, 0x06, 0x71, 0x3c, 0x8e, 0x50, 0x3f, 0x01, 0xa5, 0x69, 0x78, 0xa4, 0x85, 0xc9, 0x7d, 0x6c,
0xf4, 0xb0, 0x87, 0x56, 0x60, 0x9e, 0x38, 0xc4, 0xb0, 0x72, 0x52, 0x51, 0xda, 0x50, 0x34, 0x7e,
0x40, 0x08, 0xe4, 0x81, 0xe1, 0x0f, 0x72, 0xb1, 0xa2, 0xb4, 0x91, 0xd1, 0xd8, 0xb3, 0x3a, 0x00,
0x99, 0x9a, 0x52, 0x0b, 0xd3, 0xee, 0xe1, 0xc3, 0xb1, 0x05, 0x3b, 0x50, 0x69, 0xe7, 0x88, 0x60,
0x5f, 0x98, 0xf0, 0x03, 0xfa, 0x00, 0xe6, 0x59, 0xfe, 0xb9, 0x78, 0x51, 0xda, 0x48, 0x6f, 0xe5,
0x4a, 0xa1, 0x46, 0xf1, 0xfa, 0x4a, 0x4d, 0xaa, 0xaf, 0xc8, 0xcf, 0x5e, 0xac, 0xcf, 0x69, 0x1c,
0xac, 0x5a, 0x90, 0xa8, 0x58, 0x4e, 0xf7, 0x71, 0x7d, 0x3b, 0x48, 0x44, 0x9a, 0x24, 0x82, 0x76,
0x61, 0xc9, 0x35, 0x3c, 0xa2, 0xfb, 0x98, 0xe8, 0x03, 0x56, 0x05, 0x0b, 0x9a, 0xde, 0x5a, 0x2f,
0x9d, 0x9d, 0x43, 0x29, 0x52, 0xac, 0x88, 0xa2, 0xb8, 0x61, 0xa1, 0xfa, 0x8f, 0x0c, 0x0b, 0xa2,
0x19, 0x9f, 0x42, 0x42, 0xb4, 0x95, 0x05, 0x4c, 0x6f, 0xad, 0x85, 0x3d, 0x0a, 0x55, 0xa9, 0xea,
0xd8, 0x3e, 0xb6, 0xfd, 0x91, 0x2f, 0xfc, 0x8d, 0x6d, 0xd0, 0x3b, 0x90, 0xec, 0x0e, 0x0c, 0xd3,
0xd6, 0xcd, 0x1e, 0xcb, 0x28, 0x55, 0x49, 0x9f, 0xbe, 0x58, 0x4f, 0x54, 0xa9, 0xac, 0xbe, 0xad,
0x25, 0x98, 0xb2, 0xde, 0x43, 0x97, 0x61, 0x61, 0x80, 0xcd, 0xfe, 0x80, 0xb0, 0xb6, 0xc4, 0x35,
0x71, 0x42, 0x1f, 0x83, 0x4c, 0x09, 0x91, 0x93, 0x59, 0xec, 0x7c, 0x89, 0xb3, 0xa5, 0x34, 0x66,
0x4b, 0xa9, 0x3d, 0x66, 0x4b, 0x25, 0x49, 0x03, 0x3f, 0xfd, 0x6b, 0x5d, 0xd2, 0x98, 0x05, 0xaa,
0x82, 0x62, 0x19, 0x3e, 0xd1, 0x3b, 0xb4, 0x6d, 0x34, 0xfc, 0x3c, 0x73, 0xb1, 0x3a, 0xdd, 0x10,
0xd1, 0x58, 0x91, 0x7a, 0x9a, 0x5a, 0x71, 0x51, 0x0f, 0x6d, 0x40, 0x96, 0x39, 0xe9, 0x3a, 0xc3,
0xa1, 0x49, 0x74, 0xd6, 0xf7, 0x05, 0xd6, 0xf7, 0x45, 0x2a, 0xaf, 0x32, 0xf1, 0x7d, 0x3a, 0x81,
0xab, 0x90, 0xea, 0x19, 0xc4, 0xe0, 0x90, 0x04, 0x83, 0x24, 0xa9, 0x80, 0x29, 0x6f, 0xc0, 0x52,
0xc0, 0x3a, 0x9f, 0x43, 0x92, 0xdc, 0xcb, 0x44, 0xcc, 0x80, 0xb7, 0x61, 0xc5, 0xc6, 0x87, 0x44,
0x3f, 0x8b, 0x4e, 0x31, 0x34, 0xa2, 0xba, 0x47, 0x51, 0x8b, 0xeb, 0xb0, 0xd8, 0x1d, 0x37, 0x9f,
0x63, 0x81, 0x61, 0x95, 0x40, 0xca, 0x60, 0xab, 0x90, 0x34, 0x5c, 0x97, 0x03, 0xd2, 0x0c, 0x90,
0x30, 0x5c, 0x97, 0xa9, 0x6e, 0xc1, 0x32, 0xab, 0xd1, 0xc3, 0xfe, 0xc8, 0x22, 0xc2, 0x49, 0x86,
0x61, 0x96, 0xa8, 0x42, 0xe3, 0x72, 0x86, 0x7d, 0x1b, 0x14, 0x7c, 0x60, 0xf6, 0xb0, 0xdd, 0xc5,
0x1c, 0xa7, 0x30, 0x5c, 0x66, 0x2c, 0x64, 0xa0, 0x9b, 0x90, 0x75, 0x3d, 0xc7, 0x75, 0x7c, 0xec,
0xe9, 0x46, 0xaf, 0xe7, 0x61, 0xdf, 0xcf, 0x2d, 0x72, 0x7f, 0x63, 0x79, 0x99, 0x8b, 0xd5, 0x1c,
0xc8, 0xdb, 0x06, 0x31, 0x50, 0x16, 0xe2, 0xe4, 0xd0, 0xcf, 0x49, 0xc5, 0xf8, 0x46, 0x46, 0xa3,
0x8f, 0xea, 0x2f, 0x71, 0x90, 0x1f, 0x39, 0x04, 0xa3, 0x3b, 0x20, 0xd3, 0x31, 0x31, 0xf6, 0x2d,
0x9e, 0xc7, 0xe7, 0x96, 0xd9, 0xb7, 0x71, 0x6f, 0xd7, 0xef, 0xb7, 0x8f, 0x5c, 0xac, 0x31, 0x70,
0x88, 0x4e, 0xb1, 0x08, 0x9d, 0x56, 0x60, 0xde, 0x73, 0x46, 0x76, 0x8f, 0xb1, 0x6c, 0x5e, 0xe3,
0x07, 0x54, 0x83, 0x64, 0xc0, 0x12, 0xf9, 0x55, 0x2c, 0x59, 0xa2, 0x2c, 0xa1, 0x1c, 0x16, 0x02,
0x2d, 0xd1, 0x11, 0x64, 0xa9, 0x40, 0x2a, 0x58, 0x5e, 0x82, 0x6d, 0xaf, 0x47, 0xd8, 0x89, 0x19,
0x7a, 0x17, 0x96, 0x83, 0xd9, 0x07, 0xcd, 0xe3, 0x8c, 0xcb, 0x06, 0x0a, 0xd1, 0xbd, 0x08, 0xad,
0x74, 0xbe, 0x80, 0x12, 0xac, 0xae, 0x09, 0xad, 0xea, 0x6c, 0x13, 0x5d, 0x83, 0x94, 0x6f, 0xf6,
0x6d, 0x83, 0x8c, 0x3c, 0x2c, 0x98, 0x37, 0x11, 0xa0, 0xbb, 0xb0, 0x78, 0xe0, 0x10, 0xac, 0xe3,
0x43, 0x82, 0x6d, 0xf6, 0xa6, 0xa7, 0x66, 0xed, 0x0e, 0x3a, 0x91, 0xda, 0x18, 0xa6, 0x29, 0x07,
0xe1, 0xa3, 0x7a, 0x04, 0x4a, 0x44, 0x8f, 0x6e, 0x40, 0x96, 0x92, 0x8e, 0xbd, 0x17, 0xc4, 0xd1,
0x69, 0x44, 0xb1, 0xb5, 0x14, 0xc3, 0x75, 0xe9, 0xe0, 0xdb, 0x0e, 0x9d, 0x1e, 0xfa, 0x1c, 0xae,
0x05, 0x40, 0x1f, 0x5b, 0xfb, 0xba, 0x31, 0x22, 0x03, 0x6c, 0x13, 0xb3, 0x6b, 0x10, 0xd3, 0xee,
0x8b, 0x05, 0xba, 0x2a, 0x8c, 0x5a, 0xd8, 0xda, 0x2f, 0x47, 0x00, 0xea, 0x67, 0xf0, 0x56, 0x24,
0xb4, 0xf0, 0xfb, 0xba, 0x09, 0xa8, 0xbf, 0x49, 0xb0, 0xc0, 0x5f, 0xe6, 0x10, 0x75, 0xa4, 0xf3,
0xa9, 0x13, 0x9b, 0x45, 0x9d, 0xf8, 0xc5, 0xa9, 0x53, 0x06, 0x08, 0xe6, 0xe1, 0xe7, 0xe4, 0x62,
0x7c, 0x23, 0xbd, 0x75, 0x75, 0xda, 0x11, 0x4f, 0xb1, 0x65, 0xf6, 0xc5, 0xae, 0x0a, 0x19, 0xa9,
0x3f, 0xc7, 0x20, 0x15, 0xe8, 0x51, 0x19, 0x94, 0x71, 0x5e, 0xfa, 0xbe, 0x65, 0xf4, 0xc5, 0xeb,
0xb3, 0x36, 0x33, 0xb9, 0xbb, 0x96, 0xd1, 0xd7, 0xd2, 0x22, 0x1f, 0x7a, 0x38, 0x9f, 0x8a, 0xb1,
0x19, 0x54, 0x8c, 0x70, 0x3f, 0x7e, 0x31, 0xee, 0x47, 0x58, 0x2a, 0x9f, 0x65, 0xe9, 0xce, 0x14,
0x4b, 0xf9, 0x2b, 0x76, 0xfd, 0x15, 0x2c, 0xe5, 0x13, 0x3e, 0xcb, 0xd5, 0x5f, 0x63, 0x90, 0x6c,
0xb2, 0x65, 0x64, 0x58, 0xff, 0xc7, 0x8a, 0xb9, 0x0a, 0x29, 0xd7, 0xb1, 0x74, 0xae, 0x91, 0x99,
0x26, 0xe9, 0x3a, 0x96, 0x36, 0x45, 0xa2, 0xf9, 0x37, 0xb4, 0x7f, 0x16, 0xde, 0xc0, 0x0c, 0x12,
0x67, 0x66, 0xa0, 0x7a, 0x90, 0xe1, 0xad, 0x10, 0x97, 0x83, 0xdb, 0xb4, 0x07, 0xec, 0xb6, 0x21,
0x4d, 0x5f, 0x66, 0x78, 0xda, 0x1c, 0xa9, 0x09, 0x1c, 0xb5, 0xe0, 0xdf, 0x52, 0x71, 0x3f, 0xc9,
0xcd, 0x22, 0xb9, 0x26, 0x70, 0xea, 0xf7, 0x12, 0xc0, 0x0e, 0xed, 0x2c, 0xab, 0x97, 0x7e, 0xd6,
0x7d, 0x96, 0x82, 0x1e, 0x89, 0x5c, 0x98, 0x35, 0x34, 0x11, 0x3f, 0xe3, 0x87, 0xf3, 0xae, 0x82,
0x32, 0xa1, 0xb6, 0x8f, 0xc7, 0xc9, 0x9c, 0xe3, 0x24, 0xf8, 0xda, 0xb6, 0x30, 0xd1, 0x32, 0x07,
0xa1, 0x93, 0xfa, 0xbb, 0x04, 0x29, 0x96, 0xd3, 0x2e, 0x26, 0x46, 0x64, 0x86, 0xd2, 0xc5, 0x67,
0xb8, 0x06, 0xc0, 0xdd, 0xf8, 0xe6, 0x13, 0x2c, 0x98, 0x95, 0x62, 0x92, 0x96, 0xf9, 0x04, 0xa3,
0x0f, 0x83, 0x86, 0xc7, 0xff, 0xbb, 0xe1, 0x62, 0x41, 0x8c, 0xdb, 0x7e, 0x05, 0x12, 0xf6, 0x68,
0xa8, 0xd3, 0x6f, 0xac, 0xcc, 0xd9, 0x6a, 0x8f, 0x86, 0xed, 0x43, 0x5f, 0xfd, 0x06, 0x12, 0xed,
0x43, 0x76, 0xdf, 0xa4, 0x14, 0xf5, 0x1c, 0x47, 0x5c, 0x72, 0xf8, 0x96, 0x4c, 0x52, 0x01, 0xfb,
0xa6, 0x23, 0x90, 0xe9, 0x16, 0x1d, 0xdf, 0x7e, 0xe9, 0x33, 0x2a, 0xbd, 0xe6, 0x4d, 0x56, 0xdc,
0x61, 0x6f, 0xfd, 0x21, 0x41, 0x3a, 0xb4, 0x6d, 0xd0, 0xfb, 0x70, 0xa9, 0xb2, 0xb3, 0x57, 0x7d,
0xa0, 0xd7, 0xb7, 0xf5, 0xbb, 0x3b, 0xe5, 0x7b, 0xfa, 0xc3, 0xc6, 0x83, 0xc6, 0xde, 0x97, 0x8d,
0xec, 0x5c, 0xfe, 0xf2, 0xf1, 0x49, 0x11, 0x85, 0xb0, 0x0f, 0xed, 0xc7, 0xb6, 0xf3, 0xad, 0x8d,
0x36, 0x61, 0x25, 0x6a, 0x52, 0xae, 0xb4, 0x6a, 0x8d, 0x76, 0x56, 0xca, 0x5f, 0x3a, 0x3e, 0x29,
0x2e, 0x87, 0x2c, 0xca, 0x1d, 0x1f, 0xdb, 0x64, 0xda, 0xa0, 0xba, 0xb7, 0xbb, 0x5b, 0x6f, 0x67,
0x63, 0x53, 0x06, 0x62, 0xfd, 0xdf, 0x84, 0xe5, 0xa8, 0x41, 0xa3, 0xbe, 0x93, 0x8d, 0xe7, 0xd1,
0xf1, 0x49, 0x71, 0x31, 0x84, 0x6e, 0x98, 0x56, 0x3e, 0xf9, 0xdd, 0x0f, 0x85, 0xb9, 0x9f, 0x7e,
0x2c, 0x48, 0xb4, 0x32, 0x25, 0xb2, 0x23, 0xd0, 0x7b, 0x70, 0xa5, 0x55, 0xbf, 0xd7, 0xa8, 0x6d,
0xeb, 0xbb, 0xad, 0x7b, 0x7a, 0xfb, 0xab, 0x66, 0x2d, 0x54, 0xdd, 0xd2, 0xf1, 0x49, 0x31, 0x2d,
0x4a, 0x9a, 0x85, 0x6e, 0x6a, 0xb5, 0x47, 0x7b, 0xed, 0x5a, 0x56, 0xe2, 0xe8, 0xa6, 0x87, 0xe9,
0x02, 0x63, 0xe8, 0xdb, 0xb0, 0x7a, 0x0e, 0x3a, 0x28, 0x6c, 0xf9, 0xf8, 0xa4, 0xa8, 0x34, 0x3d,
0xcc, 0xdf, 0x1f, 0x66, 0x51, 0x82, 0xdc, 0xb4, 0xc5, 0x5e, 0x73, 0xaf, 0x55, 0xde, 0xc9, 0x16,
0xf3, 0xd9, 0xe3, 0x93, 0x62, 0x66, 0xbc, 0x0c, 0x29, 0x7e, 0x52, 0x59, 0xe5, 0x8b, 0x67, 0xa7,
0x05, 0xe9, 0xf9, 0x69, 0x41, 0xfa, 0xfb, 0xb4, 0x20, 0x3d, 0x7d, 0x59, 0x98, 0x7b, 0xfe, 0xb2,
0x30, 0xf7, 0xe7, 0xcb, 0xc2, 0xdc, 0xd7, 0x1f, 0xf5, 0x4d, 0x32, 0x18, 0x75, 0x4a, 0x5d, 0x67,
0xb8, 0x19, 0xfe, 0x8f, 0x35, 0x79, 0xe4, 0xff, 0xf5, 0xce, 0xfe, 0xff, 0xea, 0x2c, 0x30, 0xf9,
0x9d, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x38, 0xfc, 0x14, 0xb1, 0x40, 0x0e, 0x00, 0x00,
// 1341 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0xcf, 0x73, 0xdb, 0xc4,
0x17, 0x8f, 0x62, 0x25, 0xb6, 0x9f, 0xed, 0xc4, 0xd9, 0x6f, 0xda, 0xba, 0x6e, 0xe3, 0x68, 0xfc,
0x1d, 0x20, 0x2d, 0x8c, 0x52, 0x52, 0x86, 0x1f, 0x07, 0x0e, 0xb6, 0x93, 0xb6, 0x9e, 0x26, 0x8e,
0x91, 0xdd, 0x32, 0x70, 0xd1, 0xc8, 0xd6, 0xd6, 0x16, 0x95, 0x25, 0x8d, 0x76, 0x1d, 0x92, 0xfe,
0x05, 0x4c, 0x4e, 0x3d, 0x71, 0xcb, 0x09, 0x0e, 0xdc, 0x39, 0x70, 0x65, 0x38, 0xf5, 0xd8, 0x1b,
0x5c, 0x28, 0x4c, 0x3a, 0xc3, 0xdf, 0xc1, 0xec, 0x0f, 0xc9, 0x72, 0x9c, 0x40, 0xa7, 0xd3, 0xe1,
0xe2, 0xd1, 0xbe, 0xf7, 0x79, 0x6f, 0xdf, 0x8f, 0xcf, 0xee, 0x5b, 0xc3, 0x75, 0x8a, 0x3d, 0x1b,
0x87, 0x23, 0xc7, 0xa3, 0x9b, 0xf4, 0x28, 0xc0, 0x44, 0xfc, 0xea, 0x41, 0xe8, 0x53, 0x1f, 0x15,
0x27, 0x5a, 0x9d, 0xcb, 0xcb, 0xab, 0x03, 0x7f, 0xe0, 0x73, 0xe5, 0x26, 0xfb, 0x12, 0xb8, 0xf2,
0xfa, 0xc0, 0xf7, 0x07, 0x2e, 0xde, 0xe4, 0xab, 0xde, 0xf8, 0xd1, 0x26, 0x75, 0x46, 0x98, 0x50,
0x6b, 0x14, 0x48, 0xc0, 0x5a, 0x62, 0x9b, 0x7e, 0x78, 0x14, 0x50, 0x9f, 0x61, 0xfd, 0x47, 0x52,
0x5d, 0x49, 0xa8, 0x0f, 0x70, 0x48, 0x1c, 0xdf, 0x4b, 0xc6, 0x51, 0xd6, 0x66, 0xa2, 0x3c, 0xb0,
0x5c, 0xc7, 0xb6, 0xa8, 0x1f, 0x0a, 0x44, 0xf5, 0x13, 0x28, 0xb4, 0xad, 0x90, 0x76, 0x30, 0xbd,
0x87, 0x2d, 0x1b, 0x87, 0x68, 0x15, 0x16, 0xa8, 0x4f, 0x2d, 0xb7, 0xa4, 0x68, 0xca, 0x46, 0xc1,
0x10, 0x0b, 0x84, 0x40, 0x1d, 0x5a, 0x64, 0x58, 0x9a, 0xd7, 0x94, 0x8d, 0xbc, 0xc1, 0xbf, 0xab,
0x43, 0x50, 0x99, 0x29, 0xb3, 0x70, 0x3c, 0x1b, 0x1f, 0x46, 0x16, 0x7c, 0xc1, 0xa4, 0xbd, 0x23,
0x8a, 0x89, 0x34, 0x11, 0x0b, 0xf4, 0x01, 0x2c, 0xf0, 0xf8, 0x4b, 0x29, 0x4d, 0xd9, 0xc8, 0x6d,
0x95, 0xf4, 0x44, 0xa1, 0x44, 0x7e, 0x7a, 0x9b, 0xe9, 0xeb, 0xea, 0xb3, 0x17, 0xeb, 0x73, 0x86,
0x00, 0x57, 0x5d, 0x48, 0xd7, 0x5d, 0xbf, 0xff, 0xb8, 0xb9, 0x1d, 0x07, 0xa2, 0x4c, 0x02, 0x41,
0x7b, 0xb0, 0x1c, 0x58, 0x21, 0x35, 0x09, 0xa6, 0xe6, 0x90, 0x67, 0xc1, 0x37, 0xcd, 0x6d, 0xad,
0xeb, 0x67, 0xfb, 0xa0, 0x4f, 0x25, 0x2b, 0x77, 0x29, 0x04, 0x49, 0x61, 0xf5, 0x2f, 0x15, 0x16,
0x65, 0x31, 0x3e, 0x85, 0xb4, 0x2c, 0x2b, 0xdf, 0x30, 0xb7, 0xb5, 0x96, 0xf4, 0x28, 0x55, 0x7a,
0xc3, 0xf7, 0x08, 0xf6, 0xc8, 0x98, 0x48, 0x7f, 0x91, 0x0d, 0x7a, 0x1b, 0x32, 0xfd, 0xa1, 0xe5,
0x78, 0xa6, 0x63, 0xf3, 0x88, 0xb2, 0xf5, 0xdc, 0xe9, 0x8b, 0xf5, 0x74, 0x83, 0xc9, 0x9a, 0xdb,
0x46, 0x9a, 0x2b, 0x9b, 0x36, 0xba, 0x0c, 0x8b, 0x43, 0xec, 0x0c, 0x86, 0x94, 0x97, 0x25, 0x65,
0xc8, 0x15, 0xfa, 0x18, 0x54, 0x46, 0x88, 0x92, 0xca, 0xf7, 0x2e, 0xeb, 0x82, 0x2d, 0x7a, 0xc4,
0x16, 0xbd, 0x1b, 0xb1, 0xa5, 0x9e, 0x61, 0x1b, 0x3f, 0xfd, 0x63, 0x5d, 0x31, 0xb8, 0x05, 0x6a,
0x40, 0xc1, 0xb5, 0x08, 0x35, 0x7b, 0xac, 0x6c, 0x6c, 0xfb, 0x05, 0xee, 0xe2, 0xea, 0x6c, 0x41,
0x64, 0x61, 0x65, 0xe8, 0x39, 0x66, 0x25, 0x44, 0x36, 0xda, 0x80, 0x22, 0x77, 0xd2, 0xf7, 0x47,
0x23, 0x87, 0x9a, 0xbc, 0xee, 0x8b, 0xbc, 0xee, 0x4b, 0x4c, 0xde, 0xe0, 0xe2, 0x7b, 0xac, 0x03,
0xd7, 0x20, 0x6b, 0x5b, 0xd4, 0x12, 0x90, 0x34, 0x87, 0x64, 0x98, 0x80, 0x2b, 0xdf, 0x81, 0xe5,
0x98, 0x75, 0x44, 0x40, 0x32, 0xc2, 0xcb, 0x44, 0xcc, 0x81, 0xb7, 0x60, 0xd5, 0xc3, 0x87, 0xd4,
0x3c, 0x8b, 0xce, 0x72, 0x34, 0x62, 0xba, 0x87, 0xd3, 0x16, 0x6f, 0xc1, 0x52, 0x3f, 0x2a, 0xbe,
0xc0, 0x02, 0xc7, 0x16, 0x62, 0x29, 0x87, 0x5d, 0x85, 0x8c, 0x15, 0x04, 0x02, 0x90, 0xe3, 0x80,
0xb4, 0x15, 0x04, 0x5c, 0x75, 0x13, 0x56, 0x78, 0x8e, 0x21, 0x26, 0x63, 0x97, 0x4a, 0x27, 0x79,
0x8e, 0x59, 0x66, 0x0a, 0x43, 0xc8, 0x39, 0xf6, 0xff, 0x50, 0xc0, 0x07, 0x8e, 0x8d, 0xbd, 0x3e,
0x16, 0xb8, 0x02, 0xc7, 0xe5, 0x23, 0x21, 0x07, 0xdd, 0x80, 0x62, 0x10, 0xfa, 0x81, 0x4f, 0x70,
0x68, 0x5a, 0xb6, 0x1d, 0x62, 0x42, 0x4a, 0x4b, 0xc2, 0x5f, 0x24, 0xaf, 0x09, 0x71, 0xb5, 0x04,
0xea, 0xb6, 0x45, 0x2d, 0x54, 0x84, 0x14, 0x3d, 0x24, 0x25, 0x45, 0x4b, 0x6d, 0xe4, 0x0d, 0xf6,
0x59, 0xfd, 0x29, 0x05, 0xea, 0x43, 0x9f, 0x62, 0x74, 0x1b, 0x54, 0xd6, 0x26, 0xce, 0xbe, 0xa5,
0xf3, 0xf8, 0xdc, 0x71, 0x06, 0x1e, 0xb6, 0xf7, 0xc8, 0xa0, 0x7b, 0x14, 0x60, 0x83, 0x83, 0x13,
0x74, 0x9a, 0x9f, 0xa2, 0xd3, 0x2a, 0x2c, 0x84, 0xfe, 0xd8, 0xb3, 0x39, 0xcb, 0x16, 0x0c, 0xb1,
0x40, 0x3b, 0x90, 0x89, 0x59, 0xa2, 0xfe, 0x1b, 0x4b, 0x96, 0x19, 0x4b, 0x18, 0x87, 0xa5, 0xc0,
0x48, 0xf7, 0x24, 0x59, 0xea, 0x90, 0x8d, 0x2f, 0x2f, 0xc9, 0xb6, 0x57, 0x23, 0xec, 0xc4, 0x0c,
0xbd, 0x0b, 0x2b, 0x71, 0xef, 0xe3, 0xe2, 0x09, 0xc6, 0x15, 0x63, 0x85, 0xac, 0xde, 0x14, 0xad,
0x4c, 0x71, 0x01, 0xa5, 0x79, 0x5e, 0x13, 0x5a, 0x35, 0xf9, 0x4d, 0x74, 0x1d, 0xb2, 0xc4, 0x19,
0x78, 0x16, 0x1d, 0x87, 0x58, 0x32, 0x6f, 0x22, 0x60, 0x5a, 0x7c, 0x48, 0xb1, 0xc7, 0x0f, 0xb9,
0x60, 0xda, 0x44, 0x80, 0x36, 0xe1, 0x7f, 0xf1, 0xc2, 0x9c, 0x78, 0x11, 0x2c, 0x43, 0xb1, 0xaa,
0x13, 0x69, 0xaa, 0x3f, 0x2b, 0xb0, 0x28, 0x0e, 0x46, 0xa2, 0x0d, 0xca, 0xf9, 0x6d, 0x98, 0xbf,
0xa8, 0x0d, 0xa9, 0xd7, 0x6f, 0x43, 0x0d, 0x20, 0x0e, 0x93, 0x94, 0x54, 0x2d, 0xb5, 0x91, 0xdb,
0xba, 0x36, 0xeb, 0x48, 0x84, 0xd8, 0x71, 0x06, 0xf2, 0xdc, 0x27, 0x8c, 0xaa, 0xbf, 0x2b, 0x90,
0x8d, 0xf5, 0xa8, 0x06, 0x85, 0x28, 0x2e, 0xf3, 0x91, 0x6b, 0x0d, 0x24, 0x15, 0xd7, 0x2e, 0x0c,
0xee, 0x8e, 0x6b, 0x0d, 0x8c, 0x9c, 0x8c, 0x87, 0x2d, 0xce, 0x6f, 0xeb, 0xfc, 0x05, 0x6d, 0x9d,
0xe2, 0x51, 0xea, 0xf5, 0x78, 0x34, 0xd5, 0x71, 0xf5, 0x4c, 0xc7, 0xab, 0x3f, 0xce, 0x43, 0xa6,
0xcd, 0x8f, 0xa2, 0xe5, 0xfe, 0x17, 0x07, 0xec, 0x1a, 0x64, 0x03, 0xdf, 0x35, 0x85, 0x46, 0xe5,
0x9a, 0x4c, 0xe0, 0xbb, 0xc6, 0x4c, 0xdb, 0x17, 0xde, 0xd0, 0xe9, 0x5b, 0x7c, 0x03, 0x55, 0x4b,
0x9f, 0xad, 0x5a, 0x08, 0x79, 0x51, 0x0a, 0x39, 0x1a, 0x6f, 0xb1, 0x1a, 0xf0, 0x59, 0xab, 0xcc,
0x8e, 0x72, 0x11, 0xb6, 0x40, 0x1a, 0x12, 0xc7, 0x2c, 0xc4, 0x24, 0x91, 0xd3, 0xb9, 0x74, 0x11,
0x2d, 0x0d, 0x89, 0xab, 0x7e, 0xab, 0x00, 0xec, 0xb2, 0xca, 0xf2, 0x7c, 0xd9, 0x50, 0x23, 0x3c,
0x04, 0x73, 0x6a, 0xe7, 0xca, 0x45, 0x4d, 0x93, 0xfb, 0xe7, 0x49, 0x32, 0xee, 0x06, 0x14, 0x26,
0x64, 0x24, 0x38, 0x0a, 0xe6, 0x1c, 0x27, 0xf1, 0xac, 0xe9, 0x60, 0x6a, 0xe4, 0x0f, 0x12, 0xab,
0xea, 0x2f, 0x0a, 0x64, 0x79, 0x4c, 0x7b, 0x98, 0x5a, 0x53, 0x3d, 0x54, 0x5e, 0xbf, 0x87, 0x6b,
0x00, 0xc2, 0x0d, 0x71, 0x9e, 0x60, 0xc9, 0xac, 0x2c, 0x97, 0x74, 0x9c, 0x27, 0x18, 0x7d, 0x18,
0x17, 0x3c, 0xf5, 0xcf, 0x05, 0x97, 0x47, 0x3a, 0x2a, 0xfb, 0x15, 0x48, 0x7b, 0xe3, 0x91, 0xc9,
0x26, 0x8c, 0x2a, 0xd8, 0xea, 0x8d, 0x47, 0xdd, 0x43, 0x52, 0xfd, 0x0a, 0xd2, 0xdd, 0x43, 0xfe,
0xda, 0x62, 0x14, 0x0d, 0x7d, 0x5f, 0x8e, 0x78, 0xf1, 0xb4, 0xca, 0x30, 0x01, 0x9f, 0x68, 0x08,
0x54, 0x36, 0xcb, 0xa3, 0xb7, 0x1f, 0xfb, 0x46, 0xfa, 0x2b, 0xbe, 0xe3, 0xe4, 0x0b, 0xee, 0xe6,
0xaf, 0x0a, 0xe4, 0x12, 0xf7, 0x03, 0x7a, 0x1f, 0x2e, 0xd5, 0x77, 0xf7, 0x1b, 0xf7, 0xcd, 0xe6,
0xb6, 0x79, 0x67, 0xb7, 0x76, 0xd7, 0x7c, 0xd0, 0xba, 0xdf, 0xda, 0xff, 0xbc, 0x55, 0x9c, 0x2b,
0x5f, 0x3e, 0x3e, 0xd1, 0x50, 0x02, 0xfb, 0xc0, 0x7b, 0xec, 0xf9, 0x5f, 0xb3, 0xab, 0x78, 0x75,
0xda, 0xa4, 0x56, 0xef, 0xec, 0xb4, 0xba, 0x45, 0xa5, 0x7c, 0xe9, 0xf8, 0x44, 0x5b, 0x49, 0x58,
0xd4, 0x7a, 0x04, 0x7b, 0x74, 0xd6, 0xa0, 0xb1, 0xbf, 0xb7, 0xd7, 0xec, 0x16, 0xe7, 0x67, 0x0c,
0xe4, 0x85, 0x7d, 0x03, 0x56, 0xa6, 0x0d, 0x5a, 0xcd, 0xdd, 0x62, 0xaa, 0x8c, 0x8e, 0x4f, 0xb4,
0xa5, 0x04, 0xba, 0xe5, 0xb8, 0xe5, 0xcc, 0x37, 0xdf, 0x55, 0xe6, 0x7e, 0xf8, 0xbe, 0xa2, 0xb0,
0xcc, 0x0a, 0x53, 0x77, 0x04, 0x7a, 0x0f, 0xae, 0x74, 0x9a, 0x77, 0x5b, 0x3b, 0xdb, 0xe6, 0x5e,
0xe7, 0xae, 0xd9, 0xfd, 0xa2, 0xbd, 0x93, 0xc8, 0x6e, 0xf9, 0xf8, 0x44, 0xcb, 0xc9, 0x94, 0x2e,
0x42, 0xb7, 0x8d, 0x9d, 0x87, 0xfb, 0xdd, 0x9d, 0xa2, 0x22, 0xd0, 0xed, 0x10, 0x1f, 0xf8, 0x14,
0x73, 0xf4, 0x2d, 0xb8, 0x7a, 0x0e, 0x3a, 0x4e, 0x6c, 0xe5, 0xf8, 0x44, 0x2b, 0xb4, 0x43, 0x2c,
0xce, 0x0f, 0xb7, 0xd0, 0xa1, 0x34, 0x6b, 0xb1, 0xdf, 0xde, 0xef, 0xd4, 0x76, 0x8b, 0x5a, 0xb9,
0x78, 0x7c, 0xa2, 0xe5, 0xa3, 0xcb, 0x90, 0xe1, 0x27, 0x99, 0xd5, 0x3f, 0x7b, 0x76, 0x5a, 0x51,
0x9e, 0x9f, 0x56, 0x94, 0x3f, 0x4f, 0x2b, 0xca, 0xd3, 0x97, 0x95, 0xb9, 0xe7, 0x2f, 0x2b, 0x73,
0xbf, 0xbd, 0xac, 0xcc, 0x7d, 0xf9, 0xd1, 0xc0, 0xa1, 0xc3, 0x71, 0x4f, 0xef, 0xfb, 0xa3, 0xcd,
0xe4, 0x3f, 0x8c, 0xc9, 0xa7, 0xf8, 0xa7, 0x73, 0xf6, 0xdf, 0x47, 0x6f, 0x91, 0xcb, 0x6f, 0xff,
0x1d, 0x00, 0x00, 0xff, 0xff, 0xbb, 0xc0, 0x81, 0x37, 0x3e, 0x0d, 0x00, 0x00,
}
func (m *PartSetHeader) Marshal() (dAtA []byte, err error) {
@@ -1558,15 +1458,17 @@ func (m *Vote) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if m.VoteExtension != nil {
{
size, err := m.VoteExtension.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintTypes(dAtA, i, uint64(size))
}
if len(m.ExtensionSignature) > 0 {
i -= len(m.ExtensionSignature)
copy(dAtA[i:], m.ExtensionSignature)
i = encodeVarintTypes(dAtA, i, uint64(len(m.ExtensionSignature)))
i--
dAtA[i] = 0x52
}
if len(m.Extension) > 0 {
i -= len(m.Extension)
copy(dAtA[i:], m.Extension)
i = encodeVarintTypes(dAtA, i, uint64(len(m.Extension)))
i--
dAtA[i] = 0x4a
}
@@ -1589,12 +1491,12 @@ func (m *Vote) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i--
dAtA[i] = 0x32
}
n7, err7 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):])
if err7 != nil {
return 0, err7
n6, err6 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):])
if err6 != nil {
return 0, err6
}
i -= n7
i = encodeVarintTypes(dAtA, i, uint64(n7))
i -= n6
i = encodeVarintTypes(dAtA, i, uint64(n6))
i--
dAtA[i] = 0x2a
{
@@ -1625,73 +1527,6 @@ func (m *Vote) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
func (m *VoteExtension) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *VoteExtension) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *VoteExtension) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.AppDataSelfAuthenticating) > 0 {
i -= len(m.AppDataSelfAuthenticating)
copy(dAtA[i:], m.AppDataSelfAuthenticating)
i = encodeVarintTypes(dAtA, i, uint64(len(m.AppDataSelfAuthenticating)))
i--
dAtA[i] = 0x12
}
if len(m.AppDataToSign) > 0 {
i -= len(m.AppDataToSign)
copy(dAtA[i:], m.AppDataToSign)
i = encodeVarintTypes(dAtA, i, uint64(len(m.AppDataToSign)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *VoteExtensionToSign) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *VoteExtensionToSign) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *VoteExtensionToSign) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.AppDataToSign) > 0 {
i -= len(m.AppDataToSign)
copy(dAtA[i:], m.AppDataToSign)
i = encodeVarintTypes(dAtA, i, uint64(len(m.AppDataToSign)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *Commit) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@@ -1769,18 +1604,6 @@ func (m *CommitSig) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if m.VoteExtension != nil {
{
size, err := m.VoteExtension.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintTypes(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x2a
}
if len(m.Signature) > 0 {
i -= len(m.Signature)
copy(dAtA[i:], m.Signature)
@@ -1788,12 +1611,12 @@ func (m *CommitSig) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i--
dAtA[i] = 0x22
}
n11, err11 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):])
if err11 != nil {
return 0, err11
n9, err9 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):])
if err9 != nil {
return 0, err9
}
i -= n11
i = encodeVarintTypes(dAtA, i, uint64(n11))
i -= n9
i = encodeVarintTypes(dAtA, i, uint64(n9))
i--
dAtA[i] = 0x1a
if len(m.ValidatorAddress) > 0 {
@@ -1838,12 +1661,12 @@ func (m *Proposal) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i--
dAtA[i] = 0x3a
}
n12, err12 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):])
if err12 != nil {
return 0, err12
n10, err10 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):])
if err10 != nil {
return 0, err10
}
i -= n12
i = encodeVarintTypes(dAtA, i, uint64(n12))
i -= n10
i = encodeVarintTypes(dAtA, i, uint64(n10))
i--
dAtA[i] = 0x32
{
@@ -2238,37 +2061,11 @@ func (m *Vote) Size() (n int) {
if l > 0 {
n += 1 + l + sovTypes(uint64(l))
}
if m.VoteExtension != nil {
l = m.VoteExtension.Size()
n += 1 + l + sovTypes(uint64(l))
}
return n
}
func (m *VoteExtension) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.AppDataToSign)
l = len(m.Extension)
if l > 0 {
n += 1 + l + sovTypes(uint64(l))
}
l = len(m.AppDataSelfAuthenticating)
if l > 0 {
n += 1 + l + sovTypes(uint64(l))
}
return n
}
func (m *VoteExtensionToSign) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.AppDataToSign)
l = len(m.ExtensionSignature)
if l > 0 {
n += 1 + l + sovTypes(uint64(l))
}
@@ -2317,10 +2114,6 @@ func (m *CommitSig) Size() (n int) {
if l > 0 {
n += 1 + l + sovTypes(uint64(l))
}
if m.VoteExtension != nil {
l = m.VoteExtension.Size()
n += 1 + l + sovTypes(uint64(l))
}
return n
}
@@ -3618,93 +3411,7 @@ func (m *Vote) Unmarshal(dAtA []byte) error {
iNdEx = postIndex
case 9:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field VoteExtension", 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.VoteExtension == nil {
m.VoteExtension = &VoteExtension{}
}
if err := m.VoteExtension.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipTypes(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthTypes
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *VoteExtension) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: VoteExtension: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: VoteExtension: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field AppDataToSign", wireType)
return fmt.Errorf("proto: wrong wireType = %d for field Extension", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
@@ -3731,14 +3438,14 @@ func (m *VoteExtension) Unmarshal(dAtA []byte) error {
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.AppDataToSign = append(m.AppDataToSign[:0], dAtA[iNdEx:postIndex]...)
if m.AppDataToSign == nil {
m.AppDataToSign = []byte{}
m.Extension = append(m.Extension[:0], dAtA[iNdEx:postIndex]...)
if m.Extension == nil {
m.Extension = []byte{}
}
iNdEx = postIndex
case 2:
case 10:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field AppDataSelfAuthenticating", wireType)
return fmt.Errorf("proto: wrong wireType = %d for field ExtensionSignature", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
@@ -3765,93 +3472,9 @@ func (m *VoteExtension) Unmarshal(dAtA []byte) error {
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.AppDataSelfAuthenticating = append(m.AppDataSelfAuthenticating[:0], dAtA[iNdEx:postIndex]...)
if m.AppDataSelfAuthenticating == nil {
m.AppDataSelfAuthenticating = []byte{}
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipTypes(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthTypes
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *VoteExtensionToSign) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: VoteExtensionToSign: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: VoteExtensionToSign: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field AppDataToSign", 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.AppDataToSign = append(m.AppDataToSign[:0], dAtA[iNdEx:postIndex]...)
if m.AppDataToSign == nil {
m.AppDataToSign = []byte{}
m.ExtensionSignature = append(m.ExtensionSignature[:0], dAtA[iNdEx:postIndex]...)
if m.ExtensionSignature == nil {
m.ExtensionSignature = []byte{}
}
iNdEx = postIndex
default:
@@ -4179,42 +3802,6 @@ func (m *CommitSig) Unmarshal(dAtA []byte) error {
m.Signature = []byte{}
}
iNdEx = postIndex
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field VoteExtension", 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.VoteExtension == nil {
m.VoteExtension = &VoteExtensionToSign{}
}
if err := m.VoteExtension.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipTypes(dAtA[iNdEx:])
+9 -1
View File
@@ -112,7 +112,15 @@ message Vote {
[(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
bytes validator_address = 6;
int32 validator_index = 7;
bytes signature = 8;
// Vote signature by the validator if they participated in consensus for the
// associated block.
bytes signature = 8;
// Vote extension provided by the application. Only valid for precommit
// messages.
bytes extension = 9;
// Vote extension signature by the validator if they participated in
// consensus for the associated block.
bytes extension_signature = 10;
}
// Commit contains the evidence that a block was committed by a set of
+1 -2
View File
@@ -189,6 +189,5 @@ type MissedItemsError struct {
// Error satisfies the error interface.
func (e *MissedItemsError) Error() string {
return fmt.Sprintf("missed events matching %q between %q and %q",
e.Query, e.NewestSeen, e.OldestPresent)
return fmt.Sprintf("missed events matching %q between %q and %q", e.Query, e.NewestSeen, e.OldestPresent)
}
+14 -69
View File
@@ -207,19 +207,11 @@ func (c *baseRPCClient) ABCIInfo(ctx context.Context) (*coretypes.ResultABCIInfo
return result, nil
}
func (c *baseRPCClient) ABCIQuery(
ctx context.Context,
path string,
data bytes.HexBytes,
) (*coretypes.ResultABCIQuery, error) {
func (c *baseRPCClient) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*coretypes.ResultABCIQuery, error) {
return c.ABCIQueryWithOptions(ctx, path, data, rpcclient.DefaultABCIQueryOptions)
}
func (c *baseRPCClient) ABCIQueryWithOptions(
ctx context.Context,
path string,
data bytes.HexBytes,
opts rpcclient.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error) {
func (c *baseRPCClient) ABCIQueryWithOptions(ctx context.Context, path string, data bytes.HexBytes, opts rpcclient.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error) {
result := new(coretypes.ResultABCIQuery)
if err := c.caller.Call(ctx, "abci_query", abciQueryArgs{
Path: path,
@@ -232,10 +224,7 @@ func (c *baseRPCClient) ABCIQueryWithOptions(
return result, nil
}
func (c *baseRPCClient) BroadcastTxCommit(
ctx context.Context,
tx types.Tx,
) (*coretypes.ResultBroadcastTxCommit, error) {
func (c *baseRPCClient) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error) {
result := new(coretypes.ResultBroadcastTxCommit)
if err := c.caller.Call(ctx, "broadcast_tx_commit", txArgs{Tx: tx}, result); err != nil {
return nil, err
@@ -243,25 +232,15 @@ func (c *baseRPCClient) BroadcastTxCommit(
return result, nil
}
func (c *baseRPCClient) BroadcastTxAsync(
ctx context.Context,
tx types.Tx,
) (*coretypes.ResultBroadcastTx, error) {
func (c *baseRPCClient) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) {
return c.broadcastTX(ctx, "broadcast_tx_async", tx)
}
func (c *baseRPCClient) BroadcastTxSync(
ctx context.Context,
tx types.Tx,
) (*coretypes.ResultBroadcastTx, error) {
func (c *baseRPCClient) BroadcastTxSync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) {
return c.broadcastTX(ctx, "broadcast_tx_sync", tx)
}
func (c *baseRPCClient) broadcastTX(
ctx context.Context,
route string,
tx types.Tx,
) (*coretypes.ResultBroadcastTx, error) {
func (c *baseRPCClient) broadcastTX(ctx context.Context, route string, tx types.Tx) (*coretypes.ResultBroadcastTx, error) {
result := new(coretypes.ResultBroadcastTx)
if err := c.caller.Call(ctx, route, txArgs{Tx: tx}, result); err != nil {
return nil, err
@@ -269,11 +248,7 @@ func (c *baseRPCClient) broadcastTX(
return result, nil
}
func (c *baseRPCClient) UnconfirmedTxs(
ctx context.Context,
page *int,
perPage *int,
) (*coretypes.ResultUnconfirmedTxs, error) {
func (c *baseRPCClient) UnconfirmedTxs(ctx context.Context, page *int, perPage *int) (*coretypes.ResultUnconfirmedTxs, error) {
result := new(coretypes.ResultUnconfirmedTxs)
if err := c.caller.Call(ctx, "unconfirmed_txs", unconfirmedArgs{Page: page, PerPage: perPage}, result); err != nil {
@@ -329,10 +304,7 @@ func (c *baseRPCClient) ConsensusState(ctx context.Context) (*coretypes.ResultCo
return result, nil
}
func (c *baseRPCClient) ConsensusParams(
ctx context.Context,
height *int64,
) (*coretypes.ResultConsensusParams, error) {
func (c *baseRPCClient) ConsensusParams(ctx context.Context, height *int64) (*coretypes.ResultConsensusParams, error) {
result := new(coretypes.ResultConsensusParams)
if err := c.caller.Call(ctx, "consensus_params", heightArgs{Height: height}, result); err != nil {
return nil, err
@@ -356,11 +328,7 @@ func (c *baseRPCClient) Health(ctx context.Context) (*coretypes.ResultHealth, er
return result, nil
}
func (c *baseRPCClient) BlockchainInfo(
ctx context.Context,
minHeight,
maxHeight int64,
) (*coretypes.ResultBlockchainInfo, error) {
func (c *baseRPCClient) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error) {
result := new(coretypes.ResultBlockchainInfo)
if err := c.caller.Call(ctx, "blockchain", blockchainInfoArgs{
MinHeight: minHeight,
@@ -403,10 +371,7 @@ func (c *baseRPCClient) BlockByHash(ctx context.Context, hash bytes.HexBytes) (*
return result, nil
}
func (c *baseRPCClient) BlockResults(
ctx context.Context,
height *int64,
) (*coretypes.ResultBlockResults, error) {
func (c *baseRPCClient) BlockResults(ctx context.Context, height *int64) (*coretypes.ResultBlockResults, error) {
result := new(coretypes.ResultBlockResults)
if err := c.caller.Call(ctx, "block_results", heightArgs{Height: height}, result); err != nil {
return nil, err
@@ -446,14 +411,7 @@ func (c *baseRPCClient) Tx(ctx context.Context, hash bytes.HexBytes, prove bool)
return result, nil
}
func (c *baseRPCClient) TxSearch(
ctx context.Context,
query string,
prove bool,
page,
perPage *int,
orderBy string,
) (*coretypes.ResultTxSearch, error) {
func (c *baseRPCClient) TxSearch(ctx context.Context, query string, prove bool, page, perPage *int, orderBy string) (*coretypes.ResultTxSearch, error) {
result := new(coretypes.ResultTxSearch)
if err := c.caller.Call(ctx, "tx_search", searchArgs{
Query: query,
@@ -468,12 +426,7 @@ func (c *baseRPCClient) TxSearch(
return result, nil
}
func (c *baseRPCClient) BlockSearch(
ctx context.Context,
query string,
page, perPage *int,
orderBy string,
) (*coretypes.ResultBlockSearch, error) {
func (c *baseRPCClient) BlockSearch(ctx context.Context, query string, page, perPage *int, orderBy string) (*coretypes.ResultBlockSearch, error) {
result := new(coretypes.ResultBlockSearch)
if err := c.caller.Call(ctx, "block_search", searchArgs{
Query: query,
@@ -487,12 +440,7 @@ func (c *baseRPCClient) BlockSearch(
return result, nil
}
func (c *baseRPCClient) Validators(
ctx context.Context,
height *int64,
page,
perPage *int,
) (*coretypes.ResultValidators, error) {
func (c *baseRPCClient) Validators(ctx context.Context, height *int64, page, perPage *int) (*coretypes.ResultValidators, error) {
result := new(coretypes.ResultValidators)
if err := c.caller.Call(ctx, "validators", validatorArgs{
Height: height,
@@ -504,10 +452,7 @@ func (c *baseRPCClient) Validators(
return result, nil
}
func (c *baseRPCClient) BroadcastEvidence(
ctx context.Context,
ev types.Evidence,
) (*coretypes.ResultBroadcastEvidence, error) {
func (c *baseRPCClient) BroadcastEvidence(ctx context.Context, ev types.Evidence) (*coretypes.ResultBroadcastEvidence, error) {
result := new(coretypes.ResultBroadcastEvidence)
if err := c.caller.Call(ctx, "broadcast_evidence", evidenceArgs{
Evidence: coretypes.Evidence{Value: ev},
+2 -2
View File
@@ -107,6 +107,7 @@ func (w *wsEvents) Unsubscribe(ctx context.Context, subscriber, query string) er
}
w.mtx.Lock()
defer w.mtx.Unlock()
info, ok := w.subscriptions[query]
if ok {
if info.id != "" {
@@ -114,7 +115,6 @@ func (w *wsEvents) Unsubscribe(ctx context.Context, subscriber, query string) er
}
delete(w.subscriptions, info.query)
}
w.mtx.Unlock()
return nil
}
@@ -129,8 +129,8 @@ func (w *wsEvents) UnsubscribeAll(ctx context.Context, subscriber string) error
}
w.mtx.Lock()
defer w.mtx.Unlock()
w.subscriptions = make(map[string]*wsSubscription)
w.mtx.Unlock()
return nil
}
+20 -32
View File
@@ -78,11 +78,7 @@ func (c *Local) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes)
return c.ABCIQueryWithOptions(ctx, path, data, rpcclient.DefaultABCIQueryOptions)
}
func (c *Local) ABCIQueryWithOptions(
ctx context.Context,
path string,
data bytes.HexBytes,
opts rpcclient.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error) {
func (c *Local) ABCIQueryWithOptions(ctx context.Context, path string, data bytes.HexBytes, opts rpcclient.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error) {
return c.env.ABCIQuery(ctx, path, data, opts.Height, opts.Prove)
}
@@ -189,23 +185,11 @@ func (c *Local) Tx(ctx context.Context, hash bytes.HexBytes, prove bool) (*coret
return c.env.Tx(ctx, hash, prove)
}
func (c *Local) TxSearch(
ctx context.Context,
queryString string,
prove bool,
page,
perPage *int,
orderBy string,
) (*coretypes.ResultTxSearch, error) {
func (c *Local) TxSearch(ctx context.Context, queryString string, prove bool, page, perPage *int, orderBy string) (*coretypes.ResultTxSearch, error) {
return c.env.TxSearch(ctx, queryString, prove, page, perPage, orderBy)
}
func (c *Local) BlockSearch(
ctx context.Context,
queryString string,
page, perPage *int,
orderBy string,
) (*coretypes.ResultBlockSearch, error) {
func (c *Local) BlockSearch(ctx context.Context, queryString string, page, perPage *int, orderBy string) (*coretypes.ResultBlockSearch, error) {
return c.env.BlockSearch(ctx, queryString, page, perPage, orderBy)
}
@@ -213,11 +197,7 @@ func (c *Local) BroadcastEvidence(ctx context.Context, ev types.Evidence) (*core
return c.env.BroadcastEvidence(ctx, coretypes.Evidence{Value: ev})
}
func (c *Local) Subscribe(
ctx context.Context,
subscriber,
queryString string,
capacity ...int) (out <-chan coretypes.ResultEvent, err error) {
func (c *Local) Subscribe(ctx context.Context, subscriber, queryString string, capacity ...int) (<-chan coretypes.ResultEvent, error) {
q, err := query.New(queryString)
if err != nil {
return nil, fmt.Errorf("failed to parse query: %w", err)
@@ -251,12 +231,7 @@ func (c *Local) Subscribe(
return outc, nil
}
func (c *Local) eventsRoutine(
ctx context.Context,
sub eventbus.Subscription,
subArgs pubsub.SubscribeArgs,
outc chan<- coretypes.ResultEvent,
) {
func (c *Local) eventsRoutine(ctx context.Context, sub eventbus.Subscription, subArgs pubsub.SubscribeArgs, outc chan<- coretypes.ResultEvent) {
qstr := subArgs.Query.String()
for {
msg, err := sub.Next(ctx)
@@ -271,17 +246,24 @@ func (c *Local) eventsRoutine(
}
continue
}
outc <- coretypes.ResultEvent{
select {
case outc <- coretypes.ResultEvent{
SubscriptionID: msg.SubscriptionID(),
Query: qstr,
Data: msg.Data(),
Events: msg.Events(),
}:
case <-ctx.Done():
return
}
}
}
// Try to resubscribe with exponential backoff.
func (c *Local) resubscribe(ctx context.Context, subArgs pubsub.SubscribeArgs) eventbus.Subscription {
timer := time.NewTimer(0)
defer timer.Stop()
attempts := 0
for {
if !c.IsRunning() {
@@ -294,7 +276,13 @@ func (c *Local) resubscribe(ctx context.Context, subArgs pubsub.SubscribeArgs) e
}
attempts++
time.Sleep((10 << uint(attempts)) * time.Millisecond) // 10ms -> 20ms -> 40ms
timer.Reset((10 << uint(attempts)) * time.Millisecond) // 10ms -> 20ms -> 40ms
select {
case <-timer.C:
continue
case <-ctx.Done():
return nil
}
}
}
+8 -19
View File
@@ -46,13 +46,7 @@ func DefaultConfig() *Config {
// Serve creates a http.Server and calls Serve with the given listener. It
// wraps handler to recover panics and limit the request body size.
func Serve(
ctx context.Context,
listener net.Listener,
handler http.Handler,
logger log.Logger,
config *Config,
) error {
func Serve(ctx context.Context, listener net.Listener, handler http.Handler, logger log.Logger, config *Config) error {
logger.Info(fmt.Sprintf("Starting RPC HTTP server on %s", listener.Addr()))
h := recoverAndLogHandler(MaxBytesHandler(handler, config.MaxBodyBytes), logger)
s := &http.Server{
@@ -83,19 +77,14 @@ func Serve(
// Serve creates a http.Server and calls ServeTLS with the given listener,
// certFile and keyFile. It wraps handler to recover panics and limit the
// request body size.
func ServeTLS(
ctx context.Context,
listener net.Listener,
handler http.Handler,
certFile, keyFile string,
logger log.Logger,
config *Config,
) error {
logger.Info(fmt.Sprintf("Starting RPC HTTPS server on %s (cert: %q, key: %q)",
listener.Addr(), certFile, keyFile))
h := recoverAndLogHandler(MaxBytesHandler(handler, config.MaxBodyBytes), logger)
func ServeTLS(ctx context.Context, listener net.Listener, handler http.Handler, certFile, keyFile string, logger log.Logger, config *Config) error {
logger.Info("Starting RPC HTTPS server",
"listenterAddr", listener.Addr(),
"certFile", certFile,
"keyFile", keyFile)
s := &http.Server{
Handler: h,
Handler: recoverAndLogHandler(MaxBytesHandler(handler, config.MaxBodyBytes), logger),
ReadTimeout: config.ReadTimeout,
WriteTimeout: config.WriteTimeout,
MaxHeaderBytes: config.MaxHeaderBytes,
+2 -11
View File
@@ -36,11 +36,7 @@ type WebsocketManager struct {
// NewWebsocketManager returns a new WebsocketManager that passes a map of
// functions, connection options and logger to new WS connections.
func NewWebsocketManager(
logger log.Logger,
funcMap map[string]*RPCFunc,
wsConnOptions ...func(*wsConnection),
) *WebsocketManager {
func NewWebsocketManager(logger log.Logger, funcMap map[string]*RPCFunc, wsConnOptions ...func(*wsConnection)) *WebsocketManager {
return &WebsocketManager{
funcMap: funcMap,
Upgrader: websocket.Upgrader{
@@ -137,12 +133,7 @@ type wsConnection struct {
// description of how to configure ping period and pong wait time. NOTE: if the
// write buffer is full, pongs may be dropped, which may cause clients to
// disconnect. see https://github.com/gorilla/websocket/issues/97
func newWSConnection(
baseConn *websocket.Conn,
funcMap map[string]*RPCFunc,
logger log.Logger,
options ...func(*wsConnection),
) *wsConnection {
func newWSConnection(baseConn *websocket.Conn, funcMap map[string]*RPCFunc, logger log.Logger, options ...func(*wsConnection)) *wsConnection {
wsc := &wsConnection{
Logger: logger,
remoteAddr: baseConn.RemoteAddr().String(),
+2 -2
View File
@@ -12,9 +12,9 @@ cp ./proto/tendermint/types/types.proto.intermediate ./proto/tendermint/types/ty
MODNAME="$(go list -m)"
find ./proto/tendermint -name '*.proto' -not -path "./proto/tendermint/abci/types.proto" \
-exec sh ./scripts/protopackage.sh {} "$MODNAME" ';'
-exec ./scripts/protopackage.sh {} "$MODNAME" ';'
sh ./scripts/protopackage.sh ./proto/tendermint/abci/types.proto $MODNAME "abci/types"
./scripts/protopackage.sh ./proto/tendermint/abci/types.proto $MODNAME "abci/types"
make proto-gen
+1
View File
@@ -25,6 +25,7 @@ func TestGuessConfigVersion(t *testing.T) {
path, want string
}{
{"testdata/non-config.toml", ""},
{"testdata/v30-config.toml", ""},
{"testdata/v31-config.toml", ""},
{"testdata/v32-config.toml", "v0.32"},
{"testdata/v33-config.toml", "v0.33"},
+7
View File
@@ -0,0 +1,7 @@
-M consensus.blocktime-iota
+M mempool.max-txs-bytes
+M rpc.max-subscription-clients
+M rpc.max-subscriptions-per-client
+M rpc.timeout-broadcast-tx-commit
+M rpc.tls-cert-file
+M rpc.tls-key-file
+252
View File
@@ -0,0 +1,252 @@
# This is a TOML config file.
# For more information, see https://github.com/toml-lang/toml
##### main base config options #####
# TCP or UNIX socket address of the ABCI application,
# or the name of an ABCI application compiled in with the Tendermint binary
proxy_app = "tcp://127.0.0.1:26658"
# A custom human readable name for this node
moniker = "localhost"
# If this node is many blocks behind the tip of the chain, FastSync
# allows them to catchup quickly by downloading blocks in parallel
# and verifying their commits
fast_sync = true
# Database backend: leveldb | memdb | cleveldb
db_backend = "leveldb"
# Database directory
db_dir = "data"
# Output level for logging, including package level options
log_level = "main:info,state:info,*:error"
# Output format: 'plain' (colored text) or 'json'
log_format = "plain"
##### additional base config options #####
# Path to the JSON file containing the initial validator set and other meta data
genesis_file = "config/genesis.json"
# Path to the JSON file containing the private key to use as a validator in the consensus protocol
priv_validator_key_file = "config/priv_validator_key.json"
# Path to the JSON file containing the last sign state of a validator
priv_validator_state_file = "data/priv_validator_state.json"
# TCP or UNIX socket address for Tendermint to listen on for
# connections from an external PrivValidator process
priv_validator_laddr = ""
# Path to the JSON file containing the private key to use for node authentication in the p2p protocol
node_key_file = "config/node_key.json"
# Mechanism to connect to the ABCI application: socket | grpc
abci = "socket"
# TCP or UNIX socket address for the profiling server to listen on
prof_laddr = ""
# If true, query the ABCI app on connecting to a new peer
# so the app can decide if we should keep the connection or not
filter_peers = false
##### advanced configuration options #####
##### rpc server configuration options #####
[rpc]
# TCP or UNIX socket address for the RPC server to listen on
laddr = "tcp://0.0.0.0:26657"
# A list of origins a cross-domain request can be executed from
# Default value '[]' disables cors support
# Use '["*"]' to allow any origin
cors_allowed_origins = []
# A list of methods the client is allowed to use with cross-domain requests
cors_allowed_methods = ["HEAD", "GET", "POST", ]
# A list of non simple headers the client is allowed to use with cross-domain requests
cors_allowed_headers = ["Origin", "Accept", "Content-Type", "X-Requested-With", "X-Server-Time", ]
# TCP or UNIX socket address for the gRPC server to listen on
# NOTE: This server only supports /broadcast_tx_commit
grpc_laddr = ""
# Maximum number of simultaneous connections.
# Does not include RPC (HTTP&WebSocket) connections. See max_open_connections
# If you want to accept a larger number than the default, make sure
# you increase your OS limits.
# 0 - unlimited.
# Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files}
# 1024 - 40 - 10 - 50 = 924 = ~900
grpc_max_open_connections = 900
# Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool
unsafe = false
# Maximum number of simultaneous connections (including WebSocket).
# Does not include gRPC connections. See grpc_max_open_connections
# If you want to accept a larger number than the default, make sure
# you increase your OS limits.
# 0 - unlimited.
# Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files}
# 1024 - 40 - 10 - 50 = 924 = ~900
max_open_connections = 900
##### peer to peer configuration options #####
[p2p]
# Address to listen for incoming connections
laddr = "tcp://0.0.0.0:26656"
# Address to advertise to peers for them to dial
# If empty, will use the same port as the laddr,
# and will introspect on the listener or use UPnP
# to figure out the address.
external_address = ""
# Comma separated list of seed nodes to connect to
seeds = ""
# Comma separated list of nodes to keep persistent connections to
persistent_peers = ""
# UPNP port forwarding
upnp = false
# Path to address book
addr_book_file = "config/addrbook.json"
# Set true for strict address routability rules
# Set false for private or local networks
addr_book_strict = true
# Maximum number of inbound peers
max_num_inbound_peers = 40
# Maximum number of outbound peers to connect to, excluding persistent peers
max_num_outbound_peers = 10
# Time to wait before flushing messages out on the connection
flush_throttle_timeout = "100ms"
# Maximum size of a message packet payload, in bytes
max_packet_msg_payload_size = 1024
# Rate at which packets can be sent, in bytes/second
send_rate = 5120000
# Rate at which packets can be received, in bytes/second
recv_rate = 5120000
# Set true to enable the peer-exchange reactor
pex = true
# Seed mode, in which node constantly crawls the network and looks for
# peers. If another node asks it for addresses, it responds and disconnects.
#
# Does not work if the peer-exchange reactor is disabled.
seed_mode = false
# Comma separated list of peer IDs to keep private (will not be gossiped to other peers)
private_peer_ids = ""
# Toggle to disable guard against peers connecting from the same ip.
allow_duplicate_ip = false
# Peer connection configuration.
handshake_timeout = "20s"
dial_timeout = "3s"
##### mempool configuration options #####
[mempool]
recheck = true
broadcast = true
wal_dir = ""
# size of the mempool
size = 5000
# size of the cache (used to filter transactions we saw earlier)
cache_size = 10000
##### consensus configuration options #####
[consensus]
wal_file = "data/cs.wal/wal"
timeout_propose = "3s"
timeout_propose_delta = "500ms"
timeout_prevote = "1s"
timeout_prevote_delta = "500ms"
timeout_precommit = "1s"
timeout_precommit_delta = "500ms"
timeout_commit = "1s"
# Make progress as soon as we have all the precommits (as if TimeoutCommit = 0)
skip_timeout_commit = false
# EmptyBlocks mode and possible interval between empty blocks
create_empty_blocks = true
create_empty_blocks_interval = "0s"
# Reactor sleep duration parameters
peer_gossip_sleep_duration = "100ms"
peer_query_maj23_sleep_duration = "2s"
# Block time parameters. Corresponds to the minimum time increment between consecutive blocks.
blocktime_iota = "1s"
##### transactions indexer configuration options #####
[tx_index]
# What indexer to use for transactions
#
# Options:
# 1) "null"
# 2) "kv" (default) - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend).
indexer = "kv"
# Comma-separated list of tags to index (by default the only tag is "tx.hash")
#
# You can also index transactions by height by adding "tx.height" tag here.
#
# It's recommended to index only a subset of tags due to possible memory
# bloat. This is, of course, depends on the indexer's DB and the volume of
# transactions.
index_tags = ""
# When set to true, tells indexer to index all tags (predefined tags:
# "tx.hash", "tx.height" and all tags from DeliverTx responses).
#
# Note this may be not desirable (see the comment above). IndexTags has a
# precedence over IndexAllTags (i.e. when given both, IndexTags will be
# indexed).
index_all_tags = false
##### instrumentation configuration options #####
[instrumentation]
# When true, Prometheus metrics are served under /metrics on
# PrometheusListenAddr.
# Check out the documentation for the list of available metrics.
prometheus = false
# Address to listen for Prometheus collector(s) connections
prometheus_listen_addr = ":26660"
# Maximum number of simultaneous connections.
# If you want to accept a larger number than the default, make sure
# you increase your OS limits.
# 0 - unlimited.
max_open_connections = 3
# Instrumentation namespace
namespace = "tendermint"
+1 -1
View File
@@ -1,4 +1,4 @@
#!/usr/bin/sh
#!/bin/bash
set -eo pipefail
# This script appends the "option go_package" proto option to the file located at $FNAME.
+4 -4
View File
@@ -115,7 +115,7 @@ func getAllSeenCommits(ctx context.Context, db dbm.DB) ([]toMigrate, error) {
return scData, nil
}
func renameRecord(ctx context.Context, db dbm.DB, keep toMigrate) error {
func renameRecord(db dbm.DB, keep toMigrate) error {
wantKey := makeKeyFromPrefix(prefixSeenCommit)
if bytes.Equal(keep.key, wantKey) {
return nil // we already did this conversion
@@ -143,7 +143,7 @@ func renameRecord(ctx context.Context, db dbm.DB, keep toMigrate) error {
return cerr
}
func deleteRecords(ctx context.Context, db dbm.DB, scData []toMigrate) error {
func deleteRecords(db dbm.DB, scData []toMigrate) error {
// delete all the remaining stale values in a single batch
batch := db.NewBatch()
@@ -179,7 +179,7 @@ func Migrate(ctx context.Context, db dbm.DB) error {
// retain only the latest.
keep, remove := scData[0], scData[1:]
if err := renameRecord(ctx, db, keep); err != nil {
if err := renameRecord(db, keep); err != nil {
return fmt.Errorf("renaming seen commit record: %w", err)
}
@@ -189,7 +189,7 @@ func Migrate(ctx context.Context, db dbm.DB) error {
// Remove any older seen commits. Prior to v0.35, we kept these records for
// all heights, but v0.35 keeps only the latest.
if err := deleteRecords(ctx, db, remove); err != nil {
if err := deleteRecords(db, remove); err != nil {
return fmt.Errorf("writing data: %w", err)
}
+168 -3
View File
@@ -3,20 +3,29 @@ package app
import (
"bytes"
"encoding/base64"
"encoding/binary"
"errors"
"fmt"
"math/rand"
"path/filepath"
"sort"
"strconv"
"strings"
"sync"
"github.com/tendermint/tendermint/abci/example/code"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/tendermint/tendermint/version"
)
const (
voteExtensionKey string = "extensionSum"
voteExtensionMaxVal int64 = 128
)
// Application is an ABCI application for use by end-to-end tests. It is a
// simple key/value store for strings, storing data in memory and persisting
// to disk as JSON, taking state sync snapshots if requested.
@@ -215,10 +224,10 @@ func (app *Application) Commit() abci.ResponseCommit {
if err != nil {
panic(err)
}
app.logger.Info("Created state sync snapshot", "height", snapshot.Height)
app.logger.Info("created state sync snapshot", "height", snapshot.Height)
err = app.snapshots.Prune(maxSnapshotCount)
if err != nil {
app.logger.Error("Failed to prune snapshots", "err", err)
app.logger.Error("failed to prune snapshots", "err", err)
}
}
retainHeight := int64(0)
@@ -304,7 +313,74 @@ func (app *Application) ApplySnapshotChunk(req abci.RequestApplySnapshotChunk) a
return abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}
}
// PrepareProposal will take the given transactions and attempt to prepare a
// proposal from them when it's our turn to do so. In the process, vote
// extensions from the previous round of consensus, if present, will be used to
// construct a special transaction whose value is the sum of all of the vote
// extensions from the previous round.
//
// NB: Assumes that the supplied transactions do not exceed `req.MaxTxBytes`.
// If adding a special vote extension-generated transaction would cause the
// total number of transaction bytes to exceed `req.MaxTxBytes`, we will not
// append our special vote extension transaction.
func (app *Application) PrepareProposal(req abci.RequestPrepareProposal) abci.ResponsePrepareProposal {
var sum int64
var extCount int
for _, vote := range req.LocalLastCommit.Votes {
if !vote.SignedLastBlock || len(vote.VoteExtension) == 0 {
continue
}
extValue, err := parseVoteExtension(vote.VoteExtension)
// This should have been verified in VerifyVoteExtension
if err != nil {
panic(fmt.Errorf("failed to parse vote extension in PrepareProposal: %w", err))
}
valAddr := crypto.Address(vote.Validator.Address)
app.logger.Info("got vote extension value in PrepareProposal", "valAddr", valAddr, "value", extValue)
sum += extValue
extCount++
}
// We only generate our special transaction if we have vote extensions
if extCount > 0 {
var totalBytes int64
extTxPrefix := fmt.Sprintf("%s=", voteExtensionKey)
extTx := []byte(fmt.Sprintf("%s%d", extTxPrefix, sum))
app.logger.Info("preparing proposal with custom transaction from vote extensions", "tx", extTx)
// Our generated transaction takes precedence over any supplied
// transaction that attempts to modify the "extensionSum" value.
txRecords := make([]*abci.TxRecord, len(req.Txs)+1)
for i, tx := range req.Txs {
if strings.HasPrefix(string(tx), extTxPrefix) {
txRecords[i] = &abci.TxRecord{
Action: abci.TxRecord_REMOVED,
Tx: tx,
}
} else {
txRecords[i] = &abci.TxRecord{
Action: abci.TxRecord_UNMODIFIED,
Tx: tx,
}
totalBytes += int64(len(tx))
}
}
if totalBytes+int64(len(extTx)) < req.MaxTxBytes {
txRecords[len(req.Txs)] = &abci.TxRecord{
Action: abci.TxRecord_ADDED,
Tx: extTx,
}
} else {
app.logger.Info(
"too many txs to include special vote extension-generated tx",
"totalBytes", totalBytes,
"MaxTxBytes", req.MaxTxBytes,
"extTx", extTx,
"extTxLen", len(extTx),
)
}
return abci.ResponsePrepareProposal{
TxRecords: txRecords,
}
}
// None of the transactions are modified by this application.
trs := make([]*abci.TxRecord, 0, len(req.Txs))
var totalBytes int64
@@ -325,14 +401,87 @@ func (app *Application) PrepareProposal(req abci.RequestPrepareProposal) abci.Re
// It accepts any proposal that does not contain a malformed transaction.
func (app *Application) ProcessProposal(req abci.RequestProcessProposal) abci.ResponseProcessProposal {
for _, tx := range req.Txs {
_, _, err := parseTx(tx)
k, v, err := parseTx(tx)
if err != nil {
app.logger.Error("malformed transaction in ProcessProposal", "tx", tx, "err", err)
return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}
}
// Additional check for vote extension-related txs
if k == voteExtensionKey {
_, err := strconv.Atoi(v)
if err != nil {
app.logger.Error("malformed vote extension transaction", k, v, "err", err)
return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}
}
}
}
return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}
}
// ExtendVote will produce vote extensions in the form of random numbers to
// demonstrate vote extension nondeterminism.
//
// In the next block, if there are any vote extensions from the previous block,
// a new transaction will be proposed that updates a special value in the
// key/value store ("extensionSum") with the sum of all of the numbers collected
// from the vote extensions.
func (app *Application) ExtendVote(req abci.RequestExtendVote) abci.ResponseExtendVote {
// We ignore any requests for vote extensions that don't match our expected
// next height.
if req.Height != int64(app.state.Height)+1 {
app.logger.Error(
"got unexpected height in ExtendVote request",
"expectedHeight", app.state.Height+1,
"requestHeight", req.Height,
)
return abci.ResponseExtendVote{}
}
ext := make([]byte, binary.MaxVarintLen64)
// We don't care that these values are generated by a weak random number
// generator. It's just for test purposes.
// nolint:gosec // G404: Use of weak random number generator
num := rand.Int63n(voteExtensionMaxVal)
extLen := binary.PutVarint(ext, num)
app.logger.Info("generated vote extension", "num", num, "ext", fmt.Sprintf("%x", ext[:extLen]), "state.Height", app.state.Height)
return abci.ResponseExtendVote{
VoteExtension: ext[:extLen],
}
}
// VerifyVoteExtension simply validates vote extensions from other validators
// without doing anything about them. In this case, it just makes sure that the
// vote extension is a well-formed integer value.
func (app *Application) VerifyVoteExtension(req abci.RequestVerifyVoteExtension) abci.ResponseVerifyVoteExtension {
// We allow vote extensions to be optional
if len(req.VoteExtension) == 0 {
return abci.ResponseVerifyVoteExtension{
Status: abci.ResponseVerifyVoteExtension_ACCEPT,
}
}
if req.Height != int64(app.state.Height)+1 {
app.logger.Error(
"got unexpected height in VerifyVoteExtension request",
"expectedHeight", app.state.Height,
"requestHeight", req.Height,
)
return abci.ResponseVerifyVoteExtension{
Status: abci.ResponseVerifyVoteExtension_REJECT,
}
}
num, err := parseVoteExtension(req.VoteExtension)
if err != nil {
app.logger.Error("failed to verify vote extension", "req", req, "err", err)
return abci.ResponseVerifyVoteExtension{
Status: abci.ResponseVerifyVoteExtension_REJECT,
}
}
app.logger.Info("verified vote extension value", "req", req, "num", num)
return abci.ResponseVerifyVoteExtension{
Status: abci.ResponseVerifyVoteExtension_ACCEPT,
}
}
func (app *Application) Rollback() error {
app.mu.Lock()
defer app.mu.Unlock()
@@ -378,3 +527,19 @@ func parseTx(tx []byte) (string, string, error) {
}
return string(parts[0]), string(parts[1]), nil
}
// parseVoteExtension attempts to parse the given extension data into a positive
// integer value.
func parseVoteExtension(ext []byte) (int64, error) {
num, errVal := binary.Varint(ext)
if errVal == 0 {
return 0, errors.New("vote extension is too small to parse")
}
if errVal < 0 {
return 0, errors.New("vote extension value is too large")
}
if num >= voteExtensionMaxVal {
return 0, fmt.Errorf("vote extension value must be smaller than %d (was %d)", voteExtensionMaxVal, num)
}
return num, nil
}
+2 -2
View File
@@ -134,7 +134,7 @@ func NewCLI(logger log.Logger) *CLI {
if err = Wait(ctx, logger, cli.testnet, 5); err != nil { // wait for network to settle before tests
return err
}
if err := Test(logger, cli.testnet); err != nil {
if err := Test(cli.testnet); err != nil {
return err
}
return nil
@@ -259,7 +259,7 @@ func NewCLI(logger log.Logger) *CLI {
Use: "test",
Short: "Runs test cases against a running testnet",
RunE: func(cmd *cobra.Command, args []string) error {
return Test(logger, cli.testnet)
return Test(cli.testnet)
},
})
+1 -2
View File
@@ -3,12 +3,11 @@ package main
import (
"os"
"github.com/tendermint/tendermint/libs/log"
e2e "github.com/tendermint/tendermint/test/e2e/pkg"
)
// Test runs test cases under tests/
func Test(logger log.Logger, testnet *e2e.Testnet) error {
func Test(testnet *e2e.Testnet) error {
err := os.Setenv("E2E_MANIFEST", testnet.File)
if err != nil {
return err
+18 -1
View File
@@ -5,6 +5,7 @@ import (
"context"
"fmt"
"math/rand"
"strconv"
"testing"
"time"
@@ -45,9 +46,11 @@ func TestApp_Hash(t *testing.T) {
testNode(t, func(ctx context.Context, t *testing.T, node e2e.Node) {
client, err := node.Client()
require.NoError(t, err)
info, err := client.ABCIInfo(ctx)
require.NoError(t, err)
require.NotEmpty(t, info.Response.LastBlockAppHash, "expected app to return app hash")
// In next-block execution, the app hash is stored in the next block
blockHeight := info.Response.LastBlockHeight + 1
@@ -60,7 +63,6 @@ func TestApp_Hash(t *testing.T) {
block, err := client.Block(ctx, &blockHeight)
require.NoError(t, err)
require.Equal(t, blockHeight, block.Block.Height)
require.Equal(t,
fmt.Sprintf("%x", info.Response.LastBlockAppHash),
@@ -185,3 +187,18 @@ func TestApp_Tx(t *testing.T) {
}
}
func TestApp_VoteExtensions(t *testing.T) {
testNode(t, func(ctx context.Context, t *testing.T, node e2e.Node) {
client, err := node.Client()
require.NoError(t, err)
// This special value should have been created by way of vote extensions
resp, err := client.ABCIQuery(ctx, "", []byte("extensionSum"))
require.NoError(t, err)
extSum, err := strconv.Atoi(string(resp.Response.Value))
require.NoError(t, err)
require.GreaterOrEqual(t, extSum, 0)
})
}
-29
View File
@@ -1,29 +0,0 @@
#!/usr/bin/make -f
.PHONY: fuzz-mempool
fuzz-mempool:
cd mempool && \
rm -f *-fuzz.zip && \
go-fuzz-build && \
go-fuzz
.PHONY: fuzz-p2p-sc
fuzz-p2p-sc:
cd p2p/secretconnection && \
rm -f *-fuzz.zip && \
go run ./init-corpus/main.go && \
go-fuzz-build && \
go-fuzz
.PHONY: fuzz-rpc-server
fuzz-rpc-server:
cd rpc/jsonrpc/server && \
rm -f *-fuzz.zip && \
go-fuzz-build && \
go-fuzz
clean:
find . -name corpus -type d -exec rm -rf {} +;
find . -name crashers -type d -exec rm -rf {} +;
find . -name suppressions -type d -exec rm -rf {} +;
find . -name *\.zip -type f -delete
+6 -56
View File
@@ -5,68 +5,18 @@ Fuzzing for various packages in Tendermint using [go-fuzz](https://github.com/dv
Inputs:
- mempool `CheckTx` (using kvstore in-process ABCI app)
- p2p `Addrbook#AddAddress`
- p2p `pex.Reactor#Receive`
- p2p `SecretConnection#Read` and `SecretConnection#Write`
- rpc jsonrpc server
## Directory structure
```
| test
| |- corpus/
| |- crashers/
| |- init-corpus/
| |- suppressions/
| |- testdata/
| |- <testname>.go
```
`/corpus` directory contains corpus data. The idea is to help the fuzzier to
understand what bytes sequences are semantically valid (e.g. if we're testing
PNG decoder, then we would put black-white PNG into corpus directory; with
blockchain reactor - we would put blockchain messages into corpus).
`/init-corpus` (if present) contains a script for generating corpus data.
`/testdata` directory may contain an additional data (like `addrbook.json`).
Upon running the fuzzier, `/crashers` and `/suppressions` dirs will be created,
along with <testname>.zip archive. `/crashers` will show any inputs, which have
lead to panics (plus a trace). `/suppressions` will show any suppressed inputs.
## Running
```sh
make fuzz-mempool
make fuzz-p2p-addrbook
make fuzz-p2p-pex
make fuzz-p2p-sc
make fuzz-rpc-server
```
Each command will create corpus data (if needed), generate a fuzz archive and
call `go-fuzz` executable.
Then watch out for the respective outputs in the fuzzer output to announce new
crashers which can be found in the directory `crashers`.
For example if we find
The fuzz tests are in native Go fuzzing format. Use the `go`
tool to run them:
```sh
ls crashers/
61bde465f47c93254d64d643c3b2480e0a54666e
61bde465f47c93254d64d643c3b2480e0a54666e.output
61bde465f47c93254d64d643c3b2480e0a54666e.quoted
da39a3ee5e6b4b0d3255bfef95601890afd80709
da39a3ee5e6b4b0d3255bfef95601890afd80709.output
da39a3ee5e6b4b0d3255bfef95601890afd80709.quoted
go test -fuzz Mempool ./tests
go test -fuzz P2PSecretConnection ./tests
go test -fuzz RPCJSONRPCServer ./tests
```
the crashing bytes generated by the fuzzer will be in
`61bde465f47c93254d64d643c3b2480e0a54666e` the respective crash report in
`61bde465f47c93254d64d643c3b2480e0a54666e.output`
and the bug report can be created by retrieving the bytes in
`61bde465f47c93254d64d643c3b2480e0a54666e` and feeding those back into the
`Fuzz` function.
See [the Go Fuzzing introduction](https://go.dev/doc/fuzz/) for more information.
-34
View File
@@ -1,34 +0,0 @@
package mempool_test
import (
"io"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
mempool "github.com/tendermint/tendermint/test/fuzz/mempool"
)
const testdataCasesDir = "testdata/cases"
func TestMempoolTestdataCases(t *testing.T) {
entries, err := os.ReadDir(testdataCasesDir)
require.NoError(t, err)
for _, e := range entries {
entry := e
t.Run(entry.Name(), func(t *testing.T) {
defer func() {
r := recover()
require.Nilf(t, r, "testdata/cases test panic")
}()
f, err := os.Open(filepath.Join(testdataCasesDir, entry.Name()))
require.NoError(t, err)
input, err := io.ReadAll(f)
require.NoError(t, err)
mempool.Fuzz(input)
})
}
}
View File
+17 -5
View File
@@ -1,10 +1,22 @@
#!/bin/bash -eu
#!/bin/bash
set -euo pipefail
export FUZZ_ROOT="github.com/tendermint/tendermint"
(cd test/fuzz/p2p/secretconnection; go run ./init-corpus/main.go)
compile_go_fuzzer "$FUZZ_ROOT"/test/fuzz/p2p/secretconnection Fuzz fuzz_p2p_secretconnection fuzz
build_go_fuzzer() {
local function="$1"
local fuzzer="$2"
compile_go_fuzzer "$FUZZ_ROOT"/test/fuzz/mempool Fuzz fuzz_mempool fuzz
gotip run github.com/orijtech/otils/corpus2ossfuzz@latest -o "$OUT"/"$fuzzer"_seed_corpus.zip -corpus test/fuzz/tests/testdata/fuzz/"$function"
compile_native_go_fuzzer "$FUZZ_ROOT"/test/fuzz/tests "$function" "$fuzzer"
}
compile_go_fuzzer "$FUZZ_ROOT"/test/fuzz/rpc/jsonrpc/server Fuzz fuzz_rpc_jsonrpc_server fuzz
gotip get github.com/AdamKorcz/go-118-fuzz-build/utils
gotip get github.com/prometheus/common/expfmt@v0.32.1
build_go_fuzzer FuzzP2PSecretConnection fuzz_p2p_secretconnection
build_go_fuzzer FuzzMempool fuzz_mempool
build_go_fuzzer FuzzRPCJSONRPCServer fuzz_rpc_jsonrpc_server
@@ -1,34 +0,0 @@
package secretconnection_test
import (
"io"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/test/fuzz/p2p/secretconnection"
)
const testdataCasesDir = "testdata/cases"
func TestSecretConnectionTestdataCases(t *testing.T) {
entries, err := os.ReadDir(testdataCasesDir)
require.NoError(t, err)
for _, e := range entries {
entry := e
t.Run(entry.Name(), func(t *testing.T) {
defer func() {
r := recover()
require.Nilf(t, r, "testdata/cases test panic")
}()
f, err := os.Open(filepath.Join(testdataCasesDir, entry.Name()))
require.NoError(t, err)
input, err := io.ReadAll(f)
require.NoError(t, err)
secretconnection.Fuzz(input)
})
}
}
@@ -1,47 +0,0 @@
// nolint: gosec
package main
import (
"flag"
"fmt"
"log"
"os"
"path/filepath"
)
func main() {
baseDir := flag.String("base", ".", `where the "corpus" directory will live`)
flag.Parse()
initCorpus(*baseDir)
}
func initCorpus(baseDir string) {
log.SetFlags(0)
corpusDir := filepath.Join(baseDir, "corpus")
if err := os.MkdirAll(corpusDir, 0755); err != nil {
log.Fatal(err)
}
data := []string{
"dadc04c2-cfb1-4aa9-a92a-c0bf780ec8b6",
"",
" ",
" a ",
`{"a": 12, "tsp": 999, k: "blue"}`,
`9999.999`,
`""`,
`Tendermint fuzzing`,
}
for i, datum := range data {
filename := filepath.Join(corpusDir, fmt.Sprintf("%d", i))
if err := os.WriteFile(filename, []byte(datum), 0644); err != nil {
log.Fatalf("can't write %v to %q: %v", datum, filename, err)
}
log.Printf("wrote %q", filename)
}
}
-34
View File
@@ -1,34 +0,0 @@
package server_test
import (
"io"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/test/fuzz/rpc/jsonrpc/server"
)
const testdataCasesDir = "testdata/cases"
func TestServerTestdataCases(t *testing.T) {
entries, err := os.ReadDir(testdataCasesDir)
require.NoError(t, err)
for _, e := range entries {
entry := e
t.Run(entry.Name(), func(t *testing.T) {
defer func() {
r := recover()
require.Nilf(t, r, "testdata/cases test panic")
}()
f, err := os.Open(filepath.Join(testdataCasesDir, entry.Name()))
require.NoError(t, err)
input, err := io.ReadAll(f)
require.NoError(t, err)
server.Fuzz(input)
})
}
}
-65
View File
@@ -1,65 +0,0 @@
package server
import (
"bytes"
"context"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"github.com/tendermint/tendermint/libs/log"
rs "github.com/tendermint/tendermint/rpc/jsonrpc/server"
"github.com/tendermint/tendermint/rpc/jsonrpc/types"
)
var rpcFuncMap = map[string]*rs.RPCFunc{
"c": rs.NewRPCFunc(func(ctx context.Context, s string, i int) (string, error) {
return "foo", nil
}, "s", "i"),
}
var mux *http.ServeMux
func init() {
mux = http.NewServeMux()
rs.RegisterRPCFuncs(mux, rpcFuncMap, log.NewNopLogger())
}
func Fuzz(data []byte) int {
if len(data) == 0 {
return -1
}
req, _ := http.NewRequest("POST", "http://localhost/", bytes.NewReader(data))
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, req)
res := rec.Result()
blob, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if err := res.Body.Close(); err != nil {
panic(err)
}
if len(blob) == 0 {
return 1
}
if outputJSONIsSlice(blob) {
recv := []types.RPCResponse{}
if err := json.Unmarshal(blob, &recv); err != nil {
panic(err)
}
return 1
}
recv := &types.RPCResponse{}
if err := json.Unmarshal(blob, recv); err != nil {
panic(err)
}
return 1
}
func outputJSONIsSlice(input []byte) bool {
slice := []interface{}{}
return json.Unmarshal(input, &slice) == nil
}
@@ -1 +0,0 @@
[0]
View File

Some files were not shown because too many files have changed in this diff Show More