diff --git a/docs/ibc/proto-docs.md b/docs/ibc/proto-docs.md index b098c732179..989a50d1c36 100644 --- a/docs/ibc/proto-docs.md +++ b/docs/ibc/proto-docs.md @@ -192,6 +192,18 @@ - [ibc/core/types/v1/genesis.proto](#ibc/core/types/v1/genesis.proto) - [GenesisState](#ibc.core.types.v1.GenesisState) +- [ibc/core/wasm/v1/query.proto](#ibc/core/wasm/v1/query.proto) + - [WasmCodeQuery](#ibc.core.wasm.v1.WasmCodeQuery) + - [WasmCodeResponse](#ibc.core.wasm.v1.WasmCodeResponse) + + - [Query](#ibc.core.wasm.v1.Query) + +- [ibc/core/wasm/v1/tx.proto](#ibc/core/wasm/v1/tx.proto) + - [MsgPushNewWasmCode](#ibc.core.wasm.v1.MsgPushNewWasmCode) + - [MsgPushNewWasmCodeResponse](#ibc.core.wasm.v1.MsgPushNewWasmCodeResponse) + + - [Msg](#ibc.core.wasm.v1.Msg) + - [ibc/lightclients/localhost/v1/localhost.proto](#ibc/lightclients/localhost/v1/localhost.proto) - [ClientState](#ibc.lightclients.localhost.v1.ClientState) @@ -222,6 +234,12 @@ - [Header](#ibc.lightclients.tendermint.v1.Header) - [Misbehaviour](#ibc.lightclients.tendermint.v1.Misbehaviour) +- [ibc/lightclients/wasm/v1/wasm.proto](#ibc/lightclients/wasm/v1/wasm.proto) + - [ClientState](#ibc.lightclients.wasm.v1.ClientState) + - [ConsensusState](#ibc.lightclients.wasm.v1.ConsensusState) + - [Header](#ibc.lightclients.wasm.v1.Header) + - [Misbehaviour](#ibc.lightclients.wasm.v1.Misbehaviour) + - [Scalar Value Types](#scalar-value-types) @@ -565,6 +583,7 @@ Params defines the set of IBC light client parameters. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | `allowed_clients` | [string](#string) | repeated | allowed_clients defines the list of allowed client state types. | +| `wasm_clients_enabled` | [bool](#bool) | | whether or not wasm clients are enabled | @@ -2889,6 +2908,119 @@ GenesisState defines the ibc module's genesis state. + +

Top

+ +## ibc/core/wasm/v1/query.proto + + + + + +### WasmCodeQuery +WasmCode query + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `code_id` | [string](#string) | | | + + + + + + + + +### WasmCodeResponse +WasmCode response + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `code` | [bytes](#bytes) | | | + + + + + + + + + + + + + + +### Query +Query service for wasm module + +| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | +| ----------- | ------------ | ------------- | ------------| ------- | -------- | +| `WasmCode` | [WasmCodeQuery](#ibc.core.wasm.v1.WasmCodeQuery) | [WasmCodeResponse](#ibc.core.wasm.v1.WasmCodeResponse) | Get Wasm code for given code id | GET|/ibc/core/wasm/v1beta1/code/{code_id}| + + + + + + +

Top

+ +## ibc/core/wasm/v1/tx.proto + + + + + +### MsgPushNewWasmCode +Message type to push new wasm code + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `signer` | [string](#string) | | | +| `code` | [bytes](#bytes) | | | + + + + + + + + +### MsgPushNewWasmCodeResponse +Response in case of successful handling + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `code_id` | [bytes](#bytes) | | | + + + + + + + + + + + + + + +### Msg +Msg defines the ibc/wasm Msg service. + +| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | +| ----------- | ------------ | ------------- | ------------| ------- | -------- | +| `PushNewWasmCode` | [MsgPushNewWasmCode](#ibc.core.wasm.v1.MsgPushNewWasmCode) | [MsgPushNewWasmCodeResponse](#ibc.core.wasm.v1.MsgPushNewWasmCodeResponse) | PushNewWasmCode defines a rpc handler method for PushNewWasmCode. | | + + + + +

Top

@@ -3353,6 +3485,91 @@ that implements Misbehaviour interface expected by ICS-02 + + + + + + + + + + + +

Top

+ +## ibc/lightclients/wasm/v1/wasm.proto + + + + + +### ClientState +Wasm light client's Client state + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `data` | [bytes](#bytes) | | | +| `code_id` | [bytes](#bytes) | | | +| `latest_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | +| `proof_specs` | [ics23.ProofSpec](#ics23.ProofSpec) | repeated | | + + + + + + + + +### ConsensusState +Wasm light client's ConsensusState + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `data` | [bytes](#bytes) | | | +| `code_id` | [bytes](#bytes) | | | +| `timestamp` | [uint64](#uint64) | | timestamp that corresponds to the block height in which the ConsensusState was stored. | +| `root` | [ibc.core.commitment.v1.MerkleRoot](#ibc.core.commitment.v1.MerkleRoot) | | commitment root (i.e app hash) | + + + + + + + + +### Header +Wasm light client Header + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `data` | [bytes](#bytes) | | | +| `height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | + + + + + + + + +### Misbehaviour +Wasm light client Misbehaviour + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `client_id` | [string](#string) | | | +| `header_1` | [Header](#ibc.lightclients.wasm.v1.Header) | | | +| `header_2` | [Header](#ibc.lightclients.wasm.v1.Header) | | | + + + + + diff --git a/go.mod b/go.mod index 233f26b718e..397f1382915 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ module github.com/cosmos/ibc-go replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 require ( + github.com/CosmWasm/wasmvm v0.13.0 github.com/armon/go-metrics v0.3.8 github.com/confio/ics23/go v0.6.6 github.com/cosmos/cosmos-sdk v0.43.0-beta1 @@ -22,4 +23,5 @@ require ( github.com/tendermint/tm-db v0.6.4 google.golang.org/genproto v0.0.0-20210114201628-6edceaf6022f google.golang.org/grpc v1.37.0 + google.golang.org/protobuf v1.26.0 // indirect ) diff --git a/go.sum b/go.sum index 3f9f99e4403..d92fdbf7464 100644 --- a/go.sum +++ b/go.sum @@ -32,6 +32,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= +github.com/CosmWasm/wasmvm v0.13.0 h1:AP8LVcCxI3KLtHY24qLhzVe+ChOXwcR8MNm8Jxkuhwk= +github.com/CosmWasm/wasmvm v0.13.0/go.mod h1:Id107qllDJyJjVQQsKMOy2YYF98sqPJ2t+jX1QES40A= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= @@ -682,6 +684,7 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= @@ -699,6 +702,7 @@ github.com/tendermint/tendermint v0.34.0-rc6/go.mod h1:ugzyZO5foutZImv0Iyx/gOFCX github.com/tendermint/tendermint v0.34.0/go.mod h1:Aj3PIipBFSNO21r+Lq3TtzQ+uKESxkbA3yo/INM4QwQ= github.com/tendermint/tendermint v0.34.10 h1:wBOc/It8sh/pVH9np2V5fBvRmIyFN/bUrGPx+eAHexs= github.com/tendermint/tendermint v0.34.10/go.mod h1:aeHL7alPh4uTBIJQ8mgFEE8VwJLXI1VD3rVOmH2Mcy0= +github.com/tendermint/tm-db v0.5.1/go.mod h1:g92zWjHpCYlEvQXvy9M168Su8V1IBEeawpXVVBaK4f4= github.com/tendermint/tm-db v0.6.2/go.mod h1:GYtQ67SUvATOcoY8/+x6ylk8Qo02BQyLrAs+yAcLvGI= github.com/tendermint/tm-db v0.6.3/go.mod h1:lfA1dL9/Y/Y8wwyPp2NMLyn5P5Ptr/gvDFNWtrCWSf8= github.com/tendermint/tm-db v0.6.4 h1:3N2jlnYQkXNQclQwd/eKV/NzlqPlfK21cpRRIx80XXQ= @@ -814,6 +818,7 @@ golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= diff --git a/modules/core/02-client/keeper/client.go b/modules/core/02-client/keeper/client.go index 1ebcceadc4f..3d7e92416ab 100644 --- a/modules/core/02-client/keeper/client.go +++ b/modules/core/02-client/keeper/client.go @@ -27,15 +27,15 @@ func (k Keeper) CreateClient( clientID := k.GenerateClientIdentifier(ctx, clientState.ClientType()) - k.SetClientState(ctx, clientID, clientState) - k.Logger(ctx).Info("client created at height", "client-id", clientID, "height", clientState.GetLatestHeight().String()) - // verifies initial consensus state against client state and initializes client store with any client-specific metadata // e.g. set ProcessedTime in Tendermint clients if err := clientState.Initialize(ctx, k.cdc, k.ClientStore(ctx, clientID), consensusState); err != nil { return "", err } + k.SetClientState(ctx, clientID, clientState) + k.Logger(ctx).Info("client created at height", "client-id", clientID, "height", clientState.GetLatestHeight().String()) + // check if consensus state is nil in case the created client is Localhost if consensusState != nil { k.SetClientConsensusState(ctx, clientID, clientState.GetLatestHeight(), consensusState) diff --git a/modules/core/02-client/types/client.pb.go b/modules/core/02-client/types/client.pb.go index 99f5fe17fc3..e578b0e02e5 100644 --- a/modules/core/02-client/types/client.pb.go +++ b/modules/core/02-client/types/client.pb.go @@ -347,6 +347,8 @@ var xxx_messageInfo_Height proto.InternalMessageInfo type Params struct { // allowed_clients defines the list of allowed client state types. AllowedClients []string `protobuf:"bytes,1,rep,name=allowed_clients,json=allowedClients,proto3" json:"allowed_clients,omitempty" yaml:"allowed_clients"` + // whether or not wasm clients are enabled + WasmClientsEnabled bool `protobuf:"varint,2,opt,name=wasm_clients_enabled,json=wasmClientsEnabled,proto3" json:"wasm_clients_enabled,omitempty" yaml:"wasm_clients_enabled"` } func (m *Params) Reset() { *m = Params{} } @@ -389,6 +391,13 @@ func (m *Params) GetAllowedClients() []string { return nil } +func (m *Params) GetWasmClientsEnabled() bool { + if m != nil { + return m.WasmClientsEnabled + } + return false +} + func init() { proto.RegisterType((*IdentifiedClientState)(nil), "ibc.core.client.v1.IdentifiedClientState") proto.RegisterType((*ConsensusStateWithHeight)(nil), "ibc.core.client.v1.ConsensusStateWithHeight") @@ -402,54 +411,56 @@ func init() { func init() { proto.RegisterFile("ibc/core/client/v1/client.proto", fileDescriptor_b6bc4c8185546947) } var fileDescriptor_b6bc4c8185546947 = []byte{ - // 744 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0x3d, 0x73, 0xd3, 0x4a, - 0x14, 0xb5, 0x1c, 0xc7, 0x13, 0xaf, 0xf3, 0xec, 0x3c, 0xc5, 0x7e, 0x71, 0xfc, 0xf2, 0x2c, 0xcf, - 0xce, 0x2b, 0x5c, 0x10, 0x09, 0x9b, 0x81, 0x61, 0xd2, 0x61, 0x37, 0x49, 0x01, 0x18, 0x31, 0x19, - 0x18, 0x1a, 0xa3, 0x8f, 0x8d, 0xbc, 0x19, 0x59, 0xeb, 0xd1, 0xae, 0x0c, 0xfe, 0x07, 0x94, 0x94, - 0x14, 0x14, 0xf9, 0x05, 0xfc, 0x0a, 0x8a, 0x94, 0x99, 0xa1, 0xa1, 0xd2, 0x30, 0x49, 0x43, 0xad, - 0x96, 0x86, 0x91, 0x76, 0xe5, 0xd8, 0x4e, 0x02, 0x0c, 0x74, 0xab, 0xbb, 0xe7, 0x9e, 0x7b, 0xcf, - 0xd9, 0xbd, 0x2b, 0xa0, 0x60, 0xd3, 0xd2, 0x2c, 0xe2, 0x23, 0xcd, 0x72, 0x31, 0xf2, 0x98, 0x36, - 0x69, 0x8b, 0x95, 0x3a, 0xf6, 0x09, 0x23, 0xb2, 0x8c, 0x4d, 0x4b, 0x8d, 0x01, 0xaa, 0x08, 0x4f, - 0xda, 0xf5, 0x8a, 0x43, 0x1c, 0x92, 0x6c, 0x6b, 0xf1, 0x8a, 0x23, 0xeb, 0xdb, 0x0e, 0x21, 0x8e, - 0x8b, 0xb4, 0xe4, 0xcb, 0x0c, 0x8e, 0x34, 0xc3, 0x9b, 0x8a, 0xad, 0xff, 0x2d, 0x42, 0x47, 0x84, - 0x6a, 0xc1, 0xd8, 0xf1, 0x0d, 0x1b, 0x69, 0x93, 0xb6, 0x89, 0x98, 0xd1, 0x4e, 0xbf, 0x39, 0x0a, - 0xbe, 0x97, 0x40, 0xf5, 0xc0, 0x46, 0x1e, 0xc3, 0x47, 0x18, 0xd9, 0xbd, 0xa4, 0xdc, 0x53, 0x66, - 0x30, 0x24, 0xb7, 0x41, 0x81, 0x57, 0x1f, 0x60, 0xbb, 0x26, 0x35, 0xa5, 0x56, 0xa1, 0x5b, 0x89, - 0x42, 0x65, 0x63, 0x6a, 0x8c, 0xdc, 0x3d, 0x38, 0xdb, 0x82, 0xfa, 0x1a, 0x5f, 0x1f, 0xd8, 0x72, - 0x1f, 0xac, 0x8b, 0x38, 0x8d, 0x29, 0x6a, 0xd9, 0xa6, 0xd4, 0x2a, 0x76, 0x2a, 0x2a, 0x6f, 0x52, - 0x4d, 0x9b, 0x54, 0x1f, 0x78, 0xd3, 0xee, 0x56, 0x14, 0x2a, 0x9b, 0x0b, 0x5c, 0x49, 0x0e, 0xd4, - 0x8b, 0xd6, 0x65, 0x13, 0xf0, 0x83, 0x04, 0x6a, 0x3d, 0xe2, 0x51, 0xe4, 0xd1, 0x80, 0x26, 0xa1, - 0x67, 0x98, 0x0d, 0xf7, 0x11, 0x76, 0x86, 0x4c, 0xbe, 0x0f, 0xf2, 0xc3, 0x64, 0x95, 0xb4, 0x57, - 0xec, 0xd4, 0xd5, 0xab, 0xbe, 0xa9, 0x1c, 0xdb, 0xcd, 0x9d, 0x86, 0x4a, 0x46, 0x17, 0x78, 0xf9, - 0x39, 0x28, 0x5b, 0x29, 0xeb, 0x2f, 0xf4, 0xba, 0x1d, 0x85, 0x4a, 0x35, 0xee, 0x15, 0x2e, 0x65, - 0x41, 0xbd, 0x64, 0x2d, 0x74, 0x07, 0x3f, 0x4a, 0xa0, 0xca, 0x5d, 0x5c, 0x6c, 0x9b, 0xfe, 0x8e, - 0x9f, 0xaf, 0xc1, 0xc6, 0x52, 0x41, 0x5a, 0xcb, 0x36, 0x57, 0x5a, 0xc5, 0xce, 0xad, 0xeb, 0xa4, - 0xde, 0x64, 0x54, 0x57, 0x89, 0xc5, 0x47, 0xa1, 0xb2, 0x25, 0x6a, 0x2d, 0x71, 0x42, 0xbd, 0xbc, - 0xa8, 0x82, 0xc2, 0x4f, 0x59, 0x50, 0xe1, 0x32, 0x0e, 0xc7, 0xb6, 0xc1, 0x50, 0xdf, 0x27, 0x63, - 0x42, 0x0d, 0x57, 0xae, 0x80, 0x55, 0x86, 0x99, 0x8b, 0xb8, 0x02, 0x9d, 0x7f, 0xc8, 0x4d, 0x50, - 0xb4, 0x11, 0xb5, 0x7c, 0x3c, 0x66, 0x98, 0x78, 0x89, 0x97, 0x05, 0x7d, 0x3e, 0x24, 0xef, 0x83, - 0xbf, 0x69, 0x60, 0x1e, 0x23, 0x8b, 0x0d, 0x2e, 0x5d, 0x58, 0x49, 0x5c, 0xd8, 0x89, 0x42, 0xa5, - 0xc6, 0x3b, 0xbb, 0x02, 0x81, 0x7a, 0x59, 0xc4, 0x7a, 0xa9, 0x29, 0x4f, 0x40, 0x85, 0x06, 0x26, - 0x65, 0x98, 0x05, 0x0c, 0xcd, 0x91, 0xe5, 0x12, 0x32, 0x25, 0x0a, 0x95, 0x7f, 0x53, 0x32, 0x6a, - 0x2e, 0xa3, 0xa0, 0x2e, 0x5f, 0x26, 0xcf, 0x28, 0x5f, 0x82, 0x12, 0xf6, 0x30, 0xc3, 0x86, 0x3b, - 0x10, 0x17, 0x6a, 0xf5, 0xa7, 0x17, 0xea, 0x3f, 0xe1, 0x69, 0x95, 0x17, 0x5b, 0xcc, 0x87, 0xfa, - 0x5f, 0x22, 0xc0, 0xd1, 0x7b, 0xb9, 0x37, 0x27, 0x4a, 0x06, 0x7e, 0x93, 0x40, 0xf9, 0x90, 0x8f, - 0xdf, 0x1f, 0x1b, 0x7a, 0x0f, 0xe4, 0xc6, 0xae, 0xe1, 0x25, 0x1e, 0x16, 0x3b, 0x3b, 0x2a, 0x9f, - 0x76, 0x35, 0x9d, 0x6e, 0x31, 0xed, 0x6a, 0xdf, 0x35, 0x3c, 0x71, 0xf9, 0x13, 0xbc, 0x7c, 0x0c, - 0xaa, 0x02, 0x63, 0x0f, 0x16, 0x86, 0x35, 0xf7, 0x83, 0x01, 0x68, 0x46, 0xa1, 0xb2, 0xc3, 0x85, - 0x5e, 0x9b, 0x0c, 0xf5, 0xcd, 0x34, 0x3e, 0xf7, 0x84, 0xec, 0xad, 0xc7, 0xaa, 0xdf, 0x9d, 0x28, - 0x99, 0xaf, 0x27, 0x8a, 0x14, 0x3f, 0x35, 0x79, 0x31, 0xb9, 0x3d, 0x50, 0xf6, 0xd1, 0x04, 0x53, - 0x4c, 0xbc, 0x81, 0x17, 0x8c, 0x4c, 0xe4, 0x27, 0xf2, 0x73, 0xdd, 0x7a, 0x14, 0x2a, 0xff, 0xf0, - 0x42, 0x4b, 0x00, 0xa8, 0x97, 0xd2, 0xc8, 0xa3, 0x24, 0xb0, 0x40, 0x22, 0x8e, 0x2d, 0x7b, 0x23, - 0x49, 0x7a, 0x2e, 0x33, 0x12, 0x71, 0x30, 0x6b, 0x69, 0x8b, 0xf0, 0x21, 0xc8, 0xf7, 0x0d, 0xdf, - 0x18, 0xd1, 0x98, 0xd8, 0x70, 0x5d, 0xf2, 0x6a, 0x26, 0x92, 0xd6, 0xa4, 0xe6, 0x4a, 0xab, 0x30, - 0x4f, 0xbc, 0x04, 0x80, 0x7a, 0x49, 0x44, 0xb8, 0x7e, 0xda, 0x7d, 0x7c, 0x7a, 0xde, 0x90, 0xce, - 0xce, 0x1b, 0xd2, 0x97, 0xf3, 0x86, 0xf4, 0xf6, 0xa2, 0x91, 0x39, 0xbb, 0x68, 0x64, 0x3e, 0x5f, - 0x34, 0x32, 0x2f, 0xee, 0x3a, 0x98, 0x0d, 0x03, 0x53, 0xb5, 0xc8, 0x48, 0x13, 0x6f, 0x34, 0x36, - 0xad, 0x5d, 0x87, 0x68, 0x23, 0x62, 0x07, 0x2e, 0xa2, 0xfc, 0xdf, 0x70, 0xbb, 0xb3, 0x2b, 0x7e, - 0x0f, 0x6c, 0x3a, 0x46, 0xd4, 0xcc, 0x27, 0x27, 0x72, 0xe7, 0x7b, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xca, 0x6e, 0xea, 0xc6, 0x3e, 0x06, 0x00, 0x00, + // 774 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0x3f, 0x6f, 0xe3, 0x36, + 0x1c, 0xb5, 0x1c, 0xc7, 0x88, 0xe9, 0xd4, 0x4e, 0x15, 0xbb, 0x71, 0xdc, 0xd4, 0x32, 0x88, 0x0e, + 0x1e, 0x1a, 0xa9, 0x76, 0xd1, 0xa2, 0xc8, 0x56, 0x1b, 0x05, 0x92, 0xa5, 0x75, 0x55, 0x04, 0x2d, + 0xba, 0xb8, 0xfa, 0xc3, 0xc8, 0x0c, 0x64, 0xd1, 0x10, 0x29, 0xa7, 0xfe, 0x06, 0x1d, 0x3b, 0x76, + 0xe8, 0xe0, 0x4f, 0xd0, 0x4f, 0x71, 0x43, 0xc6, 0x00, 0xb7, 0xdc, 0x24, 0x1c, 0x92, 0xe5, 0x66, + 0xad, 0xb7, 0x1c, 0x44, 0x52, 0x8e, 0xed, 0x24, 0x77, 0x87, 0xbb, 0x8d, 0x7a, 0x7a, 0x7c, 0xbf, + 0xf7, 0x7b, 0xe4, 0x4f, 0x02, 0x1a, 0xb6, 0x1d, 0xc3, 0x21, 0x21, 0x32, 0x1c, 0x1f, 0xa3, 0x80, + 0x19, 0xb3, 0xae, 0x5c, 0xe9, 0xd3, 0x90, 0x30, 0xa2, 0xaa, 0xd8, 0x76, 0xf4, 0x94, 0xa0, 0x4b, + 0x78, 0xd6, 0x6d, 0xd6, 0x3c, 0xe2, 0x11, 0xfe, 0xda, 0x48, 0x57, 0x82, 0xd9, 0x3c, 0xf4, 0x08, + 0xf1, 0x7c, 0x64, 0xf0, 0x27, 0x3b, 0xba, 0x30, 0xac, 0x60, 0x2e, 0x5f, 0x7d, 0xe9, 0x10, 0x3a, + 0x21, 0xd4, 0x88, 0xa6, 0x5e, 0x68, 0xb9, 0xc8, 0x98, 0x75, 0x6d, 0xc4, 0xac, 0x6e, 0xf6, 0x2c, + 0x58, 0xf0, 0x3f, 0x05, 0xd4, 0xcf, 0x5c, 0x14, 0x30, 0x7c, 0x81, 0x91, 0x3b, 0xe0, 0xe5, 0x7e, + 0x65, 0x16, 0x43, 0x6a, 0x17, 0x94, 0x44, 0xf5, 0x11, 0x76, 0x1b, 0x4a, 0x5b, 0xe9, 0x94, 0xfa, + 0xb5, 0x24, 0xd6, 0xf6, 0xe6, 0xd6, 0xc4, 0x3f, 0x81, 0xcb, 0x57, 0xd0, 0xdc, 0x11, 0xeb, 0x33, + 0x57, 0x1d, 0x82, 0x5d, 0x89, 0xd3, 0x54, 0xa2, 0x91, 0x6f, 0x2b, 0x9d, 0x72, 0xaf, 0xa6, 0x0b, + 0x93, 0x7a, 0x66, 0x52, 0xff, 0x21, 0x98, 0xf7, 0x0f, 0x92, 0x58, 0xdb, 0x5f, 0xd3, 0xe2, 0x7b, + 0xa0, 0x59, 0x76, 0xee, 0x4d, 0xc0, 0xff, 0x15, 0xd0, 0x18, 0x90, 0x80, 0xa2, 0x80, 0x46, 0x94, + 0x43, 0xbf, 0x61, 0x36, 0x3e, 0x45, 0xd8, 0x1b, 0x33, 0xf5, 0x7b, 0x50, 0x1c, 0xf3, 0x15, 0xb7, + 0x57, 0xee, 0x35, 0xf5, 0x87, 0xb9, 0xe9, 0x82, 0xdb, 0x2f, 0x5c, 0xc7, 0x5a, 0xce, 0x94, 0x7c, + 0xf5, 0x77, 0x50, 0x75, 0x32, 0xd5, 0xf7, 0xf0, 0x7a, 0x98, 0xc4, 0x5a, 0x3d, 0xf5, 0x0a, 0x37, + 0x76, 0x41, 0xb3, 0xe2, 0xac, 0xb9, 0x83, 0xcf, 0x14, 0x50, 0x17, 0x29, 0xae, 0xdb, 0xa6, 0x1f, + 0x92, 0xe7, 0x5f, 0x60, 0x6f, 0xa3, 0x20, 0x6d, 0xe4, 0xdb, 0x5b, 0x9d, 0x72, 0xef, 0xab, 0xc7, + 0x5a, 0x7d, 0x2a, 0xa8, 0xbe, 0x96, 0x36, 0x9f, 0xc4, 0xda, 0x81, 0xac, 0xb5, 0xa1, 0x09, 0xcd, + 0xea, 0x7a, 0x17, 0x14, 0x3e, 0xcf, 0x83, 0x9a, 0x68, 0xe3, 0x7c, 0xea, 0x5a, 0x0c, 0x0d, 0x43, + 0x32, 0x25, 0xd4, 0xf2, 0xd5, 0x1a, 0xd8, 0x66, 0x98, 0xf9, 0x48, 0x74, 0x60, 0x8a, 0x07, 0xb5, + 0x0d, 0xca, 0x2e, 0xa2, 0x4e, 0x88, 0xa7, 0x0c, 0x93, 0x80, 0x67, 0x59, 0x32, 0x57, 0x21, 0xf5, + 0x14, 0x7c, 0x4a, 0x23, 0xfb, 0x12, 0x39, 0x6c, 0x74, 0x9f, 0xc2, 0x16, 0x4f, 0xe1, 0x28, 0x89, + 0xb5, 0x86, 0x70, 0xf6, 0x80, 0x02, 0xcd, 0xaa, 0xc4, 0x06, 0x59, 0x28, 0xbf, 0x80, 0x1a, 0x8d, + 0x6c, 0xca, 0x30, 0x8b, 0x18, 0x5a, 0x11, 0x2b, 0x70, 0x31, 0x2d, 0x89, 0xb5, 0xcf, 0x33, 0x31, + 0x6a, 0x6f, 0xb2, 0xa0, 0xa9, 0xde, 0x6f, 0x5e, 0x4a, 0xfe, 0x09, 0x2a, 0x38, 0xc0, 0x0c, 0x5b, + 0xfe, 0x48, 0x5e, 0xa8, 0xed, 0x77, 0x5e, 0xa8, 0x2f, 0x64, 0xa6, 0x75, 0x51, 0x6c, 0x7d, 0x3f, + 0x34, 0x3f, 0x91, 0x80, 0x60, 0x9f, 0x14, 0xfe, 0x5e, 0x68, 0x39, 0xf8, 0x5a, 0x01, 0xd5, 0x73, + 0x31, 0x7e, 0x1f, 0x1d, 0xe8, 0x77, 0xa0, 0x30, 0xf5, 0xad, 0x80, 0x67, 0x58, 0xee, 0x1d, 0xe9, + 0x62, 0xda, 0xf5, 0x6c, 0xba, 0xe5, 0xb4, 0xeb, 0x43, 0xdf, 0x0a, 0xe4, 0xe5, 0xe7, 0x7c, 0xf5, + 0x12, 0xd4, 0x25, 0xc7, 0x1d, 0xad, 0x0d, 0x6b, 0xe1, 0x2d, 0x03, 0xd0, 0x4e, 0x62, 0xed, 0x48, + 0x34, 0xfa, 0xe8, 0x66, 0x68, 0xee, 0x67, 0xf8, 0xca, 0x27, 0xe4, 0x64, 0x37, 0xed, 0xfa, 0xdf, + 0x85, 0x96, 0x7b, 0xb5, 0xd0, 0x94, 0xf4, 0x53, 0x53, 0x94, 0x93, 0x3b, 0x00, 0xd5, 0x10, 0xcd, + 0x30, 0xc5, 0x24, 0x18, 0x05, 0xd1, 0xc4, 0x46, 0x21, 0x6f, 0xbf, 0xd0, 0x6f, 0x26, 0xb1, 0xf6, + 0x99, 0x28, 0xb4, 0x41, 0x80, 0x66, 0x25, 0x43, 0x7e, 0xe2, 0xc0, 0x9a, 0x88, 0x3c, 0xb6, 0xfc, + 0x93, 0x22, 0xd9, 0xb9, 0x2c, 0x45, 0xe4, 0xc1, 0xec, 0x64, 0x16, 0xe1, 0x42, 0x01, 0xc5, 0xa1, + 0x15, 0x5a, 0x13, 0x9a, 0x2a, 0x5b, 0xbe, 0x4f, 0xae, 0x96, 0x5d, 0xd2, 0x86, 0xd2, 0xde, 0xea, + 0x94, 0x56, 0x95, 0x37, 0x08, 0xd0, 0xac, 0x48, 0x44, 0x04, 0x40, 0xd3, 0x7b, 0x7a, 0x65, 0xd1, + 0x49, 0x46, 0x18, 0xa1, 0xc0, 0xb2, 0x7d, 0xe4, 0x72, 0x8f, 0x3b, 0xab, 0xf7, 0xf4, 0x31, 0x16, + 0x34, 0xd5, 0x14, 0x96, 0x5a, 0x3f, 0x0a, 0xb0, 0xff, 0xf3, 0xf5, 0x6d, 0x4b, 0xb9, 0xb9, 0x6d, + 0x29, 0x2f, 0x6f, 0x5b, 0xca, 0x3f, 0x77, 0xad, 0xdc, 0xcd, 0x5d, 0x2b, 0xf7, 0xe2, 0xae, 0x95, + 0xfb, 0xe3, 0x5b, 0x0f, 0xb3, 0x71, 0x64, 0xeb, 0x0e, 0x99, 0x18, 0xf2, 0xbb, 0x8f, 0x6d, 0xe7, + 0xd8, 0x23, 0xc6, 0x84, 0xb8, 0x91, 0x8f, 0xa8, 0xf8, 0xdf, 0x7c, 0xdd, 0x3b, 0x96, 0xbf, 0x1c, + 0x36, 0x9f, 0x22, 0x6a, 0x17, 0xf9, 0x29, 0x7f, 0xf3, 0x26, 0x00, 0x00, 0xff, 0xff, 0x1f, 0x89, + 0x45, 0x52, 0x92, 0x06, 0x00, 0x00, } func (this *UpgradeProposal) Equal(that interface{}) bool { @@ -789,6 +800,16 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.WasmClientsEnabled { + i-- + if m.WasmClientsEnabled { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + } if len(m.AllowedClients) > 0 { for iNdEx := len(m.AllowedClients) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.AllowedClients[iNdEx]) @@ -940,6 +961,9 @@ func (m *Params) Size() (n int) { n += 1 + l + sovClient(uint64(l)) } } + if m.WasmClientsEnabled { + n += 2 + } return n } @@ -1845,6 +1869,26 @@ func (m *Params) Unmarshal(dAtA []byte) error { } m.AllowedClients = append(m.AllowedClients, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field WasmClientsEnabled", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowClient + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.WasmClientsEnabled = bool(v != 0) default: iNdEx = preIndex skippy, err := skipClient(dAtA[iNdEx:]) diff --git a/modules/core/02-client/types/events.go b/modules/core/02-client/types/events.go index 464ad4d426e..5975cb76098 100644 --- a/modules/core/02-client/types/events.go +++ b/modules/core/02-client/types/events.go @@ -13,6 +13,7 @@ const ( AttributeKeyClientType = "client_type" AttributeKeyConsensusHeight = "consensus_height" AttributeKeyHeader = "header" + AttributeKeyWasmCodeID = "wasm_code_id" ) // IBC client events vars @@ -22,6 +23,7 @@ var ( EventTypeUpgradeClient = "upgrade_client" EventTypeSubmitMisbehaviour = "client_misbehaviour" EventTypeUpdateClientProposal = "update_client_proposal" + EventTypePushWasmCode = "push_wasm_code" AttributeValueCategory = fmt.Sprintf("%s_%s", host.ModuleName, SubModuleName) ) diff --git a/modules/core/02-client/types/params.go b/modules/core/02-client/types/params.go index 6460a3fcde5..8ab9a227b56 100644 --- a/modules/core/02-client/types/params.go +++ b/modules/core/02-client/types/params.go @@ -35,7 +35,12 @@ func DefaultParams() Params { // Validate all ibc-client module parameters func (p Params) Validate() error { - return validateClients(p.AllowedClients) + err := validateClients(p.AllowedClients) + if err != nil { + return err + } + + return validateWasmClientEnabledFlag(p.WasmClientsEnabled) } // ParamSetPairs implements params.ParamSet @@ -55,6 +60,15 @@ func (p Params) IsAllowedClient(clientType string) bool { return false } +func validateWasmClientEnabledFlag(i interface{}) error { + _, ok := i.(bool) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + return nil +} + func validateClients(i interface{}) error { clients, ok := i.([]string) if !ok { diff --git a/modules/core/28-wasm/cli/cli.go b/modules/core/28-wasm/cli/cli.go new file mode 100644 index 00000000000..3bf4bc2647a --- /dev/null +++ b/modules/core/28-wasm/cli/cli.go @@ -0,0 +1,41 @@ +package cli + +import ( + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/ibc-go/modules/core/28-wasm/types" + "github.com/spf13/cobra" +) + +// GetQueryCmd returns the query commands for IBC channels +func GetQueryCmd() *cobra.Command { + queryCmd := &cobra.Command{ + Use: types.SubModuleName, + Short: "IBC wasm manager module query subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + queryCmd.AddCommand( + GetCmdCode(), + ) + + return queryCmd +} + +// NewTxCmd returns a CLI command handler for all x/ibc channel transaction commands. +func NewTxCmd() *cobra.Command { + txCmd := &cobra.Command{ + Use: types.SubModuleName, + Short: "IBC wasm manager module transaction subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + txCmd.AddCommand( + NewPushNewWasmCodeCmd(), + ) + + return txCmd +} diff --git a/modules/core/28-wasm/cli/query.go b/modules/core/28-wasm/cli/query.go new file mode 100644 index 00000000000..8696c874720 --- /dev/null +++ b/modules/core/28-wasm/cli/query.go @@ -0,0 +1,49 @@ +package cli + +import ( + "context" + "fmt" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/version" + host "github.com/cosmos/ibc-go/modules/core/24-host" + "github.com/cosmos/ibc-go/modules/core/28-wasm/types" + "github.com/spf13/cobra" +) + +// GetCmdCode defines the command to query wasm code for given code id +func GetCmdCode() *cobra.Command { + cmd := &cobra.Command{ + Use: "code [code-id]", + Short: "Query wasm code", + Long: "Query wasm code", + Example: fmt.Sprintf( + "%s query %s %s code [code-id]", version.AppName, host.ModuleName, types.SubModuleName, + ), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + codeID := args[0] + req := types.WasmCodeQuery{ + CodeId: codeID, + } + + res, err := queryClient.WasmCode(context.Background(), &req) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/modules/core/28-wasm/cli/tx.go b/modules/core/28-wasm/cli/tx.go new file mode 100644 index 00000000000..868226e3aaa --- /dev/null +++ b/modules/core/28-wasm/cli/tx.go @@ -0,0 +1,48 @@ +package cli + +import ( + "io/ioutil" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/cosmos/ibc-go/modules/core/28-wasm/types" + "github.com/spf13/cobra" +) + +// NewPushNewWasmCodeCmd returns the command to create a PushNewWasmCode transaction +func NewPushNewWasmCodeCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "push-wasm [wasm-file]", + Short: "Reads wasm code from the file and creates push transaction", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + fileName := args[0] + + code, err := ioutil.ReadFile(fileName) + if err != nil { + return err + } + + msg := &types.MsgPushNewWasmCode{ + Code: code, + Signer: clientCtx.GetFromAddress().String(), + } + + if err := msg.ValidateBasic(); err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/modules/core/28-wasm/handler.go b/modules/core/28-wasm/handler.go new file mode 100644 index 00000000000..1882612b3b8 --- /dev/null +++ b/modules/core/28-wasm/handler.go @@ -0,0 +1,19 @@ +package wasm + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/ibc-go/modules/core/28-wasm/keeper" + "github.com/cosmos/ibc-go/modules/core/28-wasm/types" +) + +func HandleMsgPushNewWasmCode(ctx sdk.Context, k keeper.Keeper, msg *types.MsgPushNewWasmCode) (*types.MsgPushNewWasmCodeResponse, error) { + codeID, err := k.PushNewWasmCode(ctx, msg.Code) + if err != nil { + return nil, sdkerrors.Wrap(err, "pushing new wasm code failed") + } + + return &types.MsgPushNewWasmCodeResponse{ + CodeId: codeID, + }, nil +} diff --git a/modules/core/28-wasm/keeper/grpc_query.go b/modules/core/28-wasm/keeper/grpc_query.go new file mode 100644 index 00000000000..b0c084759f5 --- /dev/null +++ b/modules/core/28-wasm/keeper/grpc_query.go @@ -0,0 +1,42 @@ +package keeper + +import ( + "context" + "encoding/hex" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/ibc-go/modules/core/28-wasm/types" +) + +var _ types.QueryServer = (*Keeper)(nil) + +func (q Keeper) WasmCode(c context.Context, query *types.WasmCodeQuery) (*types.WasmCodeResponse, error) { + if query == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + ctx := sdk.UnwrapSDKContext(c) + store := ctx.KVStore(q.storeKey) + + codeID, err := hex.DecodeString(query.CodeId) + if err != nil { + return nil, status.Error(codes.InvalidArgument, "invalid code id") + } + + codeKey := types.CodeID(codeID) + code := store.Get(codeKey) + if code == nil { + return nil, status.Error( + codes.NotFound, + sdkerrors.Wrap(types.ErrWasmCodeIDNotFound, query.CodeId).Error(), + ) + } + + return &types.WasmCodeResponse{ + Code: code, + }, nil +} diff --git a/modules/core/28-wasm/keeper/keeper.go b/modules/core/28-wasm/keeper/keeper.go new file mode 100644 index 00000000000..70c8a3f216c --- /dev/null +++ b/modules/core/28-wasm/keeper/keeper.go @@ -0,0 +1,91 @@ +package keeper + +import ( + "bytes" + "crypto/sha256" + "strings" + + wasm "github.com/CosmWasm/wasmvm" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/ibc-go/modules/core/28-wasm/types" +) + +// WasmVM initialized by wasm keeper +var WasmVM *wasm.VM + +// VMConfig represents Wasm virtual machine settings +type VMConfig struct { + DataDir string + SupportedFeatures []string + MemoryLimitMb uint32 + PrintDebug bool + CacheSizeMb uint32 +} + +// Keeper will have a reference to Wasmer with it's own data directory. +type Keeper struct { + storeKey sdk.StoreKey + cdc codec.BinaryCodec + wasmValidator *WasmValidator +} + +func NewKeeper(cdc codec.BinaryCodec, key sdk.StoreKey, vmConfig *VMConfig, validationConfig *ValidationConfig) Keeper { + supportedFeatures := strings.Join(vmConfig.SupportedFeatures, ",") + + vm, err := wasm.NewVM(vmConfig.DataDir, supportedFeatures, vmConfig.MemoryLimitMb, vmConfig.PrintDebug, vmConfig.CacheSizeMb) + if err != nil { + panic(err) + } + + wasmValidator, err := NewWasmValidator(validationConfig, func() (*wasm.VM, error) { + return wasm.NewVM(vmConfig.DataDir, supportedFeatures, vmConfig.MemoryLimitMb, vmConfig.PrintDebug, vmConfig.CacheSizeMb) + }) + if err != nil { + panic(err) + } + + WasmVM = vm + + return Keeper{ + cdc: cdc, + storeKey: key, + wasmValidator: wasmValidator, + } +} + +func (k Keeper) PushNewWasmCode(ctx sdk.Context, code []byte) ([]byte, error) { + store := ctx.KVStore(k.storeKey) + codeHash := generateWasmCodeHash(code) + codeIDKey := types.CodeID(codeHash) + + if store.Has(codeIDKey) { + return nil, types.ErrWasmCodeExists + } + + if isValidWasmCode, err := k.wasmValidator.validateWasmCode(code); err != nil { + return nil, sdkerrors.Wrapf(types.ErrWasmCodeValidation, "unable to validate wasm code: %s", err) + } else if !isValidWasmCode { + return nil, types.ErrWasmInvalidCode + } + + codeID, err := WasmVM.Create(code) + if err != nil { + return nil, types.ErrWasmInvalidCode + } + + // safety check to assert that code id returned by WasmVM equals to code hash + if !bytes.Equal(codeID, codeHash) { + return nil, types.ErrWasmInvalidCodeID + } + + store.Set(codeIDKey, code) + + return codeID, nil +} + +func generateWasmCodeHash(code []byte) []byte { + hash := sha256.Sum256(code) + return hash[:] +} diff --git a/modules/core/28-wasm/keeper/validation.go b/modules/core/28-wasm/keeper/validation.go new file mode 100644 index 00000000000..9757ab29f8c --- /dev/null +++ b/modules/core/28-wasm/keeper/validation.go @@ -0,0 +1,39 @@ +package keeper + +import cosmwasm "github.com/CosmWasm/wasmvm" + +// Basic validation config can be extended to add other configuration later +type ValidationConfig struct { + MaxSizeAllowed int +} + +func NewWasmValidator(config *ValidationConfig, vmCreateFn func() (*cosmwasm.VM, error)) (*WasmValidator, error) { + return &WasmValidator{ + config: config, + vmCreateFn: vmCreateFn, + }, nil +} + +type WasmValidator struct { + vmCreateFn func() (*cosmwasm.VM, error) + config *ValidationConfig +} + +func (v *WasmValidator) validateWasmCode(code []byte) (bool, error) { + if len(code) > v.config.MaxSizeAllowed { + return false, nil + } + + testVM, err := v.vmCreateFn() + if err != nil { + return false, err + } + + _, err = testVM.Create(code) + if err != nil { + return false, nil + } + + testVM.Cleanup() + return true, nil +} diff --git a/modules/core/28-wasm/module.go b/modules/core/28-wasm/module.go new file mode 100644 index 00000000000..1d448d93fe1 --- /dev/null +++ b/modules/core/28-wasm/module.go @@ -0,0 +1,28 @@ +package wasm + +import ( + "github.com/cosmos/ibc-go/modules/core/28-wasm/cli" + "github.com/cosmos/ibc-go/modules/core/28-wasm/types" + "github.com/gogo/protobuf/grpc" + "github.com/spf13/cobra" +) + +// Name returns the IBC channel ICS name. +func Name() string { + return "wasm" +} + +// GetTxCmd returns the root tx command for IBC channels. +func GetTxCmd() *cobra.Command { + return cli.NewTxCmd() +} + +// GetQueryCmd returns the root query command for IBC channels. +func GetQueryCmd() *cobra.Command { + return cli.GetQueryCmd() +} + +// RegisterQueryService registers the gRPC query service for IBC channels. +func RegisterQueryService(server grpc.Server, queryServer types.QueryServer) { + types.RegisterQueryServer(server, queryServer) +} diff --git a/modules/core/28-wasm/types/codec.go b/modules/core/28-wasm/types/codec.go new file mode 100644 index 00000000000..96425d1a602 --- /dev/null +++ b/modules/core/28-wasm/types/codec.go @@ -0,0 +1,16 @@ +package types + +import ( + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/msgservice" +) + +func RegisterInterfaces(registry codectypes.InterfaceRegistry) { + registry.RegisterImplementations( + (*sdk.Msg)(nil), + &MsgPushNewWasmCode{}, + ) + + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) +} diff --git a/modules/core/28-wasm/types/errors.go b/modules/core/28-wasm/types/errors.go new file mode 100644 index 00000000000..b3ac9538eba --- /dev/null +++ b/modules/core/28-wasm/types/errors.go @@ -0,0 +1,12 @@ +package types + +import sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + +var ( + ErrWasmEmptyCode = sdkerrors.Register(SubModuleName, 2, "empty wasm code") + ErrWasmCodeExists = sdkerrors.Register(SubModuleName, 3, "wasm code already exists") + ErrWasmCodeValidation = sdkerrors.Register(SubModuleName, 4, "unable to validate wasm code") + ErrWasmInvalidCode = sdkerrors.Register(SubModuleName, 5, "invalid wasm code") + ErrWasmInvalidCodeID = sdkerrors.Register(SubModuleName, 6, "invalid wasm code id") + ErrWasmCodeIDNotFound = sdkerrors.Register(SubModuleName, 7, "wasm code id not found") +) diff --git a/modules/core/28-wasm/types/keys.go b/modules/core/28-wasm/types/keys.go new file mode 100644 index 00000000000..df3ddc77535 --- /dev/null +++ b/modules/core/28-wasm/types/keys.go @@ -0,0 +1,14 @@ +package types + +import ( + "encoding/hex" + "fmt" +) + +const ( + SubModuleName = "wasm-manager" +) + +func CodeID(codeID []byte) []byte { + return []byte(fmt.Sprintf("code_id/%s", hex.EncodeToString(codeID))) +} diff --git a/modules/core/28-wasm/types/msgs.go b/modules/core/28-wasm/types/msgs.go new file mode 100644 index 00000000000..718de71b483 --- /dev/null +++ b/modules/core/28-wasm/types/msgs.go @@ -0,0 +1,39 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + host "github.com/cosmos/ibc-go/modules/core/24-host" +) + +var _ sdk.Msg = &MsgPushNewWasmCode{} + +func (m *MsgPushNewWasmCode) Route() string { + return host.RouterKey +} + +func (m *MsgPushNewWasmCode) Type() string { + return "wasm_push_new_code" +} + +func (m *MsgPushNewWasmCode) ValidateBasic() error { + if len(m.Code) == 0 { + return sdkerrors.Wrapf(ErrWasmEmptyCode, + "empty wasm code", + ) + } + + return nil +} + +func (m *MsgPushNewWasmCode) GetSignBytes() []byte { + panic("IBC messages do not support amino") +} + +func (m *MsgPushNewWasmCode) GetSigners() []sdk.AccAddress { + signer, err := sdk.AccAddressFromBech32(m.Signer) + if err != nil { + panic(err) + } + return []sdk.AccAddress{signer} +} diff --git a/modules/core/28-wasm/types/query.pb.go b/modules/core/28-wasm/types/query.pb.go new file mode 100644 index 00000000000..f57f745da9e --- /dev/null +++ b/modules/core/28-wasm/types/query.pb.go @@ -0,0 +1,585 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ibc/core/wasm/v1/query.proto + +package types + +import ( + context "context" + fmt "fmt" + grpc1 "github.com/gogo/protobuf/grpc" + proto "github.com/gogo/protobuf/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + 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" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// WasmCode query +type WasmCodeQuery struct { + CodeId string `protobuf:"bytes,1,opt,name=code_id,json=codeId,proto3" json:"code_id,omitempty"` +} + +func (m *WasmCodeQuery) Reset() { *m = WasmCodeQuery{} } +func (m *WasmCodeQuery) String() string { return proto.CompactTextString(m) } +func (*WasmCodeQuery) ProtoMessage() {} +func (*WasmCodeQuery) Descriptor() ([]byte, []int) { + return fileDescriptor_482bc5ce660a9729, []int{0} +} +func (m *WasmCodeQuery) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *WasmCodeQuery) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_WasmCodeQuery.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *WasmCodeQuery) XXX_Merge(src proto.Message) { + xxx_messageInfo_WasmCodeQuery.Merge(m, src) +} +func (m *WasmCodeQuery) XXX_Size() int { + return m.Size() +} +func (m *WasmCodeQuery) XXX_DiscardUnknown() { + xxx_messageInfo_WasmCodeQuery.DiscardUnknown(m) +} + +var xxx_messageInfo_WasmCodeQuery proto.InternalMessageInfo + +func (m *WasmCodeQuery) GetCodeId() string { + if m != nil { + return m.CodeId + } + return "" +} + +// WasmCode response +type WasmCodeResponse struct { + Code []byte `protobuf:"bytes,1,opt,name=code,proto3" json:"code,omitempty"` +} + +func (m *WasmCodeResponse) Reset() { *m = WasmCodeResponse{} } +func (m *WasmCodeResponse) String() string { return proto.CompactTextString(m) } +func (*WasmCodeResponse) ProtoMessage() {} +func (*WasmCodeResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_482bc5ce660a9729, []int{1} +} +func (m *WasmCodeResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *WasmCodeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_WasmCodeResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *WasmCodeResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_WasmCodeResponse.Merge(m, src) +} +func (m *WasmCodeResponse) XXX_Size() int { + return m.Size() +} +func (m *WasmCodeResponse) XXX_DiscardUnknown() { + xxx_messageInfo_WasmCodeResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_WasmCodeResponse proto.InternalMessageInfo + +func (m *WasmCodeResponse) GetCode() []byte { + if m != nil { + return m.Code + } + return nil +} + +func init() { + proto.RegisterType((*WasmCodeQuery)(nil), "ibc.core.wasm.v1.WasmCodeQuery") + proto.RegisterType((*WasmCodeResponse)(nil), "ibc.core.wasm.v1.WasmCodeResponse") +} + +func init() { proto.RegisterFile("ibc/core/wasm/v1/query.proto", fileDescriptor_482bc5ce660a9729) } + +var fileDescriptor_482bc5ce660a9729 = []byte{ + // 289 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xc9, 0x4c, 0x4a, 0xd6, + 0x4f, 0xce, 0x2f, 0x4a, 0xd5, 0x2f, 0x4f, 0x2c, 0xce, 0xd5, 0x2f, 0x33, 0xd4, 0x2f, 0x2c, 0x4d, + 0x2d, 0xaa, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0xc8, 0x4c, 0x4a, 0xd6, 0x03, 0xc9, + 0xea, 0x81, 0x64, 0xf5, 0xca, 0x0c, 0xa5, 0x64, 0xd2, 0xf3, 0xf3, 0xd3, 0x73, 0x52, 0xf5, 0x13, + 0x0b, 0x32, 0xf5, 0x13, 0xf3, 0xf2, 0xf2, 0x4b, 0x12, 0x4b, 0x32, 0xf3, 0xf3, 0x8a, 0x21, 0xea, + 0x95, 0x34, 0xb8, 0x78, 0xc3, 0x13, 0x8b, 0x73, 0x9d, 0xf3, 0x53, 0x52, 0x03, 0x41, 0xc6, 0x08, + 0x89, 0x73, 0xb1, 0x27, 0xe7, 0xa7, 0xa4, 0xc6, 0x67, 0xa6, 0x48, 0x30, 0x2a, 0x30, 0x6a, 0x70, + 0x06, 0xb1, 0x81, 0xb8, 0x9e, 0x29, 0x4a, 0x6a, 0x5c, 0x02, 0x30, 0x95, 0x41, 0xa9, 0xc5, 0x05, + 0xf9, 0x79, 0xc5, 0xa9, 0x42, 0x42, 0x5c, 0x2c, 0x20, 0x59, 0xb0, 0x4a, 0x9e, 0x20, 0x30, 0xdb, + 0xa8, 0x9d, 0x91, 0x8b, 0x15, 0x62, 0x54, 0x1d, 0x17, 0x07, 0x4c, 0x87, 0x90, 0xbc, 0x1e, 0xba, + 0xc3, 0xf4, 0x50, 0xec, 0x95, 0x52, 0xc2, 0xad, 0x00, 0x66, 0x9d, 0x92, 0x6e, 0xd3, 0xe5, 0x27, + 0x93, 0x99, 0xd4, 0x85, 0x54, 0xf5, 0xd1, 0xc3, 0x20, 0x29, 0xb5, 0x24, 0xd1, 0x50, 0x1f, 0x64, + 0xbf, 0x7e, 0x35, 0xd4, 0xf9, 0xb5, 0x4e, 0xbe, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, + 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, + 0xc7, 0x10, 0x65, 0x9c, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x9f, 0x9c, + 0x5f, 0x9c, 0x9b, 0x5f, 0x0c, 0x32, 0x51, 0x37, 0x3d, 0x5f, 0x3f, 0x37, 0x3f, 0xa5, 0x34, 0x27, + 0xb5, 0x18, 0x62, 0xb8, 0x91, 0x85, 0x2e, 0xd8, 0xfc, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, + 0x70, 0x88, 0x19, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x6c, 0xdb, 0xe2, 0x92, 0x81, 0x01, 0x00, + 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueryClient interface { + // Get Wasm code for given code id + WasmCode(ctx context.Context, in *WasmCodeQuery, opts ...grpc.CallOption) (*WasmCodeResponse, error) +} + +type queryClient struct { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) WasmCode(ctx context.Context, in *WasmCodeQuery, opts ...grpc.CallOption) (*WasmCodeResponse, error) { + out := new(WasmCodeResponse) + err := c.cc.Invoke(ctx, "/ibc.core.wasm.v1.Query/WasmCode", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +type QueryServer interface { + // Get Wasm code for given code id + WasmCode(context.Context, *WasmCodeQuery) (*WasmCodeResponse, error) +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (*UnimplementedQueryServer) WasmCode(ctx context.Context, req *WasmCodeQuery) (*WasmCodeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method WasmCode not implemented") +} + +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +func _Query_WasmCode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(WasmCodeQuery) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).WasmCode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.wasm.v1.Query/WasmCode", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).WasmCode(ctx, req.(*WasmCodeQuery)) + } + return interceptor(ctx, in, info, handler) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "ibc.core.wasm.v1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "WasmCode", + Handler: _Query_WasmCode_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "ibc/core/wasm/v1/query.proto", +} + +func (m *WasmCodeQuery) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *WasmCodeQuery) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *WasmCodeQuery) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.CodeId) > 0 { + i -= len(m.CodeId) + copy(dAtA[i:], m.CodeId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.CodeId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *WasmCodeResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *WasmCodeResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *WasmCodeResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Code) > 0 { + i -= len(m.Code) + copy(dAtA[i:], m.Code) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Code))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *WasmCodeQuery) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.CodeId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *WasmCodeResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Code) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func sovQuery(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozQuery(x uint64) (n int) { + return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *WasmCodeQuery) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: WasmCodeQuery: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: WasmCodeQuery: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CodeId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CodeId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *WasmCodeResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: WasmCodeResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: WasmCodeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Code = append(m.Code[:0], dAtA[iNdEx:postIndex]...) + if m.Code == nil { + m.Code = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipQuery(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthQuery + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupQuery + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthQuery + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") +) diff --git a/modules/core/28-wasm/types/query.pb.gw.go b/modules/core/28-wasm/types/query.pb.gw.go new file mode 100644 index 00000000000..b7b882bdb1e --- /dev/null +++ b/modules/core/28-wasm/types/query.pb.gw.go @@ -0,0 +1,184 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: ibc/core/wasm/v1/query.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage + +func request_Query_WasmCode_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq WasmCodeQuery + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["code_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "code_id") + } + + protoReq.CodeId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "code_id", err) + } + + msg, err := client.WasmCode(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_WasmCode_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq WasmCodeQuery + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["code_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "code_id") + } + + protoReq.CodeId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "code_id", err) + } + + msg, err := server.WasmCode(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterQueryHandlerServer registers the http handlers for service Query to "mux". +// UnaryRPC :call QueryServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { + + mux.Handle("GET", pattern_Query_WasmCode_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_WasmCode_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_WasmCode_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterQueryHandler(ctx, mux, conn) +} + +// RegisterQueryHandler registers the http handlers for service Query to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn)) +} + +// RegisterQueryHandlerClient registers the http handlers for service Query +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "QueryClient" to call the correct interceptors. +func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { + + mux.Handle("GET", pattern_Query_WasmCode_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_WasmCode_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_WasmCode_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Query_WasmCode_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"ibc", "core", "wasm", "v1beta1", "code", "code_id"}, "", runtime.AssumeColonVerbOpt(true))) +) + +var ( + forward_Query_WasmCode_0 = runtime.ForwardResponseMessage +) diff --git a/modules/core/28-wasm/types/tx.pb.go b/modules/core/28-wasm/types/tx.pb.go new file mode 100644 index 00000000000..27754be921e --- /dev/null +++ b/modules/core/28-wasm/types/tx.pb.go @@ -0,0 +1,637 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ibc/core/wasm/v1/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + grpc1 "github.com/gogo/protobuf/grpc" + proto "github.com/gogo/protobuf/proto" + 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" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// Message type to push new wasm code +type MsgPushNewWasmCode struct { + Signer string `protobuf:"bytes,1,opt,name=signer,proto3" json:"signer,omitempty"` + Code []byte `protobuf:"bytes,3,opt,name=code,proto3" json:"code,omitempty"` +} + +func (m *MsgPushNewWasmCode) Reset() { *m = MsgPushNewWasmCode{} } +func (m *MsgPushNewWasmCode) String() string { return proto.CompactTextString(m) } +func (*MsgPushNewWasmCode) ProtoMessage() {} +func (*MsgPushNewWasmCode) Descriptor() ([]byte, []int) { + return fileDescriptor_e7804a9f49664df6, []int{0} +} +func (m *MsgPushNewWasmCode) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgPushNewWasmCode) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgPushNewWasmCode.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgPushNewWasmCode) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgPushNewWasmCode.Merge(m, src) +} +func (m *MsgPushNewWasmCode) XXX_Size() int { + return m.Size() +} +func (m *MsgPushNewWasmCode) XXX_DiscardUnknown() { + xxx_messageInfo_MsgPushNewWasmCode.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgPushNewWasmCode proto.InternalMessageInfo + +func (m *MsgPushNewWasmCode) GetSigner() string { + if m != nil { + return m.Signer + } + return "" +} + +func (m *MsgPushNewWasmCode) GetCode() []byte { + if m != nil { + return m.Code + } + return nil +} + +// Response in case of successful handling +type MsgPushNewWasmCodeResponse struct { + CodeId []byte `protobuf:"bytes,1,opt,name=code_id,json=codeId,proto3" json:"code_id,omitempty"` +} + +func (m *MsgPushNewWasmCodeResponse) Reset() { *m = MsgPushNewWasmCodeResponse{} } +func (m *MsgPushNewWasmCodeResponse) String() string { return proto.CompactTextString(m) } +func (*MsgPushNewWasmCodeResponse) ProtoMessage() {} +func (*MsgPushNewWasmCodeResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_e7804a9f49664df6, []int{1} +} +func (m *MsgPushNewWasmCodeResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgPushNewWasmCodeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgPushNewWasmCodeResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgPushNewWasmCodeResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgPushNewWasmCodeResponse.Merge(m, src) +} +func (m *MsgPushNewWasmCodeResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgPushNewWasmCodeResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgPushNewWasmCodeResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgPushNewWasmCodeResponse proto.InternalMessageInfo + +func (m *MsgPushNewWasmCodeResponse) GetCodeId() []byte { + if m != nil { + return m.CodeId + } + return nil +} + +func init() { + proto.RegisterType((*MsgPushNewWasmCode)(nil), "ibc.core.wasm.v1.MsgPushNewWasmCode") + proto.RegisterType((*MsgPushNewWasmCodeResponse)(nil), "ibc.core.wasm.v1.MsgPushNewWasmCodeResponse") +} + +func init() { proto.RegisterFile("ibc/core/wasm/v1/tx.proto", fileDescriptor_e7804a9f49664df6) } + +var fileDescriptor_e7804a9f49664df6 = []byte{ + // 273 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x50, 0x31, 0x4b, 0xc3, 0x40, + 0x18, 0xcd, 0x51, 0x89, 0x78, 0x14, 0x94, 0x43, 0xb4, 0x66, 0x38, 0x4a, 0x71, 0xe8, 0x60, 0xef, + 0x68, 0x8b, 0xe0, 0x28, 0x3a, 0x39, 0x44, 0x24, 0x8b, 0xe0, 0x22, 0xcd, 0xe5, 0xe3, 0x7a, 0xd0, + 0xf4, 0x0b, 0xf9, 0x92, 0x56, 0xff, 0x85, 0x3f, 0xcb, 0xb1, 0xa3, 0xa3, 0x24, 0x7f, 0x44, 0x92, + 0xea, 0xd2, 0x2e, 0x6e, 0xef, 0xf1, 0x1e, 0xef, 0x3d, 0x1e, 0xbf, 0x70, 0xb1, 0xd1, 0x06, 0x73, + 0xd0, 0xeb, 0x19, 0xa5, 0x7a, 0x35, 0xd6, 0xc5, 0x9b, 0xca, 0x72, 0x2c, 0x50, 0x9c, 0xb8, 0xd8, + 0xa8, 0x46, 0x52, 0x8d, 0xa4, 0x56, 0xe3, 0xe0, 0xd4, 0xa2, 0xc5, 0x56, 0xd4, 0x0d, 0xda, 0xfa, + 0x06, 0xb7, 0x5c, 0x84, 0x64, 0x9f, 0x4a, 0x9a, 0x3f, 0xc2, 0xfa, 0x79, 0x46, 0xe9, 0x3d, 0x26, + 0x20, 0xce, 0xb8, 0x4f, 0xce, 0x2e, 0x21, 0xef, 0xb1, 0x3e, 0x1b, 0x1e, 0x45, 0xbf, 0x4c, 0x08, + 0x7e, 0x60, 0x30, 0x81, 0x5e, 0xa7, 0xcf, 0x86, 0xdd, 0xa8, 0xc5, 0x83, 0x6b, 0x1e, 0xec, 0x27, + 0x44, 0x40, 0x19, 0x2e, 0x09, 0xc4, 0x39, 0x3f, 0x6c, 0x5c, 0xaf, 0x2e, 0x69, 0xa3, 0xba, 0x91, + 0xdf, 0xd0, 0x87, 0x64, 0xb2, 0xe0, 0x9d, 0x90, 0xac, 0x00, 0x7e, 0xbc, 0x5b, 0x7e, 0xa9, 0x76, + 0xb7, 0xab, 0xfd, 0x82, 0xe0, 0xea, 0x3f, 0xae, 0xbf, 0x19, 0x77, 0xe1, 0x67, 0x25, 0xd9, 0xa6, + 0x92, 0xec, 0xbb, 0x92, 0xec, 0xa3, 0x96, 0xde, 0xa6, 0x96, 0xde, 0x57, 0x2d, 0xbd, 0x97, 0xa9, + 0x75, 0xc5, 0xbc, 0x8c, 0x95, 0xc1, 0x54, 0x1b, 0xa4, 0x14, 0x49, 0xbb, 0xd8, 0x8c, 0x2c, 0xea, + 0x14, 0x93, 0x72, 0x01, 0xb4, 0x3d, 0x78, 0x72, 0x33, 0x6a, 0x3f, 0x2e, 0xde, 0x33, 0xa0, 0xd8, + 0x6f, 0xcf, 0x9b, 0xfe, 0x04, 0x00, 0x00, 0xff, 0xff, 0x38, 0xbc, 0x3b, 0x40, 0x81, 0x01, 0x00, + 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MsgClient interface { + // PushNewWasmCode defines a rpc handler method for PushNewWasmCode. + PushNewWasmCode(ctx context.Context, in *MsgPushNewWasmCode, opts ...grpc.CallOption) (*MsgPushNewWasmCodeResponse, error) +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) PushNewWasmCode(ctx context.Context, in *MsgPushNewWasmCode, opts ...grpc.CallOption) (*MsgPushNewWasmCodeResponse, error) { + out := new(MsgPushNewWasmCodeResponse) + err := c.cc.Invoke(ctx, "/ibc.core.wasm.v1.Msg/PushNewWasmCode", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { + // PushNewWasmCode defines a rpc handler method for PushNewWasmCode. + PushNewWasmCode(context.Context, *MsgPushNewWasmCode) (*MsgPushNewWasmCodeResponse, error) +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (*UnimplementedMsgServer) PushNewWasmCode(ctx context.Context, req *MsgPushNewWasmCode) (*MsgPushNewWasmCodeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PushNewWasmCode not implemented") +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +func _Msg_PushNewWasmCode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgPushNewWasmCode) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).PushNewWasmCode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.wasm.v1.Msg/PushNewWasmCode", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).PushNewWasmCode(ctx, req.(*MsgPushNewWasmCode)) + } + return interceptor(ctx, in, info, handler) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "ibc.core.wasm.v1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "PushNewWasmCode", + Handler: _Msg_PushNewWasmCode_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "ibc/core/wasm/v1/tx.proto", +} + +func (m *MsgPushNewWasmCode) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgPushNewWasmCode) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgPushNewWasmCode) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Code) > 0 { + i -= len(m.Code) + copy(dAtA[i:], m.Code) + i = encodeVarintTx(dAtA, i, uint64(len(m.Code))) + i-- + dAtA[i] = 0x1a + } + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgPushNewWasmCodeResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgPushNewWasmCodeResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgPushNewWasmCodeResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.CodeId) > 0 { + i -= len(m.CodeId) + copy(dAtA[i:], m.CodeId) + i = encodeVarintTx(dAtA, i, uint64(len(m.CodeId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintTx(dAtA []byte, offset int, v uint64) int { + offset -= sovTx(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgPushNewWasmCode) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Code) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgPushNewWasmCodeResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.CodeId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func sovTx(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTx(x uint64) (n int) { + return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *MsgPushNewWasmCode) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgPushNewWasmCode: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgPushNewWasmCode: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Code = append(m.Code[:0], dAtA[iNdEx:postIndex]...) + if m.Code == nil { + m.Code = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgPushNewWasmCodeResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgPushNewWasmCodeResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgPushNewWasmCodeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CodeId", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CodeId = append(m.CodeId[:0], dAtA[iNdEx:postIndex]...) + if m.CodeId == nil { + m.CodeId = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTx(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthTx + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTx + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTx + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTx = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTx = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTx = fmt.Errorf("proto: unexpected end of group") +) diff --git a/modules/core/client/cli/cli.go b/modules/core/client/cli/cli.go index 687806b1c15..db985789d59 100644 --- a/modules/core/client/cli/cli.go +++ b/modules/core/client/cli/cli.go @@ -8,6 +8,7 @@ import ( connection "github.com/cosmos/ibc-go/modules/core/03-connection" channel "github.com/cosmos/ibc-go/modules/core/04-channel" host "github.com/cosmos/ibc-go/modules/core/24-host" + wasmmanager "github.com/cosmos/ibc-go/modules/core/28-wasm" ) // GetTxCmd returns the transaction commands for this module @@ -23,6 +24,7 @@ func GetTxCmd() *cobra.Command { ibcTxCmd.AddCommand( ibcclient.GetTxCmd(), channel.GetTxCmd(), + wasmmanager.GetTxCmd(), ) return ibcTxCmd @@ -43,6 +45,7 @@ func GetQueryCmd() *cobra.Command { ibcclient.GetQueryCmd(), connection.GetQueryCmd(), channel.GetQueryCmd(), + wasmmanager.GetQueryCmd(), ) return ibcQueryCmd diff --git a/modules/core/exported/client.go b/modules/core/exported/client.go index 8de7976c14c..f5a9bcd5bd6 100644 --- a/modules/core/exported/client.go +++ b/modules/core/exported/client.go @@ -25,6 +25,9 @@ const ( // for the localhost client. Localhost string = "09-localhost" + // Wasm is used to indicate that the light client is a on-chain Wasm program + Wasm string = "10-wasm" + // Active is a status type of a client. An active client is allowed to be used. Active Status = "Active" diff --git a/modules/core/keeper/grpc_query.go b/modules/core/keeper/grpc_query.go index f647ab5aceb..d706cafd441 100644 --- a/modules/core/keeper/grpc_query.go +++ b/modules/core/keeper/grpc_query.go @@ -6,6 +6,7 @@ import ( clienttypes "github.com/cosmos/ibc-go/modules/core/02-client/types" connectiontypes "github.com/cosmos/ibc-go/modules/core/03-connection/types" channeltypes "github.com/cosmos/ibc-go/modules/core/04-channel/types" + wasmtypes "github.com/cosmos/ibc-go/modules/core/28-wasm/types" ) // ClientState implements the IBC QueryServer interface @@ -132,3 +133,8 @@ func (q Keeper) UnreceivedAcks(c context.Context, req *channeltypes.QueryUnrecei func (q Keeper) NextSequenceReceive(c context.Context, req *channeltypes.QueryNextSequenceReceiveRequest) (*channeltypes.QueryNextSequenceReceiveResponse, error) { return q.ChannelKeeper.NextSequenceReceive(c, req) } + +// WasmCode implements the IBC QueryServer interface +func (q Keeper) WasmCode(c context.Context, req *wasmtypes.WasmCodeQuery) (*wasmtypes.WasmCodeResponse, error) { + return q.WasmKeeper.WasmCode(c, req) +} diff --git a/modules/core/keeper/keeper.go b/modules/core/keeper/keeper.go index 164fecfcd23..05eb27c9555 100644 --- a/modules/core/keeper/keeper.go +++ b/modules/core/keeper/keeper.go @@ -12,6 +12,7 @@ import ( channelkeeper "github.com/cosmos/ibc-go/modules/core/04-channel/keeper" portkeeper "github.com/cosmos/ibc-go/modules/core/05-port/keeper" porttypes "github.com/cosmos/ibc-go/modules/core/05-port/types" + wasmkeeper "github.com/cosmos/ibc-go/modules/core/28-wasm/keeper" "github.com/cosmos/ibc-go/modules/core/types" ) @@ -28,6 +29,7 @@ type Keeper struct { ConnectionKeeper connectionkeeper.Keeper ChannelKeeper channelkeeper.Keeper PortKeeper portkeeper.Keeper + WasmKeeper wasmkeeper.Keeper Router *porttypes.Router } @@ -49,6 +51,15 @@ func NewKeeper( connectionKeeper := connectionkeeper.NewKeeper(cdc, key, paramSpace, clientKeeper) portKeeper := portkeeper.NewKeeper(scopedKeeper) channelKeeper := channelkeeper.NewKeeper(cdc, key, clientKeeper, connectionKeeper, portKeeper, scopedKeeper) + wasmKeeper := wasmkeeper.NewKeeper(cdc, key, &wasmkeeper.VMConfig{ + DataDir: "wasm_data", + SupportedFeatures: []string{"staking"}, + MemoryLimitMb: 8, + PrintDebug: true, + CacheSizeMb: 8, + }, &wasmkeeper.ValidationConfig{ + MaxSizeAllowed: 1024 * 1024, // 1 MB + }) return &Keeper{ cdc: cdc, @@ -56,6 +67,7 @@ func NewKeeper( ConnectionKeeper: connectionKeeper, ChannelKeeper: channelKeeper, PortKeeper: portKeeper, + WasmKeeper: wasmKeeper, } } diff --git a/modules/core/keeper/msg_server.go b/modules/core/keeper/msg_server.go index 2edcdd157c2..f3c3960313c 100644 --- a/modules/core/keeper/msg_server.go +++ b/modules/core/keeper/msg_server.go @@ -2,6 +2,7 @@ package keeper import ( "context" + "encoding/hex" "github.com/armon/go-metrics" @@ -13,11 +14,36 @@ import ( channel "github.com/cosmos/ibc-go/modules/core/04-channel" channeltypes "github.com/cosmos/ibc-go/modules/core/04-channel/types" porttypes "github.com/cosmos/ibc-go/modules/core/05-port/types" + wasm "github.com/cosmos/ibc-go/modules/core/28-wasm" + wasmtypes "github.com/cosmos/ibc-go/modules/core/28-wasm/types" ) var _ clienttypes.MsgServer = Keeper{} var _ connectiontypes.MsgServer = Keeper{} var _ channeltypes.MsgServer = Keeper{} +var _ wasmtypes.MsgServer = Keeper{} + +// PushNewWasmCode defines a rpc handler method for MsgPushNewWasmCode +func (k Keeper) PushNewWasmCode(goCtx context.Context, msg *wasmtypes.MsgPushNewWasmCode) (*wasmtypes.MsgPushNewWasmCodeResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + response, err := wasm.HandleMsgPushNewWasmCode(ctx, k.WasmKeeper, msg) + if err != nil { + return nil, err + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + clienttypes.EventTypePushWasmCode, + sdk.NewAttribute(clienttypes.AttributeKeyWasmCodeID, hex.EncodeToString(response.CodeId)), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, clienttypes.AttributeValueCategory), + ), + }) + + return response, nil +} // CreateClient defines a rpc handler method for MsgCreateClient. func (k Keeper) CreateClient(goCtx context.Context, msg *clienttypes.MsgCreateClient) (*clienttypes.MsgCreateClientResponse, error) { diff --git a/modules/core/module.go b/modules/core/module.go index 1d338dcb69e..3d12190bd21 100644 --- a/modules/core/module.go +++ b/modules/core/module.go @@ -18,6 +18,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + wasmtypes "github.com/cosmos/ibc-go/modules/core/28-wasm/types" ibcclient "github.com/cosmos/ibc-go/modules/core/02-client" clienttypes "github.com/cosmos/ibc-go/modules/core/02-client/types" connectiontypes "github.com/cosmos/ibc-go/modules/core/03-connection/types" @@ -72,6 +73,7 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *r clienttypes.RegisterQueryHandlerClient(context.Background(), mux, clienttypes.NewQueryClient(clientCtx)) connectiontypes.RegisterQueryHandlerClient(context.Background(), mux, connectiontypes.NewQueryClient(clientCtx)) channeltypes.RegisterQueryHandlerClient(context.Background(), mux, channeltypes.NewQueryClient(clientCtx)) + wasmtypes.RegisterQueryHandlerClient(context.Background(), mux, wasmtypes.NewQueryClient(clientCtx)) } // GetTxCmd returns the root tx command for the ibc module. @@ -135,6 +137,7 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { clienttypes.RegisterMsgServer(cfg.MsgServer(), am.keeper) connectiontypes.RegisterMsgServer(cfg.MsgServer(), am.keeper) channeltypes.RegisterMsgServer(cfg.MsgServer(), am.keeper) + wasmtypes.RegisterMsgServer(cfg.MsgServer(), am.keeper) types.RegisterQueryService(cfg.QueryServer(), am.keeper) } diff --git a/modules/core/types/codec.go b/modules/core/types/codec.go index 83aa034d35b..82593e1d1ce 100644 --- a/modules/core/types/codec.go +++ b/modules/core/types/codec.go @@ -2,6 +2,8 @@ package types import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" + wasmmanagertypes "github.com/cosmos/ibc-go/modules/core/28-wasm/types" + wasmtypes "github.com/cosmos/ibc-go/modules/light-clients/10-wasm/types" clienttypes "github.com/cosmos/ibc-go/modules/core/02-client/types" connectiontypes "github.com/cosmos/ibc-go/modules/core/03-connection/types" channeltypes "github.com/cosmos/ibc-go/modules/core/04-channel/types" @@ -17,7 +19,9 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { connectiontypes.RegisterInterfaces(registry) channeltypes.RegisterInterfaces(registry) solomachinetypes.RegisterInterfaces(registry) + wasmtypes.RegisterInterfaces(registry) ibctmtypes.RegisterInterfaces(registry) localhosttypes.RegisterInterfaces(registry) commitmenttypes.RegisterInterfaces(registry) + wasmmanagertypes.RegisterInterfaces(registry) } diff --git a/modules/core/types/query.go b/modules/core/types/query.go index a4a4bd5448c..838f447a925 100644 --- a/modules/core/types/query.go +++ b/modules/core/types/query.go @@ -3,6 +3,8 @@ package types import ( "github.com/gogo/protobuf/grpc" + wasm "github.com/cosmos/ibc-go/modules/core/28-wasm" + wasmtypes "github.com/cosmos/ibc-go/modules/core/28-wasm/types" client "github.com/cosmos/ibc-go/modules/core/02-client" clienttypes "github.com/cosmos/ibc-go/modules/core/02-client/types" connection "github.com/cosmos/ibc-go/modules/core/03-connection" @@ -16,6 +18,7 @@ type QueryServer interface { clienttypes.QueryServer connectiontypes.QueryServer channeltypes.QueryServer + wasmtypes.QueryServer } // RegisterQueryService registers each individual IBC submodule query service @@ -23,4 +26,5 @@ func RegisterQueryService(server grpc.Server, queryService QueryServer) { client.RegisterQueryService(server, queryService) connection.RegisterQueryService(server, queryService) channel.RegisterQueryService(server, queryService) + wasm.RegisterQueryService(server, queryService) } diff --git a/modules/light-clients/07-tendermint/types/tendermint.pb.go b/modules/light-clients/07-tendermint/types/tendermint.pb.go index 84a79b66668..9a0645a4462 100644 --- a/modules/light-clients/07-tendermint/types/tendermint.pb.go +++ b/modules/light-clients/07-tendermint/types/tendermint.pb.go @@ -11,10 +11,10 @@ import ( _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" - _ "github.com/golang/protobuf/ptypes/duration" - _ "github.com/golang/protobuf/ptypes/timestamp" github_com_tendermint_tendermint_libs_bytes "github.com/tendermint/tendermint/libs/bytes" types2 "github.com/tendermint/tendermint/proto/tendermint/types" + _ "google.golang.org/protobuf/types/known/durationpb" + _ "google.golang.org/protobuf/types/known/timestamppb" io "io" math "math" math_bits "math/bits" diff --git a/modules/light-clients/10-wasm/doc.go b/modules/light-clients/10-wasm/doc.go new file mode 100644 index 00000000000..955e5a9a88b --- /dev/null +++ b/modules/light-clients/10-wasm/doc.go @@ -0,0 +1 @@ +package wasm diff --git a/modules/light-clients/10-wasm/module.go b/modules/light-clients/10-wasm/module.go new file mode 100644 index 00000000000..0eb880705d4 --- /dev/null +++ b/modules/light-clients/10-wasm/module.go @@ -0,0 +1,10 @@ +package wasm + +import ( + "github.com/cosmos/ibc-go/modules/light-clients/10-wasm/types" +) + +// Name returns the IBC client name +func Name() string { + return types.SubModuleName +} diff --git a/modules/light-clients/10-wasm/types/client_state.go b/modules/light-clients/10-wasm/types/client_state.go new file mode 100644 index 00000000000..ec968066e29 --- /dev/null +++ b/modules/light-clients/10-wasm/types/client_state.go @@ -0,0 +1,662 @@ +package types + +import ( + "encoding/json" + "fmt" + + "github.com/CosmWasm/wasmvm/api" + ics23 "github.com/confio/ics23/go" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + clienttypes "github.com/cosmos/ibc-go/modules/core/02-client/types" + "github.com/cosmos/ibc-go/modules/core/exported" +) + +func (c *ClientState) Initialize(context sdk.Context, marshaler codec.BinaryCodec, store sdk.KVStore, state exported.ConsensusState) error { + const InitializeState = "initializestate" + payload := make(map[string]map[string]interface{}) + payload[InitializeState] = make(map[string]interface{}) + inner := payload[InitializeState] + inner["me"] = c + inner["consensus_state"] = state + + encodedData, err := json.Marshal(payload) + if err != nil { + return sdkerrors.Wrapf(ErrUnableToMarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + + // Under the hood there are two calls to wasm contract for initialization as by design + // cosmwasm does not allow init call to return any value. + + _, err = initContract(c.CodeId, context, store, encodedData) + if err != nil { + return sdkerrors.Wrapf(ErrUnableToInit, fmt.Sprintf("underlying error: %s", err.Error())) + } + + out, err := callContract(c.CodeId, context, store, encodedData) + if err != nil { + return sdkerrors.Wrapf(ErrUnableToCall, fmt.Sprintf("underlying error: %s", err.Error())) + } + output := clientStateCallResponse{} + if err := json.Unmarshal(out.Data, &output); err != nil { + return sdkerrors.Wrapf(ErrUnableToUnmarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + if !output.Result.IsValid { + return fmt.Errorf("%s error occurred while initializing client state", output.Result.ErrorMsg) + } + output.resetImmutables(c) + + *c = *output.Me + return nil +} + +func (c *ClientState) CheckHeaderAndUpdateState(context sdk.Context, marshaler codec.BinaryCodec, store sdk.KVStore, header exported.Header) (exported.ClientState, exported.ConsensusState, error) { + consensusState, err := GetConsensusState(store, marshaler, c.LatestHeight) + if err != nil { + return nil, nil, sdkerrors.Wrapf(err, "could not get trusted consensus state from clientStore for Header at Height: %s", header.GetHeight()) + } + + const CheckHeaderAndUpdateState = "checkheaderandupdatestate" + payload := make(map[string]map[string]interface{}) + payload[CheckHeaderAndUpdateState] = make(map[string]interface{}) + inner := payload[CheckHeaderAndUpdateState] + inner["me"] = c + inner["header"] = header + inner["consensus_state"] = consensusState + + encodedData, err := json.Marshal(payload) + if err != nil { + return nil, nil, sdkerrors.Wrapf(ErrUnableToMarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + out, err := callContract(c.CodeId, context, store, encodedData) + if err != nil { + return nil, nil, sdkerrors.Wrapf(ErrUnableToCall, fmt.Sprintf("underlying error: %s", err.Error())) + } + output := clientStateCallResponse{} + if err := json.Unmarshal(out.Data, &output); err != nil { + return nil, nil, sdkerrors.Wrapf(ErrUnableToUnmarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + if !output.Result.IsValid { + return nil, nil, fmt.Errorf("%s error occurred while updating client state", output.Result.ErrorMsg) + } + output.resetImmutables(c) + return output.NewClientState, output.NewConsensusState, nil +} + +func (c *ClientState) CheckMisbehaviourAndUpdateState(context sdk.Context, marshaler codec.BinaryCodec, store sdk.KVStore, misbehaviour exported.Misbehaviour) (exported.ClientState, error) { + wasmMisbehaviour, ok := misbehaviour.(*Misbehaviour) + if !ok { + return nil, sdkerrors.Wrapf( + clienttypes.ErrInvalidMisbehaviour, + "invalid misbehaviour type %T, expected %T", wasmMisbehaviour, &Misbehaviour{}, + ) + } + + // Get consensus bytes from clientStore + consensusState1, err := GetConsensusState(store, marshaler, wasmMisbehaviour.Header1.Height) + if err != nil { + return nil, sdkerrors.Wrapf(err, "could not get trusted consensus state from clientStore for Header1 at Height: %s", wasmMisbehaviour.Header1) + } + + // Get consensus bytes from clientStore + consensusState2, err := GetConsensusState(store, marshaler, wasmMisbehaviour.Header2.Height) + if err != nil { + return nil, sdkerrors.Wrapf(err, "could not get trusted consensus state from clientStore for Header2 at Height: %s", wasmMisbehaviour.Header2) + } + + const CheckMisbehaviourAndUpdateState = "checkmisbehaviourandupdatestate" + payload := make(map[string]map[string]interface{}) + payload[CheckMisbehaviourAndUpdateState] = make(map[string]interface{}) + inner := payload[CheckMisbehaviourAndUpdateState] + inner["me"] = c + inner["misbehaviour"] = wasmMisbehaviour + inner["consensus_state1"] = consensusState1 + inner["consensus_state2"] = consensusState2 + + encodedData, err := json.Marshal(payload) + if err != nil { + return nil, sdkerrors.Wrapf(ErrUnableToMarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + out, err := callContract(c.CodeId, context, store, encodedData) + if err != nil { + return nil, sdkerrors.Wrapf(ErrUnableToCall, fmt.Sprintf("underlying error: %s", err.Error())) + } + output := clientStateCallResponse{} + if err := json.Unmarshal(out.Data, &output); err != nil { + return nil, sdkerrors.Wrapf(ErrUnableToUnmarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + if !output.Result.IsValid { + return nil, fmt.Errorf("%s error occurred while updating client state", output.Result.ErrorMsg) + } + output.resetImmutables(c) + return output.NewClientState, nil +} + +func (c *ClientState) CheckSubstituteAndUpdateState( + ctx sdk.Context, cdc codec.BinaryCodec, subjectClientStore, + substituteClientStore sdk.KVStore, substituteClient exported.ClientState, + initialHeight exported.Height, +) (exported.ClientState, error) { + var ( + SubjectPrefix = []byte("subject/") + SubstitutePrefix = []byte("substitute/") + ) + + consensusState, err := GetConsensusState(subjectClientStore, cdc, c.LatestHeight) + if err != nil { + return nil, sdkerrors.Wrapf( + err, "unexpected error: could not get consensus state from clientstore at height: %d", c.GetLatestHeight(), + ) + } + + store := NewWrappedStore(subjectClientStore, subjectClientStore, SubjectPrefix, SubstitutePrefix) + + const CheckSubstituteAndUpdateState = "checksubstituteandupdatestate" + payload := make(map[string]map[string]interface{}) + payload[CheckSubstituteAndUpdateState] = make(map[string]interface{}) + inner := payload[CheckSubstituteAndUpdateState] + inner["me"] = c + inner["subject_consensus_state"] = consensusState + inner["substitute_client_state"] = substituteClient + inner["initial_height"] = initialHeight + + encodedData, err := json.Marshal(payload) + if err != nil { + return nil, sdkerrors.Wrapf(ErrUnableToMarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + out, err := callContract(c.CodeId, ctx, store, encodedData) + if err != nil { + return nil, sdkerrors.Wrapf(ErrUnableToCall, fmt.Sprintf("underlying error: %s", err.Error())) + } + output := clientStateCallResponse{} + if err := json.Unmarshal(out.Data, &output); err != nil { + return nil, sdkerrors.Wrapf(ErrUnableToUnmarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + if !output.Result.IsValid { + return nil, fmt.Errorf("%s error occurred while updating client state", output.Result.ErrorMsg) + } + + output.resetImmutables(c) + return output.NewClientState, nil +} + +func (c *ClientState) VerifyUpgradeAndUpdateState(ctx sdk.Context, cdc codec.BinaryCodec, store sdk.KVStore, newClient exported.ClientState, newConsState exported.ConsensusState, proofUpgradeClient, proofUpgradeConsState []byte) (exported.ClientState, exported.ConsensusState, error) { + wasmUpgradeConsState, ok := newConsState.(*ConsensusState) + if !ok { + return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidConsensus, "upgraded consensus state must be Tendermint consensus state. expected %T, got: %T", + &ConsensusState{}, wasmUpgradeConsState) + } + + // last height of current counterparty chain must be client's latest height + lastHeight := c.LatestHeight + lastHeightConsensusState, err := GetConsensusState(store, cdc, lastHeight) + if err != nil { + return nil, nil, sdkerrors.Wrap(err, "could not retrieve consensus state for lastHeight") + } + + const VerifyUpgradeAndUpdateState = "verifyupgradeandupdatestate" + payload := make(map[string]map[string]interface{}) + payload[VerifyUpgradeAndUpdateState] = make(map[string]interface{}) + inner := payload[VerifyUpgradeAndUpdateState] + inner["me"] = c + inner["new_client_state"] = newClient + inner["new_consensus_state"] = newConsState + inner["client_upgrade_proof"] = proofUpgradeClient + inner["consensus_state_upgrade_proof"] = proofUpgradeConsState + inner["last_height_consensus_state"] = lastHeightConsensusState + + encodedData, err := json.Marshal(payload) + if err != nil { + return nil, nil, sdkerrors.Wrapf(ErrUnableToMarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + out, err := callContract(c.CodeId, ctx, store, encodedData) + if err != nil { + return nil, nil, sdkerrors.Wrapf(ErrUnableToCall, fmt.Sprintf("underlying error: %s", err.Error())) + } + output := clientStateCallResponse{} + if err := json.Unmarshal(out.Data, &output); err != nil { + return nil, nil, sdkerrors.Wrapf(ErrUnableToUnmarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + if !output.Result.IsValid { + return nil, nil, fmt.Errorf("%s error occurred while updating client state", output.Result.ErrorMsg) + } + output.resetImmutables(c) + return output.NewClientState, output.NewConsensusState, nil +} + +func (c *ClientState) ZeroCustomFields() exported.ClientState { + const ZeroCustomFields = "zerocustomfields" + payload := make(map[string]map[string]interface{}) + payload[ZeroCustomFields] = make(map[string]interface{}) + inner := payload[ZeroCustomFields] + inner["me"] = c + + encodedData, err := json.Marshal(payload) + if err != nil { + // TODO: Handle error + } + + gasMeter := sdk.NewGasMeter(maxGasLimit) + out, err := callContractWithEnvAndMeter(c.CodeId, nil, &FailKVStore{}, api.MockEnv(), gasMeter, encodedData) + if err != nil { + // TODO: Handle error + } + output := clientStateCallResponse{} + if err := json.Unmarshal(out.Data, &output); err != nil { + // TODO: Handle error + } + output.resetImmutables(c) + return output.Me +} + +/** +Following functions only queries the state so should be part of query call +*/ + +func (c *ClientState) ClientType() string { + return exported.Wasm +} + +func (c *ClientState) ExportMetadata(store sdk.KVStore) []exported.GenesisMetadata { + const ExportMetadataQuery = "exportmetadata" + payload := make(map[string]map[string]interface{}) + payload[ExportMetadataQuery] = make(map[string]interface{}) + inner := payload[ExportMetadataQuery] + inner["me"] = c + + encodedData, err := json.Marshal(payload) + if err != nil { + // TODO: Handle error + } + response, err := queryContractWithStore(c.CodeId, store, encodedData) + if err != nil { + // TODO: Handle error + } + + output := queryResponse{} + if err := json.Unmarshal(response, &output); err != nil { + // TODO: Handle error + } + + genesisMetadata := make([]exported.GenesisMetadata, len(output.GenesisMetadata)) + for i, metadata := range output.GenesisMetadata { + genesisMetadata[i] = metadata + } + return genesisMetadata +} + +func (c *ClientState) GetLatestHeight() exported.Height { + return c.LatestHeight +} + +func (c *ClientState) Status(ctx sdk.Context, store sdk.KVStore, cdc codec.BinaryCodec) exported.Status { + consensusState, err := GetConsensusState(store, cdc, c.LatestHeight) + if err != nil { + return exported.Unknown + } + + const Status = "status" + payload := make(map[string]map[string]interface{}) + payload[Status] = make(map[string]interface{}) + inner := payload[Status] + inner["me"] = c + inner["consensus_state"] = consensusState + + encodedData, err := json.Marshal(payload) + if err != nil { + return exported.Unknown + } + + response, err := queryContractWithStore(c.CodeId, store, encodedData) + if err != nil { + return exported.Unknown + } + + output := queryResponse{} + if err := json.Unmarshal(response, &output); err != nil { + return exported.Unknown + } + + return output.Status +} + +func (c *ClientState) Validate() error { + if c.Data == nil || len(c.Data) == 0 { + return fmt.Errorf("data cannot be empty") + } + + if c.CodeId == nil || len(c.CodeId) == 0 { + return fmt.Errorf("codeid cannot be empty") + } + + return nil +} + +func (c *ClientState) GetProofSpecs() []*ics23.ProofSpec { + return c.ProofSpecs +} + +func (c *ClientState) VerifyClientState(store sdk.KVStore, cdc codec.BinaryCodec, height exported.Height, prefix exported.Prefix, counterpartyClientIdentifier string, proof []byte, clientState exported.ClientState) error { + consensusState, err := GetConsensusState(store, cdc, height) + if err != nil { + return err + } + const VerifyClientStateQuery = "verifyclientstate" + payload := make(map[string]map[string]interface{}) + payload[VerifyClientStateQuery] = make(map[string]interface{}) + inner := payload[VerifyClientStateQuery] + inner["me"] = c + inner["height"] = height + inner["commitment_prefix"] = prefix + inner["counterparty_client_identifier"] = counterpartyClientIdentifier + inner["proof"] = proof + inner["counterparty_client_state"] = clientState + inner["consensus_state"] = consensusState + encodedData, err := json.Marshal(payload) + if err != nil { + return sdkerrors.Wrapf(ErrUnableToMarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + response, err := queryContractWithStore(c.CodeId, store, encodedData) + if err != nil { + return sdkerrors.Wrapf(ErrUnableToQuery, fmt.Sprintf("underlying error: %s", err.Error())) + } + output := queryResponse{} + if err := json.Unmarshal(response, &output); err != nil { + return sdkerrors.Wrapf(ErrUnableToUnmarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + if output.Result.IsValid { + return nil + } + + return fmt.Errorf("%s error while validating client state", output.Result.ErrorMsg) +} + +func (c *ClientState) VerifyClientConsensusState(store sdk.KVStore, cdc codec.BinaryCodec, height exported.Height, counterpartyClientIdentifier string, consensusHeight exported.Height, prefix exported.Prefix, proof []byte, consensusState exported.ConsensusState) error { + currentConsensusState, err := GetConsensusState(store, cdc, height) + if err != nil { + return err + } + + const VerifyClientConsensusStateQuery = "verifyclientconsensusstate" + payload := make(map[string]map[string]interface{}) + payload[VerifyClientConsensusStateQuery] = make(map[string]interface{}) + inner := payload[VerifyClientConsensusStateQuery] + inner["me"] = c + inner["height"] = height + inner["consensus_height"] = consensusHeight + inner["commitment_prefix"] = prefix + inner["counterparty_client_identifier"] = counterpartyClientIdentifier + inner["proof"] = proof + inner["counterparty_consensus_state"] = consensusState + inner["consensus_state"] = currentConsensusState + + encodedData, err := json.Marshal(payload) + if err != nil { + return sdkerrors.Wrapf(ErrUnableToMarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + response, err := queryContractWithStore(c.CodeId, store, encodedData) + if err != nil { + return sdkerrors.Wrapf(ErrUnableToQuery, fmt.Sprintf("underlying error: %s", err.Error())) + } + + output := queryResponse{} + if err := json.Unmarshal(response, &output); err != nil { + return sdkerrors.Wrapf(ErrUnableToUnmarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + + if output.Result.IsValid { + return nil + } + + return fmt.Errorf("%s error while verifying consensus state", output.Result.ErrorMsg) +} + +func (c *ClientState) VerifyConnectionState(store sdk.KVStore, cdc codec.BinaryCodec, height exported.Height, prefix exported.Prefix, proof []byte, connectionID string, connectionEnd exported.ConnectionI) error { + consensusState, err := GetConsensusState(store, cdc, height) + if err != nil { + return err + } + + const VerifyConnectionStateQuery = "verifyconnectionstate" + payload := make(map[string]map[string]interface{}) + payload[VerifyConnectionStateQuery] = make(map[string]interface{}) + inner := payload[VerifyConnectionStateQuery] + inner["me"] = c + inner["height"] = height + inner["commitment_prefix"] = prefix + inner["proof"] = proof + inner["connection_id"] = connectionID + inner["connection_end"] = connectionEnd + inner["consensus_state"] = consensusState + + encodedData, err := json.Marshal(payload) + if err != nil { + return sdkerrors.Wrapf(ErrUnableToMarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + response, err := queryContractWithStore(c.CodeId, store, encodedData) + if err != nil { + return sdkerrors.Wrapf(ErrUnableToQuery, fmt.Sprintf("underlying error: %s", err.Error())) + } + + output := queryResponse{} + if err := json.Unmarshal(response, &output); err != nil { + return sdkerrors.Wrapf(ErrUnableToUnmarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + + if output.Result.IsValid { + return nil + } + + return fmt.Errorf("%s error while verifying connection state", output.Result.ErrorMsg) +} + +func (c *ClientState) VerifyChannelState(store sdk.KVStore, cdc codec.BinaryCodec, height exported.Height, prefix exported.Prefix, proof []byte, portID, channelID string, channel exported.ChannelI) error { + consensusState, err := GetConsensusState(store, cdc, height) + if err != nil { + return err + } + + const VerifyChannelStateQuery = "verifychannelstate" + payload := make(map[string]map[string]interface{}) + payload[VerifyChannelStateQuery] = make(map[string]interface{}) + inner := payload[VerifyChannelStateQuery] + inner["me"] = c + inner["height"] = height + inner["commitment_prefix"] = prefix + inner["proof"] = proof + inner["port_id"] = portID + inner["channel_id"] = channelID + inner["channel"] = channel + inner["consensus_state"] = consensusState + + encodedData, err := json.Marshal(payload) + if err != nil { + return sdkerrors.Wrapf(ErrUnableToMarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + response, err := queryContractWithStore(c.CodeId, store, encodedData) + if err != nil { + return sdkerrors.Wrapf(ErrUnableToQuery, fmt.Sprintf("underlying error: %s", err.Error())) + } + + output := queryResponse{} + if err := json.Unmarshal(response, &output); err != nil { + return sdkerrors.Wrapf(ErrUnableToUnmarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + + if output.Result.IsValid { + return nil + } + + return fmt.Errorf("%s error while verifying channel state", output.Result.ErrorMsg) +} + +func (c *ClientState) VerifyPacketCommitment(ctx sdk.Context, store sdk.KVStore, cdc codec.BinaryCodec, height exported.Height, delayTimePeriod, delayBlockPeriod uint64, prefix exported.Prefix, proof []byte, portID, channelID string, sequence uint64, commitmentBytes []byte) error { + consensusState, err := GetConsensusState(store, cdc, height) + if err != nil { + return err + } + + const VerifyPacketCommitmentQuery = "verifypacketcommitment" + payload := make(map[string]map[string]interface{}) + payload[VerifyPacketCommitmentQuery] = make(map[string]interface{}) + inner := payload[VerifyPacketCommitmentQuery] + inner["me"] = c + inner["height"] = height + inner["commitment_prefix"] = prefix + inner["proof"] = proof + inner["port_id"] = portID + inner["channel_id"] = channelID + inner["delay_time_period"] = delayTimePeriod + inner["delay_block_period"] = delayBlockPeriod + inner["sequence"] = sequence + inner["commitment_bytes"] = commitmentBytes + inner["consensus_state"] = consensusState + + encodedData, err := json.Marshal(payload) + if err != nil { + return sdkerrors.Wrapf(ErrUnableToMarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + response, err := queryContractWithStore(c.CodeId, store, encodedData) + if err != nil { + return sdkerrors.Wrapf(ErrUnableToQuery, fmt.Sprintf("underlying error: %s", err.Error())) + } + + output := queryResponse{} + if err := json.Unmarshal(response, &output); err != nil { + return sdkerrors.Wrapf(ErrUnableToUnmarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + + if output.Result.IsValid { + return nil + } + + return fmt.Errorf("%s error while verifying packet commitment", output.Result.ErrorMsg) +} + +func (c *ClientState) VerifyPacketAcknowledgement(ctx sdk.Context, store sdk.KVStore, cdc codec.BinaryCodec, height exported.Height, delayTimePeriod, delayBlockPeriod uint64, prefix exported.Prefix, proof []byte, portID, channelID string, sequence uint64, acknowledgement []byte) error { + consensusState, err := GetConsensusState(store, cdc, height) + if err != nil { + return err + } + + const VerifyPacketAcknowledgementQuery = "verifypacketacknowledgement" + payload := make(map[string]map[string]interface{}) + payload[VerifyPacketAcknowledgementQuery] = make(map[string]interface{}) + inner := payload[VerifyPacketAcknowledgementQuery] + inner["me"] = c + inner["height"] = height + inner["commitment_prefix"] = prefix + inner["proof"] = proof + inner["port_id"] = portID + inner["channel_id"] = channelID + inner["delay_time_period"] = delayTimePeriod + inner["delay_block_period"] = delayBlockPeriod + inner["sequence"] = sequence + inner["acknowledgement"] = acknowledgement + inner["consensus_state"] = consensusState + + encodedData, err := json.Marshal(payload) + if err != nil { + return sdkerrors.Wrapf(ErrUnableToMarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + response, err := queryContractWithStore(c.CodeId, store, encodedData) + if err != nil { + return sdkerrors.Wrapf(ErrUnableToQuery, fmt.Sprintf("underlying error: %s", err.Error())) + } + + output := queryResponse{} + if err := json.Unmarshal(response, &output); err != nil { + return sdkerrors.Wrapf(ErrUnableToUnmarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + + if output.Result.IsValid { + return nil + } + + return fmt.Errorf("%s error while verifying packet acknowledgement", output.Result.ErrorMsg) +} + +func (c *ClientState) VerifyPacketReceiptAbsence(ctx sdk.Context, store sdk.KVStore, cdc codec.BinaryCodec, height exported.Height, delayTimePeriod, delayBlockPeriod uint64, prefix exported.Prefix, proof []byte, portID, channelID string, sequence uint64) error { + consensusState, err := GetConsensusState(store, cdc, height) + if err != nil { + return err + } + + const VerifyPacketReceiptAbsenceQuery = "verifypacketreceiptabsence" + payload := make(map[string]map[string]interface{}) + payload[VerifyPacketReceiptAbsenceQuery] = make(map[string]interface{}) + inner := payload[VerifyPacketReceiptAbsenceQuery] + inner["me"] = c + inner["height"] = height + inner["commitment_prefix"] = prefix + inner["proof"] = proof + inner["port_id"] = portID + inner["channel_id"] = channelID + inner["delay_time_period"] = delayTimePeriod + inner["delay_block_period"] = delayBlockPeriod + inner["sequence"] = sequence + inner["consensus_state"] = consensusState + + encodedData, err := json.Marshal(payload) + if err != nil { + return sdkerrors.Wrapf(ErrUnableToMarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + response, err := queryContractWithStore(c.CodeId, store, encodedData) + if err != nil { + return sdkerrors.Wrapf(ErrUnableToQuery, fmt.Sprintf("underlying error: %s", err.Error())) + } + + output := queryResponse{} + if err := json.Unmarshal(response, &output); err != nil { + return sdkerrors.Wrapf(ErrUnableToUnmarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + + if output.Result.IsValid { + return nil + } + + return fmt.Errorf("%s error while verifying packet receipt absence", output.Result.ErrorMsg) +} + +func (c *ClientState) VerifyNextSequenceRecv(ctx sdk.Context, store sdk.KVStore, cdc codec.BinaryCodec, height exported.Height, delayTimePeriod, delayBlockPeriod uint64, prefix exported.Prefix, proof []byte, portID, channelID string, nextSequenceRecv uint64) error { + consensusState, err := GetConsensusState(store, cdc, height) + if err != nil { + return err + } + + const VerifyNextSequenceRecvQuery = "verifynextsequencerecv" + payload := make(map[string]map[string]interface{}) + payload[VerifyNextSequenceRecvQuery] = make(map[string]interface{}) + inner := payload[VerifyNextSequenceRecvQuery] + inner["me"] = c + inner["height"] = height + inner["commitment_prefix"] = prefix + inner["proof"] = proof + inner["port_id"] = portID + inner["channel_id"] = channelID + inner["delay_time_period"] = delayTimePeriod + inner["delay_block_period"] = delayBlockPeriod + inner["next_sequence_recv"] = nextSequenceRecv + inner["consensus_state"] = consensusState + + encodedData, err := json.Marshal(payload) + if err != nil { + return sdkerrors.Wrapf(ErrUnableToMarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + response, err := queryContractWithStore(c.CodeId, store, encodedData) + if err != nil { + return sdkerrors.Wrapf(ErrUnableToQuery, fmt.Sprintf("underlying error: %s", err.Error())) + } + + output := queryResponse{} + if err := json.Unmarshal(response, &output); err != nil { + return sdkerrors.Wrapf(ErrUnableToUnmarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + + if output.Result.IsValid { + return nil + } + + return fmt.Errorf("%s error while verify next sequence", output.Result.ErrorMsg) +} diff --git a/modules/light-clients/10-wasm/types/codec.go b/modules/light-clients/10-wasm/types/codec.go new file mode 100644 index 00000000000..8b30076c25a --- /dev/null +++ b/modules/light-clients/10-wasm/types/codec.go @@ -0,0 +1,27 @@ +package types + +import ( + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/ibc-go/modules/core/exported" +) + +// RegisterInterfaces registers the tendermint concrete client-related +// implementations and interfaces. +func RegisterInterfaces(registry codectypes.InterfaceRegistry) { + registry.RegisterImplementations( + (*exported.ClientState)(nil), + &ClientState{}, + ) + registry.RegisterImplementations( + (*exported.ConsensusState)(nil), + &ConsensusState{}, + ) + registry.RegisterImplementations( + (*exported.Header)(nil), + &Header{}, + ) + registry.RegisterImplementations( + (*exported.Misbehaviour)(nil), + &Misbehaviour{}, + ) +} diff --git a/modules/light-clients/10-wasm/types/consensus_state.go b/modules/light-clients/10-wasm/types/consensus_state.go new file mode 100644 index 00000000000..cda001ec6ca --- /dev/null +++ b/modules/light-clients/10-wasm/types/consensus_state.go @@ -0,0 +1,42 @@ +package types + +import ( + "fmt" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + clienttypes "github.com/cosmos/ibc-go/modules/core/02-client/types" + "github.com/cosmos/ibc-go/modules/core/exported" +) + +var _ exported.ConsensusState = (*ConsensusState)(nil) + +func (m *ConsensusState) ClientType() string { + return exported.Wasm +} + +func (m *ConsensusState) GetRoot() exported.Root { + return m.Root +} + +func (m *ConsensusState) GetTimestamp() uint64 { + return m.Timestamp +} + +func (m *ConsensusState) ValidateBasic() error { + if m.Root.Empty() { + return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "root cannot be empty") + } + if m.Timestamp == 0 { + return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "timestamp cannot be zero Unix time") + } + + if m.Data == nil || len(m.Data) == 0 { + return fmt.Errorf("data cannot be empty") + } + + if m.CodeId == nil || len(m.CodeId) == 0 { + return fmt.Errorf("codeid cannot be empty") + } + + return nil +} diff --git a/modules/light-clients/10-wasm/types/errors.go b/modules/light-clients/10-wasm/types/errors.go new file mode 100644 index 00000000000..acd754eac5b --- /dev/null +++ b/modules/light-clients/10-wasm/types/errors.go @@ -0,0 +1,12 @@ +package types + +import sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + +var ( + ErrInvalidHeader = sdkerrors.Register(SubModuleName, 1, "invalid header") + ErrUnableToUnmarshalPayload = sdkerrors.Register(SubModuleName, 2, "unable to unmarshal wasm contract return value") + ErrUnableToInit = sdkerrors.Register(SubModuleName, 3, "unable to initialize wasm contract") + ErrUnableToCall = sdkerrors.Register(SubModuleName, 4, "unable to call wasm contract") + ErrUnableToQuery = sdkerrors.Register(SubModuleName, 5, "unable to query wasm contract") + ErrUnableToMarshalPayload = sdkerrors.Register(SubModuleName, 6, "unable to marshal wasm contract payload") +) diff --git a/modules/light-clients/10-wasm/types/fail_kv_store.go b/modules/light-clients/10-wasm/types/fail_kv_store.go new file mode 100644 index 00000000000..9b7d17ed479 --- /dev/null +++ b/modules/light-clients/10-wasm/types/fail_kv_store.go @@ -0,0 +1,53 @@ +package types + +import ( + "io" + + store "github.com/cosmos/cosmos-sdk/store/types" + "github.com/cosmos/cosmos-sdk/types" +) + +var _ types.KVStore = (*FailKVStore)(nil) + +type FailKVStore struct { +} + +func (f *FailKVStore) GetStoreType() store.StoreType { + panic("not available for this method of IBC contract") +} + +func (f *FailKVStore) CacheWrap() store.CacheWrap { + panic("not available for this method of IBC contract") +} + +func (f *FailKVStore) CacheWrapWithTrace(w io.Writer, tc store.TraceContext) store.CacheWrap { + panic("not available for this method of IBC contract") +} + +func (f *FailKVStore) CacheWrapWithListeners(storeKey types.StoreKey, listeners []store.WriteListener) types.CacheWrap { + panic("not available for this method of IBC contract") +} + +func (f *FailKVStore) Get(key []byte) []byte { + panic("not available for this method of IBC contract") +} + +func (f *FailKVStore) Has(key []byte) bool { + panic("not available for this method of IBC contract") +} + +func (f FailKVStore) Set(key, value []byte) { + panic("not available for this method of IBC contract") +} + +func (f FailKVStore) Delete(key []byte) { + panic("not available for this method of IBC contract") +} + +func (f FailKVStore) Iterator(start, end []byte) store.Iterator { + panic("not available for this method of IBC contract") +} + +func (f FailKVStore) ReverseIterator(start, end []byte) store.Iterator { + panic("not available for this method of IBC contract") +} diff --git a/modules/light-clients/10-wasm/types/header.go b/modules/light-clients/10-wasm/types/header.go new file mode 100644 index 00000000000..ce44ce646b9 --- /dev/null +++ b/modules/light-clients/10-wasm/types/header.go @@ -0,0 +1,25 @@ +package types + +import ( + "fmt" + + "github.com/cosmos/ibc-go/modules/core/exported" +) + +var _ exported.Header = (*Header)(nil) + +func (m *Header) ClientType() string { + return exported.Wasm +} + +func (m *Header) GetHeight() exported.Height { + return m.Height +} + +func (m *Header) ValidateBasic() error { + if m.Data == nil || len(m.Data) == 0 { + return fmt.Errorf("data cannot be empty") + } + + return nil +} diff --git a/modules/light-clients/10-wasm/types/keys.go b/modules/light-clients/10-wasm/types/keys.go new file mode 100644 index 00000000000..790dc5bd22f --- /dev/null +++ b/modules/light-clients/10-wasm/types/keys.go @@ -0,0 +1,7 @@ +package types + +const ( + // SubModuleName for the wasm client + SubModuleName = "wasm-client" + LastInstanceIDKey = "lastInstanceId" +) diff --git a/modules/light-clients/10-wasm/types/misbehaviour.go b/modules/light-clients/10-wasm/types/misbehaviour.go new file mode 100644 index 00000000000..e4a19879ce3 --- /dev/null +++ b/modules/light-clients/10-wasm/types/misbehaviour.go @@ -0,0 +1,29 @@ +package types + +import ( + "github.com/cosmos/ibc-go/modules/core/exported" +) + +var ( + _ exported.Misbehaviour = &Misbehaviour{} +) + +func (m *Misbehaviour) ClientType() string { + return m.Header1.ClientType() +} + +func (m *Misbehaviour) GetClientID() string { + return m.ClientId +} + +func (m *Misbehaviour) ValidateBasic() error { + if err := m.Header1.ValidateBasic(); err != nil { + return err + } + + if err := m.Header2.ValidateBasic(); err != nil { + return err + } + + return nil +} diff --git a/modules/light-clients/10-wasm/types/store.go b/modules/light-clients/10-wasm/types/store.go new file mode 100644 index 00000000000..8b7d57d18d3 --- /dev/null +++ b/modules/light-clients/10-wasm/types/store.go @@ -0,0 +1,120 @@ +package types + +import ( + "bytes" + "io" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store/cachekv" + "github.com/cosmos/cosmos-sdk/store/listenkv" + "github.com/cosmos/cosmos-sdk/store/tracekv" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + clienttypes "github.com/cosmos/ibc-go/modules/core/02-client/types" + host "github.com/cosmos/ibc-go/modules/core/24-host" + "github.com/cosmos/ibc-go/modules/core/exported" +) + +// WrappedStore combines two KVStores into one while transparently routing the calls based on key prefix +type WrappedStore struct { + first sdk.KVStore + second sdk.KVStore + + firstPrefix []byte + secondPrefix []byte +} + +func NewWrappedStore(first, second sdk.KVStore, firstPrefix, secondPrefix []byte) WrappedStore { + return WrappedStore{ + first: first, + second: second, + firstPrefix: firstPrefix, + secondPrefix: secondPrefix, + } +} + +func (ws WrappedStore) Get(key []byte) []byte { + return ws.getStore(key).Get(ws.trimPrefix(key)) +} + +func (ws WrappedStore) Has(key []byte) bool { + return ws.getStore(key).Has(ws.trimPrefix(key)) +} + +func (ws WrappedStore) Set(key, value []byte) { + ws.getStore(key).Set(ws.trimPrefix(key), value) +} + +func (ws WrappedStore) Delete(key []byte) { + ws.getStore(key).Delete(ws.trimPrefix(key)) +} + +func (ws WrappedStore) GetStoreType() storetypes.StoreType { + return ws.first.GetStoreType() +} + +func (ws WrappedStore) Iterator(start, end []byte) sdk.Iterator { + return ws.getStore(start).Iterator(ws.trimPrefix(start), ws.trimPrefix(end)) +} + +func (ws WrappedStore) ReverseIterator(start, end []byte) sdk.Iterator { + return ws.getStore(start).ReverseIterator(ws.trimPrefix(start), ws.trimPrefix(end)) +} + +func (ws WrappedStore) CacheWrap() storetypes.CacheWrap { + return cachekv.NewStore(ws) +} + +func (ws WrappedStore) CacheWrapWithTrace(w io.Writer, tc storetypes.TraceContext) storetypes.CacheWrap { + return cachekv.NewStore(tracekv.NewStore(ws, w, tc)) +} + +func (ws WrappedStore) CacheWrapWithListeners(storeKey storetypes.StoreKey, listeners []storetypes.WriteListener) storetypes.CacheWrap { + return cachekv.NewStore(listenkv.NewStore(ws, storeKey, listeners)) +} + +func (ws WrappedStore) trimPrefix(key []byte) []byte { + if bytes.HasPrefix(key, ws.firstPrefix) { + key = bytes.TrimPrefix(key, ws.firstPrefix) + } else { + key = bytes.TrimPrefix(key, ws.secondPrefix) + } + + return key +} + +func (ws WrappedStore) getStore(key []byte) sdk.KVStore { + if bytes.HasPrefix(key, ws.firstPrefix) { + return ws.first + } + + return ws.second +} + +// GetConsensusState retrieves the consensus state from the client prefixed +// store. An error is returned if the consensus state does not exist. +func GetConsensusState(store sdk.KVStore, cdc codec.BinaryCodec, height exported.Height) (*ConsensusState, error) { + bz := store.Get(host.ConsensusStateKey(height)) + if bz == nil { + return nil, sdkerrors.Wrapf( + clienttypes.ErrConsensusStateNotFound, + "consensus state does not exist for height %s", height, + ) + } + + consensusStateI, err := clienttypes.UnmarshalConsensusState(cdc, bz) + if err != nil { + return nil, sdkerrors.Wrapf(clienttypes.ErrInvalidConsensus, "unmarshal error: %v", err) + } + + consensusState, ok := consensusStateI.(*ConsensusState) + if !ok { + return nil, sdkerrors.Wrapf( + clienttypes.ErrInvalidConsensus, + "invalid consensus type %T, expected %T", consensusState, &ConsensusState{}, + ) + } + + return consensusState, nil +} diff --git a/modules/light-clients/10-wasm/types/vm.go b/modules/light-clients/10-wasm/types/vm.go new file mode 100644 index 00000000000..c6c149ebfbc --- /dev/null +++ b/modules/light-clients/10-wasm/types/vm.go @@ -0,0 +1,154 @@ +package types + +import ( + "github.com/CosmWasm/wasmvm/api" + "github.com/CosmWasm/wasmvm/types" + ics23 "github.com/confio/ics23/go" + sdk "github.com/cosmos/cosmos-sdk/types" + types2 "github.com/cosmos/ibc-go/modules/core/02-client/types" + types3 "github.com/cosmos/ibc-go/modules/core/23-commitment/types" + "github.com/cosmos/ibc-go/modules/core/28-wasm/keeper" + "github.com/cosmos/ibc-go/modules/core/exported" +) + +const GasMultiplier uint64 = 100 +const maxGasLimit = uint64(0x7FFFFFFFFFFFFFFF) + +var _ exported.ClientState = (*ClientState)(nil) + +type queryResponse struct { + ProofSpecs []*ics23.ProofSpec `json:"proof_specs,omitempty"` + Height types2.Height `json:"height,omitempty"` + GenesisMetadata []types2.GenesisMetadata `json:"genesis_metadata,omitempty"` + Result contractResult `json:"result,omitempty"` + Root types3.MerkleRoot `json:"root,omitempty"` + Timestamp uint64 `json:"timestamp,omitempty"` + Status exported.Status `json:"status,omitempty"` +} + +type contractResult struct { + IsValid bool `json:"is_valid,omitempty"` + ErrorMsg string `json:"err_msg,omitempty"` +} + +type clientStateCallResponse struct { + Me *ClientState `json:"me,omitempty"` + NewConsensusState *ConsensusState `json:"new_consensus_state,omitempty"` + NewClientState *ClientState `json:"new_client_state,omitempty"` + Result contractResult `json:"result,omitempty"` +} + +func (r *clientStateCallResponse) resetImmutables(c *ClientState) { + if r.Me != nil { + r.Me.CodeId = c.CodeId + } + + if r.NewConsensusState != nil { + r.NewConsensusState.CodeId = c.CodeId + } + + if r.NewClientState != nil { + r.NewClientState.CodeId = c.CodeId + } +} + +// Calls vm.Init with appropriate arguments +func initContract(codeID []byte, ctx sdk.Context, store sdk.KVStore, msg []byte) (*types.InitResponse, error) { + gasMeter := ctx.GasMeter() + chainID := ctx.BlockHeader().ChainID + height := ctx.BlockHeader().Height + // safety checks before casting below + if height < 0 { + panic("Block height must never be negative") + } + sec := ctx.BlockTime().Unix() + if sec < 0 { + panic("Block (unix) time must never be negative ") + } + nano := ctx.BlockTime().Nanosecond() + env := types.Env{ + Block: types.BlockInfo{ + Height: uint64(height), + Time: uint64(sec), + TimeNanos: uint64(nano), + ChainID: chainID, + }, + Contract: types.ContractInfo{ + Address: "", + }, + } + + msgInfo := types.MessageInfo{ + Sender: "", + SentFunds: nil, + } + mockFailureAPI := *api.NewMockFailureAPI() + mockQuerier := api.MockQuerier{} + + response, _, err := keeper.WasmVM.Instantiate(codeID, env, msgInfo, msg, store, mockFailureAPI, mockQuerier, gasMeter, gasMeter.Limit()) + return response, err +} + +// Calls vm.Execute with internally constructed Gas meter and environment +func callContract(codeID []byte, ctx sdk.Context, store sdk.KVStore, msg []byte) (*types.HandleResponse, error) { + gasMeter := ctx.GasMeter() + chainID := ctx.BlockHeader().ChainID + height := ctx.BlockHeader().Height + // safety checks before casting below + if height < 0 { + panic("Block height must never be negative") + } + sec := ctx.BlockTime().Unix() + if sec < 0 { + panic("Block (unix) time must never be negative ") + } + nano := ctx.BlockTime().Nanosecond() + env := types.Env{ + Block: types.BlockInfo{ + Height: uint64(height), + Time: uint64(sec), + TimeNanos: uint64(nano), + ChainID: chainID, + }, + Contract: types.ContractInfo{ + Address: "", + }, + } + + return callContractWithEnvAndMeter(codeID, &ctx, store, env, gasMeter, msg) +} + +// Calls vm.Execute with supplied environment and gas meter +func callContractWithEnvAndMeter(codeID []byte, ctx *sdk.Context, store sdk.KVStore, env types.Env, gasMeter sdk.GasMeter, msg []byte) (*types.HandleResponse, error) { + msgInfo := types.MessageInfo{ + Sender: "", + SentFunds: nil, + } + mockFailureAPI := *api.NewMockFailureAPI() + mockQuerier := api.MockQuerier{} + + resp, gasUsed, err := keeper.WasmVM.Execute(codeID, env, msgInfo, msg, store, mockFailureAPI, mockQuerier, gasMeter, gasMeter.Limit()) + if ctx != nil { + consumeGas(*ctx, gasUsed) + } + return resp, err +} + +func queryContractWithStore(codeID []byte, store sdk.KVStore, msg []byte) ([]byte, error) { + mockEnv := api.MockEnv() + mockGasMeter := api.NewMockGasMeter(1) + mockFailureAPI := *api.NewMockFailureAPI() + mockQuerier := api.MockQuerier{} + + resp, _, err := keeper.WasmVM.Query(codeID, mockEnv, msg, store, mockFailureAPI, mockQuerier, mockGasMeter, maxGasLimit) + return resp, err +} + +func consumeGas(ctx sdk.Context, gas uint64) { + consumed := gas / GasMultiplier + ctx.GasMeter().ConsumeGas(consumed, "wasm contract") + // throw OutOfGas error if we ran out (got exactly to zero due to better limit enforcing) + if ctx.GasMeter().IsOutOfGas() { + panic(sdk.ErrorOutOfGas{Descriptor: "Wasmer function execution"}) + } +} diff --git a/modules/light-clients/10-wasm/types/wasm.pb.go b/modules/light-clients/10-wasm/types/wasm.pb.go new file mode 100644 index 00000000000..2d5e277035e --- /dev/null +++ b/modules/light-clients/10-wasm/types/wasm.pb.go @@ -0,0 +1,1280 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ibc/lightclients/wasm/v1/wasm.proto + +package types + +import ( + fmt "fmt" + _go "github.com/confio/ics23/go" + types "github.com/cosmos/ibc-go/modules/core/02-client/types" + types1 "github.com/cosmos/ibc-go/modules/core/23-commitment/types" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + _ "google.golang.org/protobuf/types/known/timestamppb" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// Wasm light client's Client state +type ClientState struct { + Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` + CodeId []byte `protobuf:"bytes,2,opt,name=code_id,json=codeId,proto3" json:"code_id,omitempty"` + LatestHeight *types.Height `protobuf:"bytes,3,opt,name=latest_height,json=latestHeight,proto3" json:"latest_height,omitempty"` + ProofSpecs []*_go.ProofSpec `protobuf:"bytes,4,rep,name=proof_specs,json=proofSpecs,proto3" json:"proof_specs,omitempty"` +} + +func (m *ClientState) Reset() { *m = ClientState{} } +func (m *ClientState) String() string { return proto.CompactTextString(m) } +func (*ClientState) ProtoMessage() {} +func (*ClientState) Descriptor() ([]byte, []int) { + return fileDescriptor_678928ebbdee1807, []int{0} +} +func (m *ClientState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ClientState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ClientState.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ClientState) XXX_Merge(src proto.Message) { + xxx_messageInfo_ClientState.Merge(m, src) +} +func (m *ClientState) XXX_Size() int { + return m.Size() +} +func (m *ClientState) XXX_DiscardUnknown() { + xxx_messageInfo_ClientState.DiscardUnknown(m) +} + +var xxx_messageInfo_ClientState proto.InternalMessageInfo + +// Wasm light client's ConsensusState +type ConsensusState struct { + Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` + CodeId []byte `protobuf:"bytes,2,opt,name=code_id,json=codeId,proto3" json:"code_id,omitempty"` + // timestamp that corresponds to the block height in which the ConsensusState + // was stored. + Timestamp uint64 `protobuf:"varint,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + // commitment root (i.e app hash) + Root *types1.MerkleRoot `protobuf:"bytes,4,opt,name=root,proto3" json:"root,omitempty"` +} + +func (m *ConsensusState) Reset() { *m = ConsensusState{} } +func (m *ConsensusState) String() string { return proto.CompactTextString(m) } +func (*ConsensusState) ProtoMessage() {} +func (*ConsensusState) Descriptor() ([]byte, []int) { + return fileDescriptor_678928ebbdee1807, []int{1} +} +func (m *ConsensusState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ConsensusState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ConsensusState.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ConsensusState) XXX_Merge(src proto.Message) { + xxx_messageInfo_ConsensusState.Merge(m, src) +} +func (m *ConsensusState) XXX_Size() int { + return m.Size() +} +func (m *ConsensusState) XXX_DiscardUnknown() { + xxx_messageInfo_ConsensusState.DiscardUnknown(m) +} + +var xxx_messageInfo_ConsensusState proto.InternalMessageInfo + +// Wasm light client Header +type Header struct { + Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` + Height *types.Height `protobuf:"bytes,2,opt,name=height,proto3" json:"height,omitempty"` +} + +func (m *Header) Reset() { *m = Header{} } +func (m *Header) String() string { return proto.CompactTextString(m) } +func (*Header) ProtoMessage() {} +func (*Header) Descriptor() ([]byte, []int) { + return fileDescriptor_678928ebbdee1807, []int{2} +} +func (m *Header) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Header) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Header.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Header) XXX_Merge(src proto.Message) { + xxx_messageInfo_Header.Merge(m, src) +} +func (m *Header) XXX_Size() int { + return m.Size() +} +func (m *Header) XXX_DiscardUnknown() { + xxx_messageInfo_Header.DiscardUnknown(m) +} + +var xxx_messageInfo_Header proto.InternalMessageInfo + +// Wasm light client Misbehaviour +type Misbehaviour struct { + ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"` + Header1 *Header `protobuf:"bytes,2,opt,name=header_1,json=header1,proto3" json:"header_1,omitempty" yaml:"header_1"` + Header2 *Header `protobuf:"bytes,3,opt,name=header_2,json=header2,proto3" json:"header_2,omitempty" yaml:"header_2"` +} + +func (m *Misbehaviour) Reset() { *m = Misbehaviour{} } +func (m *Misbehaviour) String() string { return proto.CompactTextString(m) } +func (*Misbehaviour) ProtoMessage() {} +func (*Misbehaviour) Descriptor() ([]byte, []int) { + return fileDescriptor_678928ebbdee1807, []int{3} +} +func (m *Misbehaviour) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Misbehaviour) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Misbehaviour.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Misbehaviour) XXX_Merge(src proto.Message) { + xxx_messageInfo_Misbehaviour.Merge(m, src) +} +func (m *Misbehaviour) XXX_Size() int { + return m.Size() +} +func (m *Misbehaviour) XXX_DiscardUnknown() { + xxx_messageInfo_Misbehaviour.DiscardUnknown(m) +} + +var xxx_messageInfo_Misbehaviour proto.InternalMessageInfo + +func init() { + proto.RegisterType((*ClientState)(nil), "ibc.lightclients.wasm.v1.ClientState") + proto.RegisterType((*ConsensusState)(nil), "ibc.lightclients.wasm.v1.ConsensusState") + proto.RegisterType((*Header)(nil), "ibc.lightclients.wasm.v1.Header") + proto.RegisterType((*Misbehaviour)(nil), "ibc.lightclients.wasm.v1.Misbehaviour") +} + +func init() { + proto.RegisterFile("ibc/lightclients/wasm/v1/wasm.proto", fileDescriptor_678928ebbdee1807) +} + +var fileDescriptor_678928ebbdee1807 = []byte{ + // 541 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0x3f, 0x6f, 0xd3, 0x40, + 0x1c, 0x8d, 0x53, 0x2b, 0x69, 0x2e, 0x01, 0x2a, 0x53, 0x09, 0x2b, 0x42, 0x4e, 0x64, 0x06, 0xb2, + 0xe4, 0x8c, 0x5d, 0x89, 0xa1, 0x42, 0x42, 0x4a, 0x97, 0x76, 0xa8, 0x84, 0x5c, 0xa9, 0x03, 0x0c, + 0x91, 0x7d, 0xbe, 0x38, 0x27, 0xec, 0xfc, 0x2c, 0xdf, 0x25, 0xa8, 0x23, 0x1b, 0x23, 0x2b, 0x1b, + 0x1f, 0x82, 0x0f, 0xc1, 0xd8, 0x91, 0x29, 0x42, 0xc9, 0x37, 0xe8, 0x27, 0x40, 0x77, 0xe7, 0xfc, + 0x91, 0x00, 0x21, 0x3a, 0xf9, 0xfd, 0xee, 0xde, 0xbd, 0x7b, 0xbf, 0xe7, 0xfb, 0xa1, 0x67, 0x2c, + 0x26, 0x5e, 0xc6, 0xd2, 0xa9, 0x20, 0x19, 0xa3, 0x33, 0xc1, 0xbd, 0x0f, 0x11, 0xcf, 0xbd, 0x85, + 0xaf, 0xbe, 0xb8, 0x28, 0x41, 0x80, 0x65, 0xb3, 0x98, 0xe0, 0x7d, 0x12, 0x56, 0x9b, 0x0b, 0xbf, + 0x7b, 0x9c, 0x42, 0x0a, 0x8a, 0xe4, 0x49, 0xa4, 0xf9, 0xdd, 0x9e, 0x14, 0x25, 0x50, 0x52, 0x4f, + 0xf3, 0xa5, 0x9c, 0x46, 0x15, 0xe1, 0xf9, 0x8e, 0x00, 0x79, 0xce, 0x44, 0xbe, 0x21, 0x6d, 0xab, + 0x8d, 0x52, 0x0a, 0x90, 0x66, 0xd4, 0x53, 0x55, 0x3c, 0x9f, 0x78, 0x82, 0xe5, 0x94, 0x8b, 0x28, + 0x2f, 0x2a, 0xc2, 0x63, 0x02, 0xb3, 0x09, 0x03, 0x49, 0x80, 0x09, 0xd7, 0x8b, 0xee, 0x37, 0x03, + 0xb5, 0xcf, 0xd4, 0x7d, 0x57, 0x22, 0x12, 0xd4, 0xb2, 0x90, 0x99, 0x44, 0x22, 0xb2, 0x8d, 0xbe, + 0x31, 0xe8, 0x84, 0x0a, 0x5b, 0x4f, 0x50, 0x93, 0x40, 0x42, 0xc7, 0x2c, 0xb1, 0xeb, 0x6a, 0xb9, + 0x21, 0xcb, 0x8b, 0xc4, 0x7a, 0x8d, 0x1e, 0x64, 0x91, 0xa0, 0x5c, 0x8c, 0xa7, 0x54, 0xb6, 0x6c, + 0x1f, 0xf4, 0x8d, 0x41, 0x3b, 0xe8, 0x62, 0x19, 0x82, 0xf4, 0x8c, 0xab, 0x56, 0x16, 0x3e, 0x3e, + 0x57, 0x8c, 0xb0, 0xa3, 0x0f, 0xe8, 0xca, 0xf2, 0x51, 0x5b, 0xb9, 0x19, 0xf3, 0x82, 0x12, 0x6e, + 0x9b, 0xfd, 0x83, 0x41, 0x3b, 0x38, 0xc2, 0x8c, 0xf0, 0xe0, 0x04, 0xbf, 0x91, 0x3b, 0x57, 0x05, + 0x25, 0x21, 0x2a, 0x36, 0x90, 0x9f, 0x9a, 0x9f, 0xbe, 0xf6, 0x6a, 0xee, 0x17, 0x03, 0x3d, 0x3c, + 0x83, 0x19, 0xa7, 0x33, 0x3e, 0xe7, 0xf7, 0x70, 0xfe, 0x14, 0xb5, 0xb6, 0xf1, 0x28, 0xd7, 0x66, + 0xb8, 0x5b, 0xb0, 0x5e, 0x22, 0xb3, 0x04, 0x10, 0xb6, 0xa9, 0xda, 0x71, 0xf7, 0xda, 0xd9, 0x85, + 0xbe, 0xf0, 0xf1, 0x25, 0x2d, 0xdf, 0x67, 0x34, 0x04, 0x10, 0xa1, 0xe2, 0x57, 0xde, 0xae, 0x51, + 0xe3, 0x9c, 0x46, 0x09, 0x2d, 0xff, 0x68, 0x29, 0x40, 0x8d, 0x2a, 0xac, 0xfa, 0x3f, 0xc3, 0xaa, + 0x98, 0x95, 0xee, 0xc7, 0x3a, 0xea, 0x5c, 0x32, 0x1e, 0xd3, 0x69, 0xb4, 0x60, 0x30, 0x2f, 0x2d, + 0x1f, 0xb5, 0xf4, 0x11, 0xd9, 0x9f, 0xbc, 0xa3, 0x35, 0x3a, 0xbe, 0x5b, 0xf6, 0x8e, 0x6e, 0xa2, + 0x3c, 0x3b, 0x75, 0xb7, 0x5b, 0x6e, 0x78, 0xa8, 0xf1, 0x45, 0x62, 0xbd, 0x43, 0x87, 0x53, 0xe5, + 0x6d, 0xec, 0x57, 0xf7, 0xf7, 0xf1, 0xdf, 0x5e, 0x2c, 0xd6, 0x5d, 0x8c, 0x9c, 0xd5, 0xb2, 0xd7, + 0xd4, 0xd8, 0xbf, 0x5b, 0xf6, 0x1e, 0x69, 0xf9, 0x8d, 0x8c, 0x1b, 0x36, 0x35, 0xf4, 0xf7, 0xc4, + 0x83, 0xea, 0x25, 0xfc, 0x97, 0x78, 0xf0, 0x9b, 0x78, 0xb0, 0x15, 0x0f, 0x74, 0x06, 0xa3, 0xeb, + 0xef, 0x2b, 0xc7, 0xb8, 0x5d, 0x39, 0xc6, 0xcf, 0x95, 0x63, 0x7c, 0x5e, 0x3b, 0xb5, 0xdb, 0xb5, + 0x53, 0xfb, 0xb1, 0x76, 0x6a, 0x6f, 0x5f, 0xa5, 0x4c, 0x4c, 0xe7, 0xb1, 0xfc, 0x45, 0x1e, 0x01, + 0x9e, 0x03, 0xf7, 0x58, 0x4c, 0x86, 0x29, 0x78, 0x39, 0x24, 0xf3, 0x8c, 0x72, 0x3d, 0xba, 0xc3, + 0xcd, 0xec, 0xfa, 0x2f, 0x86, 0x6a, 0x7c, 0xc5, 0x4d, 0x41, 0x79, 0xdc, 0x50, 0xd3, 0x70, 0xf2, + 0x2b, 0x00, 0x00, 0xff, 0xff, 0x72, 0x42, 0xb2, 0x0c, 0xe4, 0x03, 0x00, 0x00, +} + +func (m *ClientState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ClientState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ClientState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ProofSpecs) > 0 { + for iNdEx := len(m.ProofSpecs) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ProofSpecs[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintWasm(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if m.LatestHeight != nil { + { + size, err := m.LatestHeight.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintWasm(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if len(m.CodeId) > 0 { + i -= len(m.CodeId) + copy(dAtA[i:], m.CodeId) + i = encodeVarintWasm(dAtA, i, uint64(len(m.CodeId))) + i-- + dAtA[i] = 0x12 + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = encodeVarintWasm(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ConsensusState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ConsensusState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ConsensusState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Root != nil { + { + size, err := m.Root.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintWasm(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + if m.Timestamp != 0 { + i = encodeVarintWasm(dAtA, i, uint64(m.Timestamp)) + i-- + dAtA[i] = 0x18 + } + if len(m.CodeId) > 0 { + i -= len(m.CodeId) + copy(dAtA[i:], m.CodeId) + i = encodeVarintWasm(dAtA, i, uint64(len(m.CodeId))) + i-- + dAtA[i] = 0x12 + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = encodeVarintWasm(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Header) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Header) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Header) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Height != nil { + { + size, err := m.Height.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintWasm(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = encodeVarintWasm(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Misbehaviour) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Misbehaviour) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Misbehaviour) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Header2 != nil { + { + size, err := m.Header2.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintWasm(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.Header1 != nil { + { + size, err := m.Header1.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintWasm(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.ClientId) > 0 { + i -= len(m.ClientId) + copy(dAtA[i:], m.ClientId) + i = encodeVarintWasm(dAtA, i, uint64(len(m.ClientId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintWasm(dAtA []byte, offset int, v uint64) int { + offset -= sovWasm(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *ClientState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Data) + if l > 0 { + n += 1 + l + sovWasm(uint64(l)) + } + l = len(m.CodeId) + if l > 0 { + n += 1 + l + sovWasm(uint64(l)) + } + if m.LatestHeight != nil { + l = m.LatestHeight.Size() + n += 1 + l + sovWasm(uint64(l)) + } + if len(m.ProofSpecs) > 0 { + for _, e := range m.ProofSpecs { + l = e.Size() + n += 1 + l + sovWasm(uint64(l)) + } + } + return n +} + +func (m *ConsensusState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Data) + if l > 0 { + n += 1 + l + sovWasm(uint64(l)) + } + l = len(m.CodeId) + if l > 0 { + n += 1 + l + sovWasm(uint64(l)) + } + if m.Timestamp != 0 { + n += 1 + sovWasm(uint64(m.Timestamp)) + } + if m.Root != nil { + l = m.Root.Size() + n += 1 + l + sovWasm(uint64(l)) + } + return n +} + +func (m *Header) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Data) + if l > 0 { + n += 1 + l + sovWasm(uint64(l)) + } + if m.Height != nil { + l = m.Height.Size() + n += 1 + l + sovWasm(uint64(l)) + } + return n +} + +func (m *Misbehaviour) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ClientId) + if l > 0 { + n += 1 + l + sovWasm(uint64(l)) + } + if m.Header1 != nil { + l = m.Header1.Size() + n += 1 + l + sovWasm(uint64(l)) + } + if m.Header2 != nil { + l = m.Header2.Size() + n += 1 + l + sovWasm(uint64(l)) + } + return n +} + +func sovWasm(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozWasm(x uint64) (n int) { + return sovWasm(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *ClientState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWasm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ClientState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ClientState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWasm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthWasm + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthWasm + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CodeId", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWasm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthWasm + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthWasm + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CodeId = append(m.CodeId[:0], dAtA[iNdEx:postIndex]...) + if m.CodeId == nil { + m.CodeId = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LatestHeight", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWasm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthWasm + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthWasm + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.LatestHeight == nil { + m.LatestHeight = &types.Height{} + } + if err := m.LatestHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofSpecs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWasm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthWasm + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthWasm + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ProofSpecs = append(m.ProofSpecs, &_go.ProofSpec{}) + if err := m.ProofSpecs[len(m.ProofSpecs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipWasm(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthWasm + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ConsensusState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWasm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ConsensusState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ConsensusState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWasm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthWasm + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthWasm + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CodeId", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWasm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthWasm + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthWasm + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CodeId = append(m.CodeId[:0], dAtA[iNdEx:postIndex]...) + if m.CodeId == nil { + m.CodeId = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + m.Timestamp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWasm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Timestamp |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Root", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWasm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthWasm + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthWasm + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Root == nil { + m.Root = &types1.MerkleRoot{} + } + if err := m.Root.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipWasm(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthWasm + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Header) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWasm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Header: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Header: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWasm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthWasm + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthWasm + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWasm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthWasm + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthWasm + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Height == nil { + m.Height = &types.Height{} + } + if err := m.Height.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipWasm(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthWasm + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Misbehaviour) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWasm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Misbehaviour: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Misbehaviour: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ClientId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWasm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthWasm + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthWasm + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ClientId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Header1", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWasm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthWasm + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthWasm + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Header1 == nil { + m.Header1 = &Header{} + } + if err := m.Header1.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Header2", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWasm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthWasm + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthWasm + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Header2 == nil { + m.Header2 = &Header{} + } + if err := m.Header2.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipWasm(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthWasm + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipWasm(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowWasm + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowWasm + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowWasm + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthWasm + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupWasm + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthWasm + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthWasm = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowWasm = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupWasm = fmt.Errorf("proto: unexpected end of group") +) diff --git a/proto/ibc/core/client/v1/client.proto b/proto/ibc/core/client/v1/client.proto index a4a2cc85def..8a63a1e1f3e 100644 --- a/proto/ibc/core/client/v1/client.proto +++ b/proto/ibc/core/client/v1/client.proto @@ -102,4 +102,6 @@ message Height { message Params { // allowed_clients defines the list of allowed client state types. repeated string allowed_clients = 1 [(gogoproto.moretags) = "yaml:\"allowed_clients\""]; + // whether or not wasm clients are enabled + bool wasm_clients_enabled = 2 [(gogoproto.moretags) = "yaml:\"wasm_clients_enabled\""]; } diff --git a/proto/ibc/core/wasm/v1/query.proto b/proto/ibc/core/wasm/v1/query.proto new file mode 100644 index 00000000000..85a66f986aa --- /dev/null +++ b/proto/ibc/core/wasm/v1/query.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; +package ibc.core.wasm.v1; + +import "google/api/annotations.proto"; + +option go_package = "github.com/cosmos/ibc-go/modules/core/28-wasm/types"; + +// WasmCode query +message WasmCodeQuery { + string code_id = 1; +} + +// WasmCode response +message WasmCodeResponse { + bytes code = 1; +} + +// Query service for wasm module +service Query { + // Get Wasm code for given code id + rpc WasmCode(WasmCodeQuery) returns (WasmCodeResponse) { + option (google.api.http).get = "/ibc/core/wasm/v1beta1/code/{code_id}"; + } +} diff --git a/proto/ibc/core/wasm/v1/tx.proto b/proto/ibc/core/wasm/v1/tx.proto new file mode 100644 index 00000000000..ea9d1b023a4 --- /dev/null +++ b/proto/ibc/core/wasm/v1/tx.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; +package ibc.core.wasm.v1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/ibc-go/modules/core/28-wasm/types"; + +// Msg defines the ibc/wasm Msg service. +service Msg { + // PushNewWasmCode defines a rpc handler method for PushNewWasmCode. + rpc PushNewWasmCode(MsgPushNewWasmCode) returns (MsgPushNewWasmCodeResponse); +} + +// Message type to push new wasm code +message MsgPushNewWasmCode { + string signer = 1; + bytes code = 3; +} + +// Response in case of successful handling +message MsgPushNewWasmCodeResponse { + bytes code_id = 1; +} diff --git a/proto/ibc/lightclients/wasm/v1/wasm.proto b/proto/ibc/lightclients/wasm/v1/wasm.proto new file mode 100644 index 00000000000..031b4212205 --- /dev/null +++ b/proto/ibc/lightclients/wasm/v1/wasm.proto @@ -0,0 +1,49 @@ +syntax = "proto3"; +package ibc.lightclients.wasm.v1; + +import "gogoproto/gogo.proto"; +import "ibc/core/client/v1/client.proto"; +import "ibc/core/commitment/v1/commitment.proto"; +import "google/protobuf/timestamp.proto"; +import "confio/proofs.proto"; + +option go_package = "github.com/cosmos/ibc-go/modules/light-clients/10-wasm/types"; + +// Wasm light client's Client state +message ClientState { + option (gogoproto.goproto_getters) = false; + bytes data = 1; + bytes code_id = 2; + ibc.core.client.v1.Height latest_height = 3; + repeated ics23.ProofSpec proof_specs = 4; +} + +// Wasm light client's ConsensusState +message ConsensusState { + option (gogoproto.goproto_getters) = false; + bytes data = 1; + bytes code_id = 2; + + // timestamp that corresponds to the block height in which the ConsensusState + // was stored. + uint64 timestamp = 3; + // commitment root (i.e app hash) + ibc.core.commitment.v1.MerkleRoot root = 4; +} + +// Wasm light client Header +message Header { + option (gogoproto.goproto_getters) = false; + + bytes data = 1; + ibc.core.client.v1.Height height = 2; +} + +// Wasm light client Misbehaviour +message Misbehaviour { + option (gogoproto.goproto_getters) = false; + + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + Header header_1 = 2 [(gogoproto.customname) = "Header1", (gogoproto.moretags) = "yaml:\"header_1\""]; + Header header_2 = 3 [(gogoproto.customname) = "Header2", (gogoproto.moretags) = "yaml:\"header_2\""]; +}