diff --git a/abcix/adapter/adapter.go b/abcix/adapter/adapter.go index 9c02345b850..73dd05cbf35 100644 --- a/abcix/adapter/adapter.go +++ b/abcix/adapter/adapter.go @@ -25,6 +25,8 @@ var ( type adaptedApp struct { abciApp abci.Application + appHash []byte + events []abcix.Event } type AdaptedApp interface { @@ -189,6 +191,7 @@ func (app *adaptedApp) DeliverBlock(req abcix.RequestDeliverBlock) (resp abcix.R allEvents = append(allEvents, beginEvents...) allEvents = append(allEvents, endEvents...) resp.Events = allEvents + app.events = allEvents return resp } @@ -198,12 +201,20 @@ func (app *adaptedApp) Commit() (resp abcix.ResponseCommit) { // TODO: panic for debugging purposes. better error handling soon! panic(err) } + app.appHash = abciResp.Data return } func (app *adaptedApp) CheckBlock(req abcix.RequestCheckBlock) abcix.ResponseCheckBlock { - // TODO: defer to consensus engine for now - panic("implement me") + respDeliverTx := make([]*abcix.ResponseDeliverTx, len(req.Txs)) + for i := range respDeliverTx { + respDeliverTx[i] = &abcix.ResponseDeliverTx{Code: 0} + } + return abcix.ResponseCheckBlock{ + AppHash: app.appHash, + DeliverTxs: respDeliverTx, + Events: app.events, + } } func (app *adaptedApp) ListSnapshots(req abcix.RequestListSnapshots) (resp abcix.ResponseListSnapshots) { diff --git a/abcix/example/kvstore/kvstore.go b/abcix/example/kvstore/kvstore.go index 9f971ed6757..95edf548c7d 100644 --- a/abcix/example/kvstore/kvstore.go +++ b/abcix/example/kvstore/kvstore.go @@ -124,17 +124,7 @@ func (app *Application) CreateBlock( appHash := make([]byte, 8) binary.PutVarint(appHash, size) - events := []types.Event{ - { - Type: "create_block", - Attributes: []types.EventAttribute{ - {Key: []byte("height"), Value: []byte{byte(req.Height)}}, - {Key: []byte("valid tx"), Value: []byte{byte(len(txs))}}, - {Key: []byte("invalid tx"), Value: []byte{byte(len(invalidTxs))}}, - }, - }, - } - return types.ResponseCreateBlock{Txs: txs, InvalidTxs: invalidTxs, Hash: appHash, Events: events} + return types.ResponseCreateBlock{Txs: txs, InvalidTxs: invalidTxs, Hash: appHash, Events: nil} } // Combination of ABCI.BeginBlock, []ABCI.DeliverTx, and ABCI.EndBlock @@ -154,6 +144,28 @@ func (app *Application) DeliverBlock(req types.RequestDeliverBlock) types.Respon return ret } +func (app *Application) CheckBlock(req types.RequestCheckBlock) types.ResponseCheckBlock { + // Tx looks like "[key1]=[value1],[key2]=[value2],[from],[gasprice]" + // e.g. "a=41,c=42,alice,100" + ret := types.ResponseCheckBlock{} + + lastState := app.state + for _, tx := range req.Txs { + newState, gasUsed, err := executeTx(lastState, tx, true) + if err != nil { + panic("consensus failure: invalid tx found in DeliverBlock: " + err.Error()) + } + lastState = newState + txResp := types.ResponseDeliverTx{GasUsed: gasUsed} + ret.DeliverTxs = append(ret.DeliverTxs, &txResp) + } + if len(lastState.AppHash) != 0 { + ret.AppHash = lastState.AppHash + } + + return ret +} + func (app *Application) Commit() types.ResponseCommit { // Using a memdb - just return the big endian size of the db appHash := make([]byte, 8) diff --git a/abcix/types/types.pb.go b/abcix/types/types.pb.go index 822378eb8a7..a8eeee98127 100644 --- a/abcix/types/types.pb.go +++ b/abcix/types/types.pb.go @@ -6,6 +6,11 @@ package types import ( context "context" fmt "fmt" + io "io" + math "math" + math_bits "math/bits" + time "time" + _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" _ "github.com/gogo/protobuf/types" @@ -15,10 +20,6 @@ import ( grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" - io "io" - math "math" - math_bits "math/bits" - time "time" ) // Reference imports to suppress errors if they are not otherwise used. @@ -956,6 +957,12 @@ func (m *RequestDeliverBlock) GetTxs() [][]byte { } type RequestCheckBlock struct { + Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"` + Hash []byte `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"` + Header types1.Header `protobuf:"bytes,3,opt,name=header,proto3" json:"header"` + LastCommitInfo LastCommitInfo `protobuf:"bytes,4,opt,name=last_commit_info,json=lastCommitInfo,proto3" json:"last_commit_info"` + ByzantineValidators []Evidence `protobuf:"bytes,5,rep,name=byzantine_validators,json=byzantineValidators,proto3" json:"byzantine_validators"` + Txs [][]byte `protobuf:"bytes,6,rep,name=txs,proto3" json:"txs,omitempty"` } func (m *RequestCheckBlock) Reset() { *m = RequestCheckBlock{} } @@ -991,6 +998,48 @@ func (m *RequestCheckBlock) XXX_DiscardUnknown() { var xxx_messageInfo_RequestCheckBlock proto.InternalMessageInfo +func (m *RequestCheckBlock) GetHeight() int64 { + if m != nil { + return m.Height + } + return 0 +} + +func (m *RequestCheckBlock) GetHash() []byte { + if m != nil { + return m.Hash + } + return nil +} + +func (m *RequestCheckBlock) GetHeader() types1.Header { + if m != nil { + return m.Header + } + return types1.Header{} +} + +func (m *RequestCheckBlock) GetLastCommitInfo() LastCommitInfo { + if m != nil { + return m.LastCommitInfo + } + return LastCommitInfo{} +} + +func (m *RequestCheckBlock) GetByzantineValidators() []Evidence { + if m != nil { + return m.ByzantineValidators + } + return nil +} + +func (m *RequestCheckBlock) GetTxs() [][]byte { + if m != nil { + return m.Txs + } + return nil +} + // lists available snapshots type RequestListSnapshots struct { } @@ -2309,8 +2358,13 @@ func (m *ResponseDeliverBlock) GetCodespace() string { } type ResponseCheckBlock struct { - Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` - Codespace string `protobuf:"bytes,2,opt,name=codespace,proto3" json:"codespace,omitempty"` + Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + AppHash []byte `protobuf:"bytes,2,opt,name=app_hash,json=appHash,proto3" json:"app_hash,omitempty"` + DeliverTxs []*ResponseDeliverTx `protobuf:"bytes,3,rep,name=deliver_txs,json=deliverTxs,proto3" json:"deliver_txs,omitempty"` + ValidatorUpdates []ValidatorUpdate `protobuf:"bytes,4,rep,name=validator_updates,json=validatorUpdates,proto3" json:"validator_updates"` + ConsensusParamUpdates *ConsensusParams `protobuf:"bytes,5,opt,name=consensus_param_updates,json=consensusParamUpdates,proto3" json:"consensus_param_updates,omitempty"` + Events []Event `protobuf:"bytes,6,rep,name=events,proto3" json:"events,omitempty"` + Codespace string `protobuf:"bytes,7,opt,name=codespace,proto3" json:"codespace,omitempty"` } func (m *ResponseCheckBlock) Reset() { *m = ResponseCheckBlock{} } @@ -2353,6 +2407,41 @@ func (m *ResponseCheckBlock) GetCode() uint32 { return 0 } +func (m *ResponseCheckBlock) GetAppHash() []byte { + if m != nil { + return m.AppHash + } + return nil +} + +func (m *ResponseCheckBlock) GetDeliverTxs() []*ResponseDeliverTx { + if m != nil { + return m.DeliverTxs + } + return nil +} + +func (m *ResponseCheckBlock) GetValidatorUpdates() []ValidatorUpdate { + if m != nil { + return m.ValidatorUpdates + } + return nil +} + +func (m *ResponseCheckBlock) GetConsensusParamUpdates() *ConsensusParams { + if m != nil { + return m.ConsensusParamUpdates + } + return nil +} + +func (m *ResponseCheckBlock) GetEvents() []Event { + if m != nil { + return m.Events + } + return nil +} + func (m *ResponseCheckBlock) GetCodespace() string { if m != nil { return m.Codespace @@ -3282,181 +3371,184 @@ func init() { func init() { proto.RegisterFile("tendermint/abcix/types.proto", fileDescriptor_e415c24393570900) } var fileDescriptor_e415c24393570900 = []byte{ - // 2782 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x5a, 0xcb, 0x73, 0x1b, 0xc7, + // 2818 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5a, 0xcb, 0x73, 0x1b, 0xc7, 0xd1, 0xc7, 0xe2, 0x8d, 0x06, 0x41, 0x82, 0x23, 0x5a, 0x86, 0x61, 0x89, 0xa4, 0x57, 0x7e, 0xe8, - 0x93, 0xf5, 0x91, 0x65, 0xca, 0x25, 0xbf, 0xf2, 0x28, 0x12, 0x02, 0x0d, 0x5a, 0x32, 0x49, 0x2f, + 0x93, 0xf5, 0x91, 0x65, 0xca, 0x25, 0xbf, 0xf2, 0x28, 0x12, 0x82, 0x0c, 0x5a, 0x32, 0x49, 0x2f, 0x69, 0xa9, 0xec, 0x8a, 0xbd, 0x5a, 0xee, 0x0e, 0x81, 0x8d, 0x80, 0xdd, 0xf5, 0xee, 0x80, 0x22, - 0x92, 0x4b, 0x2a, 0x95, 0xaa, 0x54, 0x39, 0x17, 0x5f, 0x73, 0x70, 0x8e, 0x49, 0x55, 0x8e, 0xce, - 0x25, 0xb7, 0x5c, 0x7d, 0x74, 0x55, 0x2e, 0x39, 0xd9, 0x29, 0xfb, 0x96, 0x7f, 0x20, 0xd7, 0xd4, - 0x3c, 0xf6, 0x05, 0xec, 0x02, 0xa0, 0xec, 0x9c, 0x72, 0x9b, 0xe9, 0xe9, 0xee, 0x79, 0xf4, 0x4c, - 0xf7, 0xaf, 0x7b, 0x17, 0xae, 0x10, 0x6c, 0x19, 0xd8, 0x1d, 0x98, 0x16, 0xd9, 0xd4, 0x4e, 0x74, - 0xf3, 0x7c, 0x93, 0x8c, 0x1c, 0xec, 0x6d, 0x38, 0xae, 0x4d, 0x6c, 0x54, 0x0f, 0x47, 0x37, 0xd8, - 0x68, 0xf3, 0x6a, 0x84, 0x5f, 0x77, 0x47, 0x0e, 0xb1, 0x37, 0x1d, 0xd7, 0xb6, 0x4f, 0xb9, 0x40, - 0x33, 0xaa, 0x8e, 0x29, 0x8a, 0xaa, 0x8b, 0x8d, 0x0a, 0xe1, 0x47, 0x78, 0xe4, 0x8f, 0x5e, 0x9d, - 0x90, 0x75, 0x34, 0x57, 0x1b, 0xf8, 0xc3, 0x6b, 0x5d, 0xdb, 0xee, 0xf6, 0xf1, 0x26, 0xeb, 0x9d, - 0x0c, 0x4f, 0x37, 0x89, 0x39, 0xc0, 0x1e, 0xd1, 0x06, 0x8e, 0x60, 0x58, 0xe9, 0xda, 0x5d, 0x9b, - 0x35, 0x37, 0x69, 0x8b, 0x53, 0xe5, 0x2f, 0xca, 0x50, 0x52, 0xf0, 0x27, 0x43, 0xec, 0x11, 0x74, - 0x0b, 0xf2, 0x58, 0xef, 0xd9, 0x8d, 0xec, 0xba, 0x74, 0xbd, 0xba, 0x75, 0x75, 0x63, 0x7c, 0x77, - 0x1b, 0x82, 0xb1, 0xad, 0xf7, 0xec, 0x4e, 0x46, 0x61, 0xcc, 0xe8, 0x36, 0x14, 0x4e, 0xfb, 0x43, - 0xaf, 0xd7, 0xc8, 0x31, 0xa9, 0xd5, 0x54, 0xa9, 0x5d, 0xca, 0xd5, 0xc9, 0x28, 0x9c, 0x9d, 0x4e, - 0x66, 0x5a, 0xa7, 0x76, 0x23, 0x3f, 0x63, 0xb2, 0x3d, 0xeb, 0x94, 0x4d, 0x46, 0x99, 0x51, 0x0b, - 0xc0, 0xc3, 0x44, 0xb5, 0x1d, 0x62, 0xda, 0x56, 0xa3, 0xc0, 0x44, 0xe5, 0x54, 0xd1, 0x23, 0x4c, - 0x0e, 0x18, 0x67, 0x27, 0xa3, 0x54, 0x3c, 0xbf, 0x43, 0x95, 0x98, 0x96, 0x49, 0x54, 0xbd, 0xa7, - 0x99, 0x56, 0xa3, 0x38, 0x43, 0xc9, 0x9e, 0x65, 0x92, 0x16, 0xe5, 0xa4, 0x4a, 0x4c, 0xbf, 0x43, - 0xb7, 0xfd, 0xc9, 0x10, 0xbb, 0xa3, 0x46, 0x69, 0xc6, 0xb6, 0xdf, 0xa3, 0x5c, 0x74, 0xdb, 0x8c, - 0x1d, 0xfd, 0x18, 0xca, 0x7a, 0x0f, 0xeb, 0x8f, 0x54, 0x72, 0xde, 0xa8, 0x30, 0xd1, 0xf5, 0x54, - 0xd1, 0x16, 0x65, 0x3c, 0x3e, 0xef, 0x64, 0x94, 0x92, 0xce, 0x9b, 0xe8, 0x1e, 0xd4, 0x0c, 0xdc, - 0x37, 0xcf, 0xb0, 0xab, 0x9e, 0xf4, 0x6d, 0xfd, 0x51, 0x63, 0x85, 0xe9, 0x78, 0x21, 0x55, 0xc7, - 0x1d, 0xce, 0xbd, 0x43, 0x99, 0x3b, 0x19, 0x65, 0xc1, 0x88, 0xf4, 0xd1, 0x2e, 0x54, 0xf9, 0x62, - 0xb8, 0xae, 0xa7, 0x98, 0xae, 0x6b, 0xd3, 0xd7, 0xe3, 0x6b, 0x02, 0x3d, 0xe8, 0xa1, 0x37, 0xa0, - 0xa8, 0xdb, 0x83, 0x81, 0x49, 0x1a, 0x0b, 0x4c, 0xc5, 0x5a, 0xba, 0x0a, 0xc6, 0xd6, 0xc9, 0x28, - 0x42, 0x00, 0x1d, 0xc0, 0x62, 0xdf, 0xf4, 0x88, 0xea, 0x59, 0x9a, 0xe3, 0xf5, 0x6c, 0xe2, 0x35, - 0x6a, 0x4c, 0xc5, 0x8b, 0xa9, 0x2a, 0xee, 0x99, 0x1e, 0x39, 0xf2, 0xb9, 0x3b, 0x19, 0xa5, 0xd6, - 0x8f, 0x12, 0xa8, 0x42, 0xfb, 0xf4, 0x14, 0xbb, 0x81, 0xc6, 0xc6, 0xe2, 0x0c, 0x85, 0x07, 0x94, - 0xdd, 0x57, 0x40, 0x15, 0xda, 0x51, 0x02, 0xfa, 0x19, 0x5c, 0xea, 0xdb, 0x9a, 0x11, 0xe8, 0x53, - 0xf5, 0xde, 0xd0, 0x7a, 0xd4, 0x58, 0x62, 0x5a, 0x6f, 0xa4, 0x2f, 0xd3, 0xd6, 0x0c, 0x5f, 0x47, - 0x8b, 0x4a, 0x74, 0x32, 0xca, 0x72, 0x7f, 0x9c, 0x88, 0x54, 0x58, 0xd1, 0x1c, 0xa7, 0x3f, 0x1a, - 0x57, 0x5f, 0x67, 0xea, 0x5f, 0x4e, 0x55, 0xbf, 0x4d, 0x85, 0xc6, 0xf5, 0x23, 0x6d, 0x82, 0x8a, - 0xf6, 0x60, 0x41, 0x77, 0xb1, 0x46, 0xb0, 0x30, 0xf2, 0x32, 0x53, 0xfc, 0x7c, 0xba, 0x85, 0x18, - 0xb3, 0x6f, 0xe5, 0xaa, 0x1e, 0x76, 0x77, 0x4a, 0x50, 0x38, 0xd3, 0xfa, 0x43, 0x2c, 0xbf, 0x04, - 0xd5, 0x88, 0x2b, 0x40, 0x0d, 0x28, 0x0d, 0xb0, 0xe7, 0x69, 0x5d, 0xdc, 0x90, 0xd6, 0xa5, 0xeb, - 0x15, 0xc5, 0xef, 0xca, 0x8b, 0xb0, 0x10, 0x7d, 0xfd, 0xf2, 0x20, 0x10, 0xa4, 0xcf, 0x9a, 0x0a, - 0x9e, 0x61, 0xd7, 0xa3, 0x6f, 0x59, 0x08, 0x8a, 0x2e, 0xba, 0x06, 0x35, 0xb6, 0x5c, 0xd5, 0x1f, - 0xa7, 0x3e, 0x29, 0xaf, 0x2c, 0x30, 0xe2, 0x7d, 0xc1, 0xb4, 0x06, 0x55, 0x67, 0xcb, 0x09, 0x58, - 0x72, 0x8c, 0x05, 0x9c, 0x2d, 0x47, 0x30, 0xc8, 0x6f, 0x42, 0x7d, 0xdc, 0x15, 0xa0, 0x3a, 0xe4, - 0x1e, 0xe1, 0x91, 0x98, 0x8f, 0x36, 0xd1, 0x8a, 0xd8, 0x16, 0x9b, 0xa3, 0xa2, 0x88, 0x3d, 0xfe, - 0x31, 0x1b, 0x08, 0x07, 0x2e, 0x00, 0xbd, 0x0e, 0x79, 0xea, 0x56, 0x99, 0x74, 0x75, 0xab, 0xb9, - 0xc1, 0x7d, 0xee, 0x86, 0xef, 0x73, 0x37, 0x8e, 0x7d, 0x9f, 0xbb, 0x53, 0xfe, 0xf2, 0xeb, 0xb5, - 0xcc, 0x67, 0xdf, 0xac, 0x49, 0x0a, 0x93, 0x40, 0xcf, 0xd0, 0x77, 0xaf, 0x99, 0x96, 0x6a, 0x1a, - 0x62, 0x9e, 0x12, 0xeb, 0xef, 0x19, 0xe8, 0x1e, 0xd4, 0x75, 0xdb, 0xf2, 0xb0, 0xe5, 0x0d, 0x3d, - 0x95, 0xfb, 0x74, 0xe1, 0x4c, 0x9f, 0x9b, 0xb4, 0x52, 0xcb, 0xe7, 0x3c, 0x64, 0x8c, 0xca, 0x92, - 0x1e, 0x27, 0xa0, 0xb7, 0x01, 0xce, 0xb4, 0xbe, 0x69, 0x68, 0xc4, 0x76, 0xbd, 0x46, 0x7e, 0x3d, - 0x97, 0xac, 0xe7, 0xbe, 0xcf, 0xf3, 0xbe, 0x63, 0x50, 0x03, 0xe7, 0xe9, 0x7a, 0x95, 0x88, 0x28, - 0x7a, 0x11, 0x96, 0x34, 0xc7, 0x51, 0x3d, 0xc2, 0xee, 0xce, 0x88, 0x60, 0x8f, 0x39, 0xdc, 0x05, - 0xa5, 0xa6, 0x39, 0xce, 0x11, 0xa5, 0xee, 0x50, 0xa2, 0x6c, 0x04, 0x36, 0x66, 0xae, 0x0e, 0x21, - 0xc8, 0x1b, 0x1a, 0xd1, 0xd8, 0x19, 0x2d, 0x28, 0xac, 0x4d, 0x69, 0x8e, 0x46, 0x7a, 0x62, 0xe7, - 0xac, 0x8d, 0x2e, 0x43, 0xb1, 0x87, 0xcd, 0x6e, 0x8f, 0xb0, 0xcd, 0xe6, 0x14, 0xd1, 0xa3, 0xe6, - 0x70, 0x5c, 0xfb, 0x0c, 0xb3, 0xc8, 0x50, 0x56, 0x78, 0x47, 0xfe, 0xbb, 0x04, 0x68, 0xf2, 0x86, - 0x46, 0x94, 0x48, 0x31, 0x25, 0x87, 0x50, 0xef, 0x6b, 0x1e, 0x51, 0xb9, 0x97, 0x51, 0x59, 0xa4, - 0xc9, 0xa6, 0xb9, 0xdb, 0x7b, 0x9a, 0xef, 0x98, 0xe8, 0xad, 0x14, 0x47, 0xb1, 0xd8, 0x8f, 0x51, - 0xd1, 0x11, 0xac, 0x9c, 0x8c, 0x7e, 0xa1, 0x59, 0xc4, 0xb4, 0xb0, 0x1a, 0x39, 0xe1, 0x1c, 0x3b, - 0xe1, 0xe6, 0xa4, 0xd6, 0xf6, 0x99, 0x69, 0x60, 0x4b, 0xf7, 0x8f, 0xf6, 0x52, 0x20, 0x1d, 0x1c, - 0xbd, 0x27, 0x1f, 0xc1, 0x62, 0xdc, 0xd7, 0xa3, 0x45, 0xc8, 0x92, 0x73, 0x71, 0x76, 0x59, 0x72, - 0x8e, 0x5e, 0x81, 0x3c, 0x0d, 0xf6, 0x6c, 0xf1, 0x8b, 0x49, 0x61, 0x52, 0x08, 0x1e, 0x8f, 0x1c, - 0xac, 0x30, 0x56, 0x79, 0x09, 0x6a, 0x31, 0x6f, 0x2b, 0x7f, 0x91, 0x85, 0x4b, 0x09, 0xe1, 0x20, - 0xf5, 0xf0, 0x10, 0xe4, 0x7b, 0x9a, 0xc7, 0xad, 0xb5, 0xa0, 0xb0, 0x36, 0xba, 0x4d, 0x79, 0x35, - 0x03, 0xbb, 0xe2, 0x6a, 0x36, 0xa2, 0x2b, 0xe1, 0x20, 0xa6, 0xc3, 0xc6, 0xc5, 0x76, 0x05, 0x77, - 0xa2, 0x21, 0xf2, 0xff, 0x15, 0x43, 0x14, 0xbe, 0x87, 0x21, 0xa8, 0x57, 0x20, 0xe7, 0x5e, 0xa3, - 0xb8, 0x9e, 0xbb, 0xbe, 0xa0, 0xd0, 0xa6, 0x7c, 0x09, 0x96, 0x27, 0xc2, 0x9e, 0x7c, 0x19, 0x56, - 0x92, 0xa2, 0x90, 0x6c, 0x06, 0xf4, 0x58, 0x30, 0x41, 0xb7, 0xa1, 0x1c, 0x84, 0x21, 0xdf, 0x67, - 0x4c, 0xac, 0xcf, 0xe7, 0x56, 0x02, 0x5e, 0xea, 0x2d, 0xe8, 0xdb, 0x8b, 0x58, 0xa1, 0xa4, 0x39, - 0x4e, 0x47, 0xf3, 0x7a, 0xf2, 0x43, 0x68, 0xa4, 0x45, 0x98, 0x31, 0x83, 0xe6, 0x03, 0x83, 0x5e, - 0x86, 0xe2, 0xa9, 0xed, 0x0e, 0x34, 0xc2, 0x94, 0xd5, 0x14, 0xd1, 0xa3, 0x4f, 0x8d, 0x47, 0x9b, - 0x1c, 0x23, 0xf3, 0x8e, 0xac, 0xc2, 0x33, 0xa9, 0x41, 0x86, 0x8a, 0x98, 0x96, 0x81, 0xf9, 0x15, - 0xad, 0x29, 0xbc, 0x13, 0x2a, 0xe2, 0x8b, 0xe5, 0x1d, 0x3a, 0xad, 0xc7, 0x36, 0xcb, 0xf4, 0x57, - 0x14, 0xd1, 0x93, 0x7f, 0x5b, 0x81, 0xb2, 0x82, 0x3d, 0x87, 0x7a, 0x2e, 0xd4, 0x82, 0x0a, 0x3e, - 0xd7, 0x31, 0x47, 0x74, 0x52, 0x3a, 0x02, 0xe1, 0xec, 0x6d, 0x9f, 0x95, 0xa2, 0xb1, 0x40, 0x0e, - 0xbd, 0x1a, 0x43, 0xae, 0xab, 0x53, 0xe4, 0xa3, 0xd0, 0xf5, 0xb5, 0x38, 0x74, 0x5d, 0x4b, 0x17, - 0x1b, 0xc3, 0xae, 0xaf, 0xc6, 0xb0, 0xeb, 0x94, 0xe9, 0x62, 0xe0, 0xf5, 0x4e, 0x02, 0x78, 0x9d, - 0xb2, 0xd5, 0x14, 0xf4, 0x7a, 0x27, 0x01, 0xbd, 0x5e, 0x9b, 0xb6, 0x82, 0x44, 0xf8, 0xfa, 0x5a, - 0x1c, 0xbe, 0x4e, 0xd9, 0xfa, 0x18, 0x7e, 0xfd, 0xc9, 0x04, 0x7e, 0x7d, 0x2e, 0x5d, 0x36, 0x01, - 0xc0, 0xbe, 0x39, 0x06, 0x15, 0xd7, 0xa7, 0x48, 0x8f, 0x63, 0xc5, 0x77, 0x93, 0xc1, 0xef, 0x8b, - 0xe9, 0x2a, 0xa6, 0xa2, 0xdf, 0xb7, 0x93, 0xd0, 0xef, 0xf3, 0x33, 0x76, 0x93, 0x04, 0x7f, 0x0f, - 0x53, 0x30, 0xec, 0x4b, 0xe9, 0xba, 0x66, 0x80, 0xd8, 0xc3, 0x14, 0x10, 0x3b, 0x45, 0xe3, 0x0c, - 0x14, 0xfb, 0xd1, 0x34, 0x14, 0xfb, 0xf2, 0x94, 0x85, 0xce, 0x07, 0x63, 0x1f, 0x4e, 0x85, 0xb1, - 0x37, 0xd3, 0xf5, 0xcf, 0x8d, 0x63, 0xdf, 0x49, 0xc4, 0xb1, 0x2f, 0x4c, 0x31, 0xd7, 0x1c, 0x40, - 0xf6, 0xff, 0xa8, 0x93, 0x1f, 0xf3, 0x2c, 0xd4, 0x99, 0x61, 0xd7, 0xb5, 0x5d, 0x81, 0x11, 0x79, - 0x47, 0xbe, 0x4e, 0x61, 0x4e, 0xe8, 0x44, 0xa6, 0x80, 0x5e, 0x16, 0x7f, 0x23, 0x7e, 0x43, 0xfe, - 0xab, 0x14, 0xca, 0xb2, 0x10, 0x16, 0x85, 0x48, 0x15, 0x01, 0x91, 0x22, 0x58, 0x38, 0x1b, 0xc7, - 0xc2, 0x6b, 0x50, 0xa5, 0xc1, 0x60, 0x0c, 0xe6, 0x6a, 0x8e, 0x0f, 0x73, 0xd1, 0x0d, 0x58, 0x66, - 0x31, 0x96, 0x23, 0x66, 0x11, 0x01, 0xf2, 0x2c, 0xa4, 0x2f, 0xd1, 0x01, 0x7e, 0x06, 0x3c, 0x14, - 0xfc, 0x3f, 0x5c, 0x8a, 0xf0, 0x06, 0x41, 0x86, 0x23, 0xbb, 0x7a, 0xc0, 0xbd, 0x2d, 0xa2, 0xcd, - 0xbb, 0xe1, 0x01, 0x85, 0x10, 0x1a, 0x41, 0x5e, 0xb7, 0x0d, 0x2c, 0x42, 0x00, 0x6b, 0xd3, 0x00, - 0xda, 0xb7, 0xbb, 0xc2, 0xd1, 0xd3, 0x26, 0xe5, 0x0a, 0x9c, 0x64, 0x85, 0xbb, 0x40, 0xf9, 0xcf, - 0x52, 0xa8, 0x2f, 0x44, 0xd5, 0x49, 0x00, 0x58, 0xfa, 0x81, 0x00, 0x70, 0xf6, 0x89, 0x01, 0xb0, - 0xfc, 0x6f, 0x29, 0x34, 0x64, 0x00, 0x6d, 0x9f, 0x6c, 0xe3, 0x61, 0xd8, 0x2c, 0x30, 0xb3, 0x88, - 0xb0, 0x29, 0x72, 0x91, 0x22, 0x3b, 0xfc, 0x78, 0x2e, 0x52, 0xe2, 0x81, 0x94, 0x75, 0xd0, 0xeb, - 0x50, 0x61, 0x55, 0x24, 0xd5, 0x76, 0xbc, 0x46, 0x99, 0x9d, 0xcc, 0xb3, 0xd1, 0x1d, 0xf1, 0x62, - 0xd1, 0xc6, 0x21, 0xe5, 0x39, 0x70, 0x3c, 0xa5, 0xec, 0x88, 0x56, 0x04, 0x11, 0x54, 0x62, 0x10, - 0xef, 0x0a, 0x54, 0xe8, 0xea, 0x3d, 0x47, 0xd3, 0x71, 0x03, 0xd8, 0x42, 0x43, 0x82, 0xfc, 0x27, - 0x89, 0x02, 0xc6, 0x89, 0x67, 0xe4, 0xa3, 0x24, 0x29, 0x40, 0x49, 0xf4, 0x6e, 0x9a, 0x16, 0x3b, - 0x33, 0x95, 0x8e, 0x64, 0xd9, 0x08, 0x08, 0xd2, 0xf1, 0xb9, 0x17, 0x60, 0xc9, 0x5c, 0x04, 0x4b, - 0xee, 0x41, 0x11, 0x9f, 0x61, 0x8b, 0xf8, 0xe9, 0xc9, 0xd3, 0x49, 0x98, 0x0d, 0x5b, 0x64, 0xa7, - 0x41, 0x6d, 0xf2, 0xaf, 0xaf, 0xd7, 0xea, 0x9c, 0xfd, 0xa6, 0x3d, 0x30, 0x09, 0x1e, 0x38, 0x64, - 0xa4, 0x08, 0x05, 0xf2, 0x1f, 0xb2, 0xb0, 0x34, 0x16, 0x6d, 0x12, 0xad, 0xe4, 0xbf, 0xb8, 0x6c, - 0x24, 0x29, 0x99, 0xcf, 0x72, 0x57, 0x01, 0xba, 0x9a, 0xa7, 0x3e, 0xd6, 0x2c, 0x82, 0x0d, 0x61, - 0xbe, 0x4a, 0x57, 0xf3, 0x1e, 0x30, 0x02, 0x45, 0x6a, 0x74, 0x78, 0xe8, 0x61, 0x83, 0xd9, 0x31, - 0xa7, 0x94, 0xba, 0x9a, 0xf7, 0xbe, 0x87, 0x8d, 0xc8, 0x36, 0x4b, 0xdf, 0x73, 0x9b, 0x71, 0x73, - 0x95, 0xc7, 0xcc, 0x85, 0x9a, 0x50, 0x76, 0x5c, 0xd3, 0x76, 0x4d, 0x32, 0x62, 0x66, 0xce, 0x2b, - 0x41, 0x5f, 0xfe, 0x4d, 0x36, 0x7c, 0x71, 0x22, 0x1a, 0xfe, 0x0f, 0x1e, 0x91, 0xbc, 0x47, 0x13, - 0xad, 0x28, 0xac, 0x48, 0xdc, 0xee, 0x35, 0xa8, 0xb9, 0x98, 0xd0, 0x2c, 0x3d, 0x96, 0x99, 0x2e, - 0x70, 0x22, 0xf7, 0xa0, 0xf2, 0xa7, 0x39, 0x0a, 0xf6, 0x27, 0xf1, 0x45, 0xe2, 0xa1, 0xde, 0x81, - 0xaa, 0x0f, 0x59, 0xfc, 0xf7, 0x31, 0x15, 0xae, 0x05, 0x26, 0x52, 0xc0, 0xf0, 0x9b, 0x1e, 0x3a, - 0x86, 0xe5, 0xc0, 0x2f, 0xa9, 0x43, 0xe6, 0xaf, 0xfc, 0xc4, 0x73, 0x6e, 0xcf, 0x56, 0x3f, 0x8b, - 0x93, 0x3d, 0xf4, 0x01, 0x3c, 0x3d, 0xe6, 0x76, 0x03, 0xdd, 0xf9, 0x79, 0xbd, 0xef, 0x53, 0x71, - 0xef, 0xeb, 0xab, 0x0e, 0xed, 0x5a, 0xf8, 0x41, 0xed, 0x5a, 0x1c, 0xb7, 0xeb, 0x2e, 0xa0, 0x49, - 0x78, 0x96, 0x68, 0x89, 0x98, 0x9e, 0xec, 0xb8, 0x9e, 0xf7, 0xe0, 0xa9, 0x44, 0x68, 0x46, 0x5d, - 0x6f, 0x08, 0xeb, 0xa4, 0xb4, 0x14, 0x33, 0x48, 0xe1, 0x42, 0x66, 0xf9, 0x6f, 0x52, 0xa8, 0x33, - 0x9e, 0x15, 0xee, 0x42, 0xd1, 0xc5, 0xde, 0xb0, 0xcf, 0xd3, 0xb4, 0xc5, 0xad, 0x8d, 0x39, 0x51, - 0x1d, 0xa5, 0x0e, 0xfb, 0x44, 0x11, 0xd2, 0xf2, 0xc7, 0x50, 0xe4, 0x14, 0x54, 0x85, 0xd2, 0xfb, - 0xfb, 0x77, 0xf7, 0x0f, 0x1e, 0xec, 0xd7, 0x33, 0x08, 0xa0, 0xb8, 0xdd, 0x6a, 0xb5, 0x0f, 0x8f, - 0xeb, 0x12, 0xaa, 0x40, 0x61, 0x7b, 0xe7, 0x40, 0x39, 0xae, 0x67, 0x29, 0x59, 0x69, 0xbf, 0xd3, - 0x6e, 0x1d, 0xd7, 0x73, 0x68, 0x19, 0x6a, 0xbc, 0xad, 0xee, 0x1e, 0x28, 0xef, 0x6e, 0x1f, 0xd7, - 0xf3, 0x11, 0xd2, 0x51, 0x7b, 0xff, 0x4e, 0x5b, 0xa9, 0x17, 0xe4, 0x57, 0x68, 0x22, 0x98, 0x02, - 0x03, 0xc3, 0x94, 0x4f, 0x8a, 0xa4, 0x7c, 0xf2, 0xef, 0xb3, 0xd0, 0x4c, 0x87, 0x76, 0xe8, 0xee, - 0xd8, 0xce, 0x6f, 0x5d, 0x04, 0x18, 0x8e, 0x6d, 0x1f, 0xbd, 0x00, 0x8b, 0x2e, 0x3e, 0xc5, 0x44, - 0xef, 0x71, 0xb0, 0xc9, 0x9f, 0x57, 0x4d, 0xa9, 0x09, 0x2a, 0x13, 0xf2, 0x38, 0xdb, 0xcf, 0xb1, - 0x4e, 0x54, 0x9e, 0x7e, 0xf2, 0x97, 0x53, 0xa1, 0x6c, 0x94, 0x7a, 0xc4, 0x89, 0xf2, 0xc3, 0x0b, - 0x1d, 0x66, 0x05, 0x0a, 0x4a, 0xfb, 0x58, 0xf9, 0xa0, 0x9e, 0x43, 0x08, 0x16, 0x59, 0x53, 0x3d, - 0xda, 0xdf, 0x3e, 0x3c, 0xea, 0x1c, 0xd0, 0xc3, 0xbc, 0x04, 0x4b, 0xfe, 0x61, 0xfa, 0xc4, 0x82, - 0xfc, 0xab, 0x2c, 0x2c, 0x8d, 0xbd, 0x1f, 0x74, 0x0b, 0x0a, 0x1c, 0xce, 0x4a, 0x69, 0x9f, 0x41, - 0xd8, 0x8d, 0x16, 0xaf, 0x8d, 0xf3, 0xa2, 0x1f, 0x41, 0x19, 0x8b, 0x9a, 0x46, 0x52, 0x51, 0x8b, - 0x57, 0x63, 0xfc, 0xaa, 0x87, 0x10, 0x0d, 0x24, 0xd0, 0x4f, 0xa1, 0x12, 0xb8, 0x82, 0xa4, 0x3a, - 0x23, 0x17, 0x0f, 0x9c, 0x88, 0x90, 0x0f, 0x65, 0xd0, 0x1b, 0x21, 0x52, 0xcd, 0x4f, 0x66, 0x8f, - 0x42, 0x9c, 0x33, 0x08, 0x61, 0x9f, 0x5f, 0x6e, 0x41, 0x35, 0xb2, 0x1f, 0xf4, 0x2c, 0x54, 0x06, - 0xda, 0xb9, 0x28, 0x2e, 0xf2, 0x1a, 0x54, 0x79, 0xa0, 0x9d, 0xb3, 0xba, 0x22, 0x7a, 0x1a, 0x4a, - 0x74, 0xb0, 0xab, 0x79, 0x6c, 0x93, 0x39, 0xa5, 0x38, 0xd0, 0xce, 0xdf, 0xd6, 0x3c, 0xf9, 0x63, - 0x58, 0x8c, 0x17, 0x8a, 0xe8, 0x5d, 0x74, 0xed, 0xa1, 0x65, 0x30, 0x1d, 0x05, 0x85, 0x77, 0xd0, - 0x6d, 0x28, 0x9c, 0xd9, 0x54, 0x73, 0x36, 0xed, 0xd9, 0xde, 0xb7, 0x09, 0x8e, 0x54, 0x9a, 0x38, - 0xbb, 0xbc, 0x0f, 0x8b, 0xcc, 0x39, 0x6d, 0x13, 0xe2, 0x9a, 0x27, 0x43, 0x82, 0xa3, 0x35, 0xe3, - 0x85, 0x84, 0x9a, 0x71, 0x80, 0xd3, 0x02, 0x94, 0x97, 0xe3, 0xa5, 0x4b, 0xd6, 0x91, 0x7f, 0x09, - 0x05, 0xa6, 0x8f, 0xba, 0x25, 0x56, 0xcb, 0x13, 0xb0, 0x9f, 0xb6, 0xd1, 0xc7, 0x00, 0x9a, 0x3f, - 0x8f, 0xbf, 0xd2, 0xf5, 0x14, 0x6f, 0x19, 0x2c, 0x68, 0xe7, 0x8a, 0x70, 0x9b, 0x2b, 0xa1, 0x6c, - 0xc4, 0x75, 0x46, 0x34, 0xca, 0xbf, 0x93, 0xa0, 0x7c, 0x7c, 0x2e, 0x6e, 0x76, 0x5a, 0xc1, 0x2f, - 0x58, 0x77, 0x36, 0x5a, 0xd4, 0xe1, 0xa5, 0xc8, 0x5c, 0x50, 0x8a, 0xdc, 0x0e, 0x1e, 0x6f, 0x7e, - 0x56, 0xd5, 0x21, 0x08, 0x63, 0x7e, 0x35, 0x50, 0x78, 0xac, 0xb7, 0xa0, 0x12, 0x5c, 0x2c, 0x9a, - 0xf1, 0x68, 0x86, 0xe1, 0x62, 0xcf, 0x13, 0x27, 0xeb, 0x77, 0x59, 0x09, 0xd8, 0x7e, 0x2c, 0xea, - 0x46, 0x39, 0x85, 0x77, 0x64, 0x03, 0x96, 0xc6, 0x42, 0x1b, 0x7a, 0x0b, 0x4a, 0xce, 0xf0, 0x44, - 0xf5, 0x8d, 0x53, 0xdd, 0xba, 0x92, 0x04, 0x8b, 0x87, 0x27, 0x7d, 0x53, 0xbf, 0x8b, 0x47, 0xfe, - 0x62, 0x9c, 0xe1, 0xc9, 0x5d, 0x6e, 0x43, 0x3e, 0x4b, 0x36, 0x3a, 0xcb, 0x63, 0x28, 0xfb, 0xd7, - 0x22, 0xfe, 0x54, 0xa4, 0x49, 0xdc, 0x3d, 0x16, 0x6f, 0x85, 0xfe, 0xc8, 0x53, 0xb9, 0x01, 0xcb, - 0x9e, 0xd9, 0xb5, 0xb0, 0xa1, 0x86, 0x49, 0x17, 0x9b, 0xae, 0xac, 0x2c, 0xf1, 0x81, 0x7b, 0x7e, - 0xc6, 0x25, 0x7f, 0x23, 0x41, 0xd9, 0x7f, 0xb4, 0x89, 0x57, 0x25, 0xb6, 0x9a, 0xec, 0x13, 0xac, - 0x26, 0xad, 0xe2, 0xee, 0x7f, 0xd5, 0xc8, 0x5f, 0xf8, 0xab, 0xc6, 0x4d, 0x40, 0xc4, 0x26, 0x5a, - 0x5f, 0x3d, 0xb3, 0x89, 0x69, 0x75, 0x55, 0x7e, 0x9e, 0x1c, 0x01, 0xd6, 0xd9, 0xc8, 0x7d, 0x36, - 0x70, 0xc8, 0x8e, 0xf6, 0xd7, 0x12, 0x94, 0x83, 0x20, 0x78, 0xd1, 0x5a, 0xe5, 0x65, 0x28, 0x0a, - 0x2f, 0xcf, 0x8b, 0x95, 0xa2, 0x17, 0x24, 0x18, 0xf9, 0x48, 0x82, 0xd1, 0x84, 0xf2, 0x00, 0x13, - 0x8d, 0xe1, 0x3b, 0x9e, 0xd9, 0x06, 0xfd, 0x1b, 0x6f, 0x40, 0x35, 0x52, 0x32, 0xa7, 0x4f, 0x7b, - 0xbf, 0xfd, 0xa0, 0x9e, 0x69, 0x96, 0x3e, 0xfd, 0x7c, 0x3d, 0xb7, 0x8f, 0x1f, 0xd3, 0x6b, 0xa9, - 0xb4, 0x5b, 0x9d, 0x76, 0xeb, 0x6e, 0x5d, 0x6a, 0x56, 0x3f, 0xfd, 0x7c, 0xbd, 0xa4, 0x60, 0x56, - 0xec, 0xd9, 0xfa, 0x0b, 0xc0, 0xd2, 0xf6, 0x4e, 0x6b, 0x8f, 0x86, 0x26, 0x53, 0xd7, 0x58, 0x2e, - 0xdc, 0x86, 0x3c, 0x2b, 0x07, 0x4c, 0xff, 0x5a, 0xde, 0x9c, 0x51, 0x92, 0x44, 0x1d, 0x28, 0xb0, - 0x5a, 0x01, 0x9a, 0xf1, 0xfd, 0xbc, 0x39, 0xab, 0x48, 0x49, 0x17, 0xc4, 0xee, 0xee, 0xf4, 0x2f, - 0xea, 0xcd, 0x19, 0x45, 0x4b, 0x74, 0x0c, 0x95, 0x30, 0xe1, 0x9f, 0xe3, 0x13, 0x7b, 0x73, 0x9e, - 0x4a, 0x26, 0xda, 0x87, 0x92, 0x9f, 0xa5, 0xcd, 0xfc, 0xec, 0xdd, 0x9c, 0x5d, 0x58, 0xa4, 0xc7, - 0xc6, 0x33, 0xf3, 0x19, 0xdf, 0xdf, 0x9b, 0xb3, 0x0a, 0x9c, 0x14, 0x99, 0x88, 0xc4, 0x60, 0xd6, - 0xc7, 0xeb, 0xe6, 0xcc, 0x92, 0x25, 0xfa, 0x10, 0xaa, 0xd1, 0xb4, 0x79, 0xae, 0x8f, 0xad, 0xcd, - 0xf9, 0x4a, 0x59, 0xd4, 0x30, 0x61, 0xe5, 0x64, 0x8e, 0xdf, 0x16, 0x9a, 0xf3, 0x14, 0x87, 0xd1, - 0x47, 0xb0, 0x10, 0xcb, 0x65, 0xe6, 0xfb, 0xa1, 0xa0, 0x39, 0x67, 0xe9, 0x15, 0x3d, 0x00, 0x88, - 0xc0, 0xf3, 0x79, 0xfe, 0x30, 0x68, 0xce, 0x55, 0x88, 0x45, 0x0f, 0xa1, 0x16, 0xc7, 0xeb, 0x73, - 0xfe, 0x37, 0xd0, 0x9c, 0xb7, 0x36, 0x4b, 0x67, 0x88, 0xa3, 0xf7, 0x39, 0x7f, 0x24, 0x68, 0xce, - 0x5b, 0xab, 0x45, 0x7d, 0x58, 0x9e, 0x84, 0xd7, 0x17, 0xf8, 0xb1, 0xa0, 0x79, 0x91, 0xf2, 0x2d, - 0xb2, 0x01, 0x25, 0x00, 0xf3, 0x8b, 0xfc, 0x68, 0xd0, 0xbc, 0x50, 0x39, 0x77, 0x67, 0xf7, 0xcb, - 0x6f, 0x57, 0xa5, 0xaf, 0xbe, 0x5d, 0x95, 0xfe, 0xf9, 0xed, 0xaa, 0xf4, 0xd9, 0x77, 0xab, 0x99, - 0xaf, 0xbe, 0x5b, 0xcd, 0xfc, 0xe3, 0xbb, 0xd5, 0xcc, 0x87, 0x37, 0xbb, 0x26, 0xe9, 0x0d, 0x4f, - 0x36, 0x74, 0x7b, 0xb0, 0x19, 0xfd, 0xb9, 0x29, 0xf1, 0x97, 0xab, 0x93, 0x22, 0x8b, 0x47, 0xb7, - 0xfe, 0x13, 0x00, 0x00, 0xff, 0xff, 0x9b, 0x4c, 0x6d, 0x38, 0x93, 0x25, 0x00, 0x00, + 0x92, 0x4b, 0x2a, 0x95, 0xaa, 0x54, 0x39, 0x17, 0x5f, 0x73, 0x70, 0x2e, 0xa9, 0x4a, 0xaa, 0x72, + 0x4a, 0x39, 0x97, 0xdc, 0x72, 0xf5, 0xd1, 0x55, 0xb9, 0xe4, 0x64, 0xa7, 0xec, 0x5b, 0xfe, 0x81, + 0x5c, 0x53, 0xf3, 0xd8, 0x17, 0xb0, 0x0b, 0x80, 0xb6, 0x7c, 0x4a, 0x6e, 0x33, 0x3d, 0xdd, 0xbd, + 0x33, 0xd3, 0x33, 0xdd, 0xbf, 0xee, 0x1d, 0xb8, 0x44, 0xb0, 0x65, 0x60, 0x77, 0x60, 0x5a, 0x64, + 0x53, 0x3b, 0xd6, 0xcd, 0xb3, 0x4d, 0x32, 0x72, 0xb0, 0xb7, 0xe1, 0xb8, 0x36, 0xb1, 0x51, 0x3d, + 0x1c, 0xdd, 0x60, 0xa3, 0xcd, 0xcb, 0x11, 0x7e, 0xdd, 0x1d, 0x39, 0xc4, 0xde, 0x74, 0x5c, 0xdb, + 0x3e, 0xe1, 0x02, 0xcd, 0xa8, 0x3a, 0xa6, 0x28, 0xaa, 0x2e, 0x36, 0x2a, 0x84, 0x1f, 0xe2, 0x91, + 0x3f, 0x7a, 0x79, 0x42, 0xd6, 0xd1, 0x5c, 0x6d, 0xe0, 0x0f, 0xaf, 0x75, 0x6d, 0xbb, 0xdb, 0xc7, + 0x9b, 0xac, 0x77, 0x3c, 0x3c, 0xd9, 0x24, 0xe6, 0x00, 0x7b, 0x44, 0x1b, 0x38, 0x82, 0x61, 0xa5, + 0x6b, 0x77, 0x6d, 0xd6, 0xdc, 0xa4, 0x2d, 0x4e, 0x95, 0x3f, 0x2b, 0x43, 0x49, 0xc1, 0x1f, 0x0d, + 0xb1, 0x47, 0xd0, 0x0d, 0xc8, 0x63, 0xbd, 0x67, 0x37, 0xb2, 0xeb, 0xd2, 0xd5, 0xea, 0xd6, 0xe5, + 0x8d, 0xf1, 0xd5, 0x6d, 0x08, 0xc6, 0xb6, 0xde, 0xb3, 0x3b, 0x19, 0x85, 0x31, 0xa3, 0x9b, 0x50, + 0x38, 0xe9, 0x0f, 0xbd, 0x5e, 0x23, 0xc7, 0xa4, 0x56, 0x53, 0xa5, 0x6e, 0x53, 0xae, 0x4e, 0x46, + 0xe1, 0xec, 0xf4, 0x63, 0xa6, 0x75, 0x62, 0x37, 0xf2, 0x33, 0x3e, 0xb6, 0x6b, 0x9d, 0xb0, 0x8f, + 0x51, 0x66, 0xd4, 0x02, 0xf0, 0x30, 0x51, 0x6d, 0x87, 0x98, 0xb6, 0xd5, 0x28, 0x30, 0x51, 0x39, + 0x55, 0xf4, 0x10, 0x93, 0x7d, 0xc6, 0xd9, 0xc9, 0x28, 0x15, 0xcf, 0xef, 0x50, 0x25, 0xa6, 0x65, + 0x12, 0x55, 0xef, 0x69, 0xa6, 0xd5, 0x28, 0xce, 0x50, 0xb2, 0x6b, 0x99, 0xa4, 0x45, 0x39, 0xa9, + 0x12, 0xd3, 0xef, 0xd0, 0x65, 0x7f, 0x34, 0xc4, 0xee, 0xa8, 0x51, 0x9a, 0xb1, 0xec, 0x77, 0x28, + 0x17, 0x5d, 0x36, 0x63, 0x47, 0x3f, 0x84, 0xb2, 0xde, 0xc3, 0xfa, 0x43, 0x95, 0x9c, 0x35, 0x2a, + 0x4c, 0x74, 0x3d, 0x55, 0xb4, 0x45, 0x19, 0x8f, 0xce, 0x3a, 0x19, 0xa5, 0xa4, 0xf3, 0x26, 0xba, + 0x0b, 0x35, 0x03, 0xf7, 0xcd, 0x53, 0xec, 0xaa, 0xc7, 0x7d, 0x5b, 0x7f, 0xd8, 0x58, 0x61, 0x3a, + 0x9e, 0x4b, 0xd5, 0x71, 0x8b, 0x73, 0xef, 0x50, 0xe6, 0x4e, 0x46, 0x59, 0x30, 0x22, 0x7d, 0x74, + 0x1b, 0xaa, 0x7c, 0x32, 0x5c, 0xd7, 0x13, 0x4c, 0xd7, 0x95, 0xe9, 0xf3, 0xf1, 0x35, 0x81, 0x1e, + 0xf4, 0xd0, 0x6b, 0x50, 0xd4, 0xed, 0xc1, 0xc0, 0x24, 0x8d, 0x05, 0xa6, 0x62, 0x2d, 0x5d, 0x05, + 0x63, 0xeb, 0x64, 0x14, 0x21, 0x80, 0xf6, 0x61, 0xb1, 0x6f, 0x7a, 0x44, 0xf5, 0x2c, 0xcd, 0xf1, + 0x7a, 0x36, 0xf1, 0x1a, 0x35, 0xa6, 0xe2, 0xf9, 0x54, 0x15, 0x77, 0x4d, 0x8f, 0x1c, 0xfa, 0xdc, + 0x9d, 0x8c, 0x52, 0xeb, 0x47, 0x09, 0x54, 0xa1, 0x7d, 0x72, 0x82, 0xdd, 0x40, 0x63, 0x63, 0x71, + 0x86, 0xc2, 0x7d, 0xca, 0xee, 0x2b, 0xa0, 0x0a, 0xed, 0x28, 0x01, 0xfd, 0x04, 0x2e, 0xf4, 0x6d, + 0xcd, 0x08, 0xf4, 0xa9, 0x7a, 0x6f, 0x68, 0x3d, 0x6c, 0x2c, 0x31, 0xad, 0xd7, 0xd2, 0xa7, 0x69, + 0x6b, 0x86, 0xaf, 0xa3, 0x45, 0x25, 0x3a, 0x19, 0x65, 0xb9, 0x3f, 0x4e, 0x44, 0x2a, 0xac, 0x68, + 0x8e, 0xd3, 0x1f, 0x8d, 0xab, 0xaf, 0x33, 0xf5, 0x2f, 0xa6, 0xaa, 0xdf, 0xa6, 0x42, 0xe3, 0xfa, + 0x91, 0x36, 0x41, 0x45, 0xbb, 0xb0, 0xa0, 0xbb, 0x58, 0x23, 0x58, 0x18, 0x79, 0x99, 0x29, 0x7e, + 0x36, 0xdd, 0x42, 0x8c, 0xd9, 0xb7, 0x72, 0x55, 0x0f, 0xbb, 0x3b, 0x25, 0x28, 0x9c, 0x6a, 0xfd, + 0x21, 0x96, 0x5f, 0x80, 0x6a, 0xc4, 0x15, 0xa0, 0x06, 0x94, 0x06, 0xd8, 0xf3, 0xb4, 0x2e, 0x6e, + 0x48, 0xeb, 0xd2, 0xd5, 0x8a, 0xe2, 0x77, 0xe5, 0x45, 0x58, 0x88, 0xde, 0x7e, 0x79, 0x10, 0x08, + 0xd2, 0x6b, 0x4d, 0x05, 0x4f, 0xb1, 0xeb, 0xd1, 0xbb, 0x2c, 0x04, 0x45, 0x17, 0x5d, 0x81, 0x1a, + 0x9b, 0xae, 0xea, 0x8f, 0x53, 0x9f, 0x94, 0x57, 0x16, 0x18, 0xf1, 0x9e, 0x60, 0x5a, 0x83, 0xaa, + 0xb3, 0xe5, 0x04, 0x2c, 0x39, 0xc6, 0x02, 0xce, 0x96, 0x23, 0x18, 0xe4, 0xd7, 0xa1, 0x3e, 0xee, + 0x0a, 0x50, 0x1d, 0x72, 0x0f, 0xf1, 0x48, 0x7c, 0x8f, 0x36, 0xd1, 0x8a, 0x58, 0x16, 0xfb, 0x46, + 0x45, 0x11, 0x6b, 0xfc, 0x43, 0x36, 0x10, 0x0e, 0x5c, 0x00, 0x7a, 0x15, 0xf2, 0xd4, 0xad, 0x32, + 0xe9, 0xea, 0x56, 0x73, 0x83, 0xfb, 0xdc, 0x0d, 0xdf, 0xe7, 0x6e, 0x1c, 0xf9, 0x3e, 0x77, 0xa7, + 0xfc, 0xf9, 0x97, 0x6b, 0x99, 0x4f, 0xbe, 0x5a, 0x93, 0x14, 0x26, 0x81, 0x9e, 0xa2, 0xf7, 0x5e, + 0x33, 0x2d, 0xd5, 0x34, 0xc4, 0x77, 0x4a, 0xac, 0xbf, 0x6b, 0xa0, 0xbb, 0x50, 0xd7, 0x6d, 0xcb, + 0xc3, 0x96, 0x37, 0xf4, 0x54, 0xee, 0xd3, 0x85, 0x33, 0x7d, 0x66, 0xd2, 0x4a, 0x2d, 0x9f, 0xf3, + 0x80, 0x31, 0x2a, 0x4b, 0x7a, 0x9c, 0x80, 0xde, 0x04, 0x38, 0xd5, 0xfa, 0xa6, 0xa1, 0x11, 0xdb, + 0xf5, 0x1a, 0xf9, 0xf5, 0x5c, 0xb2, 0x9e, 0x7b, 0x3e, 0xcf, 0xbb, 0x8e, 0x41, 0x0d, 0x9c, 0xa7, + 0xf3, 0x55, 0x22, 0xa2, 0xe8, 0x79, 0x58, 0xd2, 0x1c, 0x47, 0xf5, 0x08, 0x3b, 0x3b, 0x23, 0x82, + 0x3d, 0xe6, 0x70, 0x17, 0x94, 0x9a, 0xe6, 0x38, 0x87, 0x94, 0xba, 0x43, 0x89, 0xb2, 0x11, 0xd8, + 0x98, 0xb9, 0x3a, 0x84, 0x20, 0x6f, 0x68, 0x44, 0x63, 0x7b, 0xb4, 0xa0, 0xb0, 0x36, 0xa5, 0x39, + 0x1a, 0xe9, 0x89, 0x95, 0xb3, 0x36, 0xba, 0x08, 0xc5, 0x1e, 0x36, 0xbb, 0x3d, 0xc2, 0x16, 0x9b, + 0x53, 0x44, 0x8f, 0x9a, 0xc3, 0x71, 0xed, 0x53, 0xcc, 0x22, 0x43, 0x59, 0xe1, 0x1d, 0xf9, 0xef, + 0x12, 0xa0, 0xc9, 0x13, 0x1a, 0x51, 0x22, 0xc5, 0x94, 0x1c, 0x40, 0xbd, 0xaf, 0x79, 0x44, 0xe5, + 0x5e, 0x46, 0x65, 0x91, 0x26, 0x9b, 0xe6, 0x6e, 0xef, 0x6a, 0xbe, 0x63, 0xa2, 0xa7, 0x52, 0x6c, + 0xc5, 0x62, 0x3f, 0x46, 0x45, 0x87, 0xb0, 0x72, 0x3c, 0xfa, 0x99, 0x66, 0x11, 0xd3, 0xc2, 0x6a, + 0x64, 0x87, 0x73, 0x6c, 0x87, 0x9b, 0x93, 0x5a, 0xdb, 0xa7, 0xa6, 0x81, 0x2d, 0xdd, 0xdf, 0xda, + 0x0b, 0x81, 0x74, 0xb0, 0xf5, 0x9e, 0x7c, 0x08, 0x8b, 0x71, 0x5f, 0x8f, 0x16, 0x21, 0x4b, 0xce, + 0xc4, 0xde, 0x65, 0xc9, 0x19, 0x7a, 0x09, 0xf2, 0x34, 0xd8, 0xb3, 0xc9, 0x2f, 0x26, 0x85, 0x49, + 0x21, 0x78, 0x34, 0x72, 0xb0, 0xc2, 0x58, 0xe5, 0x25, 0xa8, 0xc5, 0xbc, 0xad, 0xfc, 0x59, 0x16, + 0x2e, 0x24, 0x84, 0x83, 0xd4, 0xcd, 0x43, 0x90, 0xef, 0x69, 0x1e, 0xb7, 0xd6, 0x82, 0xc2, 0xda, + 0xe8, 0x26, 0xe5, 0xd5, 0x0c, 0xec, 0x8a, 0xa3, 0xd9, 0x88, 0xce, 0x84, 0x83, 0x98, 0x0e, 0x1b, + 0x17, 0xcb, 0x15, 0xdc, 0x89, 0x86, 0xc8, 0x7f, 0x2f, 0x86, 0x28, 0x7c, 0x07, 0x43, 0x50, 0xaf, + 0x40, 0xce, 0xbc, 0x46, 0x71, 0x3d, 0x77, 0x75, 0x41, 0xa1, 0x4d, 0xf9, 0xcf, 0x59, 0x58, 0x9e, + 0x88, 0x7b, 0xff, 0xdb, 0xb2, 0x69, 0x5b, 0x76, 0x11, 0x56, 0x92, 0x62, 0xb4, 0x6c, 0x06, 0xf4, + 0x58, 0xa8, 0x45, 0x37, 0xa1, 0x1c, 0x04, 0x69, 0xdf, 0xa3, 0x4e, 0x4c, 0xc5, 0xe7, 0x56, 0x02, + 0x5e, 0xea, 0x4b, 0xa9, 0x67, 0x8a, 0x6c, 0x78, 0x49, 0x73, 0x9c, 0x8e, 0xe6, 0xf5, 0xe4, 0x07, + 0xd0, 0x48, 0x8b, 0xbf, 0x63, 0xb6, 0xcb, 0x07, 0xb6, 0xbb, 0x08, 0xc5, 0x13, 0xdb, 0x1d, 0x68, + 0x84, 0x29, 0xab, 0x29, 0xa2, 0x47, 0x1d, 0x11, 0x8f, 0xc5, 0x39, 0x46, 0xe6, 0x1d, 0x59, 0x85, + 0xa7, 0x52, 0x43, 0x30, 0x15, 0x31, 0x2d, 0x03, 0xf3, 0x0b, 0x5c, 0x53, 0x78, 0x27, 0x54, 0xc4, + 0x27, 0xcb, 0x3b, 0xf4, 0xb3, 0x1e, 0x5b, 0x2c, 0xd3, 0x5f, 0x51, 0x44, 0x4f, 0xfe, 0x75, 0x05, + 0xca, 0x0a, 0xf6, 0x1c, 0xea, 0xd7, 0x51, 0x0b, 0x2a, 0xf8, 0x4c, 0xc7, 0x1c, 0xef, 0x4a, 0xe9, + 0xf8, 0x8c, 0xb3, 0xb7, 0x7d, 0x56, 0x8a, 0x55, 0x03, 0x39, 0xf4, 0x72, 0x0c, 0xd7, 0xaf, 0x4e, + 0x91, 0x8f, 0x02, 0xfb, 0x57, 0xe2, 0xc0, 0x7e, 0x2d, 0x5d, 0x6c, 0x0c, 0xd9, 0xbf, 0x1c, 0x43, + 0xf6, 0x53, 0x3e, 0x17, 0x83, 0xf6, 0xb7, 0x12, 0xa0, 0xfd, 0x94, 0xa5, 0xa6, 0x60, 0xfb, 0x5b, + 0x09, 0xd8, 0xfe, 0xca, 0xb4, 0x19, 0x24, 0x82, 0xfb, 0x57, 0xe2, 0xe0, 0x7e, 0xca, 0xd2, 0xc7, + 0xd0, 0xfd, 0x8f, 0x26, 0xd0, 0xfd, 0x33, 0xe9, 0xb2, 0x09, 0xf0, 0xfe, 0xf5, 0x31, 0x20, 0xbd, + 0x3e, 0x45, 0x7a, 0x1c, 0x49, 0xbf, 0x9d, 0x9c, 0x1a, 0x3c, 0x9f, 0xae, 0x62, 0x6a, 0x6e, 0xf0, + 0x66, 0x52, 0x6e, 0xf0, 0xec, 0x8c, 0xd5, 0x24, 0x25, 0x07, 0x07, 0x29, 0x08, 0xff, 0x85, 0x74, + 0x5d, 0x33, 0x20, 0xfe, 0x41, 0x0a, 0xc4, 0x9f, 0xa2, 0x71, 0x06, 0xc6, 0xff, 0x60, 0x1a, 0xc6, + 0x7f, 0x71, 0xca, 0x44, 0xe7, 0x03, 0xf9, 0x0f, 0xa6, 0x82, 0xfc, 0xeb, 0xe9, 0xfa, 0xe7, 0x46, + 0xf9, 0x6f, 0x25, 0xa2, 0xfc, 0xe7, 0xa6, 0x98, 0x6b, 0x0e, 0x98, 0xff, 0x7f, 0x34, 0x02, 0x8e, + 0x79, 0x16, 0xea, 0xcc, 0xb0, 0xeb, 0xda, 0xae, 0x40, 0xd0, 0xbc, 0x23, 0x5f, 0xa5, 0x20, 0x30, + 0x74, 0x22, 0x53, 0x52, 0x02, 0x86, 0x4e, 0x22, 0x7e, 0x43, 0xfe, 0xab, 0x14, 0xca, 0xb2, 0x68, + 0x15, 0x05, 0x90, 0x15, 0x01, 0x20, 0x23, 0x99, 0x42, 0x36, 0x9e, 0x29, 0xac, 0x41, 0x95, 0x06, + 0x83, 0xb1, 0x24, 0x40, 0x73, 0xfc, 0x24, 0x00, 0x5d, 0x83, 0x65, 0x16, 0x4e, 0x79, 0x3e, 0x21, + 0x22, 0x40, 0x9e, 0x45, 0xef, 0x25, 0x3a, 0xc0, 0xf7, 0x80, 0x87, 0x82, 0xff, 0x87, 0x0b, 0x11, + 0xde, 0x20, 0xc8, 0x70, 0xdc, 0x5b, 0x0f, 0xb8, 0xb7, 0x45, 0xb4, 0x79, 0x3b, 0xdc, 0xa0, 0x30, + 0xc1, 0x40, 0x90, 0xd7, 0x6d, 0x03, 0x8b, 0x10, 0xc0, 0xda, 0x34, 0x56, 0xf6, 0xed, 0xae, 0x70, + 0xf4, 0xb4, 0x49, 0xb9, 0x02, 0x27, 0x59, 0xe1, 0x2e, 0x50, 0xfe, 0x93, 0x14, 0xea, 0x0b, 0x73, + 0x8e, 0xa4, 0xf4, 0x40, 0x7a, 0x4c, 0xe9, 0x41, 0xf6, 0x5b, 0xa7, 0x07, 0xf2, 0xbf, 0xa5, 0xd0, + 0x90, 0x01, 0xf0, 0xff, 0x76, 0x0b, 0x0f, 0xc3, 0x66, 0x81, 0x99, 0x45, 0x84, 0x4d, 0x91, 0xa9, + 0x15, 0xd9, 0xe6, 0xc7, 0x33, 0xb5, 0x12, 0x0f, 0xa4, 0xac, 0x83, 0x5e, 0x85, 0x0a, 0xab, 0xb1, + 0xa9, 0xb6, 0xe3, 0x35, 0xca, 0x6c, 0x67, 0x9e, 0x8e, 0xae, 0x88, 0x97, 0xd2, 0x36, 0x0e, 0x28, + 0xcf, 0xbe, 0xe3, 0x29, 0x65, 0x47, 0xb4, 0x22, 0x88, 0xa0, 0x12, 0x43, 0x73, 0x97, 0xa0, 0x42, + 0x67, 0xef, 0x39, 0x9a, 0x8e, 0x1b, 0xc0, 0x26, 0x1a, 0x12, 0xe4, 0x3f, 0x4a, 0x14, 0x4e, 0x4f, + 0x5c, 0x23, 0x1f, 0x10, 0x49, 0x01, 0x20, 0xa2, 0x67, 0xd3, 0xb4, 0xd8, 0x9e, 0xa9, 0x74, 0x24, + 0xcb, 0x46, 0x40, 0x90, 0x8e, 0xce, 0xbc, 0x00, 0x36, 0xe6, 0x22, 0xb0, 0x71, 0x17, 0x8a, 0xf8, + 0x14, 0x5b, 0xc4, 0x4f, 0xde, 0x9e, 0x4c, 0x82, 0x67, 0xd8, 0x22, 0x3b, 0x0d, 0x6a, 0x93, 0x7f, + 0x7d, 0xb9, 0x56, 0xe7, 0xec, 0xd7, 0xed, 0x81, 0x49, 0xf0, 0xc0, 0x21, 0x23, 0x45, 0x28, 0x90, + 0x7f, 0x97, 0x85, 0xa5, 0xb1, 0x68, 0x93, 0x68, 0x25, 0xff, 0xc6, 0x65, 0x23, 0x29, 0xdb, 0x7c, + 0x96, 0xbb, 0x0c, 0xd0, 0xd5, 0x3c, 0xf5, 0x91, 0x66, 0x11, 0x6c, 0x08, 0xf3, 0x55, 0xba, 0x9a, + 0x77, 0x9f, 0x11, 0x28, 0x52, 0xa3, 0xc3, 0x43, 0x0f, 0x1b, 0xcc, 0x8e, 0x39, 0xa5, 0xd4, 0xd5, + 0xbc, 0x77, 0x3d, 0x6c, 0x44, 0x96, 0x59, 0xfa, 0x8e, 0xcb, 0x8c, 0x9b, 0xab, 0x3c, 0x66, 0x2e, + 0xd4, 0x84, 0xb2, 0xe3, 0x9a, 0xb6, 0x6b, 0x92, 0x11, 0x33, 0x73, 0x5e, 0x09, 0xfa, 0xf2, 0xaf, + 0xb2, 0xe1, 0x8d, 0x13, 0xd1, 0xf0, 0xbf, 0x70, 0x8b, 0xe4, 0x5d, 0x9a, 0x86, 0x46, 0x61, 0x45, + 0xe2, 0x72, 0xaf, 0x40, 0xcd, 0xc5, 0x44, 0x33, 0x2d, 0x35, 0x96, 0xb7, 0x2f, 0x70, 0x22, 0xf7, + 0xa0, 0xf2, 0xc7, 0x39, 0x0a, 0xf6, 0x27, 0xf1, 0x45, 0xe2, 0xa6, 0xde, 0x82, 0xaa, 0x0f, 0x59, + 0xfc, 0xfb, 0x31, 0x15, 0xae, 0x05, 0x26, 0x52, 0xc0, 0xf0, 0x9b, 0x1e, 0x3a, 0x82, 0xe5, 0xc0, + 0x2f, 0xa9, 0x43, 0xe6, 0xaf, 0xfc, 0xb4, 0x7c, 0x6e, 0xcf, 0x56, 0x3f, 0x8d, 0x93, 0x3d, 0xf4, + 0x1e, 0x3c, 0x39, 0xe6, 0x76, 0x03, 0xdd, 0xf9, 0x79, 0xbd, 0xef, 0x13, 0x71, 0xef, 0xeb, 0xab, + 0x0e, 0xed, 0x5a, 0x78, 0xac, 0x76, 0x2d, 0x8e, 0xdb, 0xf5, 0xf7, 0x39, 0x40, 0x93, 0xf8, 0x2c, + 0xd1, 0x14, 0xe9, 0x39, 0xd5, 0xb8, 0x95, 0x72, 0x8f, 0xd1, 0x4a, 0xf9, 0xef, 0xd1, 0x4a, 0x85, + 0xc7, 0x66, 0xa5, 0xe2, 0x63, 0xb5, 0x52, 0x69, 0xdc, 0x4a, 0xef, 0xc0, 0x13, 0x89, 0xc0, 0x97, + 0x06, 0xb6, 0x10, 0x34, 0x4b, 0x69, 0xb9, 0x7a, 0x90, 0x20, 0x87, 0xcc, 0xf2, 0xdf, 0xa4, 0x50, + 0x67, 0x3c, 0xe7, 0xbe, 0x0d, 0x45, 0x17, 0x7b, 0xc3, 0x3e, 0x4f, 0x82, 0x17, 0xb7, 0x36, 0xe6, + 0xc4, 0xcc, 0x94, 0x3a, 0xec, 0x13, 0x45, 0x48, 0xcb, 0x1f, 0x42, 0x91, 0x53, 0x50, 0x15, 0x4a, + 0xef, 0xee, 0xdd, 0xd9, 0xdb, 0xbf, 0xbf, 0x57, 0xcf, 0x20, 0x80, 0xe2, 0x76, 0xab, 0xd5, 0x3e, + 0x38, 0xaa, 0x4b, 0xa8, 0x02, 0x85, 0xed, 0x9d, 0x7d, 0xe5, 0xa8, 0x9e, 0xa5, 0x64, 0xa5, 0xfd, + 0x56, 0xbb, 0x75, 0x54, 0xcf, 0xa1, 0x65, 0xa8, 0xf1, 0xb6, 0x7a, 0x7b, 0x5f, 0x79, 0x7b, 0xfb, + 0xa8, 0x9e, 0x8f, 0x90, 0x0e, 0xdb, 0x7b, 0xb7, 0xda, 0x4a, 0xbd, 0x20, 0xbf, 0x44, 0xd3, 0xec, + 0x14, 0x90, 0x1d, 0x26, 0xd4, 0x52, 0x24, 0xa1, 0x96, 0x7f, 0x9b, 0x85, 0x66, 0x3a, 0x70, 0x46, + 0x77, 0xc6, 0x56, 0x7e, 0xe3, 0x3c, 0xb0, 0x7b, 0x6c, 0xf9, 0xe8, 0x39, 0x58, 0x74, 0xf1, 0x09, + 0x26, 0x7a, 0x8f, 0x43, 0x79, 0xee, 0xbc, 0x6a, 0x4a, 0x4d, 0x50, 0x99, 0x90, 0xc7, 0xd9, 0x7e, + 0x8a, 0x75, 0xa2, 0xf2, 0xe4, 0x9e, 0xdf, 0x9e, 0x0a, 0x65, 0xa3, 0xd4, 0x43, 0x4e, 0x94, 0x1f, + 0x9c, 0x6b, 0x33, 0x2b, 0x50, 0x50, 0xda, 0x47, 0xca, 0x7b, 0xf5, 0x1c, 0x42, 0xb0, 0xc8, 0x9a, + 0xea, 0xe1, 0xde, 0xf6, 0xc1, 0x61, 0x67, 0x9f, 0x6e, 0xe6, 0x05, 0x58, 0xf2, 0x37, 0xd3, 0x27, + 0x16, 0xe4, 0x5f, 0x64, 0x61, 0x69, 0xec, 0xdc, 0xa3, 0x1b, 0x50, 0xe0, 0xc9, 0x82, 0x94, 0xf6, + 0x0b, 0x8e, 0xb9, 0x0b, 0x71, 0x4b, 0x38, 0x2f, 0xfa, 0x01, 0x94, 0xb1, 0x28, 0x0e, 0x25, 0x15, + 0x54, 0x79, 0x59, 0xcb, 0x2f, 0x1f, 0x09, 0xd1, 0x40, 0x02, 0xfd, 0x18, 0x2a, 0xc1, 0x15, 0x4e, + 0xaa, 0x71, 0x73, 0xf1, 0xe0, 0xf2, 0x0b, 0xf9, 0x50, 0x06, 0xbd, 0x16, 0xe6, 0x01, 0xf9, 0xc9, + 0xdc, 0x5c, 0x88, 0x73, 0x06, 0x21, 0xec, 0xf3, 0xcb, 0x2d, 0xa8, 0x46, 0xd6, 0x83, 0x9e, 0x86, + 0xca, 0x40, 0x3b, 0x13, 0x85, 0x6d, 0x5e, 0xcc, 0x2b, 0x0f, 0xb4, 0x33, 0x56, 0xd3, 0x46, 0x4f, + 0x42, 0x89, 0x0e, 0x76, 0x35, 0x8f, 0x2d, 0x32, 0xa7, 0x14, 0x07, 0xda, 0xd9, 0x9b, 0x9a, 0x27, + 0x7f, 0x08, 0x8b, 0xf1, 0x8a, 0x1b, 0x3d, 0x8b, 0xae, 0x3d, 0xb4, 0x0c, 0xa6, 0xa3, 0xa0, 0xf0, + 0x0e, 0xba, 0x09, 0x85, 0x53, 0x9b, 0x6a, 0xce, 0xa6, 0x5d, 0xdb, 0x7b, 0x36, 0xc1, 0x91, 0x92, + 0x1d, 0x67, 0x97, 0xf7, 0x60, 0x91, 0x39, 0x95, 0x6d, 0x42, 0x5c, 0xf3, 0x78, 0x48, 0x70, 0xf4, + 0x7f, 0xc5, 0x42, 0xc2, 0xff, 0x8a, 0x00, 0x05, 0x07, 0x18, 0x3a, 0xc7, 0xcb, 0xe6, 0xac, 0x23, + 0xff, 0x1c, 0x0a, 0x4c, 0x1f, 0xf5, 0xf9, 0xac, 0x8e, 0x2c, 0x92, 0x2a, 0xda, 0x46, 0x1f, 0x02, + 0x68, 0xfe, 0x77, 0xfc, 0x99, 0xae, 0xa7, 0x78, 0xb9, 0x60, 0x42, 0x3b, 0x97, 0x84, 0xbb, 0x5b, + 0x09, 0x65, 0x23, 0x2e, 0x2f, 0xa2, 0x51, 0xfe, 0x8d, 0x04, 0xe5, 0xa3, 0x33, 0x71, 0xb2, 0xd3, + 0x2a, 0xa7, 0xc1, 0xbc, 0xb3, 0xd1, 0x92, 0x19, 0x2f, 0x83, 0xe7, 0x82, 0x32, 0xf8, 0x76, 0x70, + 0x79, 0xf3, 0xb3, 0x6a, 0x3a, 0x41, 0xf8, 0xf1, 0xcb, 0xaa, 0xc2, 0x63, 0xbd, 0x01, 0x95, 0xe0, + 0x60, 0xd1, 0x7c, 0x52, 0x33, 0x0c, 0x17, 0x7b, 0x9e, 0xd8, 0x59, 0xbf, 0xcb, 0x7e, 0x3f, 0xd8, + 0x8f, 0x44, 0x55, 0x2e, 0xa7, 0xf0, 0x8e, 0x6c, 0xc0, 0xd2, 0x58, 0x48, 0x42, 0x6f, 0x40, 0xc9, + 0x19, 0x1e, 0xab, 0xbe, 0x71, 0xaa, 0x5b, 0x97, 0x92, 0x92, 0x8e, 0xe1, 0x71, 0xdf, 0xd4, 0xef, + 0xe0, 0x91, 0x3f, 0x19, 0x67, 0x78, 0x7c, 0x87, 0xdb, 0x90, 0x7f, 0x25, 0x1b, 0xfd, 0xca, 0x23, + 0x28, 0xfb, 0xc7, 0x22, 0x7e, 0x55, 0xa4, 0xc9, 0xac, 0x66, 0x2c, 0x4e, 0x0a, 0xfd, 0x91, 0xab, + 0x72, 0x0d, 0x96, 0x3d, 0xb3, 0x6b, 0x61, 0x43, 0x0d, 0x53, 0x5a, 0xf6, 0xb9, 0xb2, 0xb2, 0xc4, + 0x07, 0xee, 0xfa, 0xf9, 0xac, 0xfc, 0x95, 0x04, 0x65, 0xff, 0xd2, 0x26, 0x1e, 0x95, 0xd8, 0x6c, + 0xb2, 0xdf, 0x62, 0x36, 0x69, 0x7f, 0x7b, 0xfc, 0x3f, 0x6a, 0xf9, 0x73, 0xff, 0x51, 0xbb, 0x0e, + 0x88, 0xd8, 0x44, 0xeb, 0xab, 0xa7, 0x36, 0x31, 0xad, 0xae, 0xca, 0xf7, 0x93, 0xe3, 0xeb, 0x3a, + 0x1b, 0xb9, 0xc7, 0x06, 0x0e, 0xd8, 0xd6, 0xfe, 0x52, 0x82, 0x72, 0x10, 0x04, 0xcf, 0x5b, 0x09, + 0xbe, 0x08, 0x45, 0xe1, 0xe5, 0x79, 0x29, 0x58, 0xf4, 0x82, 0xf4, 0x2d, 0x1f, 0x49, 0xdf, 0x9a, + 0x50, 0x1e, 0x60, 0xa2, 0x31, 0xf4, 0xcc, 0xeb, 0x06, 0x41, 0xff, 0xda, 0x6b, 0x50, 0x8d, 0xfc, + 0xae, 0xa1, 0x57, 0x7b, 0xaf, 0x7d, 0xbf, 0x9e, 0x69, 0x96, 0x3e, 0xfe, 0x74, 0x3d, 0xb7, 0x87, + 0x1f, 0xd1, 0x63, 0xa9, 0xb4, 0x5b, 0x9d, 0x76, 0xeb, 0x4e, 0x5d, 0x6a, 0x56, 0x3f, 0xfe, 0x74, + 0xbd, 0xa4, 0x60, 0x56, 0x4a, 0xdb, 0xfa, 0x0b, 0xc0, 0xd2, 0xf6, 0x4e, 0x6b, 0x97, 0x86, 0x26, + 0x53, 0xd7, 0x58, 0xa5, 0xa1, 0x0d, 0x79, 0x56, 0x6c, 0x99, 0xfe, 0x52, 0xa3, 0x39, 0xa3, 0xe0, + 0x8b, 0x3a, 0x50, 0x60, 0x95, 0x18, 0x34, 0xe3, 0xed, 0x46, 0x73, 0x56, 0x09, 0x98, 0x4e, 0x88, + 0x9d, 0xdd, 0xe9, 0xaf, 0x39, 0x9a, 0x33, 0x4a, 0xc2, 0xe8, 0x08, 0x2a, 0x61, 0x39, 0x65, 0x8e, + 0xe7, 0x1d, 0xcd, 0x79, 0xea, 0xc4, 0x68, 0x0f, 0x4a, 0x7e, 0x0e, 0x3c, 0xf3, 0xc9, 0x45, 0x73, + 0x76, 0xd9, 0x96, 0x6e, 0x1b, 0xaf, 0x7b, 0xcc, 0x78, 0xfb, 0xd1, 0x9c, 0x55, 0x3e, 0xa6, 0xc8, + 0x44, 0xa4, 0x5d, 0xb3, 0x1e, 0x4e, 0x34, 0x67, 0x16, 0x84, 0xd1, 0xfb, 0x50, 0x8d, 0x16, 0x25, + 0xe6, 0xfa, 0xd1, 0xdf, 0x9c, 0xaf, 0x50, 0x48, 0x0d, 0x13, 0xd6, 0xa5, 0xe6, 0x78, 0x32, 0xd3, + 0x9c, 0xa7, 0xf4, 0x8e, 0x3e, 0x80, 0x85, 0x58, 0xa6, 0x38, 0xdf, 0x63, 0x96, 0xe6, 0x9c, 0x85, + 0x6d, 0x74, 0x1f, 0x20, 0x92, 0xfb, 0xcc, 0xf3, 0xba, 0xa5, 0x39, 0x57, 0x99, 0x1b, 0x3d, 0x80, + 0x5a, 0x1c, 0xaf, 0xcf, 0xf9, 0x66, 0xa5, 0x39, 0x6f, 0xe5, 0x9b, 0x7e, 0x21, 0x8e, 0xde, 0xe7, + 0x7c, 0xc4, 0xd2, 0x9c, 0xb7, 0x12, 0x8e, 0xfa, 0xb0, 0x3c, 0x09, 0xaf, 0xcf, 0xf1, 0xa8, 0xa5, + 0x79, 0x9e, 0xe2, 0x38, 0xb2, 0x01, 0x25, 0x00, 0xf3, 0xf3, 0x3c, 0x72, 0x69, 0x9e, 0xab, 0x58, + 0xbe, 0x73, 0xfb, 0xf3, 0xaf, 0x57, 0xa5, 0x2f, 0xbe, 0x5e, 0x95, 0xfe, 0xf9, 0xf5, 0xaa, 0xf4, + 0xc9, 0x37, 0xab, 0x99, 0x2f, 0xbe, 0x59, 0xcd, 0xfc, 0xe3, 0x9b, 0xd5, 0xcc, 0xfb, 0xd7, 0xbb, + 0x26, 0xe9, 0x0d, 0x8f, 0x37, 0x74, 0x7b, 0xb0, 0x19, 0x7d, 0x58, 0x97, 0xf8, 0xdc, 0xef, 0xb8, + 0xc8, 0xe2, 0xd1, 0x8d, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x55, 0x7c, 0xe4, 0x14, 0x0f, 0x28, + 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -4859,6 +4951,61 @@ func (m *RequestCheckBlock) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.Txs) > 0 { + for iNdEx := len(m.Txs) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Txs[iNdEx]) + copy(dAtA[i:], m.Txs[iNdEx]) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Txs[iNdEx]))) + i-- + dAtA[i] = 0x32 + } + } + if len(m.ByzantineValidators) > 0 { + for iNdEx := len(m.ByzantineValidators) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ByzantineValidators[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } + { + size, err := m.LastCommitInfo.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + { + size, err := m.Header.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + if len(m.Hash) > 0 { + i -= len(m.Hash) + copy(dAtA[i:], m.Hash) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Hash))) + i-- + dAtA[i] = 0x12 + } + if m.Height != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Height)) + i-- + dAtA[i] = 0x8 + } return len(dAtA) - i, nil } @@ -6072,6 +6219,67 @@ func (m *ResponseCheckBlock) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.Codespace) i = encodeVarintTypes(dAtA, i, uint64(len(m.Codespace))) i-- + dAtA[i] = 0x3a + } + if len(m.Events) > 0 { + for iNdEx := len(m.Events) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Events[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + } + if m.ConsensusParamUpdates != nil { + { + size, err := m.ConsensusParamUpdates.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + if len(m.ValidatorUpdates) > 0 { + for iNdEx := len(m.ValidatorUpdates) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ValidatorUpdates[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if len(m.DeliverTxs) > 0 { + for iNdEx := len(m.DeliverTxs) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.DeliverTxs[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.AppHash) > 0 { + i -= len(m.AppHash) + copy(dAtA[i:], m.AppHash) + i = encodeVarintTypes(dAtA, i, uint64(len(m.AppHash))) + i-- dAtA[i] = 0x12 } if m.Code != 0 { @@ -6207,20 +6415,20 @@ func (m *ResponseApplySnapshotChunk) MarshalToSizedBuffer(dAtA []byte) (int, err } } if len(m.RefetchChunks) > 0 { - dAtA42 := make([]byte, len(m.RefetchChunks)*10) - var j41 int + dAtA45 := make([]byte, len(m.RefetchChunks)*10) + var j44 int for _, num := range m.RefetchChunks { for num >= 1<<7 { - dAtA42[j41] = uint8(uint64(num)&0x7f | 0x80) + dAtA45[j44] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j41++ + j44++ } - dAtA42[j41] = uint8(num) - j41++ + dAtA45[j44] = uint8(num) + j44++ } - i -= j41 - copy(dAtA[i:], dAtA42[:j41]) - i = encodeVarintTypes(dAtA, i, uint64(j41)) + i -= j44 + copy(dAtA[i:], dAtA45[:j44]) + i = encodeVarintTypes(dAtA, i, uint64(j44)) i-- dAtA[i] = 0x12 } @@ -6660,12 +6868,12 @@ func (m *Evidence) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x28 } - n50, err50 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) - if err50 != nil { - return 0, err50 + n53, err53 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) + if err53 != nil { + return 0, err53 } - i -= n50 - i = encodeVarintTypes(dAtA, i, uint64(n50)) + i -= n53 + i = encodeVarintTypes(dAtA, i, uint64(n53)) i-- dAtA[i] = 0x22 if m.Height != 0 { @@ -7141,6 +7349,29 @@ func (m *RequestCheckBlock) Size() (n int) { } var l int _ = l + if m.Height != 0 { + n += 1 + sovTypes(uint64(m.Height)) + } + l = len(m.Hash) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = m.Header.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() + n += 1 + l + sovTypes(uint64(l)) + } + } + if len(m.Txs) > 0 { + for _, b := range m.Txs { + l = len(b) + n += 1 + l + sovTypes(uint64(l)) + } + } return n } @@ -7732,6 +7963,32 @@ func (m *ResponseCheckBlock) Size() (n int) { if m.Code != 0 { n += 1 + sovTypes(uint64(m.Code)) } + l = len(m.AppHash) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if len(m.DeliverTxs) > 0 { + for _, e := range m.DeliverTxs { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + if len(m.ValidatorUpdates) > 0 { + for _, e := range m.ValidatorUpdates { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + if m.ConsensusParamUpdates != nil { + l = m.ConsensusParamUpdates.Size() + n += 1 + l + sovTypes(uint64(l)) + } + if len(m.Events) > 0 { + for _, e := range m.Events { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } l = len(m.Codespace) if l > 0 { n += 1 + l + sovTypes(uint64(l)) @@ -9922,14 +10179,199 @@ func (m *RequestCheckBlock) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: RequestCheckBlock: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipTypes(dAtA[iNdEx:]) - if err != nil { - return err + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) } - if skippy < 0 { - return ErrInvalidLengthTypes + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Hash = append(m.Hash[:0], dAtA[iNdEx:postIndex]...) + if m.Hash == nil { + m.Hash = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LastCommitInfo", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.LastCommitInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ByzantineValidators", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ByzantineValidators = append(m.ByzantineValidators, Evidence{}) + if err := m.ByzantineValidators[len(m.ByzantineValidators)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Txs", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Txs = append(m.Txs, make([]byte, postIndex-iNdEx)) + copy(m.Txs[len(m.Txs)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes } if (iNdEx + skippy) < 0 { return ErrInvalidLengthTypes @@ -13113,6 +13555,178 @@ func (m *ResponseCheckBlock) Unmarshal(dAtA []byte) error { } } case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AppHash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AppHash = append(m.AppHash[:0], dAtA[iNdEx:postIndex]...) + if m.AppHash == nil { + m.AppHash = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DeliverTxs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DeliverTxs = append(m.DeliverTxs, &ResponseDeliverTx{}) + if err := m.DeliverTxs[len(m.DeliverTxs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorUpdates", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValidatorUpdates = append(m.ValidatorUpdates, ValidatorUpdate{}) + if err := m.ValidatorUpdates[len(m.ValidatorUpdates)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConsensusParamUpdates", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ConsensusParamUpdates == nil { + m.ConsensusParamUpdates = &ConsensusParams{} + } + if err := m.ConsensusParamUpdates.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Events", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Events = append(m.Events, Event{}) + if err := m.Events[len(m.Events)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Codespace", wireType) } diff --git a/consensus/common_test.go b/consensus/common_test.go index 1d605d25825..9f0ba2892a7 100644 --- a/consensus/common_test.go +++ b/consensus/common_test.go @@ -434,6 +434,24 @@ func randState(nValidators int) (*State, []*validatorStub) { return cs, vss } +func randStateShouldCheckBlockFail(nValidators int) (*State, []*validatorStub) { + // Get State + state, privVals := randGenesisState(nValidators, false, 10) + + vss := make([]*validatorStub, nValidators) + + badxApp := &badxApp{} + cs := newState(state, privVals[0], badxApp) + + for i := 0; i < nValidators; i++ { + vss[i] = newValidatorStub(privVals[i], int32(i)) + } + // since cs1 starts at 1 + incrementHeight(vss[1:]...) + + return cs, vss +} + func randStateWithEvpool(nValidators int) (*State, []*validatorStub, *evidence.Pool) { state, privVals := randGenesisState(nValidators, false, 10) @@ -681,6 +699,24 @@ func ensureVote(voteCh <-chan tmpubsub.Message, height int64, round int32, } } +func ensurePrevoteWithNilBlock(voteCh <-chan tmpubsub.Message) { + select { + case <-time.After(ensureTimeout): + panic("Timeout expired while waiting for NewVote event") + case msg := <-voteCh: + voteEvent, ok := msg.Data().(types.EventDataVote) + if !ok { + panic(fmt.Sprintf("expected a EventDataVote, got %T. Wrong subscription channel?", + msg.Data())) + } + + vote := voteEvent.Vote + if len(vote.BlockID.Hash) != 0 { + panic("Expect vote with nil block") + } + } +} + func ensurePrecommitTimeout(ch <-chan tmpubsub.Message) { select { case <-time.After(ensureTimeout): @@ -904,3 +940,14 @@ func newPersistentKVStore() abcix.Application { func newPersistentKVStoreWithPath(dbDir string) abcix.Application { return adapter.AdaptToABCIx(kvstore.NewPersistentKVStoreApplication(dbDir)) } + +//------------------------------------ +type badxApp struct { + abcix.BaseApplication +} + +func (app *badxApp) CheckBlock(req abcix.RequestCheckBlock) abcix.ResponseCheckBlock { + return abcix.ResponseCheckBlock{ + Code: 1, + } +} diff --git a/consensus/mempool_test.go b/consensus/mempool_test.go index e64268d6f3c..219ed7e72fc 100644 --- a/consensus/mempool_test.go +++ b/consensus/mempool_test.go @@ -290,6 +290,13 @@ func (app *CounterApplication) CheckTx(req abcix.RequestCheckTx) abcix.ResponseC return abcix.ResponseCheckTx{Code: code.CodeTypeOK} } +func (app *CounterApplication) CheckBlock(req abcix.RequestCheckBlock) abcix.ResponseCheckBlock { + return abcix.ResponseCheckBlock{ + //TODO: uncomment + //AppHash: req.Header.AppHash, + } +} + func txAsUint64(tx []byte) uint64 { tx8 := make([]byte, 8) copy(tx8[len(tx8)-len(tx):], tx) diff --git a/consensus/state.go b/consensus/state.go index 1445dd4790a..cb83fa2834e 100644 --- a/consensus/state.go +++ b/consensus/state.go @@ -1739,6 +1739,11 @@ func (cs *State) addProposalBlockPart(msg *BlockPartMessage, peerID p2p.ID) (add return added, err } + if err = cs.blockExec.CheckBlock(block); err != nil { + cs.Logger.Error("Error on CheckBlock", "err", err) + return false, err + } + cs.ProposalBlock = block // NOTE: it's possible to receive complete proposal blocks for future rounds without having the proposal cs.Logger.Info("Received complete proposal block", "height", cs.ProposalBlock.Height, "hash", cs.ProposalBlock.Hash()) diff --git a/consensus/state_test.go b/consensus/state_test.go index e495f1acf83..23f805f7202 100644 --- a/consensus/state_test.go +++ b/consensus/state_test.go @@ -1833,6 +1833,23 @@ func TestStateOutputVoteStats(t *testing.T) { } +func TestStateCheckBlockFail(t *testing.T) { + cs, _ := randStateShouldCheckBlockFail(1) + height, round := cs.Height, cs.Round + + cs.eventBus.Stop() + eventBus := types.NewEventBusWithBufferCapacity(0) + eventBus.SetLogger(log.TestingLogger().With("module", "events")) + cs.SetEventBus(eventBus) + eventBus.Start() + + voteCh := subscribeUnBuffered(cs.eventBus, types.EventQueryVote) + // start round and wait for propose and prevote + startTestRound(cs, height, round) + + ensurePrevoteWithNilBlock(voteCh) +} + // subscribe subscribes test client to the given query and returns a channel with cap = 1. func subscribe(eventBus *types.EventBus, q tmpubsub.Query) <-chan tmpubsub.Message { sub, err := eventBus.Subscribe(context.Background(), testSubscriber, q) diff --git a/proto/tendermint/abcix/types.proto b/proto/tendermint/abcix/types.proto index 4e514f6113c..290528740a6 100644 --- a/proto/tendermint/abcix/types.proto +++ b/proto/tendermint/abcix/types.proto @@ -101,6 +101,12 @@ message RequestDeliverBlock { } message RequestCheckBlock { + int64 height = 1; + bytes hash = 2; + tendermint.types.Header header = 3 [(gogoproto.nullable) = false]; + LastCommitInfo last_commit_info = 4 [(gogoproto.nullable) = false]; + repeated Evidence byzantine_validators = 5 [(gogoproto.nullable) = false]; + repeated bytes txs = 6; } // lists available snapshots @@ -250,8 +256,15 @@ message ResponseDeliverBlock { } message ResponseCheckBlock { - uint32 code = 1; - string codespace = 2; + uint32 code = 1; + bytes app_hash = 2; + repeated ResponseDeliverTx deliver_txs = 3; + repeated ValidatorUpdate validator_updates = 4 + [(gogoproto.nullable) = false]; + ConsensusParams consensus_param_updates = 5; + repeated Event events = 6 + [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; + string codespace = 7; } message ResponseListSnapshots { diff --git a/state/execution.go b/state/execution.go index 8b91e5f15e5..0b34368f2a0 100644 --- a/state/execution.go +++ b/state/execution.go @@ -1,9 +1,14 @@ package state import ( + "bytes" + "errors" "fmt" "time" + "github.com/tendermint/tendermint/crypto/merkle" + + "github.com/gogo/protobuf/proto" dbm "github.com/tendermint/tm-db" abcix "github.com/tendermint/tendermint/abcix/types" @@ -268,6 +273,60 @@ func (blockExec *BlockExecutor) Commit( return res.Data, res.RetainHeight, err } +func (blockExec *BlockExecutor) CheckBlock(block *types.Block) error { + commitInfo, byzVals := getBlockValidatorInfo( + block.Time, + block.Height, + block.LastCommit, + block.Evidence.Evidence, + blockExec.db, + ) + pbh := block.Header.ToProto() + txs := make([][]byte, 0, len(block.Txs)) + for _, tx := range block.Txs { + txs = append(txs, tx) + } + + resp, err := blockExec.proxyApp.CheckBlockSync(abcix.RequestCheckBlock{ + Height: block.Height, + Hash: block.Hash(), + Header: *pbh, + LastCommitInfo: commitInfo, + ByzantineValidators: byzVals, + Txs: txs, + }) + + if err != nil { + return err + } + if resp.Code != 0 { + return fmt.Errorf("application error during CheckBlock, code: %d", resp.Code) + } + for _, tx := range resp.DeliverTxs { + if tx.Code != 0 { + return fmt.Errorf("invalid transaction, code: %d", tx.Code) + } + } + resultHash := CheckBlockResponseResultHash(resp) + if !bytes.Equal(resultHash, block.Header.LastResultsHash.Bytes()) { + blockExec.logger.Error( + "resultHash mismatch. ResultHash in ResponseCheckBlock: %X\n ResultHash in block header: %X", + resultHash, block.Header.LastResultsHash, + ) + return errors.New("resultHash mismatch") + } + + if !bytes.Equal(resp.AppHash, block.Header.AppHash.Bytes()) { + blockExec.logger.Error( + "appHash mismatch. AppHash in ResponseCheckBlock: %X\n AppHash in block header: %X", + resp.AppHash, block.Header.AppHash, + ) + return errors.New("appHash mismatch") + } + + return err +} + //--------------------------------------------------------- // Helper functions for executing blocks and updating state @@ -523,3 +582,18 @@ func ExecCommitBlock( // ResponseCommit has no error or log, just data return res.Data, nil } + +func CheckBlockResponseResultHash(resp *abcix.ResponseCheckBlock) []byte { + cbeBytes, err := proto.Marshal(&abcix.ResponseCheckBlock{ + Events: resp.Events, + }) + if err != nil { + panic(err) + } + + // Build a Merkle tree of proto-encoded DeliverTx results and get a hash. + results := types.NewResults(resp.DeliverTxs) + + // Build a Merkle tree out of the above 3 binary slices. + return merkle.HashFromByteSlices([][]byte{cbeBytes, results.Hash()}) +} diff --git a/state/execution_test.go b/state/execution_test.go index 8c8c90c6bec..a46e8d9f7a5 100644 --- a/state/execution_test.go +++ b/state/execution_test.go @@ -467,3 +467,82 @@ func TestEndBlockValidatorUpdatesResultingInEmptySet(t *testing.T) { assert.NotNil(t, err) assert.NotEmpty(t, state.NextValidators.Validators) } + +func TestCheckBlockWithAppError(t *testing.T) { + app := &testApp{} + cc := proxy.NewLocalClientCreator(app) + proxyApp := proxy.NewAppConns(cc) + err := proxyApp.Start() + require.Nil(t, err) + defer proxyApp.Stop() //nolint:errcheck // ignore for tests + + state, stateDB, _ := makeState(1, 1) + blockExec := sm.NewBlockExecutor( + stateDB, + log.TestingLogger(), + proxyApp.Consensus(), + mock.Mempool{}, + sm.MockEvidencePool{}, + ) + + block := makeBlock(state, 1) + err = blockExec.CheckBlock(block) + assert.Error(t, err) +} + +func TestCheckBlockWithErrors(t *testing.T) { + app := &testApp{} + cc := proxy.NewLocalClientCreator(app) + proxyApp := proxy.NewAppConns(cc) + err := proxyApp.Start() + require.Nil(t, err) + defer proxyApp.Stop() //nolint:errcheck // ignore for tests + + state, stateDB, _ := makeState(2, 4) + blockExec := sm.NewBlockExecutor( + stateDB, + log.TestingLogger(), + proxyApp.Consensus(), + mock.Mempool{}, + sm.MockEvidencePool{}, + ) + + // block for height 1: Response with error code 1 + block1 := makeBlock(state, 1) + err = blockExec.CheckBlock(block1) + assert.EqualError(t, err, "application error during CheckBlock, code: 1") + + prevHash := state.LastBlockID.Hash + prevParts := types.PartSetHeader{} + prevBlockID := types.BlockID{Hash: prevHash, PartSetHeader: prevParts} + + var ( + now = tmtime.Now() + commitSig0 = types.NewCommitSigForBlock( + []byte("Signature1"), + state.Validators.Validators[0].Address, + now) + commitSig1 = types.NewCommitSigForBlock( + []byte("Signature2"), + state.Validators.Validators[1].Address, + now) + ) + + // block for height 2: Response with invalid tx + lastCommit1 := types.NewCommit(1, 0, prevBlockID, []types.CommitSig{commitSig0, commitSig1}) + block2, _ := state.MakeBlock(2, makeTxs(2), lastCommit1, nil, state.Validators.GetProposer().Address) + err = blockExec.CheckBlock(block2) + assert.EqualError(t, err, "invalid transaction, code: 1") + + // block for height 3: Response with mismatch ResultHash + lastCommit2 := types.NewCommit(2, 0, prevBlockID, []types.CommitSig{commitSig0, commitSig1}) + block3, _ := state.MakeBlock(3, makeTxs(3), lastCommit2, nil, state.Validators.GetProposer().Address) + err = blockExec.CheckBlock(block3) + assert.Contains(t, err.Error(), "resultHash") + + //// block for height 4: Response with mismatch AppHash + //lastCommit3 := types.NewCommit(3, 0, prevBlockID, []types.CommitSig{commitSig0, commitSig1}) + //block4, _ := state.MakeBlock(4, makeTxs(4), lastCommit3, nil, state.Validators.GetProposer().Address) + //err = blockExec.CheckBlock(block4) + //assert.Contains(t, err.Error(), "appHash") +} diff --git a/state/helpers_test.go b/state/helpers_test.go index 965bcb39b59..3cfb022fb52 100644 --- a/state/helpers_test.go +++ b/state/helpers_test.go @@ -267,6 +267,31 @@ func (app *testApp) Commit() abcix.ResponseCommit { return abcix.ResponseCommit{RetainHeight: 1} } +func (app *testApp) CheckBlock(req abcix.RequestCheckBlock) abcix.ResponseCheckBlock { + if req.Height == 1 { + return abcix.ResponseCheckBlock{ + Code: 1, + } + } + if req.Height == 2 { + return abcix.ResponseCheckBlock{ + DeliverTxs: []*abcix.ResponseDeliverTx{ + { + Code: 1, + }, + }, + } + } + //TODO: uncomment + //if req.Height == 4 { + // return abcix.ResponseCheckBlock{ + // AppHash: tmrand.Bytes(20), + // } + //} + + return abcix.ResponseCheckBlock{} +} + func (app *testApp) Query(reqQuery abcix.RequestQuery) (resQuery abcix.ResponseQuery) { return } diff --git a/state/validation_test.go b/state/validation_test.go index 087d8328cf1..619efecb3f0 100644 --- a/state/validation_test.go +++ b/state/validation_test.go @@ -68,7 +68,6 @@ func TestValidateBlockHeader(t *testing.T) { {"ConsensusHash wrong", func(block *types.Block) { block.ConsensusHash = wrongHash }}, {"AppHash wrong", func(block *types.Block) { block.AppHash = wrongHash }}, {"LastResultsHash wrong", func(block *types.Block) { block.LastResultsHash = wrongHash }}, - {"EvidenceHash wrong", func(block *types.Block) { block.EvidenceHash = wrongHash }}, {"Proposer wrong", func(block *types.Block) { block.ProposerAddress = ed25519.GenPrivKey().PubKey().Address() }}, {"Proposer invalid", func(block *types.Block) { block.ProposerAddress = []byte("wrong size") }},