diff --git a/.circleci/config.yml b/.circleci/config.yml index e76499712..8d321e9e6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -147,7 +147,7 @@ jobs: for pkg in $(go list github.com/tendermint/tendermint/... | circleci tests split --split-by=timings); do id=$(basename "$pkg") - GOCACHE=off go test -v -timeout 5m -race -coverprofile=/tmp/workspace/profiles/$id.out -covermode=atomic "$pkg" | tee "/tmp/logs/$id-$RANDOM.log" + GOCACHE=off go test -timeout 5m -race -coverprofile=/tmp/workspace/profiles/$id.out -covermode=atomic "$pkg" | tee "/tmp/logs/$id-$RANDOM.log" done - persist_to_workspace: root: /tmp/workspace diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 5bb79e4f6..e85a6ed64 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -7,6 +7,7 @@ BREAKING CHANGES: - [tools] Removed `make ensure_deps` in favor of `make get_vendor_deps` - [p2p] Remove salsa and ripemd primitives, in favor of using chacha as a stream cipher, and hkdf - [abci] Changed time format from int64 to google.protobuf.Timestamp +- [abci] Changed Validators to LastCommitInfo in RequestBeginBlock FEATURES: - [tools] Added `make check_dep` @@ -19,7 +20,9 @@ IMPROVEMENTS: - only process one block at a time to avoid starving - [crypto] Switch hkdfchachapoly1305 to xchachapoly1305 - [common] bit array functions which take in another parameter are now thread safe +- [p2p] begin connecting to peers as soon a seed node provides them to you ([#2093](https://github.com/tendermint/tendermint/issues/2093)) BUG FIXES: +- [common] Safely handle cases where atomic write files already exist [#2109](https://github.com/tendermint/tendermint/issues/2109) - [privval] fix a deadline for accepting new connections in socket private validator. diff --git a/README.md b/README.md index 6268e0547..94d8d7f01 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ develop | [![CircleCI](https://circleci.com/gh/tendermint/tendermint/tree/deve Tendermint Core is Byzantine Fault Tolerant (BFT) middleware that takes a state transition machine - written in any programming language - and securely replicates it on many machines. -For protocol details, see [the specification](/docs/spec). +For protocol details, see [the specification](/docs/spec). For a consensus proof and detailed protocol analysis checkout our recent paper, "[The latest gossip on BFT consensus](https://arxiv.org/abs/1807.04938)". ## A Note on Production Readiness diff --git a/abci/README.md b/abci/README.md index 6de9f7069..493d862f0 100644 --- a/abci/README.md +++ b/abci/README.md @@ -29,7 +29,7 @@ The two guides to focus on are the `Application Development Guide` and `Using AB To compile the protobuf file, run: ``` -make protoc +cd $GOPATH/src/github.com/tendermint/tendermint/; make protoc_abci ``` See `protoc --help` and [the Protocol Buffers site](https://developers.google.com/protocol-buffers) diff --git a/abci/types/types.pb.go b/abci/types/types.pb.go index 9a2b511b2..ac71d91c8 100644 --- a/abci/types/types.pb.go +++ b/abci/types/types.pb.go @@ -59,7 +59,7 @@ func (m *Request) Reset() { *m = Request{} } func (m *Request) String() string { return proto.CompactTextString(m) } func (*Request) ProtoMessage() {} func (*Request) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{0} + return fileDescriptor_types_d8da2202f45d32c0, []int{0} } func (m *Request) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -481,7 +481,7 @@ func (m *RequestEcho) Reset() { *m = RequestEcho{} } func (m *RequestEcho) String() string { return proto.CompactTextString(m) } func (*RequestEcho) ProtoMessage() {} func (*RequestEcho) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{1} + return fileDescriptor_types_d8da2202f45d32c0, []int{1} } func (m *RequestEcho) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -527,7 +527,7 @@ func (m *RequestFlush) Reset() { *m = RequestFlush{} } func (m *RequestFlush) String() string { return proto.CompactTextString(m) } func (*RequestFlush) ProtoMessage() {} func (*RequestFlush) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{2} + return fileDescriptor_types_d8da2202f45d32c0, []int{2} } func (m *RequestFlush) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -567,7 +567,7 @@ func (m *RequestInfo) Reset() { *m = RequestInfo{} } func (m *RequestInfo) String() string { return proto.CompactTextString(m) } func (*RequestInfo) ProtoMessage() {} func (*RequestInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{3} + return fileDescriptor_types_d8da2202f45d32c0, []int{3} } func (m *RequestInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -616,7 +616,7 @@ func (m *RequestSetOption) Reset() { *m = RequestSetOption{} } func (m *RequestSetOption) String() string { return proto.CompactTextString(m) } func (*RequestSetOption) ProtoMessage() {} func (*RequestSetOption) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{4} + return fileDescriptor_types_d8da2202f45d32c0, []int{4} } func (m *RequestSetOption) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -674,7 +674,7 @@ func (m *RequestInitChain) Reset() { *m = RequestInitChain{} } func (m *RequestInitChain) String() string { return proto.CompactTextString(m) } func (*RequestInitChain) ProtoMessage() {} func (*RequestInitChain) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{5} + return fileDescriptor_types_d8da2202f45d32c0, []int{5} } func (m *RequestInitChain) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -752,7 +752,7 @@ func (m *RequestQuery) Reset() { *m = RequestQuery{} } func (m *RequestQuery) String() string { return proto.CompactTextString(m) } func (*RequestQuery) ProtoMessage() {} func (*RequestQuery) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{6} + return fileDescriptor_types_d8da2202f45d32c0, []int{6} } func (m *RequestQuery) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -809,21 +809,22 @@ func (m *RequestQuery) GetProve() bool { return false } +// NOTE: validators here have empty pubkeys. type RequestBeginBlock struct { - Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` - Header Header `protobuf:"bytes,2,opt,name=header" json:"header"` - Validators []SigningValidator `protobuf:"bytes,3,rep,name=validators" json:"validators"` - ByzantineValidators []Evidence `protobuf:"bytes,4,rep,name=byzantine_validators,json=byzantineValidators" json:"byzantine_validators"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` + Header Header `protobuf:"bytes,2,opt,name=header" json:"header"` + LastCommitInfo LastCommitInfo `protobuf:"bytes,3,opt,name=last_commit_info,json=lastCommitInfo" json:"last_commit_info"` + ByzantineValidators []Evidence `protobuf:"bytes,4,rep,name=byzantine_validators,json=byzantineValidators" json:"byzantine_validators"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *RequestBeginBlock) Reset() { *m = RequestBeginBlock{} } func (m *RequestBeginBlock) String() string { return proto.CompactTextString(m) } func (*RequestBeginBlock) ProtoMessage() {} func (*RequestBeginBlock) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{7} + return fileDescriptor_types_d8da2202f45d32c0, []int{7} } func (m *RequestBeginBlock) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -866,11 +867,11 @@ func (m *RequestBeginBlock) GetHeader() Header { return Header{} } -func (m *RequestBeginBlock) GetValidators() []SigningValidator { +func (m *RequestBeginBlock) GetLastCommitInfo() LastCommitInfo { if m != nil { - return m.Validators + return m.LastCommitInfo } - return nil + return LastCommitInfo{} } func (m *RequestBeginBlock) GetByzantineValidators() []Evidence { @@ -891,7 +892,7 @@ func (m *RequestCheckTx) Reset() { *m = RequestCheckTx{} } func (m *RequestCheckTx) String() string { return proto.CompactTextString(m) } func (*RequestCheckTx) ProtoMessage() {} func (*RequestCheckTx) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{8} + return fileDescriptor_types_d8da2202f45d32c0, []int{8} } func (m *RequestCheckTx) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -938,7 +939,7 @@ func (m *RequestDeliverTx) Reset() { *m = RequestDeliverTx{} } func (m *RequestDeliverTx) String() string { return proto.CompactTextString(m) } func (*RequestDeliverTx) ProtoMessage() {} func (*RequestDeliverTx) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{9} + return fileDescriptor_types_d8da2202f45d32c0, []int{9} } func (m *RequestDeliverTx) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -985,7 +986,7 @@ func (m *RequestEndBlock) Reset() { *m = RequestEndBlock{} } func (m *RequestEndBlock) String() string { return proto.CompactTextString(m) } func (*RequestEndBlock) ProtoMessage() {} func (*RequestEndBlock) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{10} + return fileDescriptor_types_d8da2202f45d32c0, []int{10} } func (m *RequestEndBlock) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1031,7 +1032,7 @@ func (m *RequestCommit) Reset() { *m = RequestCommit{} } func (m *RequestCommit) String() string { return proto.CompactTextString(m) } func (*RequestCommit) ProtoMessage() {} func (*RequestCommit) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{11} + return fileDescriptor_types_d8da2202f45d32c0, []int{11} } func (m *RequestCommit) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1084,7 +1085,7 @@ func (m *Response) Reset() { *m = Response{} } func (m *Response) String() string { return proto.CompactTextString(m) } func (*Response) ProtoMessage() {} func (*Response) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{12} + return fileDescriptor_types_d8da2202f45d32c0, []int{12} } func (m *Response) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1537,7 +1538,7 @@ func (m *ResponseException) Reset() { *m = ResponseException{} } func (m *ResponseException) String() string { return proto.CompactTextString(m) } func (*ResponseException) ProtoMessage() {} func (*ResponseException) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{13} + return fileDescriptor_types_d8da2202f45d32c0, []int{13} } func (m *ResponseException) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1584,7 +1585,7 @@ func (m *ResponseEcho) Reset() { *m = ResponseEcho{} } func (m *ResponseEcho) String() string { return proto.CompactTextString(m) } func (*ResponseEcho) ProtoMessage() {} func (*ResponseEcho) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{14} + return fileDescriptor_types_d8da2202f45d32c0, []int{14} } func (m *ResponseEcho) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1630,7 +1631,7 @@ func (m *ResponseFlush) Reset() { *m = ResponseFlush{} } func (m *ResponseFlush) String() string { return proto.CompactTextString(m) } func (*ResponseFlush) ProtoMessage() {} func (*ResponseFlush) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{15} + return fileDescriptor_types_d8da2202f45d32c0, []int{15} } func (m *ResponseFlush) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1673,7 +1674,7 @@ func (m *ResponseInfo) Reset() { *m = ResponseInfo{} } func (m *ResponseInfo) String() string { return proto.CompactTextString(m) } func (*ResponseInfo) ProtoMessage() {} func (*ResponseInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{16} + return fileDescriptor_types_d8da2202f45d32c0, []int{16} } func (m *ResponseInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1745,7 +1746,7 @@ func (m *ResponseSetOption) Reset() { *m = ResponseSetOption{} } func (m *ResponseSetOption) String() string { return proto.CompactTextString(m) } func (*ResponseSetOption) ProtoMessage() {} func (*ResponseSetOption) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{17} + return fileDescriptor_types_d8da2202f45d32c0, []int{17} } func (m *ResponseSetOption) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1807,7 +1808,7 @@ func (m *ResponseInitChain) Reset() { *m = ResponseInitChain{} } func (m *ResponseInitChain) String() string { return proto.CompactTextString(m) } func (*ResponseInitChain) ProtoMessage() {} func (*ResponseInitChain) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{18} + return fileDescriptor_types_d8da2202f45d32c0, []int{18} } func (m *ResponseInitChain) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1869,7 +1870,7 @@ func (m *ResponseQuery) Reset() { *m = ResponseQuery{} } func (m *ResponseQuery) String() string { return proto.CompactTextString(m) } func (*ResponseQuery) ProtoMessage() {} func (*ResponseQuery) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{19} + return fileDescriptor_types_d8da2202f45d32c0, []int{19} } func (m *ResponseQuery) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1965,7 +1966,7 @@ func (m *ResponseBeginBlock) Reset() { *m = ResponseBeginBlock{} } func (m *ResponseBeginBlock) String() string { return proto.CompactTextString(m) } func (*ResponseBeginBlock) ProtoMessage() {} func (*ResponseBeginBlock) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{20} + return fileDescriptor_types_d8da2202f45d32c0, []int{20} } func (m *ResponseBeginBlock) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2018,7 +2019,7 @@ func (m *ResponseCheckTx) Reset() { *m = ResponseCheckTx{} } func (m *ResponseCheckTx) String() string { return proto.CompactTextString(m) } func (*ResponseCheckTx) ProtoMessage() {} func (*ResponseCheckTx) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{21} + return fileDescriptor_types_d8da2202f45d32c0, []int{21} } func (m *ResponseCheckTx) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2113,7 +2114,7 @@ func (m *ResponseDeliverTx) Reset() { *m = ResponseDeliverTx{} } func (m *ResponseDeliverTx) String() string { return proto.CompactTextString(m) } func (*ResponseDeliverTx) ProtoMessage() {} func (*ResponseDeliverTx) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{22} + return fileDescriptor_types_d8da2202f45d32c0, []int{22} } func (m *ResponseDeliverTx) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2204,7 +2205,7 @@ func (m *ResponseEndBlock) Reset() { *m = ResponseEndBlock{} } func (m *ResponseEndBlock) String() string { return proto.CompactTextString(m) } func (*ResponseEndBlock) ProtoMessage() {} func (*ResponseEndBlock) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{23} + return fileDescriptor_types_d8da2202f45d32c0, []int{23} } func (m *ResponseEndBlock) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2266,7 +2267,7 @@ func (m *ResponseCommit) Reset() { *m = ResponseCommit{} } func (m *ResponseCommit) String() string { return proto.CompactTextString(m) } func (*ResponseCommit) ProtoMessage() {} func (*ResponseCommit) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{24} + return fileDescriptor_types_d8da2202f45d32c0, []int{24} } func (m *ResponseCommit) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2317,7 +2318,7 @@ func (m *ConsensusParams) Reset() { *m = ConsensusParams{} } func (m *ConsensusParams) String() string { return proto.CompactTextString(m) } func (*ConsensusParams) ProtoMessage() {} func (*ConsensusParams) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{25} + return fileDescriptor_types_d8da2202f45d32c0, []int{25} } func (m *ConsensusParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2367,7 +2368,7 @@ func (m *ConsensusParams) GetBlockGossip() *BlockGossip { return nil } -// BlockSize contain limits on the block size. +// BlockSize contains limits on the block size. type BlockSize struct { MaxBytes int32 `protobuf:"varint,1,opt,name=max_bytes,json=maxBytes,proto3" json:"max_bytes,omitempty"` MaxTxs int32 `protobuf:"varint,2,opt,name=max_txs,json=maxTxs,proto3" json:"max_txs,omitempty"` @@ -2381,7 +2382,7 @@ func (m *BlockSize) Reset() { *m = BlockSize{} } func (m *BlockSize) String() string { return proto.CompactTextString(m) } func (*BlockSize) ProtoMessage() {} func (*BlockSize) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{26} + return fileDescriptor_types_d8da2202f45d32c0, []int{26} } func (m *BlockSize) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2431,7 +2432,7 @@ func (m *BlockSize) GetMaxGas() int64 { return 0 } -// TxSize contain limits on the tx size. +// TxSize contains limits on the tx size. type TxSize struct { MaxBytes int32 `protobuf:"varint,1,opt,name=max_bytes,json=maxBytes,proto3" json:"max_bytes,omitempty"` MaxGas int64 `protobuf:"varint,2,opt,name=max_gas,json=maxGas,proto3" json:"max_gas,omitempty"` @@ -2444,7 +2445,7 @@ func (m *TxSize) Reset() { *m = TxSize{} } func (m *TxSize) String() string { return proto.CompactTextString(m) } func (*TxSize) ProtoMessage() {} func (*TxSize) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{27} + return fileDescriptor_types_d8da2202f45d32c0, []int{27} } func (m *TxSize) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2501,7 +2502,7 @@ func (m *BlockGossip) Reset() { *m = BlockGossip{} } func (m *BlockGossip) String() string { return proto.CompactTextString(m) } func (*BlockGossip) ProtoMessage() {} func (*BlockGossip) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{28} + return fileDescriptor_types_d8da2202f45d32c0, []int{28} } func (m *BlockGossip) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2537,6 +2538,61 @@ func (m *BlockGossip) GetBlockPartSizeBytes() int32 { return 0 } +type LastCommitInfo struct { + CommitRound int32 `protobuf:"varint,1,opt,name=commit_round,json=commitRound,proto3" json:"commit_round,omitempty"` + Validators []SigningValidator `protobuf:"bytes,2,rep,name=validators" json:"validators"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LastCommitInfo) Reset() { *m = LastCommitInfo{} } +func (m *LastCommitInfo) String() string { return proto.CompactTextString(m) } +func (*LastCommitInfo) ProtoMessage() {} +func (*LastCommitInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_types_d8da2202f45d32c0, []int{29} +} +func (m *LastCommitInfo) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LastCommitInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_LastCommitInfo.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (dst *LastCommitInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_LastCommitInfo.Merge(dst, src) +} +func (m *LastCommitInfo) XXX_Size() int { + return m.Size() +} +func (m *LastCommitInfo) XXX_DiscardUnknown() { + xxx_messageInfo_LastCommitInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_LastCommitInfo proto.InternalMessageInfo + +func (m *LastCommitInfo) GetCommitRound() int32 { + if m != nil { + return m.CommitRound + } + return 0 +} + +func (m *LastCommitInfo) GetValidators() []SigningValidator { + if m != nil { + return m.Validators + } + return nil +} + // just the minimum the app might need type Header struct { // basics @@ -2561,7 +2617,7 @@ func (m *Header) Reset() { *m = Header{} } func (m *Header) String() string { return proto.CompactTextString(m) } func (*Header) ProtoMessage() {} func (*Header) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{29} + return fileDescriptor_types_d8da2202f45d32c0, []int{30} } func (m *Header) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2667,7 +2723,7 @@ func (m *Validator) Reset() { *m = Validator{} } func (m *Validator) String() string { return proto.CompactTextString(m) } func (*Validator) ProtoMessage() {} func (*Validator) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{30} + return fileDescriptor_types_d8da2202f45d32c0, []int{31} } func (m *Validator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2730,7 +2786,7 @@ func (m *SigningValidator) Reset() { *m = SigningValidator{} } func (m *SigningValidator) String() string { return proto.CompactTextString(m) } func (*SigningValidator) ProtoMessage() {} func (*SigningValidator) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{31} + return fileDescriptor_types_d8da2202f45d32c0, []int{32} } func (m *SigningValidator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2785,7 +2841,7 @@ func (m *PubKey) Reset() { *m = PubKey{} } func (m *PubKey) String() string { return proto.CompactTextString(m) } func (*PubKey) ProtoMessage() {} func (*PubKey) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{32} + return fileDescriptor_types_d8da2202f45d32c0, []int{33} } func (m *PubKey) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2843,7 +2899,7 @@ func (m *Evidence) Reset() { *m = Evidence{} } func (m *Evidence) String() string { return proto.CompactTextString(m) } func (*Evidence) ProtoMessage() {} func (*Evidence) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{33} + return fileDescriptor_types_d8da2202f45d32c0, []int{34} } func (m *Evidence) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2966,6 +3022,8 @@ func init() { golang_proto.RegisterType((*TxSize)(nil), "types.TxSize") proto.RegisterType((*BlockGossip)(nil), "types.BlockGossip") golang_proto.RegisterType((*BlockGossip)(nil), "types.BlockGossip") + proto.RegisterType((*LastCommitInfo)(nil), "types.LastCommitInfo") + golang_proto.RegisterType((*LastCommitInfo)(nil), "types.LastCommitInfo") proto.RegisterType((*Header)(nil), "types.Header") golang_proto.RegisterType((*Header)(nil), "types.Header") proto.RegisterType((*Validator)(nil), "types.Validator") @@ -3487,14 +3545,9 @@ func (this *RequestBeginBlock) Equal(that interface{}) bool { if !this.Header.Equal(&that1.Header) { return false } - if len(this.Validators) != len(that1.Validators) { + if !this.LastCommitInfo.Equal(&that1.LastCommitInfo) { return false } - for i := range this.Validators { - if !this.Validators[i].Equal(&that1.Validators[i]) { - return false - } - } if len(this.ByzantineValidators) != len(that1.ByzantineValidators) { return false } @@ -4489,6 +4542,41 @@ func (this *BlockGossip) Equal(that interface{}) bool { } return true } +func (this *LastCommitInfo) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*LastCommitInfo) + if !ok { + that2, ok := that.(LastCommitInfo) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.CommitRound != that1.CommitRound { + return false + } + if len(this.Validators) != len(that1.Validators) { + return false + } + for i := range this.Validators { + if !this.Validators[i].Equal(&that1.Validators[i]) { + return false + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} func (this *Header) Equal(that interface{}) bool { if that == nil { return this == nil @@ -5507,18 +5595,14 @@ func (m *RequestBeginBlock) MarshalTo(dAtA []byte) (int, error) { return 0, err } i += n15 - if len(m.Validators) > 0 { - for _, msg := range m.Validators { - dAtA[i] = 0x1a - i++ - i = encodeVarintTypes(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } + dAtA[i] = 0x1a + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.LastCommitInfo.Size())) + n16, err := m.LastCommitInfo.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err } + i += n16 if len(m.ByzantineValidators) > 0 { for _, msg := range m.ByzantineValidators { dAtA[i] = 0x22 @@ -5654,11 +5738,11 @@ func (m *Response) MarshalTo(dAtA []byte) (int, error) { var l int _ = l if m.Value != nil { - nn16, err := m.Value.MarshalTo(dAtA[i:]) + nn17, err := m.Value.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += nn16 + i += nn17 } if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) @@ -5672,11 +5756,11 @@ func (m *Response_Exception) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Exception.Size())) - n17, err := m.Exception.MarshalTo(dAtA[i:]) + n18, err := m.Exception.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n17 + i += n18 } return i, nil } @@ -5686,11 +5770,11 @@ func (m *Response_Echo) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Echo.Size())) - n18, err := m.Echo.MarshalTo(dAtA[i:]) + n19, err := m.Echo.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n18 + i += n19 } return i, nil } @@ -5700,11 +5784,11 @@ func (m *Response_Flush) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Flush.Size())) - n19, err := m.Flush.MarshalTo(dAtA[i:]) + n20, err := m.Flush.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n19 + i += n20 } return i, nil } @@ -5714,11 +5798,11 @@ func (m *Response_Info) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x22 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Info.Size())) - n20, err := m.Info.MarshalTo(dAtA[i:]) + n21, err := m.Info.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n20 + i += n21 } return i, nil } @@ -5728,11 +5812,11 @@ func (m *Response_SetOption) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2a i++ i = encodeVarintTypes(dAtA, i, uint64(m.SetOption.Size())) - n21, err := m.SetOption.MarshalTo(dAtA[i:]) + n22, err := m.SetOption.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n21 + i += n22 } return i, nil } @@ -5742,11 +5826,11 @@ func (m *Response_InitChain) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x32 i++ i = encodeVarintTypes(dAtA, i, uint64(m.InitChain.Size())) - n22, err := m.InitChain.MarshalTo(dAtA[i:]) + n23, err := m.InitChain.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n22 + i += n23 } return i, nil } @@ -5756,11 +5840,11 @@ func (m *Response_Query) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x3a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Query.Size())) - n23, err := m.Query.MarshalTo(dAtA[i:]) + n24, err := m.Query.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n23 + i += n24 } return i, nil } @@ -5770,11 +5854,11 @@ func (m *Response_BeginBlock) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x42 i++ i = encodeVarintTypes(dAtA, i, uint64(m.BeginBlock.Size())) - n24, err := m.BeginBlock.MarshalTo(dAtA[i:]) + n25, err := m.BeginBlock.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n24 + i += n25 } return i, nil } @@ -5784,11 +5868,11 @@ func (m *Response_CheckTx) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x4a i++ i = encodeVarintTypes(dAtA, i, uint64(m.CheckTx.Size())) - n25, err := m.CheckTx.MarshalTo(dAtA[i:]) + n26, err := m.CheckTx.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n25 + i += n26 } return i, nil } @@ -5798,11 +5882,11 @@ func (m *Response_DeliverTx) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x52 i++ i = encodeVarintTypes(dAtA, i, uint64(m.DeliverTx.Size())) - n26, err := m.DeliverTx.MarshalTo(dAtA[i:]) + n27, err := m.DeliverTx.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n26 + i += n27 } return i, nil } @@ -5812,11 +5896,11 @@ func (m *Response_EndBlock) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x5a i++ i = encodeVarintTypes(dAtA, i, uint64(m.EndBlock.Size())) - n27, err := m.EndBlock.MarshalTo(dAtA[i:]) + n28, err := m.EndBlock.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n27 + i += n28 } return i, nil } @@ -5826,11 +5910,11 @@ func (m *Response_Commit) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x62 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Commit.Size())) - n28, err := m.Commit.MarshalTo(dAtA[i:]) + n29, err := m.Commit.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n28 + i += n29 } return i, nil } @@ -6010,11 +6094,11 @@ func (m *ResponseInitChain) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.ConsensusParams.Size())) - n29, err := m.ConsensusParams.MarshalTo(dAtA[i:]) + n30, err := m.ConsensusParams.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n29 + i += n30 } if len(m.Validators) > 0 { for _, msg := range m.Validators { @@ -6296,11 +6380,11 @@ func (m *ResponseEndBlock) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.ConsensusParamUpdates.Size())) - n30, err := m.ConsensusParamUpdates.MarshalTo(dAtA[i:]) + n31, err := m.ConsensusParamUpdates.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n30 + i += n31 } if len(m.Tags) > 0 { for _, msg := range m.Tags { @@ -6366,32 +6450,32 @@ func (m *ConsensusParams) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.BlockSize.Size())) - n31, err := m.BlockSize.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n31 - } - if m.TxSize != nil { - dAtA[i] = 0x12 - i++ - i = encodeVarintTypes(dAtA, i, uint64(m.TxSize.Size())) - n32, err := m.TxSize.MarshalTo(dAtA[i:]) + n32, err := m.BlockSize.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n32 } - if m.BlockGossip != nil { - dAtA[i] = 0x1a + if m.TxSize != nil { + dAtA[i] = 0x12 i++ - i = encodeVarintTypes(dAtA, i, uint64(m.BlockGossip.Size())) - n33, err := m.BlockGossip.MarshalTo(dAtA[i:]) + i = encodeVarintTypes(dAtA, i, uint64(m.TxSize.Size())) + n33, err := m.TxSize.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n33 } + if m.BlockGossip != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.BlockGossip.Size())) + n34, err := m.BlockGossip.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n34 + } if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) } @@ -6491,6 +6575,44 @@ func (m *BlockGossip) MarshalTo(dAtA []byte) (int, error) { return i, nil } +func (m *LastCommitInfo) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LastCommitInfo) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.CommitRound != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.CommitRound)) + } + if len(m.Validators) > 0 { + for _, msg := range m.Validators { + dAtA[i] = 0x12 + i++ + i = encodeVarintTypes(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + func (m *Header) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -6520,11 +6642,11 @@ func (m *Header) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.Time))) - n34, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i:]) + n35, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i:]) if err != nil { return 0, err } - i += n34 + i += n35 if m.NumTxs != 0 { dAtA[i] = 0x20 i++ @@ -6556,11 +6678,11 @@ func (m *Header) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x4a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Proposer.Size())) - n35, err := m.Proposer.MarshalTo(dAtA[i:]) + n36, err := m.Proposer.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n35 + i += n36 if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) } @@ -6591,11 +6713,11 @@ func (m *Validator) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.PubKey.Size())) - n36, err := m.PubKey.MarshalTo(dAtA[i:]) + n37, err := m.PubKey.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n36 + i += n37 if m.Power != 0 { dAtA[i] = 0x18 i++ @@ -6625,11 +6747,11 @@ func (m *SigningValidator) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Validator.Size())) - n37, err := m.Validator.MarshalTo(dAtA[i:]) + n38, err := m.Validator.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n37 + i += n38 if m.SignedLastBlock { dAtA[i] = 0x10 i++ @@ -6703,11 +6825,11 @@ func (m *Evidence) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Validator.Size())) - n38, err := m.Validator.MarshalTo(dAtA[i:]) + n39, err := m.Validator.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n38 + i += n39 if m.Height != 0 { dAtA[i] = 0x18 i++ @@ -6716,11 +6838,11 @@ func (m *Evidence) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x22 i++ i = encodeVarintTypes(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.Time))) - n39, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i:]) + n40, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i:]) if err != nil { return 0, err } - i += n39 + i += n40 if m.TotalVotingPower != 0 { dAtA[i] = 0x28 i++ @@ -6920,20 +7042,14 @@ func NewPopulatedRequestBeginBlock(r randyTypes, easy bool) *RequestBeginBlock { } v7 := NewPopulatedHeader(r, easy) this.Header = *v7 + v8 := NewPopulatedLastCommitInfo(r, easy) + this.LastCommitInfo = *v8 if r.Intn(10) != 0 { - v8 := r.Intn(5) - this.Validators = make([]SigningValidator, v8) - for i := 0; i < v8; i++ { - v9 := NewPopulatedSigningValidator(r, easy) - this.Validators[i] = *v9 - } - } - if r.Intn(10) != 0 { - v10 := r.Intn(5) - this.ByzantineValidators = make([]Evidence, v10) - for i := 0; i < v10; i++ { - v11 := NewPopulatedEvidence(r, easy) - this.ByzantineValidators[i] = *v11 + v9 := r.Intn(5) + this.ByzantineValidators = make([]Evidence, v9) + for i := 0; i < v9; i++ { + v10 := NewPopulatedEvidence(r, easy) + this.ByzantineValidators[i] = *v10 } } if !easy && r.Intn(10) != 0 { @@ -6944,9 +7060,9 @@ func NewPopulatedRequestBeginBlock(r randyTypes, easy bool) *RequestBeginBlock { func NewPopulatedRequestCheckTx(r randyTypes, easy bool) *RequestCheckTx { this := &RequestCheckTx{} - v12 := r.Intn(100) - this.Tx = make([]byte, v12) - for i := 0; i < v12; i++ { + v11 := r.Intn(100) + this.Tx = make([]byte, v11) + for i := 0; i < v11; i++ { this.Tx[i] = byte(r.Intn(256)) } if !easy && r.Intn(10) != 0 { @@ -6957,9 +7073,9 @@ func NewPopulatedRequestCheckTx(r randyTypes, easy bool) *RequestCheckTx { func NewPopulatedRequestDeliverTx(r randyTypes, easy bool) *RequestDeliverTx { this := &RequestDeliverTx{} - v13 := r.Intn(100) - this.Tx = make([]byte, v13) - for i := 0; i < v13; i++ { + v12 := r.Intn(100) + this.Tx = make([]byte, v12) + for i := 0; i < v12; i++ { this.Tx[i] = byte(r.Intn(256)) } if !easy && r.Intn(10) != 0 { @@ -7117,9 +7233,9 @@ func NewPopulatedResponseInfo(r randyTypes, easy bool) *ResponseInfo { if r.Intn(2) == 0 { this.LastBlockHeight *= -1 } - v14 := r.Intn(100) - this.LastBlockAppHash = make([]byte, v14) - for i := 0; i < v14; i++ { + v13 := r.Intn(100) + this.LastBlockAppHash = make([]byte, v13) + for i := 0; i < v13; i++ { this.LastBlockAppHash[i] = byte(r.Intn(256)) } if !easy && r.Intn(10) != 0 { @@ -7145,11 +7261,11 @@ func NewPopulatedResponseInitChain(r randyTypes, easy bool) *ResponseInitChain { this.ConsensusParams = NewPopulatedConsensusParams(r, easy) } if r.Intn(10) != 0 { - v15 := r.Intn(5) - this.Validators = make([]Validator, v15) - for i := 0; i < v15; i++ { - v16 := NewPopulatedValidator(r, easy) - this.Validators[i] = *v16 + v14 := r.Intn(5) + this.Validators = make([]Validator, v14) + for i := 0; i < v14; i++ { + v15 := NewPopulatedValidator(r, easy) + this.Validators[i] = *v15 } } if !easy && r.Intn(10) != 0 { @@ -7167,19 +7283,19 @@ func NewPopulatedResponseQuery(r randyTypes, easy bool) *ResponseQuery { if r.Intn(2) == 0 { this.Index *= -1 } - v17 := r.Intn(100) - this.Key = make([]byte, v17) - for i := 0; i < v17; i++ { + v16 := r.Intn(100) + this.Key = make([]byte, v16) + for i := 0; i < v16; i++ { this.Key[i] = byte(r.Intn(256)) } - v18 := r.Intn(100) - this.Value = make([]byte, v18) - for i := 0; i < v18; i++ { + v17 := r.Intn(100) + this.Value = make([]byte, v17) + for i := 0; i < v17; i++ { this.Value[i] = byte(r.Intn(256)) } - v19 := r.Intn(100) - this.Proof = make([]byte, v19) - for i := 0; i < v19; i++ { + v18 := r.Intn(100) + this.Proof = make([]byte, v18) + for i := 0; i < v18; i++ { this.Proof[i] = byte(r.Intn(256)) } this.Height = int64(r.Int63()) @@ -7195,11 +7311,11 @@ func NewPopulatedResponseQuery(r randyTypes, easy bool) *ResponseQuery { func NewPopulatedResponseBeginBlock(r randyTypes, easy bool) *ResponseBeginBlock { this := &ResponseBeginBlock{} if r.Intn(10) != 0 { - v20 := r.Intn(5) - this.Tags = make([]common.KVPair, v20) - for i := 0; i < v20; i++ { - v21 := common.NewPopulatedKVPair(r, easy) - this.Tags[i] = *v21 + v19 := r.Intn(5) + this.Tags = make([]common.KVPair, v19) + for i := 0; i < v19; i++ { + v20 := common.NewPopulatedKVPair(r, easy) + this.Tags[i] = *v20 } } if !easy && r.Intn(10) != 0 { @@ -7211,9 +7327,9 @@ func NewPopulatedResponseBeginBlock(r randyTypes, easy bool) *ResponseBeginBlock func NewPopulatedResponseCheckTx(r randyTypes, easy bool) *ResponseCheckTx { this := &ResponseCheckTx{} this.Code = uint32(r.Uint32()) - v22 := r.Intn(100) - this.Data = make([]byte, v22) - for i := 0; i < v22; i++ { + v21 := r.Intn(100) + this.Data = make([]byte, v21) + for i := 0; i < v21; i++ { this.Data[i] = byte(r.Intn(256)) } this.Log = string(randStringTypes(r)) @@ -7227,11 +7343,11 @@ func NewPopulatedResponseCheckTx(r randyTypes, easy bool) *ResponseCheckTx { this.GasUsed *= -1 } if r.Intn(10) != 0 { - v23 := r.Intn(5) - this.Tags = make([]common.KVPair, v23) - for i := 0; i < v23; i++ { - v24 := common.NewPopulatedKVPair(r, easy) - this.Tags[i] = *v24 + v22 := r.Intn(5) + this.Tags = make([]common.KVPair, v22) + for i := 0; i < v22; i++ { + v23 := common.NewPopulatedKVPair(r, easy) + this.Tags[i] = *v23 } } if !easy && r.Intn(10) != 0 { @@ -7243,9 +7359,9 @@ func NewPopulatedResponseCheckTx(r randyTypes, easy bool) *ResponseCheckTx { func NewPopulatedResponseDeliverTx(r randyTypes, easy bool) *ResponseDeliverTx { this := &ResponseDeliverTx{} this.Code = uint32(r.Uint32()) - v25 := r.Intn(100) - this.Data = make([]byte, v25) - for i := 0; i < v25; i++ { + v24 := r.Intn(100) + this.Data = make([]byte, v24) + for i := 0; i < v24; i++ { this.Data[i] = byte(r.Intn(256)) } this.Log = string(randStringTypes(r)) @@ -7259,11 +7375,11 @@ func NewPopulatedResponseDeliverTx(r randyTypes, easy bool) *ResponseDeliverTx { this.GasUsed *= -1 } if r.Intn(10) != 0 { - v26 := r.Intn(5) - this.Tags = make([]common.KVPair, v26) - for i := 0; i < v26; i++ { - v27 := common.NewPopulatedKVPair(r, easy) - this.Tags[i] = *v27 + v25 := r.Intn(5) + this.Tags = make([]common.KVPair, v25) + for i := 0; i < v25; i++ { + v26 := common.NewPopulatedKVPair(r, easy) + this.Tags[i] = *v26 } } if !easy && r.Intn(10) != 0 { @@ -7275,22 +7391,22 @@ func NewPopulatedResponseDeliverTx(r randyTypes, easy bool) *ResponseDeliverTx { func NewPopulatedResponseEndBlock(r randyTypes, easy bool) *ResponseEndBlock { this := &ResponseEndBlock{} if r.Intn(10) != 0 { - v28 := r.Intn(5) - this.ValidatorUpdates = make([]Validator, v28) - for i := 0; i < v28; i++ { - v29 := NewPopulatedValidator(r, easy) - this.ValidatorUpdates[i] = *v29 + v27 := r.Intn(5) + this.ValidatorUpdates = make([]Validator, v27) + for i := 0; i < v27; i++ { + v28 := NewPopulatedValidator(r, easy) + this.ValidatorUpdates[i] = *v28 } } if r.Intn(10) != 0 { this.ConsensusParamUpdates = NewPopulatedConsensusParams(r, easy) } if r.Intn(10) != 0 { - v30 := r.Intn(5) - this.Tags = make([]common.KVPair, v30) - for i := 0; i < v30; i++ { - v31 := common.NewPopulatedKVPair(r, easy) - this.Tags[i] = *v31 + v29 := r.Intn(5) + this.Tags = make([]common.KVPair, v29) + for i := 0; i < v29; i++ { + v30 := common.NewPopulatedKVPair(r, easy) + this.Tags[i] = *v30 } } if !easy && r.Intn(10) != 0 { @@ -7301,9 +7417,9 @@ func NewPopulatedResponseEndBlock(r randyTypes, easy bool) *ResponseEndBlock { func NewPopulatedResponseCommit(r randyTypes, easy bool) *ResponseCommit { this := &ResponseCommit{} - v32 := r.Intn(100) - this.Data = make([]byte, v32) - for i := 0; i < v32; i++ { + v31 := r.Intn(100) + this.Data = make([]byte, v31) + for i := 0; i < v31; i++ { this.Data[i] = byte(r.Intn(256)) } if !easy && r.Intn(10) != 0 { @@ -7377,6 +7493,26 @@ func NewPopulatedBlockGossip(r randyTypes, easy bool) *BlockGossip { return this } +func NewPopulatedLastCommitInfo(r randyTypes, easy bool) *LastCommitInfo { + this := &LastCommitInfo{} + this.CommitRound = int32(r.Int31()) + if r.Intn(2) == 0 { + this.CommitRound *= -1 + } + if r.Intn(10) != 0 { + v32 := r.Intn(5) + this.Validators = make([]SigningValidator, v32) + for i := 0; i < v32; i++ { + v33 := NewPopulatedSigningValidator(r, easy) + this.Validators[i] = *v33 + } + } + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedTypes(r, 3) + } + return this +} + func NewPopulatedHeader(r randyTypes, easy bool) *Header { this := &Header{} this.ChainID = string(randStringTypes(r)) @@ -7384,8 +7520,8 @@ func NewPopulatedHeader(r randyTypes, easy bool) *Header { if r.Intn(2) == 0 { this.Height *= -1 } - v33 := github_com_gogo_protobuf_types.NewPopulatedStdTime(r, easy) - this.Time = *v33 + v34 := github_com_gogo_protobuf_types.NewPopulatedStdTime(r, easy) + this.Time = *v34 this.NumTxs = int32(r.Int31()) if r.Intn(2) == 0 { this.NumTxs *= -1 @@ -7394,23 +7530,23 @@ func NewPopulatedHeader(r randyTypes, easy bool) *Header { if r.Intn(2) == 0 { this.TotalTxs *= -1 } - v34 := r.Intn(100) - this.LastBlockHash = make([]byte, v34) - for i := 0; i < v34; i++ { + v35 := r.Intn(100) + this.LastBlockHash = make([]byte, v35) + for i := 0; i < v35; i++ { this.LastBlockHash[i] = byte(r.Intn(256)) } - v35 := r.Intn(100) - this.ValidatorsHash = make([]byte, v35) - for i := 0; i < v35; i++ { + v36 := r.Intn(100) + this.ValidatorsHash = make([]byte, v36) + for i := 0; i < v36; i++ { this.ValidatorsHash[i] = byte(r.Intn(256)) } - v36 := r.Intn(100) - this.AppHash = make([]byte, v36) - for i := 0; i < v36; i++ { + v37 := r.Intn(100) + this.AppHash = make([]byte, v37) + for i := 0; i < v37; i++ { this.AppHash[i] = byte(r.Intn(256)) } - v37 := NewPopulatedValidator(r, easy) - this.Proposer = *v37 + v38 := NewPopulatedValidator(r, easy) + this.Proposer = *v38 if !easy && r.Intn(10) != 0 { this.XXX_unrecognized = randUnrecognizedTypes(r, 10) } @@ -7419,13 +7555,13 @@ func NewPopulatedHeader(r randyTypes, easy bool) *Header { func NewPopulatedValidator(r randyTypes, easy bool) *Validator { this := &Validator{} - v38 := r.Intn(100) - this.Address = make([]byte, v38) - for i := 0; i < v38; i++ { + v39 := r.Intn(100) + this.Address = make([]byte, v39) + for i := 0; i < v39; i++ { this.Address[i] = byte(r.Intn(256)) } - v39 := NewPopulatedPubKey(r, easy) - this.PubKey = *v39 + v40 := NewPopulatedPubKey(r, easy) + this.PubKey = *v40 this.Power = int64(r.Int63()) if r.Intn(2) == 0 { this.Power *= -1 @@ -7438,8 +7574,8 @@ func NewPopulatedValidator(r randyTypes, easy bool) *Validator { func NewPopulatedSigningValidator(r randyTypes, easy bool) *SigningValidator { this := &SigningValidator{} - v40 := NewPopulatedValidator(r, easy) - this.Validator = *v40 + v41 := NewPopulatedValidator(r, easy) + this.Validator = *v41 this.SignedLastBlock = bool(bool(r.Intn(2) == 0)) if !easy && r.Intn(10) != 0 { this.XXX_unrecognized = randUnrecognizedTypes(r, 3) @@ -7450,9 +7586,9 @@ func NewPopulatedSigningValidator(r randyTypes, easy bool) *SigningValidator { func NewPopulatedPubKey(r randyTypes, easy bool) *PubKey { this := &PubKey{} this.Type = string(randStringTypes(r)) - v41 := r.Intn(100) - this.Data = make([]byte, v41) - for i := 0; i < v41; i++ { + v42 := r.Intn(100) + this.Data = make([]byte, v42) + for i := 0; i < v42; i++ { this.Data[i] = byte(r.Intn(256)) } if !easy && r.Intn(10) != 0 { @@ -7464,14 +7600,14 @@ func NewPopulatedPubKey(r randyTypes, easy bool) *PubKey { func NewPopulatedEvidence(r randyTypes, easy bool) *Evidence { this := &Evidence{} this.Type = string(randStringTypes(r)) - v42 := NewPopulatedValidator(r, easy) - this.Validator = *v42 + v43 := NewPopulatedValidator(r, easy) + this.Validator = *v43 this.Height = int64(r.Int63()) if r.Intn(2) == 0 { this.Height *= -1 } - v43 := github_com_gogo_protobuf_types.NewPopulatedStdTime(r, easy) - this.Time = *v43 + v44 := github_com_gogo_protobuf_types.NewPopulatedStdTime(r, easy) + this.Time = *v44 this.TotalVotingPower = int64(r.Int63()) if r.Intn(2) == 0 { this.TotalVotingPower *= -1 @@ -7501,9 +7637,9 @@ func randUTF8RuneTypes(r randyTypes) rune { return rune(ru + 61) } func randStringTypes(r randyTypes) string { - v44 := r.Intn(100) - tmps := make([]rune, v44) - for i := 0; i < v44; i++ { + v45 := r.Intn(100) + tmps := make([]rune, v45) + for i := 0; i < v45; i++ { tmps[i] = randUTF8RuneTypes(r) } return string(tmps) @@ -7525,11 +7661,11 @@ func randFieldTypes(dAtA []byte, r randyTypes, fieldNumber int, wire int) []byte switch wire { case 0: dAtA = encodeVarintPopulateTypes(dAtA, uint64(key)) - v45 := r.Int63() + v46 := r.Int63() if r.Intn(2) == 0 { - v45 *= -1 + v46 *= -1 } - dAtA = encodeVarintPopulateTypes(dAtA, uint64(v45)) + dAtA = encodeVarintPopulateTypes(dAtA, uint64(v46)) case 1: dAtA = encodeVarintPopulateTypes(dAtA, uint64(key)) dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256))) @@ -7778,12 +7914,8 @@ func (m *RequestBeginBlock) Size() (n int) { } l = m.Header.Size() n += 1 + l + sovTypes(uint64(l)) - if len(m.Validators) > 0 { - for _, e := range m.Validators { - l = e.Size() - n += 1 + l + sovTypes(uint64(l)) - } - } + l = m.LastCommitInfo.Size() + n += 1 + l + sovTypes(uint64(l)) if len(m.ByzantineValidators) > 0 { for _, e := range m.ByzantineValidators { l = e.Size() @@ -8290,6 +8422,24 @@ func (m *BlockGossip) Size() (n int) { return n } +func (m *LastCommitInfo) Size() (n int) { + var l int + _ = l + if m.CommitRound != 0 { + n += 1 + sovTypes(uint64(m.CommitRound)) + } + if len(m.Validators) > 0 { + for _, e := range m.Validators { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func (m *Header) Size() (n int) { var l int _ = l @@ -9583,7 +9733,7 @@ func (m *RequestBeginBlock) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Validators", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field LastCommitInfo", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -9607,8 +9757,7 @@ func (m *RequestBeginBlock) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Validators = append(m.Validators, SigningValidator{}) - if err := m.Validators[len(m.Validators)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.LastCommitInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -12440,6 +12589,107 @@ func (m *BlockGossip) Unmarshal(dAtA []byte) error { } return nil } +func (m *LastCommitInfo) 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: LastCommitInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LastCommitInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CommitRound", wireType) + } + m.CommitRound = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CommitRound |= (int32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Validators", 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 > l { + return io.ErrUnexpectedEOF + } + m.Validators = append(m.Validators, SigningValidator{}) + if err := m.Validators[len(m.Validators)-1].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 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *Header) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -13356,131 +13606,134 @@ var ( ErrIntOverflowTypes = fmt.Errorf("proto: integer overflow") ) -func init() { proto.RegisterFile("abci/types/types.proto", fileDescriptor_types_2c69c6b96b429b1c) } +func init() { proto.RegisterFile("abci/types/types.proto", fileDescriptor_types_d8da2202f45d32c0) } func init() { - golang_proto.RegisterFile("abci/types/types.proto", fileDescriptor_types_2c69c6b96b429b1c) + golang_proto.RegisterFile("abci/types/types.proto", fileDescriptor_types_d8da2202f45d32c0) } -var fileDescriptor_types_2c69c6b96b429b1c = []byte{ - // 1911 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x58, 0x4b, 0x73, 0x24, 0x47, - 0x11, 0x56, 0xcf, 0xbb, 0x73, 0x24, 0x8d, 0xb6, 0xb4, 0x2b, 0xcd, 0x8e, 0x41, 0xda, 0xe8, 0x20, - 0xd6, 0x5a, 0x2c, 0x8f, 0x40, 0x66, 0x1d, 0x5a, 0x1b, 0x1c, 0x68, 0xe4, 0xc5, 0xa3, 0x30, 0x0f, - 0xd1, 0xbb, 0x5e, 0x22, 0xb8, 0x4c, 0xd4, 0x4c, 0x97, 0x7a, 0x3a, 0x76, 0xfa, 0xe1, 0xae, 0x1a, - 0x79, 0xb4, 0x3f, 0x81, 0x70, 0x10, 0xdc, 0x38, 0x73, 0xe3, 0x0f, 0x10, 0xc1, 0x91, 0x13, 0xe1, - 0x23, 0x07, 0x08, 0xb8, 0xb0, 0x80, 0x7c, 0xe3, 0x17, 0x70, 0x24, 0xb2, 0xaa, 0xdf, 0xea, 0xd9, - 0x90, 0x97, 0x1b, 0x17, 0xa9, 0xb2, 0x33, 0xb3, 0xaa, 0x32, 0x27, 0xf3, 0xcb, 0xcc, 0x82, 0x2d, - 0x3a, 0x9e, 0x38, 0x07, 0xe2, 0x32, 0x60, 0x5c, 0xfd, 0xed, 0x07, 0xa1, 0x2f, 0x7c, 0x52, 0x97, - 0x44, 0xef, 0x6d, 0xdb, 0x11, 0xd3, 0xf9, 0xb8, 0x3f, 0xf1, 0xdd, 0x03, 0xdb, 0xb7, 0xfd, 0x03, - 0xc9, 0x1d, 0xcf, 0xcf, 0x25, 0x25, 0x09, 0xb9, 0x52, 0x5a, 0xbd, 0x5d, 0xdb, 0xf7, 0xed, 0x19, - 0x4b, 0xa5, 0x84, 0xe3, 0x32, 0x2e, 0xa8, 0x1b, 0x44, 0x02, 0x47, 0x99, 0xfd, 0x04, 0xf3, 0x2c, - 0x16, 0xba, 0x8e, 0x27, 0xb2, 0xcb, 0x99, 0x33, 0xe6, 0x07, 0x13, 0xdf, 0x75, 0x7d, 0x2f, 0x7b, - 0x21, 0xe3, 0x8f, 0x35, 0x68, 0x9a, 0xec, 0xd3, 0x39, 0xe3, 0x82, 0xec, 0x41, 0x8d, 0x4d, 0xa6, - 0x7e, 0xb7, 0x72, 0x4f, 0xdb, 0x6b, 0x1f, 0x92, 0xbe, 0x92, 0x8b, 0xb8, 0x8f, 0x27, 0x53, 0x7f, - 0xb8, 0x62, 0x4a, 0x09, 0xf2, 0x16, 0xd4, 0xcf, 0x67, 0x73, 0x3e, 0xed, 0x56, 0xa5, 0xe8, 0x66, - 0x5e, 0xf4, 0x07, 0xc8, 0x1a, 0xae, 0x98, 0x4a, 0x06, 0xb7, 0x75, 0xbc, 0x73, 0xbf, 0x5b, 0x2b, - 0xdb, 0xf6, 0xd4, 0x3b, 0x97, 0xdb, 0xa2, 0x04, 0x39, 0x02, 0xe0, 0x4c, 0x8c, 0xfc, 0x40, 0x38, - 0xbe, 0xd7, 0xad, 0x4b, 0xf9, 0xed, 0xbc, 0xfc, 0x13, 0x26, 0x7e, 0x22, 0xd9, 0xc3, 0x15, 0x53, - 0xe7, 0x31, 0x81, 0x9a, 0x8e, 0xe7, 0x88, 0xd1, 0x64, 0x4a, 0x1d, 0xaf, 0xdb, 0x28, 0xd3, 0x3c, - 0xf5, 0x1c, 0x71, 0x82, 0x6c, 0xd4, 0x74, 0x62, 0x02, 0x4d, 0xf9, 0x74, 0xce, 0xc2, 0xcb, 0x6e, - 0xb3, 0xcc, 0x94, 0x9f, 0x22, 0x0b, 0x4d, 0x91, 0x32, 0xe4, 0x7d, 0x68, 0x8f, 0x99, 0xed, 0x78, - 0xa3, 0xf1, 0xcc, 0x9f, 0x3c, 0xef, 0xb6, 0xa4, 0x4a, 0x37, 0xaf, 0x32, 0x40, 0x81, 0x01, 0xf2, - 0x87, 0x2b, 0x26, 0x8c, 0x13, 0x8a, 0x1c, 0x42, 0x6b, 0x32, 0x65, 0x93, 0xe7, 0x23, 0xb1, 0xe8, - 0xea, 0x52, 0xf3, 0x4e, 0x5e, 0xf3, 0x04, 0xb9, 0x4f, 0x17, 0xc3, 0x15, 0xb3, 0x39, 0x51, 0x4b, - 0xf2, 0x10, 0x74, 0xe6, 0x59, 0xd1, 0x71, 0x6d, 0xa9, 0xb4, 0x55, 0xf8, 0x5d, 0x3c, 0x2b, 0x3e, - 0xac, 0xc5, 0xa2, 0x35, 0xe9, 0x43, 0x03, 0x7f, 0x6b, 0x47, 0x74, 0x57, 0xa5, 0xce, 0xed, 0xc2, - 0x41, 0x92, 0x37, 0x5c, 0x31, 0x23, 0x29, 0x74, 0x9f, 0xc5, 0x66, 0xce, 0x05, 0x0b, 0xf1, 0x72, - 0x9b, 0x65, 0xee, 0xfb, 0x50, 0xf1, 0xe5, 0xf5, 0x74, 0x2b, 0x26, 0x06, 0x4d, 0xa8, 0x5f, 0xd0, - 0xd9, 0x9c, 0x19, 0x6f, 0x42, 0x3b, 0x13, 0x29, 0xa4, 0x0b, 0x4d, 0x97, 0x71, 0x4e, 0x6d, 0xd6, - 0xd5, 0xee, 0x69, 0x7b, 0xba, 0x19, 0x93, 0xc6, 0x3a, 0xac, 0x66, 0xe3, 0x24, 0xa3, 0x88, 0xb1, - 0x80, 0x8a, 0x17, 0x2c, 0xe4, 0x18, 0x00, 0x91, 0x62, 0x44, 0x1a, 0xef, 0xc1, 0x46, 0x31, 0x08, - 0xc8, 0x06, 0x54, 0x9f, 0xb3, 0xcb, 0x48, 0x12, 0x97, 0xe4, 0x76, 0x74, 0x21, 0x19, 0xc5, 0xba, - 0x19, 0xdd, 0xee, 0x17, 0x95, 0x44, 0x39, 0x89, 0x03, 0x72, 0x04, 0x35, 0x4c, 0x24, 0xa9, 0xdd, - 0x3e, 0xec, 0xf5, 0x55, 0x96, 0xf5, 0xe3, 0x2c, 0xeb, 0x3f, 0x8d, 0xb3, 0x6c, 0xd0, 0xfa, 0xe2, - 0xe5, 0xee, 0xca, 0xaf, 0xfe, 0xb1, 0xab, 0x99, 0x52, 0x83, 0xdc, 0xc5, 0x9f, 0x92, 0x3a, 0xde, - 0xc8, 0xb1, 0xa2, 0x73, 0x9a, 0x92, 0x3e, 0xb5, 0xc8, 0x31, 0x6c, 0x4c, 0x7c, 0x8f, 0x33, 0x8f, - 0xcf, 0xf9, 0x28, 0xa0, 0x21, 0x75, 0x79, 0x94, 0x25, 0xf1, 0x0f, 0x77, 0x12, 0xb3, 0xcf, 0x24, - 0xd7, 0xec, 0x4c, 0xf2, 0x1f, 0xc8, 0xbb, 0x00, 0x17, 0x74, 0xe6, 0x58, 0x54, 0xf8, 0x21, 0xef, - 0xd6, 0xee, 0x55, 0xf7, 0xda, 0x87, 0x1b, 0x91, 0xf2, 0xb3, 0x98, 0x31, 0xa8, 0xe1, 0x9d, 0xcc, - 0x8c, 0x24, 0xb9, 0x0f, 0x1d, 0x1a, 0x04, 0x23, 0x2e, 0xa8, 0x60, 0xa3, 0xf1, 0xa5, 0x60, 0x5c, - 0xe6, 0xd0, 0xaa, 0xb9, 0x46, 0x83, 0xe0, 0x09, 0x7e, 0x1d, 0xe0, 0x47, 0xc3, 0x4a, 0x7e, 0x01, - 0x19, 0xde, 0x84, 0x40, 0xcd, 0xa2, 0x82, 0x4a, 0x3f, 0xac, 0x9a, 0x72, 0x8d, 0xdf, 0x02, 0x2a, - 0xa6, 0x91, 0x75, 0x72, 0x4d, 0xb6, 0xa0, 0x31, 0x65, 0x8e, 0x3d, 0x15, 0xd2, 0xa0, 0xaa, 0x19, - 0x51, 0xe8, 0xf2, 0x20, 0xf4, 0x2f, 0x98, 0xcc, 0xf0, 0x96, 0xa9, 0x08, 0xe3, 0xef, 0x1a, 0xdc, - 0xba, 0x96, 0x12, 0xb8, 0xef, 0x94, 0xf2, 0x69, 0x7c, 0x16, 0xae, 0xc9, 0x5b, 0xb8, 0x2f, 0xb5, - 0x58, 0x18, 0x21, 0xcf, 0x5a, 0x64, 0xeb, 0x50, 0x7e, 0x8c, 0x0c, 0x8d, 0x44, 0xc8, 0xf7, 0x72, - 0xce, 0xa9, 0x4a, 0xe7, 0xc4, 0xa1, 0xfa, 0xc4, 0xb1, 0x3d, 0xc7, 0xb3, 0x5f, 0xe5, 0xa3, 0x21, - 0xdc, 0x1e, 0x5f, 0xbe, 0xa0, 0x9e, 0x70, 0x3c, 0x36, 0xba, 0xe6, 0xe5, 0x4e, 0xb4, 0xd1, 0xe3, - 0x0b, 0xc7, 0x62, 0xde, 0x84, 0x45, 0x1b, 0x6c, 0x26, 0x2a, 0xc9, 0xd6, 0xdc, 0xb8, 0x07, 0xeb, - 0xf9, 0xbc, 0x25, 0xeb, 0x50, 0x11, 0x8b, 0xc8, 0xb2, 0x8a, 0x58, 0x18, 0x46, 0x12, 0x73, 0x49, - 0xf2, 0x5c, 0x93, 0x79, 0x00, 0x9d, 0x42, 0x22, 0x67, 0xdc, 0xac, 0x65, 0xdd, 0x6c, 0x74, 0x60, - 0x2d, 0x97, 0xbf, 0xc6, 0xe7, 0x75, 0x68, 0x99, 0x8c, 0x07, 0x18, 0x3e, 0xe4, 0x08, 0x74, 0xb6, - 0x98, 0x30, 0x05, 0x9d, 0x5a, 0x01, 0x98, 0x94, 0xcc, 0xe3, 0x98, 0x8f, 0x29, 0x9c, 0x08, 0x93, - 0x07, 0x39, 0xd8, 0xdf, 0x2c, 0x2a, 0x65, 0x71, 0x7f, 0x3f, 0x8f, 0xfb, 0xb7, 0x0b, 0xb2, 0x05, - 0xe0, 0x7f, 0x90, 0x03, 0xfe, 0xe2, 0xc6, 0x39, 0xe4, 0x7f, 0x54, 0x82, 0xfc, 0xc5, 0xeb, 0x2f, - 0x81, 0xfe, 0x47, 0x25, 0xd0, 0xdf, 0xbd, 0x76, 0x56, 0x29, 0xf6, 0xef, 0xe7, 0xb1, 0xbf, 0x68, - 0x4e, 0x01, 0xfc, 0xbf, 0x5b, 0x06, 0xfe, 0x77, 0x0b, 0x3a, 0x4b, 0xd1, 0xff, 0x9d, 0x6b, 0xe8, - 0xbf, 0x55, 0x50, 0x2d, 0x81, 0xff, 0x47, 0x39, 0x5c, 0x86, 0x52, 0xdb, 0xca, 0x81, 0x99, 0xbc, - 0x7b, 0xbd, 0x72, 0x6c, 0x17, 0x7f, 0xda, 0xb2, 0xd2, 0x71, 0x50, 0x28, 0x1d, 0x77, 0x8a, 0xb7, - 0x2c, 0xd4, 0x8e, 0xb4, 0x02, 0x3c, 0xc0, 0x7c, 0x2f, 0x44, 0x1a, 0x62, 0x03, 0x0b, 0x43, 0x3f, - 0x8c, 0x20, 0x5a, 0x11, 0xc6, 0x1e, 0x22, 0x50, 0x1a, 0x5f, 0xaf, 0xa8, 0x16, 0x32, 0xe8, 0x33, - 0xd1, 0x65, 0xfc, 0x5a, 0x4b, 0x75, 0x65, 0xc1, 0xc8, 0xa2, 0x97, 0x1e, 0xa1, 0x57, 0xa6, 0x88, - 0x54, 0x72, 0x45, 0x84, 0x7c, 0x13, 0x6e, 0xcd, 0x28, 0x17, 0xca, 0x2f, 0xa3, 0x1c, 0x9c, 0x75, - 0x90, 0xa1, 0x1c, 0xa2, 0x70, 0xed, 0x6d, 0xd8, 0xcc, 0xc8, 0x22, 0xb4, 0x4a, 0xe8, 0xaa, 0xc9, - 0xe4, 0xdd, 0x48, 0xa4, 0x8f, 0x83, 0x60, 0x48, 0xf9, 0xd4, 0xf8, 0x51, 0x6a, 0x7f, 0x5a, 0xa0, - 0x08, 0xd4, 0x26, 0xbe, 0xa5, 0xcc, 0x5a, 0x33, 0xe5, 0x1a, 0x8b, 0xd6, 0xcc, 0xb7, 0xe5, 0xa9, - 0xba, 0x89, 0x4b, 0x94, 0x4a, 0x32, 0x45, 0x57, 0x29, 0x61, 0xfc, 0x52, 0x4b, 0xf7, 0x4b, 0x6b, - 0x56, 0x59, 0x79, 0xd1, 0xfe, 0x97, 0xf2, 0x52, 0xb9, 0x69, 0x79, 0x31, 0x7e, 0xa7, 0xa5, 0xbf, - 0x45, 0x52, 0x38, 0x5e, 0xcf, 0x38, 0x0c, 0x0b, 0xc7, 0xb3, 0xd8, 0x42, 0xa6, 0x7a, 0xd5, 0x54, - 0x44, 0x5c, 0xcd, 0x1b, 0xd2, 0xc1, 0xf9, 0x6a, 0xde, 0x94, 0xdf, 0x14, 0x11, 0x15, 0x1c, 0xff, - 0x5c, 0xe6, 0xe0, 0xaa, 0xa9, 0x88, 0x0c, 0x6e, 0xea, 0x39, 0xdc, 0x3c, 0x03, 0x72, 0x3d, 0x3b, - 0xc9, 0x7b, 0x50, 0x13, 0xd4, 0x46, 0xe7, 0xa1, 0xfd, 0xeb, 0x7d, 0xd5, 0x1b, 0xf7, 0x3f, 0x7e, - 0x76, 0x46, 0x9d, 0x70, 0xb0, 0x85, 0xd6, 0xff, 0xfb, 0xe5, 0xee, 0x3a, 0xca, 0xec, 0xfb, 0xae, - 0x23, 0x98, 0x1b, 0x88, 0x4b, 0x53, 0xea, 0x18, 0x7f, 0xd1, 0x10, 0xb5, 0x73, 0x59, 0x5b, 0xea, - 0x8b, 0x38, 0x34, 0x2b, 0x99, 0xc2, 0x7a, 0x33, 0xff, 0x7c, 0x1d, 0xc0, 0xa6, 0x7c, 0xf4, 0x19, - 0xf5, 0x04, 0xb3, 0x22, 0x27, 0xe9, 0x36, 0xe5, 0x3f, 0x93, 0x1f, 0xb0, 0xff, 0x40, 0xf6, 0x9c, - 0x33, 0x4b, 0x7a, 0xab, 0x6a, 0x36, 0x6d, 0xca, 0x3f, 0xe1, 0xcc, 0x4a, 0xec, 0x6a, 0xbe, 0x86, - 0x5d, 0x7f, 0xcd, 0x84, 0x5c, 0x5a, 0xb2, 0xfe, 0x1f, 0x2c, 0xfb, 0x52, 0xc3, 0x5a, 0x9c, 0x87, - 0x3d, 0x72, 0x02, 0xb7, 0x92, 0xf0, 0x1e, 0xcd, 0x03, 0x8b, 0x62, 0xc7, 0xa4, 0xbd, 0x32, 0x1f, - 0x36, 0x12, 0x85, 0x4f, 0x94, 0x3c, 0xf9, 0x31, 0x6c, 0x17, 0x12, 0x32, 0xd9, 0xaa, 0xf2, 0xca, - 0xbc, 0xbc, 0x93, 0xcf, 0xcb, 0x78, 0xbf, 0xd8, 0xca, 0xea, 0x6b, 0x58, 0xf9, 0x0d, 0x6c, 0x49, - 0xb2, 0x30, 0x5d, 0xf6, 0x3b, 0x19, 0xbf, 0xd1, 0xa0, 0x53, 0xb8, 0x0c, 0x39, 0x00, 0x50, 0x28, - 0xc7, 0x9d, 0x17, 0x71, 0x43, 0x1c, 0xfb, 0x40, 0x3a, 0xeb, 0x89, 0xf3, 0x82, 0x99, 0xfa, 0x38, - 0x5e, 0x92, 0xfb, 0xd0, 0x14, 0x0b, 0x25, 0x9d, 0x6f, 0xda, 0x9e, 0x2e, 0xa4, 0x68, 0x43, 0xc8, - 0xff, 0xe4, 0x21, 0xac, 0xaa, 0x8d, 0x6d, 0x9f, 0x73, 0x27, 0x88, 0x1a, 0x07, 0x92, 0xdd, 0xfa, - 0x23, 0xc9, 0x31, 0xdb, 0xe3, 0x94, 0x30, 0x7e, 0x0e, 0x7a, 0x72, 0x2c, 0x79, 0x03, 0x74, 0x97, - 0x2e, 0xa2, 0x8e, 0x16, 0xef, 0x56, 0x37, 0x5b, 0x2e, 0x5d, 0xc8, 0x66, 0x96, 0x6c, 0x43, 0x13, - 0x99, 0x62, 0xa1, 0xfc, 0x5d, 0x37, 0x1b, 0x2e, 0x5d, 0x3c, 0x5d, 0x24, 0x0c, 0x9b, 0xf2, 0xb8, - 0x5d, 0x75, 0xe9, 0xe2, 0x23, 0xca, 0x8d, 0x0f, 0xa0, 0xa1, 0x2e, 0x79, 0xa3, 0x8d, 0x51, 0xbf, - 0x92, 0xd3, 0xff, 0x3e, 0xb4, 0x33, 0xf7, 0x26, 0xdf, 0x86, 0x3b, 0xca, 0xc2, 0x80, 0x86, 0x42, - 0x7a, 0x24, 0xb7, 0x21, 0x91, 0xcc, 0x33, 0x1a, 0x0a, 0x3c, 0x52, 0x35, 0xe0, 0x7f, 0xab, 0x40, - 0x43, 0x35, 0xb7, 0xe4, 0x7e, 0x66, 0x92, 0x90, 0x15, 0x6c, 0xd0, 0xbe, 0x7a, 0xb9, 0xdb, 0x94, - 0x60, 0x7f, 0xfa, 0x61, 0x3a, 0x56, 0xa4, 0xe0, 0x56, 0xc9, 0xf5, 0xde, 0xf1, 0x0c, 0x53, 0xfd, - 0xca, 0x33, 0xcc, 0x36, 0x34, 0xbd, 0xb9, 0x2b, 0x1d, 0x57, 0x53, 0x8e, 0xf3, 0xe6, 0x2e, 0x3a, - 0xee, 0x0d, 0xd0, 0x85, 0x2f, 0xe8, 0x4c, 0xb2, 0x54, 0x82, 0xb6, 0xe4, 0x07, 0x64, 0xde, 0x87, - 0x4e, 0xb6, 0x7e, 0x62, 0x3d, 0x54, 0x70, 0xbd, 0x96, 0x56, 0x4f, 0xec, 0xe9, 0xdf, 0x84, 0x4e, - 0x5a, 0x3a, 0x94, 0x9c, 0x82, 0xf0, 0xf5, 0xf4, 0xb3, 0x14, 0xbc, 0x0b, 0xad, 0xa4, 0xb2, 0x2a, - 0x38, 0x6f, 0x52, 0x55, 0x50, 0x71, 0x60, 0x0e, 0x42, 0x3f, 0xf0, 0x39, 0x0b, 0xa3, 0x96, 0x69, - 0x59, 0x5a, 0x26, 0x72, 0x86, 0x03, 0x7a, 0xc2, 0xc4, 0x36, 0x80, 0x5a, 0x56, 0xc8, 0x38, 0x8f, - 0x3a, 0xee, 0x98, 0x24, 0xfb, 0xd0, 0x0c, 0xe6, 0xe3, 0x11, 0x56, 0x9b, 0x7c, 0xf8, 0x9e, 0xcd, - 0xc7, 0x1f, 0xb3, 0xcb, 0x78, 0xe6, 0x08, 0x24, 0x25, 0xeb, 0x8d, 0xff, 0x19, 0x0b, 0xa3, 0x40, - 0x52, 0x84, 0x21, 0x60, 0xa3, 0x38, 0x70, 0x90, 0xef, 0x80, 0x9e, 0xd8, 0x57, 0x48, 0xa3, 0xe2, - 0x9d, 0x53, 0x41, 0x6c, 0x4a, 0xb8, 0x63, 0x7b, 0xcc, 0x1a, 0xa5, 0xbe, 0x95, 0xf7, 0x6a, 0x99, - 0x1d, 0xc5, 0xf8, 0x61, 0xec, 0x5c, 0xe3, 0x5b, 0xd0, 0x50, 0x77, 0xc4, 0xdc, 0xc6, 0x9d, 0xe3, - 0xc6, 0x07, 0xd7, 0xa5, 0xf9, 0xfe, 0x67, 0x0d, 0x5a, 0xf1, 0x40, 0x53, 0xaa, 0x94, 0xbb, 0x74, - 0xe5, 0xa6, 0x97, 0x5e, 0x36, 0x0d, 0xc6, 0x11, 0x59, 0xfb, 0xca, 0x11, 0xb9, 0x0f, 0x44, 0x05, - 0xde, 0x85, 0x2f, 0x1c, 0xcf, 0x1e, 0x29, 0x9f, 0xab, 0x08, 0xdc, 0x90, 0x9c, 0x67, 0x92, 0x71, - 0x86, 0xdf, 0x0f, 0x3f, 0xaf, 0x43, 0xe7, 0x78, 0x70, 0x72, 0x7a, 0x1c, 0x04, 0x33, 0x67, 0x42, - 0x65, 0xb7, 0x75, 0x00, 0x35, 0xd9, 0x4f, 0x96, 0xbc, 0x5d, 0xf5, 0xca, 0x06, 0x1b, 0x72, 0x08, - 0x75, 0xd9, 0x56, 0x92, 0xb2, 0x27, 0xac, 0x5e, 0xe9, 0x7c, 0x83, 0x87, 0xa8, 0xc6, 0xf3, 0xfa, - 0x4b, 0x56, 0xaf, 0x6c, 0xc8, 0x21, 0x1f, 0x80, 0x9e, 0x36, 0x84, 0xcb, 0xde, 0xb3, 0x7a, 0x4b, - 0xc7, 0x1d, 0xd4, 0x4f, 0xab, 0xf1, 0xb2, 0x67, 0x99, 0xde, 0xd2, 0xb9, 0x80, 0x1c, 0x41, 0x33, - 0xee, 0x52, 0xca, 0x5f, 0x9c, 0x7a, 0x4b, 0x46, 0x11, 0x74, 0x8f, 0xea, 0xf4, 0xca, 0x9e, 0xc5, - 0x7a, 0xa5, 0xf3, 0x12, 0x79, 0x08, 0x8d, 0xa8, 0xf8, 0x94, 0xbe, 0x3a, 0xf5, 0xca, 0x07, 0x0a, - 0x34, 0x32, 0xed, 0x72, 0x97, 0x3d, 0xdd, 0xf5, 0x96, 0x0e, 0x76, 0xe4, 0x18, 0x20, 0xd3, 0xdd, - 0x2d, 0x7d, 0x93, 0xeb, 0x2d, 0x1f, 0xd8, 0xc8, 0xfb, 0xd0, 0x4a, 0x87, 0xf0, 0xf2, 0x57, 0xb6, - 0xde, 0xb2, 0x19, 0x6a, 0xf0, 0xb5, 0xff, 0xfc, 0x6b, 0x47, 0xfb, 0xed, 0xd5, 0x8e, 0xf6, 0xfb, - 0xab, 0x1d, 0xed, 0x8b, 0xab, 0x1d, 0xed, 0x4f, 0x57, 0x3b, 0xda, 0x3f, 0xaf, 0x76, 0xb4, 0x3f, - 0x7c, 0xb9, 0xa3, 0x8d, 0x1b, 0x32, 0xfc, 0xdf, 0xf9, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x9c, - 0x90, 0xd5, 0xfd, 0x18, 0x16, 0x00, 0x00, +var fileDescriptor_types_d8da2202f45d32c0 = []byte{ + // 1959 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x58, 0x4f, 0x73, 0x1b, 0x49, + 0x15, 0xf7, 0xc8, 0xb2, 0xa4, 0x79, 0xb2, 0x2d, 0xa7, 0x9d, 0xd8, 0x8a, 0x16, 0xec, 0x30, 0x45, + 0x65, 0x1d, 0xd6, 0x2b, 0x83, 0x97, 0x6c, 0x39, 0xbb, 0xb0, 0x85, 0xe5, 0x0d, 0x2b, 0xd7, 0x2e, + 0x60, 0x26, 0xd9, 0x50, 0xc5, 0x45, 0xd5, 0xd2, 0xb4, 0x47, 0x53, 0x91, 0x66, 0x66, 0xa7, 0x5b, + 0x5e, 0x39, 0x1f, 0x81, 0xda, 0xa2, 0xb8, 0x71, 0xe6, 0xc6, 0x17, 0xa0, 0x8a, 0x23, 0x27, 0x6a, + 0x8f, 0x1c, 0xa0, 0xe0, 0x14, 0xc0, 0x5b, 0x5c, 0xf8, 0x04, 0x1c, 0xa9, 0xd7, 0xdd, 0xf3, 0xd7, + 0xa3, 0x54, 0x12, 0x6e, 0x5c, 0xa4, 0xee, 0x7e, 0xef, 0xf5, 0xf4, 0x7b, 0xfd, 0xde, 0xfb, 0xbd, + 0xd7, 0xb0, 0x45, 0x87, 0x23, 0xef, 0x40, 0x5c, 0x86, 0x8c, 0xab, 0xdf, 0x6e, 0x18, 0x05, 0x22, + 0x20, 0x2b, 0x72, 0xd2, 0x79, 0xdb, 0xf5, 0xc4, 0x78, 0x36, 0xec, 0x8e, 0x82, 0xe9, 0x81, 0x1b, + 0xb8, 0xc1, 0x81, 0xa4, 0x0e, 0x67, 0xe7, 0x72, 0x26, 0x27, 0x72, 0xa4, 0xa4, 0x3a, 0xbb, 0x6e, + 0x10, 0xb8, 0x13, 0x96, 0x72, 0x09, 0x6f, 0xca, 0xb8, 0xa0, 0xd3, 0x50, 0x33, 0x1c, 0x65, 0xf6, + 0x13, 0xcc, 0x77, 0x58, 0x34, 0xf5, 0x7c, 0x91, 0x1d, 0x4e, 0xbc, 0x21, 0x3f, 0x18, 0x05, 0xd3, + 0x69, 0xe0, 0x67, 0x0f, 0x64, 0xfd, 0xb1, 0x0a, 0x75, 0x9b, 0x7d, 0x36, 0x63, 0x5c, 0x90, 0x3d, + 0xa8, 0xb2, 0xd1, 0x38, 0x68, 0x57, 0xee, 0x18, 0x7b, 0xcd, 0x43, 0xd2, 0x55, 0x7c, 0x9a, 0xfa, + 0x70, 0x34, 0x0e, 0xfa, 0x4b, 0xb6, 0xe4, 0x20, 0x6f, 0xc1, 0xca, 0xf9, 0x64, 0xc6, 0xc7, 0xed, + 0x65, 0xc9, 0xba, 0x99, 0x67, 0xfd, 0x21, 0x92, 0xfa, 0x4b, 0xb6, 0xe2, 0xc1, 0x6d, 0x3d, 0xff, + 0x3c, 0x68, 0x57, 0xcb, 0xb6, 0x3d, 0xf5, 0xcf, 0xe5, 0xb6, 0xc8, 0x41, 0x8e, 0x00, 0x38, 0x13, + 0x83, 0x20, 0x14, 0x5e, 0xe0, 0xb7, 0x57, 0x24, 0xff, 0x76, 0x9e, 0xff, 0x11, 0x13, 0x3f, 0x91, + 0xe4, 0xfe, 0x92, 0x6d, 0xf2, 0x78, 0x82, 0x92, 0x9e, 0xef, 0x89, 0xc1, 0x68, 0x4c, 0x3d, 0xbf, + 0x5d, 0x2b, 0x93, 0x3c, 0xf5, 0x3d, 0x71, 0x82, 0x64, 0x94, 0xf4, 0xe2, 0x09, 0xaa, 0xf2, 0xd9, + 0x8c, 0x45, 0x97, 0xed, 0x7a, 0x99, 0x2a, 0x3f, 0x45, 0x12, 0xaa, 0x22, 0x79, 0xc8, 0xfb, 0xd0, + 0x1c, 0x32, 0xd7, 0xf3, 0x07, 0xc3, 0x49, 0x30, 0x7a, 0xda, 0x6e, 0x48, 0x91, 0x76, 0x5e, 0xa4, + 0x87, 0x0c, 0x3d, 0xa4, 0xf7, 0x97, 0x6c, 0x18, 0x26, 0x33, 0x72, 0x08, 0x8d, 0xd1, 0x98, 0x8d, + 0x9e, 0x0e, 0xc4, 0xbc, 0x6d, 0x4a, 0xc9, 0x5b, 0x79, 0xc9, 0x13, 0xa4, 0x3e, 0x9e, 0xf7, 0x97, + 0xec, 0xfa, 0x48, 0x0d, 0xc9, 0x7d, 0x30, 0x99, 0xef, 0xe8, 0xcf, 0x35, 0xa5, 0xd0, 0x56, 0xe1, + 0x5e, 0x7c, 0x27, 0xfe, 0x58, 0x83, 0xe9, 0x31, 0xe9, 0x42, 0x0d, 0xef, 0xda, 0x13, 0xed, 0x55, + 0x29, 0x73, 0xb3, 0xf0, 0x21, 0x49, 0xeb, 0x2f, 0xd9, 0x9a, 0x0b, 0xcd, 0xe7, 0xb0, 0x89, 0x77, + 0xc1, 0x22, 0x3c, 0xdc, 0x66, 0x99, 0xf9, 0x3e, 0x54, 0x74, 0x79, 0x3c, 0xd3, 0x89, 0x27, 0xbd, + 0x3a, 0xac, 0x5c, 0xd0, 0xc9, 0x8c, 0x59, 0x6f, 0x42, 0x33, 0xe3, 0x29, 0xa4, 0x0d, 0xf5, 0x29, + 0xe3, 0x9c, 0xba, 0xac, 0x6d, 0xdc, 0x31, 0xf6, 0x4c, 0x3b, 0x9e, 0x5a, 0xeb, 0xb0, 0x9a, 0xf5, + 0x93, 0x8c, 0x20, 0xfa, 0x02, 0x0a, 0x5e, 0xb0, 0x88, 0xa3, 0x03, 0x68, 0x41, 0x3d, 0xb5, 0xde, + 0x83, 0x8d, 0xa2, 0x13, 0x90, 0x0d, 0x58, 0x7e, 0xca, 0x2e, 0x35, 0x27, 0x0e, 0xc9, 0x4d, 0x7d, + 0x20, 0xe9, 0xc5, 0xa6, 0xad, 0x4f, 0xf7, 0x8b, 0x4a, 0x22, 0x9c, 0xf8, 0x01, 0x39, 0x82, 0x2a, + 0x06, 0x92, 0x94, 0x6e, 0x1e, 0x76, 0xba, 0x2a, 0xca, 0xba, 0x71, 0x94, 0x75, 0x1f, 0xc7, 0x51, + 0xd6, 0x6b, 0x7c, 0xf9, 0x7c, 0x77, 0xe9, 0x57, 0x7f, 0xdf, 0x35, 0x6c, 0x29, 0x41, 0x6e, 0xe3, + 0x55, 0x52, 0xcf, 0x1f, 0x78, 0x8e, 0xfe, 0x4e, 0x5d, 0xce, 0x4f, 0x1d, 0x72, 0x0c, 0x1b, 0xa3, + 0xc0, 0xe7, 0xcc, 0xe7, 0x33, 0x3e, 0x08, 0x69, 0x44, 0xa7, 0x5c, 0x47, 0x49, 0x7c, 0x71, 0x27, + 0x31, 0xf9, 0x4c, 0x52, 0xed, 0xd6, 0x28, 0xbf, 0x40, 0xde, 0x05, 0xb8, 0xa0, 0x13, 0xcf, 0xa1, + 0x22, 0x88, 0x78, 0xbb, 0x7a, 0x67, 0x79, 0xaf, 0x79, 0xb8, 0xa1, 0x85, 0x9f, 0xc4, 0x84, 0x5e, + 0x15, 0xcf, 0x64, 0x67, 0x38, 0xc9, 0x5d, 0x68, 0xd1, 0x30, 0x1c, 0x70, 0x41, 0x05, 0x1b, 0x0c, + 0x2f, 0x05, 0xe3, 0x32, 0x86, 0x56, 0xed, 0x35, 0x1a, 0x86, 0x8f, 0x70, 0xb5, 0x87, 0x8b, 0x96, + 0x93, 0xdc, 0x80, 0x74, 0x6f, 0x42, 0xa0, 0xea, 0x50, 0x41, 0xa5, 0x1d, 0x56, 0x6d, 0x39, 0xc6, + 0xb5, 0x90, 0x8a, 0xb1, 0xd6, 0x4e, 0x8e, 0xc9, 0x16, 0xd4, 0xc6, 0xcc, 0x73, 0xc7, 0x42, 0x2a, + 0xb4, 0x6c, 0xeb, 0x19, 0x9a, 0x3c, 0x8c, 0x82, 0x0b, 0x26, 0x23, 0xbc, 0x61, 0xab, 0x89, 0xf5, + 0x2f, 0x03, 0x6e, 0x5c, 0x0b, 0x09, 0xdc, 0x77, 0x4c, 0xf9, 0x38, 0xfe, 0x16, 0x8e, 0xc9, 0x5b, + 0xb8, 0x2f, 0x75, 0x58, 0xa4, 0x33, 0xcf, 0x9a, 0xd6, 0xb5, 0x2f, 0x17, 0xb5, 0xa2, 0x9a, 0x85, + 0x3c, 0x84, 0x8d, 0x09, 0xe5, 0x62, 0xa0, 0x3c, 0x77, 0x20, 0x33, 0xcb, 0x72, 0x2e, 0x9a, 0x3e, + 0xa1, 0xb1, 0x87, 0xa3, 0x43, 0x69, 0xf1, 0xf5, 0x49, 0x6e, 0x95, 0xf4, 0xe1, 0xe6, 0xf0, 0xf2, + 0x19, 0xf5, 0x85, 0xe7, 0xb3, 0xc1, 0x35, 0x6b, 0xb7, 0xf4, 0x56, 0x0f, 0x2f, 0x3c, 0x87, 0xf9, + 0x23, 0xa6, 0x37, 0xd9, 0x4c, 0x44, 0x92, 0x6b, 0xe0, 0xd6, 0x1d, 0x58, 0xcf, 0xc7, 0x2f, 0x59, + 0x87, 0x8a, 0x98, 0x6b, 0x0d, 0x2b, 0x62, 0x6e, 0x59, 0x89, 0xef, 0x25, 0x41, 0x74, 0x8d, 0xe7, + 0x1e, 0xb4, 0x0a, 0x01, 0x9d, 0x31, 0xb7, 0x91, 0x35, 0xb7, 0xd5, 0x82, 0xb5, 0x5c, 0x1c, 0x5b, + 0x5f, 0xac, 0x40, 0xc3, 0x66, 0x3c, 0x44, 0x37, 0x22, 0x47, 0x60, 0xb2, 0xf9, 0x88, 0xa9, 0x14, + 0x6a, 0x14, 0x12, 0x94, 0xe2, 0x79, 0x18, 0xd3, 0x31, 0x94, 0x13, 0x66, 0x72, 0x2f, 0x97, 0xfe, + 0x37, 0x8b, 0x42, 0xd9, 0xfc, 0xbf, 0x9f, 0xcf, 0xff, 0x37, 0x0b, 0xbc, 0x05, 0x00, 0xb8, 0x97, + 0x03, 0x80, 0xe2, 0xc6, 0x39, 0x04, 0x78, 0x50, 0x82, 0x00, 0xc5, 0xe3, 0x2f, 0x80, 0x80, 0x07, + 0x25, 0x10, 0xd0, 0xbe, 0xf6, 0xad, 0x52, 0x0c, 0xd8, 0xcf, 0x63, 0x40, 0x51, 0x9d, 0x02, 0x08, + 0x7c, 0xaf, 0x0c, 0x04, 0x6e, 0x17, 0x64, 0x16, 0xa2, 0xc0, 0x3b, 0xd7, 0x50, 0x60, 0xab, 0x20, + 0x5a, 0x02, 0x03, 0x0f, 0x72, 0xf9, 0x19, 0x4a, 0x75, 0x2b, 0x4f, 0xd0, 0xe4, 0xdd, 0xeb, 0x08, + 0xb2, 0x5d, 0xbc, 0xda, 0x32, 0x08, 0x39, 0x28, 0x40, 0xc8, 0xad, 0xe2, 0x29, 0x0b, 0x18, 0x92, + 0x22, 0xc1, 0x3d, 0x8c, 0xfb, 0x82, 0xa7, 0x61, 0x8e, 0x60, 0x51, 0x14, 0x44, 0x3a, 0x55, 0xab, + 0x89, 0xb5, 0x87, 0x99, 0x28, 0xf5, 0xaf, 0x17, 0xa0, 0x86, 0x74, 0xfa, 0x8c, 0x77, 0x59, 0xbf, + 0x36, 0x52, 0x59, 0x19, 0xd1, 0xd9, 0x2c, 0x66, 0xea, 0x2c, 0x96, 0x01, 0x93, 0x4a, 0x0e, 0x4c, + 0xc8, 0xb7, 0xe0, 0x86, 0x4c, 0x23, 0xd2, 0x2e, 0x83, 0x5c, 0x5a, 0x6b, 0x21, 0x41, 0x19, 0x44, + 0xe5, 0xb7, 0xb7, 0x61, 0x33, 0xc3, 0x8b, 0x29, 0x56, 0xa6, 0xb0, 0xaa, 0x0c, 0xde, 0x8d, 0x84, + 0xfb, 0x38, 0x0c, 0xfb, 0x94, 0x8f, 0xad, 0x1f, 0xa5, 0xfa, 0xa7, 0x40, 0x45, 0xa0, 0x3a, 0x0a, + 0x1c, 0xa5, 0xd6, 0x9a, 0x2d, 0xc7, 0x08, 0x5e, 0x93, 0xc0, 0x95, 0x5f, 0x35, 0x6d, 0x1c, 0x22, + 0x57, 0x12, 0x29, 0xa6, 0x0a, 0x09, 0xeb, 0x97, 0x46, 0xba, 0x5f, 0x8a, 0x5d, 0x65, 0x30, 0x63, + 0xfc, 0x2f, 0x30, 0x53, 0x79, 0x59, 0x98, 0xb1, 0x7e, 0x67, 0xa4, 0x77, 0x91, 0x00, 0xc8, 0xeb, + 0x29, 0x87, 0x6e, 0xe1, 0xf9, 0x0e, 0x9b, 0xcb, 0x50, 0x5f, 0xb6, 0xd5, 0x24, 0x46, 0xf5, 0x9a, + 0x34, 0x70, 0x1e, 0xd5, 0xeb, 0x72, 0x4d, 0x4d, 0x34, 0xf0, 0x04, 0xe7, 0x32, 0x06, 0x57, 0x6d, + 0x35, 0xc9, 0xe4, 0x4d, 0x33, 0x97, 0x37, 0xcf, 0x80, 0x5c, 0x8f, 0x4e, 0xf2, 0x1e, 0x54, 0x05, + 0x75, 0xd1, 0x78, 0xa8, 0xff, 0x7a, 0x57, 0xd5, 0xc8, 0xdd, 0x8f, 0x9f, 0x9c, 0x51, 0x2f, 0xea, + 0x6d, 0xa1, 0xf6, 0xff, 0x7e, 0xbe, 0xbb, 0x8e, 0x3c, 0xfb, 0xc1, 0xd4, 0x13, 0x6c, 0x1a, 0x8a, + 0x4b, 0x5b, 0xca, 0x58, 0x7f, 0x31, 0x30, 0x6b, 0xe7, 0xa2, 0xb6, 0xd4, 0x16, 0xb1, 0x6b, 0x56, + 0x32, 0x00, 0xfb, 0x72, 0xf6, 0xf9, 0x3a, 0x80, 0x4b, 0xf9, 0xe0, 0x73, 0xea, 0x0b, 0xe6, 0x68, + 0x23, 0x99, 0x2e, 0xe5, 0x3f, 0x93, 0x0b, 0x58, 0x87, 0x20, 0x79, 0xc6, 0x99, 0x23, 0xad, 0xb5, + 0x6c, 0xd7, 0x5d, 0xca, 0x3f, 0xe5, 0xcc, 0x49, 0xf4, 0xaa, 0xbf, 0x86, 0x5e, 0x7f, 0xcd, 0xb8, + 0x5c, 0x0a, 0x59, 0xff, 0x0f, 0x9a, 0x7d, 0x65, 0x20, 0x16, 0xe7, 0xd3, 0x1e, 0x39, 0x81, 0x1b, + 0x89, 0x7b, 0x0f, 0x66, 0xa1, 0x43, 0xb1, 0x72, 0x32, 0x5e, 0x18, 0x0f, 0x1b, 0x89, 0xc0, 0xa7, + 0x8a, 0x9f, 0xfc, 0x18, 0xb6, 0x0b, 0x01, 0x99, 0x6c, 0x55, 0x79, 0x61, 0x5c, 0xde, 0xca, 0xc7, + 0x65, 0xbc, 0x5f, 0xac, 0xe5, 0xf2, 0x6b, 0x68, 0xf9, 0x4d, 0x2c, 0x49, 0xb2, 0x69, 0xba, 0xec, + 0x9e, 0xac, 0xdf, 0x18, 0xd0, 0x2a, 0x1c, 0x86, 0x1c, 0x00, 0xa8, 0x2c, 0xc7, 0xbd, 0x67, 0x71, + 0x61, 0x1c, 0xdb, 0x40, 0x1a, 0xeb, 0x91, 0xf7, 0x8c, 0xd9, 0xe6, 0x30, 0x1e, 0x92, 0xbb, 0x50, + 0x17, 0x73, 0xc5, 0x9d, 0x2f, 0xde, 0x1e, 0xcf, 0x25, 0x6b, 0x4d, 0xc8, 0x7f, 0x72, 0x1f, 0x56, + 0xd5, 0xc6, 0x6e, 0xc0, 0xb9, 0x17, 0xea, 0xc2, 0x81, 0x64, 0xb7, 0xfe, 0x48, 0x52, 0xec, 0xe6, + 0x30, 0x9d, 0x58, 0x3f, 0x07, 0x33, 0xf9, 0x2c, 0x79, 0x03, 0xcc, 0x29, 0x9d, 0xeb, 0xca, 0x16, + 0xcf, 0xb6, 0x62, 0x37, 0xa6, 0x74, 0x2e, 0x8b, 0x5a, 0xb2, 0x0d, 0x75, 0x24, 0x8a, 0xb9, 0xb2, + 0xf7, 0x8a, 0x5d, 0x9b, 0xd2, 0xf9, 0xe3, 0x79, 0x42, 0x70, 0x29, 0x8f, 0xcb, 0xd6, 0x29, 0x9d, + 0x7f, 0x44, 0xb9, 0xf5, 0x01, 0xd4, 0xd4, 0x21, 0x5f, 0x6a, 0x63, 0x94, 0xaf, 0xe4, 0xe4, 0x7f, + 0x00, 0xcd, 0xcc, 0xb9, 0xc9, 0x77, 0xe0, 0x96, 0xd2, 0x30, 0xa4, 0x91, 0x90, 0x16, 0xc9, 0x6d, + 0x48, 0x24, 0xf1, 0x8c, 0x46, 0x02, 0x3f, 0xa9, 0x0a, 0xf1, 0x08, 0xd6, 0xf3, 0xc5, 0x2a, 0xf9, + 0x06, 0xac, 0xea, 0xc2, 0x36, 0x0a, 0x66, 0xbe, 0xa3, 0x65, 0x9b, 0x6a, 0xcd, 0xc6, 0x25, 0xf2, + 0xfd, 0x92, 0xb4, 0x1d, 0x23, 0xfa, 0x23, 0xcf, 0xf5, 0x3d, 0xdf, 0x7d, 0x51, 0xf6, 0xfe, 0x5b, + 0x05, 0x6a, 0xaa, 0xb0, 0x26, 0x77, 0x33, 0x5d, 0x8c, 0x44, 0xcd, 0x5e, 0xf3, 0xea, 0xf9, 0x6e, + 0x5d, 0x02, 0xcc, 0xe9, 0x87, 0x69, 0x4b, 0x93, 0x26, 0xd4, 0x4a, 0xae, 0xee, 0x8f, 0xfb, 0xa7, + 0xe5, 0x57, 0xee, 0x9f, 0xb6, 0xa1, 0xee, 0xcf, 0xa6, 0xf2, 0xb2, 0xaa, 0xea, 0xb2, 0xfc, 0xd9, + 0x14, 0x2f, 0xeb, 0x0d, 0x30, 0x45, 0x20, 0xe8, 0x44, 0x92, 0x54, 0x52, 0x68, 0xc8, 0x05, 0x24, + 0xde, 0x85, 0x56, 0x16, 0xb3, 0x11, 0x83, 0x15, 0x44, 0xac, 0xa5, 0x88, 0x8d, 0xfd, 0xc4, 0x9b, + 0xd0, 0x4a, 0x15, 0x56, 0x7c, 0x0a, 0x36, 0xd6, 0xd3, 0x65, 0xc9, 0x78, 0x1b, 0x1a, 0x09, 0x9a, + 0x2b, 0x08, 0xa9, 0x53, 0x05, 0xe2, 0xd8, 0xac, 0x87, 0x51, 0x10, 0x06, 0x9c, 0x45, 0xba, 0x4c, + 0x5b, 0x94, 0x0a, 0x12, 0x3e, 0xcb, 0x03, 0x33, 0x21, 0x62, 0xe9, 0x41, 0x1d, 0x27, 0x62, 0x9c, + 0xeb, 0x2a, 0x3f, 0x9e, 0x92, 0x7d, 0xa8, 0x87, 0xb3, 0xe1, 0x00, 0x11, 0x2e, 0x1f, 0x32, 0x67, + 0xb3, 0xe1, 0xc7, 0xec, 0x32, 0xee, 0x77, 0x42, 0x39, 0x93, 0x18, 0x17, 0x7c, 0xce, 0x22, 0xed, + 0xbc, 0x6a, 0x62, 0x09, 0xd8, 0x28, 0xde, 0x35, 0xf9, 0x2e, 0x98, 0x89, 0x7e, 0x85, 0xd0, 0x2d, + 0x9e, 0x39, 0x65, 0xc4, 0x42, 0x88, 0x7b, 0xae, 0xcf, 0x9c, 0x41, 0x6a, 0x5b, 0x79, 0xae, 0x86, + 0xdd, 0x52, 0x84, 0x4f, 0x62, 0xe3, 0x5a, 0xdf, 0x86, 0x9a, 0x3a, 0x23, 0xe6, 0x13, 0xdc, 0x39, + 0x2e, 0xb6, 0x70, 0x5c, 0x9a, 0x63, 0xfe, 0x6c, 0x40, 0x23, 0x6e, 0xa2, 0x4a, 0x85, 0x72, 0x87, + 0xae, 0xbc, 0xec, 0xa1, 0x17, 0x75, 0xa2, 0xb1, 0x47, 0x56, 0x5f, 0xd9, 0x23, 0xf7, 0x81, 0x28, + 0xc7, 0xbb, 0x08, 0x84, 0xe7, 0xbb, 0x03, 0x65, 0x73, 0xe5, 0x81, 0x1b, 0x92, 0xf2, 0x44, 0x12, + 0xce, 0x70, 0xfd, 0xf0, 0x8b, 0x15, 0x68, 0x1d, 0xf7, 0x4e, 0x4e, 0x8f, 0xc3, 0x70, 0xe2, 0x8d, + 0xa8, 0xac, 0xf0, 0x0e, 0xa0, 0x2a, 0x6b, 0xd8, 0x92, 0x77, 0xb3, 0x4e, 0x59, 0x33, 0x45, 0x0e, + 0x61, 0x45, 0x96, 0xb2, 0xa4, 0xec, 0xf9, 0xac, 0x53, 0xda, 0x53, 0xe1, 0x47, 0x54, 0xb1, 0x7b, + 0xfd, 0x15, 0xad, 0x53, 0xd6, 0x58, 0x91, 0x0f, 0xc0, 0x4c, 0x8b, 0xd0, 0x45, 0x6f, 0x69, 0x9d, + 0x85, 0x2d, 0x16, 0xca, 0xa7, 0x15, 0xc0, 0xa2, 0x27, 0xa1, 0xce, 0xc2, 0x5e, 0x84, 0x1c, 0x41, + 0x3d, 0xae, 0x8c, 0xca, 0x5f, 0xbb, 0x3a, 0x0b, 0xda, 0x1f, 0x34, 0x8f, 0xaa, 0x2e, 0xcb, 0x9e, + 0xe4, 0x3a, 0xa5, 0x3d, 0x1a, 0xb9, 0x0f, 0x35, 0x0d, 0x78, 0xa5, 0x2f, 0x5e, 0x9d, 0xf2, 0x26, + 0x06, 0x95, 0x4c, 0x2b, 0xeb, 0x45, 0xcf, 0x86, 0x9d, 0x85, 0xcd, 0x24, 0x39, 0x06, 0xc8, 0x54, + 0x94, 0x0b, 0xdf, 0x03, 0x3b, 0x8b, 0x9b, 0x44, 0xf2, 0x3e, 0x34, 0xd2, 0xc6, 0xbf, 0xfc, 0x85, + 0xaf, 0xb3, 0xa8, 0x6f, 0xeb, 0x7d, 0xed, 0x3f, 0xff, 0xdc, 0x31, 0x7e, 0x7b, 0xb5, 0x63, 0xfc, + 0xfe, 0x6a, 0xc7, 0xf8, 0xf2, 0x6a, 0xc7, 0xf8, 0xd3, 0xd5, 0x8e, 0xf1, 0x8f, 0xab, 0x1d, 0xe3, + 0x0f, 0x5f, 0xed, 0x18, 0xc3, 0x9a, 0x74, 0xff, 0x77, 0xfe, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xc1, + 0xc2, 0x93, 0xfb, 0x94, 0x16, 0x00, 0x00, } diff --git a/abci/types/types.proto b/abci/types/types.proto index 7f87628e1..6e6b1cd36 100644 --- a/abci/types/types.proto +++ b/abci/types/types.proto @@ -71,10 +71,11 @@ message RequestQuery { bool prove = 4; } +// NOTE: validators here have empty pubkeys. message RequestBeginBlock { bytes hash = 1; Header header = 2 [(gogoproto.nullable)=false]; - repeated SigningValidator validators = 3 [(gogoproto.nullable)=false]; + LastCommitInfo last_commit_info = 3 [(gogoproto.nullable)=false]; repeated Evidence byzantine_validators = 4 [(gogoproto.nullable)=false]; } @@ -203,14 +204,14 @@ message ConsensusParams { BlockGossip block_gossip = 3; } -// BlockSize contain limits on the block size. +// BlockSize contains limits on the block size. message BlockSize { int32 max_bytes = 1; int32 max_txs = 2; int64 max_gas = 3; } -// TxSize contain limits on the tx size. +// TxSize contains limits on the tx size. message TxSize { int32 max_bytes = 1; int64 max_gas = 2; @@ -223,6 +224,11 @@ message BlockGossip { int32 block_part_size_bytes = 1; } +message LastCommitInfo { + int32 commit_round = 1; + repeated SigningValidator validators = 2 [(gogoproto.nullable)=false]; +} + //---------------------------------------- // Blockchain Types diff --git a/abci/types/typespb_test.go b/abci/types/typespb_test.go index db88ed394..33a368af4 100644 --- a/abci/types/typespb_test.go +++ b/abci/types/typespb_test.go @@ -1646,6 +1646,62 @@ func TestBlockGossipMarshalTo(t *testing.T) { } } +func TestLastCommitInfoProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLastCommitInfo(popr, false) + dAtA, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &LastCommitInfo{} + if err := github_com_gogo_protobuf_proto.Unmarshal(dAtA, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + littlefuzz := make([]byte, len(dAtA)) + copy(littlefuzz, dAtA) + for i := range dAtA { + dAtA[i] = byte(popr.Intn(256)) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) + } +} + +func TestLastCommitInfoMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLastCommitInfo(popr, false) + size := p.Size() + dAtA := make([]byte, size) + for i := range dAtA { + dAtA[i] = byte(popr.Intn(256)) + } + _, err := p.MarshalTo(dAtA) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &LastCommitInfo{} + if err := github_com_gogo_protobuf_proto.Unmarshal(dAtA, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + for i := range dAtA { + dAtA[i] = byte(popr.Intn(256)) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } +} + func TestHeaderProto(t *testing.T) { seed := time.Now().UnixNano() popr := math_rand.New(math_rand.NewSource(seed)) @@ -2448,6 +2504,24 @@ func TestBlockGossipJSON(t *testing.T) { t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } +func TestLastCommitInfoJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLastCommitInfo(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &LastCommitInfo{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) + } +} func TestHeaderJSON(t *testing.T) { seed := time.Now().UnixNano() popr := math_rand.New(math_rand.NewSource(seed)) @@ -3350,6 +3424,34 @@ func TestBlockGossipProtoCompactText(t *testing.T) { } } +func TestLastCommitInfoProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLastCommitInfo(popr, true) + dAtA := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &LastCommitInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(dAtA, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } +} + +func TestLastCommitInfoProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLastCommitInfo(popr, true) + dAtA := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &LastCommitInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(dAtA, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } +} + func TestHeaderProtoText(t *testing.T) { seed := time.Now().UnixNano() popr := math_rand.New(math_rand.NewSource(seed)) @@ -4128,6 +4230,28 @@ func TestBlockGossipSize(t *testing.T) { } } +func TestLastCommitInfoSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLastCommitInfo(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + dAtA, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(dAtA) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(dAtA)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + func TestHeaderSize(t *testing.T) { seed := time.Now().UnixNano() popr := math_rand.New(math_rand.NewSource(seed)) diff --git a/blockchain/reactor.go b/blockchain/reactor.go index eadeedc91..f00df50c3 100644 --- a/blockchain/reactor.go +++ b/blockchain/reactor.go @@ -109,9 +109,6 @@ func (bcR *BlockchainReactor) SetLogger(l log.Logger) { // OnStart implements cmn.Service. func (bcR *BlockchainReactor) OnStart() error { - if err := bcR.BaseReactor.OnStart(); err != nil { - return err - } if bcR.fastSync { err := bcR.pool.Start() if err != nil { @@ -124,7 +121,6 @@ func (bcR *BlockchainReactor) OnStart() error { // OnStop implements cmn.Service. func (bcR *BlockchainReactor) OnStop() { - bcR.BaseReactor.OnStop() bcR.pool.Stop() } diff --git a/consensus/common_test.go b/consensus/common_test.go index 2df226ba1..f4855992d 100644 --- a/consensus/common_test.go +++ b/consensus/common_test.go @@ -17,14 +17,14 @@ import ( bc "github.com/tendermint/tendermint/blockchain" cfg "github.com/tendermint/tendermint/config" cstypes "github.com/tendermint/tendermint/consensus/types" + cmn "github.com/tendermint/tendermint/libs/common" + dbm "github.com/tendermint/tendermint/libs/db" + "github.com/tendermint/tendermint/libs/log" mempl "github.com/tendermint/tendermint/mempool" "github.com/tendermint/tendermint/p2p" "github.com/tendermint/tendermint/privval" sm "github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/types" - cmn "github.com/tendermint/tendermint/libs/common" - dbm "github.com/tendermint/tendermint/libs/db" - "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/abci/example/counter" "github.com/tendermint/tendermint/abci/example/kvstore" @@ -378,8 +378,11 @@ func randConsensusNetWithPeers(nValidators, nPeers int, testName string, tickerF if i < nValidators { privVal = privVals[i] } else { - _, tempFilePath := cmn.Tempfile("priv_validator_") - privVal = privval.GenFilePV(tempFilePath) + tempFile, err := ioutil.TempFile("", "priv_validator_") + if err != nil { + panic(err) + } + privVal = privval.GenFilePV(tempFile.Name()) } app := appFunc() @@ -429,7 +432,7 @@ func randGenesisDoc(numValidators int, randPower bool, minPower int64) (*types.G func randGenesisState(numValidators int, randPower bool, minPower int64) (sm.State, []types.PrivValidator) { genDoc, privValidators := randGenesisDoc(numValidators, randPower, minPower) s0, _ := sm.MakeGenesisState(genDoc) - db := dbm.NewMemDB() + db := dbm.NewMemDB() // remove this ? sm.SaveState(db, s0) return s0, privValidators } diff --git a/consensus/reactor.go b/consensus/reactor.go index 3eb1d73aa..58ff42ae2 100644 --- a/consensus/reactor.go +++ b/consensus/reactor.go @@ -58,9 +58,6 @@ func NewConsensusReactor(consensusState *ConsensusState, fastSync bool) *Consens // broadcasted to other peers and starting state if we're not in fast sync. func (conR *ConsensusReactor) OnStart() error { conR.Logger.Info("ConsensusReactor ", "fastSync", conR.FastSync()) - if err := conR.BaseReactor.OnStart(); err != nil { - return err - } conR.subscribeToBroadcastEvents() @@ -77,7 +74,6 @@ func (conR *ConsensusReactor) OnStart() error { // OnStop implements BaseService by unsubscribing from events and stopping // state. func (conR *ConsensusReactor) OnStop() { - conR.BaseReactor.OnStop() conR.unsubscribeFromBroadcastEvents() conR.conS.Stop() if !conR.FastSync() { diff --git a/consensus/reactor_test.go b/consensus/reactor_test.go index 90def612b..63dd9075f 100644 --- a/consensus/reactor_test.go +++ b/consensus/reactor_test.go @@ -4,15 +4,21 @@ import ( "context" "fmt" "os" + "path" "runtime" "runtime/pprof" "sync" "testing" "time" + abcicli "github.com/tendermint/tendermint/abci/client" "github.com/tendermint/tendermint/abci/example/kvstore" + abci "github.com/tendermint/tendermint/abci/types" + bc "github.com/tendermint/tendermint/blockchain" cmn "github.com/tendermint/tendermint/libs/common" + dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" + mempl "github.com/tendermint/tendermint/mempool" sm "github.com/tendermint/tendermint/state" cfg "github.com/tendermint/tendermint/config" @@ -94,49 +100,118 @@ func TestReactorBasic(t *testing.T) { // Ensure we can process blocks with evidence func TestReactorWithEvidence(t *testing.T) { - N := 4 - css := randConsensusNet(N, "consensus_reactor_test", newMockTickerFunc(true), newCounter) - evpool := mockEvidencePool{ - t: t, - ev: []types.Evidence{types.NewMockGoodEvidence(1, 1, []byte("somone"))}, + nValidators := 4 + testName := "consensus_reactor_test" + tickerFunc := newMockTickerFunc(true) + appFunc := newCounter + + // heed the advice from https://www.sandimetz.com/blog/2016/1/20/the-wrong-abstraction + // to unroll unwieldy abstractions. Here we duplicate the code from: + // css := randConsensusNet(N, "consensus_reactor_test", newMockTickerFunc(true), newCounter) + + genDoc, privVals := randGenesisDoc(nValidators, false, 30) + css := make([]*ConsensusState, nValidators) + logger := consensusLogger() + for i := 0; i < nValidators; i++ { + stateDB := dbm.NewMemDB() // each state needs its own db + state, _ := sm.LoadStateFromDBOrGenesisDoc(stateDB, genDoc) + thisConfig := ResetConfig(cmn.Fmt("%s_%d", testName, i)) + ensureDir(path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal + app := appFunc() + vals := types.TM2PB.Validators(state.Validators) + app.InitChain(abci.RequestInitChain{Validators: vals}) + + pv := privVals[i] + // duplicate code from: + // css[i] = newConsensusStateWithConfig(thisConfig, state, privVals[i], app) + + blockDB := dbm.NewMemDB() + blockStore := bc.NewBlockStore(blockDB) + + // one for mempool, one for consensus + mtx := new(sync.Mutex) + proxyAppConnMem := abcicli.NewLocalClient(mtx, app) + proxyAppConnCon := abcicli.NewLocalClient(mtx, app) + + // Make Mempool + mempool := mempl.NewMempool(thisConfig.Mempool, proxyAppConnMem, 0) + mempool.SetLogger(log.TestingLogger().With("module", "mempool")) + if thisConfig.Consensus.WaitForTxs() { + mempool.EnableTxsAvailable() + } + + // mock the evidence pool + // everyone includes evidence of another double signing + vIdx := (i + 1) % nValidators + evpool := newMockEvidencePool(privVals[vIdx].GetAddress()) + + // Make ConsensusState + blockExec := sm.NewBlockExecutor(stateDB, log.TestingLogger(), proxyAppConnCon, mempool, evpool) + cs := NewConsensusState(thisConfig.Consensus, state, blockExec, blockStore, mempool, evpool) + cs.SetLogger(log.TestingLogger().With("module", "consensus")) + cs.SetPrivValidator(pv) + + eventBus := types.NewEventBus() + eventBus.SetLogger(log.TestingLogger().With("module", "events")) + eventBus.Start() + cs.SetEventBus(eventBus) + + cs.SetTimeoutTicker(tickerFunc()) + cs.SetLogger(logger.With("validator", i, "module", "consensus")) + + css[i] = cs } - for i := 0; i < N; i++ { - css[i].evpool = evpool - } - reactors, eventChans, eventBuses := startConsensusNet(t, css, N) + + reactors, eventChans, eventBuses := startConsensusNet(t, css, nValidators) defer stopConsensusNet(log.TestingLogger(), reactors, eventBuses) - // wait till everyone makes the first new block - timeoutWaitGroup(t, N, func(j int) { - <-eventChans[j] + + // wait till everyone makes the first new block with no evidence + timeoutWaitGroup(t, nValidators, func(j int) { + blockI := <-eventChans[j] + block := blockI.(types.EventDataNewBlock).Block + assert.True(t, len(block.Evidence.Evidence) == 0) }, css) // second block should have evidence - timeoutWaitGroup(t, N, func(j int) { - <-eventChans[j] + timeoutWaitGroup(t, nValidators, func(j int) { + blockI := <-eventChans[j] + block := blockI.(types.EventDataNewBlock).Block + assert.True(t, len(block.Evidence.Evidence) > 0) }, css) } +// mock evidence pool returns no evidence for block 1, +// and returnes one piece for all higher blocks. The one piece +// is for a given validator at block 1. type mockEvidencePool struct { height int ev []types.Evidence - t *testing.T } -func (m mockEvidencePool) PendingEvidence() []types.Evidence { +func newMockEvidencePool(val []byte) *mockEvidencePool { + return &mockEvidencePool{ + ev: []types.Evidence{types.NewMockGoodEvidence(1, 1, val)}, + } +} + +func (m *mockEvidencePool) PendingEvidence() []types.Evidence { if m.height > 0 { return m.ev } return nil } -func (m mockEvidencePool) AddEvidence(types.Evidence) error { return nil } -func (m mockEvidencePool) Update(block *types.Block, state sm.State) { - m.height += 1 - +func (m *mockEvidencePool) AddEvidence(types.Evidence) error { return nil } +func (m *mockEvidencePool) Update(block *types.Block, state sm.State) { if m.height > 0 { - require.True(m.t, len(block.Evidence.Evidence) > 0) + if len(block.Evidence.Evidence) == 0 { + panic("block has no evidence") + } } + m.height += 1 } +//------------------------------------ + // Ensure a testnet sends proposal heartbeats and makes blocks when there are txs func TestReactorProposalHeartbeats(t *testing.T) { N := 4 diff --git a/docs/app-dev/abci-spec.md b/docs/app-dev/abci-spec.md index 0e5eb0044..770740b86 100644 --- a/docs/app-dev/abci-spec.md +++ b/docs/app-dev/abci-spec.md @@ -160,9 +160,8 @@ See below for more details on the message types and how they are used. - **Request**: - `Hash ([]byte)`: The block's hash. This can be derived from the block header. - - `Header (struct{})`: The block header - - `Validators ([]SigningValidator)`: List of validators in the current validator - set and whether or not they signed a vote in the LastCommit + - `Header (struct{})`: The block header. + - `LastCommitInfo (LastCommitInfo)`: Info about the last commit. - `ByzantineValidators ([]Evidence)`: List of evidence of validators that acted maliciously - **Response**: @@ -171,8 +170,9 @@ See below for more details on the message types and how they are used. - Signals the beginning of a new block. Called prior to any DeliverTxs. - The header is expected to at least contain the Height. - - The `Validators` and `ByzantineValidators` can be used to - determine rewards and punishments for the validators. + - The `LastCommitInfo` and `ByzantineValidators` can be used to determine + rewards and punishments for the validators. NOTE validators here do not + include pubkeys. ### CheckTx @@ -326,3 +326,10 @@ See below for more details on the message types and how they are used. It is the proposer's local time when block was created. - `TotalVotingPower (int64)`: Total voting power of the validator set at height `Height` + +### LastCommitInfo + +- **Fields**: + - `CommitRound (int32)`: Commit round. + - `Validators ([]SigningValidator)`: List of validators in the current + validator set and whether or not they signed a vote. diff --git a/docs/app-dev/app-development.md b/docs/app-dev/app-development.md index a795673f1..d3f22362b 100644 --- a/docs/app-dev/app-development.md +++ b/docs/app-dev/app-development.md @@ -365,14 +365,14 @@ ResponseBeginBlock requestBeginBlock(RequestBeginBlock req) { ### EndBlock -The EndBlock request can be used to run some code at the end of every -block. Additionally, the response may contain a list of validators, -which can be used to update the validator set. To add a new validator or -update an existing one, simply include them in the list returned in the -EndBlock response. To remove one, include it in the list with a `power` -equal to `0`. Tendermint core will take care of updating the validator -set. Note the change in voting power must be strictly less than 1/3 per -block if you want a light client to be able to prove the transition +The EndBlock request can be used to run some code at the end of every block. +Additionally, the response may contain a list of validators, which can be used +to update the validator set. To add a new validator or update an existing one, +simply include them in the list returned in the EndBlock response. To remove +one, include it in the list with a `power` equal to `0`. Validator's `address` +field can be left empty. Tendermint core will take care of updating the +validator set. Note the change in voting power must be strictly less than 1/3 +per block if you want a light client to be able to prove the transition externally. See the [light client docs](https://godoc.org/github.com/tendermint/tendermint/lite#hdr-How_We_Track_Validators) for details on how it tracks validators. diff --git a/docs/architecture/adr-015-crypto-encoding.md b/docs/architecture/adr-015-crypto-encoding.md new file mode 100644 index 000000000..983411270 --- /dev/null +++ b/docs/architecture/adr-015-crypto-encoding.md @@ -0,0 +1,80 @@ +# ADR 015: Crypto encoding + +## Context + +We must standardize our method for encoding public keys and signatures on chain. +Currently we amino encode the public keys and signatures. +The reason we are using amino here is primarily due to ease of support in +parsing for other languages. +We don't need its upgradability properties in cryptosystems, as a change in +the crypto that requires adapting the encoding, likely warrants being deemed +a new cryptosystem. +(I.e. using new public parameters) + +## Decision + +### Public keys + +For public keys, we will continue to use amino encoding on the canonical +representation of the pubkey. +(Canonical as defined by the cryptosystem itself) +This has two significant drawbacks. +Amino encoding is less space-efficient, due to requiring support for upgradability. +Amino encoding support requires forking protobuf and adding this new interface support +option in the langauge of choice. + +The reason for continuing to use amino however is that people can create code +more easily in languages that already have an up to date amino library. +It is possible that this will change in the future, if it is deemed that +requiring amino for interacting with tendermint cryptography is unneccessary. + +The arguments for space efficiency here are refuted on the basis that there are +far more egregious wastages of space in the SDK. +The space requirement of the public keys doesn't cause many problems beyond +increasing the space attached to each validator / account. + +The alternative to using amino here would be for us to create an enum type. +Switching to just an enum type is worthy of investigation post-launch. +For referrence, part of amino encoding interfaces is basically a 4 byte enum +type definition. +Enum types would just change that 4 bytes to be a varuint, and it would remove +the protobuf overhead, but it would be hard to integrate into the existing API. + +### Signatures + +Signatures should be switched to be `[]byte`. +Spatial efficiency in the signatures is quite important, +as it directly affects the gas cost of every transaction, +and the throughput of the chain. +Signatures don't need to encode what type they are for (unlike public keys) +since public keys must already be known. +Therefore we can validate the signature without needing to encode its type. + +When placed in state, signatures will still be amino encoded, but it will be the +primitive type `[]byte` getting encoded. + +#### Ed25519 +Use the canonical representation for signatures. + +#### Secp256k1 +There isn't a clear canonical representation here. +Signatures have two elements `r,s`. +We should encode these bytes as `r || s`, where `r` and `s` are both exactly +32 bytes long. +This is basically Ethereum's encoding, but without the leading recovery bit. + +## Status + +Proposed. The signature section seems to be agreed upon for the most part. +Needs decision on Enum types. + +## Consequences + +### Positive +* More space efficient signatures + +### Negative +* We have an amino dependency for cryptography. + +### Neutral +* No change to public keys \ No newline at end of file diff --git a/docs/spec/blockchain/blockchain.md b/docs/spec/blockchain/blockchain.md index eb34f4c87..e3171818a 100644 --- a/docs/spec/blockchain/blockchain.md +++ b/docs/spec/blockchain/blockchain.md @@ -52,7 +52,8 @@ type Header struct { // application ResultsHash []byte // SimpleMerkle of []abci.Result from prevBlock AppHash []byte // Arbitrary state digest - ValidatorsHash []byte // SimpleMerkle of the ValidatorSet + ValidatorsHash []byte // SimpleMerkle of the current ValidatorSet + NextValidatorsHash []byte // SimpleMerkle of the next ValidatorSet ConsensusParamsHash []byte // SimpleMerkle of the ConsensusParams // consensus @@ -160,9 +161,12 @@ We refer to certain globally available objects: `block` is the block under consideration, `prevBlock` is the `block` at the previous height, and `state` keeps track of the validator set, the consensus parameters -and other results from the application. +and other results from the application. At the point when `block` is the block under consideration, +the current version of the `state` corresponds to the state +after executing transactions from the `prevBlock`. Elements of an object are accessed as expected, -ie. `block.Header`. See [here](https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/state.md) for the definition of `state`. +ie. `block.Header`. +See [here](https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/state.md) for the definition of `state`. ### Header @@ -278,7 +282,14 @@ block.ValidatorsHash == SimpleMerkleRoot(state.Validators) Simple Merkle root of the current validator set that is committing the block. This can be used to validate the `LastCommit` included in the next block. -May be updated by the application. + +### NextValidatorsHash + +```go +block.NextValidatorsHash == SimpleMerkleRoot(state.NextValidators) +``` +Simple Merkle root of the next validator set that will be the validator set that commits the next block. +Modifications to the validator set are defined by the application. ### ConsensusParamsHash @@ -407,25 +418,20 @@ set (TODO). Execute is defined as: ```go Execute(s State, app ABCIApp, block Block) State { - TODO: just spell out ApplyBlock here - and remove ABCIResponses struct. - abciResponses := app.ApplyBlock(block) + // Fuction ApplyBlock executes block of transactions against the app and returns the new root hash of the app state, + // modifications to the validator set and the changes of the consensus parameters. + AppHash, ValidatorChanges, ConsensusParamChanges := app.ApplyBlock(block) return State{ LastResults: abciResponses.DeliverTxResults, - AppHash: abciResponses.AppHash, - Validators: UpdateValidators(state.Validators, abciResponses.ValidatorChanges), + AppHash: AppHash, LastValidators: state.Validators, - ConsensusParams: UpdateConsensusParams(state.ConsensusParams, abci.Responses.ConsensusParamChanges), + Validators: state.NextValidators, + NextValidators: UpdateValidators(state.NextValidators, ValidatorChanges), + ConsensusParams: UpdateConsensusParams(state.ConsensusParams, ConsensusParamChanges), } } -type ABCIResponses struct { - DeliverTxResults []Result - ValidatorChanges []Validator - ConsensusParamChanges ConsensusParams - AppHash []byte -} ``` diff --git a/docs/spec/blockchain/state.md b/docs/spec/blockchain/state.md index 3b374f70a..df86cd450 100644 --- a/docs/spec/blockchain/state.md +++ b/docs/spec/blockchain/state.md @@ -3,7 +3,7 @@ ## State The state contains information whose cryptographic digest is included in block headers, and thus is -necessary for validating new blocks. For instance, the set of validators and the results of +necessary for validating new blocks. For instance, the validators set and the results of transactions are never included in blocks, but their Merkle roots are - the state keeps track of them. Note that the `State` object itself is an implementation detail, since it is never @@ -18,8 +18,9 @@ type State struct { LastResults []Result AppHash []byte - Validators []Validator LastValidators []Validator + Validators []Validator + NextValidators []Validator ConsensusParams ConsensusParams } diff --git a/evidence/reactor.go b/evidence/reactor.go index bf11ac105..cfe47364c 100644 --- a/evidence/reactor.go +++ b/evidence/reactor.go @@ -44,11 +44,6 @@ func (evR *EvidenceReactor) SetLogger(l log.Logger) { evR.evpool.SetLogger(l) } -// OnStart implements cmn.Service -func (evR *EvidenceReactor) OnStart() error { - return evR.BaseReactor.OnStart() -} - // GetChannels implements Reactor. // It returns the list of channels for this reactor. func (evR *EvidenceReactor) GetChannels() []*p2p.ChannelDescriptor { diff --git a/libs/autofile/autofile_test.go b/libs/autofile/autofile_test.go index b39fb7cf3..67397380b 100644 --- a/libs/autofile/autofile_test.go +++ b/libs/autofile/autofile_test.go @@ -1,6 +1,7 @@ package autofile import ( + "io/ioutil" "os" "sync/atomic" "syscall" @@ -13,10 +14,14 @@ import ( func TestSIGHUP(t *testing.T) { // First, create an AutoFile writing to a tempfile dir - file, name := cmn.Tempfile("sighup_test") - if err := file.Close(); err != nil { + file, err := ioutil.TempFile("", "sighup_test") + if err != nil { t.Fatalf("Error creating tempfile: %v", err) } + if err := file.Close(); err != nil { + t.Fatalf("Error closing tempfile: %v", err) + } + name := file.Name() // Here is the actual AutoFile af, err := OpenAutoFile(name) if err != nil { diff --git a/libs/autofile/group_test.go b/libs/autofile/group_test.go index 72581f9e2..c7e8725cf 100644 --- a/libs/autofile/group_test.go +++ b/libs/autofile/group_test.go @@ -147,14 +147,13 @@ func TestSearch(t *testing.T) { // Now search for each number for i := 0; i < 100; i++ { - t.Log("Testing for i", i) gr, match, err := g.Search("INFO", makeSearchFunc(i)) - require.NoError(t, err, "Failed to search for line") - assert.True(t, match, "Expected Search to return exact match") + require.NoError(t, err, "Failed to search for line, tc #%d", i) + assert.True(t, match, "Expected Search to return exact match, tc #%d", i) line, err := gr.ReadLine() - require.NoError(t, err, "Failed to read line after search") + require.NoError(t, err, "Failed to read line after search, tc #%d", i) if !strings.HasPrefix(line, fmt.Sprintf("INFO %v ", i)) { - t.Fatal("Failed to get correct line") + t.Fatalf("Failed to get correct line, tc #%d", i) } // Make sure we can continue to read from there. cur := i + 1 @@ -165,16 +164,16 @@ func TestSearch(t *testing.T) { // OK! break } else { - t.Fatal("Got EOF after the wrong INFO #") + t.Fatalf("Got EOF after the wrong INFO #, tc #%d", i) } } else if err != nil { - t.Fatal("Error reading line", err) + t.Fatalf("Error reading line, tc #%d, err:\n%s", i, err) } if !strings.HasPrefix(line, "INFO ") { continue } if !strings.HasPrefix(line, fmt.Sprintf("INFO %v ", cur)) { - t.Fatalf("Unexpected INFO #. Expected %v got:\n%v", cur, line) + t.Fatalf("Unexpected INFO #. Expected %v got:\n%v, tc #%d", cur, line, i) } cur++ } diff --git a/libs/common/os.go b/libs/common/os.go index 00f4da57b..b8419764e 100644 --- a/libs/common/os.go +++ b/libs/common/os.go @@ -8,7 +8,6 @@ import ( "os" "os/exec" "os/signal" - "path/filepath" "strings" "syscall" ) @@ -124,60 +123,6 @@ func MustWriteFile(filePath string, contents []byte, mode os.FileMode) { } } -// WriteFileAtomic creates a temporary file with data and the perm given and -// swaps it atomically with filename if successful. -func WriteFileAtomic(filename string, data []byte, perm os.FileMode) error { - var ( - dir = filepath.Dir(filename) - tempFile = filepath.Join(dir, "write-file-atomic-"+RandStr(32)) - // Override in case it does exist, create in case it doesn't and force kernel - // flush, which still leaves the potential of lingering disk cache. - flag = os.O_WRONLY | os.O_CREATE | os.O_SYNC | os.O_TRUNC - ) - - f, err := os.OpenFile(tempFile, flag, perm) - if err != nil { - return err - } - // Clean up in any case. Defer stacking order is last-in-first-out. - defer os.Remove(f.Name()) - defer f.Close() - - if n, err := f.Write(data); err != nil { - return err - } else if n < len(data) { - return io.ErrShortWrite - } - // Close the file before renaming it, otherwise it will cause "The process - // cannot access the file because it is being used by another process." on windows. - f.Close() - - return os.Rename(f.Name(), filename) -} - -//-------------------------------------------------------------------------------- - -func Tempfile(prefix string) (*os.File, string) { - file, err := ioutil.TempFile("", prefix) - if err != nil { - PanicCrisis(err) - } - return file, file.Name() -} - -func Tempdir(prefix string) (*os.File, string) { - tempDir := os.TempDir() + "/" + prefix + RandStr(12) - err := EnsureDir(tempDir, 0700) - if err != nil { - panic(Fmt("Error creating temp dir: %v", err)) - } - dir, err := os.Open(tempDir) - if err != nil { - panic(Fmt("Error opening temp dir: %v", err)) - } - return dir, tempDir -} - //-------------------------------------------------------------------------------- func Prompt(prompt string, defaultValue string) (string, error) { diff --git a/libs/common/os_test.go b/libs/common/os_test.go index 3edd6496e..bf65f0c99 100644 --- a/libs/common/os_test.go +++ b/libs/common/os_test.go @@ -1,52 +1,10 @@ package common import ( - "bytes" - "io/ioutil" "os" "testing" ) -func TestWriteFileAtomic(t *testing.T) { - var ( - data = []byte(RandStr(RandIntn(2048))) - old = RandBytes(RandIntn(2048)) - perm os.FileMode = 0600 - ) - - f, err := ioutil.TempFile("/tmp", "write-atomic-test-") - if err != nil { - t.Fatal(err) - } - defer os.Remove(f.Name()) - - if err = ioutil.WriteFile(f.Name(), old, 0664); err != nil { - t.Fatal(err) - } - - if err = WriteFileAtomic(f.Name(), data, perm); err != nil { - t.Fatal(err) - } - - rData, err := ioutil.ReadFile(f.Name()) - if err != nil { - t.Fatal(err) - } - - if !bytes.Equal(data, rData) { - t.Fatalf("data mismatch: %v != %v", data, rData) - } - - stat, err := os.Stat(f.Name()) - if err != nil { - t.Fatal(err) - } - - if have, want := stat.Mode().Perm(), perm; have != want { - t.Errorf("have %v, want %v", have, want) - } -} - func TestGoPath(t *testing.T) { // restore original gopath upon exit path := os.Getenv("GOPATH") diff --git a/libs/common/random.go b/libs/common/random.go index 51bfd15c4..4b0594d0e 100644 --- a/libs/common/random.go +++ b/libs/common/random.go @@ -109,6 +109,10 @@ func RandInt63n(n int64) int64 { return grand.Int63n(n) } +func RandBool() bool { + return grand.Bool() +} + func RandFloat32() float32 { return grand.Float32() } @@ -274,6 +278,13 @@ func (r *Rand) Intn(n int) int { return i } +// Bool returns a uniformly random boolean +func (r *Rand) Bool() bool { + // See https://github.com/golang/go/issues/23804#issuecomment-365370418 + // for reasoning behind computing like this + return r.Int63()%2 == 0 +} + // Perm returns a pseudo-random permutation of n integers in [0, n). func (r *Rand) Perm(n int) []int { r.Lock() diff --git a/libs/common/tempfile.go b/libs/common/tempfile.go new file mode 100644 index 000000000..a5bb7a5b5 --- /dev/null +++ b/libs/common/tempfile.go @@ -0,0 +1,128 @@ +package common + +import ( + fmt "fmt" + "io" + "os" + "path/filepath" + "strconv" + "strings" + "sync" + "time" +) + +const ( + atomicWriteFilePrefix = "write-file-atomic-" + // Maximum number of atomic write file conflicts before we start reseeding + // (reduced from golang's default 10 due to using an increased randomness space) + atomicWriteFileMaxNumConflicts = 5 + // Maximum number of attempts to make at writing the write file before giving up + // (reduced from golang's default 10000 due to using an increased randomness space) + atomicWriteFileMaxNumWriteAttempts = 1000 + // LCG constants from Donald Knuth MMIX + // This LCG's has a period equal to 2**64 + lcgA = 6364136223846793005 + lcgC = 1442695040888963407 + // Create in case it doesn't exist and force kernel + // flush, which still leaves the potential of lingering disk cache. + // Never overwrites files + atomicWriteFileFlag = os.O_WRONLY | os.O_CREATE | os.O_SYNC | os.O_TRUNC | os.O_EXCL +) + +var ( + atomicWriteFileRand uint64 + atomicWriteFileRandMu sync.Mutex +) + +func writeFileRandReseed() uint64 { + // Scale the PID, to minimize the chance that two processes seeded at similar times + // don't get the same seed. Note that PID typically ranges in [0, 2**15), but can be + // up to 2**22 under certain configurations. We left bit-shift the PID by 20, so that + // a PID difference of one corresponds to a time difference of 2048 seconds. + // The important thing here is that now for a seed conflict, they would both have to be on + // the correct nanosecond offset, and second-based offset, which is much less likely than + // just a conflict with the correct nanosecond offset. + return uint64(time.Now().UnixNano() + int64(os.Getpid()<<20)) +} + +// Use a fast thread safe LCG for atomic write file names. +// Returns a string corresponding to a 64 bit int. +// If it was a negative int, the leading number is a 0. +func randWriteFileSuffix() string { + atomicWriteFileRandMu.Lock() + r := atomicWriteFileRand + if r == 0 { + r = writeFileRandReseed() + } + + // Update randomness according to lcg + r = r*lcgA + lcgC + + atomicWriteFileRand = r + atomicWriteFileRandMu.Unlock() + // Can have a negative name, replace this in the following + suffix := strconv.Itoa(int(r)) + if string(suffix[0]) == "-" { + // Replace first "-" with "0". This is purely for UI clarity, + // as otherwhise there would be two `-` in a row. + suffix = strings.Replace(suffix, "-", "0", 1) + } + return suffix +} + +// WriteFileAtomic creates a temporary file with data and provided perm and +// swaps it atomically with filename if successful. +func WriteFileAtomic(filename string, data []byte, perm os.FileMode) (err error) { + // This implementation is inspired by the golang stdlibs method of creating + // tempfiles. Notable differences are that we use different flags, a 64 bit LCG + // and handle negatives differently. + // The core reason we can't use golang's TempFile is that we must write + // to the file synchronously, as we need this to persist to disk. + // We also open it in write-only mode, to avoid concerns that arise with read. + var ( + dir = filepath.Dir(filename) + f *os.File + ) + + nconflict := 0 + // Limit the number of attempts to create a file. Something is seriously + // wrong if it didn't get created after 1000 attempts, and we don't want + // an infinite loop + i := 0 + for ; i < atomicWriteFileMaxNumWriteAttempts; i++ { + name := filepath.Join(dir, atomicWriteFilePrefix+randWriteFileSuffix()) + f, err = os.OpenFile(name, atomicWriteFileFlag, perm) + // If the file already exists, try a new file + if os.IsExist(err) { + // If the files exists too many times, start reseeding as we've + // likely hit another instances seed. + if nconflict++; nconflict > atomicWriteFileMaxNumConflicts { + atomicWriteFileRandMu.Lock() + atomicWriteFileRand = writeFileRandReseed() + atomicWriteFileRandMu.Unlock() + } + continue + } else if err != nil { + return err + } + break + } + if i == atomicWriteFileMaxNumWriteAttempts { + return fmt.Errorf("Could not create atomic write file after %d attempts", i) + } + + // Clean up in any case. Defer stacking order is last-in-first-out. + defer os.Remove(f.Name()) + defer f.Close() + + if n, err := f.Write(data); err != nil { + return err + } else if n < len(data) { + return io.ErrShortWrite + } + // Close the file before renaming it, otherwise it will cause "The process + // cannot access the file because it is being used by another process." on windows. + f.Close() + + return os.Rename(f.Name(), filename) +} diff --git a/libs/common/tempfile_test.go b/libs/common/tempfile_test.go new file mode 100644 index 000000000..51da90913 --- /dev/null +++ b/libs/common/tempfile_test.go @@ -0,0 +1,138 @@ +package common + +// Need access to internal variables, so can't use _test package + +import ( + "bytes" + fmt "fmt" + "io/ioutil" + "os" + testing "testing" + + "github.com/stretchr/testify/require" +) + +func TestWriteFileAtomic(t *testing.T) { + var ( + data = []byte(RandStr(RandIntn(2048))) + old = RandBytes(RandIntn(2048)) + perm os.FileMode = 0600 + ) + + f, err := ioutil.TempFile("/tmp", "write-atomic-test-") + if err != nil { + t.Fatal(err) + } + defer os.Remove(f.Name()) + + if err = ioutil.WriteFile(f.Name(), old, 0664); err != nil { + t.Fatal(err) + } + + if err = WriteFileAtomic(f.Name(), data, perm); err != nil { + t.Fatal(err) + } + + rData, err := ioutil.ReadFile(f.Name()) + if err != nil { + t.Fatal(err) + } + + if !bytes.Equal(data, rData) { + t.Fatalf("data mismatch: %v != %v", data, rData) + } + + stat, err := os.Stat(f.Name()) + if err != nil { + t.Fatal(err) + } + + if have, want := stat.Mode().Perm(), perm; have != want { + t.Errorf("have %v, want %v", have, want) + } +} + +// This tests atomic write file when there is a single duplicate file. +// Expected behavior is for a new file to be created, and the original write file to be unaltered. +func TestWriteFileAtomicDuplicateFile(t *testing.T) { + var ( + defaultSeed uint64 = 1 + testString = "This is a glorious test string" + expectedString = "Did the test file's string appear here?" + + fileToWrite = "/tmp/TestWriteFileAtomicDuplicateFile-test.txt" + ) + // Create a file at the seed, and reset the seed. + atomicWriteFileRand = defaultSeed + firstFileRand := randWriteFileSuffix() + atomicWriteFileRand = defaultSeed + fname := "/tmp/" + atomicWriteFilePrefix + firstFileRand + f, err := os.OpenFile(fname, atomicWriteFileFlag, 0777) + defer os.Remove(fname) + // Defer here, in case there is a panic in WriteFileAtomic. + defer os.Remove(fileToWrite) + + require.Nil(t, err) + f.WriteString(testString) + WriteFileAtomic(fileToWrite, []byte(expectedString), 0777) + // Check that the first atomic file was untouched + firstAtomicFileBytes, err := ioutil.ReadFile(fname) + require.Nil(t, err, "Error reading first atomic file") + require.Equal(t, []byte(testString), firstAtomicFileBytes, "First atomic file was overwritten") + // Check that the resultant file is correct + resultantFileBytes, err := ioutil.ReadFile(fileToWrite) + require.Nil(t, err, "Error reading resultant file") + require.Equal(t, []byte(expectedString), resultantFileBytes, "Written file had incorrect bytes") + + // Check that the intermediate write file was deleted + // Get the second write files' randomness + atomicWriteFileRand = defaultSeed + _ = randWriteFileSuffix() + secondFileRand := randWriteFileSuffix() + _, err = os.Stat("/tmp/" + atomicWriteFilePrefix + secondFileRand) + require.True(t, os.IsNotExist(err), "Intermittent atomic write file not deleted") +} + +// This tests atomic write file when there are many duplicate files. +// Expected behavior is for a new file to be created under a completely new seed, +// and the original write files to be unaltered. +func TestWriteFileAtomicManyDuplicates(t *testing.T) { + var ( + defaultSeed uint64 = 2 + testString = "This is a glorious test string, from file %d" + expectedString = "Did any of the test file's string appear here?" + + fileToWrite = "/tmp/TestWriteFileAtomicDuplicateFile-test.txt" + ) + // Initialize all of the atomic write files + atomicWriteFileRand = defaultSeed + for i := 0; i < atomicWriteFileMaxNumConflicts+2; i++ { + fileRand := randWriteFileSuffix() + fname := "/tmp/" + atomicWriteFilePrefix + fileRand + f, err := os.OpenFile(fname, atomicWriteFileFlag, 0777) + require.Nil(t, err) + f.WriteString(fmt.Sprintf(testString, i)) + defer os.Remove(fname) + } + + atomicWriteFileRand = defaultSeed + // Defer here, in case there is a panic in WriteFileAtomic. + defer os.Remove(fileToWrite) + + WriteFileAtomic(fileToWrite, []byte(expectedString), 0777) + // Check that all intermittent atomic file were untouched + atomicWriteFileRand = defaultSeed + for i := 0; i < atomicWriteFileMaxNumConflicts+2; i++ { + fileRand := randWriteFileSuffix() + fname := "/tmp/" + atomicWriteFilePrefix + fileRand + firstAtomicFileBytes, err := ioutil.ReadFile(fname) + require.Nil(t, err, "Error reading first atomic file") + require.Equal(t, []byte(fmt.Sprintf(testString, i)), firstAtomicFileBytes, + "atomic write file %d was overwritten", i) + } + + // Check that the resultant file is correct + resultantFileBytes, err := ioutil.ReadFile(fileToWrite) + require.Nil(t, err, "Error reading resultant file") + require.Equal(t, []byte(expectedString), resultantFileBytes, "Written file had incorrect bytes") +} diff --git a/libs/db/backend_test.go b/libs/db/backend_test.go index 493ed83f9..b31b4d74a 100644 --- a/libs/db/backend_test.go +++ b/libs/db/backend_test.go @@ -2,6 +2,7 @@ package db import ( "fmt" + "io/ioutil" "os" "path/filepath" "testing" @@ -17,8 +18,8 @@ func cleanupDBDir(dir, name string) { func testBackendGetSetDelete(t *testing.T, backend DBBackendType) { // Default - dir, dirname := cmn.Tempdir(fmt.Sprintf("test_backend_%s_", backend)) - defer dir.Close() + dirname, err := ioutil.TempDir("", fmt.Sprintf("test_backend_%s_", backend)) + require.Nil(t, err) db := NewDB("testdb", backend, dirname) // A nonexistent key should return nil, even if the key is empty diff --git a/libs/db/common_test.go b/libs/db/common_test.go index 027b8ee53..68420cd2b 100644 --- a/libs/db/common_test.go +++ b/libs/db/common_test.go @@ -2,12 +2,12 @@ package db import ( "fmt" + "io/ioutil" "sync" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - cmn "github.com/tendermint/tendermint/libs/common" ) //---------------------------------------- @@ -61,9 +61,9 @@ func checkValuePanics(t *testing.T, itr Iterator) { } func newTempDB(t *testing.T, backend DBBackendType) (db DB) { - dir, dirname := cmn.Tempdir("db_common_test") + dirname, err := ioutil.TempDir("", "db_common_test") + require.Nil(t, err) db = NewDB("testdb", backend, dirname) - dir.Close() return db } diff --git a/p2p/conn/secret_connection_test.go b/p2p/conn/secret_connection_test.go index 27dca034a..75ed8fe02 100644 --- a/p2p/conn/secret_connection_test.go +++ b/p2p/conn/secret_connection_test.go @@ -1,8 +1,16 @@ package conn import ( + "bufio" + "encoding/hex" + "flag" "fmt" "io" + "log" + "os" + "path/filepath" + "strconv" + "strings" "testing" "github.com/stretchr/testify/assert" @@ -208,6 +216,66 @@ func TestSecretConnectionReadWrite(t *testing.T) { } +// Run go test -update from within this module +// to update the golden test vector file +var update = flag.Bool("update", false, "update .golden files") + +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) + cmn.WriteFile(goldenFilepath, []byte(data), 0644) + } + f, err := os.Open(goldenFilepath) + if err != nil { + log.Fatal(err) + } + defer f.Close() + scanner := bufio.NewScanner(f) + for scanner.Scan() { + line := scanner.Text() + params := strings.Split(line, ",") + randSecretVector, err := hex.DecodeString(params[0]) + require.Nil(t, err) + randSecret := new([32]byte) + copy((*randSecret)[:], randSecretVector) + locIsLeast, err := strconv.ParseBool(params[1]) + require.Nil(t, err) + expectedRecvSecret, err := hex.DecodeString(params[2]) + require.Nil(t, err) + expectedSendSecret, err := hex.DecodeString(params[3]) + require.Nil(t, err) + expectedChallenge, err := hex.DecodeString(params[4]) + require.Nil(t, err) + + recvSecret, sendSecret, challenge := deriveSecretAndChallenge(randSecret, locIsLeast) + require.Equal(t, expectedRecvSecret, (*recvSecret)[:], "Recv Secrets aren't equal") + require.Equal(t, expectedSendSecret, (*sendSecret)[:], "Send Secrets aren't equal") + require.Equal(t, expectedChallenge, (*challenge)[:], "challenges aren't equal") + } +} + +// 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 { + data := "" + for i := 0; i < 32; i++ { + randSecretVector := cmn.RandBytes(32) + randSecret := new([32]byte) + copy((*randSecret)[:], randSecretVector) + data += hex.EncodeToString((*randSecret)[:]) + "," + locIsLeast := cmn.RandBool() + data += strconv.FormatBool(locIsLeast) + "," + recvSecret, sendSecret, challenge := deriveSecretAndChallenge(randSecret, locIsLeast) + data += hex.EncodeToString((*recvSecret)[:]) + "," + data += hex.EncodeToString((*sendSecret)[:]) + "," + data += hex.EncodeToString((*challenge)[:]) + "\n" + } + return data +} + func BenchmarkSecretConnection(b *testing.B) { b.StopTimer() fooSecConn, barSecConn := makeSecretConnPair(b) diff --git a/p2p/conn/testdata/TestDeriveSecretsAndChallengeGolden.golden b/p2p/conn/testdata/TestDeriveSecretsAndChallengeGolden.golden new file mode 100644 index 000000000..eb69b29fe --- /dev/null +++ b/p2p/conn/testdata/TestDeriveSecretsAndChallengeGolden.golden @@ -0,0 +1,32 @@ +9fe4a5a73df12dbd8659b1d9280873fe993caefec6b0ebc2686dd65027148e03,true,80a83ad6afcb6f8175192e41973aed31dd75e3c106f813d986d9567a4865eb2f,96362a04f628a0666d9866147326898bb0847b8db8680263ad19e6336d4eed9e,2632c3fd20f456c5383ed16aa1d56dc7875a2b0fc0d5ff053c3ada8934098c69 +0716764b370d543fee692af03832c16410f0a56e4ddb79604ea093b10bb6f654,false,84f2b1e8658456529a2c324f46c3406c3c6fecd5fbbf9169f60bed8956a8b03d,cba357ae33d7234520d5742102a2a6cdb39b7db59c14a58fa8aadd310127630f,576643a8fcc1a4cf866db900f4a150dbe35d44a1b3ff36e4911565c3fa22fc32 +358dd73aae2c5b7b94b57f950408a3c681e748777ecab2063c8ca51a63588fa8,false,c2e2f664c8ee561af8e1e30553373be4ae23edecc8c6bd762d44b2afb7f2a037,d1563f428ac1c023c15d8082b2503157fe9ecbde4fb3493edd69ebc299b4970c,89fb6c6439b12fe11a4c604b8ad883f7dc76be33df590818fe5eb15ddb01face +0958308bdb583e639dd399a98cd21077d834b4b5e30771275a5a73a62efcc7e0,false,523c0ae97039173566f7ab4b8f271d8d78feef5a432d618e58ced4f80f7c1696,c1b743401c6e4508e62b8245ea7c3252bbad082e10af10e80608084d63877977,d7c52adf12ebc69677aec4bd387b0c5a35570fe61cb7b8ae55f3ab14b1b79be0 +d93d134e72f58f177642ac30f36b2d3cd4720aa7e60feb1296411a9009cf4524,false,47a427bcc1ef6f0ce31dbf343bc8bbf49554b4dd1e2330fd97d0df23ecdbba10,73e23adb7801179349ecf9c8cdf64d71d64a9f1145ba6730e5d029f99eaf8840,a8fdcb77f591bfba7b8483aa15ae7b42054ba68625d51dec005896dfe910281f +6104474c791cda24d952b356fb41a5d273c0ce6cc87d270b1701d0523cd5aa13,true,1cb4397b9e478430321af4647da2ccbef62ff8888542d31cca3f626766c8080f,673b23318826bd31ad1a4995c6e5095c4b092f5598aa0a96381a3e977bc0eaf9,4a25a25c5f75d6cc512f2ba8c1546e6263e9ef8269f0c046c37838cc66aa83e6 +8a6002503c15cab763e27c53fc449f6854a210c95cdd67e4466b0f2cb46b629c,false,f01ff06aef356c87f8d2646ff9ed8b855497c2ca00ea330661d84ef421a67e63,4f59bb23090010614877265a1597f1a142fa97b7208e1d554435763505f36f6a,1aadcb1c8b5993da102cebcb60c545b03197c98137064530840f45d917ad300e +31a57c6b1fe33beb1f7ebbbfc06d58c4f307cd355b6f9753e58f3edec16c7559,false,13e126c4cb240349dccf0dc843977671d34a1daffd0517d06ed66b703344db22,d491431906a306af45ecf9f1977e32d7f65a79f5139f931760416de27554b687,5ea7e8e3d5a30503423341609d360d246b61a9159fc07f253a46e357977cd745 +71a3c79718b824627faeefdce887d9465b353bd962cc5e97c5b5dfedab457ef9,true,e2e8eea547dcee7eafa89ae41f48ab049beac24935fad75258924fd5273d23cb,45d2e839bf36a3616cbe8a9bdbd4e7b288bf5bf1e6e79c07995eb2b18eb2eaff,7ee50e0810bc9f98e56bc46de5da22d84b3efa52fe5d85db4b2344530ef17ed8 +2e9dba2eb4f9019c2628ff5899744469c26caf793636f30ddb76601751aee968,false,8bfc3b314e4468d4e19c9d28b7bfd5b5532263105273b0fe80801f6146313993,b77d2b223e27038f978ab87a725859f6995f903056bdbd594ab04f0b2cbad517,9032be49a9cbcd1de6fee332f8f24ebf545c05e0175b98c564e7d1e69630ae20 +81322b22c835efb26d78051f3a3840a9d01aa558c019ecfa26483b5c5535728c,true,61eacb7e9665e362ef492ef950cea58f8bc67434ab7ee5545139147adf395da4,0f600ef0c358cae938969f434c2ec0ce3be632fdf5246b7bb8ee3ff294036ecd,a7026b4c21fe225ecd775ae81249405c6f492882eb85f3f8e2232f11e515561e +826b86c5e8cb4173ff2d05c48e3537140c5e0f26f7866bbcd4e57616806e1be2,true,ae44dabd077d227c8d898930a7705a2b785c8849121282106c045bb58b66eb36,24b2c1b1e2a9ebe387df6dfb9fbde6c681e4eeb0a33bb1c3df3789087f56ffe3,b37a64ea97431b25cb271c4c8435f6dd97118b35da57168f3c3c269920f7bbc1 +18b5a7b973d4b263072e69515c5b6ed22191c3d6e851aaba872904672f8344ec,true,ce402af2fb93b6ef18cd406f7c437d3cbfb09141b7a02116b1cfbabbf75ad84a,c86bdb1709ef0f4a31a818843660f83338b9db77e262bb7c6546138e51c6046b,11fcd8e59c4e7f6050d3cd332337db794ae31260c159e409af3ed8f4d6523bf4 +26d10c56872b72bb76ae7c7b3f074afb3d4a364e5e3f8c661be9b4f5a522ea75,true,1c9782a8485c4ecb13904ec551a7f9300ecd687abfbe63c91c7fd583f84a7a4d,ae3f4ccd0dfee8b514f67db2e923714d324935b9ae9e488d088ebb79569d8cc4,8139a3ab728b0e765e4d90549ab8eed7e1048a83267eafa7442208a7f627558a +558838dfcfe94105c46a4ade4548e6c96271d33e6c752661356cc66024615bae,true,d5a38625be74177318072cf877f2427ce2327e9b58d2eb134d0ac52c9126572f,dead938f77007e3164b6eee4cd153433d03ca5d9ec64f41aa6b2d6a069edeeda,4a081a356361da429c564cf7ac8e217121bbe8c5ee5c9632bae0b7ddbe94f9d4 +f4a3f6a93a4827a59682fd8bf1a8e4fd9aaff01a337a86e1966c8fff0e746014,true,39a0aea2a8ac7f0524d63e395a25b98fc3844ed039f20b11058019dca2b3840f,6ff53243426ded506d22501ae0f989d9946b86a8bb2550d7ed6e90fdf41d0e7c,8784e728bf12f465ed20dc6f0e1d949a68e5795d4799536427a6f859547b7fd6 +1717020e1c4fca1b4926dba16671c0c04e4f19c621c646cb4525fa533b1c205c,false,b9a909767f3044608b4e314b149a729bef199f8311310e1ecd2072e5659b7194,7baf0ff4b980919cf545312f45234976f0b6c574aac5b772024f73248aad7538,99a18e1e4b039ef3777a8fdd0d9ffaccaf3b4523b6d26adacfe91cc5fcd9977e +de769062be27b2a4248dd5be315960c8d231738417ece670c2d6a1c52877b59e,true,cc6c2086718b21813513894546e85766d34c754e81fd6a19c12fc322ffb9b1c3,5a7da7500191c65a5f1fbb2a6122717edc70ca0469baf2bbbd6ca8255b93c077,8c0d32091dc687f1399c754a617d224742726bece848b50c35b4db5f0469ace7 +7c5549f36767e02ebf49a4616467199459aa6932dcc091f182f822185659559a,true,d8335e606128b0c621ff6cda99dc62babf4a4436c574c5c478c20122712727d0,0a7c673cccd6f7fd4ed1673f7d0f2cb08961faced123ca901b74581d5bdc8b25,16ac1eb2a39384716c7d490272d87e76c10665fdb331e1883435de175ce4460e +ecf8261ebda248dc7796f98987efe1b7be363a59037c9e61044490d08a077610,true,53def80fcdba01367c0ea36459b57409f59a771f57a8259b54f24785e5656b7d,90140870b3b1e84c9dcf7836eac0581b16fe0a40307619d267c6f871e1efce6a,c6d1836b66c1a722a377c7eb058995a0ef8711839c6d6a0cdd6ad1ff70f935a5 +21c0ef76ce0eae9391ceabfb08a861899db55ac4ccf010ed672599669c6938f2,false,8af5482cc015093f261d5b7ce87035dda41d8318b9960b52cca3e5f0d3f61808,f4d5338bcb57262e1034f01ed3858ca1e5d66a73f18588e72f3dc8c6a730be0c,7ba82c2820c95e3354d9a6ab4920ebcd7938ce19e25930fee58439246b0321b1 +05f3b66d6b0fe906137e60b4719083a2465106badedcdae3a4c91c46c5367340,false,e5c9e074e95c2896fa4093830e96e9cf159b8dcba2ead21f37237cf6e9a9aaa2,b3a0a50309b4ca23cd34363fd8df30e73ec4a275973986c2e11a53752eff0a3b,358a62056ff05f27185b9952d291c6346171937f6811cafbacddd82e17010f39 +fef0251cff7c5d1ba0514f1820a8265453365fd9f5bb8a92f955dc007a40e730,true,e35a0aff6e9060a39c15d276a1337f1948d0be0aef81fcd563a6783115b5283d,20a8efe83474253d70e5fd847df0cd26222cd39e9210687b68c0a23b73429108,2989fab4278b32f4f40dc02227ab30e10f62e15ab7aa7382da769b1d084e33df +1b7bb172baa2753ec9c3e81a7a9b4c6ef10f9ed7afcafa975395f095eca63a54,false,a98257203987d0c4d260d8feef841466977276612e268b69b5ce4191af161b29,ea177a20d6c1f73f9667090568f9197943037d6586f7e2d6b7b81756fc71df5f,844eff318ef4c6ee45f158c1946ff999e40ffac70883ab6d6b90995f246e69a2 +5ee9b60a25753066d0ecc1155ca6afcc6b853ba558c9533c134a93b82e756856,true,9889460b95ca9545864a4a5194891b7d475362428d6d797532da10bf1fc92076,a7a96739abd8eceb6751afc98df68e29f7af16fbfda3d4710df9c35b6dcdb4d5,998326285c90a2ea2e1f6c6dac79530742645e3dd1b2b42a0733388a99cab81b +a102613781872f88a949d82cb5efcc2e0f437010a950d71b87929ecb480af3b3,false,e099080a55b9b29ccecbbb0d91dbe49defcc217efd1de0588e0836ce5970d327,319293b8660a3cea9879487645ddadda72a5c60079c9154bb0dbb8a0c9cda79e,4d567f1b1a1b304347cf7b129e4c7a05aa57e2bbb8ea335db9e33d05fab12e4d +1d4538180d06f37c43e8caa2d0d80aa7c5d701c8c3e31508704131427837f5cc,true,73afeeb46efc03d2b9f20fc271752528e52b8931287296a7e4367c96bccb32bd,59dc4b69d9ccf6f77715e47fb9bf454f1b90bbd05f1d2bbd07c7d6666f31c91f,ac59d735dfcdc3a0a4ce5a10f09dea8c6afd47de9c0308dc817e3789c8aee963 +e4c480af1b0e3487a331761f64eb3f020a2b8ffa25ad17e00f57aa7ec2c5e84d,true,1145e9f001c70d364e97fcdbc88a2a3d6aecdd975212923820f90a0b215f11f6,b802ac7ef21c8abaeae024c76e3fa70a2a82f73e0bb7c7fe76752ad1742af2e6,0a95876e30617e32ae25acd3af97c37dc075825f800def3f2bf3f68a268744e9 +3a7a83dd657dd6277bcfa957534f40d9b559039aad752066a8d7ed9a6d9c0ab5,false,f90a251ad2338b19cfee6a7965f6f5098136974abb99b3d24553fa6117384978,e422ed7567e5602731b3d980106d0546ef4a4da5eb7175d66a452df12d37bad2,b086bed71dfb6662cb10e2b4fb16a7c22394f488e822fc19697db6077f6caf6f +273e8560c2b1734e863a6542bded7a6fcbfb49a12770bd8866d4863dceea3ae9,false,3b7849a362e7b7ba8c8b8a0cd00df5180604987dbda6c03f37d9a09fdb27fb28,e6cdf4d767df0f411e970da8dda6acd3c2c34ce63908d8a6dbf3715daa0318e4,359a4a39fbdffc808161a48a3ffbe77fc6a03ff52324c22510a42e46c08a6f22 +9b4f8702991be9569b6c0b07a2173104d41325017b27d68fa5af91cdab164c4d,true,598323677db11ece050289f31881ee8caacb59376c7182f9055708b2a4673f84,7675adc1264b6758beb097a991f766f62796f78c1cfa58a4de3d81c36434d3ae,d5d8d610ffd85b04cbe1c73ff5becd5917c513d9625b001f51d486d0dadcefe3 +e1a686ba0169eb97379ebf9d22e073819450ee5ad5f049c8e93016e8d2ec1430,false,ffe461e6075865cde2704aa148fd29bcf0af245803f446cb6153244f25617993,46df6c25fa0344e662490c4da0bddca626644e67e66705840ef08aae35c343fa,e9a56d75acad4272ab0c49ee5919a4e86e6c5695ef065704c1e592d4e7b41a10 diff --git a/p2p/pex/pex_reactor.go b/p2p/pex/pex_reactor.go index 5c4894ce4..c59b3797d 100644 --- a/p2p/pex/pex_reactor.go +++ b/p2p/pex/pex_reactor.go @@ -74,6 +74,8 @@ type PEXReactor struct { requestsSent *cmn.CMap // ID->struct{}: unanswered send requests lastReceivedRequests *cmn.CMap // ID->time.Time: last time peer requested from us + seedAddrs []*p2p.NetAddress + attemptsToDial sync.Map // address (string) -> {number of attempts (int), last time dialed (time.Time)} } @@ -113,9 +115,6 @@ func NewPEXReactor(b AddrBook, config *PEXReactorConfig) *PEXReactor { // OnStart implements BaseService func (r *PEXReactor) OnStart() error { - if err := r.BaseReactor.OnStart(); err != nil { - return err - } err := r.book.Start() if err != nil && err != cmn.ErrAlreadyStarted { return err @@ -123,10 +122,13 @@ func (r *PEXReactor) OnStart() error { // return err if user provided a bad seed address // or a host name that we cant resolve - if err := r.checkSeeds(); err != nil { + seedAddrs, err := r.checkSeeds() + if err != nil { return err } + r.seedAddrs = seedAddrs + // Check if this node should run // in seed/crawler mode if r.config.SeedMode { @@ -139,7 +141,6 @@ func (r *PEXReactor) OnStart() error { // OnStop implements BaseService func (r *PEXReactor) OnStop() { - r.BaseReactor.OnStop() r.book.Stop() } @@ -285,7 +286,6 @@ func (r *PEXReactor) RequestAddrs(p Peer) { // request for this peer and deletes the open request. // If there's no open request for the src peer, it returns an error. func (r *PEXReactor) ReceiveAddrs(addrs []*p2p.NetAddress, src Peer) error { - id := string(src.ID()) if !r.requestsSent.Has(id) { return cmn.NewError("Received unsolicited pexAddrsMessage") @@ -301,6 +301,13 @@ func (r *PEXReactor) ReceiveAddrs(addrs []*p2p.NetAddress, src Peer) error { err := r.book.AddAddress(netAddr, srcAddr) r.logErrAddrBook(err) + + // If this address came from a seed node, try to connect to it without waiting. + for _, seedAddr := range r.seedAddrs { + if seedAddr.Equals(srcAddr) { + r.ensurePeers() + } + } } return nil } @@ -472,18 +479,18 @@ func (r *PEXReactor) dialPeer(addr *p2p.NetAddress) { } // check seed addresses are well formed -func (r *PEXReactor) checkSeeds() error { +func (r *PEXReactor) checkSeeds() ([]*p2p.NetAddress, error) { lSeeds := len(r.config.Seeds) if lSeeds == 0 { - return nil + return nil, nil } - _, errs := p2p.NewNetAddressStrings(r.config.Seeds) + netAddrs, errs := p2p.NewNetAddressStrings(r.config.Seeds) for _, err := range errs { if err != nil { - return err + return nil, err } } - return nil + return netAddrs, nil } // randomly dial seeds until we connect to one or exhaust them @@ -492,13 +499,12 @@ func (r *PEXReactor) dialSeeds() { if lSeeds == 0 { return } - seedAddrs, _ := p2p.NewNetAddressStrings(r.config.Seeds) perm := cmn.RandPerm(lSeeds) // perm := r.Switch.rng.Perm(lSeeds) for _, i := range perm { // dial a random seed - seedAddr := seedAddrs[i] + seedAddr := r.seedAddrs[i] err := r.Switch.DialPeerWithAddress(seedAddr, false) if err == nil { return diff --git a/p2p/pex/pex_reactor_test.go b/p2p/pex/pex_reactor_test.go index 8d54693fe..36f38c570 100644 --- a/p2p/pex/pex_reactor_test.go +++ b/p2p/pex/pex_reactor_test.go @@ -211,31 +211,26 @@ func TestPEXReactorUsesSeedsIfNeeded(t *testing.T) { defer os.RemoveAll(dir) // nolint: errcheck // 1. create seed - seed := p2p.MakeSwitch( - cfg, - 0, - "127.0.0.1", - "123.123.123", - func(i int, sw *p2p.Switch) *p2p.Switch { - book := NewAddrBook(filepath.Join(dir, "addrbook0.json"), false) - book.SetLogger(log.TestingLogger()) - sw.SetAddrBook(book) - - sw.SetLogger(log.TestingLogger()) - - r := NewPEXReactor(book, &PEXReactorConfig{}) - r.SetLogger(log.TestingLogger()) - sw.AddReactor("pex", r) - return sw - }, - ) - seed.AddListener( - p2p.NewDefaultListener("tcp://"+seed.NodeInfo().ListenAddr, "", false, log.TestingLogger()), - ) + seed := testCreateSeed(dir, 0, []*p2p.NetAddress{}, []*p2p.NetAddress{}) require.Nil(t, seed.Start()) defer seed.Stop() // 2. create usual peer with only seed configured. + peer := testCreatePeerWithSeed(dir, 1, seed) + require.Nil(t, peer.Start()) + defer peer.Stop() + + // 3. check that the peer connects to seed immediately + assertPeersWithTimeout(t, []*p2p.Switch{peer}, 10*time.Millisecond, 3*time.Second, 1) +} + +func TestConnectionSpeedForPeerReceivedFromSeed(t *testing.T) { + // directory to store address books + dir, err := ioutil.TempDir("", "pex_reactor") + require.Nil(t, err) + defer os.RemoveAll(dir) // nolint: errcheck + + // 1. create peer peer := p2p.MakeSwitch( cfg, 1, @@ -250,20 +245,34 @@ func TestPEXReactorUsesSeedsIfNeeded(t *testing.T) { r := NewPEXReactor( book, - &PEXReactorConfig{ - Seeds: []string{seed.NodeInfo().NetAddress().String()}, - }, + &PEXReactorConfig{}, ) r.SetLogger(log.TestingLogger()) sw.AddReactor("pex", r) return sw }, ) + peer.AddListener( + p2p.NewDefaultListener("tcp://"+peer.NodeInfo().ListenAddr, "", false, log.TestingLogger()), + ) require.Nil(t, peer.Start()) defer peer.Stop() - // 3. check that the peer connects to seed immediately - assertPeersWithTimeout(t, []*p2p.Switch{peer}, 10*time.Millisecond, 3*time.Second, 1) + // 2. Create seed which knows about the peer + seed := testCreateSeed(dir, 2, []*p2p.NetAddress{peer.NodeInfo().NetAddress()}, []*p2p.NetAddress{peer.NodeInfo().NetAddress()}) + require.Nil(t, seed.Start()) + defer seed.Stop() + + // 3. create another peer with only seed configured. + secondPeer := testCreatePeerWithSeed(dir, 3, seed) + require.Nil(t, secondPeer.Start()) + defer secondPeer.Stop() + + // 4. check that the second peer connects to seed immediately + assertPeersWithTimeout(t, []*p2p.Switch{secondPeer}, 10*time.Millisecond, 3*time.Second, 1) + + // 5. check that the second peer connects to the first peer immediately + assertPeersWithTimeout(t, []*p2p.Switch{secondPeer}, 10*time.Millisecond, 1*time.Second, 2) } func TestPEXReactorCrawlStatus(t *testing.T) { @@ -401,6 +410,7 @@ func assertPeersWithTimeout( outbound, inbound, _ := s.NumPeers() if outbound+inbound < nPeers { allGood = false + break } } remaining -= checkPeriod @@ -417,14 +427,77 @@ func assertPeersWithTimeout( numPeersStr += fmt.Sprintf("%d => {outbound: %d, inbound: %d}, ", i, outbound, inbound) } t.Errorf( - "expected all switches to be connected to at least one peer (switches: %s)", - numPeersStr, + "expected all switches to be connected to at least %d peer(s) (switches: %s)", + nPeers, numPeersStr, ) return } } } +// Creates a seed which knows about the provided addresses / source address pairs. +// Starting and stopping the seed is left to the caller +func testCreateSeed(dir string, id int, knownAddrs, srcAddrs []*p2p.NetAddress) *p2p.Switch { + seed := p2p.MakeSwitch( + cfg, + id, + "127.0.0.1", + "123.123.123", + func(i int, sw *p2p.Switch) *p2p.Switch { + book := NewAddrBook(filepath.Join(dir, "addrbookSeed.json"), false) + book.SetLogger(log.TestingLogger()) + for j := 0; j < len(knownAddrs); j++ { + book.AddAddress(knownAddrs[j], srcAddrs[j]) + book.MarkGood(knownAddrs[j]) + } + sw.SetAddrBook(book) + + sw.SetLogger(log.TestingLogger()) + + r := NewPEXReactor(book, &PEXReactorConfig{}) + r.SetLogger(log.TestingLogger()) + sw.AddReactor("pex", r) + return sw + }, + ) + seed.AddListener( + p2p.NewDefaultListener("tcp://"+seed.NodeInfo().ListenAddr, "", false, log.TestingLogger()), + ) + return seed +} + +// Creates a peer which knows about the provided seed. +// Starting and stopping the peer is left to the caller +func testCreatePeerWithSeed(dir string, id int, seed *p2p.Switch) *p2p.Switch { + peer := p2p.MakeSwitch( + cfg, + id, + "127.0.0.1", + "123.123.123", + func(i int, sw *p2p.Switch) *p2p.Switch { + book := NewAddrBook(filepath.Join(dir, fmt.Sprintf("addrbook%d.json", id)), false) + book.SetLogger(log.TestingLogger()) + sw.SetAddrBook(book) + + sw.SetLogger(log.TestingLogger()) + + r := NewPEXReactor( + book, + &PEXReactorConfig{ + Seeds: []string{seed.NodeInfo().NetAddress().String()}, + }, + ) + r.SetLogger(log.TestingLogger()) + sw.AddReactor("pex", r) + return sw + }, + ) + peer.AddListener( + p2p.NewDefaultListener("tcp://"+peer.NodeInfo().ListenAddr, "", false, log.TestingLogger()), + ) + return peer +} + func createReactor(conf *PEXReactorConfig) (r *PEXReactor, book *addrBook) { // directory to store address book dir, err := ioutil.TempDir("", "pex_reactor") diff --git a/privval/priv_validator_test.go b/privval/priv_validator_test.go index 7c9c93fcf..127f5c1f3 100644 --- a/privval/priv_validator_test.go +++ b/privval/priv_validator_test.go @@ -3,6 +3,7 @@ package privval import ( "encoding/base64" "fmt" + "io/ioutil" "os" "testing" "time" @@ -11,22 +12,22 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" - cmn "github.com/tendermint/tendermint/libs/common" "github.com/tendermint/tendermint/types" ) func TestGenLoadValidator(t *testing.T) { assert := assert.New(t) - _, tempFilePath := cmn.Tempfile("priv_validator_") - privVal := GenFilePV(tempFilePath) + tempFile, err := ioutil.TempFile("", "priv_validator_") + require.Nil(t, err) + privVal := GenFilePV(tempFile.Name()) height := int64(100) privVal.LastHeight = height privVal.Save() addr := privVal.GetAddress() - privVal = LoadFilePV(tempFilePath) + privVal = LoadFilePV(tempFile.Name()) assert.Equal(addr, privVal.GetAddress(), "expected privval addr to be the same") assert.Equal(height, privVal.LastHeight, "expected privval.LastHeight to have been saved") } @@ -34,7 +35,9 @@ func TestGenLoadValidator(t *testing.T) { func TestLoadOrGenValidator(t *testing.T) { assert := assert.New(t) - _, tempFilePath := cmn.Tempfile("priv_validator_") + tempFile, err := ioutil.TempFile("", "priv_validator_") + require.Nil(t, err) + tempFilePath := tempFile.Name() if err := os.Remove(tempFilePath); err != nil { t.Error(err) } @@ -91,8 +94,9 @@ func TestUnmarshalValidator(t *testing.T) { func TestSignVote(t *testing.T) { assert := assert.New(t) - _, tempFilePath := cmn.Tempfile("priv_validator_") - privVal := GenFilePV(tempFilePath) + tempFile, err := ioutil.TempFile("", "priv_validator_") + require.Nil(t, err) + privVal := GenFilePV(tempFile.Name()) block1 := types.BlockID{[]byte{1, 2, 3}, types.PartSetHeader{}} block2 := types.BlockID{[]byte{3, 2, 1}, types.PartSetHeader{}} @@ -101,7 +105,7 @@ func TestSignVote(t *testing.T) { // sign a vote for first time vote := newVote(privVal.Address, 0, height, round, voteType, block1) - err := privVal.SignVote("mychainid", vote) + err = privVal.SignVote("mychainid", vote) assert.NoError(err, "expected no error signing vote") // try to sign the same vote again; should be fine @@ -132,8 +136,9 @@ func TestSignVote(t *testing.T) { func TestSignProposal(t *testing.T) { assert := assert.New(t) - _, tempFilePath := cmn.Tempfile("priv_validator_") - privVal := GenFilePV(tempFilePath) + tempFile, err := ioutil.TempFile("", "priv_validator_") + require.Nil(t, err) + privVal := GenFilePV(tempFile.Name()) block1 := types.PartSetHeader{5, []byte{1, 2, 3}} block2 := types.PartSetHeader{10, []byte{3, 2, 1}} @@ -141,7 +146,7 @@ func TestSignProposal(t *testing.T) { // sign a proposal for first time proposal := newProposal(height, round, block1) - err := privVal.SignProposal("mychainid", proposal) + err = privVal.SignProposal("mychainid", proposal) assert.NoError(err, "expected no error signing proposal") // try to sign the same proposal again; should be fine @@ -170,8 +175,9 @@ func TestSignProposal(t *testing.T) { } func TestDifferByTimestamp(t *testing.T) { - _, tempFilePath := cmn.Tempfile("priv_validator_") - privVal := GenFilePV(tempFilePath) + tempFile, err := ioutil.TempFile("", "priv_validator_") + require.Nil(t, err) + privVal := GenFilePV(tempFile.Name()) block1 := types.PartSetHeader{5, []byte{1, 2, 3}} height, round := int64(10), 1 diff --git a/rpc/core/status.go b/rpc/core/status.go index 137aaf422..4cb7667b7 100644 --- a/rpc/core/status.go +++ b/rpc/core/status.go @@ -104,20 +104,11 @@ func Status() (*ctypes.ResultStatus, error) { return result, nil } -const consensusTimeout = time.Second - func validatorAtHeight(h int64) *types.Validator { - lastBlockHeight, vals := getValidatorsWithTimeout( - consensusState, - consensusTimeout, - ) - - if lastBlockHeight == -1 { - return nil - } - privValAddress := pubKey.Address() + lastBlockHeight, vals := consensusState.GetValidators() + // if we're still at height h, search in the current validator set if lastBlockHeight == h { for _, val := range vals { @@ -140,35 +131,3 @@ func validatorAtHeight(h int64) *types.Validator { return nil } - -type validatorRetriever interface { - GetValidators() (int64, []*types.Validator) -} - -// NOTE: Consensus might halt, but we still need to process RPC requests (at -// least for endpoints whole output does not depend on consensus state). -func getValidatorsWithTimeout( - vr validatorRetriever, - t time.Duration, -) (int64, []*types.Validator) { - resultCh := make(chan struct { - lastBlockHeight int64 - vals []*types.Validator - }) - go func() { - h, v := vr.GetValidators() - resultCh <- struct { - lastBlockHeight int64 - vals []*types.Validator - }{h, v} - }() - select { - case res := <-resultCh: - return res.lastBlockHeight, res.vals - case <-time.After(t): - if logger != nil { - logger.Error("Timed out querying validators from consensus", "timeout", t) - } - return -1, []*types.Validator{} - } -} diff --git a/rpc/core/status_test.go b/rpc/core/status_test.go deleted file mode 100644 index e44ffed0f..000000000 --- a/rpc/core/status_test.go +++ /dev/null @@ -1,39 +0,0 @@ -package core - -import ( - "testing" - "time" - - "github.com/tendermint/tendermint/types" -) - -func TestGetValidatorsWithTimeout(t *testing.T) { - height, vs := getValidatorsWithTimeout( - testValidatorReceiver{}, - time.Millisecond, - ) - - if height != -1 { - t.Errorf("expected negative height") - } - - if len(vs) != 0 { - t.Errorf("expected no validators") - } -} - -type testValidatorReceiver struct{} - -func (tr testValidatorReceiver) GetValidators() (int64, []*types.Validator) { - vs := []*types.Validator{} - - for i := 0; i < 3; i++ { - v, _ := types.RandValidator(true, 10) - - vs = append(vs, v) - } - - time.Sleep(time.Millisecond) - - return 10, vs -} diff --git a/state/execution.go b/state/execution.go index f57b6e4dd..54e1ec73a 100644 --- a/state/execution.go +++ b/state/execution.go @@ -188,9 +188,12 @@ func execBlockOnProxyApp(logger log.Logger, proxyAppConn proxy.AppConnConsensus, // Begin block _, err := proxyAppConn.BeginBlockSync(abci.RequestBeginBlock{ - Hash: block.Hash(), - Header: types.TM2PB.Header(&block.Header), - Validators: signVals, + Hash: block.Hash(), + Header: types.TM2PB.Header(&block.Header), + LastCommitInfo: abci.LastCommitInfo{ + CommitRound: int32(block.LastCommit.Round()), + Validators: signVals, + }, ByzantineValidators: byzVals, }) if err != nil { @@ -245,7 +248,7 @@ func getBeginBlockValidatorInfo(block *types.Block, lastValSet *types.ValidatorS vote = block.LastCommit.Precommits[i] } val := abci.SigningValidator{ - Validator: types.TM2PB.Validator(val), + Validator: types.TM2PB.ValidatorWithoutPubKey(val), SignedLastBlock: vote != nil, } signVals[i] = val diff --git a/state/execution_test.go b/state/execution_test.go index 516ca2ed5..53c5c882b 100644 --- a/state/execution_test.go +++ b/state/execution_test.go @@ -293,7 +293,7 @@ func (app *testApp) Info(req abci.RequestInfo) (resInfo abci.ResponseInfo) { } func (app *testApp) BeginBlock(req abci.RequestBeginBlock) abci.ResponseBeginBlock { - app.Validators = req.Validators + app.Validators = req.LastCommitInfo.Validators app.ByzantineValidators = req.ByzantineValidators return abci.ResponseBeginBlock{} } diff --git a/types/protobuf.go b/types/protobuf.go index 0ed3d0c43..01d4ebf0c 100644 --- a/types/protobuf.go +++ b/types/protobuf.go @@ -50,6 +50,13 @@ func (tm2pb) Header(header *Header) abci.Header { } } +func (tm2pb) ValidatorWithoutPubKey(val *Validator) abci.Validator { + return abci.Validator{ + Address: val.PubKey.Address(), + Power: val.VotingPower, + } +} + // XXX: panics on unknown pubkey type func (tm2pb) Validator(val *Validator) abci.Validator { return abci.Validator{ @@ -129,7 +136,7 @@ func (tm2pb) Evidence(ev Evidence, valSet *ValidatorSet, evTime time.Time) abci. return abci.Evidence{ Type: evType, - Validator: TM2PB.Validator(val), + Validator: TM2PB.ValidatorWithoutPubKey(val), Height: ev.Height(), Time: evTime, TotalVotingPower: valSet.TotalVotingPower(), diff --git a/types/protobuf_test.go b/types/protobuf_test.go index 6ee79b906..8711974e3 100644 --- a/types/protobuf_test.go +++ b/types/protobuf_test.go @@ -102,6 +102,9 @@ func TestABCIEvidence(t *testing.T) { ) assert.Equal(t, "duplicate/vote", abciEv.Type) + + // test we do not send pubkeys + assert.Empty(t, abciEv.Validator.PubKey) } type pubKeyEddie struct{} @@ -120,3 +123,21 @@ func TestABCIValidatorFromPubKeyAndPower(t *testing.T) { assert.Panics(t, func() { TM2PB.ValidatorFromPubKeyAndPower(nil, 10) }) assert.Panics(t, func() { TM2PB.ValidatorFromPubKeyAndPower(pubKeyEddie{}, 10) }) } + +func TestABCIValidatorWithoutPubKey(t *testing.T) { + pkEd := ed25519.GenPrivKey().PubKey() + + abciVal := TM2PB.ValidatorWithoutPubKey(&Validator{ + Address: pkEd.Address(), + PubKey: pkEd, + VotingPower: 10, + }) + + // pubkey must be nil + tmValExpected := abci.Validator{ + Address: pkEd.Address(), + Power: 10, + } + + assert.Equal(t, tmValExpected, abciVal) +}