ADR-016: Update ABCI Info method for versions (#2662)

* abci: update RequestInfo for versions

* abci: update ResponseInfo for versions

* compile fix

* fix test

* software_version -> version

* comment fix

* update spec

* add test

* comments and fix test
This commit is contained in:
Ethan Buchman 2018-10-18 16:51:17 -04:00 committed by GitHub
parent 055d7adffb
commit ed4ce5ff6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 425 additions and 212 deletions

View File

@ -21,6 +21,8 @@ BREAKING CHANGES:
* [abci] \#2298 ResponseQuery.Proof is now a structured merkle.Proof, not just * [abci] \#2298 ResponseQuery.Proof is now a structured merkle.Proof, not just
arbitrary bytes arbitrary bytes
* [abci] \#2644 Add Version to Header and shift all fields by one * [abci] \#2644 Add Version to Header and shift all fields by one
* [abci] \#2662 Bump the field numbers for some `ResponseInfo` fields to make room for
`AppVersion`
* Go API * Go API
* [node] Remove node.RunForever * [node] Remove node.RunForever
@ -52,6 +54,7 @@ BREAKING CHANGES:
FEATURES: FEATURES:
- [crypto/merkle] \#2298 General Merkle Proof scheme for chaining various types of Merkle trees together - [crypto/merkle] \#2298 General Merkle Proof scheme for chaining various types of Merkle trees together
- [abci] \#2557 Add `Codespace` field to `Response{CheckTx, DeliverTx, Query}` - [abci] \#2557 Add `Codespace` field to `Response{CheckTx, DeliverTx, Query}`
- [abci] \#2662 Add `BlockVersion` and `P2PVersion` to `RequestInfo`
IMPROVEMENTS: IMPROVEMENTS:
- Additional Metrics - Additional Metrics

View File

@ -10,11 +10,14 @@ import (
"github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/abci/types"
cmn "github.com/tendermint/tendermint/libs/common" cmn "github.com/tendermint/tendermint/libs/common"
dbm "github.com/tendermint/tendermint/libs/db" dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/version"
) )
var ( var (
stateKey = []byte("stateKey") stateKey = []byte("stateKey")
kvPairPrefixKey = []byte("kvPairKey:") kvPairPrefixKey = []byte("kvPairKey:")
ProtocolVersion version.Protocol = 0x1
) )
type State struct { type State struct {
@ -65,7 +68,11 @@ func NewKVStoreApplication() *KVStoreApplication {
} }
func (app *KVStoreApplication) Info(req types.RequestInfo) (resInfo types.ResponseInfo) { func (app *KVStoreApplication) Info(req types.RequestInfo) (resInfo types.ResponseInfo) {
return types.ResponseInfo{Data: fmt.Sprintf("{\"size\":%v}", app.state.Size)} return types.ResponseInfo{
Data: fmt.Sprintf("{\"size\":%v}", app.state.Size),
Version: version.ABCIVersion,
AppVersion: ProtocolVersion.Uint64(),
}
} }
// tx is either "key=value" or just arbitrary bytes // tx is either "key=value" or just arbitrary bytes

View File

@ -61,7 +61,7 @@ func (m *Request) Reset() { *m = Request{} }
func (m *Request) String() string { return proto.CompactTextString(m) } func (m *Request) String() string { return proto.CompactTextString(m) }
func (*Request) ProtoMessage() {} func (*Request) ProtoMessage() {}
func (*Request) Descriptor() ([]byte, []int) { func (*Request) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{0} return fileDescriptor_types_4449c1011851ea19, []int{0}
} }
func (m *Request) XXX_Unmarshal(b []byte) error { func (m *Request) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -483,7 +483,7 @@ func (m *RequestEcho) Reset() { *m = RequestEcho{} }
func (m *RequestEcho) String() string { return proto.CompactTextString(m) } func (m *RequestEcho) String() string { return proto.CompactTextString(m) }
func (*RequestEcho) ProtoMessage() {} func (*RequestEcho) ProtoMessage() {}
func (*RequestEcho) Descriptor() ([]byte, []int) { func (*RequestEcho) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{1} return fileDescriptor_types_4449c1011851ea19, []int{1}
} }
func (m *RequestEcho) XXX_Unmarshal(b []byte) error { func (m *RequestEcho) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -529,7 +529,7 @@ func (m *RequestFlush) Reset() { *m = RequestFlush{} }
func (m *RequestFlush) String() string { return proto.CompactTextString(m) } func (m *RequestFlush) String() string { return proto.CompactTextString(m) }
func (*RequestFlush) ProtoMessage() {} func (*RequestFlush) ProtoMessage() {}
func (*RequestFlush) Descriptor() ([]byte, []int) { func (*RequestFlush) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{2} return fileDescriptor_types_4449c1011851ea19, []int{2}
} }
func (m *RequestFlush) XXX_Unmarshal(b []byte) error { func (m *RequestFlush) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -560,6 +560,8 @@ var xxx_messageInfo_RequestFlush proto.InternalMessageInfo
type RequestInfo struct { type RequestInfo struct {
Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`
BlockVersion uint64 `protobuf:"varint,2,opt,name=block_version,json=blockVersion,proto3" json:"block_version,omitempty"`
P2PVersion uint64 `protobuf:"varint,3,opt,name=p2p_version,json=p2pVersion,proto3" json:"p2p_version,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -569,7 +571,7 @@ func (m *RequestInfo) Reset() { *m = RequestInfo{} }
func (m *RequestInfo) String() string { return proto.CompactTextString(m) } func (m *RequestInfo) String() string { return proto.CompactTextString(m) }
func (*RequestInfo) ProtoMessage() {} func (*RequestInfo) ProtoMessage() {}
func (*RequestInfo) Descriptor() ([]byte, []int) { func (*RequestInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{3} return fileDescriptor_types_4449c1011851ea19, []int{3}
} }
func (m *RequestInfo) XXX_Unmarshal(b []byte) error { func (m *RequestInfo) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -605,6 +607,20 @@ func (m *RequestInfo) GetVersion() string {
return "" return ""
} }
func (m *RequestInfo) GetBlockVersion() uint64 {
if m != nil {
return m.BlockVersion
}
return 0
}
func (m *RequestInfo) GetP2PVersion() uint64 {
if m != nil {
return m.P2PVersion
}
return 0
}
// nondeterministic // nondeterministic
type RequestSetOption struct { type RequestSetOption struct {
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
@ -618,7 +634,7 @@ func (m *RequestSetOption) Reset() { *m = RequestSetOption{} }
func (m *RequestSetOption) String() string { return proto.CompactTextString(m) } func (m *RequestSetOption) String() string { return proto.CompactTextString(m) }
func (*RequestSetOption) ProtoMessage() {} func (*RequestSetOption) ProtoMessage() {}
func (*RequestSetOption) Descriptor() ([]byte, []int) { func (*RequestSetOption) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{4} return fileDescriptor_types_4449c1011851ea19, []int{4}
} }
func (m *RequestSetOption) XXX_Unmarshal(b []byte) error { func (m *RequestSetOption) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -676,7 +692,7 @@ func (m *RequestInitChain) Reset() { *m = RequestInitChain{} }
func (m *RequestInitChain) String() string { return proto.CompactTextString(m) } func (m *RequestInitChain) String() string { return proto.CompactTextString(m) }
func (*RequestInitChain) ProtoMessage() {} func (*RequestInitChain) ProtoMessage() {}
func (*RequestInitChain) Descriptor() ([]byte, []int) { func (*RequestInitChain) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{5} return fileDescriptor_types_4449c1011851ea19, []int{5}
} }
func (m *RequestInitChain) XXX_Unmarshal(b []byte) error { func (m *RequestInitChain) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -754,7 +770,7 @@ func (m *RequestQuery) Reset() { *m = RequestQuery{} }
func (m *RequestQuery) String() string { return proto.CompactTextString(m) } func (m *RequestQuery) String() string { return proto.CompactTextString(m) }
func (*RequestQuery) ProtoMessage() {} func (*RequestQuery) ProtoMessage() {}
func (*RequestQuery) Descriptor() ([]byte, []int) { func (*RequestQuery) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{6} return fileDescriptor_types_4449c1011851ea19, []int{6}
} }
func (m *RequestQuery) XXX_Unmarshal(b []byte) error { func (m *RequestQuery) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -826,7 +842,7 @@ func (m *RequestBeginBlock) Reset() { *m = RequestBeginBlock{} }
func (m *RequestBeginBlock) String() string { return proto.CompactTextString(m) } func (m *RequestBeginBlock) String() string { return proto.CompactTextString(m) }
func (*RequestBeginBlock) ProtoMessage() {} func (*RequestBeginBlock) ProtoMessage() {}
func (*RequestBeginBlock) Descriptor() ([]byte, []int) { func (*RequestBeginBlock) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{7} return fileDescriptor_types_4449c1011851ea19, []int{7}
} }
func (m *RequestBeginBlock) XXX_Unmarshal(b []byte) error { func (m *RequestBeginBlock) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -894,7 +910,7 @@ func (m *RequestCheckTx) Reset() { *m = RequestCheckTx{} }
func (m *RequestCheckTx) String() string { return proto.CompactTextString(m) } func (m *RequestCheckTx) String() string { return proto.CompactTextString(m) }
func (*RequestCheckTx) ProtoMessage() {} func (*RequestCheckTx) ProtoMessage() {}
func (*RequestCheckTx) Descriptor() ([]byte, []int) { func (*RequestCheckTx) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{8} return fileDescriptor_types_4449c1011851ea19, []int{8}
} }
func (m *RequestCheckTx) XXX_Unmarshal(b []byte) error { func (m *RequestCheckTx) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -941,7 +957,7 @@ func (m *RequestDeliverTx) Reset() { *m = RequestDeliverTx{} }
func (m *RequestDeliverTx) String() string { return proto.CompactTextString(m) } func (m *RequestDeliverTx) String() string { return proto.CompactTextString(m) }
func (*RequestDeliverTx) ProtoMessage() {} func (*RequestDeliverTx) ProtoMessage() {}
func (*RequestDeliverTx) Descriptor() ([]byte, []int) { func (*RequestDeliverTx) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{9} return fileDescriptor_types_4449c1011851ea19, []int{9}
} }
func (m *RequestDeliverTx) XXX_Unmarshal(b []byte) error { func (m *RequestDeliverTx) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -988,7 +1004,7 @@ func (m *RequestEndBlock) Reset() { *m = RequestEndBlock{} }
func (m *RequestEndBlock) String() string { return proto.CompactTextString(m) } func (m *RequestEndBlock) String() string { return proto.CompactTextString(m) }
func (*RequestEndBlock) ProtoMessage() {} func (*RequestEndBlock) ProtoMessage() {}
func (*RequestEndBlock) Descriptor() ([]byte, []int) { func (*RequestEndBlock) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{10} return fileDescriptor_types_4449c1011851ea19, []int{10}
} }
func (m *RequestEndBlock) XXX_Unmarshal(b []byte) error { func (m *RequestEndBlock) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1034,7 +1050,7 @@ func (m *RequestCommit) Reset() { *m = RequestCommit{} }
func (m *RequestCommit) String() string { return proto.CompactTextString(m) } func (m *RequestCommit) String() string { return proto.CompactTextString(m) }
func (*RequestCommit) ProtoMessage() {} func (*RequestCommit) ProtoMessage() {}
func (*RequestCommit) Descriptor() ([]byte, []int) { func (*RequestCommit) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{11} return fileDescriptor_types_4449c1011851ea19, []int{11}
} }
func (m *RequestCommit) XXX_Unmarshal(b []byte) error { func (m *RequestCommit) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1087,7 +1103,7 @@ func (m *Response) Reset() { *m = Response{} }
func (m *Response) String() string { return proto.CompactTextString(m) } func (m *Response) String() string { return proto.CompactTextString(m) }
func (*Response) ProtoMessage() {} func (*Response) ProtoMessage() {}
func (*Response) Descriptor() ([]byte, []int) { func (*Response) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{12} return fileDescriptor_types_4449c1011851ea19, []int{12}
} }
func (m *Response) XXX_Unmarshal(b []byte) error { func (m *Response) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1540,7 +1556,7 @@ func (m *ResponseException) Reset() { *m = ResponseException{} }
func (m *ResponseException) String() string { return proto.CompactTextString(m) } func (m *ResponseException) String() string { return proto.CompactTextString(m) }
func (*ResponseException) ProtoMessage() {} func (*ResponseException) ProtoMessage() {}
func (*ResponseException) Descriptor() ([]byte, []int) { func (*ResponseException) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{13} return fileDescriptor_types_4449c1011851ea19, []int{13}
} }
func (m *ResponseException) XXX_Unmarshal(b []byte) error { func (m *ResponseException) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1587,7 +1603,7 @@ func (m *ResponseEcho) Reset() { *m = ResponseEcho{} }
func (m *ResponseEcho) String() string { return proto.CompactTextString(m) } func (m *ResponseEcho) String() string { return proto.CompactTextString(m) }
func (*ResponseEcho) ProtoMessage() {} func (*ResponseEcho) ProtoMessage() {}
func (*ResponseEcho) Descriptor() ([]byte, []int) { func (*ResponseEcho) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{14} return fileDescriptor_types_4449c1011851ea19, []int{14}
} }
func (m *ResponseEcho) XXX_Unmarshal(b []byte) error { func (m *ResponseEcho) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1633,7 +1649,7 @@ func (m *ResponseFlush) Reset() { *m = ResponseFlush{} }
func (m *ResponseFlush) String() string { return proto.CompactTextString(m) } func (m *ResponseFlush) String() string { return proto.CompactTextString(m) }
func (*ResponseFlush) ProtoMessage() {} func (*ResponseFlush) ProtoMessage() {}
func (*ResponseFlush) Descriptor() ([]byte, []int) { func (*ResponseFlush) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{15} return fileDescriptor_types_4449c1011851ea19, []int{15}
} }
func (m *ResponseFlush) XXX_Unmarshal(b []byte) error { func (m *ResponseFlush) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1665,8 +1681,9 @@ var xxx_messageInfo_ResponseFlush proto.InternalMessageInfo
type ResponseInfo struct { type ResponseInfo struct {
Data string `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` Data string `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"`
LastBlockHeight int64 `protobuf:"varint,3,opt,name=last_block_height,json=lastBlockHeight,proto3" json:"last_block_height,omitempty"` AppVersion uint64 `protobuf:"varint,3,opt,name=app_version,json=appVersion,proto3" json:"app_version,omitempty"`
LastBlockAppHash []byte `protobuf:"bytes,4,opt,name=last_block_app_hash,json=lastBlockAppHash,proto3" json:"last_block_app_hash,omitempty"` LastBlockHeight int64 `protobuf:"varint,4,opt,name=last_block_height,json=lastBlockHeight,proto3" json:"last_block_height,omitempty"`
LastBlockAppHash []byte `protobuf:"bytes,5,opt,name=last_block_app_hash,json=lastBlockAppHash,proto3" json:"last_block_app_hash,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -1676,7 +1693,7 @@ func (m *ResponseInfo) Reset() { *m = ResponseInfo{} }
func (m *ResponseInfo) String() string { return proto.CompactTextString(m) } func (m *ResponseInfo) String() string { return proto.CompactTextString(m) }
func (*ResponseInfo) ProtoMessage() {} func (*ResponseInfo) ProtoMessage() {}
func (*ResponseInfo) Descriptor() ([]byte, []int) { func (*ResponseInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{16} return fileDescriptor_types_4449c1011851ea19, []int{16}
} }
func (m *ResponseInfo) XXX_Unmarshal(b []byte) error { func (m *ResponseInfo) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1719,6 +1736,13 @@ func (m *ResponseInfo) GetVersion() string {
return "" return ""
} }
func (m *ResponseInfo) GetAppVersion() uint64 {
if m != nil {
return m.AppVersion
}
return 0
}
func (m *ResponseInfo) GetLastBlockHeight() int64 { func (m *ResponseInfo) GetLastBlockHeight() int64 {
if m != nil { if m != nil {
return m.LastBlockHeight return m.LastBlockHeight
@ -1748,7 +1772,7 @@ func (m *ResponseSetOption) Reset() { *m = ResponseSetOption{} }
func (m *ResponseSetOption) String() string { return proto.CompactTextString(m) } func (m *ResponseSetOption) String() string { return proto.CompactTextString(m) }
func (*ResponseSetOption) ProtoMessage() {} func (*ResponseSetOption) ProtoMessage() {}
func (*ResponseSetOption) Descriptor() ([]byte, []int) { func (*ResponseSetOption) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{17} return fileDescriptor_types_4449c1011851ea19, []int{17}
} }
func (m *ResponseSetOption) XXX_Unmarshal(b []byte) error { func (m *ResponseSetOption) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1810,7 +1834,7 @@ func (m *ResponseInitChain) Reset() { *m = ResponseInitChain{} }
func (m *ResponseInitChain) String() string { return proto.CompactTextString(m) } func (m *ResponseInitChain) String() string { return proto.CompactTextString(m) }
func (*ResponseInitChain) ProtoMessage() {} func (*ResponseInitChain) ProtoMessage() {}
func (*ResponseInitChain) Descriptor() ([]byte, []int) { func (*ResponseInitChain) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{18} return fileDescriptor_types_4449c1011851ea19, []int{18}
} }
func (m *ResponseInitChain) XXX_Unmarshal(b []byte) error { func (m *ResponseInitChain) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1873,7 +1897,7 @@ func (m *ResponseQuery) Reset() { *m = ResponseQuery{} }
func (m *ResponseQuery) String() string { return proto.CompactTextString(m) } func (m *ResponseQuery) String() string { return proto.CompactTextString(m) }
func (*ResponseQuery) ProtoMessage() {} func (*ResponseQuery) ProtoMessage() {}
func (*ResponseQuery) Descriptor() ([]byte, []int) { func (*ResponseQuery) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{19} return fileDescriptor_types_4449c1011851ea19, []int{19}
} }
func (m *ResponseQuery) XXX_Unmarshal(b []byte) error { func (m *ResponseQuery) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1976,7 +2000,7 @@ func (m *ResponseBeginBlock) Reset() { *m = ResponseBeginBlock{} }
func (m *ResponseBeginBlock) String() string { return proto.CompactTextString(m) } func (m *ResponseBeginBlock) String() string { return proto.CompactTextString(m) }
func (*ResponseBeginBlock) ProtoMessage() {} func (*ResponseBeginBlock) ProtoMessage() {}
func (*ResponseBeginBlock) Descriptor() ([]byte, []int) { func (*ResponseBeginBlock) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{20} return fileDescriptor_types_4449c1011851ea19, []int{20}
} }
func (m *ResponseBeginBlock) XXX_Unmarshal(b []byte) error { func (m *ResponseBeginBlock) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2030,7 +2054,7 @@ func (m *ResponseCheckTx) Reset() { *m = ResponseCheckTx{} }
func (m *ResponseCheckTx) String() string { return proto.CompactTextString(m) } func (m *ResponseCheckTx) String() string { return proto.CompactTextString(m) }
func (*ResponseCheckTx) ProtoMessage() {} func (*ResponseCheckTx) ProtoMessage() {}
func (*ResponseCheckTx) Descriptor() ([]byte, []int) { func (*ResponseCheckTx) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{21} return fileDescriptor_types_4449c1011851ea19, []int{21}
} }
func (m *ResponseCheckTx) XXX_Unmarshal(b []byte) error { func (m *ResponseCheckTx) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2133,7 +2157,7 @@ func (m *ResponseDeliverTx) Reset() { *m = ResponseDeliverTx{} }
func (m *ResponseDeliverTx) String() string { return proto.CompactTextString(m) } func (m *ResponseDeliverTx) String() string { return proto.CompactTextString(m) }
func (*ResponseDeliverTx) ProtoMessage() {} func (*ResponseDeliverTx) ProtoMessage() {}
func (*ResponseDeliverTx) Descriptor() ([]byte, []int) { func (*ResponseDeliverTx) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{22} return fileDescriptor_types_4449c1011851ea19, []int{22}
} }
func (m *ResponseDeliverTx) XXX_Unmarshal(b []byte) error { func (m *ResponseDeliverTx) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2231,7 +2255,7 @@ func (m *ResponseEndBlock) Reset() { *m = ResponseEndBlock{} }
func (m *ResponseEndBlock) String() string { return proto.CompactTextString(m) } func (m *ResponseEndBlock) String() string { return proto.CompactTextString(m) }
func (*ResponseEndBlock) ProtoMessage() {} func (*ResponseEndBlock) ProtoMessage() {}
func (*ResponseEndBlock) Descriptor() ([]byte, []int) { func (*ResponseEndBlock) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{23} return fileDescriptor_types_4449c1011851ea19, []int{23}
} }
func (m *ResponseEndBlock) XXX_Unmarshal(b []byte) error { func (m *ResponseEndBlock) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2293,7 +2317,7 @@ func (m *ResponseCommit) Reset() { *m = ResponseCommit{} }
func (m *ResponseCommit) String() string { return proto.CompactTextString(m) } func (m *ResponseCommit) String() string { return proto.CompactTextString(m) }
func (*ResponseCommit) ProtoMessage() {} func (*ResponseCommit) ProtoMessage() {}
func (*ResponseCommit) Descriptor() ([]byte, []int) { func (*ResponseCommit) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{24} return fileDescriptor_types_4449c1011851ea19, []int{24}
} }
func (m *ResponseCommit) XXX_Unmarshal(b []byte) error { func (m *ResponseCommit) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2343,7 +2367,7 @@ func (m *ConsensusParams) Reset() { *m = ConsensusParams{} }
func (m *ConsensusParams) String() string { return proto.CompactTextString(m) } func (m *ConsensusParams) String() string { return proto.CompactTextString(m) }
func (*ConsensusParams) ProtoMessage() {} func (*ConsensusParams) ProtoMessage() {}
func (*ConsensusParams) Descriptor() ([]byte, []int) { func (*ConsensusParams) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{25} return fileDescriptor_types_4449c1011851ea19, []int{25}
} }
func (m *ConsensusParams) XXX_Unmarshal(b []byte) error { func (m *ConsensusParams) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2401,7 +2425,7 @@ func (m *BlockSize) Reset() { *m = BlockSize{} }
func (m *BlockSize) String() string { return proto.CompactTextString(m) } func (m *BlockSize) String() string { return proto.CompactTextString(m) }
func (*BlockSize) ProtoMessage() {} func (*BlockSize) ProtoMessage() {}
func (*BlockSize) Descriptor() ([]byte, []int) { func (*BlockSize) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{26} return fileDescriptor_types_4449c1011851ea19, []int{26}
} }
func (m *BlockSize) XXX_Unmarshal(b []byte) error { func (m *BlockSize) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2457,7 +2481,7 @@ func (m *EvidenceParams) Reset() { *m = EvidenceParams{} }
func (m *EvidenceParams) String() string { return proto.CompactTextString(m) } func (m *EvidenceParams) String() string { return proto.CompactTextString(m) }
func (*EvidenceParams) ProtoMessage() {} func (*EvidenceParams) ProtoMessage() {}
func (*EvidenceParams) Descriptor() ([]byte, []int) { func (*EvidenceParams) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{27} return fileDescriptor_types_4449c1011851ea19, []int{27}
} }
func (m *EvidenceParams) XXX_Unmarshal(b []byte) error { func (m *EvidenceParams) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2505,7 +2529,7 @@ func (m *LastCommitInfo) Reset() { *m = LastCommitInfo{} }
func (m *LastCommitInfo) String() string { return proto.CompactTextString(m) } func (m *LastCommitInfo) String() string { return proto.CompactTextString(m) }
func (*LastCommitInfo) ProtoMessage() {} func (*LastCommitInfo) ProtoMessage() {}
func (*LastCommitInfo) Descriptor() ([]byte, []int) { func (*LastCommitInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{28} return fileDescriptor_types_4449c1011851ea19, []int{28}
} }
func (m *LastCommitInfo) XXX_Unmarshal(b []byte) error { func (m *LastCommitInfo) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2579,7 +2603,7 @@ func (m *Header) Reset() { *m = Header{} }
func (m *Header) String() string { return proto.CompactTextString(m) } func (m *Header) String() string { return proto.CompactTextString(m) }
func (*Header) ProtoMessage() {} func (*Header) ProtoMessage() {}
func (*Header) Descriptor() ([]byte, []int) { func (*Header) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{29} return fileDescriptor_types_4449c1011851ea19, []int{29}
} }
func (m *Header) XXX_Unmarshal(b []byte) error { func (m *Header) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2732,7 +2756,7 @@ func (m *Version) Reset() { *m = Version{} }
func (m *Version) String() string { return proto.CompactTextString(m) } func (m *Version) String() string { return proto.CompactTextString(m) }
func (*Version) ProtoMessage() {} func (*Version) ProtoMessage() {}
func (*Version) Descriptor() ([]byte, []int) { func (*Version) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{30} return fileDescriptor_types_4449c1011851ea19, []int{30}
} }
func (m *Version) XXX_Unmarshal(b []byte) error { func (m *Version) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2787,7 +2811,7 @@ func (m *BlockID) Reset() { *m = BlockID{} }
func (m *BlockID) String() string { return proto.CompactTextString(m) } func (m *BlockID) String() string { return proto.CompactTextString(m) }
func (*BlockID) ProtoMessage() {} func (*BlockID) ProtoMessage() {}
func (*BlockID) Descriptor() ([]byte, []int) { func (*BlockID) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{31} return fileDescriptor_types_4449c1011851ea19, []int{31}
} }
func (m *BlockID) XXX_Unmarshal(b []byte) error { func (m *BlockID) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2842,7 +2866,7 @@ func (m *PartSetHeader) Reset() { *m = PartSetHeader{} }
func (m *PartSetHeader) String() string { return proto.CompactTextString(m) } func (m *PartSetHeader) String() string { return proto.CompactTextString(m) }
func (*PartSetHeader) ProtoMessage() {} func (*PartSetHeader) ProtoMessage() {}
func (*PartSetHeader) Descriptor() ([]byte, []int) { func (*PartSetHeader) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{32} return fileDescriptor_types_4449c1011851ea19, []int{32}
} }
func (m *PartSetHeader) XXX_Unmarshal(b []byte) error { func (m *PartSetHeader) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2899,7 +2923,7 @@ func (m *Validator) Reset() { *m = Validator{} }
func (m *Validator) String() string { return proto.CompactTextString(m) } func (m *Validator) String() string { return proto.CompactTextString(m) }
func (*Validator) ProtoMessage() {} func (*Validator) ProtoMessage() {}
func (*Validator) Descriptor() ([]byte, []int) { func (*Validator) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{33} return fileDescriptor_types_4449c1011851ea19, []int{33}
} }
func (m *Validator) XXX_Unmarshal(b []byte) error { func (m *Validator) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2955,7 +2979,7 @@ func (m *ValidatorUpdate) Reset() { *m = ValidatorUpdate{} }
func (m *ValidatorUpdate) String() string { return proto.CompactTextString(m) } func (m *ValidatorUpdate) String() string { return proto.CompactTextString(m) }
func (*ValidatorUpdate) ProtoMessage() {} func (*ValidatorUpdate) ProtoMessage() {}
func (*ValidatorUpdate) Descriptor() ([]byte, []int) { func (*ValidatorUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{34} return fileDescriptor_types_4449c1011851ea19, []int{34}
} }
func (m *ValidatorUpdate) XXX_Unmarshal(b []byte) error { func (m *ValidatorUpdate) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -3011,7 +3035,7 @@ func (m *VoteInfo) Reset() { *m = VoteInfo{} }
func (m *VoteInfo) String() string { return proto.CompactTextString(m) } func (m *VoteInfo) String() string { return proto.CompactTextString(m) }
func (*VoteInfo) ProtoMessage() {} func (*VoteInfo) ProtoMessage() {}
func (*VoteInfo) Descriptor() ([]byte, []int) { func (*VoteInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{35} return fileDescriptor_types_4449c1011851ea19, []int{35}
} }
func (m *VoteInfo) XXX_Unmarshal(b []byte) error { func (m *VoteInfo) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -3066,7 +3090,7 @@ func (m *PubKey) Reset() { *m = PubKey{} }
func (m *PubKey) String() string { return proto.CompactTextString(m) } func (m *PubKey) String() string { return proto.CompactTextString(m) }
func (*PubKey) ProtoMessage() {} func (*PubKey) ProtoMessage() {}
func (*PubKey) Descriptor() ([]byte, []int) { func (*PubKey) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{36} return fileDescriptor_types_4449c1011851ea19, []int{36}
} }
func (m *PubKey) XXX_Unmarshal(b []byte) error { func (m *PubKey) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -3124,7 +3148,7 @@ func (m *Evidence) Reset() { *m = Evidence{} }
func (m *Evidence) String() string { return proto.CompactTextString(m) } func (m *Evidence) String() string { return proto.CompactTextString(m) }
func (*Evidence) ProtoMessage() {} func (*Evidence) ProtoMessage() {}
func (*Evidence) Descriptor() ([]byte, []int) { func (*Evidence) Descriptor() ([]byte, []int) {
return fileDescriptor_types_07d64ea985a686e2, []int{37} return fileDescriptor_types_4449c1011851ea19, []int{37}
} }
func (m *Evidence) XXX_Unmarshal(b []byte) error { func (m *Evidence) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -3636,6 +3660,12 @@ func (this *RequestInfo) Equal(that interface{}) bool {
if this.Version != that1.Version { if this.Version != that1.Version {
return false return false
} }
if this.BlockVersion != that1.BlockVersion {
return false
}
if this.P2PVersion != that1.P2PVersion {
return false
}
if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
return false return false
} }
@ -4321,6 +4351,9 @@ func (this *ResponseInfo) Equal(that interface{}) bool {
if this.Version != that1.Version { if this.Version != that1.Version {
return false return false
} }
if this.AppVersion != that1.AppVersion {
return false
}
if this.LastBlockHeight != that1.LastBlockHeight { if this.LastBlockHeight != that1.LastBlockHeight {
return false return false
} }
@ -5758,6 +5791,16 @@ func (m *RequestInfo) MarshalTo(dAtA []byte) (int, error) {
i = encodeVarintTypes(dAtA, i, uint64(len(m.Version))) i = encodeVarintTypes(dAtA, i, uint64(len(m.Version)))
i += copy(dAtA[i:], m.Version) i += copy(dAtA[i:], m.Version)
} }
if m.BlockVersion != 0 {
dAtA[i] = 0x10
i++
i = encodeVarintTypes(dAtA, i, uint64(m.BlockVersion))
}
if m.P2PVersion != 0 {
dAtA[i] = 0x18
i++
i = encodeVarintTypes(dAtA, i, uint64(m.P2PVersion))
}
if m.XXX_unrecognized != nil { if m.XXX_unrecognized != nil {
i += copy(dAtA[i:], m.XXX_unrecognized) i += copy(dAtA[i:], m.XXX_unrecognized)
} }
@ -6362,13 +6405,18 @@ func (m *ResponseInfo) MarshalTo(dAtA []byte) (int, error) {
i = encodeVarintTypes(dAtA, i, uint64(len(m.Version))) i = encodeVarintTypes(dAtA, i, uint64(len(m.Version)))
i += copy(dAtA[i:], m.Version) i += copy(dAtA[i:], m.Version)
} }
if m.LastBlockHeight != 0 { if m.AppVersion != 0 {
dAtA[i] = 0x18 dAtA[i] = 0x18
i++ i++
i = encodeVarintTypes(dAtA, i, uint64(m.AppVersion))
}
if m.LastBlockHeight != 0 {
dAtA[i] = 0x20
i++
i = encodeVarintTypes(dAtA, i, uint64(m.LastBlockHeight)) i = encodeVarintTypes(dAtA, i, uint64(m.LastBlockHeight))
} }
if len(m.LastBlockAppHash) > 0 { if len(m.LastBlockAppHash) > 0 {
dAtA[i] = 0x22 dAtA[i] = 0x2a
i++ i++
i = encodeVarintTypes(dAtA, i, uint64(len(m.LastBlockAppHash))) i = encodeVarintTypes(dAtA, i, uint64(len(m.LastBlockAppHash)))
i += copy(dAtA[i:], m.LastBlockAppHash) i += copy(dAtA[i:], m.LastBlockAppHash)
@ -7459,8 +7507,10 @@ func NewPopulatedRequestFlush(r randyTypes, easy bool) *RequestFlush {
func NewPopulatedRequestInfo(r randyTypes, easy bool) *RequestInfo { func NewPopulatedRequestInfo(r randyTypes, easy bool) *RequestInfo {
this := &RequestInfo{} this := &RequestInfo{}
this.Version = string(randStringTypes(r)) this.Version = string(randStringTypes(r))
this.BlockVersion = uint64(uint64(r.Uint32()))
this.P2PVersion = uint64(uint64(r.Uint32()))
if !easy && r.Intn(10) != 0 { if !easy && r.Intn(10) != 0 {
this.XXX_unrecognized = randUnrecognizedTypes(r, 2) this.XXX_unrecognized = randUnrecognizedTypes(r, 4)
} }
return this return this
} }
@ -7717,6 +7767,7 @@ func NewPopulatedResponseInfo(r randyTypes, easy bool) *ResponseInfo {
this := &ResponseInfo{} this := &ResponseInfo{}
this.Data = string(randStringTypes(r)) this.Data = string(randStringTypes(r))
this.Version = string(randStringTypes(r)) this.Version = string(randStringTypes(r))
this.AppVersion = uint64(uint64(r.Uint32()))
this.LastBlockHeight = int64(r.Int63()) this.LastBlockHeight = int64(r.Int63())
if r.Intn(2) == 0 { if r.Intn(2) == 0 {
this.LastBlockHeight *= -1 this.LastBlockHeight *= -1
@ -7727,7 +7778,7 @@ func NewPopulatedResponseInfo(r randyTypes, easy bool) *ResponseInfo {
this.LastBlockAppHash[i] = byte(r.Intn(256)) this.LastBlockAppHash[i] = byte(r.Intn(256))
} }
if !easy && r.Intn(10) != 0 { if !easy && r.Intn(10) != 0 {
this.XXX_unrecognized = randUnrecognizedTypes(r, 5) this.XXX_unrecognized = randUnrecognizedTypes(r, 6)
} }
return this return this
} }
@ -8382,6 +8433,12 @@ func (m *RequestInfo) Size() (n int) {
if l > 0 { if l > 0 {
n += 1 + l + sovTypes(uint64(l)) n += 1 + l + sovTypes(uint64(l))
} }
if m.BlockVersion != 0 {
n += 1 + sovTypes(uint64(m.BlockVersion))
}
if m.P2PVersion != 0 {
n += 1 + sovTypes(uint64(m.P2PVersion))
}
if m.XXX_unrecognized != nil { if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized) n += len(m.XXX_unrecognized)
} }
@ -8693,6 +8750,9 @@ func (m *ResponseInfo) Size() (n int) {
if l > 0 { if l > 0 {
n += 1 + l + sovTypes(uint64(l)) n += 1 + l + sovTypes(uint64(l))
} }
if m.AppVersion != 0 {
n += 1 + sovTypes(uint64(m.AppVersion))
}
if m.LastBlockHeight != 0 { if m.LastBlockHeight != 0 {
n += 1 + sovTypes(uint64(m.LastBlockHeight)) n += 1 + sovTypes(uint64(m.LastBlockHeight))
} }
@ -9781,6 +9841,44 @@ func (m *RequestInfo) Unmarshal(dAtA []byte) error {
} }
m.Version = string(dAtA[iNdEx:postIndex]) m.Version = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex iNdEx = postIndex
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field BlockVersion", wireType)
}
m.BlockVersion = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.BlockVersion |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field P2PVersion", wireType)
}
m.P2PVersion = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.P2PVersion |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipTypes(dAtA[iNdEx:]) skippy, err := skipTypes(dAtA[iNdEx:])
@ -11459,6 +11557,25 @@ func (m *ResponseInfo) Unmarshal(dAtA []byte) error {
m.Version = string(dAtA[iNdEx:postIndex]) m.Version = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex iNdEx = postIndex
case 3: case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field AppVersion", wireType)
}
m.AppVersion = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.AppVersion |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 4:
if wireType != 0 { if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field LastBlockHeight", wireType) return fmt.Errorf("proto: wrong wireType = %d for field LastBlockHeight", wireType)
} }
@ -11477,7 +11594,7 @@ func (m *ResponseInfo) Unmarshal(dAtA []byte) error {
break break
} }
} }
case 4: case 5:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field LastBlockAppHash", wireType) return fmt.Errorf("proto: wrong wireType = %d for field LastBlockAppHash", wireType)
} }
@ -14768,145 +14885,148 @@ var (
ErrIntOverflowTypes = fmt.Errorf("proto: integer overflow") ErrIntOverflowTypes = fmt.Errorf("proto: integer overflow")
) )
func init() { proto.RegisterFile("abci/types/types.proto", fileDescriptor_types_07d64ea985a686e2) } func init() { proto.RegisterFile("abci/types/types.proto", fileDescriptor_types_4449c1011851ea19) }
func init() { func init() {
golang_proto.RegisterFile("abci/types/types.proto", fileDescriptor_types_07d64ea985a686e2) golang_proto.RegisterFile("abci/types/types.proto", fileDescriptor_types_4449c1011851ea19)
} }
var fileDescriptor_types_07d64ea985a686e2 = []byte{ var fileDescriptor_types_4449c1011851ea19 = []byte{
// 2133 bytes of a gzipped FileDescriptorProto // 2177 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x58, 0xcd, 0x93, 0x1b, 0x47, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x58, 0xcd, 0x93, 0x1b, 0x47,
0x15, 0xdf, 0xd1, 0x6a, 0x25, 0xcd, 0xdb, 0x5d, 0x49, 0x6e, 0x7f, 0xc9, 0x22, 0xac, 0x5d, 0x13, 0x15, 0xdf, 0xd1, 0x6a, 0x25, 0xcd, 0xd3, 0xea, 0x23, 0xed, 0xb5, 0x2d, 0x8b, 0xb0, 0xeb, 0x1a,
0x48, 0xbc, 0xc4, 0xd1, 0x06, 0x87, 0x50, 0xeb, 0x38, 0xa4, 0x6a, 0x65, 0x1b, 0x76, 0x2b, 0x01, 0x43, 0xe2, 0x25, 0x8e, 0x36, 0x6c, 0x08, 0xb5, 0x8e, 0x43, 0xaa, 0x56, 0xb6, 0x61, 0xb7, 0x12,
0x96, 0xf1, 0x07, 0x17, 0xaa, 0xa6, 0x5a, 0x9a, 0xb6, 0x34, 0x65, 0x69, 0x66, 0x32, 0xd3, 0xda, 0x60, 0x19, 0xdb, 0xcb, 0x85, 0xaa, 0xa9, 0x96, 0xa6, 0x2d, 0x4d, 0x59, 0x9a, 0x99, 0xcc, 0xb4,
0x68, 0x7d, 0xcc, 0x39, 0x87, 0x1c, 0xa8, 0xe2, 0x5f, 0xe0, 0x4f, 0xe0, 0xc8, 0x89, 0xca, 0x91, 0x36, 0x5a, 0x1f, 0x73, 0xce, 0x21, 0x07, 0xfe, 0x08, 0xfe, 0x84, 0x1c, 0x39, 0x51, 0x39, 0x72,
0x03, 0x67, 0x03, 0x4b, 0x71, 0x80, 0x2b, 0x45, 0x15, 0x47, 0xea, 0xbd, 0xee, 0xf9, 0xdc, 0x91, 0xe0, 0x6c, 0x60, 0x29, 0x0e, 0x70, 0xa5, 0xa8, 0xe2, 0x48, 0xf5, 0xeb, 0xee, 0xf9, 0xda, 0x91,
0x89, 0x03, 0x27, 0x2e, 0xd2, 0xf4, 0xfb, 0xe8, 0x8f, 0xd7, 0xef, 0xbd, 0xdf, 0x7b, 0x0d, 0x57, 0x89, 0x03, 0x27, 0x2e, 0x52, 0xf7, 0xfb, 0xe8, 0x8f, 0x37, 0xef, 0xbd, 0xdf, 0x7b, 0x0d, 0xd7,
0xf8, 0x68, 0xec, 0xed, 0xc9, 0xd3, 0x50, 0xc4, 0xea, 0x77, 0x10, 0x46, 0x81, 0x0c, 0xd8, 0x06, 0xe8, 0x68, 0xec, 0xed, 0xf1, 0xf3, 0x90, 0xc5, 0xf2, 0x77, 0x10, 0x46, 0x01, 0x0f, 0xc8, 0x06,
0x0d, 0xfa, 0x6f, 0x4f, 0x3c, 0x39, 0x5d, 0x8c, 0x06, 0xe3, 0x60, 0xbe, 0x37, 0x09, 0x26, 0xc1, 0x4e, 0xfa, 0x6f, 0x4f, 0x3c, 0x3e, 0x5d, 0x8c, 0x06, 0xe3, 0x60, 0xbe, 0x37, 0x09, 0x26, 0xc1,
0x1e, 0x71, 0x47, 0x8b, 0xa7, 0x34, 0xa2, 0x01, 0x7d, 0x29, 0xad, 0xfe, 0xf5, 0x49, 0x10, 0x4c, 0x1e, 0x72, 0x47, 0x8b, 0xa7, 0x38, 0xc3, 0x09, 0x8e, 0xa4, 0x56, 0x7f, 0x67, 0x12, 0x04, 0x93,
0x66, 0x22, 0x93, 0x92, 0xde, 0x5c, 0xc4, 0x92, 0xcf, 0x43, 0x2d, 0xb0, 0x9f, 0x9b, 0x4f, 0x0a, 0x19, 0x4b, 0xa5, 0xb8, 0x37, 0x67, 0x31, 0xa7, 0xf3, 0x50, 0x09, 0x1c, 0x64, 0xd6, 0xe3, 0xcc,
0xdf, 0x15, 0xd1, 0xdc, 0xf3, 0x65, 0xfe, 0x73, 0xe6, 0x8d, 0xe2, 0xbd, 0x71, 0x30, 0x9f, 0x07, 0x77, 0x59, 0x34, 0xf7, 0x7c, 0x9e, 0x1d, 0xce, 0xbc, 0x51, 0xbc, 0x37, 0x0e, 0xe6, 0xf3, 0xc0,
0x7e, 0x7e, 0x43, 0xfd, 0xbb, 0xff, 0x51, 0x73, 0x1c, 0x9d, 0x86, 0x32, 0xd8, 0x9b, 0x8b, 0xe8, 0xcf, 0x1e, 0xa8, 0x7f, 0xef, 0x3f, 0x6a, 0x8e, 0xa3, 0xf3, 0x90, 0x07, 0x7b, 0x73, 0x16, 0x3d,
0xd9, 0x4c, 0xe8, 0x3f, 0xa5, 0x6c, 0xfd, 0xae, 0x0e, 0x4d, 0x5b, 0x7c, 0xb2, 0x10, 0xb1, 0x64, 0x9b, 0x31, 0xf5, 0x27, 0x95, 0xad, 0xdf, 0x55, 0xa1, 0x6e, 0xb3, 0x4f, 0x16, 0x2c, 0xe6, 0xe4,
0x37, 0xa1, 0x2e, 0xc6, 0xd3, 0xa0, 0x57, 0xbb, 0x61, 0xdc, 0xdc, 0xbc, 0xcd, 0x06, 0x6a, 0x11, 0x36, 0x54, 0xd9, 0x78, 0x1a, 0xf4, 0x2a, 0x37, 0x8d, 0xdb, 0xcd, 0x7d, 0x32, 0x90, 0x9b, 0x28,
0xcd, 0x7d, 0x30, 0x9e, 0x06, 0x87, 0x6b, 0x36, 0x49, 0xb0, 0xb7, 0x60, 0xe3, 0xe9, 0x6c, 0x11, 0xee, 0xc3, 0xf1, 0x34, 0x38, 0x5a, 0xb3, 0x51, 0x82, 0xbc, 0x05, 0x1b, 0x4f, 0x67, 0x8b, 0x78,
0x4f, 0x7b, 0xeb, 0x24, 0x7a, 0xb1, 0x28, 0xfa, 0x43, 0x64, 0x1d, 0xae, 0xd9, 0x4a, 0x06, 0xa7, 0xda, 0x5b, 0x47, 0xd1, 0x2b, 0x79, 0xd1, 0x1f, 0x0b, 0xd6, 0xd1, 0x9a, 0x2d, 0x65, 0xc4, 0xb2,
0xf5, 0xfc, 0xa7, 0x41, 0xaf, 0x5e, 0x35, 0xed, 0x91, 0xff, 0x94, 0xa6, 0x45, 0x09, 0xb6, 0x0f, 0x9e, 0xff, 0x34, 0xe8, 0x55, 0xcb, 0x96, 0x3d, 0xf6, 0x9f, 0xe2, 0xb2, 0x42, 0x82, 0x1c, 0x00,
0x10, 0x0b, 0xe9, 0x04, 0xa1, 0xf4, 0x02, 0xbf, 0xb7, 0x41, 0xf2, 0x57, 0x8b, 0xf2, 0x0f, 0x85, 0xc4, 0x8c, 0x3b, 0x41, 0xc8, 0xbd, 0xc0, 0xef, 0x6d, 0xa0, 0xfc, 0xf5, 0xbc, 0xfc, 0x23, 0xc6,
0xfc, 0x29, 0xb1, 0x0f, 0xd7, 0x6c, 0x33, 0x4e, 0x06, 0xa8, 0xe9, 0xf9, 0x9e, 0x74, 0xc6, 0x53, 0x7f, 0x8e, 0xec, 0xa3, 0x35, 0xdb, 0x8c, 0xf5, 0x44, 0x68, 0x7a, 0xbe, 0xc7, 0x9d, 0xf1, 0x94,
0xee, 0xf9, 0xbd, 0x46, 0x95, 0xe6, 0x91, 0xef, 0xc9, 0x7b, 0xc8, 0x46, 0x4d, 0x2f, 0x19, 0xe0, 0x7a, 0x7e, 0xaf, 0x56, 0xa6, 0x79, 0xec, 0x7b, 0xfc, 0xbe, 0x60, 0x0b, 0x4d, 0x4f, 0x4f, 0xc4,
0x51, 0x3e, 0x59, 0x88, 0xe8, 0xb4, 0xd7, 0xac, 0x3a, 0xca, 0xcf, 0x90, 0x85, 0x47, 0x21, 0x19, 0x55, 0x3e, 0x59, 0xb0, 0xe8, 0xbc, 0x57, 0x2f, 0xbb, 0xca, 0x2f, 0x04, 0x4b, 0x5c, 0x05, 0x65,
0x76, 0x17, 0x36, 0x47, 0x62, 0xe2, 0xf9, 0xce, 0x68, 0x16, 0x8c, 0x9f, 0xf5, 0x5a, 0xa4, 0xd2, 0xc8, 0x3d, 0x68, 0x8e, 0xd8, 0xc4, 0xf3, 0x9d, 0xd1, 0x2c, 0x18, 0x3f, 0xeb, 0x35, 0x50, 0xa5,
0x2b, 0xaa, 0x0c, 0x51, 0x60, 0x88, 0xfc, 0xc3, 0x35, 0x1b, 0x46, 0xe9, 0x88, 0xdd, 0x86, 0xd6, 0x97, 0x57, 0x19, 0x0a, 0x81, 0xa1, 0xe0, 0x1f, 0xad, 0xd9, 0x30, 0x4a, 0x66, 0x64, 0x1f, 0x1a,
0x78, 0x2a, 0xc6, 0xcf, 0x1c, 0xb9, 0xec, 0x99, 0xa4, 0x79, 0xb9, 0xa8, 0x79, 0x0f, 0xb9, 0x8f, 0xe3, 0x29, 0x1b, 0x3f, 0x73, 0xf8, 0xb2, 0x67, 0xa2, 0xe6, 0xd5, 0xbc, 0xe6, 0x7d, 0xc1, 0x7d,
0x96, 0x87, 0x6b, 0x76, 0x73, 0xac, 0x3e, 0xd9, 0x7b, 0x60, 0x0a, 0xdf, 0xd5, 0xcb, 0x6d, 0x92, 0xbc, 0x3c, 0x5a, 0xb3, 0xeb, 0x63, 0x39, 0x24, 0xef, 0x81, 0xc9, 0x7c, 0x57, 0x6d, 0xd7, 0x44,
0xd2, 0x95, 0xd2, 0xbd, 0xf8, 0x6e, 0xb2, 0x58, 0x4b, 0xe8, 0x6f, 0x36, 0x80, 0x06, 0x3a, 0x8a, 0xa5, 0x6b, 0x85, 0xef, 0xe2, 0xbb, 0x7a, 0xb3, 0x06, 0x53, 0x63, 0x32, 0x80, 0x9a, 0x70, 0x14,
0x27, 0x7b, 0x5b, 0xa4, 0x73, 0xa9, 0xb4, 0x10, 0xf1, 0x0e, 0xd7, 0x6c, 0x2d, 0x85, 0xe6, 0x73, 0x8f, 0xf7, 0x36, 0x51, 0x67, 0xab, 0xb0, 0x11, 0xf2, 0x8e, 0xd6, 0x6c, 0x25, 0x25, 0xcc, 0xe7,
0xc5, 0xcc, 0x3b, 0x11, 0x11, 0x6e, 0xee, 0x62, 0x95, 0xf9, 0xee, 0x2b, 0x3e, 0x6d, 0xcf, 0x74, 0xb2, 0x99, 0x77, 0xc6, 0x22, 0x71, 0xb8, 0x2b, 0x65, 0xe6, 0x7b, 0x20, 0xf9, 0x78, 0x3c, 0xd3,
0x93, 0xc1, 0xb0, 0x09, 0x1b, 0x27, 0x7c, 0xb6, 0x10, 0xd6, 0x9b, 0xb0, 0x99, 0xf3, 0x14, 0xd6, 0xd5, 0x93, 0x61, 0x1d, 0x36, 0xce, 0xe8, 0x6c, 0xc1, 0xac, 0x37, 0xa1, 0x99, 0xf1, 0x14, 0xd2,
0x83, 0xe6, 0x5c, 0xc4, 0x31, 0x9f, 0x88, 0x9e, 0x71, 0xc3, 0xb8, 0x69, 0xda, 0xc9, 0xd0, 0x6a, 0x83, 0xfa, 0x9c, 0xc5, 0x31, 0x9d, 0xb0, 0x9e, 0x71, 0xd3, 0xb8, 0x6d, 0xda, 0x7a, 0x6a, 0xb5,
0xc3, 0x56, 0xde, 0x4f, 0x72, 0x8a, 0xe8, 0x0b, 0xa8, 0x78, 0x22, 0xa2, 0x18, 0x1d, 0x40, 0x2b, 0x61, 0x33, 0xeb, 0x27, 0xd6, 0x3c, 0x51, 0x14, 0xbe, 0x20, 0x14, 0xcf, 0x58, 0x14, 0x0b, 0x07,
0xea, 0xa1, 0xf5, 0x3e, 0x74, 0xcb, 0x4e, 0xc0, 0xba, 0xb0, 0xfe, 0x4c, 0x9c, 0x6a, 0x49, 0xfc, 0x50, 0x8a, 0x6a, 0x4a, 0x6e, 0x41, 0x0b, 0xed, 0xe0, 0x68, 0xbe, 0xf0, 0xd3, 0xaa, 0xbd, 0x89,
0x64, 0x97, 0xf4, 0x86, 0xc8, 0x8b, 0x4d, 0x5b, 0xef, 0xee, 0x8b, 0x5a, 0xaa, 0x9c, 0xfa, 0x01, 0xc4, 0x53, 0x25, 0xb4, 0x03, 0xcd, 0x70, 0x3f, 0x4c, 0x44, 0xd6, 0x51, 0x04, 0xc2, 0xfd, 0x50,
0xdb, 0x87, 0x3a, 0x46, 0x21, 0x69, 0x6f, 0xde, 0xee, 0x0f, 0x54, 0x88, 0x0e, 0x92, 0x10, 0x1d, 0x09, 0x58, 0xef, 0x43, 0xb7, 0xe8, 0x4a, 0xa4, 0x0b, 0xeb, 0xcf, 0xd8, 0xb9, 0xda, 0x4f, 0x0c,
0x3c, 0x4a, 0x42, 0x74, 0xd8, 0xfa, 0xf2, 0xc5, 0xf5, 0xb5, 0x2f, 0xfe, 0x78, 0xdd, 0xb0, 0x49, 0xc9, 0x96, 0xba, 0x16, 0xee, 0x61, 0xda, 0xea, 0x8e, 0x5f, 0x54, 0x12, 0xe5, 0xc4, 0x9b, 0xc8,
0x83, 0x5d, 0xc3, 0xab, 0xe4, 0x9e, 0xef, 0x78, 0xae, 0x5e, 0xa7, 0x49, 0xe3, 0x23, 0x97, 0x1d, 0x01, 0x54, 0x45, 0x2c, 0xa3, 0x76, 0x73, 0xbf, 0x3f, 0x90, 0x81, 0x3e, 0xd0, 0x81, 0x3e, 0x78,
0x40, 0x77, 0x1c, 0xf8, 0xb1, 0xf0, 0xe3, 0x45, 0xec, 0x84, 0x3c, 0xe2, 0xf3, 0x58, 0x47, 0x49, 0xac, 0x03, 0x7d, 0xd8, 0xf8, 0xea, 0xc5, 0xce, 0xda, 0x17, 0x7f, 0xdc, 0x31, 0x6c, 0xd4, 0x20,
0x72, 0x71, 0xf7, 0x12, 0xf6, 0x31, 0x71, 0xed, 0xce, 0xb8, 0x48, 0x60, 0x1f, 0x00, 0x9c, 0xf0, 0x37, 0x84, 0x43, 0x50, 0xcf, 0x77, 0x3c, 0x57, 0xed, 0x53, 0xc7, 0xf9, 0xb1, 0x4b, 0x0e, 0xa1,
0x99, 0xe7, 0x72, 0x19, 0x44, 0x71, 0xaf, 0x7e, 0x63, 0x3d, 0xa7, 0xfc, 0x24, 0x61, 0x3c, 0x0e, 0x3b, 0x0e, 0xfc, 0x98, 0xf9, 0xf1, 0x22, 0x76, 0x42, 0x1a, 0xd1, 0x79, 0xac, 0x62, 0x4d, 0x7f,
0x5d, 0x2e, 0xc5, 0xb0, 0x8e, 0x3b, 0xb3, 0x73, 0xf2, 0xec, 0x0d, 0xe8, 0xf0, 0x30, 0x74, 0x62, 0xfe, 0xfb, 0x9a, 0x7d, 0x82, 0x5c, 0xbb, 0x33, 0xce, 0x13, 0xc8, 0x07, 0x00, 0x67, 0x74, 0xe6,
0xc9, 0xa5, 0x70, 0x46, 0xa7, 0x52, 0xc4, 0x14, 0x49, 0x5b, 0xf6, 0x36, 0x0f, 0xc3, 0x87, 0x48, 0xb9, 0x94, 0x07, 0x51, 0xdc, 0xab, 0xde, 0x5c, 0xcf, 0x28, 0x9f, 0x6a, 0xc6, 0x93, 0xd0, 0xa5,
0x1d, 0x22, 0xd1, 0x72, 0xd3, 0x7b, 0x20, 0x27, 0x67, 0x0c, 0xea, 0x2e, 0x97, 0x9c, 0xac, 0xb1, 0x9c, 0x0d, 0xab, 0xe2, 0x64, 0x76, 0x46, 0x9e, 0xbc, 0x01, 0x1d, 0x1a, 0x86, 0x4e, 0xcc, 0x29,
0x65, 0xd3, 0x37, 0xd2, 0x42, 0x2e, 0xa7, 0xfa, 0x8c, 0xf4, 0xcd, 0xae, 0x40, 0x63, 0x2a, 0xbc, 0x67, 0xce, 0xe8, 0x9c, 0xb3, 0x18, 0xe3, 0x71, 0xd3, 0x6e, 0xd1, 0x30, 0x7c, 0x24, 0xa8, 0x43,
0xc9, 0x54, 0xd2, 0xb1, 0xd6, 0x6d, 0x3d, 0x42, 0xc3, 0x87, 0x51, 0x70, 0x22, 0x28, 0xce, 0x5b, 0x41, 0xb4, 0xdc, 0xe4, 0x6b, 0x62, 0xa8, 0x10, 0x02, 0x55, 0x97, 0x72, 0x8a, 0xd6, 0xd8, 0xb4,
0xb6, 0x1a, 0x58, 0x7f, 0x35, 0xe0, 0xc2, 0xb9, 0xc0, 0xc0, 0x79, 0xa7, 0x3c, 0x9e, 0x26, 0x6b, 0x71, 0x2c, 0x68, 0x21, 0xe5, 0x53, 0x75, 0x47, 0x1c, 0x93, 0x6b, 0x50, 0x9b, 0x32, 0x6f, 0x32,
0xe1, 0x37, 0x7b, 0x0b, 0xe7, 0xe5, 0xae, 0x88, 0x74, 0xfe, 0xd9, 0xd6, 0x27, 0x3e, 0x24, 0xa2, 0xe5, 0x78, 0xad, 0x75, 0x5b, 0xcd, 0x84, 0xe1, 0xc3, 0x28, 0x38, 0x63, 0x98, 0x2d, 0x1a, 0xb6,
0x3e, 0xa8, 0x16, 0x61, 0x0f, 0xa0, 0x3b, 0xe3, 0xb1, 0x74, 0x94, 0xff, 0x3a, 0x94, 0x5f, 0xd6, 0x9c, 0x58, 0x7f, 0x35, 0xe0, 0xb5, 0x4b, 0xe1, 0x25, 0xd6, 0x9d, 0xd2, 0x78, 0xaa, 0xf7, 0x12,
0x0b, 0x31, 0xf5, 0x31, 0x4f, 0xfc, 0x1c, 0xdd, 0x4a, 0xab, 0xb7, 0x67, 0x05, 0x2a, 0x3b, 0x84, 0x63, 0xf2, 0x96, 0x58, 0x97, 0xba, 0x2c, 0x52, 0x59, 0xac, 0xa5, 0x6e, 0x7c, 0x84, 0x44, 0x75,
0x4b, 0xa3, 0xd3, 0xe7, 0xdc, 0x97, 0x9e, 0x2f, 0x9c, 0x73, 0x36, 0xef, 0xe8, 0xa9, 0x1e, 0x9c, 0x51, 0x25, 0x42, 0x1e, 0x42, 0x77, 0x46, 0x63, 0xee, 0xc8, 0x28, 0x70, 0x30, 0x4b, 0xad, 0xe7,
0x78, 0xae, 0xf0, 0xc7, 0x89, 0xb1, 0x2f, 0xa6, 0x2a, 0xe9, 0x65, 0xc4, 0xd6, 0x0d, 0x68, 0x17, 0x22, 0xf3, 0x63, 0xaa, 0xa3, 0x45, 0x38, 0xa7, 0x52, 0x6f, 0xcf, 0x72, 0x54, 0x72, 0x04, 0x5b,
0xa3, 0x98, 0xb5, 0xa1, 0x26, 0x97, 0xfa, 0x84, 0x35, 0xb9, 0xb4, 0xac, 0xd4, 0x03, 0xd3, 0x50, 0xa3, 0xf3, 0xe7, 0xd4, 0xe7, 0x9e, 0xcf, 0x9c, 0x4b, 0x36, 0xef, 0xa8, 0xa5, 0x1e, 0x9e, 0x79,
0x3a, 0x27, 0xb3, 0x0b, 0x9d, 0x52, 0x58, 0xe7, 0xcc, 0x6d, 0xe4, 0xcd, 0x6d, 0x75, 0x60, 0xbb, 0x2e, 0xf3, 0xc7, 0xda, 0xd8, 0x57, 0x12, 0x95, 0xe4, 0x63, 0xc4, 0xd6, 0x4d, 0x68, 0xe7, 0x73,
0x10, 0xcd, 0xd6, 0xe7, 0x1b, 0xd0, 0xb2, 0x45, 0x1c, 0xa2, 0x33, 0xb1, 0x7d, 0x30, 0xc5, 0x72, 0x01, 0x69, 0x43, 0x85, 0x2f, 0xd5, 0x0d, 0x2b, 0x7c, 0x69, 0x59, 0x89, 0x07, 0x26, 0x01, 0x79,
0x2c, 0x54, 0x22, 0x35, 0x4a, 0x69, 0x4a, 0xc9, 0x3c, 0x48, 0xf8, 0x18, 0xd0, 0xa9, 0x30, 0xdb, 0x49, 0x66, 0x17, 0x3a, 0x85, 0xe4, 0x90, 0x31, 0xb7, 0x91, 0x35, 0xb7, 0xd5, 0x81, 0x56, 0x2e,
0x2d, 0x80, 0xc0, 0xc5, 0xb2, 0x52, 0x1e, 0x05, 0x6e, 0x15, 0x51, 0xe0, 0x52, 0x49, 0xb6, 0x04, 0x27, 0x58, 0x9f, 0x6f, 0x40, 0xc3, 0x66, 0x71, 0x28, 0x9c, 0x89, 0x1c, 0x80, 0xc9, 0x96, 0x63,
0x03, 0xbb, 0x05, 0x18, 0x28, 0x4f, 0x5c, 0xc0, 0x81, 0x3b, 0x15, 0x38, 0x50, 0xde, 0xfe, 0x0a, 0x26, 0xd3, 0xb1, 0x51, 0x48, 0x76, 0x52, 0xe6, 0xa1, 0xe6, 0x8b, 0xb4, 0x90, 0x08, 0x93, 0xdd,
0x20, 0xb8, 0x53, 0x01, 0x04, 0xbd, 0x73, 0x6b, 0x55, 0x22, 0xc1, 0xad, 0x22, 0x12, 0x94, 0x8f, 0x1c, 0x94, 0x5c, 0x29, 0x2a, 0x65, 0xb1, 0xe4, 0x4e, 0x1e, 0x4b, 0xb6, 0x0a, 0xb2, 0x05, 0x30,
0x53, 0x82, 0x82, 0x0f, 0xaa, 0xa0, 0xe0, 0x5a, 0x49, 0x67, 0x25, 0x16, 0xbc, 0x7b, 0x0e, 0x0b, 0xd9, 0xcd, 0x81, 0x49, 0x71, 0xe1, 0x1c, 0x9a, 0xdc, 0x2d, 0x41, 0x93, 0xe2, 0xf1, 0x57, 0xc0,
0xae, 0x94, 0x54, 0x2b, 0xc0, 0xe0, 0x4e, 0x21, 0x4b, 0x43, 0xe5, 0xd9, 0xaa, 0xd3, 0x34, 0xfb, 0xc9, 0xdd, 0x12, 0x38, 0xe9, 0x5d, 0xda, 0xab, 0x14, 0x4f, 0xee, 0xe4, 0xf1, 0xa4, 0x78, 0x9d,
0xfe, 0x79, 0x1c, 0xb9, 0x5a, 0xbe, 0xda, 0x2a, 0x20, 0xd9, 0x2b, 0x01, 0xc9, 0xe5, 0xf2, 0x2e, 0x02, 0xa0, 0x7c, 0x50, 0x06, 0x28, 0x37, 0x0a, 0x3a, 0x2b, 0x11, 0xe5, 0xdd, 0x4b, 0x88, 0x72,
0x4b, 0x48, 0x92, 0xe1, 0xc1, 0x2e, 0xc6, 0x7d, 0xc9, 0xd3, 0x30, 0x47, 0x88, 0x28, 0x0a, 0x22, 0xad, 0xa0, 0x5a, 0x02, 0x29, 0x77, 0x73, 0xb9, 0x1e, 0x4a, 0xef, 0x56, 0x9e, 0xec, 0xc9, 0x0f,
0x9d, 0xb0, 0xd5, 0xc0, 0xba, 0x89, 0x99, 0x28, 0xf3, 0xaf, 0x97, 0x60, 0x07, 0x39, 0x7d, 0xce, 0x2f, 0xa3, 0xd1, 0xf5, 0xe2, 0xa7, 0x2d, 0x83, 0xa3, 0xbd, 0x02, 0x1c, 0x5d, 0x2d, 0x9e, 0xb2,
0xbb, 0xac, 0x5f, 0x19, 0x99, 0x2e, 0x45, 0x74, 0x3e, 0x8b, 0x99, 0x3a, 0x8b, 0xe5, 0x20, 0xa5, 0x80, 0x47, 0x29, 0xaa, 0xec, 0x8a, 0xb8, 0x2f, 0x78, 0x9a, 0xc8, 0x11, 0x2c, 0x8a, 0x82, 0x48,
0x56, 0x80, 0x14, 0xf6, 0x1d, 0xb8, 0x40, 0x69, 0x84, 0xec, 0xe2, 0x14, 0xd2, 0x5a, 0x07, 0x19, 0x25, 0x6c, 0x39, 0xb1, 0x6e, 0x8b, 0x4c, 0x94, 0xfa, 0xd7, 0x4b, 0x10, 0x08, 0x9d, 0x3e, 0xe3,
0xca, 0x20, 0x2a, 0xbf, 0xbd, 0x0d, 0x17, 0x73, 0xb2, 0x98, 0x62, 0x29, 0x85, 0xd5, 0x29, 0x78, 0x5d, 0xd6, 0x97, 0x46, 0xaa, 0x8b, 0x11, 0x9d, 0xcd, 0x62, 0xa6, 0xca, 0x62, 0x19, 0x60, 0xaa,
0xbb, 0xa9, 0xf4, 0x41, 0x18, 0x1e, 0xf2, 0x78, 0x6a, 0xfd, 0x38, 0x3b, 0x7f, 0x06, 0x57, 0x0c, 0xe4, 0x81, 0x69, 0x07, 0x9a, 0x22, 0x57, 0x16, 0x30, 0x87, 0x86, 0x1a, 0x73, 0xc8, 0xf7, 0xe0,
0xea, 0xe3, 0xc0, 0x55, 0xc7, 0xda, 0xb6, 0xe9, 0x1b, 0x21, 0x6c, 0x16, 0x4c, 0x68, 0x55, 0xd3, 0x35, 0xcc, 0x33, 0x12, 0xbe, 0x54, 0x20, 0x56, 0x31, 0x10, 0x3b, 0x82, 0x21, 0x2d, 0x26, 0x13,
0xc6, 0x4f, 0x94, 0x4a, 0x23, 0xc5, 0x54, 0x21, 0x61, 0xfd, 0xd2, 0xc8, 0xe6, 0xcb, 0x10, 0xac, 0xe0, 0xdb, 0x70, 0x25, 0x23, 0x2b, 0xd6, 0xc5, 0x1c, 0x27, 0x93, 0x6f, 0x37, 0x91, 0x3e, 0x0c,
0x0a, 0x6c, 0x8c, 0xff, 0x06, 0x6c, 0x6a, 0xaf, 0x06, 0x36, 0xd6, 0x99, 0x91, 0xdd, 0x48, 0x0a, 0xc3, 0x23, 0x1a, 0x4f, 0xad, 0x9f, 0xa6, 0x06, 0x4a, 0xf1, 0x8c, 0x40, 0x75, 0x1c, 0xb8, 0xf2,
0x23, 0x5f, 0xef, 0x88, 0xe8, 0x1c, 0x9e, 0xef, 0x8a, 0x25, 0x05, 0xfc, 0xba, 0xad, 0x06, 0x09, 0xde, 0x2d, 0x1b, 0xc7, 0x02, 0xe3, 0x66, 0xc1, 0x04, 0x0f, 0x67, 0xda, 0x62, 0x28, 0xa4, 0x92,
0xc2, 0x37, 0xc8, 0xcc, 0x45, 0x84, 0x6f, 0x12, 0x4d, 0x0d, 0xd8, 0xeb, 0x04, 0x3f, 0xc1, 0x53, 0x50, 0x32, 0x65, 0xcc, 0x58, 0xbf, 0x36, 0xd2, 0xf5, 0x52, 0x88, 0x2b, 0x43, 0x23, 0xe3, 0xbf,
0x1d, 0x89, 0xdb, 0x03, 0x5d, 0xe6, 0x1e, 0x23, 0xd1, 0x56, 0xbc, 0x5c, 0x32, 0x35, 0x0b, 0xd8, 0x41, 0xa3, 0xca, 0xab, 0xa1, 0x91, 0x75, 0x61, 0xa4, 0x9f, 0x2c, 0xc1, 0x99, 0x6f, 0x76, 0x45,
0xf5, 0x1a, 0x98, 0xb8, 0xd1, 0x38, 0xe4, 0x63, 0x41, 0x81, 0x65, 0xda, 0x19, 0xc1, 0x3a, 0x06, 0xe1, 0x3d, 0x9e, 0xef, 0xb2, 0x25, 0x9a, 0x74, 0xdd, 0x96, 0x13, 0x5d, 0x02, 0xd4, 0xd0, 0xcc,
0x76, 0x3e, 0xa0, 0xd9, 0xfb, 0x50, 0x97, 0x7c, 0x82, 0xf6, 0x46, 0x93, 0xb5, 0x07, 0xaa, 0x32, 0xf9, 0x12, 0xa0, 0x8e, 0x34, 0x39, 0x21, 0xb7, 0x10, 0x9f, 0x82, 0xa7, 0x2a, 0x54, 0x5b, 0x03,
0x1f, 0x7c, 0xf4, 0xe4, 0x98, 0x7b, 0xd1, 0xf0, 0x0a, 0x9a, 0xea, 0xef, 0x2f, 0xae, 0xb7, 0x51, 0x55, 0x4d, 0x9f, 0x08, 0xa2, 0x2d, 0x79, 0x99, 0x6c, 0x6b, 0xe6, 0xc0, 0xed, 0x75, 0x30, 0xc5,
0xe6, 0x56, 0x30, 0xf7, 0xa4, 0x98, 0x87, 0xf2, 0xd4, 0x26, 0x1d, 0xeb, 0x1f, 0x06, 0x26, 0xfa, 0x41, 0xe3, 0x90, 0x8e, 0x19, 0x46, 0x9e, 0x69, 0xa7, 0x04, 0xeb, 0x04, 0xc8, 0xe5, 0x88, 0x27,
0x42, 0xa0, 0x57, 0x1a, 0x2e, 0xf1, 0xe6, 0x5a, 0x0e, 0x93, 0xbf, 0x9a, 0x31, 0xbf, 0x09, 0x30, 0xef, 0x43, 0x95, 0xd3, 0x89, 0xb0, 0xb7, 0x30, 0x59, 0x7b, 0x20, 0x1b, 0x80, 0xc1, 0x47, 0xa7,
0xe1, 0xb1, 0xf3, 0x29, 0xf7, 0xa5, 0x70, 0xb5, 0x45, 0xcd, 0x09, 0x8f, 0x7f, 0x4e, 0x04, 0x2c, 0x27, 0xd4, 0x8b, 0x86, 0xd7, 0x84, 0xa9, 0xfe, 0xfe, 0x62, 0xa7, 0x2d, 0x64, 0xee, 0x04, 0x73,
0x60, 0x90, 0xbd, 0x88, 0x85, 0x4b, 0xa6, 0x5d, 0xb7, 0x9b, 0x13, 0x1e, 0x3f, 0x8e, 0x85, 0x9b, 0x8f, 0xb3, 0x79, 0xc8, 0xcf, 0x6d, 0xd4, 0xb1, 0xfe, 0x61, 0x08, 0x24, 0xc8, 0x65, 0x82, 0x52,
0x9e, 0xab, 0xf9, 0xea, 0xe7, 0x2a, 0xda, 0xb1, 0x55, 0xb6, 0xe3, 0x3f, 0x73, 0x3e, 0x9c, 0x61, 0xc3, 0x69, 0x77, 0xaf, 0x64, 0x40, 0xfb, 0xeb, 0x19, 0xf3, 0xdb, 0x00, 0x13, 0x1a, 0x3b, 0x9f,
0xe0, 0xff, 0xff, 0xb9, 0xff, 0x66, 0x20, 0xf4, 0x17, 0xb3, 0x2c, 0x3b, 0x82, 0x0b, 0x69, 0x1c, 0x52, 0x9f, 0x33, 0x57, 0x59, 0xd4, 0x9c, 0xd0, 0xf8, 0x97, 0x48, 0x10, 0x15, 0x8e, 0x60, 0x2f,
0x39, 0x0b, 0x8a, 0xaf, 0xc4, 0x97, 0x5e, 0x1e, 0x7e, 0xdd, 0x93, 0x22, 0x39, 0x66, 0x3f, 0x81, 0x62, 0xe6, 0xa2, 0x69, 0xd7, 0xed, 0xfa, 0x84, 0xc6, 0x4f, 0x62, 0xe6, 0x26, 0xf7, 0xaa, 0xbf,
0xab, 0xa5, 0x2c, 0x90, 0x4e, 0x58, 0x7b, 0x69, 0x32, 0xb8, 0x5c, 0x4c, 0x06, 0xc9, 0x7c, 0x89, 0xfa, 0xbd, 0xf2, 0x76, 0x6c, 0x14, 0xed, 0xf8, 0xcf, 0x8c, 0x0f, 0xa7, 0x20, 0xf9, 0xff, 0x7f,
0x25, 0xd6, 0xbf, 0x86, 0x67, 0x7f, 0x0b, 0xeb, 0xa0, 0x3c, 0x36, 0x54, 0xdd, 0xa5, 0xf5, 0x99, 0xef, 0xbf, 0x19, 0xa2, 0x36, 0xc8, 0xa7, 0x61, 0x72, 0x0c, 0xaf, 0x25, 0x71, 0xe4, 0x2c, 0x30,
0x01, 0x9d, 0xd2, 0x66, 0xd8, 0x1e, 0x80, 0x4a, 0xad, 0xb1, 0xf7, 0x3c, 0xa9, 0xc9, 0xbb, 0x7a, 0xbe, 0xb4, 0x2f, 0xbd, 0x3c, 0xfc, 0xba, 0x67, 0x79, 0x72, 0x4c, 0x7e, 0x06, 0xd7, 0x0b, 0x59,
0xe3, 0x64, 0xb2, 0x87, 0xde, 0x73, 0x61, 0x9b, 0xa3, 0xe4, 0x93, 0x7d, 0x08, 0x1d, 0xa1, 0x2b, 0x20, 0x59, 0xb0, 0xf2, 0xd2, 0x64, 0x70, 0x35, 0x9f, 0x0c, 0xf4, 0x7a, 0xda, 0x12, 0xeb, 0xdf,
0xb3, 0x24, 0xf7, 0xd5, 0x0a, 0x20, 0x95, 0xd4, 0x6d, 0xfa, 0xb4, 0x6d, 0x51, 0x18, 0x5b, 0x07, 0xc0, 0xb3, 0xbf, 0x23, 0x0a, 0xa5, 0x2c, 0x78, 0x94, 0x7d, 0x4b, 0xeb, 0x33, 0x03, 0x3a, 0x85,
0x60, 0xa6, 0xf3, 0xb2, 0x6f, 0x80, 0x39, 0xe7, 0x4b, 0x5d, 0x2f, 0xab, 0x4a, 0xab, 0x35, 0xe7, 0xc3, 0x90, 0x3d, 0x00, 0x99, 0x5a, 0x63, 0xef, 0xb9, 0x2e, 0xda, 0xbb, 0xea, 0xe0, 0x68, 0xb2,
0x4b, 0x2a, 0x95, 0xd9, 0x55, 0x68, 0x22, 0x73, 0xc2, 0xd5, 0x0a, 0xeb, 0x76, 0x63, 0xce, 0x97, 0x47, 0xde, 0x73, 0x66, 0x9b, 0x23, 0x3d, 0x24, 0x1f, 0x42, 0x87, 0xa9, 0xd2, 0x4d, 0xe7, 0xbe,
0x3f, 0xe2, 0xb1, 0xb5, 0x0b, 0xed, 0xe2, 0x22, 0x89, 0x68, 0x82, 0x5d, 0x4a, 0xf4, 0x60, 0x22, 0x4a, 0x0e, 0xc5, 0x74, 0x61, 0xa7, 0x6e, 0xdb, 0x66, 0xb9, 0xb9, 0x75, 0x08, 0x66, 0xb2, 0x2e,
0xac, 0x87, 0xd0, 0x2e, 0x96, 0xa4, 0x98, 0xc7, 0xa2, 0x60, 0xe1, 0xbb, 0x24, 0xb8, 0x61, 0xab, 0xf9, 0x16, 0x98, 0x73, 0xba, 0x54, 0x05, 0xb5, 0x2c, 0xc5, 0x1a, 0x73, 0xba, 0xc4, 0x5a, 0x9a,
0x01, 0xf6, 0xa3, 0x27, 0x81, 0xba, 0xba, 0x7c, 0x0d, 0xfa, 0x24, 0x90, 0x22, 0x57, 0xc8, 0x2a, 0x5c, 0x87, 0xba, 0x60, 0x4e, 0xa8, 0xdc, 0x61, 0xdd, 0xae, 0xcd, 0xe9, 0xf2, 0x27, 0x34, 0xb6,
0x19, 0xeb, 0xb3, 0x0d, 0x68, 0xa8, 0xfa, 0x98, 0x0d, 0x8a, 0x7d, 0x13, 0xde, 0x9b, 0xd6, 0x54, 0x76, 0xa1, 0x9d, 0xdf, 0x44, 0x8b, 0x6a, 0x70, 0x93, 0xa2, 0x87, 0x13, 0x66, 0x3d, 0x82, 0x76,
0x54, 0xad, 0x98, 0x42, 0xdf, 0x1b, 0xe5, 0x16, 0x66, 0xb8, 0x79, 0xf6, 0xe2, 0x7a, 0x93, 0x70, 0xbe, 0x66, 0x15, 0x79, 0x2c, 0x0a, 0x16, 0xbe, 0x8b, 0x82, 0x1b, 0xb6, 0x9c, 0x88, 0xb6, 0xf7,
0xe5, 0xe8, 0x7e, 0xd6, 0xcf, 0xac, 0x2a, 0xf7, 0x93, 0xe6, 0xa9, 0xfe, 0xca, 0xcd, 0xd3, 0x55, 0x2c, 0x90, 0x9f, 0x2e, 0x5b, 0xa4, 0x9e, 0x06, 0x9c, 0x65, 0x2a, 0x5d, 0x29, 0x63, 0x7d, 0xb6,
0x68, 0xfa, 0x8b, 0xb9, 0x23, 0x97, 0xb1, 0x8e, 0xcf, 0x86, 0xbf, 0x98, 0x3f, 0x5a, 0xc6, 0x78, 0x01, 0x35, 0x59, 0x40, 0x93, 0x41, 0xbe, 0x3d, 0x13, 0xdf, 0x4d, 0x69, 0x4a, 0xaa, 0x52, 0x4c,
0x07, 0x32, 0x90, 0x7c, 0x46, 0x2c, 0x15, 0x9d, 0x2d, 0x22, 0x20, 0x73, 0x1f, 0xb6, 0x73, 0xf0, 0xb0, 0xf1, 0x8d, 0x62, 0x8f, 0x33, 0x6c, 0x5e, 0xbc, 0xd8, 0xa9, 0x23, 0xae, 0x1c, 0x3f, 0x48,
0xeb, 0xb9, 0xba, 0x4a, 0x6b, 0xe7, 0x3d, 0xe4, 0xe8, 0xbe, 0x3e, 0xe5, 0x66, 0x0a, 0xc7, 0x47, 0x1b, 0x9e, 0x55, 0xfd, 0x80, 0xee, 0xae, 0xaa, 0xaf, 0xdc, 0x5d, 0x5d, 0x87, 0xba, 0xbf, 0x98,
0x2e, 0xbb, 0x59, 0xec, 0x15, 0x08, 0xb5, 0x5b, 0xe4, 0x8c, 0xb9, 0x76, 0x00, 0x31, 0x1b, 0x37, 0x3b, 0x7c, 0x19, 0xab, 0xf8, 0xac, 0xf9, 0x8b, 0xf9, 0xe3, 0x65, 0x2c, 0xbe, 0x01, 0x0f, 0x38,
0x80, 0xee, 0xa9, 0x44, 0x4c, 0x12, 0x69, 0x21, 0x81, 0x98, 0x6f, 0x42, 0x27, 0x03, 0x3e, 0x25, 0x9d, 0x21, 0x4b, 0x46, 0x67, 0x03, 0x09, 0x82, 0x79, 0x00, 0xad, 0x0c, 0xfc, 0x7a, 0xae, 0x2a,
0x02, 0x6a, 0x96, 0x8c, 0x4c, 0x82, 0xef, 0xc0, 0x25, 0x5f, 0x2c, 0xa5, 0x53, 0x96, 0xde, 0x24, 0xe3, 0xda, 0x59, 0x0f, 0x39, 0x7e, 0xa0, 0x6e, 0xd9, 0x4c, 0xe0, 0xf8, 0xd8, 0x25, 0xb7, 0xf3,
0x69, 0x86, 0xbc, 0x27, 0x45, 0x8d, 0x6f, 0x43, 0x3b, 0x0b, 0x60, 0x92, 0xdd, 0x52, 0x1d, 0x5b, 0xcd, 0x04, 0xa2, 0x76, 0x03, 0x9d, 0x31, 0xd3, 0x2f, 0x08, 0xcc, 0x16, 0x07, 0x10, 0xee, 0x29,
0x4a, 0x25, 0xb1, 0x6b, 0xd0, 0x4a, 0xcb, 0x8e, 0x6d, 0x12, 0x68, 0x72, 0x55, 0x6d, 0xa4, 0x85, 0x45, 0x4c, 0x14, 0x69, 0x08, 0x02, 0x32, 0xdf, 0x84, 0x4e, 0x0a, 0x7c, 0x52, 0x04, 0xe4, 0x2a,
0x4c, 0x24, 0xe2, 0xc5, 0x4c, 0xea, 0x49, 0xda, 0x24, 0x43, 0x85, 0x8c, 0xad, 0xe8, 0x24, 0xfb, 0x29, 0x19, 0x05, 0xdf, 0x81, 0x2d, 0x9f, 0x2d, 0xb9, 0x53, 0x94, 0x6e, 0xa2, 0x34, 0x11, 0xbc,
0x3a, 0x6c, 0xa7, 0x71, 0x43, 0x72, 0x1d, 0x92, 0xdb, 0x4a, 0x88, 0x24, 0xb4, 0x0b, 0xdd, 0x30, 0xd3, 0xbc, 0xc6, 0x77, 0xa1, 0x9d, 0x06, 0x30, 0xca, 0x6e, 0xca, 0x96, 0x2e, 0xa1, 0xa2, 0xd8,
0x0a, 0xc2, 0x20, 0x16, 0x91, 0xc3, 0x5d, 0x37, 0x12, 0x71, 0xdc, 0xeb, 0xaa, 0xf9, 0x12, 0xfa, 0x0d, 0x68, 0x24, 0x65, 0x47, 0x0b, 0x05, 0xea, 0x54, 0x56, 0x1b, 0x49, 0x21, 0x13, 0xb1, 0x78,
0x81, 0x22, 0x5b, 0xdf, 0x85, 0xa6, 0xf6, 0x31, 0x74, 0x69, 0xb2, 0x3a, 0xb9, 0x60, 0xdd, 0x56, 0x31, 0xe3, 0x6a, 0x91, 0x36, 0xca, 0x60, 0x21, 0x63, 0x4b, 0x3a, 0xca, 0xde, 0x82, 0x56, 0x12,
0x03, 0xcc, 0xdc, 0x07, 0x61, 0x48, 0x5e, 0x56, 0xb7, 0xf1, 0xd3, 0xfa, 0x05, 0x34, 0xf5, 0x85, 0x37, 0x28, 0xd7, 0x41, 0xb9, 0x4d, 0x4d, 0x44, 0xa1, 0x5d, 0xe8, 0x86, 0x51, 0x10, 0x06, 0x31,
0x55, 0xb6, 0x82, 0x3f, 0x80, 0xad, 0x90, 0x47, 0x78, 0x8c, 0x7c, 0x43, 0x98, 0x14, 0xe4, 0xc7, 0x8b, 0x1c, 0xea, 0xba, 0x11, 0x8b, 0xe3, 0x5e, 0x57, 0xae, 0xa7, 0xe9, 0x87, 0x92, 0x6c, 0x7d,
0x3c, 0x92, 0x0f, 0x85, 0x2c, 0xf4, 0x85, 0x9b, 0x24, 0xaf, 0x48, 0xd6, 0x1d, 0xd8, 0x2e, 0xc8, 0x1f, 0xea, 0xba, 0x9e, 0xda, 0x82, 0x0d, 0xb4, 0x3a, 0xba, 0x60, 0xd5, 0x96, 0x13, 0x91, 0xb9,
0xe0, 0xb6, 0xc8, 0x8f, 0x92, 0x48, 0xa3, 0x41, 0xba, 0x72, 0x2d, 0x5b, 0xd9, 0xba, 0x0b, 0x66, 0x0f, 0xc3, 0x50, 0xbd, 0x0a, 0x88, 0xa1, 0xf5, 0x2b, 0xa8, 0xab, 0x0f, 0x56, 0xda, 0x2b, 0xfe,
0x7a, 0x37, 0x58, 0x37, 0x26, 0x47, 0x37, 0xb4, 0xb9, 0xd5, 0x90, 0x7a, 0xdd, 0xe0, 0x53, 0x11, 0x08, 0x36, 0x43, 0x1a, 0x89, 0x6b, 0x64, 0x3b, 0x46, 0x5d, 0xb1, 0x9f, 0xd0, 0x88, 0x3f, 0x62,
0xe9, 0x98, 0x50, 0x03, 0xeb, 0x31, 0x74, 0x4a, 0x29, 0x9b, 0xdd, 0x82, 0x66, 0xb8, 0x18, 0x39, 0x3c, 0xd7, 0x38, 0x36, 0x51, 0x5e, 0x92, 0xac, 0xbb, 0xd0, 0xca, 0xc9, 0x88, 0x63, 0xa1, 0x1f,
0xc9, 0x1b, 0x45, 0xd6, 0xd5, 0x1e, 0x2f, 0x46, 0x1f, 0x89, 0xd3, 0xa4, 0xab, 0x0d, 0x69, 0x94, 0xe9, 0x48, 0xc3, 0x49, 0xb2, 0x73, 0x25, 0xdd, 0xd9, 0xba, 0x07, 0x66, 0xf2, 0x6d, 0x44, 0x61,
0x4d, 0x5b, 0xcb, 0x4f, 0x3b, 0x83, 0x56, 0x12, 0xfd, 0xec, 0x7b, 0x60, 0xa6, 0x6e, 0x55, 0xca, 0xa9, 0xaf, 0x6e, 0x28, 0x73, 0xcb, 0x29, 0x36, 0xc3, 0xc1, 0xa7, 0x2c, 0x52, 0x31, 0x21, 0x27,
0x91, 0xe9, 0xd2, 0x7a, 0xd2, 0x4c, 0x10, 0xbd, 0x23, 0xf6, 0x26, 0xbe, 0x70, 0x9d, 0x2c, 0x84, 0xd6, 0x13, 0xe8, 0x14, 0x52, 0x36, 0xb9, 0x03, 0xf5, 0x70, 0x31, 0x72, 0xf4, 0x23, 0x46, 0xda,
0x68, 0x8d, 0x96, 0xdd, 0x51, 0x8c, 0x8f, 0x93, 0x78, 0xb1, 0xde, 0x81, 0x86, 0xda, 0x1b, 0xda, 0xf6, 0x9e, 0x2c, 0x46, 0x1f, 0xb1, 0x73, 0xdd, 0xf6, 0x86, 0x38, 0x4b, 0x97, 0xad, 0x64, 0x97,
0x07, 0x67, 0x4e, 0x4a, 0x69, 0xfc, 0xae, 0x4c, 0xe6, 0x7f, 0x30, 0xa0, 0x95, 0x64, 0xc1, 0x4a, 0x9d, 0x41, 0x43, 0x47, 0x3f, 0xf9, 0x01, 0x98, 0x89, 0x5b, 0x15, 0x72, 0x64, 0xb2, 0xb5, 0x5a,
0xa5, 0xc2, 0xa6, 0x6b, 0x5f, 0x75, 0xd3, 0xff, 0xfb, 0xc4, 0x73, 0x0b, 0x98, 0xca, 0x2f, 0x27, 0x34, 0x15, 0x14, 0xde, 0x11, 0x7b, 0x13, 0x9f, 0xb9, 0x4e, 0x1a, 0x42, 0xb8, 0x47, 0xc3, 0xee,
0x81, 0xf4, 0xfc, 0x89, 0xa3, 0x6c, 0xad, 0x72, 0x50, 0x97, 0x38, 0x4f, 0x88, 0x71, 0x8c, 0xf4, 0x48, 0xc6, 0xc7, 0x3a, 0x5e, 0xac, 0x77, 0xa0, 0x26, 0xcf, 0x26, 0xec, 0x23, 0x56, 0xd6, 0xb5,
0xdb, 0x9f, 0x6f, 0x40, 0xe7, 0x60, 0x78, 0xef, 0xe8, 0x20, 0x0c, 0x67, 0xde, 0x98, 0x53, 0xfd, 0xb6, 0x18, 0x97, 0x26, 0xf3, 0x3f, 0x18, 0xd0, 0xd0, 0x59, 0xb0, 0x54, 0x29, 0x77, 0xe8, 0xca,
0xbe, 0x07, 0x75, 0xea, 0x50, 0x2a, 0xde, 0x46, 0xfb, 0x55, 0xad, 0x32, 0xbb, 0x0d, 0x1b, 0xd4, 0xd7, 0x3d, 0xf4, 0xff, 0x3e, 0xf1, 0xdc, 0x01, 0x22, 0xf3, 0xcb, 0x59, 0xc0, 0x3d, 0x7f, 0xe2,
0xa8, 0xb0, 0xaa, 0x27, 0xd2, 0x7e, 0x65, 0xc7, 0x8c, 0x8b, 0xa8, 0x56, 0xe6, 0xfc, 0x4b, 0x69, 0x48, 0x5b, 0xcb, 0x1c, 0xd4, 0x45, 0xce, 0x29, 0x32, 0x4e, 0x04, 0x7d, 0xff, 0xf3, 0x0d, 0xe8,
0xbf, 0xaa, 0x6d, 0x66, 0x1f, 0x82, 0x99, 0xb5, 0x18, 0xab, 0xde, 0x4b, 0xfb, 0x2b, 0x1b, 0x68, 0x1c, 0x0e, 0xef, 0x1f, 0x1f, 0x86, 0xe1, 0xcc, 0x1b, 0x53, 0xac, 0xdf, 0xf7, 0xa0, 0x8a, 0x2d,
0xd4, 0xcf, 0xca, 0xb1, 0x55, 0xcf, 0x7e, 0xfd, 0x95, 0x9d, 0x26, 0xdb, 0x87, 0x66, 0x52, 0xc4, 0x4c, 0xc9, 0x13, 0x6c, 0xbf, 0xac, 0x97, 0x26, 0xfb, 0xb0, 0x81, 0x9d, 0x0c, 0x29, 0x7b, 0x89,
0x56, 0xbf, 0x68, 0xf6, 0x57, 0x34, 0xb7, 0x68, 0x1e, 0xd5, 0x35, 0x54, 0x3d, 0xbb, 0xf6, 0x2b, 0xed, 0x97, 0xb6, 0xd4, 0x62, 0x13, 0xd9, 0xeb, 0x5c, 0x7e, 0x90, 0xed, 0x97, 0xf5, 0xd5, 0xe4,
0x3b, 0x70, 0xf6, 0x1e, 0x34, 0x74, 0x65, 0x51, 0xf9, 0xaa, 0xd9, 0xaf, 0x6e, 0x51, 0xf1, 0x90, 0x43, 0x30, 0xd3, 0x16, 0x63, 0xd5, 0xb3, 0x6c, 0x7f, 0x65, 0x87, 0x2d, 0xf4, 0xd3, 0x72, 0x6c,
0x59, 0xdf, 0xb4, 0xea, 0x69, 0xb8, 0xbf, 0xf2, 0xa9, 0x80, 0x1d, 0x00, 0xe4, 0x8a, 0xff, 0x95, 0xd5, 0xeb, 0x62, 0x7f, 0x65, 0x2b, 0x4a, 0x0e, 0xa0, 0xae, 0x8b, 0xd8, 0xf2, 0x87, 0xd3, 0xfe,
0x6f, 0xbe, 0xfd, 0xd5, 0x4f, 0x00, 0xec, 0x2e, 0xb4, 0xb2, 0x67, 0x9d, 0xea, 0x57, 0xdc, 0xfe, 0x8a, 0xee, 0x57, 0x98, 0x47, 0x76, 0x0d, 0x65, 0xaf, 0xbb, 0xfd, 0xd2, 0x16, 0x9d, 0xbc, 0x07,
0xaa, 0xae, 0x7c, 0xf8, 0xda, 0xbf, 0xfe, 0xbc, 0x63, 0xfc, 0xfa, 0x6c, 0xc7, 0xf8, 0xcd, 0xd9, 0x35, 0x55, 0x59, 0x94, 0x3e, 0x9e, 0xf6, 0xcb, 0x7b, 0x58, 0x71, 0xc9, 0xb4, 0x6f, 0x5a, 0xf5,
0x8e, 0xf1, 0xe5, 0xd9, 0x8e, 0xf1, 0xfb, 0xb3, 0x1d, 0xe3, 0x4f, 0x67, 0x3b, 0xc6, 0x6f, 0xff, 0x02, 0xdd, 0x5f, 0xf9, 0x96, 0x40, 0x0e, 0x01, 0x32, 0xc5, 0xff, 0xca, 0xa7, 0xe5, 0xfe, 0xea,
0xb2, 0x63, 0x8c, 0x1a, 0xe4, 0xfe, 0xef, 0xfe, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xf4, 0x43, 0x2c, 0x37, 0x02, 0x72, 0x0f, 0x1a, 0xe9, 0xbb, 0x4f, 0xf9, 0x63, 0x71, 0x7f, 0x55, 0xdb, 0x3e, 0x7c,
0xa9, 0xb5, 0x18, 0x00, 0x00, 0xfd, 0x5f, 0x7f, 0xde, 0x36, 0x7e, 0x73, 0xb1, 0x6d, 0x7c, 0x79, 0xb1, 0x6d, 0x7c, 0x75, 0xb1,
0x6d, 0xfc, 0xfe, 0x62, 0xdb, 0xf8, 0xd3, 0xc5, 0xb6, 0xf1, 0xdb, 0xbf, 0x6c, 0x1b, 0xa3, 0x1a,
0xba, 0xff, 0xbb, 0xff, 0x0e, 0x00, 0x00, 0xff, 0xff, 0x1a, 0x7c, 0xbd, 0x95, 0x1c, 0x19, 0x00,
0x00,
} }

View File

@ -49,6 +49,8 @@ message RequestFlush {
message RequestInfo { message RequestInfo {
string version = 1; string version = 1;
uint64 block_version = 2;
uint64 p2p_version = 3;
} }
// nondeterministic // nondeterministic
@ -129,9 +131,12 @@ message ResponseFlush {
message ResponseInfo { message ResponseInfo {
string data = 1; string data = 1;
string version = 2; string version = 2;
int64 last_block_height = 3; uint64 app_version = 3;
bytes last_block_app_hash = 4;
int64 last_block_height = 4;
bytes last_block_app_hash = 5;
} }
// nondeterministic // nondeterministic

View File

@ -11,6 +11,7 @@ import (
"time" "time"
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/version"
//auto "github.com/tendermint/tendermint/libs/autofile" //auto "github.com/tendermint/tendermint/libs/autofile"
cmn "github.com/tendermint/tendermint/libs/common" cmn "github.com/tendermint/tendermint/libs/common"
dbm "github.com/tendermint/tendermint/libs/db" dbm "github.com/tendermint/tendermint/libs/db"
@ -19,7 +20,6 @@ import (
"github.com/tendermint/tendermint/proxy" "github.com/tendermint/tendermint/proxy"
sm "github.com/tendermint/tendermint/state" sm "github.com/tendermint/tendermint/state"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
"github.com/tendermint/tendermint/version"
) )
var crc32c = crc32.MakeTable(crc32.Castagnoli) var crc32c = crc32.MakeTable(crc32.Castagnoli)
@ -227,7 +227,7 @@ func (h *Handshaker) NBlocks() int {
func (h *Handshaker) Handshake(proxyApp proxy.AppConns) error { func (h *Handshaker) Handshake(proxyApp proxy.AppConns) error {
// Handshake is done via ABCI Info on the query conn. // Handshake is done via ABCI Info on the query conn.
res, err := proxyApp.Query().InfoSync(abci.RequestInfo{Version: version.Version}) res, err := proxyApp.Query().InfoSync(proxy.RequestInfo)
if err != nil { if err != nil {
return fmt.Errorf("Error calling Info: %v", err) return fmt.Errorf("Error calling Info: %v", err)
} }
@ -238,9 +238,15 @@ func (h *Handshaker) Handshake(proxyApp proxy.AppConns) error {
} }
appHash := res.LastBlockAppHash appHash := res.LastBlockAppHash
h.logger.Info("ABCI Handshake", "appHeight", blockHeight, "appHash", fmt.Sprintf("%X", appHash)) h.logger.Info("ABCI Handshake App Info",
"height", blockHeight,
"hash", fmt.Sprintf("%X", appHash),
"software-version", res.Version,
"protocol-version", res.AppVersion,
)
// TODO: check app version. // Set AppVersion on the state.
h.initialState.Version.Consensus.App = version.Protocol(res.AppVersion)
// Replay blocks up to the latest in the blockstore. // Replay blocks up to the latest in the blockstore.
_, err = h.ReplayBlocks(h.initialState, appHash, blockHeight, proxyApp) _, err = h.ReplayBlocks(h.initialState, appHash, blockHeight, proxyApp)

View File

@ -20,6 +20,7 @@ import (
crypto "github.com/tendermint/tendermint/crypto" crypto "github.com/tendermint/tendermint/crypto"
auto "github.com/tendermint/tendermint/libs/autofile" auto "github.com/tendermint/tendermint/libs/autofile"
dbm "github.com/tendermint/tendermint/libs/db" dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/version"
cfg "github.com/tendermint/tendermint/config" cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/log"
@ -337,7 +338,7 @@ func testHandshakeReplay(t *testing.T, nBlocks int, mode uint) {
t.Fatalf(err.Error()) t.Fatalf(err.Error())
} }
stateDB, state, store := stateAndStore(config, privVal.GetPubKey()) stateDB, state, store := stateAndStore(config, privVal.GetPubKey(), kvstore.ProtocolVersion)
store.chain = chain store.chain = chain
store.commits = commits store.commits = commits
@ -352,7 +353,7 @@ func testHandshakeReplay(t *testing.T, nBlocks int, mode uint) {
// run nBlocks against a new client to build up the app state. // run nBlocks against a new client to build up the app state.
// use a throwaway tendermint state // use a throwaway tendermint state
proxyApp := proxy.NewAppConns(clientCreator2) proxyApp := proxy.NewAppConns(clientCreator2)
stateDB, state, _ := stateAndStore(config, privVal.GetPubKey()) stateDB, state, _ := stateAndStore(config, privVal.GetPubKey(), kvstore.ProtocolVersion)
buildAppStateFromChain(proxyApp, stateDB, state, chain, nBlocks, mode) buildAppStateFromChain(proxyApp, stateDB, state, chain, nBlocks, mode)
} }
@ -442,7 +443,7 @@ func buildAppStateFromChain(proxyApp proxy.AppConns, stateDB dbm.DB,
func buildTMStateFromChain(config *cfg.Config, stateDB dbm.DB, state sm.State, chain []*types.Block, mode uint) sm.State { func buildTMStateFromChain(config *cfg.Config, stateDB dbm.DB, state sm.State, chain []*types.Block, mode uint) sm.State {
// run the whole chain against this client to build up the tendermint state // run the whole chain against this client to build up the tendermint state
clientCreator := proxy.NewLocalClientCreator(kvstore.NewPersistentKVStoreApplication(path.Join(config.DBDir(), "1"))) clientCreator := proxy.NewLocalClientCreator(kvstore.NewPersistentKVStoreApplication(path.Join(config.DBDir(), "1")))
proxyApp := proxy.NewAppConns(clientCreator) // sm.NewHandshaker(config, state, store, ReplayLastBlock)) proxyApp := proxy.NewAppConns(clientCreator)
if err := proxyApp.Start(); err != nil { if err := proxyApp.Start(); err != nil {
panic(err) panic(err)
} }
@ -588,9 +589,10 @@ func readPieceFromWAL(msg *TimedWALMessage) interface{} {
} }
// fresh state and mock store // fresh state and mock store
func stateAndStore(config *cfg.Config, pubKey crypto.PubKey) (dbm.DB, sm.State, *mockBlockStore) { func stateAndStore(config *cfg.Config, pubKey crypto.PubKey, appVersion version.Protocol) (dbm.DB, sm.State, *mockBlockStore) {
stateDB := dbm.NewMemDB() stateDB := dbm.NewMemDB()
state, _ := sm.MakeGenesisStateFromFile(config.GenesisFile()) state, _ := sm.MakeGenesisStateFromFile(config.GenesisFile())
state.Version.Consensus.App = appVersion
store := NewMockBlockStore(config, state.ConsensusParams) store := NewMockBlockStore(config, state.ConsensusParams)
return stateDB, state, store return stateDB, state, store
} }
@ -639,7 +641,7 @@ func TestInitChainUpdateValidators(t *testing.T) {
config := ResetConfig("proxy_test_") config := ResetConfig("proxy_test_")
privVal := privval.LoadFilePV(config.PrivValidatorFile()) privVal := privval.LoadFilePV(config.PrivValidatorFile())
stateDB, state, store := stateAndStore(config, privVal.GetPubKey()) stateDB, state, store := stateAndStore(config, privVal.GetPubKey(), 0x0)
oldValAddr := state.Validators.Validators[0].Address oldValAddr := state.Validators.Validators[0].Address

View File

@ -38,7 +38,8 @@ func WALGenerateNBlocks(wr io.Writer, numBlocks int) (err error) {
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// COPY PASTE FROM node.go WITH A FEW MODIFICATIONS // COPY PASTE FROM node.go WITH A FEW MODIFICATIONS
// NOTE: we can't import node package because of circular dependency // NOTE: we can't import node package because of circular dependency.
// NOTE: we don't do handshake so need to set state.Version.Consensus.App directly.
privValidatorFile := config.PrivValidatorFile() privValidatorFile := config.PrivValidatorFile()
privValidator := privval.LoadOrGenFilePV(privValidatorFile) privValidator := privval.LoadOrGenFilePV(privValidatorFile)
genDoc, err := types.GenesisDocFromFile(config.GenesisFile()) genDoc, err := types.GenesisDocFromFile(config.GenesisFile())
@ -51,6 +52,7 @@ func WALGenerateNBlocks(wr io.Writer, numBlocks int) (err error) {
if err != nil { if err != nil {
return errors.Wrap(err, "failed to make genesis state") return errors.Wrap(err, "failed to make genesis state")
} }
state.Version.Consensus.App = kvstore.ProtocolVersion
blockStore := bc.NewBlockStore(blockStoreDB) blockStore := bc.NewBlockStore(blockStoreDB)
proxyApp := proxy.NewAppConns(proxy.NewLocalClientCreator(app)) proxyApp := proxy.NewAppConns(proxy.NewLocalClientCreator(app))
proxyApp.SetLogger(logger.With("module", "proxy")) proxyApp.SetLogger(logger.With("module", "proxy"))

View File

@ -134,10 +134,13 @@ Commit are included in the header of the next block.
### Info ### Info
- **Request**: - **Request**:
- `Version (string)`: The Tendermint version - `Version (string)`: The Tendermint software semantic version
- `BlockVersion (uint64)`: The Tendermint Block Protocol version
- `P2PVersion (uint64)`: The Tendermint P2P Protocol version
- **Response**: - **Response**:
- `Data (string)`: Some arbitrary information - `Data (string)`: Some arbitrary information
- `Version (Version)`: Version information - `Version (string)`: The application software semantic version
- `AppVersion (uint64)`: The application protocol version
- `LastBlockHeight (int64)`: Latest block for which the app has - `LastBlockHeight (int64)`: Latest block for which the app has
called Commit called Commit
- `LastBlockAppHash ([]byte)`: Latest result of Commit - `LastBlockAppHash ([]byte)`: Latest result of Commit
@ -145,6 +148,7 @@ Commit are included in the header of the next block.
- Return information about the application state. - Return information about the application state.
- Used to sync Tendermint with the application during a handshake - Used to sync Tendermint with the application during a handshake
that happens on startup. that happens on startup.
- The returned `AppVersion` will be included in the Header of every block.
- Tendermint expects `LastBlockAppHash` and `LastBlockHeight` to - Tendermint expects `LastBlockAppHash` and `LastBlockHeight` to
be updated during `Commit`, ensuring that `Commit` is never be updated during `Commit`, ensuring that `Commit` is never
called twice for the same block height. called twice for the same block height.

View File

@ -195,8 +195,8 @@ func NewNode(config *cfg.Config,
return nil, fmt.Errorf("Error starting proxy app connections: %v", err) return nil, fmt.Errorf("Error starting proxy app connections: %v", err)
} }
// Create the handshaker, which calls RequestInfo and replays any blocks // Create the handshaker, which calls RequestInfo, sets the AppVersion on the state,
// as necessary to sync tendermint with the app. // and replays any blocks as necessary to sync tendermint with the app.
consensusLogger := logger.With("module", "consensus") consensusLogger := logger.With("module", "consensus")
handshaker := cs.NewHandshaker(stateDB, state, blockStore, genDoc) handshaker := cs.NewHandshaker(stateDB, state, blockStore, genDoc)
handshaker.SetLogger(consensusLogger) handshaker.SetLogger(consensusLogger)
@ -204,9 +204,12 @@ func NewNode(config *cfg.Config,
return nil, fmt.Errorf("Error during handshake: %v", err) return nil, fmt.Errorf("Error during handshake: %v", err)
} }
// reload the state (it may have been updated by the handshake) // Reload the state. It will have the Version.Consensus.App set by the
// Handshake, and may have other modifications as well (ie. depending on
// what happened during block replay).
state = sm.LoadState(stateDB) state = sm.LoadState(stateDB)
// Ensure the state's block version matches that of the software.
if state.Version.Consensus.Block != version.BlockProtocol { if state.Version.Consensus.Block != version.BlockProtocol {
return nil, fmt.Errorf( return nil, fmt.Errorf(
"Block version of the software does not match that of the state.\n"+ "Block version of the software does not match that of the state.\n"+
@ -359,7 +362,13 @@ func NewNode(config *cfg.Config,
var ( var (
p2pLogger = logger.With("module", "p2p") p2pLogger = logger.With("module", "p2p")
nodeInfo = makeNodeInfo(config, nodeKey.ID(), txIndexer, genDoc.ChainID) nodeInfo = makeNodeInfo(
config,
nodeKey.ID(),
txIndexer,
genDoc.ChainID,
p2p.ProtocolVersionWithApp(state.Version.Consensus.App),
)
) )
// Setup Transport. // Setup Transport.
@ -764,13 +773,14 @@ func makeNodeInfo(
nodeID p2p.ID, nodeID p2p.ID,
txIndexer txindex.TxIndexer, txIndexer txindex.TxIndexer,
chainID string, chainID string,
protocolVersion p2p.ProtocolVersion,
) p2p.NodeInfo { ) p2p.NodeInfo {
txIndexerStatus := "on" txIndexerStatus := "on"
if _, ok := txIndexer.(*null.TxIndex); ok { if _, ok := txIndexer.(*null.TxIndex); ok {
txIndexerStatus = "off" txIndexerStatus = "off"
} }
nodeInfo := p2p.DefaultNodeInfo{ nodeInfo := p2p.DefaultNodeInfo{
ProtocolVersion: p2p.InitProtocolVersion, ProtocolVersion: protocolVersion,
ID_: nodeID, ID_: nodeID,
Network: chainID, Network: chainID,
Version: version.TMCoreSemVer, Version: version.TMCoreSemVer,

View File

@ -10,7 +10,11 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/tendermint/tendermint/abci/example/kvstore"
"github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/p2p"
sm "github.com/tendermint/tendermint/state"
"github.com/tendermint/tendermint/version"
cfg "github.com/tendermint/tendermint/config" cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
@ -91,3 +95,21 @@ func TestNodeDelayedStop(t *testing.T) {
startTime := tmtime.Now() startTime := tmtime.Now()
assert.Equal(t, true, startTime.After(n.GenesisDoc().GenesisTime)) assert.Equal(t, true, startTime.After(n.GenesisDoc().GenesisTime))
} }
func TestNodeSetAppVersion(t *testing.T) {
config := cfg.ResetTestRoot("node_app_version_test")
// create & start node
n, err := DefaultNewNode(config, log.TestingLogger())
assert.NoError(t, err, "expected no err on DefaultNewNode")
// default config uses the kvstore app
var appVersion version.Protocol = kvstore.ProtocolVersion
// check version is set in state
state := sm.LoadState(n.stateDB)
assert.Equal(t, state.Version.Consensus.App, appVersion)
// check version is set in node info
assert.Equal(t, n.nodeInfo.(p2p.DefaultNodeInfo).ProtocolVersion.App, appVersion)
}

View File

@ -49,10 +49,17 @@ type ProtocolVersion struct {
App version.Protocol `json:"app"` App version.Protocol `json:"app"`
} }
var InitProtocolVersion = ProtocolVersion{ // InitProtocolVersion populates the Block and P2P versions, but not the App.
P2P: version.P2PProtocol, var InitProtocolVersion = ProtocolVersionWithApp(0)
Block: version.BlockProtocol,
App: 0, // ProtocolVersionWithApp returns a fully populated ProtocolVersion
// using the provided App version and the Block and P2P versions defined in the `version` package.
func ProtocolVersionWithApp(appVersion version.Protocol) ProtocolVersion {
return ProtocolVersion{
P2P: version.P2PProtocol,
Block: version.BlockProtocol,
App: appVersion,
}
} }
//------------------------------------------------------------- //-------------------------------------------------------------
@ -148,7 +155,7 @@ func (info DefaultNodeInfo) ValidateBasic() error {
switch txIndex { switch txIndex {
case "", "on", "off": case "", "on", "off":
default: default:
return fmt.Errorf("info.Other.TxIndex should be either 'on' or 'off', got '%v'", txIndex) return fmt.Errorf("info.Other.TxIndex should be either 'on', 'off', or empty string, got '%v'", txIndex)
} }
// XXX: Should we be more strict about address formats? // XXX: Should we be more strict about address formats?
rpcAddr := other.RPCAddress rpcAddr := other.RPCAddress

View File

@ -143,7 +143,7 @@ func TestInfo(t *testing.T) {
proxy := NewAppConnTest(cli) proxy := NewAppConnTest(cli)
t.Log("Connected") t.Log("Connected")
resInfo, err := proxy.InfoSync(types.RequestInfo{Version: ""}) resInfo, err := proxy.InfoSync(RequestInfo)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }

15
proxy/version.go Normal file
View File

@ -0,0 +1,15 @@
package proxy
import (
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/version"
)
// RequestInfo contains all the information for sending
// the abci.RequestInfo message during handshake with the app.
// It contains only compile-time version information.
var RequestInfo = abci.RequestInfo{
Version: version.Version,
BlockVersion: version.BlockProtocol.Uint64(),
P2PVersion: version.P2PProtocol.Uint64(),
}

View File

@ -3,10 +3,10 @@ package mock
import ( import (
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
cmn "github.com/tendermint/tendermint/libs/common" cmn "github.com/tendermint/tendermint/libs/common"
"github.com/tendermint/tendermint/proxy"
"github.com/tendermint/tendermint/rpc/client" "github.com/tendermint/tendermint/rpc/client"
ctypes "github.com/tendermint/tendermint/rpc/core/types" ctypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
"github.com/tendermint/tendermint/version"
) )
// ABCIApp will send all abci related request to the named app, // ABCIApp will send all abci related request to the named app,
@ -23,7 +23,7 @@ var (
) )
func (a ABCIApp) ABCIInfo() (*ctypes.ResultABCIInfo, error) { func (a ABCIApp) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
return &ctypes.ResultABCIInfo{a.App.Info(abci.RequestInfo{Version: version.Version})}, nil return &ctypes.ResultABCIInfo{a.App.Info(proxy.RequestInfo)}, nil
} }
func (a ABCIApp) ABCIQuery(path string, data cmn.HexBytes) (*ctypes.ResultABCIQuery, error) { func (a ABCIApp) ABCIQuery(path string, data cmn.HexBytes) (*ctypes.ResultABCIQuery, error) {

View File

@ -3,8 +3,8 @@ package core
import ( import (
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
cmn "github.com/tendermint/tendermint/libs/common" cmn "github.com/tendermint/tendermint/libs/common"
"github.com/tendermint/tendermint/proxy"
ctypes "github.com/tendermint/tendermint/rpc/core/types" ctypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/tendermint/tendermint/version"
) )
// Query the application for some information. // Query the application for some information.
@ -87,7 +87,7 @@ func ABCIQuery(path string, data cmn.HexBytes, height int64, prove bool) (*ctype
// } // }
// ``` // ```
func ABCIInfo() (*ctypes.ResultABCIInfo, error) { func ABCIInfo() (*ctypes.ResultABCIInfo, error) {
resInfo, err := proxyAppQuery.InfoSync(abci.RequestInfo{Version: version.Version}) resInfo, err := proxyAppQuery.InfoSync(proxy.RequestInfo)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -27,6 +27,10 @@ type Version struct {
Software string Software string
} }
// initStateVersion sets the Consensus.Block and Software versions,
// but leaves the Consensus.App version blank.
// The Consensus.App version will be set during the Handshake, once
// we hear from the app what protocol version it is running.
var initStateVersion = Version{ var initStateVersion = Version{
Consensus: version.Consensus{ Consensus: version.Consensus{
Block: version.BlockProtocol, Block: version.BlockProtocol,

View File

@ -28,6 +28,12 @@ const (
// Protocol is used for implementation agnostic versioning. // Protocol is used for implementation agnostic versioning.
type Protocol uint64 type Protocol uint64
// Uint64 returns the Protocol version as a uint64,
// eg. for compatibility with ABCI types.
func (p Protocol) Uint64() uint64 {
return uint64(p)
}
var ( var (
// P2PProtocol versions all p2p behaviour and msgs. // P2PProtocol versions all p2p behaviour and msgs.
P2PProtocol Protocol = 4 P2PProtocol Protocol = 4