From b36d9ca2c16d8b91947a47c1584cbd24601df5e6 Mon Sep 17 00:00:00 2001 From: swelf Date: Thu, 25 Jul 2024 19:04:11 +0300 Subject: [PATCH 01/15] icq MaxKvQueryKeysCount and MaxTransactionsFilters gov gated --- app/app.go | 8 +- proto/neutron/interchainqueries/params.proto | 6 + x/interchainqueries/keeper/migrations.go | 25 ++++ x/interchainqueries/keeper/msg_server.go | 19 ++- x/interchainqueries/keeper/msg_server_test.go | 4 +- .../migrations/v3/migration.go | 28 ++++ .../migrations/v3/migration_test.go | 83 ++++++++++++ x/interchainqueries/module.go | 11 ++ x/interchainqueries/types/constants.go | 2 +- x/interchainqueries/types/genesis.go | 4 +- x/interchainqueries/types/params.go | 26 ++-- x/interchainqueries/types/params.pb.go | 120 ++++++++++++++---- x/interchainqueries/types/tx.go | 22 ++-- x/interchainqueries/types/types.go | 7 +- x/interchainqueries/types/types_test.go | 44 +++---- 15 files changed, 320 insertions(+), 89 deletions(-) create mode 100644 x/interchainqueries/keeper/migrations.go create mode 100644 x/interchainqueries/migrations/v3/migration.go create mode 100644 x/interchainqueries/migrations/v3/migration_test.go diff --git a/app/app.go b/app/app.go index 87293d3f7..4ddaf0718 100644 --- a/app/app.go +++ b/app/app.go @@ -904,7 +904,13 @@ func New( icaHostIBCModule := icahost.NewIBCModule(app.ICAHostKeeper) - interchainQueriesModule := interchainqueries.NewAppModule(appCodec, app.InterchainQueriesKeeper, app.AccountKeeper, app.BankKeeper) + interchainQueriesModule := interchainqueries.NewAppModule( + appCodec, + keys[interchainqueriesmoduletypes.StoreKey], + app.InterchainQueriesKeeper, + app.AccountKeeper, + app.BankKeeper, + ) interchainTxsModule := interchaintxs.NewAppModule(appCodec, app.InterchainTxsKeeper, app.AccountKeeper, app.BankKeeper) contractManagerModule := contractmanager.NewAppModule(appCodec, app.ContractManagerKeeper) ibcHooksModule := ibchooks.NewAppModule(app.AccountKeeper) diff --git a/proto/neutron/interchainqueries/params.proto b/proto/neutron/interchainqueries/params.proto index 0dca4a206..7b05c1f58 100644 --- a/proto/neutron/interchainqueries/params.proto +++ b/proto/neutron/interchainqueries/params.proto @@ -23,4 +23,10 @@ message Params { // balance between network cleaning speed and EndBlock duration. A zero value // means no limit. uint64 tx_query_removal_limit = 3; + + // Maximum amount of keys in a registered key value query + uint64 max_kv_query_keys_count = 4; + + // max_transactions_filters defines maximum allowed amount of tx filters in msgRegisterInterchainQuery + uint64 max_transactions_filters = 5; } diff --git a/x/interchainqueries/keeper/migrations.go b/x/interchainqueries/keeper/migrations.go new file mode 100644 index 000000000..a036ea33e --- /dev/null +++ b/x/interchainqueries/keeper/migrations.go @@ -0,0 +1,25 @@ +package keeper + +import ( + storetypes "cosmossdk.io/store/types" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + + v3 "github.com/neutron-org/neutron/v4/x/interchainqueries/migrations/v3" +) + +// Migrator is a struct for handling in-place store migrations. +type Migrator struct { + cdc codec.BinaryCodec + storeKey storetypes.StoreKey +} + +// NewMigrator returns a new Migrator. +func NewMigrator(cdc codec.BinaryCodec, storeKey storetypes.StoreKey) Migrator { + return Migrator{storeKey: storeKey, cdc: cdc} +} + +// Migrate2to3 migrates from version 2 to 3. +func (m Migrator) Migrate2to3(ctx sdk.Context) error { + return v3.MigrateParams(ctx, m.cdc, m.storeKey) +} diff --git a/x/interchainqueries/keeper/msg_server.go b/x/interchainqueries/keeper/msg_server.go index 384c9d6b1..9845c8455 100644 --- a/x/interchainqueries/keeper/msg_server.go +++ b/x/interchainqueries/keeper/msg_server.go @@ -35,14 +35,14 @@ func NewMsgServerImpl(keeper Keeper) types.MsgServer { func (m msgServer) RegisterInterchainQuery(goCtx context.Context, msg *types.MsgRegisterInterchainQuery) (*types.MsgRegisterInterchainQueryResponse, error) { defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), LabelRegisterInterchainQuery) + ctx := sdk.UnwrapSDKContext(goCtx) + ctx.Logger().Debug("RegisterInterchainQuery", "msg", msg) + params := m.GetParams(ctx) - if err := msg.Validate(); err != nil { + if err := msg.Validate(params); err != nil { return nil, errors.Wrap(err, "failed to validate MsgRegisterInterchainQuery") } - ctx := sdk.UnwrapSDKContext(goCtx) - ctx.Logger().Debug("RegisterInterchainQuery", "msg", msg) - senderAddr, err := sdk.AccAddressFromBech32(msg.Sender) if err != nil { m.Logger(ctx).Debug("RegisterInterchainQuery: failed to parse sender address", "sender_address", msg.Sender) @@ -62,8 +62,6 @@ func (m msgServer) RegisterInterchainQuery(goCtx context.Context, msg *types.Msg lastID := m.GetLastRegisteredQueryKey(ctx) lastID++ - params := m.GetParams(ctx) - registeredQuery := &types.RegisteredQuery{ Id: lastID, Owner: msg.Sender, @@ -122,12 +120,13 @@ func (m msgServer) RemoveInterchainQuery(goCtx context.Context, msg *types.MsgRe } func (m msgServer) UpdateInterchainQuery(goCtx context.Context, msg *types.MsgUpdateInterchainQueryRequest) (*types.MsgUpdateInterchainQueryResponse, error) { - if err := msg.Validate(); err != nil { - return nil, errors.Wrap(err, "failed to validate MsgUpdateInterchainQueryRequest") - } - ctx := sdk.UnwrapSDKContext(goCtx) ctx.Logger().Debug("UpdateInterchainQuery", "msg", msg) + params := m.GetParams(ctx) + + if err := msg.Validate(params); err != nil { + return nil, errors.Wrap(err, "failed to validate MsgUpdateInterchainQueryRequest") + } query, err := m.GetQueryByID(ctx, msg.GetQueryId()) if err != nil { diff --git a/x/interchainqueries/keeper/msg_server_test.go b/x/interchainqueries/keeper/msg_server_test.go index a92a7f6d8..efdc36bbf 100644 --- a/x/interchainqueries/keeper/msg_server_test.go +++ b/x/interchainqueries/keeper/msg_server_test.go @@ -99,7 +99,7 @@ func TestMsgRegisterInterchainQueryValidate(t *testing.T) { "too many keys", types.MsgRegisterInterchainQuery{ QueryType: string(types.InterchainQueryTypeKV), - Keys: make([]*types.KVKey, types.MaxKVQueryKeysCount+1), + Keys: make([]*types.KVKey, types.DefaultMaxKvQueryKeysCount+1), TransactionsFilter: "[]", ConnectionId: "connection-0", UpdatePeriod: 1, @@ -418,7 +418,7 @@ func TestMsgUpdateInterchainQueryRequestValidate(t *testing.T) { "too many keys", types.MsgUpdateInterchainQueryRequest{ QueryId: 1, - NewKeys: make([]*types.KVKey, types.MaxKVQueryKeysCount+1), + NewKeys: make([]*types.KVKey, types.DefaultMaxKvQueryKeysCount+1), NewUpdatePeriod: 0, Sender: testutil.TestOwnerAddress, }, diff --git a/x/interchainqueries/migrations/v3/migration.go b/x/interchainqueries/migrations/v3/migration.go new file mode 100644 index 000000000..a77e4bed8 --- /dev/null +++ b/x/interchainqueries/migrations/v3/migration.go @@ -0,0 +1,28 @@ +package v3 + +import ( + "fmt" + + store "cosmossdk.io/store/types" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/neutron-org/neutron/v4/x/interchainqueries/types" +) + +func MigrateParams(ctx sdk.Context, cdc codec.BinaryCodec, storeKey store.StoreKey) error { + var params types.Params + st := ctx.KVStore(storeKey) + bz := st.Get(types.ParamsKey) + if bz == nil { + return fmt.Errorf("no params stored in %s", types.ParamsKey) + } + + cdc.MustUnmarshal(bz, ¶ms) + params.MaxTransactionsFilters = types.DefaultMaxTransactionsFilters + params.MaxKvQueryKeysCount = types.DefaultMaxKvQueryKeysCount + bz = cdc.MustMarshal(¶ms) + st.Set(types.ParamsKey, bz) + return nil +} diff --git a/x/interchainqueries/migrations/v3/migration_test.go b/x/interchainqueries/migrations/v3/migration_test.go new file mode 100644 index 000000000..c36014df8 --- /dev/null +++ b/x/interchainqueries/migrations/v3/migration_test.go @@ -0,0 +1,83 @@ +package v3_test + +import ( + "testing" + + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/suite" + "gopkg.in/yaml.v2" + + "github.com/neutron-org/neutron/v4/testutil" + v3 "github.com/neutron-org/neutron/v4/x/interchainqueries/migrations/v3" + "github.com/neutron-org/neutron/v4/x/interchainqueries/types" +) + +type V3ICQMigrationTestSuite struct { + testutil.IBCConnectionTestSuite +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(V3ICQMigrationTestSuite)) +} + +// ParamsV2 defines the parameters for the module v2. +type ParamsV2 struct { + // Defines amount of blocks required before query becomes available for + // removal by anybody + QuerySubmitTimeout uint64 `protobuf:"varint,1,opt,name=query_submit_timeout,json=querySubmitTimeout,proto3" json:"query_submit_timeout,omitempty"` + // Amount of coins deposited for the query. + QueryDeposit github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,2,rep,name=query_deposit,json=queryDeposit,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"query_deposit"` + // Amount of tx hashes to be removed during a single EndBlock. Can vary to + // balance between network cleaning speed and EndBlock duration. A zero value + // means no limit. + TxQueryRemovalLimit uint64 `protobuf:"varint,3,opt,name=tx_query_removal_limit,json=txQueryRemovalLimit,proto3" json:"tx_query_removal_limit,omitempty"` +} + +func (p *ParamsV2) Reset() { *p = ParamsV2{} } +func (p *ParamsV2) ProtoMessage() {} + +// String implements the Stringer interface. +func (p ParamsV2) String() string { + out, _ := yaml.Marshal(p) + return string(out) +} + +func (suite *V3ICQMigrationTestSuite) TestParamsMigration() { + var ( + app = suite.GetNeutronZoneApp(suite.ChainA) + storeKey = app.GetKey(types.StoreKey) + ctx = suite.ChainA.GetContext() + cdc = app.AppCodec() + ) + + // preinitialize v2 params + p := ParamsV2{ + QuerySubmitTimeout: types.DefaultQuerySubmitTimeout, + QueryDeposit: types.DefaultQueryDeposit, + TxQueryRemovalLimit: types.DefaultTxQueryRemovalLimit, + } + store := ctx.KVStore(storeKey) + bz, err := cdc.Marshal(&p) + suite.Require().NoError(err) + store.Set(types.ParamsKey, bz) + + paramsOld := app.InterchainQueriesKeeper.GetParams(ctx) + suite.Require().Equal(paramsOld.TxQueryRemovalLimit, p.TxQueryRemovalLimit) + suite.Require().Equal(paramsOld.QuerySubmitTimeout, p.QuerySubmitTimeout) + suite.Require().Equal(paramsOld.QueryDeposit, p.QueryDeposit) + suite.Require().Equal(paramsOld.MaxTransactionsFilters, uint64(0)) + suite.Require().Equal(paramsOld.MaxKvQueryKeysCount, uint64(0)) + + err = v3.MigrateParams(ctx, cdc, storeKey) + suite.Require().NoError(err) + + paramsNew := app.InterchainQueriesKeeper.GetParams(ctx) + params := types.Params{ + QuerySubmitTimeout: types.DefaultQuerySubmitTimeout, + QueryDeposit: types.DefaultQueryDeposit, + TxQueryRemovalLimit: types.DefaultTxQueryRemovalLimit, + MaxKvQueryKeysCount: types.DefaultMaxKvQueryKeysCount, + MaxTransactionsFilters: types.DefaultMaxTransactionsFilters, + } + suite.Require().Equal(params, paramsNew) +} diff --git a/x/interchainqueries/module.go b/x/interchainqueries/module.go index 4f9910975..cf1572bd7 100644 --- a/x/interchainqueries/module.go +++ b/x/interchainqueries/module.go @@ -5,6 +5,8 @@ import ( "encoding/json" "fmt" + storetypes "cosmossdk.io/store/types" + "cosmossdk.io/core/appmodule" abci "github.com/cometbft/cometbft/abci/types" @@ -103,6 +105,7 @@ var _ appmodule.AppModule = AppModule{} type AppModule struct { AppModuleBasic + storeKey storetypes.StoreKey keeper keeper.Keeper accountKeeper types.AccountKeeper bankKeeper types.BankKeeper @@ -110,12 +113,14 @@ type AppModule struct { func NewAppModule( cdc codec.Codec, + storeKey storetypes.StoreKey, keeper keeper.Keeper, accountKeeper types.AccountKeeper, bankKeeper types.BankKeeper, ) AppModule { return AppModule{ AppModuleBasic: NewAppModuleBasic(cdc), + storeKey: storeKey, keeper: keeper, accountKeeper: accountKeeper, bankKeeper: bankKeeper, @@ -141,6 +146,12 @@ func (AppModule) QuerierRoute() string { return types.QuerierRoute } // RegisterServices registers a GRPC query service to respond to the // module-specific GRPC queries. func (am AppModule) RegisterServices(cfg module.Configurator) { + m := keeper.NewMigrator(am.cdc, am.storeKey) + + if err := cfg.RegisterMigration(types.ModuleName, 2, m.Migrate2to3); err != nil { + panic(fmt.Sprintf("failed to migrate x/interchainqueries from version 2 to 3: %v", err)) + } + types.RegisterQueryServer(cfg.QueryServer(), am.keeper) types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) } diff --git a/x/interchainqueries/types/constants.go b/x/interchainqueries/types/constants.go index 4c93fbeff..fef80f236 100644 --- a/x/interchainqueries/types/constants.go +++ b/x/interchainqueries/types/constants.go @@ -1,3 +1,3 @@ package types -const ConsensusVersion = 2 +const ConsensusVersion = 3 diff --git a/x/interchainqueries/types/genesis.go b/x/interchainqueries/types/genesis.go index c00668e58..29cc30ae1 100644 --- a/x/interchainqueries/types/genesis.go +++ b/x/interchainqueries/types/genesis.go @@ -34,14 +34,14 @@ func (gs GenesisState) Validate() error { switch val.QueryType { case string(InterchainQueryTypeTX): - if err := ValidateTransactionsFilter(val.TransactionsFilter); err != nil { + if err := ValidateTransactionsFilter(val.TransactionsFilter, gs.Params.MaxTransactionsFilters); err != nil { return errors.Wrap(ErrInvalidTransactionsFilter, err.Error()) } case string(InterchainQueryTypeKV): if len(val.Keys) == 0 { return errors.Wrap(ErrEmptyKeys, "keys cannot be empty") } - if err := validateKeys(val.GetKeys()); err != nil { + if err := validateKeys(val.GetKeys(), gs.Params.MaxKvQueryKeysCount); err != nil { return err } default: diff --git a/x/interchainqueries/types/params.go b/x/interchainqueries/types/params.go index ce52e3689..063cefc28 100644 --- a/x/interchainqueries/types/params.go +++ b/x/interchainqueries/types/params.go @@ -14,12 +14,14 @@ import ( var _ paramtypes.ParamSet = (*Params)(nil) var ( - KeyQuerySubmitTimeout = []byte("QuerySubmitTimeout") - DefaultQuerySubmitTimeout = uint64(1036800) // One month, with block_time = 2.5s - KeyQueryDeposit = []byte("QueryDeposit") - DefaultQueryDeposit = sdk.NewCoins(sdk.NewCoin(params.DefaultDenom, math.NewInt(int64(1_000_000)))) - KeyTxQueryRemovalLimit = []byte("TxQueryRemovalLimit") - DefaultTxQueryRemovalLimit = uint64(10_000) + KeyQuerySubmitTimeout = []byte("QuerySubmitTimeout") + DefaultQuerySubmitTimeout = uint64(1036800) // One month, with block_time = 2.5s + KeyQueryDeposit = []byte("QueryDeposit") + DefaultQueryDeposit = sdk.NewCoins(sdk.NewCoin(params.DefaultDenom, math.NewInt(int64(1_000_000)))) + KeyTxQueryRemovalLimit = []byte("TxQueryRemovalLimit") + DefaultTxQueryRemovalLimit = uint64(10_000) + DefaultMaxKvQueryKeysCount = uint64(32) + DefaultMaxTransactionsFilters = uint64(32) ) // ParamKeyTable the param key table for launch module @@ -32,17 +34,19 @@ func ParamKeyTable() paramtypes.KeyTable { } // NewParams creates a new Params instance -func NewParams(querySubmitTimeout uint64, queryDeposit sdk.Coins, txQueryRemovalLimit uint64) Params { +func NewParams(querySubmitTimeout uint64, queryDeposit sdk.Coins, txQueryRemovalLimit, maxKvQueryKeysCount, maxTransactionsFilters uint64) Params { return Params{ - QuerySubmitTimeout: querySubmitTimeout, - QueryDeposit: queryDeposit, - TxQueryRemovalLimit: txQueryRemovalLimit, + QuerySubmitTimeout: querySubmitTimeout, + QueryDeposit: queryDeposit, + TxQueryRemovalLimit: txQueryRemovalLimit, + MaxKvQueryKeysCount: maxKvQueryKeysCount, + MaxTransactionsFilters: maxTransactionsFilters, } } // DefaultParams returns a default set of parameters func DefaultParams() Params { - return NewParams(DefaultQuerySubmitTimeout, DefaultQueryDeposit, DefaultTxQueryRemovalLimit) + return NewParams(DefaultQuerySubmitTimeout, DefaultQueryDeposit, DefaultTxQueryRemovalLimit, DefaultMaxKvQueryKeysCount, DefaultMaxTransactionsFilters) } // ParamSetPairs get the params.ParamSet diff --git a/x/interchainqueries/types/params.pb.go b/x/interchainqueries/types/params.pb.go index 5afc785e0..18d044b6f 100644 --- a/x/interchainqueries/types/params.pb.go +++ b/x/interchainqueries/types/params.pb.go @@ -36,6 +36,10 @@ type Params struct { // balance between network cleaning speed and EndBlock duration. A zero value // means no limit. TxQueryRemovalLimit uint64 `protobuf:"varint,3,opt,name=tx_query_removal_limit,json=txQueryRemovalLimit,proto3" json:"tx_query_removal_limit,omitempty"` + // Maximum amount of keys in a registered key value query + MaxKvQueryKeysCount uint64 `protobuf:"varint,4,opt,name=max_kv_query_keys_count,json=maxKvQueryKeysCount,proto3" json:"max_kv_query_keys_count,omitempty"` + // max_transactions_filters defines maximum allowed amount of tx filters in msgRegisterInterchainQuery + MaxTransactionsFilters uint64 `protobuf:"varint,5,opt,name=max_transactions_filters,json=maxTransactionsFilters,proto3" json:"max_transactions_filters,omitempty"` } func (m *Params) Reset() { *m = Params{} } @@ -91,6 +95,20 @@ func (m *Params) GetTxQueryRemovalLimit() uint64 { return 0 } +func (m *Params) GetMaxKvQueryKeysCount() uint64 { + if m != nil { + return m.MaxKvQueryKeysCount + } + return 0 +} + +func (m *Params) GetMaxTransactionsFilters() uint64 { + if m != nil { + return m.MaxTransactionsFilters + } + return 0 +} + func init() { proto.RegisterType((*Params)(nil), "neutron.interchainqueries.Params") } @@ -100,28 +118,32 @@ func init() { } var fileDescriptor_752a5f3346da64b1 = []byte{ - // 331 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0xb1, 0x4e, 0xf3, 0x30, - 0x10, 0xc7, 0x93, 0xaf, 0x55, 0x87, 0x7c, 0xb0, 0x84, 0x0a, 0xb5, 0x1d, 0xdc, 0x8a, 0x01, 0x75, - 0xa9, 0xdd, 0x52, 0x26, 0xd8, 0x0a, 0x23, 0x03, 0x14, 0x58, 0x58, 0xa2, 0x24, 0xb5, 0x52, 0x8b, - 0x3a, 0x17, 0xec, 0x4b, 0xd5, 0xbe, 0x05, 0x23, 0x23, 0x33, 0x4f, 0xd2, 0xb1, 0x23, 0x13, 0xa0, - 0x76, 0xe0, 0x35, 0x50, 0xec, 0x20, 0x21, 0xc1, 0xe4, 0x93, 0x7f, 0x77, 0xfe, 0xff, 0x74, 0xf6, - 0x0e, 0x53, 0x9e, 0xa3, 0x82, 0x94, 0x89, 0x14, 0xb9, 0x8a, 0xa7, 0xa1, 0x48, 0x1f, 0x72, 0xae, - 0x04, 0xd7, 0x2c, 0x0b, 0x55, 0x28, 0x35, 0xcd, 0x14, 0x20, 0xf8, 0xcd, 0xb2, 0x8f, 0xfe, 0xea, - 0x6b, 0x91, 0x18, 0xb4, 0x04, 0xcd, 0xa2, 0x50, 0x73, 0x36, 0x1f, 0x44, 0x1c, 0xc3, 0x01, 0x8b, - 0x41, 0xa4, 0x76, 0xb4, 0x55, 0x4f, 0x20, 0x01, 0x53, 0xb2, 0xa2, 0xb2, 0xb7, 0x07, 0x9f, 0xae, - 0x57, 0xbb, 0x34, 0x09, 0x7e, 0xdf, 0xab, 0x17, 0x6f, 0x2d, 0x03, 0x9d, 0x47, 0x52, 0x60, 0x80, - 0x42, 0x72, 0xc8, 0xb1, 0xe1, 0x76, 0xdc, 0x6e, 0x75, 0xec, 0x1b, 0x76, 0x6d, 0xd0, 0x8d, 0x25, - 0x7e, 0xe6, 0xed, 0xda, 0x89, 0x09, 0xcf, 0x40, 0x0b, 0x6c, 0xfc, 0xeb, 0x54, 0xba, 0xff, 0x8f, - 0x9a, 0xd4, 0xaa, 0xd0, 0x42, 0x85, 0x96, 0x2a, 0xf4, 0x0c, 0x44, 0x3a, 0xea, 0xaf, 0xde, 0xda, - 0xce, 0xcb, 0x7b, 0xbb, 0x9b, 0x08, 0x9c, 0xe6, 0x11, 0x8d, 0x41, 0xb2, 0xd2, 0xdb, 0x1e, 0x3d, - 0x3d, 0xb9, 0x67, 0xb8, 0xcc, 0xb8, 0x36, 0x03, 0x7a, 0xbc, 0x63, 0x12, 0xce, 0x6d, 0x80, 0x3f, - 0xf4, 0xf6, 0x71, 0x11, 0xd8, 0x50, 0xc5, 0x25, 0xcc, 0xc3, 0x59, 0x30, 0x13, 0x52, 0x60, 0xa3, - 0x62, 0x2c, 0xf7, 0x70, 0x71, 0x55, 0xc0, 0xb1, 0x65, 0x17, 0x05, 0x3a, 0xa9, 0x3e, 0x3d, 0xb7, - 0x9d, 0xd1, 0xed, 0x6a, 0x43, 0xdc, 0xf5, 0x86, 0xb8, 0x1f, 0x1b, 0xe2, 0x3e, 0x6e, 0x89, 0xb3, - 0xde, 0x12, 0xe7, 0x75, 0x4b, 0x9c, 0xbb, 0xd3, 0x1f, 0x32, 0xe5, 0x7e, 0x7b, 0xa0, 0x92, 0xef, - 0x9a, 0xcd, 0x8f, 0xd9, 0xe2, 0x8f, 0x8f, 0x31, 0x96, 0x51, 0xcd, 0xec, 0x71, 0xf8, 0x15, 0x00, - 0x00, 0xff, 0xff, 0xc7, 0x61, 0x00, 0x43, 0xc2, 0x01, 0x00, 0x00, + // 397 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x92, 0x31, 0x8f, 0xd3, 0x30, + 0x14, 0xc7, 0x93, 0xbb, 0x72, 0x43, 0x80, 0x25, 0x9c, 0x8e, 0x5c, 0x87, 0xb4, 0x62, 0x40, 0x5d, + 0x1a, 0xb7, 0xb4, 0x03, 0x82, 0xad, 0x45, 0x2c, 0x65, 0x80, 0x52, 0x16, 0x96, 0xc8, 0x49, 0x4d, + 0x6a, 0xb5, 0xf6, 0x0b, 0xf6, 0x4b, 0x94, 0x7c, 0x0b, 0x46, 0x46, 0x66, 0x3e, 0x49, 0xc7, 0x6e, + 0x30, 0x01, 0x6a, 0xbf, 0x08, 0x8a, 0x1d, 0xa4, 0x4a, 0xdc, 0x94, 0xa7, 0xfc, 0xfc, 0xcb, 0xff, + 0x9f, 0xbc, 0x78, 0x4f, 0x25, 0x2b, 0x50, 0x81, 0x24, 0x5c, 0x22, 0x53, 0xe9, 0x86, 0x72, 0xf9, + 0xb9, 0x60, 0x8a, 0x33, 0x4d, 0x72, 0xaa, 0xa8, 0xd0, 0x51, 0xae, 0x00, 0xc1, 0xbf, 0x6d, 0xcf, + 0x45, 0xff, 0x9d, 0xeb, 0x86, 0x29, 0x68, 0x01, 0x9a, 0x24, 0x54, 0x33, 0x52, 0x8e, 0x13, 0x86, + 0x74, 0x4c, 0x52, 0xe0, 0xd2, 0xaa, 0xdd, 0xeb, 0x0c, 0x32, 0x30, 0x23, 0x69, 0x26, 0x7b, 0xf7, + 0xc9, 0x8f, 0x0b, 0xef, 0xea, 0xad, 0x49, 0xf0, 0x47, 0xde, 0x75, 0xf3, 0xac, 0x3a, 0xd6, 0x45, + 0x22, 0x38, 0xc6, 0xc8, 0x05, 0x83, 0x02, 0x03, 0xb7, 0xef, 0x0e, 0x3a, 0x4b, 0xdf, 0xb0, 0xf7, + 0x06, 0xad, 0x2c, 0xf1, 0x73, 0xef, 0xa1, 0x35, 0xd6, 0x2c, 0x07, 0xcd, 0x31, 0xb8, 0xe8, 0x5f, + 0x0e, 0xee, 0x3f, 0xbb, 0x8d, 0x6c, 0x95, 0xa8, 0xa9, 0x12, 0xb5, 0x55, 0xa2, 0x39, 0x70, 0x39, + 0x1b, 0xed, 0x7f, 0xf5, 0x9c, 0xef, 0xbf, 0x7b, 0x83, 0x8c, 0xe3, 0xa6, 0x48, 0xa2, 0x14, 0x04, + 0x69, 0x7b, 0xdb, 0xcb, 0x50, 0xaf, 0xb7, 0x04, 0xeb, 0x9c, 0x69, 0x23, 0xe8, 0xe5, 0x03, 0x93, + 0xf0, 0xca, 0x06, 0xf8, 0x13, 0xef, 0x06, 0xab, 0xd8, 0x86, 0x2a, 0x26, 0xa0, 0xa4, 0xbb, 0x78, + 0xc7, 0x05, 0xc7, 0xe0, 0xd2, 0xb4, 0x7c, 0x84, 0xd5, 0xbb, 0x06, 0x2e, 0x2d, 0x7b, 0xd3, 0x20, + 0x7f, 0xea, 0x3d, 0x16, 0xb4, 0x8a, 0xb7, 0x65, 0x2b, 0x6e, 0x59, 0xad, 0xe3, 0x14, 0x0a, 0x89, + 0x41, 0xc7, 0x5a, 0x82, 0x56, 0x8b, 0xd2, 0x88, 0x0b, 0x56, 0xeb, 0x79, 0x83, 0xfc, 0xe7, 0x5e, + 0xd0, 0x58, 0xa8, 0xa8, 0xd4, 0x34, 0x45, 0x0e, 0x52, 0xc7, 0x9f, 0xf8, 0x0e, 0x99, 0xd2, 0xc1, + 0x3d, 0xa3, 0xdd, 0x08, 0x5a, 0xad, 0xce, 0xf0, 0x6b, 0x4b, 0x5f, 0x74, 0xbe, 0x7e, 0xeb, 0x39, + 0xb3, 0x0f, 0xfb, 0x63, 0xe8, 0x1e, 0x8e, 0xa1, 0xfb, 0xe7, 0x18, 0xba, 0x5f, 0x4e, 0xa1, 0x73, + 0x38, 0x85, 0xce, 0xcf, 0x53, 0xe8, 0x7c, 0x7c, 0x79, 0xf6, 0xf2, 0xed, 0x3e, 0x87, 0xa0, 0xb2, + 0x7f, 0x33, 0x29, 0xa7, 0xa4, 0xba, 0xe3, 0x47, 0x30, 0x5f, 0x25, 0xb9, 0x32, 0x7b, 0x9b, 0xfc, + 0x0d, 0x00, 0x00, 0xff, 0xff, 0x8f, 0x38, 0x73, 0xdc, 0x32, 0x02, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -144,6 +166,16 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.MaxTransactionsFilters != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.MaxTransactionsFilters)) + i-- + dAtA[i] = 0x28 + } + if m.MaxKvQueryKeysCount != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.MaxKvQueryKeysCount)) + i-- + dAtA[i] = 0x20 + } if m.TxQueryRemovalLimit != 0 { i = encodeVarintParams(dAtA, i, uint64(m.TxQueryRemovalLimit)) i-- @@ -200,6 +232,12 @@ func (m *Params) Size() (n int) { if m.TxQueryRemovalLimit != 0 { n += 1 + sovParams(uint64(m.TxQueryRemovalLimit)) } + if m.MaxKvQueryKeysCount != 0 { + n += 1 + sovParams(uint64(m.MaxKvQueryKeysCount)) + } + if m.MaxTransactionsFilters != 0 { + n += 1 + sovParams(uint64(m.MaxTransactionsFilters)) + } return n } @@ -310,6 +348,44 @@ func (m *Params) Unmarshal(dAtA []byte) error { break } } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxKvQueryKeysCount", wireType) + } + m.MaxKvQueryKeysCount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxKvQueryKeysCount |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxTransactionsFilters", wireType) + } + m.MaxTransactionsFilters = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxTransactionsFilters |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipParams(dAtA[iNdEx:]) diff --git a/x/interchainqueries/types/tx.go b/x/interchainqueries/types/tx.go index 6bce76392..7353125b1 100644 --- a/x/interchainqueries/types/tx.go +++ b/x/interchainqueries/types/tx.go @@ -11,10 +11,6 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -const ( - MaxKVQueryKeysCount = 32 -) - var ( _ sdk.Msg = &MsgSubmitQueryResult{} _ codectypes.UnpackInterfacesMessage = MsgSubmitQueryResult{} @@ -90,7 +86,7 @@ func (msg MsgRegisterInterchainQuery) Type() string { return "register-interchain-query" } -func (msg MsgRegisterInterchainQuery) Validate() error { +func (msg MsgRegisterInterchainQuery) Validate(params Params) error { if msg.UpdatePeriod == 0 { return errors.Wrap(ErrInvalidUpdatePeriod, "update period can not be equal to zero") } @@ -115,13 +111,13 @@ func (msg MsgRegisterInterchainQuery) Validate() error { if len(msg.Keys) == 0 { return errors.Wrap(ErrEmptyKeys, "keys cannot be empty") } - if err := validateKeys(msg.GetKeys()); err != nil { + if err := validateKeys(msg.GetKeys(), params.MaxKvQueryKeysCount); err != nil { return err } } if InterchainQueryType(msg.QueryType).IsTX() { - if err := ValidateTransactionsFilter(msg.TransactionsFilter); err != nil { + if err := ValidateTransactionsFilter(msg.TransactionsFilter, params.MaxTransactionsFilters); err != nil { return errors.Wrap(ErrInvalidTransactionsFilter, err.Error()) } } @@ -144,7 +140,7 @@ func (msg MsgRegisterInterchainQuery) GetSigners() []sdk.AccAddress { var _ sdk.Msg = &MsgUpdateInterchainQueryRequest{} -func (msg MsgUpdateInterchainQueryRequest) Validate() error { +func (msg MsgUpdateInterchainQueryRequest) Validate(params Params) error { if msg.GetQueryId() == 0 { return errors.Wrap(ErrInvalidQueryID, "query_id cannot be empty or equal to 0") } @@ -167,13 +163,13 @@ func (msg MsgUpdateInterchainQueryRequest) Validate() error { } if len(newKeys) != 0 { - if err := validateKeys(newKeys); err != nil { + if err := validateKeys(newKeys, params.MaxKvQueryKeysCount); err != nil { return err } } if newTxFilter != "" { - if err := ValidateTransactionsFilter(newTxFilter); err != nil { + if err := ValidateTransactionsFilter(newTxFilter, params.MaxTransactionsFilters); err != nil { return errors.Wrap(ErrInvalidTransactionsFilter, err.Error()) } } @@ -230,9 +226,9 @@ func (msg *MsgUpdateParams) Validate() error { return nil } -func validateKeys(keys []*KVKey) error { - if uint64(len(keys)) > MaxKVQueryKeysCount { - return errors.Wrapf(ErrTooManyKVQueryKeys, "keys count cannot be more than %d", MaxKVQueryKeysCount) +func validateKeys(keys []*KVKey, maxKVQueryKeysCount uint64) error { + if uint64(len(keys)) > maxKVQueryKeysCount { + return errors.Wrapf(ErrTooManyKVQueryKeys, "keys count cannot be more than %d", maxKVQueryKeysCount) } duplicates := make(map[string]struct{}) diff --git a/x/interchainqueries/types/types.go b/x/interchainqueries/types/types.go index dafa661f3..be94cc357 100644 --- a/x/interchainqueries/types/types.go +++ b/x/interchainqueries/types/types.go @@ -43,9 +43,6 @@ const ( // AttributeValueQueryRemoved represents the value for the 'action' event attribute. AttributeValueQueryRemoved = "query_removed" - - // maxTransactionsFilters defines maximum allowed amount of tx filters in msgRegisterInterchainQuery - maxTransactionsFilters = 32 ) const ( @@ -107,13 +104,13 @@ type TransactionsFilterItem struct { } // ValidateTransactionsFilter checks if the passed string is a valid TransactionsFilter value. -func ValidateTransactionsFilter(s string) error { +func ValidateTransactionsFilter(s string, maxTransactionsFilters uint64) error { const forbiddenCharacters = "\t\n\r\\()\"'=><" filters := TransactionsFilter{} if err := json.Unmarshal([]byte(s), &filters); err != nil { return fmt.Errorf("failed to unmarshal transactions filter: %w", err) } - if len(filters) > maxTransactionsFilters { + if uint64(len(filters)) > maxTransactionsFilters { return fmt.Errorf("too many transactions filters, provided=%d, max=%d", len(filters), maxTransactionsFilters) } diff --git a/x/interchainqueries/types/types_test.go b/x/interchainqueries/types/types_test.go index 202c8c531..f062a310e 100644 --- a/x/interchainqueries/types/types_test.go +++ b/x/interchainqueries/types/types_test.go @@ -10,37 +10,37 @@ import ( func TestTransactionFilterValidation(t *testing.T) { t.Run("Valid", func(t *testing.T) { // several conditions - assert.NoError(t, ValidateTransactionsFilter(`[{"field":"transfer.recipient","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"},{"field":"tx.height","op":"Gte","value":100}]`)) + assert.NoError(t, ValidateTransactionsFilter(`[{"field":"transfer.recipient","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"},{"field":"tx.height","op":"Gte","value":100}]`, DefaultMaxTransactionsFilters)) // all supported operations with a whole operand - assert.NoError(t, ValidateTransactionsFilter(`[{"field":"tx.height","op":"Eq","value":1000}]`)) - assert.NoError(t, ValidateTransactionsFilter(`[{"field":"tx.height","op":"Gt","value":1000}]`)) - assert.NoError(t, ValidateTransactionsFilter(`[{"field":"tx.height","op":"Gte","value":1000}]`)) - assert.NoError(t, ValidateTransactionsFilter(`[{"field":"tx.height","op":"Lt","value":1000}]`)) - assert.NoError(t, ValidateTransactionsFilter(`[{"field":"tx.height","op":"Lte","value":1000}]`)) + assert.NoError(t, ValidateTransactionsFilter(`[{"field":"tx.height","op":"Eq","value":1000}]`, DefaultMaxTransactionsFilters)) + assert.NoError(t, ValidateTransactionsFilter(`[{"field":"tx.height","op":"Gt","value":1000}]`, DefaultMaxTransactionsFilters)) + assert.NoError(t, ValidateTransactionsFilter(`[{"field":"tx.height","op":"Gte","value":1000}]`, DefaultMaxTransactionsFilters)) + assert.NoError(t, ValidateTransactionsFilter(`[{"field":"tx.height","op":"Lt","value":1000}]`, DefaultMaxTransactionsFilters)) + assert.NoError(t, ValidateTransactionsFilter(`[{"field":"tx.height","op":"Lte","value":1000}]`, DefaultMaxTransactionsFilters)) }) t.Run("Invalid", func(t *testing.T) { // invalid json - assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.recipient","op":"Eq","value":`), "unexpected end of JSON input") + assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.recipient","op":"Eq","value":`, DefaultMaxTransactionsFilters), "unexpected end of JSON input") // empty operation - assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.recipient","op":"","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`), "op '' is expected to be one of: eq, gt, gte, lt, lte") + assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.recipient","op":"","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`, DefaultMaxTransactionsFilters), "op '' is expected to be one of: eq, gt, gte, lt, lte") // empty field - assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`), "field couldn't be empty") + assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`, DefaultMaxTransactionsFilters), "field couldn't be empty") // field with forbidden symbols const specialSymbolsAreNotAllowed = "special symbols \t\n\r\\()\"'=>< are not allowed" - assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.\t","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`), specialSymbolsAreNotAllowed) - assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.\n","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`), specialSymbolsAreNotAllowed) - assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.\r","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`), specialSymbolsAreNotAllowed) - assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.\\","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`), specialSymbolsAreNotAllowed) - assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.(","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`), specialSymbolsAreNotAllowed) - assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.)","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`), specialSymbolsAreNotAllowed) - assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.\"","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`), specialSymbolsAreNotAllowed) - assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.'","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`), specialSymbolsAreNotAllowed) - assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.=","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`), specialSymbolsAreNotAllowed) - assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.>","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`), specialSymbolsAreNotAllowed) - assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.<","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`), specialSymbolsAreNotAllowed) + assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.\t","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`, DefaultMaxTransactionsFilters), specialSymbolsAreNotAllowed) + assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.\n","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`, DefaultMaxTransactionsFilters), specialSymbolsAreNotAllowed) + assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.\r","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`, DefaultMaxTransactionsFilters), specialSymbolsAreNotAllowed) + assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.\\","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`, DefaultMaxTransactionsFilters), specialSymbolsAreNotAllowed) + assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.(","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`, DefaultMaxTransactionsFilters), specialSymbolsAreNotAllowed) + assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.)","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`, DefaultMaxTransactionsFilters), specialSymbolsAreNotAllowed) + assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.\"","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`, DefaultMaxTransactionsFilters), specialSymbolsAreNotAllowed) + assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.'","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`, DefaultMaxTransactionsFilters), specialSymbolsAreNotAllowed) + assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.=","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`, DefaultMaxTransactionsFilters), specialSymbolsAreNotAllowed) + assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.>","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`, DefaultMaxTransactionsFilters), specialSymbolsAreNotAllowed) + assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"transfer.<","op":"Eq","value":"neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u"}]`, DefaultMaxTransactionsFilters), specialSymbolsAreNotAllowed) // decimal number - assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"tx.height","op":"Gte","value":15.5}]`), "can't be a decimal number") - assert.ErrorContains(t, ValidateTransactionsFilter(lotsOfTxFilters(t, 40)), "too many transactions filters") + assert.ErrorContains(t, ValidateTransactionsFilter(`[{"field":"tx.height","op":"Gte","value":15.5}]`, DefaultMaxTransactionsFilters), "can't be a decimal number") + assert.ErrorContains(t, ValidateTransactionsFilter(lotsOfTxFilters(t, 40), DefaultMaxTransactionsFilters), "too many transactions filters") }) } From ba1b1d6dc91370d81e7125962e02aee01274eac9 Mon Sep 17 00:00:00 2001 From: nhpd Date: Wed, 7 Aug 2024 13:44:08 +0400 Subject: [PATCH 02/15] feat: add possibility for unordered ica channels --- proto/neutron/interchaintxs/v1/tx.proto | 2 + x/dex/types/limit_order_tranche_user.pb.go | 5 +- x/interchaintxs/keeper/msg_server.go | 3 +- x/interchaintxs/types/tx.pb.go | 150 +++++++++++++-------- 4 files changed, 98 insertions(+), 62 deletions(-) diff --git a/proto/neutron/interchaintxs/v1/tx.proto b/proto/neutron/interchaintxs/v1/tx.proto index ef59d3075..32148ce7b 100644 --- a/proto/neutron/interchaintxs/v1/tx.proto +++ b/proto/neutron/interchaintxs/v1/tx.proto @@ -11,6 +11,7 @@ import "google/api/http.proto"; import "google/protobuf/any.proto"; import "neutron/feerefunder/fee.proto"; import "neutron/interchaintxs/v1/params.proto"; +import "ibc/core/channel/v1/channel.proto"; option go_package = "github.com/neutron-org/neutron/v4/x/interchaintxs/types"; @@ -36,6 +37,7 @@ message MsgRegisterInterchainAccount { (gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" ]; + ibc.core.channel.v1.Order ordering = 5; } // MsgRegisterInterchainAccountResponse is the response type for diff --git a/x/dex/types/limit_order_tranche_user.pb.go b/x/dex/types/limit_order_tranche_user.pb.go index b0e65087b..6e52c57d5 100644 --- a/x/dex/types/limit_order_tranche_user.pb.go +++ b/x/dex/types/limit_order_tranche_user.pb.go @@ -31,8 +31,9 @@ type LimitOrderTrancheUser struct { Address string `protobuf:"bytes,4,opt,name=address,proto3" json:"address,omitempty"` SharesOwned cosmossdk_io_math.Int `protobuf:"bytes,5,opt,name=shares_owned,json=sharesOwned,proto3,customtype=cosmossdk.io/math.Int" json:"shares_owned" yaml:"shares_owned"` SharesWithdrawn cosmossdk_io_math.Int `protobuf:"bytes,6,opt,name=shares_withdrawn,json=sharesWithdrawn,proto3,customtype=cosmossdk.io/math.Int" json:"shares_withdrawn" yaml:"shares_withdrawn"` - SharesCancelled cosmossdk_io_math.Int `protobuf:"bytes,7,opt,name=shares_cancelled,json=sharesCancelled,proto3,customtype=cosmossdk.io/math.Int" json:"shares_cancelled" yaml:"shares_cancelled"` - OrderType LimitOrderType `protobuf:"varint,8,opt,name=order_type,json=orderType,proto3,enum=neutron.dex.LimitOrderType" json:"order_type,omitempty"` + // TODO: remove this in next release. It is no longer used + SharesCancelled cosmossdk_io_math.Int `protobuf:"bytes,7,opt,name=shares_cancelled,json=sharesCancelled,proto3,customtype=cosmossdk.io/math.Int" json:"shares_cancelled" yaml:"shares_cancelled"` + OrderType LimitOrderType `protobuf:"varint,8,opt,name=order_type,json=orderType,proto3,enum=neutron.dex.LimitOrderType" json:"order_type,omitempty"` } func (m *LimitOrderTrancheUser) Reset() { *m = LimitOrderTrancheUser{} } diff --git a/x/interchaintxs/keeper/msg_server.go b/x/interchaintxs/keeper/msg_server.go index ed1dcc9ed..54c64e9e8 100644 --- a/x/interchaintxs/keeper/msg_server.go +++ b/x/interchaintxs/keeper/msg_server.go @@ -66,7 +66,8 @@ func (k Keeper) RegisterInterchainAccount(goCtx context.Context, msg *ictxtypes. Owner: icaOwner, ConnectionId: msg.ConnectionId, Version: "", // FIXME: empty version string doesn't look good - Ordering: channeltypes.ORDERED, + // underlying controller uses ORDER_ORDERED as default in case msg's ordering is NONE + Ordering: msg.Ordering, }) if err != nil { k.Logger(ctx).Debug("RegisterInterchainAccount: failed to RegisterInterchainAccount:", "error", err, "owner", icaOwner, "msg", &msg) diff --git a/x/interchaintxs/types/tx.pb.go b/x/interchaintxs/types/tx.pb.go index 8b7fb7755..4b18fd1a1 100644 --- a/x/interchaintxs/types/tx.pb.go +++ b/x/interchaintxs/types/tx.pb.go @@ -7,7 +7,7 @@ import ( context "context" fmt "fmt" _ "github.com/cosmos/cosmos-proto" - types1 "github.com/cosmos/cosmos-sdk/codec/types" + types2 "github.com/cosmos/cosmos-sdk/codec/types" github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" types "github.com/cosmos/cosmos-sdk/types" _ "github.com/cosmos/cosmos-sdk/types/msgservice" @@ -15,7 +15,8 @@ import ( _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" proto "github.com/cosmos/gogoproto/proto" - types2 "github.com/neutron-org/neutron/v4/x/feerefunder/types" + types1 "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + types3 "github.com/neutron-org/neutron/v4/x/feerefunder/types" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -42,6 +43,7 @@ type MsgRegisterInterchainAccount struct { ConnectionId string `protobuf:"bytes,2,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty" yaml:"connection_id"` InterchainAccountId string `protobuf:"bytes,3,opt,name=interchain_account_id,json=interchainAccountId,proto3" json:"interchain_account_id,omitempty" yaml:"interchain_account_id"` RegisterFee github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,4,rep,name=register_fee,json=registerFee,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"register_fee"` + Ordering types1.Order `protobuf:"varint,5,opt,name=ordering,proto3,enum=ibc.core.channel.v1.Order" json:"ordering,omitempty"` } func (m *MsgRegisterInterchainAccount) Reset() { *m = MsgRegisterInterchainAccount{} } @@ -126,11 +128,11 @@ type MsgSubmitTx struct { // claim our capability for. InterchainAccountId string `protobuf:"bytes,2,opt,name=interchain_account_id,json=interchainAccountId,proto3" json:"interchain_account_id,omitempty"` ConnectionId string `protobuf:"bytes,3,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"` - Msgs []*types1.Any `protobuf:"bytes,4,rep,name=msgs,proto3" json:"msgs,omitempty"` + Msgs []*types2.Any `protobuf:"bytes,4,rep,name=msgs,proto3" json:"msgs,omitempty"` Memo string `protobuf:"bytes,5,opt,name=memo,proto3" json:"memo,omitempty"` // timeout in seconds after which the packet times out Timeout uint64 `protobuf:"varint,6,opt,name=timeout,proto3" json:"timeout,omitempty"` - Fee types2.Fee `protobuf:"bytes,7,opt,name=fee,proto3" json:"fee"` + Fee types3.Fee `protobuf:"bytes,7,opt,name=fee,proto3" json:"fee"` } func (m *MsgSubmitTx) Reset() { *m = MsgSubmitTx{} } @@ -332,60 +334,63 @@ func init() { func init() { proto.RegisterFile("neutron/interchaintxs/v1/tx.proto", fileDescriptor_50f087790e59c806) } var fileDescriptor_50f087790e59c806 = []byte{ - // 839 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0xbf, 0x6f, 0xfb, 0x44, - 0x14, 0x8f, 0x93, 0x7c, 0x53, 0x72, 0x09, 0x42, 0xb8, 0xa9, 0xea, 0x44, 0x6d, 0x92, 0x1a, 0x2a, - 0x85, 0x4a, 0xb1, 0x9b, 0x80, 0x8a, 0x14, 0x09, 0xa4, 0xa6, 0x52, 0xa5, 0x0c, 0x91, 0x8a, 0x5b, - 0x16, 0x96, 0xe8, 0x62, 0x5f, 0x1c, 0x8b, 0xf8, 0xce, 0xf8, 0xce, 0x51, 0xb2, 0x21, 0x26, 0xc4, - 0xc4, 0xc2, 0xde, 0x11, 0x31, 0xa0, 0x0e, 0xfc, 0x01, 0x8c, 0x1d, 0x2b, 0x26, 0xa6, 0x02, 0xed, - 0x50, 0xe6, 0x0e, 0xcc, 0xe8, 0xec, 0x73, 0x7e, 0xa9, 0x89, 0xaa, 0xef, 0x92, 0xdc, 0x7b, 0xef, - 0x73, 0xef, 0xbd, 0xfb, 0x7c, 0xee, 0x9d, 0xc1, 0x01, 0x46, 0x01, 0xf3, 0x09, 0xd6, 0x1d, 0xcc, - 0x90, 0x6f, 0x0e, 0xa1, 0x83, 0xd9, 0x84, 0xea, 0xe3, 0x86, 0xce, 0x26, 0x9a, 0xe7, 0x13, 0x46, - 0x64, 0x45, 0x40, 0xb4, 0x25, 0x88, 0x36, 0x6e, 0x94, 0xde, 0x87, 0xae, 0x83, 0x89, 0x1e, 0xfe, - 0x46, 0xe0, 0x52, 0xd9, 0x24, 0xd4, 0x25, 0x54, 0xef, 0x43, 0x8a, 0xf4, 0x71, 0xa3, 0x8f, 0x18, - 0x6c, 0xe8, 0x26, 0x71, 0xb0, 0x88, 0xef, 0x8a, 0xb8, 0x4b, 0x6d, 0x5e, 0xc4, 0xa5, 0xb6, 0x08, - 0x14, 0xa3, 0x40, 0x2f, 0xb4, 0xf4, 0xc8, 0x10, 0xa1, 0x82, 0x4d, 0x6c, 0x12, 0xf9, 0xf9, 0x4a, - 0x78, 0xf7, 0x6c, 0x42, 0xec, 0x11, 0xd2, 0xa1, 0xe7, 0xe8, 0x10, 0x63, 0xc2, 0x20, 0x73, 0x08, - 0x8e, 0xf7, 0xec, 0x2c, 0x44, 0x87, 0x8c, 0x79, 0x71, 0x15, 0xe1, 0x0e, 0xad, 0x7e, 0x30, 0xd0, - 0x21, 0x9e, 0x8a, 0xd0, 0x7e, 0xcc, 0xc4, 0x00, 0x21, 0x1f, 0x0d, 0x02, 0x6c, 0x21, 0x9f, 0xaf, - 0x45, 0xf8, 0x70, 0x2d, 0x51, 0x1e, 0xf4, 0xa1, 0x2b, 0xea, 0xaa, 0xff, 0x24, 0xc1, 0x5e, 0x97, - 0xda, 0x06, 0xb2, 0x1d, 0xca, 0x90, 0xdf, 0x99, 0x81, 0x4f, 0x4d, 0x93, 0x04, 0x98, 0xc9, 0x07, - 0x20, 0x3f, 0xf0, 0x89, 0xdb, 0x83, 0x96, 0xe5, 0x23, 0x4a, 0x15, 0xa9, 0x2a, 0xd5, 0xb2, 0x46, - 0x8e, 0xfb, 0x4e, 0x23, 0x97, 0xfc, 0x19, 0x78, 0xd7, 0x24, 0x18, 0x23, 0x93, 0x1f, 0xa8, 0xe7, - 0x58, 0x4a, 0x92, 0x63, 0xda, 0xca, 0xf3, 0x7d, 0xa5, 0x30, 0x85, 0xee, 0xa8, 0xa5, 0x2e, 0x85, - 0x55, 0x23, 0x3f, 0xb7, 0x3b, 0x96, 0x7c, 0x05, 0x76, 0xe6, 0x3d, 0xf6, 0x60, 0x54, 0x97, 0xa7, - 0x49, 0x85, 0x69, 0xaa, 0xcf, 0xf7, 0x95, 0xbd, 0x28, 0xcd, 0x8b, 0x30, 0xd5, 0xd8, 0x76, 0x56, - 0xbb, 0xee, 0x58, 0x32, 0x06, 0x79, 0x5f, 0x1c, 0xaa, 0x37, 0x40, 0x48, 0x49, 0x57, 0x53, 0xb5, - 0x5c, 0xb3, 0xa8, 0x09, 0xa5, 0xb8, 0xde, 0x9a, 0xd0, 0x5b, 0x3b, 0x23, 0x0e, 0x6e, 0x1f, 0xdf, - 0xde, 0x57, 0x12, 0xbf, 0xfc, 0x55, 0xa9, 0xd9, 0x0e, 0x1b, 0x06, 0x7d, 0xcd, 0x24, 0xae, 0x90, - 0x55, 0xfc, 0xd5, 0xa9, 0xf5, 0xb5, 0xce, 0xa6, 0x1e, 0xa2, 0xe1, 0x06, 0x6a, 0xe4, 0xe2, 0x02, - 0xe7, 0x08, 0xb5, 0x8a, 0xdf, 0x5f, 0x57, 0x12, 0xff, 0x5e, 0x57, 0x12, 0xdf, 0x3d, 0xdd, 0x1c, - 0x2d, 0x51, 0xa6, 0x5a, 0xe0, 0xc3, 0x4d, 0x14, 0x1b, 0x88, 0x7a, 0x04, 0x53, 0x24, 0xef, 0x03, - 0x60, 0x0e, 0x21, 0xc6, 0x68, 0xc4, 0x4f, 0x1f, 0x11, 0x9d, 0x15, 0x9e, 0x8e, 0x25, 0xef, 0x82, - 0x2d, 0x8f, 0xf8, 0x6c, 0x46, 0xb0, 0x91, 0xe1, 0x66, 0xc7, 0x6a, 0xa5, 0x79, 0x69, 0xf5, 0xd7, - 0x24, 0xc8, 0x75, 0xa9, 0x7d, 0x19, 0xf4, 0x5d, 0x87, 0x5d, 0x4d, 0x5e, 0x23, 0x5c, 0x73, 0x1d, - 0xf3, 0x51, 0xfe, 0x17, 0x79, 0xfd, 0x60, 0x55, 0xec, 0x50, 0xa5, 0x15, 0x49, 0x6b, 0x20, 0xed, - 0x52, 0x9b, 0x0a, 0xd2, 0x0b, 0x5a, 0x74, 0x8b, 0xb5, 0xf8, 0x16, 0x6b, 0xa7, 0x78, 0x6a, 0x84, - 0x08, 0x59, 0x06, 0x69, 0x17, 0xb9, 0x44, 0x79, 0x13, 0x66, 0x09, 0xd7, 0xb2, 0x02, 0xb6, 0x98, - 0xe3, 0x22, 0x12, 0x30, 0x25, 0x53, 0x95, 0x6a, 0x69, 0x23, 0x36, 0xe5, 0x63, 0x90, 0xe2, 0x5a, - 0x6e, 0x55, 0xa5, 0x5a, 0xae, 0xa9, 0x68, 0xf1, 0xa0, 0x2f, 0x4c, 0x80, 0x76, 0x8e, 0x50, 0x3b, - 0xcd, 0xa5, 0x34, 0x38, 0x74, 0x93, 0x2c, 0x17, 0x60, 0x7b, 0x81, 0xaf, 0x99, 0x0a, 0x15, 0x90, - 0xa3, 0xe8, 0x9b, 0x00, 0x61, 0x13, 0xc5, 0x32, 0xa4, 0x0d, 0x10, 0xbb, 0x3a, 0x16, 0x6f, 0x4f, - 0x88, 0x22, 0x78, 0x8a, 0x4d, 0xf5, 0x77, 0x09, 0xbc, 0xd7, 0xa5, 0xf6, 0x97, 0x9e, 0x05, 0x19, - 0xba, 0x08, 0xc7, 0x4c, 0x3e, 0x01, 0x59, 0x18, 0xb0, 0x21, 0xf1, 0x1d, 0x36, 0x8d, 0x34, 0x68, - 0x2b, 0x7f, 0xfc, 0x56, 0x2f, 0x88, 0x7b, 0x28, 0xa4, 0xb8, 0x64, 0xbe, 0x83, 0x6d, 0x63, 0x0e, - 0x95, 0xcf, 0x40, 0x26, 0x1a, 0xd4, 0xb0, 0x48, 0xae, 0x59, 0xd5, 0xd6, 0x3d, 0x6b, 0x5a, 0x54, - 0xa9, 0x9d, 0xe5, 0xa7, 0xfe, 0xf9, 0xe9, 0xe6, 0x48, 0x32, 0xc4, 0xd6, 0xd6, 0x31, 0x3f, 0xf5, - 0x3c, 0xe9, 0x0f, 0x4f, 0x37, 0x47, 0xfb, 0xcb, 0xef, 0xc1, 0x4a, 0xbb, 0x6a, 0x11, 0xec, 0xae, - 0xb8, 0x62, 0x62, 0x9a, 0xff, 0x25, 0x41, 0xaa, 0x4b, 0x6d, 0xf9, 0x27, 0x09, 0x14, 0xd7, 0xbf, - 0x17, 0x27, 0xeb, 0xfb, 0xdc, 0x34, 0x04, 0xa5, 0xcf, 0xdf, 0x6e, 0x5f, 0xdc, 0x9d, 0x9a, 0x90, - 0xfb, 0xe0, 0x9d, 0xd9, 0xe5, 0x3f, 0xdc, 0x98, 0x2d, 0x86, 0x95, 0xea, 0xaf, 0x82, 0x2d, 0xd4, - 0x18, 0x81, 0xfc, 0x92, 0xba, 0x1f, 0x6d, 0x4c, 0xb0, 0x08, 0x2d, 0x35, 0x5e, 0x0d, 0x8d, 0xeb, - 0x95, 0xde, 0x7c, 0xcb, 0xd5, 0x6c, 0x7f, 0x71, 0xfb, 0x50, 0x96, 0xee, 0x1e, 0xca, 0xd2, 0xdf, - 0x0f, 0x65, 0xe9, 0xc7, 0xc7, 0x72, 0xe2, 0xee, 0xb1, 0x9c, 0xf8, 0xf3, 0xb1, 0x9c, 0xf8, 0xea, - 0xd3, 0x85, 0xb7, 0x4a, 0x64, 0xaf, 0x13, 0xdf, 0x8e, 0xd7, 0xfa, 0xf8, 0x13, 0x7d, 0xb2, 0xf2, - 0x01, 0x08, 0x1f, 0xb0, 0x7e, 0x26, 0x1c, 0xc5, 0x8f, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xd9, - 0x95, 0xf0, 0x9e, 0x4f, 0x07, 0x00, 0x00, + // 891 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0x31, 0x6f, 0x23, 0x45, + 0x14, 0xf6, 0xc6, 0xbe, 0xe4, 0x3c, 0x0e, 0x20, 0xf6, 0x72, 0xca, 0xda, 0x4a, 0x6c, 0x67, 0xe1, + 0x24, 0x13, 0x29, 0xb3, 0xb1, 0x41, 0x41, 0x8a, 0x04, 0x52, 0x7c, 0xd2, 0x49, 0x2e, 0x22, 0x8e, + 0xbd, 0xa3, 0xa1, 0xb1, 0x66, 0x77, 0xc7, 0xeb, 0x11, 0xd9, 0x19, 0x33, 0x33, 0x6b, 0xc5, 0x1d, + 0xa2, 0x42, 0x54, 0x34, 0x14, 0x74, 0x57, 0x22, 0x0a, 0x94, 0x82, 0x1f, 0x40, 0x79, 0xe5, 0x89, + 0x8a, 0x2a, 0xa0, 0xa4, 0x08, 0xf5, 0x15, 0xd4, 0x68, 0x76, 0x67, 0x1c, 0xdb, 0x3a, 0x5b, 0x11, + 0x8d, 0x3d, 0xef, 0xbd, 0x6f, 0xde, 0x37, 0xf3, 0xbe, 0x37, 0x6f, 0xc1, 0x1e, 0xc5, 0xa9, 0xe4, + 0x8c, 0x7a, 0x84, 0x4a, 0xcc, 0xc3, 0x21, 0x22, 0x54, 0x9e, 0x0b, 0x6f, 0xdc, 0xf6, 0xe4, 0x39, + 0x1c, 0x71, 0x26, 0x99, 0xed, 0x68, 0x08, 0x9c, 0x83, 0xc0, 0x71, 0xbb, 0xf6, 0x2e, 0x4a, 0x08, + 0x65, 0x5e, 0xf6, 0x9b, 0x83, 0x6b, 0xf5, 0x90, 0x89, 0x84, 0x09, 0x2f, 0x40, 0x02, 0x7b, 0xe3, + 0x76, 0x80, 0x25, 0x6a, 0x7b, 0x21, 0x23, 0x54, 0xc7, 0xb7, 0x75, 0x3c, 0x11, 0xb1, 0x22, 0x49, + 0x44, 0xac, 0x03, 0xd5, 0x3c, 0xd0, 0xcf, 0x2c, 0x2f, 0x37, 0x74, 0x68, 0x2b, 0x66, 0x31, 0xcb, + 0xfd, 0x6a, 0xa5, 0xbd, 0x3b, 0x31, 0x63, 0xf1, 0x19, 0xf6, 0xd0, 0x88, 0x78, 0x88, 0x52, 0x26, + 0x91, 0x24, 0x8c, 0x9a, 0x3d, 0x0f, 0x67, 0xa2, 0x43, 0x29, 0x47, 0x86, 0x45, 0xbb, 0x33, 0x2b, + 0x48, 0x07, 0x1e, 0xa2, 0x13, 0x1d, 0xda, 0x35, 0x95, 0x18, 0x60, 0xcc, 0xf1, 0x20, 0xa5, 0x11, + 0xe6, 0x6a, 0xad, 0xc3, 0x8f, 0x96, 0x16, 0x6a, 0x84, 0x38, 0x4a, 0x0c, 0xef, 0x1e, 0x09, 0x42, + 0x2f, 0x64, 0x1c, 0x7b, 0xe1, 0x10, 0x51, 0x8a, 0xcf, 0x14, 0x42, 0x2f, 0x73, 0x88, 0xfb, 0x53, + 0x11, 0xec, 0x9c, 0x8a, 0xd8, 0xc7, 0x31, 0x11, 0x12, 0xf3, 0xde, 0x34, 0xdf, 0x49, 0x18, 0xb2, + 0x94, 0x4a, 0x7b, 0x0f, 0x6c, 0x0e, 0x38, 0x4b, 0xfa, 0x28, 0x8a, 0x38, 0x16, 0xc2, 0xb1, 0x9a, + 0x56, 0xab, 0xec, 0x57, 0x94, 0xef, 0x24, 0x77, 0xd9, 0x9f, 0x80, 0xb7, 0x42, 0x46, 0x29, 0x0e, + 0xd5, 0x9d, 0xfb, 0x24, 0x72, 0xd6, 0x14, 0xa6, 0xeb, 0xbc, 0xbe, 0x6c, 0x6c, 0x4d, 0x50, 0x72, + 0x76, 0xec, 0xce, 0x85, 0x5d, 0x7f, 0xf3, 0xd6, 0xee, 0x45, 0xf6, 0x73, 0xf0, 0xf0, 0xf6, 0x1a, + 0x7d, 0x94, 0xf3, 0xaa, 0x34, 0xc5, 0x2c, 0x4d, 0xf3, 0xf5, 0x65, 0x63, 0x27, 0x4f, 0xf3, 0x46, + 0x98, 0xeb, 0x3f, 0x20, 0x8b, 0xa7, 0xee, 0x45, 0x36, 0x05, 0x9b, 0x5c, 0x5f, 0xaa, 0x3f, 0xc0, + 0xd8, 0x29, 0x35, 0x8b, 0xad, 0x4a, 0xa7, 0x0a, 0xb5, 0x98, 0xaa, 0x25, 0xa0, 0x6e, 0x09, 0xf8, + 0x98, 0x11, 0xda, 0x3d, 0x7c, 0x79, 0xd9, 0x28, 0xfc, 0xf2, 0x57, 0xa3, 0x15, 0x13, 0x39, 0x4c, + 0x03, 0x18, 0xb2, 0x44, 0x2b, 0xaf, 0xff, 0x0e, 0x44, 0xf4, 0x95, 0x27, 0x27, 0x23, 0x2c, 0xb2, + 0x0d, 0xc2, 0xaf, 0x18, 0x82, 0x27, 0x18, 0xdb, 0x47, 0xe0, 0x3e, 0xe3, 0x11, 0xe6, 0x84, 0xc6, + 0xce, 0xbd, 0xa6, 0xd5, 0x7a, 0xbb, 0x53, 0x83, 0x24, 0x08, 0xa1, 0x2a, 0x3f, 0x34, 0x35, 0x1f, + 0xb7, 0xe1, 0x67, 0x0a, 0xe4, 0x4f, 0xb1, 0xc7, 0xd5, 0xef, 0x5e, 0x34, 0x0a, 0xff, 0xbc, 0x68, + 0x14, 0xbe, 0xbd, 0xb9, 0xd8, 0x9f, 0x2b, 0xb5, 0x1b, 0x81, 0xf7, 0x57, 0x49, 0xe3, 0x63, 0x31, + 0x62, 0x54, 0x60, 0x7b, 0x17, 0x00, 0x4d, 0xa0, 0xaa, 0x96, 0x0b, 0x54, 0xd6, 0x9e, 0x5e, 0x64, + 0x6f, 0x83, 0x8d, 0x11, 0xe3, 0x72, 0x2a, 0x8c, 0xbf, 0xae, 0xcc, 0x5e, 0x74, 0x5c, 0x52, 0xd4, + 0xee, 0xaf, 0x6b, 0xa0, 0x72, 0x2a, 0xe2, 0x67, 0x69, 0x90, 0x10, 0xf9, 0xfc, 0xfc, 0x2e, 0x82, + 0x77, 0x96, 0x29, 0x96, 0xe7, 0x7f, 0xa3, 0x1e, 0xef, 0x2d, 0x36, 0x49, 0xa6, 0xee, 0x42, 0x2b, + 0xb4, 0x40, 0x29, 0x11, 0xb1, 0xd0, 0x62, 0x6d, 0xc1, 0xfc, 0x81, 0x40, 0xf3, 0x40, 0xe0, 0x09, + 0x9d, 0xf8, 0x19, 0xc2, 0xb6, 0x41, 0x29, 0xc1, 0x09, 0xcb, 0x4a, 0x5d, 0xf6, 0xb3, 0xb5, 0xed, + 0x80, 0x0d, 0x49, 0x12, 0xcc, 0x52, 0xe9, 0xac, 0x37, 0xad, 0x56, 0xc9, 0x37, 0xa6, 0x7d, 0x08, + 0x8a, 0xaa, 0x07, 0x36, 0x9a, 0x56, 0xab, 0xd2, 0x71, 0xa0, 0x99, 0x21, 0x33, 0x8f, 0x0b, 0x3e, + 0xc1, 0xb8, 0x5b, 0x52, 0x2d, 0xe0, 0x2b, 0xe8, 0x2a, 0x59, 0x9e, 0x82, 0x07, 0x33, 0xf5, 0x9a, + 0xaa, 0xd0, 0x00, 0x15, 0x81, 0xbf, 0x4e, 0x31, 0x0d, 0xb1, 0x91, 0xa1, 0xe4, 0x03, 0xe3, 0xea, + 0x45, 0xea, 0x78, 0x5a, 0x14, 0x5d, 0x27, 0x63, 0xba, 0xbf, 0x5b, 0xe0, 0x9d, 0x53, 0x11, 0x7f, + 0x31, 0x8a, 0x90, 0xc4, 0x4f, 0xb3, 0x17, 0x6c, 0x1f, 0x81, 0x32, 0x4a, 0xe5, 0x90, 0x71, 0x22, + 0x27, 0xb9, 0x06, 0x5d, 0xe7, 0x8f, 0xdf, 0x0e, 0xb6, 0x74, 0xff, 0x6a, 0x29, 0x9e, 0x49, 0xd5, + 0x44, 0xfe, 0x2d, 0xd4, 0x7e, 0x0c, 0xd6, 0xf3, 0x19, 0x90, 0x91, 0x54, 0x3a, 0x4d, 0xb8, 0x6c, + 0x62, 0xc2, 0x9c, 0xa9, 0x5b, 0x56, 0xb7, 0xfe, 0xf9, 0xe6, 0x62, 0xdf, 0xf2, 0xf5, 0xd6, 0xe3, + 0x43, 0x75, 0xeb, 0xdb, 0xa4, 0xdf, 0xdf, 0x5c, 0xec, 0xef, 0xce, 0x8f, 0x9a, 0x85, 0xe3, 0xba, + 0x55, 0xb0, 0xbd, 0xe0, 0x32, 0x85, 0xe9, 0xfc, 0xbb, 0x06, 0x8a, 0xa7, 0x22, 0xb6, 0x7f, 0xb4, + 0x40, 0x75, 0xf9, 0x9c, 0x39, 0x5a, 0x7e, 0xce, 0x55, 0x8f, 0xa0, 0xf6, 0xe9, 0xff, 0xdb, 0x67, + 0x4e, 0xe7, 0x16, 0xec, 0x00, 0xdc, 0x9f, 0x36, 0xff, 0xa3, 0x95, 0xd9, 0x0c, 0xac, 0x76, 0x70, + 0x27, 0xd8, 0x0c, 0xc7, 0x19, 0xd8, 0x9c, 0x53, 0xf7, 0x83, 0x95, 0x09, 0x66, 0xa1, 0xb5, 0xf6, + 0x9d, 0xa1, 0x86, 0xaf, 0x76, 0xef, 0x1b, 0xa5, 0x66, 0xf7, 0xf3, 0x97, 0x57, 0x75, 0xeb, 0xd5, + 0x55, 0xdd, 0xfa, 0xfb, 0xaa, 0x6e, 0xfd, 0x70, 0x5d, 0x2f, 0xbc, 0xba, 0xae, 0x17, 0xfe, 0xbc, + 0xae, 0x17, 0xbe, 0xfc, 0x78, 0x66, 0xc6, 0xe9, 0xec, 0x07, 0x8c, 0xc7, 0x66, 0xed, 0x8d, 0x3f, + 0xf2, 0xce, 0x17, 0xbe, 0x2d, 0xd9, 0xe0, 0x0b, 0xd6, 0xb3, 0xa7, 0xf8, 0xe1, 0x7f, 0x01, 0x00, + 0x00, 0xff, 0xff, 0x03, 0x83, 0x36, 0x64, 0xaa, 0x07, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -560,6 +565,11 @@ func (m *MsgRegisterInterchainAccount) MarshalToSizedBuffer(dAtA []byte) (int, e _ = i var l int _ = l + if m.Ordering != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Ordering)) + i-- + dAtA[i] = 0x28 + } if len(m.RegisterFee) > 0 { for iNdEx := len(m.RegisterFee) - 1; iNdEx >= 0; iNdEx-- { { @@ -848,6 +858,9 @@ func (m *MsgRegisterInterchainAccount) Size() (n int) { n += 1 + l + sovTx(uint64(l)) } } + if m.Ordering != 0 { + n += 1 + sovTx(uint64(m.Ordering)) + } return n } @@ -1109,6 +1122,25 @@ func (m *MsgRegisterInterchainAccount) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Ordering", wireType) + } + m.Ordering = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Ordering |= types1.Order(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) @@ -1398,7 +1430,7 @@ func (m *MsgSubmitTx) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Msgs = append(m.Msgs, &types1.Any{}) + m.Msgs = append(m.Msgs, &types2.Any{}) if err := m.Msgs[len(m.Msgs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } From 53590d875852bef9a44c5affab1ef3e8a4907da8 Mon Sep 17 00:00:00 2001 From: nhpd Date: Wed, 7 Aug 2024 18:55:05 +0400 Subject: [PATCH 03/15] feat: add bindings for ordering in ica channels --- wasmbinding/bindings/msg.go | 1 + wasmbinding/message_plugin.go | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/wasmbinding/bindings/msg.go b/wasmbinding/bindings/msg.go index 03fc3640b..dad007622 100644 --- a/wasmbinding/bindings/msg.go +++ b/wasmbinding/bindings/msg.go @@ -81,6 +81,7 @@ type RegisterInterchainAccount struct { ConnectionId string `json:"connection_id"` InterchainAccountId string `json:"interchain_account_id"` RegisterFee sdk.Coins `json:"register_fee,omitempty"` + Ordering string `json:"ordering"` } // RegisterInterchainAccountResponse holds response for RegisterInterchainAccount. diff --git a/wasmbinding/message_plugin.go b/wasmbinding/message_plugin.go index a22c5e78d..37086aee2 100644 --- a/wasmbinding/message_plugin.go +++ b/wasmbinding/message_plugin.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + types1 "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" "strings" "time" @@ -865,11 +866,24 @@ func (m *CustomMessenger) registerInterchainAccount(ctx sdk.Context, contractAdd } func (m *CustomMessenger) performRegisterInterchainAccount(ctx sdk.Context, contractAddr sdk.AccAddress, reg *bindings.RegisterInterchainAccount) (*ictxtypes.MsgRegisterInterchainAccountResponse, error) { + // parse incoming ordering. If nothing passed, use ORDERED by default + var orderValue types1.Order + if reg.Ordering == "" { + orderValueInt, ok := types1.Order_value[reg.Ordering] + if !ok { + return nil, fmt.Errorf("failed to register interchain account: incorrect order value passed: %s", reg.Ordering) + } + orderValue = types1.Order(orderValueInt) + } else { + orderValue = types1.ORDERED + } + msg := ictxtypes.MsgRegisterInterchainAccount{ FromAddress: contractAddr.String(), ConnectionId: reg.ConnectionId, InterchainAccountId: reg.InterchainAccountId, RegisterFee: getRegisterFee(reg.RegisterFee), + Ordering: orderValue, } response, err := m.Ictxmsgserver.RegisterInterchainAccount(ctx, &msg) From d586932a98fe72f5229a14540d398ce242c71aa0 Mon Sep 17 00:00:00 2001 From: nhpd Date: Thu, 8 Aug 2024 16:01:37 +0400 Subject: [PATCH 04/15] omitempty for ica creation ordering field --- wasmbinding/bindings/msg.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wasmbinding/bindings/msg.go b/wasmbinding/bindings/msg.go index dad007622..2aee5622a 100644 --- a/wasmbinding/bindings/msg.go +++ b/wasmbinding/bindings/msg.go @@ -81,7 +81,7 @@ type RegisterInterchainAccount struct { ConnectionId string `json:"connection_id"` InterchainAccountId string `json:"interchain_account_id"` RegisterFee sdk.Coins `json:"register_fee,omitempty"` - Ordering string `json:"ordering"` + Ordering string `json:"ordering,omitempty"` } // RegisterInterchainAccountResponse holds response for RegisterInterchainAccount. From f103be80bb1bb131fb19ec731f8926ad1c237cbe Mon Sep 17 00:00:00 2001 From: nhpd Date: Mon, 12 Aug 2024 23:55:09 +0400 Subject: [PATCH 05/15] fix --- wasmbinding/message_plugin.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wasmbinding/message_plugin.go b/wasmbinding/message_plugin.go index 37086aee2..61499d249 100644 --- a/wasmbinding/message_plugin.go +++ b/wasmbinding/message_plugin.go @@ -869,13 +869,13 @@ func (m *CustomMessenger) performRegisterInterchainAccount(ctx sdk.Context, cont // parse incoming ordering. If nothing passed, use ORDERED by default var orderValue types1.Order if reg.Ordering == "" { + orderValue = types1.ORDERED + } else { orderValueInt, ok := types1.Order_value[reg.Ordering] if !ok { return nil, fmt.Errorf("failed to register interchain account: incorrect order value passed: %s", reg.Ordering) } orderValue = types1.Order(orderValueInt) - } else { - orderValue = types1.ORDERED } msg := ictxtypes.MsgRegisterInterchainAccount{ From 3484f7e98f3704119d31098095f384c41f201449 Mon Sep 17 00:00:00 2001 From: nhpd Date: Thu, 15 Aug 2024 12:15:25 +0400 Subject: [PATCH 06/15] lint --- wasmbinding/message_plugin.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wasmbinding/message_plugin.go b/wasmbinding/message_plugin.go index 61499d249..81e05eed0 100644 --- a/wasmbinding/message_plugin.go +++ b/wasmbinding/message_plugin.go @@ -4,10 +4,11 @@ import ( "context" "encoding/json" "fmt" - types1 "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" "strings" "time" + types1 "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + "github.com/cosmos/gogoproto/proto" "golang.org/x/exp/maps" From 71e12c163c527c95d53147726f6e2c3ac2ae5751 Mon Sep 17 00:00:00 2001 From: nhpd Date: Thu, 15 Aug 2024 12:17:52 +0400 Subject: [PATCH 07/15] format proto --- proto/neutron/interchaintxs/v1/tx.proto | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proto/neutron/interchaintxs/v1/tx.proto b/proto/neutron/interchaintxs/v1/tx.proto index 32148ce7b..a2bb14202 100644 --- a/proto/neutron/interchaintxs/v1/tx.proto +++ b/proto/neutron/interchaintxs/v1/tx.proto @@ -9,9 +9,9 @@ import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; import "google/api/http.proto"; import "google/protobuf/any.proto"; +import "ibc/core/channel/v1/channel.proto"; import "neutron/feerefunder/fee.proto"; import "neutron/interchaintxs/v1/params.proto"; -import "ibc/core/channel/v1/channel.proto"; option go_package = "github.com/neutron-org/neutron/v4/x/interchaintxs/types"; @@ -37,7 +37,7 @@ message MsgRegisterInterchainAccount { (gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" ]; - ibc.core.channel.v1.Order ordering = 5; + ibc.core.channel.v1.Order ordering = 5; } // MsgRegisterInterchainAccountResponse is the response type for From de5192853149f5d57037d44c0f22524cabd53fa7 Mon Sep 17 00:00:00 2001 From: nhpd Date: Thu, 15 Aug 2024 15:25:11 +0400 Subject: [PATCH 08/15] copy third party proto for ibc from v8.2.1 --- .../proto/ibc/applications/fee/v1/ack.proto | 8 +- .../proto/ibc/applications/fee/v1/fee.proto | 27 +- .../ibc/applications/fee/v1/genesis.proto | 28 +- .../ibc/applications/fee/v1/metadata.proto | 6 +- .../proto/ibc/applications/fee/v1/query.proto | 44 +- .../proto/ibc/applications/fee/v1/tx.proto | 40 +- .../controller/v1/controller.proto | 4 +- .../controller/v1/query.proto | 3 +- .../controller/v1/tx.proto | 55 +- .../genesis/v1/genesis.proto | 40 +- .../interchain_accounts/host/v1/host.proto | 6 +- .../interchain_accounts/host/v1/tx.proto | 35 ++ .../interchain_accounts/v1/account.proto | 5 +- .../interchain_accounts/v1/metadata.proto | 6 +- .../ibc/applications/transfer/v1/authz.proto | 7 +- .../applications/transfer/v1/genesis.proto | 17 +- .../applications/transfer/v1/transfer.proto | 6 +- .../ibc/applications/transfer/v1/tx.proto | 44 +- .../proto/ibc/channel/v1/channel.proto | 187 +++++++ .../proto/ibc/channel/v1/genesis.proto | 30 ++ third_party/proto/ibc/channel/v1/query.proto | 459 +++++++++++++++++ third_party/proto/ibc/channel/v1/tx.proto | 469 ++++++++++++++++++ .../proto/ibc/channel/v1/upgrade.proto | 43 ++ third_party/proto/ibc/client/v1/client.proto | 113 +++++ third_party/proto/ibc/client/v1/genesis.proto | 44 ++ third_party/proto/ibc/client/v1/query.proto | 207 ++++++++ third_party/proto/ibc/client/v1/tx.proto | 175 +++++++ .../proto/ibc/commitment/v1/commitment.proto | 39 ++ .../proto/ibc/connection/v1/connection.proto | 114 +++++ .../proto/ibc/connection/v1/genesis.proto | 17 + .../proto/ibc/connection/v1/query.proto | 152 ++++++ third_party/proto/ibc/connection/v1/tx.proto | 146 ++++++ .../proto/ibc/core/channel/v1/channel.proto | 57 ++- .../proto/ibc/core/channel/v1/genesis.proto | 16 +- .../proto/ibc/core/channel/v1/query.proto | 85 +++- .../proto/ibc/core/channel/v1/tx.proto | 349 ++++++++++--- .../proto/ibc/core/channel/v1/upgrade.proto | 43 ++ .../proto/ibc/core/client/v1/client.proto | 86 ++-- .../proto/ibc/core/client/v1/genesis.proto | 24 +- third_party/proto/ibc/core/client/v1/tx.proto | 107 +++- .../ibc/core/commitment/v1/commitment.proto | 6 +- .../ibc/core/connection/v1/connection.proto | 18 +- .../ibc/core/connection/v1/genesis.proto | 5 +- .../proto/ibc/core/connection/v1/query.proto | 4 +- .../proto/ibc/core/connection/v1/tx.proto | 98 ++-- .../proto/ibc/core/types/v1/genesis.proto | 9 +- third_party/proto/ibc/fee/v1/ack.proto | 15 + third_party/proto/ibc/fee/v1/fee.proto | 61 +++ third_party/proto/ibc/fee/v1/genesis.proto | 60 +++ third_party/proto/ibc/fee/v1/metadata.proto | 14 + third_party/proto/ibc/fee/v1/query.proto | 218 ++++++++ third_party/proto/ibc/fee/v1/tx.proto | 122 +++++ .../controller/v1/controller.proto | 12 + .../controller/v1/query.proto | 42 ++ .../controller/v1/tx.proto | 82 +++ .../genesis/v1/genesis.proto | 47 ++ .../interchain_accounts/host/v1/host.proto | 14 + .../interchain_accounts/host/v1/query.proto | 25 + .../ibc/interchain_accounts/host/v1/tx.proto | 35 ++ .../ibc/interchain_accounts/v1/account.proto | 19 + .../ibc/interchain_accounts/v1/metadata.proto | 23 + .../ibc/interchain_accounts/v1/packet.proto | 31 ++ .../solomachine/v2/solomachine.proto | 34 +- .../solomachine/v3/solomachine.proto | 20 +- .../tendermint/v1/tendermint.proto | 52 +- .../ibc/lightclients/wasm/v1/genesis.proto | 20 + .../ibc/lightclients/wasm/v1/query.proto | 46 ++ .../proto/ibc/lightclients/wasm/v1/tx.proto | 66 +++ .../proto/ibc/lightclients/wasm/v1/wasm.proto | 43 ++ .../proto/ibc/localhost/v2/localhost.proto | 16 + .../ibc/solomachine/v2/solomachine.proto | 189 +++++++ .../ibc/solomachine/v3/solomachine.proto | 99 ++++ .../proto/ibc/tendermint/v1/tendermint.proto | 101 ++++ third_party/proto/ibc/transfer/v1/authz.proto | 34 ++ .../proto/ibc/transfer/v1/genesis.proto | 20 + third_party/proto/ibc/transfer/v1/query.proto | 121 +++++ .../proto/ibc/transfer/v1/transfer.proto | 28 ++ third_party/proto/ibc/transfer/v1/tx.proto | 79 +++ .../proto/ibc/transfer/v2/packet.proto | 21 + third_party/proto/ibc/types/v1/genesis.proto | 20 + third_party/proto/ibc/wasm/v1/genesis.proto | 20 + third_party/proto/ibc/wasm/v1/query.proto | 46 ++ third_party/proto/ibc/wasm/v1/tx.proto | 66 +++ third_party/proto/ibc/wasm/v1/wasm.proto | 43 ++ x/interchaintxs/keeper/msg_server.go | 2 +- x/interchaintxs/keeper/msg_server_test.go | 3 +- x/interchaintxs/types/tx.pb.go | 100 ++-- 87 files changed, 5108 insertions(+), 484 deletions(-) create mode 100644 third_party/proto/ibc/applications/interchain_accounts/host/v1/tx.proto create mode 100644 third_party/proto/ibc/channel/v1/channel.proto create mode 100644 third_party/proto/ibc/channel/v1/genesis.proto create mode 100644 third_party/proto/ibc/channel/v1/query.proto create mode 100644 third_party/proto/ibc/channel/v1/tx.proto create mode 100644 third_party/proto/ibc/channel/v1/upgrade.proto create mode 100644 third_party/proto/ibc/client/v1/client.proto create mode 100644 third_party/proto/ibc/client/v1/genesis.proto create mode 100644 third_party/proto/ibc/client/v1/query.proto create mode 100644 third_party/proto/ibc/client/v1/tx.proto create mode 100644 third_party/proto/ibc/commitment/v1/commitment.proto create mode 100644 third_party/proto/ibc/connection/v1/connection.proto create mode 100644 third_party/proto/ibc/connection/v1/genesis.proto create mode 100644 third_party/proto/ibc/connection/v1/query.proto create mode 100644 third_party/proto/ibc/connection/v1/tx.proto create mode 100644 third_party/proto/ibc/core/channel/v1/upgrade.proto create mode 100644 third_party/proto/ibc/fee/v1/ack.proto create mode 100644 third_party/proto/ibc/fee/v1/fee.proto create mode 100644 third_party/proto/ibc/fee/v1/genesis.proto create mode 100644 third_party/proto/ibc/fee/v1/metadata.proto create mode 100644 third_party/proto/ibc/fee/v1/query.proto create mode 100644 third_party/proto/ibc/fee/v1/tx.proto create mode 100644 third_party/proto/ibc/interchain_accounts/controller/v1/controller.proto create mode 100644 third_party/proto/ibc/interchain_accounts/controller/v1/query.proto create mode 100644 third_party/proto/ibc/interchain_accounts/controller/v1/tx.proto create mode 100644 third_party/proto/ibc/interchain_accounts/genesis/v1/genesis.proto create mode 100644 third_party/proto/ibc/interchain_accounts/host/v1/host.proto create mode 100644 third_party/proto/ibc/interchain_accounts/host/v1/query.proto create mode 100644 third_party/proto/ibc/interchain_accounts/host/v1/tx.proto create mode 100644 third_party/proto/ibc/interchain_accounts/v1/account.proto create mode 100644 third_party/proto/ibc/interchain_accounts/v1/metadata.proto create mode 100644 third_party/proto/ibc/interchain_accounts/v1/packet.proto create mode 100644 third_party/proto/ibc/lightclients/wasm/v1/genesis.proto create mode 100644 third_party/proto/ibc/lightclients/wasm/v1/query.proto create mode 100644 third_party/proto/ibc/lightclients/wasm/v1/tx.proto create mode 100644 third_party/proto/ibc/lightclients/wasm/v1/wasm.proto create mode 100644 third_party/proto/ibc/localhost/v2/localhost.proto create mode 100644 third_party/proto/ibc/solomachine/v2/solomachine.proto create mode 100644 third_party/proto/ibc/solomachine/v3/solomachine.proto create mode 100644 third_party/proto/ibc/tendermint/v1/tendermint.proto create mode 100644 third_party/proto/ibc/transfer/v1/authz.proto create mode 100644 third_party/proto/ibc/transfer/v1/genesis.proto create mode 100644 third_party/proto/ibc/transfer/v1/query.proto create mode 100644 third_party/proto/ibc/transfer/v1/transfer.proto create mode 100644 third_party/proto/ibc/transfer/v1/tx.proto create mode 100644 third_party/proto/ibc/transfer/v2/packet.proto create mode 100644 third_party/proto/ibc/types/v1/genesis.proto create mode 100644 third_party/proto/ibc/wasm/v1/genesis.proto create mode 100644 third_party/proto/ibc/wasm/v1/query.proto create mode 100644 third_party/proto/ibc/wasm/v1/tx.proto create mode 100644 third_party/proto/ibc/wasm/v1/wasm.proto diff --git a/third_party/proto/ibc/applications/fee/v1/ack.proto b/third_party/proto/ibc/applications/fee/v1/ack.proto index cc12f3b58..2f3746d2c 100644 --- a/third_party/proto/ibc/applications/fee/v1/ack.proto +++ b/third_party/proto/ibc/applications/fee/v1/ack.proto @@ -4,14 +4,12 @@ package ibc.applications.fee.v1; option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"; -import "gogoproto/gogo.proto"; - // IncentivizedAcknowledgement is the acknowledgement format to be used by applications wrapped in the fee middleware message IncentivizedAcknowledgement { // the underlying app acknowledgement bytes - bytes app_acknowledgement = 1 [(gogoproto.moretags) = "yaml:\"app_acknowledgement\""]; + bytes app_acknowledgement = 1; // the relayer address which submits the recv packet message - string forward_relayer_address = 2 [(gogoproto.moretags) = "yaml:\"forward_relayer_address\""]; + string forward_relayer_address = 2; // success flag of the base application callback - bool underlying_app_success = 3 [(gogoproto.moretags) = "yaml:\"underlying_app_successl\""]; + bool underlying_app_success = 3; } diff --git a/third_party/proto/ibc/applications/fee/v1/fee.proto b/third_party/proto/ibc/applications/fee/v1/fee.proto index 4ef626d41..867e88455 100644 --- a/third_party/proto/ibc/applications/fee/v1/fee.proto +++ b/third_party/proto/ibc/applications/fee/v1/fee.proto @@ -4,38 +4,44 @@ package ibc.applications.fee.v1; option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"; +import "amino/amino.proto"; import "cosmos/base/v1beta1/coin.proto"; import "gogoproto/gogo.proto"; import "ibc/core/channel/v1/channel.proto"; +import "cosmos/msg/v1/msg.proto"; // Fee defines the ICS29 receive, acknowledgement and timeout fees message Fee { // the packet receive fee repeated cosmos.base.v1beta1.Coin recv_fee = 1 [ - (gogoproto.moretags) = "yaml:\"recv_fee\"", (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (amino.encoding) = "legacy_coins" ]; + // the packet acknowledgement fee repeated cosmos.base.v1beta1.Coin ack_fee = 2 [ - (gogoproto.moretags) = "yaml:\"ack_fee\"", (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (amino.encoding) = "legacy_coins" ]; + // the packet timeout fee repeated cosmos.base.v1beta1.Coin timeout_fee = 3 [ - (gogoproto.moretags) = "yaml:\"timeout_fee\"", (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (amino.encoding) = "legacy_coins" ]; } // PacketFee contains ICS29 relayer fees, refund address and optional list of permitted relayers message PacketFee { + option (cosmos.msg.v1.signer) = "refund_address"; + // fee encapsulates the recv, ack and timeout fees associated with an IBC packet Fee fee = 1 [(gogoproto.nullable) = false]; // the refund address for unspent fees - string refund_address = 2 [(gogoproto.moretags) = "yaml:\"refund_address\""]; + string refund_address = 2; // optional list of relayers permitted to receive fees repeated string relayers = 3; } @@ -43,14 +49,13 @@ message PacketFee { // PacketFees contains a list of type PacketFee message PacketFees { // list of packet fees - repeated PacketFee packet_fees = 1 [(gogoproto.moretags) = "yaml:\"packet_fees\"", (gogoproto.nullable) = false]; + repeated PacketFee packet_fees = 1 [(gogoproto.nullable) = false]; } // IdentifiedPacketFees contains a list of type PacketFee and associated PacketId message IdentifiedPacketFees { // unique packet identifier comprised of the channel ID, port ID and sequence - ibc.core.channel.v1.PacketId packet_id = 1 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"packet_id\""]; + ibc.core.channel.v1.PacketId packet_id = 1 [(gogoproto.nullable) = false]; // list of packet fees - repeated PacketFee packet_fees = 2 [(gogoproto.moretags) = "yaml:\"packet_fees\"", (gogoproto.nullable) = false]; + repeated PacketFee packet_fees = 2 [(gogoproto.nullable) = false]; } diff --git a/third_party/proto/ibc/applications/fee/v1/genesis.proto b/third_party/proto/ibc/applications/fee/v1/genesis.proto index 245525ca1..e48ceb535 100644 --- a/third_party/proto/ibc/applications/fee/v1/genesis.proto +++ b/third_party/proto/ibc/applications/fee/v1/genesis.proto @@ -11,34 +11,29 @@ import "ibc/core/channel/v1/channel.proto"; // GenesisState defines the ICS29 fee middleware genesis state message GenesisState { // list of identified packet fees - repeated IdentifiedPacketFees identified_fees = 1 - [(gogoproto.moretags) = "yaml:\"identified_fees\"", (gogoproto.nullable) = false]; + repeated IdentifiedPacketFees identified_fees = 1 [(gogoproto.nullable) = false]; // list of fee enabled channels - repeated FeeEnabledChannel fee_enabled_channels = 2 - [(gogoproto.moretags) = "yaml:\"fee_enabled_channels\"", (gogoproto.nullable) = false]; + repeated FeeEnabledChannel fee_enabled_channels = 2 [(gogoproto.nullable) = false]; // list of registered payees - repeated RegisteredPayee registered_payees = 3 - [(gogoproto.moretags) = "yaml:\"registered_payees\"", (gogoproto.nullable) = false]; + repeated RegisteredPayee registered_payees = 3 [(gogoproto.nullable) = false]; // list of registered counterparty payees - repeated RegisteredCounterpartyPayee registered_counterparty_payees = 4 - [(gogoproto.moretags) = "yaml:\"registered_counterparty_payees\"", (gogoproto.nullable) = false]; + repeated RegisteredCounterpartyPayee registered_counterparty_payees = 4 [(gogoproto.nullable) = false]; // list of forward relayer addresses - repeated ForwardRelayerAddress forward_relayers = 5 - [(gogoproto.moretags) = "yaml:\"forward_relayers\"", (gogoproto.nullable) = false]; + repeated ForwardRelayerAddress forward_relayers = 5 [(gogoproto.nullable) = false]; } // FeeEnabledChannel contains the PortID & ChannelID for a fee enabled channel message FeeEnabledChannel { // unique port identifier - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + string port_id = 1; // unique channel identifier - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + string channel_id = 2; } // RegisteredPayee contains the relayer address and payee address for a specific channel message RegisteredPayee { // unique channel identifier - string channel_id = 1 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + string channel_id = 1; // the relayer address string relayer = 2; // the payee address @@ -49,11 +44,11 @@ message RegisteredPayee { // for recv fee distribution) message RegisteredCounterpartyPayee { // unique channel identifier - string channel_id = 1 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + string channel_id = 1; // the relayer address string relayer = 2; // the counterparty payee address - string counterparty_payee = 3 [(gogoproto.moretags) = "yaml:\"counterparty_payee\""]; + string counterparty_payee = 3; } // ForwardRelayerAddress contains the forward relayer address and PacketId used for async acknowledgements @@ -61,6 +56,5 @@ message ForwardRelayerAddress { // the forward relayer address string address = 1; // unique packet identifer comprised of the channel ID, port ID and sequence - ibc.core.channel.v1.PacketId packet_id = 2 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"packet_id\""]; + ibc.core.channel.v1.PacketId packet_id = 2 [(gogoproto.nullable) = false]; } diff --git a/third_party/proto/ibc/applications/fee/v1/metadata.proto b/third_party/proto/ibc/applications/fee/v1/metadata.proto index 8d9879f35..1e82e7c25 100644 --- a/third_party/proto/ibc/applications/fee/v1/metadata.proto +++ b/third_party/proto/ibc/applications/fee/v1/metadata.proto @@ -4,13 +4,11 @@ package ibc.applications.fee.v1; option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"; -import "gogoproto/gogo.proto"; - // Metadata defines the ICS29 channel specific metadata encoded into the channel version bytestring // See ICS004: https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#Versioning message Metadata { // fee_version defines the ICS29 fee version - string fee_version = 1 [(gogoproto.moretags) = "yaml:\"fee_version\""]; + string fee_version = 1; // app_version defines the underlying application version, which may or may not be a JSON encoded bytestring - string app_version = 2 [(gogoproto.moretags) = "yaml:\"app_version\""]; + string app_version = 2; } diff --git a/third_party/proto/ibc/applications/fee/v1/query.proto b/third_party/proto/ibc/applications/fee/v1/query.proto index 7d54bcd01..726370ee0 100644 --- a/third_party/proto/ibc/applications/fee/v1/query.proto +++ b/third_party/proto/ibc/applications/fee/v1/query.proto @@ -83,6 +83,8 @@ message QueryIncentivizedPacketsRequest { message QueryIncentivizedPacketsResponse { // list of identified fees for incentivized packets repeated ibc.applications.fee.v1.IdentifiedPacketFees incentivized_packets = 1 [(gogoproto.nullable) = false]; + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; } // QueryIncentivizedPacketRequest defines the request type for the IncentivizedPacket rpc @@ -114,6 +116,8 @@ message QueryIncentivizedPacketsForChannelRequest { message QueryIncentivizedPacketsForChannelResponse { // Map of all incentivized_packets repeated ibc.applications.fee.v1.IdentifiedPacketFees incentivized_packets = 1; + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; } // QueryTotalRecvFeesRequest defines the request type for the TotalRecvFees rpc @@ -125,11 +129,8 @@ message QueryTotalRecvFeesRequest { // QueryTotalRecvFeesResponse defines the response type for the TotalRecvFees rpc message QueryTotalRecvFeesResponse { // the total packet receive fees - repeated cosmos.base.v1beta1.Coin recv_fees = 1 [ - (gogoproto.moretags) = "yaml:\"recv_fees\"", - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" - ]; + repeated cosmos.base.v1beta1.Coin recv_fees = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; } // QueryTotalAckFeesRequest defines the request type for the TotalAckFees rpc @@ -141,11 +142,8 @@ message QueryTotalAckFeesRequest { // QueryTotalAckFeesResponse defines the response type for the TotalAckFees rpc message QueryTotalAckFeesResponse { // the total packet acknowledgement fees - repeated cosmos.base.v1beta1.Coin ack_fees = 1 [ - (gogoproto.moretags) = "yaml:\"ack_fees\"", - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" - ]; + repeated cosmos.base.v1beta1.Coin ack_fees = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; } // QueryTotalTimeoutFeesRequest defines the request type for the TotalTimeoutFees rpc @@ -157,17 +155,14 @@ message QueryTotalTimeoutFeesRequest { // QueryTotalTimeoutFeesResponse defines the response type for the TotalTimeoutFees rpc message QueryTotalTimeoutFeesResponse { // the total packet timeout fees - repeated cosmos.base.v1beta1.Coin timeout_fees = 1 [ - (gogoproto.moretags) = "yaml:\"timeout_fees\"", - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" - ]; + repeated cosmos.base.v1beta1.Coin timeout_fees = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; } // QueryPayeeRequest defines the request type for the Payee rpc message QueryPayeeRequest { // unique channel identifier - string channel_id = 1 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + string channel_id = 1; // the relayer address to which the distribution address is registered string relayer = 2; } @@ -175,13 +170,13 @@ message QueryPayeeRequest { // QueryPayeeResponse defines the response type for the Payee rpc message QueryPayeeResponse { // the payee address to which packet fees are paid out - string payee_address = 1 [(gogoproto.moretags) = "yaml:\"payee_address\""]; + string payee_address = 1; } // QueryCounterpartyPayeeRequest defines the request type for the CounterpartyPayee rpc message QueryCounterpartyPayeeRequest { // unique channel identifier - string channel_id = 1 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + string channel_id = 1; // the relayer address to which the counterparty is registered string relayer = 2; } @@ -189,7 +184,7 @@ message QueryCounterpartyPayeeRequest { // QueryCounterpartyPayeeResponse defines the response type for the CounterpartyPayee rpc message QueryCounterpartyPayeeResponse { // the counterparty payee address used to compensate forward relaying - string counterparty_payee = 1 [(gogoproto.moretags) = "yaml:\"counterparty_payee\""]; + string counterparty_payee = 1; } // QueryFeeEnabledChannelsRequest defines the request type for the FeeEnabledChannels rpc @@ -203,20 +198,21 @@ message QueryFeeEnabledChannelsRequest { // QueryFeeEnabledChannelsResponse defines the response type for the FeeEnabledChannels rpc message QueryFeeEnabledChannelsResponse { // list of fee enabled channels - repeated ibc.applications.fee.v1.FeeEnabledChannel fee_enabled_channels = 1 - [(gogoproto.moretags) = "yaml:\"fee_enabled_channels\"", (gogoproto.nullable) = false]; + repeated ibc.applications.fee.v1.FeeEnabledChannel fee_enabled_channels = 1 [(gogoproto.nullable) = false]; + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; } // QueryFeeEnabledChannelRequest defines the request type for the FeeEnabledChannel rpc message QueryFeeEnabledChannelRequest { // unique port identifier - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + string port_id = 1; // unique channel identifier - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + string channel_id = 2; } // QueryFeeEnabledChannelResponse defines the response type for the FeeEnabledChannel rpc message QueryFeeEnabledChannelResponse { // boolean flag representing the fee enabled channel status - bool fee_enabled = 1 [(gogoproto.moretags) = "yaml:\"fee_enabled\""]; + bool fee_enabled = 1; } diff --git a/third_party/proto/ibc/applications/fee/v1/tx.proto b/third_party/proto/ibc/applications/fee/v1/tx.proto index 63e591617..e59dddfd1 100644 --- a/third_party/proto/ibc/applications/fee/v1/tx.proto +++ b/third_party/proto/ibc/applications/fee/v1/tx.proto @@ -4,12 +4,16 @@ package ibc.applications.fee.v1; option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"; +import "amino/amino.proto"; import "gogoproto/gogo.proto"; import "ibc/applications/fee/v1/fee.proto"; import "ibc/core/channel/v1/channel.proto"; +import "cosmos/msg/v1/msg.proto"; // Msg defines the ICS29 Msg service. service Msg { + option (cosmos.msg.v1.service) = true; + // RegisterPayee defines a rpc handler method for MsgRegisterPayee // RegisterPayee is called by the relayer on each channelEnd and allows them to set an optional // payee to which reverse and timeout relayer packet fees will be paid out. The payee should be registered on @@ -39,13 +43,15 @@ service Msg { // MsgRegisterPayee defines the request type for the RegisterPayee rpc message MsgRegisterPayee { - option (gogoproto.equal) = false; + option (amino.name) = "cosmos-sdk/MsgRegisterPayee"; + option (cosmos.msg.v1.signer) = "relayer"; + option (gogoproto.goproto_getters) = false; // unique port identifier - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + string port_id = 1; // unique channel identifier - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + string channel_id = 2; // the relayer address string relayer = 3; // the payee address @@ -57,17 +63,19 @@ message MsgRegisterPayeeResponse {} // MsgRegisterCounterpartyPayee defines the request type for the RegisterCounterpartyPayee rpc message MsgRegisterCounterpartyPayee { - option (gogoproto.equal) = false; + option (amino.name) = "cosmos-sdk/MsgRegisterCounterpartyPayee"; + option (cosmos.msg.v1.signer) = "relayer"; + option (gogoproto.goproto_getters) = false; // unique port identifier - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + string port_id = 1; // unique channel identifier - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + string channel_id = 2; // the relayer address string relayer = 3; // the counterparty payee address - string counterparty_payee = 4 [(gogoproto.moretags) = "yaml:\"counterparty_payee\""]; + string counterparty_payee = 4; } // MsgRegisterCounterpartyPayeeResponse defines the response type for the RegisterCounterpartyPayee rpc @@ -77,15 +85,17 @@ message MsgRegisterCounterpartyPayeeResponse {} // This Msg can be used to pay for a packet at the next sequence send & should be combined with the Msg that will be // paid for message MsgPayPacketFee { - option (gogoproto.equal) = false; + option (amino.name) = "cosmos-sdk/MsgPayPacketFee"; + option (cosmos.msg.v1.signer) = "signer"; + option (gogoproto.goproto_getters) = false; // fee encapsulates the recv, ack and timeout fees associated with an IBC packet - ibc.applications.fee.v1.Fee fee = 1 [(gogoproto.nullable) = false]; + ibc.applications.fee.v1.Fee fee = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; // the source port unique identifier - string source_port_id = 2 [(gogoproto.moretags) = "yaml:\"source_port_id\""]; + string source_port_id = 2; // the source channel unique identifer - string source_channel_id = 3 [(gogoproto.moretags) = "yaml:\"source_channel_id\""]; + string source_channel_id = 3; // account address to refund fee if necessary string signer = 4; // optional list of relayers permitted to the receive packet fees @@ -98,14 +108,14 @@ message MsgPayPacketFeeResponse {} // MsgPayPacketFeeAsync defines the request type for the PayPacketFeeAsync rpc // This Msg can be used to pay for a packet at a specified sequence (instead of the next sequence send) message MsgPayPacketFeeAsync { - option (gogoproto.equal) = false; + option (amino.name) = "cosmos-sdk/MsgPayPacketFeeAsync"; + option (cosmos.msg.v1.signer) = "packet_fee"; option (gogoproto.goproto_getters) = false; // unique packet identifier comprised of the channel ID, port ID and sequence - ibc.core.channel.v1.PacketId packet_id = 1 - [(gogoproto.moretags) = "yaml:\"packet_id\"", (gogoproto.nullable) = false]; + ibc.core.channel.v1.PacketId packet_id = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; // the packet fee associated with a particular IBC packet - PacketFee packet_fee = 2 [(gogoproto.moretags) = "yaml:\"packet_fee\"", (gogoproto.nullable) = false]; + PacketFee packet_fee = 2 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; } // MsgPayPacketFeeAsyncResponse defines the response type for the PayPacketFeeAsync rpc diff --git a/third_party/proto/ibc/applications/interchain_accounts/controller/v1/controller.proto b/third_party/proto/ibc/applications/interchain_accounts/controller/v1/controller.proto index 0974b9d9b..2e6bbe1a1 100644 --- a/third_party/proto/ibc/applications/interchain_accounts/controller/v1/controller.proto +++ b/third_party/proto/ibc/applications/interchain_accounts/controller/v1/controller.proto @@ -4,11 +4,9 @@ package ibc.applications.interchain_accounts.controller.v1; option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types"; -import "gogoproto/gogo.proto"; - // Params defines the set of on-chain interchain accounts parameters. // The following parameters may be used to disable the controller submodule. message Params { // controller_enabled enables or disables the controller submodule. - bool controller_enabled = 1 [(gogoproto.moretags) = "yaml:\"controller_enabled\""]; + bool controller_enabled = 1; } diff --git a/third_party/proto/ibc/applications/interchain_accounts/controller/v1/query.proto b/third_party/proto/ibc/applications/interchain_accounts/controller/v1/query.proto index 3779ed387..31885fcb2 100644 --- a/third_party/proto/ibc/applications/interchain_accounts/controller/v1/query.proto +++ b/third_party/proto/ibc/applications/interchain_accounts/controller/v1/query.proto @@ -5,7 +5,6 @@ package ibc.applications.interchain_accounts.controller.v1; option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types"; import "ibc/applications/interchain_accounts/controller/v1/controller.proto"; -import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; // Query provides defines the gRPC querier service. @@ -25,7 +24,7 @@ service Query { // QueryInterchainAccountRequest is the request type for the Query/InterchainAccount RPC method. message QueryInterchainAccountRequest { string owner = 1; - string connection_id = 2 [(gogoproto.moretags) = "yaml:\"connection_id\""]; + string connection_id = 2; } // QueryInterchainAccountResponse the response type for the Query/InterchainAccount RPC method. diff --git a/third_party/proto/ibc/applications/interchain_accounts/controller/v1/tx.proto b/third_party/proto/ibc/applications/interchain_accounts/controller/v1/tx.proto index 11fb3cfdc..ec5c2e62e 100644 --- a/third_party/proto/ibc/applications/interchain_accounts/controller/v1/tx.proto +++ b/third_party/proto/ibc/applications/interchain_accounts/controller/v1/tx.proto @@ -6,46 +6,77 @@ option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-acco import "gogoproto/gogo.proto"; import "ibc/applications/interchain_accounts/v1/packet.proto"; +import "ibc/applications/interchain_accounts/controller/v1/controller.proto"; +import "cosmos/msg/v1/msg.proto"; +import "ibc/core/channel/v1/channel.proto"; // Msg defines the 27-interchain-accounts/controller Msg service. service Msg { + option (cosmos.msg.v1.service) = true; + // RegisterInterchainAccount defines a rpc handler for MsgRegisterInterchainAccount. rpc RegisterInterchainAccount(MsgRegisterInterchainAccount) returns (MsgRegisterInterchainAccountResponse); // SendTx defines a rpc handler for MsgSendTx. rpc SendTx(MsgSendTx) returns (MsgSendTxResponse); + // UpdateParams defines a rpc handler for MsgUpdateParams. + rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); } // MsgRegisterInterchainAccount defines the payload for Msg/RegisterAccount message MsgRegisterInterchainAccount { - option (gogoproto.equal) = false; + option (cosmos.msg.v1.signer) = "owner"; + option (gogoproto.goproto_getters) = false; - string owner = 1; - string connection_id = 2 [(gogoproto.moretags) = "yaml:\"connection_id\""]; - string version = 3; + string owner = 1; + string connection_id = 2; + string version = 3; + ibc.core.channel.v1.Order ordering = 4; } // MsgRegisterInterchainAccountResponse defines the response for Msg/RegisterAccount message MsgRegisterInterchainAccountResponse { - string channel_id = 1 [(gogoproto.moretags) = "yaml:\"channel_id\""]; - string port_id = 2 [(gogoproto.moretags) = "yaml:\"port_id\""]; + option (gogoproto.goproto_getters) = false; + + string channel_id = 1; + string port_id = 2; } // MsgSendTx defines the payload for Msg/SendTx message MsgSendTx { - option (gogoproto.equal) = false; + option (cosmos.msg.v1.signer) = "owner"; + option (gogoproto.goproto_getters) = false; - string owner = 1; - string connection_id = 2 [(gogoproto.moretags) = "yaml:\"connection_id\""]; - ibc.applications.interchain_accounts.v1.InterchainAccountPacketData packet_data = 3 - [(gogoproto.moretags) = "yaml:\"packet_data\"", (gogoproto.nullable) = false]; + string owner = 1; + string connection_id = 2; + ibc.applications.interchain_accounts.v1.InterchainAccountPacketData packet_data = 3 [(gogoproto.nullable) = false]; // Relative timeout timestamp provided will be added to the current block time during transaction execution. // The timeout timestamp must be non-zero. - uint64 relative_timeout = 4 [(gogoproto.moretags) = "yaml:\"relative_timeout\""]; + uint64 relative_timeout = 4; } // MsgSendTxResponse defines the response for MsgSendTx message MsgSendTxResponse { + option (gogoproto.goproto_getters) = false; + uint64 sequence = 1; } + +// MsgUpdateParams defines the payload for Msg/UpdateParams +message MsgUpdateParams { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + // signer address + string signer = 1; + + // params defines the 27-interchain-accounts/controller parameters to update. + // + // NOTE: All parameters must be supplied. + Params params = 2 [(gogoproto.nullable) = false]; +} + +// MsgUpdateParamsResponse defines the response for Msg/UpdateParams +message MsgUpdateParamsResponse {} \ No newline at end of file diff --git a/third_party/proto/ibc/applications/interchain_accounts/genesis/v1/genesis.proto b/third_party/proto/ibc/applications/interchain_accounts/genesis/v1/genesis.proto index f0fd73ede..4393e5b0b 100644 --- a/third_party/proto/ibc/applications/interchain_accounts/genesis/v1/genesis.proto +++ b/third_party/proto/ibc/applications/interchain_accounts/genesis/v1/genesis.proto @@ -10,44 +10,38 @@ import "ibc/applications/interchain_accounts/host/v1/host.proto"; // GenesisState defines the interchain accounts genesis state message GenesisState { - ControllerGenesisState controller_genesis_state = 1 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"controller_genesis_state\""]; - HostGenesisState host_genesis_state = 2 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"host_genesis_state\""]; + ControllerGenesisState controller_genesis_state = 1 [(gogoproto.nullable) = false]; + HostGenesisState host_genesis_state = 2 [(gogoproto.nullable) = false]; } // ControllerGenesisState defines the interchain accounts controller genesis state message ControllerGenesisState { - repeated ActiveChannel active_channels = 1 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"active_channels\""]; - repeated RegisteredInterchainAccount interchain_accounts = 2 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"interchain_accounts\""]; - repeated string ports = 3; - ibc.applications.interchain_accounts.controller.v1.Params params = 4 [(gogoproto.nullable) = false]; + repeated ActiveChannel active_channels = 1 [(gogoproto.nullable) = false]; + repeated RegisteredInterchainAccount interchain_accounts = 2 [(gogoproto.nullable) = false]; + repeated string ports = 3; + ibc.applications.interchain_accounts.controller.v1.Params params = 4 [(gogoproto.nullable) = false]; } // HostGenesisState defines the interchain accounts host genesis state message HostGenesisState { - repeated ActiveChannel active_channels = 1 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"active_channels\""]; - repeated RegisteredInterchainAccount interchain_accounts = 2 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"interchain_accounts\""]; - string port = 3; - ibc.applications.interchain_accounts.host.v1.Params params = 4 [(gogoproto.nullable) = false]; + repeated ActiveChannel active_channels = 1 [(gogoproto.nullable) = false]; + repeated RegisteredInterchainAccount interchain_accounts = 2 [(gogoproto.nullable) = false]; + string port = 3; + ibc.applications.interchain_accounts.host.v1.Params params = 4 [(gogoproto.nullable) = false]; } // ActiveChannel contains a connection ID, port ID and associated active channel ID, as well as a boolean flag to // indicate if the channel is middleware enabled message ActiveChannel { - string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; - string port_id = 2 [(gogoproto.moretags) = "yaml:\"port_id\""]; - string channel_id = 3 [(gogoproto.moretags) = "yaml:\"channel_id\""]; - bool is_middleware_enabled = 4 [(gogoproto.moretags) = "yaml:\"is_middleware_enabled\""]; + string connection_id = 1; + string port_id = 2; + string channel_id = 3; + bool is_middleware_enabled = 4; } // RegisteredInterchainAccount contains a connection ID, port ID and associated interchain account address message RegisteredInterchainAccount { - string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; - string port_id = 2 [(gogoproto.moretags) = "yaml:\"port_id\""]; - string account_address = 3 [(gogoproto.moretags) = "yaml:\"account_address\""]; + string connection_id = 1; + string port_id = 2; + string account_address = 3; } \ No newline at end of file diff --git a/third_party/proto/ibc/applications/interchain_accounts/host/v1/host.proto b/third_party/proto/ibc/applications/interchain_accounts/host/v1/host.proto index 2247e2fe0..f03685711 100644 --- a/third_party/proto/ibc/applications/interchain_accounts/host/v1/host.proto +++ b/third_party/proto/ibc/applications/interchain_accounts/host/v1/host.proto @@ -4,13 +4,11 @@ package ibc.applications.interchain_accounts.host.v1; option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/host/types"; -import "gogoproto/gogo.proto"; - // Params defines the set of on-chain interchain accounts parameters. // The following parameters may be used to disable the host submodule. message Params { // host_enabled enables or disables the host submodule. - bool host_enabled = 1 [(gogoproto.moretags) = "yaml:\"host_enabled\""]; + bool host_enabled = 1; // allow_messages defines a list of sdk message typeURLs allowed to be executed on a host chain. - repeated string allow_messages = 2 [(gogoproto.moretags) = "yaml:\"allow_messages\""]; + repeated string allow_messages = 2; } diff --git a/third_party/proto/ibc/applications/interchain_accounts/host/v1/tx.proto b/third_party/proto/ibc/applications/interchain_accounts/host/v1/tx.proto new file mode 100644 index 000000000..5a8073bc9 --- /dev/null +++ b/third_party/proto/ibc/applications/interchain_accounts/host/v1/tx.proto @@ -0,0 +1,35 @@ +syntax = "proto3"; + +package ibc.applications.interchain_accounts.host.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/host/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/msg/v1/msg.proto"; +import "ibc/applications/interchain_accounts/host/v1/host.proto"; + +// Msg defines the 27-interchain-accounts/host Msg service. +service Msg { + option (cosmos.msg.v1.service) = true; + + // UpdateParams defines a rpc handler for MsgUpdateParams. + rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); +} + +// MsgUpdateParams defines the payload for Msg/UpdateParams +message MsgUpdateParams { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + // signer address + string signer = 1; + + // params defines the 27-interchain-accounts/host parameters to update. + // + // NOTE: All parameters must be supplied. + Params params = 2 [(gogoproto.nullable) = false]; +} + +// MsgUpdateParamsResponse defines the response for Msg/UpdateParams +message MsgUpdateParamsResponse {} diff --git a/third_party/proto/ibc/applications/interchain_accounts/v1/account.proto b/third_party/proto/ibc/applications/interchain_accounts/v1/account.proto index 85d4e5828..4a6947c1c 100644 --- a/third_party/proto/ibc/applications/interchain_accounts/v1/account.proto +++ b/third_party/proto/ibc/applications/interchain_accounts/v1/account.proto @@ -14,7 +14,6 @@ message InterchainAccount { option (gogoproto.goproto_stringer) = false; option (cosmos_proto.implements_interface) = "ibc.applications.interchain_accounts.v1.InterchainAccountI"; - cosmos.auth.v1beta1.BaseAccount base_account = 1 - [(gogoproto.embed) = true, (gogoproto.moretags) = "yaml:\"base_account\""]; - string account_owner = 2 [(gogoproto.moretags) = "yaml:\"account_owner\""]; + cosmos.auth.v1beta1.BaseAccount base_account = 1 [(gogoproto.embed) = true]; + string account_owner = 2; } diff --git a/third_party/proto/ibc/applications/interchain_accounts/v1/metadata.proto b/third_party/proto/ibc/applications/interchain_accounts/v1/metadata.proto index 5984ba4d6..df72b41eb 100644 --- a/third_party/proto/ibc/applications/interchain_accounts/v1/metadata.proto +++ b/third_party/proto/ibc/applications/interchain_accounts/v1/metadata.proto @@ -4,17 +4,15 @@ package ibc.applications.interchain_accounts.v1; option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types"; -import "gogoproto/gogo.proto"; - // Metadata defines a set of protocol specific data encoded into the ICS27 channel version bytestring // See ICS004: https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#Versioning message Metadata { // version defines the ICS27 protocol version string version = 1; // controller_connection_id is the connection identifier associated with the controller chain - string controller_connection_id = 2 [(gogoproto.moretags) = "yaml:\"controller_connection_id\""]; + string controller_connection_id = 2; // host_connection_id is the connection identifier associated with the host chain - string host_connection_id = 3 [(gogoproto.moretags) = "yaml:\"host_connection_id\""]; + string host_connection_id = 3; // address defines the interchain account address to be fulfilled upon the OnChanOpenTry handshake step // NOTE: the address field is empty on the OnChanOpenInit handshake step string address = 4; diff --git a/third_party/proto/ibc/applications/transfer/v1/authz.proto b/third_party/proto/ibc/applications/transfer/v1/authz.proto index df1ee24ed..e7561b070 100644 --- a/third_party/proto/ibc/applications/transfer/v1/authz.proto +++ b/third_party/proto/ibc/applications/transfer/v1/authz.proto @@ -11,14 +11,17 @@ import "cosmos/base/v1beta1/coin.proto"; // Allocation defines the spend limit for a particular port and channel message Allocation { // the port on which the packet will be sent - string source_port = 1 [(gogoproto.moretags) = "yaml:\"source_port\""]; + string source_port = 1; // the channel by which the packet will be sent - string source_channel = 2 [(gogoproto.moretags) = "yaml:\"source_channel\""]; + string source_channel = 2; // spend limitation on the channel repeated cosmos.base.v1beta1.Coin spend_limit = 3 [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; // allow list of receivers, an empty allow list permits any receiver address repeated string allow_list = 4; + // allow list of packet data keys, an empty list prohibits all packet data keys; + // a list only with "*" permits any packet data key + repeated string allowed_packet_data = 5; } // TransferAuthorization allows the grantee to spend up to spend_limit coins from diff --git a/third_party/proto/ibc/applications/transfer/v1/genesis.proto b/third_party/proto/ibc/applications/transfer/v1/genesis.proto index 578c2242e..f7d707f6c 100644 --- a/third_party/proto/ibc/applications/transfer/v1/genesis.proto +++ b/third_party/proto/ibc/applications/transfer/v1/genesis.proto @@ -10,18 +10,11 @@ import "gogoproto/gogo.proto"; // GenesisState defines the ibc-transfer genesis state message GenesisState { - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; - repeated DenomTrace denom_traces = 2 [ - (gogoproto.castrepeated) = "Traces", - (gogoproto.nullable) = false, - (gogoproto.moretags) = "yaml:\"denom_traces\"" - ]; - Params params = 3 [(gogoproto.nullable) = false]; + string port_id = 1; + repeated DenomTrace denom_traces = 2 [(gogoproto.castrepeated) = "Traces", (gogoproto.nullable) = false]; + Params params = 3 [(gogoproto.nullable) = false]; // total_escrowed contains the total amount of tokens escrowed // by the transfer module - repeated cosmos.base.v1beta1.Coin total_escrowed = 4 [ - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (gogoproto.nullable) = false, - (gogoproto.moretags) = "yaml:\"total_escrowed\"" - ]; + repeated cosmos.base.v1beta1.Coin total_escrowed = 4 + [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false]; } diff --git a/third_party/proto/ibc/applications/transfer/v1/transfer.proto b/third_party/proto/ibc/applications/transfer/v1/transfer.proto index 0c13a48ce..7f7723762 100644 --- a/third_party/proto/ibc/applications/transfer/v1/transfer.proto +++ b/third_party/proto/ibc/applications/transfer/v1/transfer.proto @@ -4,8 +4,6 @@ package ibc.applications.transfer.v1; option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"; -import "gogoproto/gogo.proto"; - // DenomTrace contains the base denomination for ICS20 fungible tokens and the // source tracing information path. message DenomTrace { @@ -23,8 +21,8 @@ message DenomTrace { message Params { // send_enabled enables or disables all cross-chain token transfers from this // chain. - bool send_enabled = 1 [(gogoproto.moretags) = "yaml:\"send_enabled\""]; + bool send_enabled = 1; // receive_enabled enables or disables all cross-chain token transfers to this // chain. - bool receive_enabled = 2 [(gogoproto.moretags) = "yaml:\"receive_enabled\""]; + bool receive_enabled = 2; } diff --git a/third_party/proto/ibc/applications/transfer/v1/tx.proto b/third_party/proto/ibc/applications/transfer/v1/tx.proto index 02466eab7..42c70d3be 100644 --- a/third_party/proto/ibc/applications/transfer/v1/tx.proto +++ b/third_party/proto/ibc/applications/transfer/v1/tx.proto @@ -4,46 +4,76 @@ package ibc.applications.transfer.v1; option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"; +import "amino/amino.proto"; import "gogoproto/gogo.proto"; +import "cosmos/msg/v1/msg.proto"; import "cosmos/base/v1beta1/coin.proto"; import "ibc/core/client/v1/client.proto"; +import "ibc/applications/transfer/v1/transfer.proto"; // Msg defines the ibc/transfer Msg service. service Msg { + option (cosmos.msg.v1.service) = true; + // Transfer defines a rpc handler method for MsgTransfer. rpc Transfer(MsgTransfer) returns (MsgTransferResponse); + + // UpdateParams defines a rpc handler for MsgUpdateParams. + rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); } // MsgTransfer defines a msg to transfer fungible tokens (i.e Coins) between // ICS20 enabled chains. See ICS Spec here: // https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structures message MsgTransfer { - option (gogoproto.equal) = false; + option (amino.name) = "cosmos-sdk/MsgTransfer"; + option (cosmos.msg.v1.signer) = "sender"; + option (gogoproto.goproto_getters) = false; // the port on which the packet will be sent - string source_port = 1 [(gogoproto.moretags) = "yaml:\"source_port\""]; + string source_port = 1; // the channel by which the packet will be sent - string source_channel = 2 [(gogoproto.moretags) = "yaml:\"source_channel\""]; + string source_channel = 2; // the tokens to be transferred - cosmos.base.v1beta1.Coin token = 3 [(gogoproto.nullable) = false]; + cosmos.base.v1beta1.Coin token = 3 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; // the sender address string sender = 4; // the recipient address on the destination chain string receiver = 5; // Timeout height relative to the current block height. // The timeout is disabled when set to 0. - ibc.core.client.v1.Height timeout_height = 6 - [(gogoproto.moretags) = "yaml:\"timeout_height\"", (gogoproto.nullable) = false]; + ibc.core.client.v1.Height timeout_height = 6 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; // Timeout timestamp in absolute nanoseconds since unix epoch. // The timeout is disabled when set to 0. - uint64 timeout_timestamp = 7 [(gogoproto.moretags) = "yaml:\"timeout_timestamp\""]; + uint64 timeout_timestamp = 7; // optional memo string memo = 8; } // MsgTransferResponse defines the Msg/Transfer response type. message MsgTransferResponse { + option (gogoproto.goproto_getters) = false; + // sequence number of the transfer packet sent uint64 sequence = 1; } + +// MsgUpdateParams is the Msg/UpdateParams request type. +message MsgUpdateParams { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + // signer address + string signer = 1; + + // params defines the transfer parameters to update. + // + // NOTE: All parameters must be supplied. + Params params = 2 [(gogoproto.nullable) = false]; +} + +// MsgUpdateParamsResponse defines the response structure for executing a +// MsgUpdateParams message. +message MsgUpdateParamsResponse {} \ No newline at end of file diff --git a/third_party/proto/ibc/channel/v1/channel.proto b/third_party/proto/ibc/channel/v1/channel.proto new file mode 100644 index 000000000..05a18fefb --- /dev/null +++ b/third_party/proto/ibc/channel/v1/channel.proto @@ -0,0 +1,187 @@ +syntax = "proto3"; + +package ibc.core.channel.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"; + +import "gogoproto/gogo.proto"; +import "ibc/core/client/v1/client.proto"; + +// Channel defines pipeline for exactly-once packet delivery between specific +// modules on separate blockchains, which has at least one end capable of +// sending packets and one end capable of receiving packets. +message Channel { + option (gogoproto.goproto_getters) = false; + + // current state of the channel end + State state = 1; + // whether the channel is ordered or unordered + Order ordering = 2; + // counterparty channel end + Counterparty counterparty = 3 [(gogoproto.nullable) = false]; + // list of connection identifiers, in order, along which packets sent on + // this channel will travel + repeated string connection_hops = 4; + // opaque channel version, which is agreed upon during the handshake + string version = 5; + // upgrade sequence indicates the latest upgrade attempt performed by this channel + // the value of 0 indicates the channel has never been upgraded + uint64 upgrade_sequence = 6; +} + +// IdentifiedChannel defines a channel with additional port and channel +// identifier fields. +message IdentifiedChannel { + option (gogoproto.goproto_getters) = false; + + // current state of the channel end + State state = 1; + // whether the channel is ordered or unordered + Order ordering = 2; + // counterparty channel end + Counterparty counterparty = 3 [(gogoproto.nullable) = false]; + // list of connection identifiers, in order, along which packets sent on + // this channel will travel + repeated string connection_hops = 4; + // opaque channel version, which is agreed upon during the handshake + string version = 5; + // port identifier + string port_id = 6; + // channel identifier + string channel_id = 7; + // upgrade sequence indicates the latest upgrade attempt performed by this channel + // the value of 0 indicates the channel has never been upgraded + uint64 upgrade_sequence = 8; +} + +// State defines if a channel is in one of the following states: +// CLOSED, INIT, TRYOPEN, OPEN, FLUSHING, FLUSHCOMPLETE or UNINITIALIZED. +enum State { + option (gogoproto.goproto_enum_prefix) = false; + + // Default State + STATE_UNINITIALIZED_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNINITIALIZED"]; + // A channel has just started the opening handshake. + STATE_INIT = 1 [(gogoproto.enumvalue_customname) = "INIT"]; + // A channel has acknowledged the handshake step on the counterparty chain. + STATE_TRYOPEN = 2 [(gogoproto.enumvalue_customname) = "TRYOPEN"]; + // A channel has completed the handshake. Open channels are + // ready to send and receive packets. + STATE_OPEN = 3 [(gogoproto.enumvalue_customname) = "OPEN"]; + // A channel has been closed and can no longer be used to send or receive + // packets. + STATE_CLOSED = 4 [(gogoproto.enumvalue_customname) = "CLOSED"]; + // A channel has just accepted the upgrade handshake attempt and is flushing in-flight packets. + STATE_FLUSHING = 5 [(gogoproto.enumvalue_customname) = "FLUSHING"]; + // A channel has just completed flushing any in-flight packets. + STATE_FLUSHCOMPLETE = 6 [(gogoproto.enumvalue_customname) = "FLUSHCOMPLETE"]; +} + +// Order defines if a channel is ORDERED or UNORDERED +enum Order { + option (gogoproto.goproto_enum_prefix) = false; + + // zero-value for channel ordering + ORDER_NONE_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "NONE"]; + // packets can be delivered in any order, which may differ from the order in + // which they were sent. + ORDER_UNORDERED = 1 [(gogoproto.enumvalue_customname) = "UNORDERED"]; + // packets are delivered exactly in the order which they were sent + ORDER_ORDERED = 2 [(gogoproto.enumvalue_customname) = "ORDERED"]; +} + +// Counterparty defines a channel end counterparty +message Counterparty { + option (gogoproto.goproto_getters) = false; + + // port on the counterparty chain which owns the other end of the channel. + string port_id = 1; + // channel end on the counterparty chain + string channel_id = 2; +} + +// Packet defines a type that carries data across different chains through IBC +message Packet { + option (gogoproto.goproto_getters) = false; + + // number corresponds to the order of sends and receives, where a Packet + // with an earlier sequence number must be sent and received before a Packet + // with a later sequence number. + uint64 sequence = 1; + // identifies the port on the sending chain. + string source_port = 2; + // identifies the channel end on the sending chain. + string source_channel = 3; + // identifies the port on the receiving chain. + string destination_port = 4; + // identifies the channel end on the receiving chain. + string destination_channel = 5; + // actual opaque bytes transferred directly to the application module + bytes data = 6; + // block height after which the packet times out + ibc.core.client.v1.Height timeout_height = 7 [(gogoproto.nullable) = false]; + // block timestamp (in nanoseconds) after which the packet times out + uint64 timeout_timestamp = 8; +} + +// PacketState defines the generic type necessary to retrieve and store +// packet commitments, acknowledgements, and receipts. +// Caller is responsible for knowing the context necessary to interpret this +// state as a commitment, acknowledgement, or a receipt. +message PacketState { + option (gogoproto.goproto_getters) = false; + + // channel port identifier. + string port_id = 1; + // channel unique identifier. + string channel_id = 2; + // packet sequence. + uint64 sequence = 3; + // embedded data that represents packet state. + bytes data = 4; +} + +// PacketId is an identifer for a unique Packet +// Source chains refer to packets by source port/channel +// Destination chains refer to packets by destination port/channel +message PacketId { + option (gogoproto.goproto_getters) = false; + + // channel port identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // packet sequence + uint64 sequence = 3; +} + +// Acknowledgement is the recommended acknowledgement format to be used by +// app-specific protocols. +// NOTE: The field numbers 21 and 22 were explicitly chosen to avoid accidental +// conflicts with other protobuf message formats used for acknowledgements. +// The first byte of any message with this format will be the non-ASCII values +// `0xaa` (result) or `0xb2` (error). Implemented as defined by ICS: +// https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#acknowledgement-envelope +message Acknowledgement { + // response contains either a result or an error and must be non-empty + oneof response { + bytes result = 21; + string error = 22; + } +} + +// Timeout defines an execution deadline structure for 04-channel handlers. +// This includes packet lifecycle handlers as well as the upgrade handshake handlers. +// A valid Timeout contains either one or both of a timestamp and block height (sequence). +message Timeout { + // block height after which the packet or upgrade times out + ibc.core.client.v1.Height height = 1 [(gogoproto.nullable) = false]; + // block timestamp (in nanoseconds) after which the packet or upgrade times out + uint64 timestamp = 2; +} + +// Params defines the set of IBC channel parameters. +message Params { + // the relative timeout after which channel upgrades will time out. + Timeout upgrade_timeout = 1 [(gogoproto.nullable) = false]; +} diff --git a/third_party/proto/ibc/channel/v1/genesis.proto b/third_party/proto/ibc/channel/v1/genesis.proto new file mode 100644 index 000000000..665b2b156 --- /dev/null +++ b/third_party/proto/ibc/channel/v1/genesis.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; + +package ibc.core.channel.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"; + +import "gogoproto/gogo.proto"; +import "ibc/core/channel/v1/channel.proto"; + +// GenesisState defines the ibc channel submodule's genesis state. +message GenesisState { + repeated IdentifiedChannel channels = 1 [(gogoproto.casttype) = "IdentifiedChannel", (gogoproto.nullable) = false]; + repeated PacketState acknowledgements = 2 [(gogoproto.nullable) = false]; + repeated PacketState commitments = 3 [(gogoproto.nullable) = false]; + repeated PacketState receipts = 4 [(gogoproto.nullable) = false]; + repeated PacketSequence send_sequences = 5 [(gogoproto.nullable) = false]; + repeated PacketSequence recv_sequences = 6 [(gogoproto.nullable) = false]; + repeated PacketSequence ack_sequences = 7 [(gogoproto.nullable) = false]; + // the sequence for the next generated channel identifier + uint64 next_channel_sequence = 8; + Params params = 9 [(gogoproto.nullable) = false]; +} + +// PacketSequence defines the genesis type necessary to retrieve and store +// next send and receive sequences. +message PacketSequence { + string port_id = 1; + string channel_id = 2; + uint64 sequence = 3; +} diff --git a/third_party/proto/ibc/channel/v1/query.proto b/third_party/proto/ibc/channel/v1/query.proto new file mode 100644 index 000000000..f89d21273 --- /dev/null +++ b/third_party/proto/ibc/channel/v1/query.proto @@ -0,0 +1,459 @@ +syntax = "proto3"; + +package ibc.core.channel.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"; + +import "ibc/core/client/v1/client.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "ibc/core/channel/v1/channel.proto"; +import "google/api/annotations.proto"; +import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; +import "ibc/core/channel/v1/upgrade.proto"; + +// Query provides defines the gRPC querier service +service Query { + // Channel queries an IBC Channel. + rpc Channel(QueryChannelRequest) returns (QueryChannelResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}"; + } + + // Channels queries all the IBC channels of a chain. + rpc Channels(QueryChannelsRequest) returns (QueryChannelsResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels"; + } + + // ConnectionChannels queries all the channels associated with a connection + // end. + rpc ConnectionChannels(QueryConnectionChannelsRequest) returns (QueryConnectionChannelsResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/connections/{connection}/channels"; + } + + // ChannelClientState queries for the client state for the channel associated + // with the provided channel identifiers. + rpc ChannelClientState(QueryChannelClientStateRequest) returns (QueryChannelClientStateResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/client_state"; + } + + // ChannelConsensusState queries for the consensus state for the channel + // associated with the provided channel identifiers. + rpc ChannelConsensusState(QueryChannelConsensusStateRequest) returns (QueryChannelConsensusStateResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/consensus_state/revision/" + "{revision_number}/height/{revision_height}"; + } + + // PacketCommitment queries a stored packet commitment hash. + rpc PacketCommitment(QueryPacketCommitmentRequest) returns (QueryPacketCommitmentResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/" + "packet_commitments/{sequence}"; + } + + // PacketCommitments returns all the packet commitments hashes associated + // with a channel. + rpc PacketCommitments(QueryPacketCommitmentsRequest) returns (QueryPacketCommitmentsResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/packet_commitments"; + } + + // PacketReceipt queries if a given packet sequence has been received on the + // queried chain + rpc PacketReceipt(QueryPacketReceiptRequest) returns (QueryPacketReceiptResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/packet_receipts/{sequence}"; + } + + // PacketAcknowledgement queries a stored packet acknowledgement hash. + rpc PacketAcknowledgement(QueryPacketAcknowledgementRequest) returns (QueryPacketAcknowledgementResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/packet_acks/{sequence}"; + } + + // PacketAcknowledgements returns all the packet acknowledgements associated + // with a channel. + rpc PacketAcknowledgements(QueryPacketAcknowledgementsRequest) returns (QueryPacketAcknowledgementsResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/packet_acknowledgements"; + } + + // UnreceivedPackets returns all the unreceived IBC packets associated with a + // channel and sequences. + rpc UnreceivedPackets(QueryUnreceivedPacketsRequest) returns (QueryUnreceivedPacketsResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/" + "packet_commitments/" + "{packet_commitment_sequences}/unreceived_packets"; + } + + // UnreceivedAcks returns all the unreceived IBC acknowledgements associated + // with a channel and sequences. + rpc UnreceivedAcks(QueryUnreceivedAcksRequest) returns (QueryUnreceivedAcksResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/packet_commitments/" + "{packet_ack_sequences}/unreceived_acks"; + } + + // NextSequenceReceive returns the next receive sequence for a given channel. + rpc NextSequenceReceive(QueryNextSequenceReceiveRequest) returns (QueryNextSequenceReceiveResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/next_sequence"; + } + + // NextSequenceSend returns the next send sequence for a given channel. + rpc NextSequenceSend(QueryNextSequenceSendRequest) returns (QueryNextSequenceSendResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/next_sequence_send"; + } + + // UpgradeError returns the error receipt if the upgrade handshake failed. + rpc UpgradeError(QueryUpgradeErrorRequest) returns (QueryUpgradeErrorResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/upgrade_error"; + } + + // Upgrade returns the upgrade for a given port and channel id. + rpc Upgrade(QueryUpgradeRequest) returns (QueryUpgradeResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/upgrade"; + } + + // ChannelParams queries all parameters of the ibc channel submodule. + rpc ChannelParams(QueryChannelParamsRequest) returns (QueryChannelParamsResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/params"; + } +} + +// QueryChannelRequest is the request type for the Query/Channel RPC method +message QueryChannelRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; +} + +// QueryChannelResponse is the response type for the Query/Channel RPC method. +// Besides the Channel end, it includes a proof and the height from which the +// proof was retrieved. +message QueryChannelResponse { + // channel associated with the request identifiers + ibc.core.channel.v1.Channel channel = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryChannelsRequest is the request type for the Query/Channels RPC method +message QueryChannelsRequest { + // pagination request + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryChannelsResponse is the response type for the Query/Channels RPC method. +message QueryChannelsResponse { + // list of stored channels of the chain. + repeated ibc.core.channel.v1.IdentifiedChannel channels = 1; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; + // query block height + ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; +} + +// QueryConnectionChannelsRequest is the request type for the +// Query/QueryConnectionChannels RPC method +message QueryConnectionChannelsRequest { + // connection unique identifier + string connection = 1; + // pagination request + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryConnectionChannelsResponse is the Response type for the +// Query/QueryConnectionChannels RPC method +message QueryConnectionChannelsResponse { + // list of channels associated with a connection. + repeated ibc.core.channel.v1.IdentifiedChannel channels = 1; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; + // query block height + ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; +} + +// QueryChannelClientStateRequest is the request type for the Query/ClientState +// RPC method +message QueryChannelClientStateRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; +} + +// QueryChannelClientStateResponse is the Response type for the +// Query/QueryChannelClientState RPC method +message QueryChannelClientStateResponse { + // client state associated with the channel + ibc.core.client.v1.IdentifiedClientState identified_client_state = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryChannelConsensusStateRequest is the request type for the +// Query/ConsensusState RPC method +message QueryChannelConsensusStateRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // revision number of the consensus state + uint64 revision_number = 3; + // revision height of the consensus state + uint64 revision_height = 4; +} + +// QueryChannelClientStateResponse is the Response type for the +// Query/QueryChannelClientState RPC method +message QueryChannelConsensusStateResponse { + // consensus state associated with the channel + google.protobuf.Any consensus_state = 1; + // client ID associated with the consensus state + string client_id = 2; + // merkle proof of existence + bytes proof = 3; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; +} + +// QueryPacketCommitmentRequest is the request type for the +// Query/PacketCommitment RPC method +message QueryPacketCommitmentRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // packet sequence + uint64 sequence = 3; +} + +// QueryPacketCommitmentResponse defines the client query response for a packet +// which also includes a proof and the height from which the proof was +// retrieved +message QueryPacketCommitmentResponse { + // packet associated with the request fields + bytes commitment = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryPacketCommitmentsRequest is the request type for the +// Query/QueryPacketCommitments RPC method +message QueryPacketCommitmentsRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // pagination request + cosmos.base.query.v1beta1.PageRequest pagination = 3; +} + +// QueryPacketCommitmentsResponse is the request type for the +// Query/QueryPacketCommitments RPC method +message QueryPacketCommitmentsResponse { + repeated ibc.core.channel.v1.PacketState commitments = 1; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; + // query block height + ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; +} + +// QueryPacketReceiptRequest is the request type for the +// Query/PacketReceipt RPC method +message QueryPacketReceiptRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // packet sequence + uint64 sequence = 3; +} + +// QueryPacketReceiptResponse defines the client query response for a packet +// receipt which also includes a proof, and the height from which the proof was +// retrieved +message QueryPacketReceiptResponse { + // success flag for if receipt exists + bool received = 2; + // merkle proof of existence + bytes proof = 3; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; +} + +// QueryPacketAcknowledgementRequest is the request type for the +// Query/PacketAcknowledgement RPC method +message QueryPacketAcknowledgementRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // packet sequence + uint64 sequence = 3; +} + +// QueryPacketAcknowledgementResponse defines the client query response for a +// packet which also includes a proof and the height from which the +// proof was retrieved +message QueryPacketAcknowledgementResponse { + // packet associated with the request fields + bytes acknowledgement = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryPacketAcknowledgementsRequest is the request type for the +// Query/QueryPacketCommitments RPC method +message QueryPacketAcknowledgementsRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // pagination request + cosmos.base.query.v1beta1.PageRequest pagination = 3; + // list of packet sequences + repeated uint64 packet_commitment_sequences = 4; +} + +// QueryPacketAcknowledgemetsResponse is the request type for the +// Query/QueryPacketAcknowledgements RPC method +message QueryPacketAcknowledgementsResponse { + repeated ibc.core.channel.v1.PacketState acknowledgements = 1; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; + // query block height + ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; +} + +// QueryUnreceivedPacketsRequest is the request type for the +// Query/UnreceivedPackets RPC method +message QueryUnreceivedPacketsRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // list of packet sequences + repeated uint64 packet_commitment_sequences = 3; +} + +// QueryUnreceivedPacketsResponse is the response type for the +// Query/UnreceivedPacketCommitments RPC method +message QueryUnreceivedPacketsResponse { + // list of unreceived packet sequences + repeated uint64 sequences = 1; + // query block height + ibc.core.client.v1.Height height = 2 [(gogoproto.nullable) = false]; +} + +// QueryUnreceivedAcks is the request type for the +// Query/UnreceivedAcks RPC method +message QueryUnreceivedAcksRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // list of acknowledgement sequences + repeated uint64 packet_ack_sequences = 3; +} + +// QueryUnreceivedAcksResponse is the response type for the +// Query/UnreceivedAcks RPC method +message QueryUnreceivedAcksResponse { + // list of unreceived acknowledgement sequences + repeated uint64 sequences = 1; + // query block height + ibc.core.client.v1.Height height = 2 [(gogoproto.nullable) = false]; +} + +// QueryNextSequenceReceiveRequest is the request type for the +// Query/QueryNextSequenceReceiveRequest RPC method +message QueryNextSequenceReceiveRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; +} + +// QuerySequenceResponse is the response type for the +// Query/QueryNextSequenceReceiveResponse RPC method +message QueryNextSequenceReceiveResponse { + // next sequence receive number + uint64 next_sequence_receive = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryNextSequenceSendRequest is the request type for the +// Query/QueryNextSequenceSend RPC method +message QueryNextSequenceSendRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; +} + +// QueryNextSequenceSendResponse is the request type for the +// Query/QueryNextSequenceSend RPC method +message QueryNextSequenceSendResponse { + // next sequence send number + uint64 next_sequence_send = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryUpgradeErrorRequest is the request type for the Query/QueryUpgradeError RPC method +message QueryUpgradeErrorRequest { + string port_id = 1; + string channel_id = 2; +} + +// QueryUpgradeErrorResponse is the response type for the Query/QueryUpgradeError RPC method +message QueryUpgradeErrorResponse { + ErrorReceipt error_receipt = 1 [(gogoproto.nullable) = false]; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryUpgradeRequest is the request type for the QueryUpgradeRequest RPC method +message QueryUpgradeRequest { + string port_id = 1; + string channel_id = 2; +} + +// QueryUpgradeResponse is the response type for the QueryUpgradeResponse RPC method +message QueryUpgradeResponse { + Upgrade upgrade = 1 [(gogoproto.nullable) = false]; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryChannelParamsRequest is the request type for the Query/ChannelParams RPC method. +message QueryChannelParamsRequest {} + +// QueryChannelParamsResponse is the response type for the Query/ChannelParams RPC method. +message QueryChannelParamsResponse { + // params defines the parameters of the module. + Params params = 1; +} \ No newline at end of file diff --git a/third_party/proto/ibc/channel/v1/tx.proto b/third_party/proto/ibc/channel/v1/tx.proto new file mode 100644 index 000000000..3f30e8b8c --- /dev/null +++ b/third_party/proto/ibc/channel/v1/tx.proto @@ -0,0 +1,469 @@ +syntax = "proto3"; + +package ibc.core.channel.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/msg/v1/msg.proto"; +import "ibc/core/client/v1/client.proto"; +import "ibc/core/channel/v1/channel.proto"; +import "ibc/core/channel/v1/upgrade.proto"; + +// Msg defines the ibc/channel Msg service. +service Msg { + option (cosmos.msg.v1.service) = true; + + // ChannelOpenInit defines a rpc handler method for MsgChannelOpenInit. + rpc ChannelOpenInit(MsgChannelOpenInit) returns (MsgChannelOpenInitResponse); + + // ChannelOpenTry defines a rpc handler method for MsgChannelOpenTry. + rpc ChannelOpenTry(MsgChannelOpenTry) returns (MsgChannelOpenTryResponse); + + // ChannelOpenAck defines a rpc handler method for MsgChannelOpenAck. + rpc ChannelOpenAck(MsgChannelOpenAck) returns (MsgChannelOpenAckResponse); + + // ChannelOpenConfirm defines a rpc handler method for MsgChannelOpenConfirm. + rpc ChannelOpenConfirm(MsgChannelOpenConfirm) returns (MsgChannelOpenConfirmResponse); + + // ChannelCloseInit defines a rpc handler method for MsgChannelCloseInit. + rpc ChannelCloseInit(MsgChannelCloseInit) returns (MsgChannelCloseInitResponse); + + // ChannelCloseConfirm defines a rpc handler method for + // MsgChannelCloseConfirm. + rpc ChannelCloseConfirm(MsgChannelCloseConfirm) returns (MsgChannelCloseConfirmResponse); + + // RecvPacket defines a rpc handler method for MsgRecvPacket. + rpc RecvPacket(MsgRecvPacket) returns (MsgRecvPacketResponse); + + // Timeout defines a rpc handler method for MsgTimeout. + rpc Timeout(MsgTimeout) returns (MsgTimeoutResponse); + + // TimeoutOnClose defines a rpc handler method for MsgTimeoutOnClose. + rpc TimeoutOnClose(MsgTimeoutOnClose) returns (MsgTimeoutOnCloseResponse); + + // Acknowledgement defines a rpc handler method for MsgAcknowledgement. + rpc Acknowledgement(MsgAcknowledgement) returns (MsgAcknowledgementResponse); + + // ChannelUpgradeInit defines a rpc handler method for MsgChannelUpgradeInit. + rpc ChannelUpgradeInit(MsgChannelUpgradeInit) returns (MsgChannelUpgradeInitResponse); + + // ChannelUpgradeTry defines a rpc handler method for MsgChannelUpgradeTry. + rpc ChannelUpgradeTry(MsgChannelUpgradeTry) returns (MsgChannelUpgradeTryResponse); + + // ChannelUpgradeAck defines a rpc handler method for MsgChannelUpgradeAck. + rpc ChannelUpgradeAck(MsgChannelUpgradeAck) returns (MsgChannelUpgradeAckResponse); + + // ChannelUpgradeConfirm defines a rpc handler method for MsgChannelUpgradeConfirm. + rpc ChannelUpgradeConfirm(MsgChannelUpgradeConfirm) returns (MsgChannelUpgradeConfirmResponse); + + // ChannelUpgradeOpen defines a rpc handler method for MsgChannelUpgradeOpen. + rpc ChannelUpgradeOpen(MsgChannelUpgradeOpen) returns (MsgChannelUpgradeOpenResponse); + + // ChannelUpgradeTimeout defines a rpc handler method for MsgChannelUpgradeTimeout. + rpc ChannelUpgradeTimeout(MsgChannelUpgradeTimeout) returns (MsgChannelUpgradeTimeoutResponse); + + // ChannelUpgradeCancel defines a rpc handler method for MsgChannelUpgradeCancel. + rpc ChannelUpgradeCancel(MsgChannelUpgradeCancel) returns (MsgChannelUpgradeCancelResponse); + + // UpdateChannelParams defines a rpc handler method for MsgUpdateParams. + rpc UpdateChannelParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); + + // PruneAcknowledgements defines a rpc handler method for MsgPruneAcknowledgements. + rpc PruneAcknowledgements(MsgPruneAcknowledgements) returns (MsgPruneAcknowledgementsResponse); +} + +// ResponseResultType defines the possible outcomes of the execution of a message +enum ResponseResultType { + option (gogoproto.goproto_enum_prefix) = false; + + // Default zero value enumeration + RESPONSE_RESULT_TYPE_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNSPECIFIED"]; + // The message did not call the IBC application callbacks (because, for example, the packet had already been relayed) + RESPONSE_RESULT_TYPE_NOOP = 1 [(gogoproto.enumvalue_customname) = "NOOP"]; + // The message was executed successfully + RESPONSE_RESULT_TYPE_SUCCESS = 2 [(gogoproto.enumvalue_customname) = "SUCCESS"]; + // The message was executed unsuccessfully + RESPONSE_RESULT_TYPE_FAILURE = 3 [(gogoproto.enumvalue_customname) = "FAILURE"]; +} + +// MsgChannelOpenInit defines an sdk.Msg to initialize a channel handshake. It +// is called by a relayer on Chain A. +message MsgChannelOpenInit { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + string port_id = 1; + Channel channel = 2 [(gogoproto.nullable) = false]; + string signer = 3; +} + +// MsgChannelOpenInitResponse defines the Msg/ChannelOpenInit response type. +message MsgChannelOpenInitResponse { + option (gogoproto.goproto_getters) = false; + + string channel_id = 1; + string version = 2; +} + +// MsgChannelOpenInit defines a msg sent by a Relayer to try to open a channel +// on Chain B. The version field within the Channel field has been deprecated. Its +// value will be ignored by core IBC. +message MsgChannelOpenTry { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + string port_id = 1; + // Deprecated: this field is unused. Crossing hello's are no longer supported in core IBC. + string previous_channel_id = 2 [deprecated = true]; + // NOTE: the version field within the channel has been deprecated. Its value will be ignored by core IBC. + Channel channel = 3 [(gogoproto.nullable) = false]; + string counterparty_version = 4; + bytes proof_init = 5; + ibc.core.client.v1.Height proof_height = 6 [(gogoproto.nullable) = false]; + string signer = 7; +} + +// MsgChannelOpenTryResponse defines the Msg/ChannelOpenTry response type. +message MsgChannelOpenTryResponse { + option (gogoproto.goproto_getters) = false; + + string version = 1; + string channel_id = 2; +} + +// MsgChannelOpenAck defines a msg sent by a Relayer to Chain A to acknowledge +// the change of channel state to TRYOPEN on Chain B. +// WARNING: a channel upgrade MUST NOT initialize an upgrade for this channel +// in the same block as executing this message otherwise the counterparty will +// be incapable of opening. +message MsgChannelOpenAck { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + string port_id = 1; + string channel_id = 2; + string counterparty_channel_id = 3; + string counterparty_version = 4; + bytes proof_try = 5; + ibc.core.client.v1.Height proof_height = 6 [(gogoproto.nullable) = false]; + string signer = 7; +} + +// MsgChannelOpenAckResponse defines the Msg/ChannelOpenAck response type. +message MsgChannelOpenAckResponse {} + +// MsgChannelOpenConfirm defines a msg sent by a Relayer to Chain B to +// acknowledge the change of channel state to OPEN on Chain A. +message MsgChannelOpenConfirm { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + string port_id = 1; + string channel_id = 2; + bytes proof_ack = 3; + ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; + string signer = 5; +} + +// MsgChannelOpenConfirmResponse defines the Msg/ChannelOpenConfirm response +// type. +message MsgChannelOpenConfirmResponse {} + +// MsgChannelCloseInit defines a msg sent by a Relayer to Chain A +// to close a channel with Chain B. +message MsgChannelCloseInit { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + string port_id = 1; + string channel_id = 2; + string signer = 3; +} + +// MsgChannelCloseInitResponse defines the Msg/ChannelCloseInit response type. +message MsgChannelCloseInitResponse {} + +// MsgChannelCloseConfirm defines a msg sent by a Relayer to Chain B +// to acknowledge the change of channel state to CLOSED on Chain A. +message MsgChannelCloseConfirm { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + string port_id = 1; + string channel_id = 2; + bytes proof_init = 3; + ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; + string signer = 5; + uint64 counterparty_upgrade_sequence = 6; +} + +// MsgChannelCloseConfirmResponse defines the Msg/ChannelCloseConfirm response +// type. +message MsgChannelCloseConfirmResponse {} + +// MsgRecvPacket receives incoming IBC packet +message MsgRecvPacket { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes proof_commitment = 2; + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; + string signer = 4; +} + +// MsgRecvPacketResponse defines the Msg/RecvPacket response type. +message MsgRecvPacketResponse { + option (gogoproto.goproto_getters) = false; + + ResponseResultType result = 1; +} + +// MsgTimeout receives timed-out packet +message MsgTimeout { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes proof_unreceived = 2; + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; + uint64 next_sequence_recv = 4; + string signer = 5; +} + +// MsgTimeoutResponse defines the Msg/Timeout response type. +message MsgTimeoutResponse { + option (gogoproto.goproto_getters) = false; + + ResponseResultType result = 1; +} + +// MsgTimeoutOnClose timed-out packet upon counterparty channel closure. +message MsgTimeoutOnClose { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes proof_unreceived = 2; + bytes proof_close = 3; + ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; + uint64 next_sequence_recv = 5; + string signer = 6; + uint64 counterparty_upgrade_sequence = 7; +} + +// MsgTimeoutOnCloseResponse defines the Msg/TimeoutOnClose response type. +message MsgTimeoutOnCloseResponse { + option (gogoproto.goproto_getters) = false; + + ResponseResultType result = 1; +} + +// MsgAcknowledgement receives incoming IBC acknowledgement +message MsgAcknowledgement { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes acknowledgement = 2; + bytes proof_acked = 3; + ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; + string signer = 5; +} + +// MsgAcknowledgementResponse defines the Msg/Acknowledgement response type. +message MsgAcknowledgementResponse { + option (gogoproto.goproto_getters) = false; + + ResponseResultType result = 1; +} + +// MsgChannelUpgradeInit defines the request type for the ChannelUpgradeInit rpc +// WARNING: Initializing a channel upgrade in the same block as opening the channel +// may result in the counterparty being incapable of opening. +message MsgChannelUpgradeInit { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + string port_id = 1; + string channel_id = 2; + UpgradeFields fields = 3 [(gogoproto.nullable) = false]; + string signer = 4; +} + +// MsgChannelUpgradeInitResponse defines the MsgChannelUpgradeInit response type +message MsgChannelUpgradeInitResponse { + option (gogoproto.goproto_getters) = false; + + Upgrade upgrade = 1 [(gogoproto.nullable) = false]; + uint64 upgrade_sequence = 2; +} + +// MsgChannelUpgradeTry defines the request type for the ChannelUpgradeTry rpc +message MsgChannelUpgradeTry { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + string port_id = 1; + string channel_id = 2; + repeated string proposed_upgrade_connection_hops = 3; + UpgradeFields counterparty_upgrade_fields = 4 [(gogoproto.nullable) = false]; + uint64 counterparty_upgrade_sequence = 5; + bytes proof_channel = 6; + bytes proof_upgrade = 7; + ibc.core.client.v1.Height proof_height = 8 [(gogoproto.nullable) = false]; + string signer = 9; +} + +// MsgChannelUpgradeTryResponse defines the MsgChannelUpgradeTry response type +message MsgChannelUpgradeTryResponse { + option (gogoproto.goproto_getters) = false; + + Upgrade upgrade = 1 [(gogoproto.nullable) = false]; + uint64 upgrade_sequence = 2; + ResponseResultType result = 3; +} + +// MsgChannelUpgradeAck defines the request type for the ChannelUpgradeAck rpc +message MsgChannelUpgradeAck { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + string port_id = 1; + string channel_id = 2; + Upgrade counterparty_upgrade = 3 [(gogoproto.nullable) = false]; + bytes proof_channel = 4; + bytes proof_upgrade = 5; + ibc.core.client.v1.Height proof_height = 6 [(gogoproto.nullable) = false]; + string signer = 7; +} + +// MsgChannelUpgradeAckResponse defines MsgChannelUpgradeAck response type +message MsgChannelUpgradeAckResponse { + option (gogoproto.goproto_getters) = false; + + ResponseResultType result = 1; +} + +// MsgChannelUpgradeConfirm defines the request type for the ChannelUpgradeConfirm rpc +message MsgChannelUpgradeConfirm { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + string port_id = 1; + string channel_id = 2; + State counterparty_channel_state = 3; + Upgrade counterparty_upgrade = 4 [(gogoproto.nullable) = false]; + bytes proof_channel = 5; + bytes proof_upgrade = 6; + ibc.core.client.v1.Height proof_height = 7 [(gogoproto.nullable) = false]; + string signer = 8; +} + +// MsgChannelUpgradeConfirmResponse defines MsgChannelUpgradeConfirm response type +message MsgChannelUpgradeConfirmResponse { + option (gogoproto.goproto_getters) = false; + + ResponseResultType result = 1; +} + +// MsgChannelUpgradeOpen defines the request type for the ChannelUpgradeOpen rpc +message MsgChannelUpgradeOpen { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + string port_id = 1; + string channel_id = 2; + State counterparty_channel_state = 3; + uint64 counterparty_upgrade_sequence = 4; + bytes proof_channel = 5; + ibc.core.client.v1.Height proof_height = 6 [(gogoproto.nullable) = false]; + string signer = 7; +} + +// MsgChannelUpgradeOpenResponse defines the MsgChannelUpgradeOpen response type +message MsgChannelUpgradeOpenResponse {} + +// MsgChannelUpgradeTimeout defines the request type for the ChannelUpgradeTimeout rpc +message MsgChannelUpgradeTimeout { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + string port_id = 1; + string channel_id = 2; + Channel counterparty_channel = 3 [(gogoproto.nullable) = false]; + bytes proof_channel = 4; + ibc.core.client.v1.Height proof_height = 5 [(gogoproto.nullable) = false]; + string signer = 6; +} + +// MsgChannelUpgradeTimeoutRepsonse defines the MsgChannelUpgradeTimeout response type +message MsgChannelUpgradeTimeoutResponse {} + +// MsgChannelUpgradeCancel defines the request type for the ChannelUpgradeCancel rpc +message MsgChannelUpgradeCancel { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + string port_id = 1; + string channel_id = 2; + ErrorReceipt error_receipt = 3 [(gogoproto.nullable) = false]; + bytes proof_error_receipt = 4; + ibc.core.client.v1.Height proof_height = 5 [(gogoproto.nullable) = false]; + string signer = 6; +} + +// MsgChannelUpgradeCancelResponse defines the MsgChannelUpgradeCancel response type +message MsgChannelUpgradeCancelResponse {} + +// MsgUpdateParams is the MsgUpdateParams request type. +message MsgUpdateParams { + option (cosmos.msg.v1.signer) = "authority"; + + option (gogoproto.goproto_getters) = false; + + // authority is the address that controls the module (defaults to x/gov unless overwritten). + string authority = 1; + + // params defines the channel parameters to update. + // + // NOTE: All parameters must be supplied. + Params params = 2 [(gogoproto.nullable) = false]; +} + +// MsgUpdateParamsResponse defines the MsgUpdateParams response type. +message MsgUpdateParamsResponse {} + +// MsgPruneAcknowledgements defines the request type for the PruneAcknowledgements rpc. +message MsgPruneAcknowledgements { + option (cosmos.msg.v1.signer) = "signer"; + option (gogoproto.goproto_getters) = false; + + string port_id = 1; + string channel_id = 2; + uint64 limit = 3; + string signer = 4; +} + +// MsgPruneAcknowledgementsResponse defines the response type for the PruneAcknowledgements rpc. +message MsgPruneAcknowledgementsResponse { + // Number of sequences pruned (includes both packet acknowledgements and packet receipts where appropriate). + uint64 total_pruned_sequences = 1; + // Number of sequences left after pruning. + uint64 total_remaining_sequences = 2; +} diff --git a/third_party/proto/ibc/channel/v1/upgrade.proto b/third_party/proto/ibc/channel/v1/upgrade.proto new file mode 100644 index 000000000..81530ed2a --- /dev/null +++ b/third_party/proto/ibc/channel/v1/upgrade.proto @@ -0,0 +1,43 @@ +syntax = "proto3"; + +package ibc.core.channel.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"; + +import "gogoproto/gogo.proto"; +import "ibc/core/channel/v1/channel.proto"; + +// Upgrade is a verifiable type which contains the relevant information +// for an attempted upgrade. It provides the proposed changes to the channel +// end, the timeout for this upgrade attempt and the next packet sequence +// which allows the counterparty to efficiently know the highest sequence it has received. +// The next sequence send is used for pruning and upgrading from unordered to ordered channels. +message Upgrade { + option (gogoproto.goproto_getters) = false; + + UpgradeFields fields = 1 [(gogoproto.nullable) = false]; + Timeout timeout = 2 [(gogoproto.nullable) = false]; + uint64 next_sequence_send = 3; +} + +// UpgradeFields are the fields in a channel end which may be changed +// during a channel upgrade. +message UpgradeFields { + option (gogoproto.goproto_getters) = false; + + Order ordering = 1; + repeated string connection_hops = 2; + string version = 3; +} + +// ErrorReceipt defines a type which encapsulates the upgrade sequence and error associated with the +// upgrade handshake failure. When a channel upgrade handshake is aborted both chains are expected to increment to the +// next sequence. +message ErrorReceipt { + option (gogoproto.goproto_getters) = false; + + // the channel upgrade sequence + uint64 sequence = 1; + // the error message detailing the cause of failure + string message = 2; +} diff --git a/third_party/proto/ibc/client/v1/client.proto b/third_party/proto/ibc/client/v1/client.proto new file mode 100644 index 000000000..7a09e360a --- /dev/null +++ b/third_party/proto/ibc/client/v1/client.proto @@ -0,0 +1,113 @@ +syntax = "proto3"; + +package ibc.core.client.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"; + +import "cosmos/upgrade/v1beta1/upgrade.proto"; +import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +// IdentifiedClientState defines a client state with an additional client +// identifier field. +message IdentifiedClientState { + // client identifier + string client_id = 1; + // client state + google.protobuf.Any client_state = 2; +} + +// ConsensusStateWithHeight defines a consensus state with an additional height +// field. +message ConsensusStateWithHeight { + // consensus state height + Height height = 1 [(gogoproto.nullable) = false]; + // consensus state + google.protobuf.Any consensus_state = 2; +} + +// ClientConsensusStates defines all the stored consensus states for a given +// client. +message ClientConsensusStates { + // client identifier + string client_id = 1; + // consensus states and their heights associated with the client + repeated ConsensusStateWithHeight consensus_states = 2 [(gogoproto.nullable) = false]; +} + +// Height is a monotonically increasing data type +// that can be compared against another Height for the purposes of updating and +// freezing clients +// +// Normally the RevisionHeight is incremented at each height while keeping +// RevisionNumber the same. However some consensus algorithms may choose to +// reset the height in certain conditions e.g. hard forks, state-machine +// breaking changes In these cases, the RevisionNumber is incremented so that +// height continues to be monitonically increasing even as the RevisionHeight +// gets reset +message Height { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + // the revision that the client is currently on + uint64 revision_number = 1; + // the height within the given revision + uint64 revision_height = 2; +} + +// Params defines the set of IBC light client parameters. +message Params { + // allowed_clients defines the list of allowed client state types which can be created + // and interacted with. If a client type is removed from the allowed clients list, usage + // of this client will be disabled until it is added again to the list. + repeated string allowed_clients = 1; +} + +// ClientUpdateProposal is a legacy governance proposal. If it passes, the substitute +// client's latest consensus state is copied over to the subject client. The proposal +// handler may fail if the subject and the substitute do not match in client and +// chain parameters (with exception to latest height, frozen height, and chain-id). +// +// Deprecated: Please use MsgRecoverClient in favour of this message type. +message ClientUpdateProposal { + option deprecated = true; + + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + option (gogoproto.goproto_getters) = false; + + // the title of the update proposal + string title = 1; + // the description of the proposal + string description = 2; + // the client identifier for the client to be updated if the proposal passes + string subject_client_id = 3 [(gogoproto.moretags) = "yaml:\"subject_client_id\""]; + // the substitute client identifier for the client standing in for the subject + // client + string substitute_client_id = 4 [(gogoproto.moretags) = "yaml:\"substitute_client_id\""]; +} + +// UpgradeProposal is a gov Content type for initiating an IBC breaking +// upgrade. +// +// Deprecated: Please use MsgIBCSoftwareUpgrade in favour of this message type. +message UpgradeProposal { + option deprecated = true; + + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + option (gogoproto.equal) = true; + + string title = 1; + string description = 2; + cosmos.upgrade.v1beta1.Plan plan = 3 [(gogoproto.nullable) = false]; + + // An UpgradedClientState must be provided to perform an IBC breaking upgrade. + // This will make the chain commit to the correct upgraded (self) client state + // before the upgrade occurs, so that connecting chains can verify that the + // new upgraded client is valid by verifying a proof on the previous version + // of the chain. This will allow IBC connections to persist smoothly across + // planned chain upgrades + google.protobuf.Any upgraded_client_state = 4 [(gogoproto.moretags) = "yaml:\"upgraded_client_state\""]; +} diff --git a/third_party/proto/ibc/client/v1/genesis.proto b/third_party/proto/ibc/client/v1/genesis.proto new file mode 100644 index 000000000..43610b0d4 --- /dev/null +++ b/third_party/proto/ibc/client/v1/genesis.proto @@ -0,0 +1,44 @@ +syntax = "proto3"; + +package ibc.core.client.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"; + +import "ibc/core/client/v1/client.proto"; +import "gogoproto/gogo.proto"; + +// GenesisState defines the ibc client submodule's genesis state. +message GenesisState { + // client states with their corresponding identifiers + repeated IdentifiedClientState clients = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "IdentifiedClientStates"]; + // consensus states from each client + repeated ClientConsensusStates clients_consensus = 2 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "ClientsConsensusStates"]; + // metadata from each client + repeated IdentifiedGenesisMetadata clients_metadata = 3 [(gogoproto.nullable) = false]; + Params params = 4 [(gogoproto.nullable) = false]; + // Deprecated: create_localhost has been deprecated. + // The localhost client is automatically created at genesis. + bool create_localhost = 5 [deprecated = true]; + // the sequence for the next generated client identifier + uint64 next_client_sequence = 6; +} + +// GenesisMetadata defines the genesis type for metadata that clients may return +// with ExportMetadata +message GenesisMetadata { + option (gogoproto.goproto_getters) = false; + + // store key of metadata without clientID-prefix + bytes key = 1; + // metadata value + bytes value = 2; +} + +// IdentifiedGenesisMetadata has the client metadata with the corresponding +// client id. +message IdentifiedGenesisMetadata { + string client_id = 1; + repeated GenesisMetadata client_metadata = 2 [(gogoproto.nullable) = false]; +} diff --git a/third_party/proto/ibc/client/v1/query.proto b/third_party/proto/ibc/client/v1/query.proto new file mode 100644 index 000000000..0032306ec --- /dev/null +++ b/third_party/proto/ibc/client/v1/query.proto @@ -0,0 +1,207 @@ +syntax = "proto3"; + +package ibc.core.client.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "ibc/core/client/v1/client.proto"; +import "google/protobuf/any.proto"; +import "google/api/annotations.proto"; +import "gogoproto/gogo.proto"; + +// Query provides defines the gRPC querier service +service Query { + // ClientState queries an IBC light client. + rpc ClientState(QueryClientStateRequest) returns (QueryClientStateResponse) { + option (google.api.http).get = "/ibc/core/client/v1/client_states/{client_id}"; + } + + // ClientStates queries all the IBC light clients of a chain. + rpc ClientStates(QueryClientStatesRequest) returns (QueryClientStatesResponse) { + option (google.api.http).get = "/ibc/core/client/v1/client_states"; + } + + // ConsensusState queries a consensus state associated with a client state at + // a given height. + rpc ConsensusState(QueryConsensusStateRequest) returns (QueryConsensusStateResponse) { + option (google.api.http).get = "/ibc/core/client/v1/consensus_states/" + "{client_id}/revision/{revision_number}/" + "height/{revision_height}"; + } + + // ConsensusStates queries all the consensus state associated with a given + // client. + rpc ConsensusStates(QueryConsensusStatesRequest) returns (QueryConsensusStatesResponse) { + option (google.api.http).get = "/ibc/core/client/v1/consensus_states/{client_id}"; + } + + // ConsensusStateHeights queries the height of every consensus states associated with a given client. + rpc ConsensusStateHeights(QueryConsensusStateHeightsRequest) returns (QueryConsensusStateHeightsResponse) { + option (google.api.http).get = "/ibc/core/client/v1/consensus_states/{client_id}/heights"; + } + + // Status queries the status of an IBC client. + rpc ClientStatus(QueryClientStatusRequest) returns (QueryClientStatusResponse) { + option (google.api.http).get = "/ibc/core/client/v1/client_status/{client_id}"; + } + + // ClientParams queries all parameters of the ibc client submodule. + rpc ClientParams(QueryClientParamsRequest) returns (QueryClientParamsResponse) { + option (google.api.http).get = "/ibc/core/client/v1/params"; + } + + // UpgradedClientState queries an Upgraded IBC light client. + rpc UpgradedClientState(QueryUpgradedClientStateRequest) returns (QueryUpgradedClientStateResponse) { + option (google.api.http).get = "/ibc/core/client/v1/upgraded_client_states"; + } + + // UpgradedConsensusState queries an Upgraded IBC consensus state. + rpc UpgradedConsensusState(QueryUpgradedConsensusStateRequest) returns (QueryUpgradedConsensusStateResponse) { + option (google.api.http).get = "/ibc/core/client/v1/upgraded_consensus_states"; + } +} + +// QueryClientStateRequest is the request type for the Query/ClientState RPC +// method +message QueryClientStateRequest { + // client state unique identifier + string client_id = 1; +} + +// QueryClientStateResponse is the response type for the Query/ClientState RPC +// method. Besides the client state, it includes a proof and the height from +// which the proof was retrieved. +message QueryClientStateResponse { + // client state associated with the request identifier + google.protobuf.Any client_state = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryClientStatesRequest is the request type for the Query/ClientStates RPC +// method +message QueryClientStatesRequest { + // pagination request + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryClientStatesResponse is the response type for the Query/ClientStates RPC +// method. +message QueryClientStatesResponse { + // list of stored ClientStates of the chain. + repeated IdentifiedClientState client_states = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "IdentifiedClientStates"]; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryConsensusStateRequest is the request type for the Query/ConsensusState +// RPC method. Besides the consensus state, it includes a proof and the height +// from which the proof was retrieved. +message QueryConsensusStateRequest { + // client identifier + string client_id = 1; + // consensus state revision number + uint64 revision_number = 2; + // consensus state revision height + uint64 revision_height = 3; + // latest_height overrrides the height field and queries the latest stored + // ConsensusState + bool latest_height = 4; +} + +// QueryConsensusStateResponse is the response type for the Query/ConsensusState +// RPC method +message QueryConsensusStateResponse { + // consensus state associated with the client identifier at the given height + google.protobuf.Any consensus_state = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryConsensusStatesRequest is the request type for the Query/ConsensusStates +// RPC method. +message QueryConsensusStatesRequest { + // client identifier + string client_id = 1; + // pagination request + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryConsensusStatesResponse is the response type for the +// Query/ConsensusStates RPC method +message QueryConsensusStatesResponse { + // consensus states associated with the identifier + repeated ConsensusStateWithHeight consensus_states = 1 [(gogoproto.nullable) = false]; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryConsensusStateHeightsRequest is the request type for Query/ConsensusStateHeights +// RPC method. +message QueryConsensusStateHeightsRequest { + // client identifier + string client_id = 1; + // pagination request + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryConsensusStateHeightsResponse is the response type for the +// Query/ConsensusStateHeights RPC method +message QueryConsensusStateHeightsResponse { + // consensus state heights + repeated Height consensus_state_heights = 1 [(gogoproto.nullable) = false]; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryClientStatusRequest is the request type for the Query/ClientStatus RPC +// method +message QueryClientStatusRequest { + // client unique identifier + string client_id = 1; +} + +// QueryClientStatusResponse is the response type for the Query/ClientStatus RPC +// method. It returns the current status of the IBC client. +message QueryClientStatusResponse { + string status = 1; +} + +// QueryClientParamsRequest is the request type for the Query/ClientParams RPC +// method. +message QueryClientParamsRequest {} + +// QueryClientParamsResponse is the response type for the Query/ClientParams RPC +// method. +message QueryClientParamsResponse { + // params defines the parameters of the module. + Params params = 1; +} + +// QueryUpgradedClientStateRequest is the request type for the +// Query/UpgradedClientState RPC method +message QueryUpgradedClientStateRequest {} + +// QueryUpgradedClientStateResponse is the response type for the +// Query/UpgradedClientState RPC method. +message QueryUpgradedClientStateResponse { + // client state associated with the request identifier + google.protobuf.Any upgraded_client_state = 1; +} + +// QueryUpgradedConsensusStateRequest is the request type for the +// Query/UpgradedConsensusState RPC method +message QueryUpgradedConsensusStateRequest {} + +// QueryUpgradedConsensusStateResponse is the response type for the +// Query/UpgradedConsensusState RPC method. +message QueryUpgradedConsensusStateResponse { + // Consensus state associated with the request identifier + google.protobuf.Any upgraded_consensus_state = 1; +} diff --git a/third_party/proto/ibc/client/v1/tx.proto b/third_party/proto/ibc/client/v1/tx.proto new file mode 100644 index 000000000..b504ab692 --- /dev/null +++ b/third_party/proto/ibc/client/v1/tx.proto @@ -0,0 +1,175 @@ +syntax = "proto3"; + +package ibc.core.client.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"; + +import "cosmos/msg/v1/msg.proto"; +import "cosmos/upgrade/v1beta1/upgrade.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "ibc/core/client/v1/client.proto"; + +// Msg defines the ibc/client Msg service. +service Msg { + option (cosmos.msg.v1.service) = true; + + // CreateClient defines a rpc handler method for MsgCreateClient. + rpc CreateClient(MsgCreateClient) returns (MsgCreateClientResponse); + + // UpdateClient defines a rpc handler method for MsgUpdateClient. + rpc UpdateClient(MsgUpdateClient) returns (MsgUpdateClientResponse); + + // UpgradeClient defines a rpc handler method for MsgUpgradeClient. + rpc UpgradeClient(MsgUpgradeClient) returns (MsgUpgradeClientResponse); + + // SubmitMisbehaviour defines a rpc handler method for MsgSubmitMisbehaviour. + rpc SubmitMisbehaviour(MsgSubmitMisbehaviour) returns (MsgSubmitMisbehaviourResponse); + + // RecoverClient defines a rpc handler method for MsgRecoverClient. + rpc RecoverClient(MsgRecoverClient) returns (MsgRecoverClientResponse); + + // IBCSoftwareUpgrade defines a rpc handler method for MsgIBCSoftwareUpgrade. + rpc IBCSoftwareUpgrade(MsgIBCSoftwareUpgrade) returns (MsgIBCSoftwareUpgradeResponse); + + // UpdateClientParams defines a rpc handler method for MsgUpdateParams. + rpc UpdateClientParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); +} + +// MsgCreateClient defines a message to create an IBC client +message MsgCreateClient { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + // light client state + google.protobuf.Any client_state = 1; + // consensus state associated with the client that corresponds to a given + // height. + google.protobuf.Any consensus_state = 2; + // signer address + string signer = 3; +} + +// MsgCreateClientResponse defines the Msg/CreateClient response type. +message MsgCreateClientResponse {} + +// MsgUpdateClient defines an sdk.Msg to update a IBC client state using +// the given client message. +message MsgUpdateClient { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + // client unique identifier + string client_id = 1; + // client message to update the light client + google.protobuf.Any client_message = 2; + // signer address + string signer = 3; +} + +// MsgUpdateClientResponse defines the Msg/UpdateClient response type. +message MsgUpdateClientResponse {} + +// MsgUpgradeClient defines an sdk.Msg to upgrade an IBC client to a new client +// state +message MsgUpgradeClient { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + // client unique identifier + string client_id = 1; + // upgraded client state + google.protobuf.Any client_state = 2; + // upgraded consensus state, only contains enough information to serve as a + // basis of trust in update logic + google.protobuf.Any consensus_state = 3; + // proof that old chain committed to new client + bytes proof_upgrade_client = 4; + // proof that old chain committed to new consensus state + bytes proof_upgrade_consensus_state = 5; + // signer address + string signer = 6; +} + +// MsgUpgradeClientResponse defines the Msg/UpgradeClient response type. +message MsgUpgradeClientResponse {} + +// MsgSubmitMisbehaviour defines an sdk.Msg type that submits Evidence for +// light client misbehaviour. +// This message has been deprecated. Use MsgUpdateClient instead. +message MsgSubmitMisbehaviour { + option deprecated = true; + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + // client unique identifier + string client_id = 1; + // misbehaviour used for freezing the light client + google.protobuf.Any misbehaviour = 2; + // signer address + string signer = 3; +} + +// MsgSubmitMisbehaviourResponse defines the Msg/SubmitMisbehaviour response +// type. +message MsgSubmitMisbehaviourResponse {} + +// MsgRecoverClient defines the message used to recover a frozen or expired client. +message MsgRecoverClient { + option (gogoproto.goproto_getters) = false; + option (cosmos.msg.v1.signer) = "signer"; + + // the client identifier for the client to be updated if the proposal passes + string subject_client_id = 1; + // the substitute client identifier for the client which will replace the subject + // client + string substitute_client_id = 2; + + // signer address + string signer = 3; +} + +// MsgRecoverClientResponse defines the Msg/RecoverClient response type. +message MsgRecoverClientResponse {} + +// MsgIBCSoftwareUpgrade defines the message used to schedule an upgrade of an IBC client using a v1 governance proposal +message MsgIBCSoftwareUpgrade { + option (cosmos.msg.v1.signer) = "signer"; + cosmos.upgrade.v1beta1.Plan plan = 1 [(gogoproto.nullable) = false]; + // An UpgradedClientState must be provided to perform an IBC breaking upgrade. + // This will make the chain commit to the correct upgraded (self) client state + // before the upgrade occurs, so that connecting chains can verify that the + // new upgraded client is valid by verifying a proof on the previous version + // of the chain. This will allow IBC connections to persist smoothly across + // planned chain upgrades. Correspondingly, the UpgradedClientState field has been + // deprecated in the Cosmos SDK to allow for this logic to exist solely in + // the 02-client module. + google.protobuf.Any upgraded_client_state = 2; + // signer address + string signer = 3; +} + +// MsgIBCSoftwareUpgradeResponse defines the Msg/IBCSoftwareUpgrade response type. +message MsgIBCSoftwareUpgradeResponse {} + +// MsgUpdateParams defines the sdk.Msg type to update the client parameters. +message MsgUpdateParams { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + // signer address + string signer = 1; + + // params defines the client parameters to update. + // + // NOTE: All parameters must be supplied. + Params params = 2 [(gogoproto.nullable) = false]; +} + +// MsgUpdateParamsResponse defines the MsgUpdateParams response type. +message MsgUpdateParamsResponse {} diff --git a/third_party/proto/ibc/commitment/v1/commitment.proto b/third_party/proto/ibc/commitment/v1/commitment.proto new file mode 100644 index 000000000..b4753be2d --- /dev/null +++ b/third_party/proto/ibc/commitment/v1/commitment.proto @@ -0,0 +1,39 @@ +syntax = "proto3"; + +package ibc.core.commitment.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/ics23/v1/proofs.proto"; + +// MerkleRoot defines a merkle root hash. +// In the Cosmos SDK, the AppHash of a block header becomes the root. +message MerkleRoot { + option (gogoproto.goproto_getters) = false; + + bytes hash = 1; +} + +// MerklePrefix is merkle path prefixed to the key. +// The constructed key from the Path and the key will be append(Path.KeyPath, +// append(Path.KeyPrefix, key...)) +message MerklePrefix { + bytes key_prefix = 1; +} + +// MerklePath is the path used to verify commitment proofs, which can be an +// arbitrary structured object (defined by a commitment type). +// MerklePath is represented from root-to-leaf +message MerklePath { + repeated string key_path = 1; +} + +// MerkleProof is a wrapper type over a chain of CommitmentProofs. +// It demonstrates membership or non-membership for an element or set of +// elements, verifiable in conjunction with a known commitment root. Proofs +// should be succinct. +// MerkleProofs are ordered from leaf-to-root +message MerkleProof { + repeated cosmos.ics23.v1.CommitmentProof proofs = 1; +} diff --git a/third_party/proto/ibc/connection/v1/connection.proto b/third_party/proto/ibc/connection/v1/connection.proto new file mode 100644 index 000000000..852f3999b --- /dev/null +++ b/third_party/proto/ibc/connection/v1/connection.proto @@ -0,0 +1,114 @@ +syntax = "proto3"; + +package ibc.core.connection.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types"; + +import "gogoproto/gogo.proto"; +import "ibc/core/commitment/v1/commitment.proto"; + +// ICS03 - Connection Data Structures as defined in +// https://github.com/cosmos/ibc/blob/master/spec/core/ics-003-connection-semantics#data-structures + +// ConnectionEnd defines a stateful object on a chain connected to another +// separate one. +// NOTE: there must only be 2 defined ConnectionEnds to establish +// a connection between two chains. +message ConnectionEnd { + option (gogoproto.goproto_getters) = false; + // client associated with this connection. + string client_id = 1; + // IBC version which can be utilised to determine encodings or protocols for + // channels or packets utilising this connection. + repeated Version versions = 2; + // current state of the connection end. + State state = 3; + // counterparty chain associated with this connection. + Counterparty counterparty = 4 [(gogoproto.nullable) = false]; + // delay period that must pass before a consensus state can be used for + // packet-verification NOTE: delay period logic is only implemented by some + // clients. + uint64 delay_period = 5; +} + +// IdentifiedConnection defines a connection with additional connection +// identifier field. +message IdentifiedConnection { + option (gogoproto.goproto_getters) = false; + // connection identifier. + string id = 1; + // client associated with this connection. + string client_id = 2; + // IBC version which can be utilised to determine encodings or protocols for + // channels or packets utilising this connection + repeated Version versions = 3; + // current state of the connection end. + State state = 4; + // counterparty chain associated with this connection. + Counterparty counterparty = 5 [(gogoproto.nullable) = false]; + // delay period associated with this connection. + uint64 delay_period = 6; +} + +// State defines if a connection is in one of the following states: +// INIT, TRYOPEN, OPEN or UNINITIALIZED. +enum State { + option (gogoproto.goproto_enum_prefix) = false; + + // Default State + STATE_UNINITIALIZED_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNINITIALIZED"]; + // A connection end has just started the opening handshake. + STATE_INIT = 1 [(gogoproto.enumvalue_customname) = "INIT"]; + // A connection end has acknowledged the handshake step on the counterparty + // chain. + STATE_TRYOPEN = 2 [(gogoproto.enumvalue_customname) = "TRYOPEN"]; + // A connection end has completed the handshake. + STATE_OPEN = 3 [(gogoproto.enumvalue_customname) = "OPEN"]; +} + +// Counterparty defines the counterparty chain associated with a connection end. +message Counterparty { + option (gogoproto.goproto_getters) = false; + + // identifies the client on the counterparty chain associated with a given + // connection. + string client_id = 1; + // identifies the connection end on the counterparty chain associated with a + // given connection. + string connection_id = 2; + // commitment merkle prefix of the counterparty chain. + ibc.core.commitment.v1.MerklePrefix prefix = 3 [(gogoproto.nullable) = false]; +} + +// ClientPaths define all the connection paths for a client state. +message ClientPaths { + // list of connection paths + repeated string paths = 1; +} + +// ConnectionPaths define all the connection paths for a given client state. +message ConnectionPaths { + // client state unique identifier + string client_id = 1; + // list of connection paths + repeated string paths = 2; +} + +// Version defines the versioning scheme used to negotiate the IBC verison in +// the connection handshake. +message Version { + option (gogoproto.goproto_getters) = false; + + // unique version identifier + string identifier = 1; + // list of features compatible with the specified identifier + repeated string features = 2; +} + +// Params defines the set of Connection parameters. +message Params { + // maximum expected time per block (in nanoseconds), used to enforce block delay. This parameter should reflect the + // largest amount of time that the chain might reasonably take to produce the next block under normal operating + // conditions. A safe choice is 3-5x the expected time per block. + uint64 max_expected_time_per_block = 1; +} diff --git a/third_party/proto/ibc/connection/v1/genesis.proto b/third_party/proto/ibc/connection/v1/genesis.proto new file mode 100644 index 000000000..a5eb6b3a1 --- /dev/null +++ b/third_party/proto/ibc/connection/v1/genesis.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +package ibc.core.connection.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types"; + +import "gogoproto/gogo.proto"; +import "ibc/core/connection/v1/connection.proto"; + +// GenesisState defines the ibc connection submodule's genesis state. +message GenesisState { + repeated IdentifiedConnection connections = 1 [(gogoproto.nullable) = false]; + repeated ConnectionPaths client_connection_paths = 2 [(gogoproto.nullable) = false]; + // the sequence for the next generated connection identifier + uint64 next_connection_sequence = 3; + Params params = 4 [(gogoproto.nullable) = false]; +} diff --git a/third_party/proto/ibc/connection/v1/query.proto b/third_party/proto/ibc/connection/v1/query.proto new file mode 100644 index 000000000..c0f1a6f57 --- /dev/null +++ b/third_party/proto/ibc/connection/v1/query.proto @@ -0,0 +1,152 @@ +syntax = "proto3"; + +package ibc.core.connection.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "ibc/core/client/v1/client.proto"; +import "ibc/core/connection/v1/connection.proto"; +import "google/api/annotations.proto"; +import "google/protobuf/any.proto"; + +// Query provides defines the gRPC querier service +service Query { + // Connection queries an IBC connection end. + rpc Connection(QueryConnectionRequest) returns (QueryConnectionResponse) { + option (google.api.http).get = "/ibc/core/connection/v1/connections/{connection_id}"; + } + + // Connections queries all the IBC connections of a chain. + rpc Connections(QueryConnectionsRequest) returns (QueryConnectionsResponse) { + option (google.api.http).get = "/ibc/core/connection/v1/connections"; + } + + // ClientConnections queries the connection paths associated with a client + // state. + rpc ClientConnections(QueryClientConnectionsRequest) returns (QueryClientConnectionsResponse) { + option (google.api.http).get = "/ibc/core/connection/v1/client_connections/{client_id}"; + } + + // ConnectionClientState queries the client state associated with the + // connection. + rpc ConnectionClientState(QueryConnectionClientStateRequest) returns (QueryConnectionClientStateResponse) { + option (google.api.http).get = "/ibc/core/connection/v1/connections/{connection_id}/client_state"; + } + + // ConnectionConsensusState queries the consensus state associated with the + // connection. + rpc ConnectionConsensusState(QueryConnectionConsensusStateRequest) returns (QueryConnectionConsensusStateResponse) { + option (google.api.http).get = "/ibc/core/connection/v1/connections/{connection_id}/consensus_state/" + "revision/{revision_number}/height/{revision_height}"; + } + + // ConnectionParams queries all parameters of the ibc connection submodule. + rpc ConnectionParams(QueryConnectionParamsRequest) returns (QueryConnectionParamsResponse) { + option (google.api.http).get = "/ibc/core/connection/v1/params"; + } +} + +// QueryConnectionRequest is the request type for the Query/Connection RPC +// method +message QueryConnectionRequest { + // connection unique identifier + string connection_id = 1; +} + +// QueryConnectionResponse is the response type for the Query/Connection RPC +// method. Besides the connection end, it includes a proof and the height from +// which the proof was retrieved. +message QueryConnectionResponse { + // connection associated with the request identifier + ibc.core.connection.v1.ConnectionEnd connection = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryConnectionsRequest is the request type for the Query/Connections RPC +// method +message QueryConnectionsRequest { + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryConnectionsResponse is the response type for the Query/Connections RPC +// method. +message QueryConnectionsResponse { + // list of stored connections of the chain. + repeated ibc.core.connection.v1.IdentifiedConnection connections = 1; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; + // query block height + ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; +} + +// QueryClientConnectionsRequest is the request type for the +// Query/ClientConnections RPC method +message QueryClientConnectionsRequest { + // client identifier associated with a connection + string client_id = 1; +} + +// QueryClientConnectionsResponse is the response type for the +// Query/ClientConnections RPC method +message QueryClientConnectionsResponse { + // slice of all the connection paths associated with a client. + repeated string connection_paths = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was generated + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryConnectionClientStateRequest is the request type for the +// Query/ConnectionClientState RPC method +message QueryConnectionClientStateRequest { + // connection identifier + string connection_id = 1; +} + +// QueryConnectionClientStateResponse is the response type for the +// Query/ConnectionClientState RPC method +message QueryConnectionClientStateResponse { + // client state associated with the channel + ibc.core.client.v1.IdentifiedClientState identified_client_state = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryConnectionConsensusStateRequest is the request type for the +// Query/ConnectionConsensusState RPC method +message QueryConnectionConsensusStateRequest { + // connection identifier + string connection_id = 1; + uint64 revision_number = 2; + uint64 revision_height = 3; +} + +// QueryConnectionConsensusStateResponse is the response type for the +// Query/ConnectionConsensusState RPC method +message QueryConnectionConsensusStateResponse { + // consensus state associated with the channel + google.protobuf.Any consensus_state = 1; + // client ID associated with the consensus state + string client_id = 2; + // merkle proof of existence + bytes proof = 3; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; +} + +// QueryConnectionParamsRequest is the request type for the Query/ConnectionParams RPC method. +message QueryConnectionParamsRequest {} + +// QueryConnectionParamsResponse is the response type for the Query/ConnectionParams RPC method. +message QueryConnectionParamsResponse { + // params defines the parameters of the module. + Params params = 1; +} \ No newline at end of file diff --git a/third_party/proto/ibc/connection/v1/tx.proto b/third_party/proto/ibc/connection/v1/tx.proto new file mode 100644 index 000000000..3ba8ff456 --- /dev/null +++ b/third_party/proto/ibc/connection/v1/tx.proto @@ -0,0 +1,146 @@ +syntax = "proto3"; + +package ibc.core.connection.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/msg/v1/msg.proto"; +import "google/protobuf/any.proto"; +import "ibc/core/client/v1/client.proto"; +import "ibc/core/connection/v1/connection.proto"; + +// Msg defines the ibc/connection Msg service. +service Msg { + option (cosmos.msg.v1.service) = true; + + // ConnectionOpenInit defines a rpc handler method for MsgConnectionOpenInit. + rpc ConnectionOpenInit(MsgConnectionOpenInit) returns (MsgConnectionOpenInitResponse); + + // ConnectionOpenTry defines a rpc handler method for MsgConnectionOpenTry. + rpc ConnectionOpenTry(MsgConnectionOpenTry) returns (MsgConnectionOpenTryResponse); + + // ConnectionOpenAck defines a rpc handler method for MsgConnectionOpenAck. + rpc ConnectionOpenAck(MsgConnectionOpenAck) returns (MsgConnectionOpenAckResponse); + + // ConnectionOpenConfirm defines a rpc handler method for + // MsgConnectionOpenConfirm. + rpc ConnectionOpenConfirm(MsgConnectionOpenConfirm) returns (MsgConnectionOpenConfirmResponse); + + // UpdateConnectionParams defines a rpc handler method for + // MsgUpdateParams. + rpc UpdateConnectionParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); +} + +// MsgConnectionOpenInit defines the msg sent by an account on Chain A to +// initialize a connection with Chain B. +message MsgConnectionOpenInit { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + string client_id = 1; + Counterparty counterparty = 2 [(gogoproto.nullable) = false]; + Version version = 3; + uint64 delay_period = 4; + string signer = 5; +} + +// MsgConnectionOpenInitResponse defines the Msg/ConnectionOpenInit response +// type. +message MsgConnectionOpenInitResponse {} + +// MsgConnectionOpenTry defines a msg sent by a Relayer to try to open a +// connection on Chain B. +message MsgConnectionOpenTry { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + string client_id = 1; + // Deprecated: this field is unused. Crossing hellos are no longer supported in core IBC. + string previous_connection_id = 2 [deprecated = true]; + google.protobuf.Any client_state = 3; + Counterparty counterparty = 4 [(gogoproto.nullable) = false]; + uint64 delay_period = 5; + repeated Version counterparty_versions = 6; + ibc.core.client.v1.Height proof_height = 7 [(gogoproto.nullable) = false]; + // proof of the initialization the connection on Chain A: `UNITIALIZED -> + // INIT` + bytes proof_init = 8; + // proof of client state included in message + bytes proof_client = 9; + // proof of client consensus state + bytes proof_consensus = 10; + ibc.core.client.v1.Height consensus_height = 11 [(gogoproto.nullable) = false]; + string signer = 12; + // optional proof data for host state machines that are unable to introspect their own consensus state + bytes host_consensus_state_proof = 13; +} + +// MsgConnectionOpenTryResponse defines the Msg/ConnectionOpenTry response type. +message MsgConnectionOpenTryResponse {} + +// MsgConnectionOpenAck defines a msg sent by a Relayer to Chain A to +// acknowledge the change of connection state to TRYOPEN on Chain B. +message MsgConnectionOpenAck { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + string connection_id = 1; + string counterparty_connection_id = 2; + Version version = 3; + google.protobuf.Any client_state = 4; + ibc.core.client.v1.Height proof_height = 5 [(gogoproto.nullable) = false]; + // proof of the initialization the connection on Chain B: `UNITIALIZED -> + // TRYOPEN` + bytes proof_try = 6; + // proof of client state included in message + bytes proof_client = 7; + // proof of client consensus state + bytes proof_consensus = 8; + ibc.core.client.v1.Height consensus_height = 9 [(gogoproto.nullable) = false]; + string signer = 10; + // optional proof data for host state machines that are unable to introspect their own consensus state + bytes host_consensus_state_proof = 11; +} + +// MsgConnectionOpenAckResponse defines the Msg/ConnectionOpenAck response type. +message MsgConnectionOpenAckResponse {} + +// MsgConnectionOpenConfirm defines a msg sent by a Relayer to Chain B to +// acknowledge the change of connection state to OPEN on Chain A. +message MsgConnectionOpenConfirm { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + string connection_id = 1; + // proof for the change of the connection state on Chain A: `INIT -> OPEN` + bytes proof_ack = 2; + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; + string signer = 4; +} + +// MsgConnectionOpenConfirmResponse defines the Msg/ConnectionOpenConfirm +// response type. +message MsgConnectionOpenConfirmResponse {} + +// MsgUpdateParams defines the sdk.Msg type to update the connection parameters. +message MsgUpdateParams { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + // signer address + string signer = 1; + + // params defines the connection parameters to update. + // + // NOTE: All parameters must be supplied. + Params params = 2 [(gogoproto.nullable) = false]; +} + +// MsgUpdateParamsResponse defines the MsgUpdateParams response type. +message MsgUpdateParamsResponse {} \ No newline at end of file diff --git a/third_party/proto/ibc/core/channel/v1/channel.proto b/third_party/proto/ibc/core/channel/v1/channel.proto index eb073fd18..05a18fefb 100644 --- a/third_party/proto/ibc/core/channel/v1/channel.proto +++ b/third_party/proto/ibc/core/channel/v1/channel.proto @@ -21,9 +21,12 @@ message Channel { Counterparty counterparty = 3 [(gogoproto.nullable) = false]; // list of connection identifiers, in order, along which packets sent on // this channel will travel - repeated string connection_hops = 4 [(gogoproto.moretags) = "yaml:\"connection_hops\""]; + repeated string connection_hops = 4; // opaque channel version, which is agreed upon during the handshake string version = 5; + // upgrade sequence indicates the latest upgrade attempt performed by this channel + // the value of 0 indicates the channel has never been upgraded + uint64 upgrade_sequence = 6; } // IdentifiedChannel defines a channel with additional port and channel @@ -39,17 +42,20 @@ message IdentifiedChannel { Counterparty counterparty = 3 [(gogoproto.nullable) = false]; // list of connection identifiers, in order, along which packets sent on // this channel will travel - repeated string connection_hops = 4 [(gogoproto.moretags) = "yaml:\"connection_hops\""]; + repeated string connection_hops = 4; // opaque channel version, which is agreed upon during the handshake string version = 5; // port identifier string port_id = 6; // channel identifier string channel_id = 7; + // upgrade sequence indicates the latest upgrade attempt performed by this channel + // the value of 0 indicates the channel has never been upgraded + uint64 upgrade_sequence = 8; } // State defines if a channel is in one of the following states: -// CLOSED, INIT, TRYOPEN, OPEN or UNINITIALIZED. +// CLOSED, INIT, TRYOPEN, OPEN, FLUSHING, FLUSHCOMPLETE or UNINITIALIZED. enum State { option (gogoproto.goproto_enum_prefix) = false; @@ -65,6 +71,10 @@ enum State { // A channel has been closed and can no longer be used to send or receive // packets. STATE_CLOSED = 4 [(gogoproto.enumvalue_customname) = "CLOSED"]; + // A channel has just accepted the upgrade handshake attempt and is flushing in-flight packets. + STATE_FLUSHING = 5 [(gogoproto.enumvalue_customname) = "FLUSHING"]; + // A channel has just completed flushing any in-flight packets. + STATE_FLUSHCOMPLETE = 6 [(gogoproto.enumvalue_customname) = "FLUSHCOMPLETE"]; } // Order defines if a channel is ORDERED or UNORDERED @@ -85,9 +95,9 @@ message Counterparty { option (gogoproto.goproto_getters) = false; // port on the counterparty chain which owns the other end of the channel. - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + string port_id = 1; // channel end on the counterparty chain - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + string channel_id = 2; } // Packet defines a type that carries data across different chains through IBC @@ -99,20 +109,19 @@ message Packet { // with a later sequence number. uint64 sequence = 1; // identifies the port on the sending chain. - string source_port = 2 [(gogoproto.moretags) = "yaml:\"source_port\""]; + string source_port = 2; // identifies the channel end on the sending chain. - string source_channel = 3 [(gogoproto.moretags) = "yaml:\"source_channel\""]; + string source_channel = 3; // identifies the port on the receiving chain. - string destination_port = 4 [(gogoproto.moretags) = "yaml:\"destination_port\""]; + string destination_port = 4; // identifies the channel end on the receiving chain. - string destination_channel = 5 [(gogoproto.moretags) = "yaml:\"destination_channel\""]; + string destination_channel = 5; // actual opaque bytes transferred directly to the application module bytes data = 6; // block height after which the packet times out - ibc.core.client.v1.Height timeout_height = 7 - [(gogoproto.moretags) = "yaml:\"timeout_height\"", (gogoproto.nullable) = false]; + ibc.core.client.v1.Height timeout_height = 7 [(gogoproto.nullable) = false]; // block timestamp (in nanoseconds) after which the packet times out - uint64 timeout_timestamp = 8 [(gogoproto.moretags) = "yaml:\"timeout_timestamp\""]; + uint64 timeout_timestamp = 8; } // PacketState defines the generic type necessary to retrieve and store @@ -123,9 +132,9 @@ message PacketState { option (gogoproto.goproto_getters) = false; // channel port identifier. - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + string port_id = 1; // channel unique identifier. - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + string channel_id = 2; // packet sequence. uint64 sequence = 3; // embedded data that represents packet state. @@ -139,9 +148,9 @@ message PacketId { option (gogoproto.goproto_getters) = false; // channel port identifier - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + string port_id = 1; // channel unique identifier - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + string channel_id = 2; // packet sequence uint64 sequence = 3; } @@ -160,3 +169,19 @@ message Acknowledgement { string error = 22; } } + +// Timeout defines an execution deadline structure for 04-channel handlers. +// This includes packet lifecycle handlers as well as the upgrade handshake handlers. +// A valid Timeout contains either one or both of a timestamp and block height (sequence). +message Timeout { + // block height after which the packet or upgrade times out + ibc.core.client.v1.Height height = 1 [(gogoproto.nullable) = false]; + // block timestamp (in nanoseconds) after which the packet or upgrade times out + uint64 timestamp = 2; +} + +// Params defines the set of IBC channel parameters. +message Params { + // the relative timeout after which channel upgrades will time out. + Timeout upgrade_timeout = 1 [(gogoproto.nullable) = false]; +} diff --git a/third_party/proto/ibc/core/channel/v1/genesis.proto b/third_party/proto/ibc/core/channel/v1/genesis.proto index 813e98f36..665b2b156 100644 --- a/third_party/proto/ibc/core/channel/v1/genesis.proto +++ b/third_party/proto/ibc/core/channel/v1/genesis.proto @@ -13,20 +13,18 @@ message GenesisState { repeated PacketState acknowledgements = 2 [(gogoproto.nullable) = false]; repeated PacketState commitments = 3 [(gogoproto.nullable) = false]; repeated PacketState receipts = 4 [(gogoproto.nullable) = false]; - repeated PacketSequence send_sequences = 5 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"send_sequences\""]; - repeated PacketSequence recv_sequences = 6 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"recv_sequences\""]; - repeated PacketSequence ack_sequences = 7 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"ack_sequences\""]; + repeated PacketSequence send_sequences = 5 [(gogoproto.nullable) = false]; + repeated PacketSequence recv_sequences = 6 [(gogoproto.nullable) = false]; + repeated PacketSequence ack_sequences = 7 [(gogoproto.nullable) = false]; // the sequence for the next generated channel identifier - uint64 next_channel_sequence = 8 [(gogoproto.moretags) = "yaml:\"next_channel_sequence\""]; + uint64 next_channel_sequence = 8; + Params params = 9 [(gogoproto.nullable) = false]; } // PacketSequence defines the genesis type necessary to retrieve and store // next send and receive sequences. message PacketSequence { - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + string port_id = 1; + string channel_id = 2; uint64 sequence = 3; } diff --git a/third_party/proto/ibc/core/channel/v1/query.proto b/third_party/proto/ibc/core/channel/v1/query.proto index 0170a2aac..f89d21273 100644 --- a/third_party/proto/ibc/core/channel/v1/query.proto +++ b/third_party/proto/ibc/core/channel/v1/query.proto @@ -10,6 +10,7 @@ import "ibc/core/channel/v1/channel.proto"; import "google/api/annotations.proto"; import "google/protobuf/any.proto"; import "gogoproto/gogo.proto"; +import "ibc/core/channel/v1/upgrade.proto"; // Query provides defines the gRPC querier service service Query { @@ -98,6 +99,29 @@ service Query { option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" "ports/{port_id}/next_sequence"; } + + // NextSequenceSend returns the next send sequence for a given channel. + rpc NextSequenceSend(QueryNextSequenceSendRequest) returns (QueryNextSequenceSendResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/next_sequence_send"; + } + + // UpgradeError returns the error receipt if the upgrade handshake failed. + rpc UpgradeError(QueryUpgradeErrorRequest) returns (QueryUpgradeErrorResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/upgrade_error"; + } + + // Upgrade returns the upgrade for a given port and channel id. + rpc Upgrade(QueryUpgradeRequest) returns (QueryUpgradeResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/upgrade"; + } + + // ChannelParams queries all parameters of the ibc channel submodule. + rpc ChannelParams(QueryChannelParamsRequest) returns (QueryChannelParamsResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/params"; + } } // QueryChannelRequest is the request type for the Query/Channel RPC method @@ -364,7 +388,7 @@ message QueryNextSequenceReceiveRequest { string channel_id = 2; } -// QuerySequenceResponse is the request type for the +// QuerySequenceResponse is the response type for the // Query/QueryNextSequenceReceiveResponse RPC method message QueryNextSequenceReceiveResponse { // next sequence receive number @@ -374,3 +398,62 @@ message QueryNextSequenceReceiveResponse { // height at which the proof was retrieved ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; } + +// QueryNextSequenceSendRequest is the request type for the +// Query/QueryNextSequenceSend RPC method +message QueryNextSequenceSendRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; +} + +// QueryNextSequenceSendResponse is the request type for the +// Query/QueryNextSequenceSend RPC method +message QueryNextSequenceSendResponse { + // next sequence send number + uint64 next_sequence_send = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryUpgradeErrorRequest is the request type for the Query/QueryUpgradeError RPC method +message QueryUpgradeErrorRequest { + string port_id = 1; + string channel_id = 2; +} + +// QueryUpgradeErrorResponse is the response type for the Query/QueryUpgradeError RPC method +message QueryUpgradeErrorResponse { + ErrorReceipt error_receipt = 1 [(gogoproto.nullable) = false]; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryUpgradeRequest is the request type for the QueryUpgradeRequest RPC method +message QueryUpgradeRequest { + string port_id = 1; + string channel_id = 2; +} + +// QueryUpgradeResponse is the response type for the QueryUpgradeResponse RPC method +message QueryUpgradeResponse { + Upgrade upgrade = 1 [(gogoproto.nullable) = false]; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryChannelParamsRequest is the request type for the Query/ChannelParams RPC method. +message QueryChannelParamsRequest {} + +// QueryChannelParamsResponse is the response type for the Query/ChannelParams RPC method. +message QueryChannelParamsResponse { + // params defines the parameters of the module. + Params params = 1; +} \ No newline at end of file diff --git a/third_party/proto/ibc/core/channel/v1/tx.proto b/third_party/proto/ibc/core/channel/v1/tx.proto index d0918eaff..3f30e8b8c 100644 --- a/third_party/proto/ibc/core/channel/v1/tx.proto +++ b/third_party/proto/ibc/core/channel/v1/tx.proto @@ -5,11 +5,15 @@ package ibc.core.channel.v1; option go_package = "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"; import "gogoproto/gogo.proto"; +import "cosmos/msg/v1/msg.proto"; import "ibc/core/client/v1/client.proto"; import "ibc/core/channel/v1/channel.proto"; +import "ibc/core/channel/v1/upgrade.proto"; // Msg defines the ibc/channel Msg service. service Msg { + option (cosmos.msg.v1.service) = true; + // ChannelOpenInit defines a rpc handler method for MsgChannelOpenInit. rpc ChannelOpenInit(MsgChannelOpenInit) returns (MsgChannelOpenInitResponse); @@ -40,6 +44,33 @@ service Msg { // Acknowledgement defines a rpc handler method for MsgAcknowledgement. rpc Acknowledgement(MsgAcknowledgement) returns (MsgAcknowledgementResponse); + + // ChannelUpgradeInit defines a rpc handler method for MsgChannelUpgradeInit. + rpc ChannelUpgradeInit(MsgChannelUpgradeInit) returns (MsgChannelUpgradeInitResponse); + + // ChannelUpgradeTry defines a rpc handler method for MsgChannelUpgradeTry. + rpc ChannelUpgradeTry(MsgChannelUpgradeTry) returns (MsgChannelUpgradeTryResponse); + + // ChannelUpgradeAck defines a rpc handler method for MsgChannelUpgradeAck. + rpc ChannelUpgradeAck(MsgChannelUpgradeAck) returns (MsgChannelUpgradeAckResponse); + + // ChannelUpgradeConfirm defines a rpc handler method for MsgChannelUpgradeConfirm. + rpc ChannelUpgradeConfirm(MsgChannelUpgradeConfirm) returns (MsgChannelUpgradeConfirmResponse); + + // ChannelUpgradeOpen defines a rpc handler method for MsgChannelUpgradeOpen. + rpc ChannelUpgradeOpen(MsgChannelUpgradeOpen) returns (MsgChannelUpgradeOpenResponse); + + // ChannelUpgradeTimeout defines a rpc handler method for MsgChannelUpgradeTimeout. + rpc ChannelUpgradeTimeout(MsgChannelUpgradeTimeout) returns (MsgChannelUpgradeTimeoutResponse); + + // ChannelUpgradeCancel defines a rpc handler method for MsgChannelUpgradeCancel. + rpc ChannelUpgradeCancel(MsgChannelUpgradeCancel) returns (MsgChannelUpgradeCancelResponse); + + // UpdateChannelParams defines a rpc handler method for MsgUpdateParams. + rpc UpdateChannelParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); + + // PruneAcknowledgements defines a rpc handler method for MsgPruneAcknowledgements. + rpc PruneAcknowledgements(MsgPruneAcknowledgements) returns (MsgPruneAcknowledgementsResponse); } // ResponseResultType defines the possible outcomes of the execution of a message @@ -52,22 +83,27 @@ enum ResponseResultType { RESPONSE_RESULT_TYPE_NOOP = 1 [(gogoproto.enumvalue_customname) = "NOOP"]; // The message was executed successfully RESPONSE_RESULT_TYPE_SUCCESS = 2 [(gogoproto.enumvalue_customname) = "SUCCESS"]; + // The message was executed unsuccessfully + RESPONSE_RESULT_TYPE_FAILURE = 3 [(gogoproto.enumvalue_customname) = "FAILURE"]; } // MsgChannelOpenInit defines an sdk.Msg to initialize a channel handshake. It // is called by a relayer on Chain A. message MsgChannelOpenInit { - option (gogoproto.equal) = false; + option (cosmos.msg.v1.signer) = "signer"; + option (gogoproto.goproto_getters) = false; - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + string port_id = 1; Channel channel = 2 [(gogoproto.nullable) = false]; string signer = 3; } // MsgChannelOpenInitResponse defines the Msg/ChannelOpenInit response type. message MsgChannelOpenInitResponse { - string channel_id = 1 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + option (gogoproto.goproto_getters) = false; + + string channel_id = 1; string version = 2; } @@ -75,41 +111,46 @@ message MsgChannelOpenInitResponse { // on Chain B. The version field within the Channel field has been deprecated. Its // value will be ignored by core IBC. message MsgChannelOpenTry { - option (gogoproto.equal) = false; + option (cosmos.msg.v1.signer) = "signer"; + option (gogoproto.goproto_getters) = false; - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + string port_id = 1; // Deprecated: this field is unused. Crossing hello's are no longer supported in core IBC. - string previous_channel_id = 2 [deprecated = true, (gogoproto.moretags) = "yaml:\"previous_channel_id\""]; + string previous_channel_id = 2 [deprecated = true]; // NOTE: the version field within the channel has been deprecated. Its value will be ignored by core IBC. Channel channel = 3 [(gogoproto.nullable) = false]; - string counterparty_version = 4 [(gogoproto.moretags) = "yaml:\"counterparty_version\""]; - bytes proof_init = 5 [(gogoproto.moretags) = "yaml:\"proof_init\""]; - ibc.core.client.v1.Height proof_height = 6 - [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; - string signer = 7; + string counterparty_version = 4; + bytes proof_init = 5; + ibc.core.client.v1.Height proof_height = 6 [(gogoproto.nullable) = false]; + string signer = 7; } // MsgChannelOpenTryResponse defines the Msg/ChannelOpenTry response type. message MsgChannelOpenTryResponse { + option (gogoproto.goproto_getters) = false; + string version = 1; - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + string channel_id = 2; } // MsgChannelOpenAck defines a msg sent by a Relayer to Chain A to acknowledge // the change of channel state to TRYOPEN on Chain B. +// WARNING: a channel upgrade MUST NOT initialize an upgrade for this channel +// in the same block as executing this message otherwise the counterparty will +// be incapable of opening. message MsgChannelOpenAck { - option (gogoproto.equal) = false; + option (cosmos.msg.v1.signer) = "signer"; + option (gogoproto.goproto_getters) = false; - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; - string counterparty_channel_id = 3 [(gogoproto.moretags) = "yaml:\"counterparty_channel_id\""]; - string counterparty_version = 4 [(gogoproto.moretags) = "yaml:\"counterparty_version\""]; - bytes proof_try = 5 [(gogoproto.moretags) = "yaml:\"proof_try\""]; - ibc.core.client.v1.Height proof_height = 6 - [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; - string signer = 7; + string port_id = 1; + string channel_id = 2; + string counterparty_channel_id = 3; + string counterparty_version = 4; + bytes proof_try = 5; + ibc.core.client.v1.Height proof_height = 6 [(gogoproto.nullable) = false]; + string signer = 7; } // MsgChannelOpenAckResponse defines the Msg/ChannelOpenAck response type. @@ -118,15 +159,15 @@ message MsgChannelOpenAckResponse {} // MsgChannelOpenConfirm defines a msg sent by a Relayer to Chain B to // acknowledge the change of channel state to OPEN on Chain A. message MsgChannelOpenConfirm { - option (gogoproto.equal) = false; + option (cosmos.msg.v1.signer) = "signer"; + option (gogoproto.goproto_getters) = false; - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; - bytes proof_ack = 3 [(gogoproto.moretags) = "yaml:\"proof_ack\""]; - ibc.core.client.v1.Height proof_height = 4 - [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; - string signer = 5; + string port_id = 1; + string channel_id = 2; + bytes proof_ack = 3; + ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; + string signer = 5; } // MsgChannelOpenConfirmResponse defines the Msg/ChannelOpenConfirm response @@ -136,11 +177,12 @@ message MsgChannelOpenConfirmResponse {} // MsgChannelCloseInit defines a msg sent by a Relayer to Chain A // to close a channel with Chain B. message MsgChannelCloseInit { - option (gogoproto.equal) = false; + option (cosmos.msg.v1.signer) = "signer"; + option (gogoproto.goproto_getters) = false; - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + string port_id = 1; + string channel_id = 2; string signer = 3; } @@ -150,15 +192,16 @@ message MsgChannelCloseInitResponse {} // MsgChannelCloseConfirm defines a msg sent by a Relayer to Chain B // to acknowledge the change of channel state to CLOSED on Chain A. message MsgChannelCloseConfirm { - option (gogoproto.equal) = false; + option (cosmos.msg.v1.signer) = "signer"; + option (gogoproto.goproto_getters) = false; - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; - bytes proof_init = 3 [(gogoproto.moretags) = "yaml:\"proof_init\""]; - ibc.core.client.v1.Height proof_height = 4 - [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; - string signer = 5; + string port_id = 1; + string channel_id = 2; + bytes proof_init = 3; + ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; + string signer = 5; + uint64 counterparty_upgrade_sequence = 6; } // MsgChannelCloseConfirmResponse defines the Msg/ChannelCloseConfirm response @@ -167,14 +210,14 @@ message MsgChannelCloseConfirmResponse {} // MsgRecvPacket receives incoming IBC packet message MsgRecvPacket { - option (gogoproto.equal) = false; + option (cosmos.msg.v1.signer) = "signer"; + option (gogoproto.goproto_getters) = false; Packet packet = 1 [(gogoproto.nullable) = false]; - bytes proof_commitment = 2 [(gogoproto.moretags) = "yaml:\"proof_commitment\""]; - ibc.core.client.v1.Height proof_height = 3 - [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; - string signer = 4; + bytes proof_commitment = 2; + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; + string signer = 4; } // MsgRecvPacketResponse defines the Msg/RecvPacket response type. @@ -186,15 +229,15 @@ message MsgRecvPacketResponse { // MsgTimeout receives timed-out packet message MsgTimeout { - option (gogoproto.equal) = false; + option (cosmos.msg.v1.signer) = "signer"; + option (gogoproto.goproto_getters) = false; - Packet packet = 1 [(gogoproto.nullable) = false]; - bytes proof_unreceived = 2 [(gogoproto.moretags) = "yaml:\"proof_unreceived\""]; - ibc.core.client.v1.Height proof_height = 3 - [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; - uint64 next_sequence_recv = 4 [(gogoproto.moretags) = "yaml:\"next_sequence_recv\""]; - string signer = 5; + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes proof_unreceived = 2; + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; + uint64 next_sequence_recv = 4; + string signer = 5; } // MsgTimeoutResponse defines the Msg/Timeout response type. @@ -206,16 +249,17 @@ message MsgTimeoutResponse { // MsgTimeoutOnClose timed-out packet upon counterparty channel closure. message MsgTimeoutOnClose { - option (gogoproto.equal) = false; + option (cosmos.msg.v1.signer) = "signer"; + option (gogoproto.goproto_getters) = false; - Packet packet = 1 [(gogoproto.nullable) = false]; - bytes proof_unreceived = 2 [(gogoproto.moretags) = "yaml:\"proof_unreceived\""]; - bytes proof_close = 3 [(gogoproto.moretags) = "yaml:\"proof_close\""]; - ibc.core.client.v1.Height proof_height = 4 - [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; - uint64 next_sequence_recv = 5 [(gogoproto.moretags) = "yaml:\"next_sequence_recv\""]; - string signer = 6; + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes proof_unreceived = 2; + bytes proof_close = 3; + ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; + uint64 next_sequence_recv = 5; + string signer = 6; + uint64 counterparty_upgrade_sequence = 7; } // MsgTimeoutOnCloseResponse defines the Msg/TimeoutOnClose response type. @@ -227,15 +271,15 @@ message MsgTimeoutOnCloseResponse { // MsgAcknowledgement receives incoming IBC acknowledgement message MsgAcknowledgement { - option (gogoproto.equal) = false; + option (cosmos.msg.v1.signer) = "signer"; + option (gogoproto.goproto_getters) = false; Packet packet = 1 [(gogoproto.nullable) = false]; bytes acknowledgement = 2; - bytes proof_acked = 3 [(gogoproto.moretags) = "yaml:\"proof_acked\""]; - ibc.core.client.v1.Height proof_height = 4 - [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; - string signer = 5; + bytes proof_acked = 3; + ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; + string signer = 5; } // MsgAcknowledgementResponse defines the Msg/Acknowledgement response type. @@ -244,3 +288,182 @@ message MsgAcknowledgementResponse { ResponseResultType result = 1; } + +// MsgChannelUpgradeInit defines the request type for the ChannelUpgradeInit rpc +// WARNING: Initializing a channel upgrade in the same block as opening the channel +// may result in the counterparty being incapable of opening. +message MsgChannelUpgradeInit { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + string port_id = 1; + string channel_id = 2; + UpgradeFields fields = 3 [(gogoproto.nullable) = false]; + string signer = 4; +} + +// MsgChannelUpgradeInitResponse defines the MsgChannelUpgradeInit response type +message MsgChannelUpgradeInitResponse { + option (gogoproto.goproto_getters) = false; + + Upgrade upgrade = 1 [(gogoproto.nullable) = false]; + uint64 upgrade_sequence = 2; +} + +// MsgChannelUpgradeTry defines the request type for the ChannelUpgradeTry rpc +message MsgChannelUpgradeTry { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + string port_id = 1; + string channel_id = 2; + repeated string proposed_upgrade_connection_hops = 3; + UpgradeFields counterparty_upgrade_fields = 4 [(gogoproto.nullable) = false]; + uint64 counterparty_upgrade_sequence = 5; + bytes proof_channel = 6; + bytes proof_upgrade = 7; + ibc.core.client.v1.Height proof_height = 8 [(gogoproto.nullable) = false]; + string signer = 9; +} + +// MsgChannelUpgradeTryResponse defines the MsgChannelUpgradeTry response type +message MsgChannelUpgradeTryResponse { + option (gogoproto.goproto_getters) = false; + + Upgrade upgrade = 1 [(gogoproto.nullable) = false]; + uint64 upgrade_sequence = 2; + ResponseResultType result = 3; +} + +// MsgChannelUpgradeAck defines the request type for the ChannelUpgradeAck rpc +message MsgChannelUpgradeAck { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + string port_id = 1; + string channel_id = 2; + Upgrade counterparty_upgrade = 3 [(gogoproto.nullable) = false]; + bytes proof_channel = 4; + bytes proof_upgrade = 5; + ibc.core.client.v1.Height proof_height = 6 [(gogoproto.nullable) = false]; + string signer = 7; +} + +// MsgChannelUpgradeAckResponse defines MsgChannelUpgradeAck response type +message MsgChannelUpgradeAckResponse { + option (gogoproto.goproto_getters) = false; + + ResponseResultType result = 1; +} + +// MsgChannelUpgradeConfirm defines the request type for the ChannelUpgradeConfirm rpc +message MsgChannelUpgradeConfirm { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + string port_id = 1; + string channel_id = 2; + State counterparty_channel_state = 3; + Upgrade counterparty_upgrade = 4 [(gogoproto.nullable) = false]; + bytes proof_channel = 5; + bytes proof_upgrade = 6; + ibc.core.client.v1.Height proof_height = 7 [(gogoproto.nullable) = false]; + string signer = 8; +} + +// MsgChannelUpgradeConfirmResponse defines MsgChannelUpgradeConfirm response type +message MsgChannelUpgradeConfirmResponse { + option (gogoproto.goproto_getters) = false; + + ResponseResultType result = 1; +} + +// MsgChannelUpgradeOpen defines the request type for the ChannelUpgradeOpen rpc +message MsgChannelUpgradeOpen { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + string port_id = 1; + string channel_id = 2; + State counterparty_channel_state = 3; + uint64 counterparty_upgrade_sequence = 4; + bytes proof_channel = 5; + ibc.core.client.v1.Height proof_height = 6 [(gogoproto.nullable) = false]; + string signer = 7; +} + +// MsgChannelUpgradeOpenResponse defines the MsgChannelUpgradeOpen response type +message MsgChannelUpgradeOpenResponse {} + +// MsgChannelUpgradeTimeout defines the request type for the ChannelUpgradeTimeout rpc +message MsgChannelUpgradeTimeout { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + string port_id = 1; + string channel_id = 2; + Channel counterparty_channel = 3 [(gogoproto.nullable) = false]; + bytes proof_channel = 4; + ibc.core.client.v1.Height proof_height = 5 [(gogoproto.nullable) = false]; + string signer = 6; +} + +// MsgChannelUpgradeTimeoutRepsonse defines the MsgChannelUpgradeTimeout response type +message MsgChannelUpgradeTimeoutResponse {} + +// MsgChannelUpgradeCancel defines the request type for the ChannelUpgradeCancel rpc +message MsgChannelUpgradeCancel { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + string port_id = 1; + string channel_id = 2; + ErrorReceipt error_receipt = 3 [(gogoproto.nullable) = false]; + bytes proof_error_receipt = 4; + ibc.core.client.v1.Height proof_height = 5 [(gogoproto.nullable) = false]; + string signer = 6; +} + +// MsgChannelUpgradeCancelResponse defines the MsgChannelUpgradeCancel response type +message MsgChannelUpgradeCancelResponse {} + +// MsgUpdateParams is the MsgUpdateParams request type. +message MsgUpdateParams { + option (cosmos.msg.v1.signer) = "authority"; + + option (gogoproto.goproto_getters) = false; + + // authority is the address that controls the module (defaults to x/gov unless overwritten). + string authority = 1; + + // params defines the channel parameters to update. + // + // NOTE: All parameters must be supplied. + Params params = 2 [(gogoproto.nullable) = false]; +} + +// MsgUpdateParamsResponse defines the MsgUpdateParams response type. +message MsgUpdateParamsResponse {} + +// MsgPruneAcknowledgements defines the request type for the PruneAcknowledgements rpc. +message MsgPruneAcknowledgements { + option (cosmos.msg.v1.signer) = "signer"; + option (gogoproto.goproto_getters) = false; + + string port_id = 1; + string channel_id = 2; + uint64 limit = 3; + string signer = 4; +} + +// MsgPruneAcknowledgementsResponse defines the response type for the PruneAcknowledgements rpc. +message MsgPruneAcknowledgementsResponse { + // Number of sequences pruned (includes both packet acknowledgements and packet receipts where appropriate). + uint64 total_pruned_sequences = 1; + // Number of sequences left after pruning. + uint64 total_remaining_sequences = 2; +} diff --git a/third_party/proto/ibc/core/channel/v1/upgrade.proto b/third_party/proto/ibc/core/channel/v1/upgrade.proto new file mode 100644 index 000000000..81530ed2a --- /dev/null +++ b/third_party/proto/ibc/core/channel/v1/upgrade.proto @@ -0,0 +1,43 @@ +syntax = "proto3"; + +package ibc.core.channel.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"; + +import "gogoproto/gogo.proto"; +import "ibc/core/channel/v1/channel.proto"; + +// Upgrade is a verifiable type which contains the relevant information +// for an attempted upgrade. It provides the proposed changes to the channel +// end, the timeout for this upgrade attempt and the next packet sequence +// which allows the counterparty to efficiently know the highest sequence it has received. +// The next sequence send is used for pruning and upgrading from unordered to ordered channels. +message Upgrade { + option (gogoproto.goproto_getters) = false; + + UpgradeFields fields = 1 [(gogoproto.nullable) = false]; + Timeout timeout = 2 [(gogoproto.nullable) = false]; + uint64 next_sequence_send = 3; +} + +// UpgradeFields are the fields in a channel end which may be changed +// during a channel upgrade. +message UpgradeFields { + option (gogoproto.goproto_getters) = false; + + Order ordering = 1; + repeated string connection_hops = 2; + string version = 3; +} + +// ErrorReceipt defines a type which encapsulates the upgrade sequence and error associated with the +// upgrade handshake failure. When a channel upgrade handshake is aborted both chains are expected to increment to the +// next sequence. +message ErrorReceipt { + option (gogoproto.goproto_getters) = false; + + // the channel upgrade sequence + uint64 sequence = 1; + // the error message detailing the cause of failure + string message = 2; +} diff --git a/third_party/proto/ibc/core/client/v1/client.proto b/third_party/proto/ibc/core/client/v1/client.proto index b9f6b1ca1..7a09e360a 100644 --- a/third_party/proto/ibc/core/client/v1/client.proto +++ b/third_party/proto/ibc/core/client/v1/client.proto @@ -4,18 +4,18 @@ package ibc.core.client.v1; option go_package = "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"; -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; import "cosmos/upgrade/v1beta1/upgrade.proto"; import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; // IdentifiedClientState defines a client state with an additional client // identifier field. message IdentifiedClientState { // client identifier - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + string client_id = 1; // client state - google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""]; + google.protobuf.Any client_state = 2; } // ConsensusStateWithHeight defines a consensus state with an additional height @@ -24,26 +24,58 @@ message ConsensusStateWithHeight { // consensus state height Height height = 1 [(gogoproto.nullable) = false]; // consensus state - google.protobuf.Any consensus_state = 2 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; + google.protobuf.Any consensus_state = 2; } // ClientConsensusStates defines all the stored consensus states for a given // client. message ClientConsensusStates { // client identifier - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + string client_id = 1; // consensus states and their heights associated with the client - repeated ConsensusStateWithHeight consensus_states = 2 - [(gogoproto.moretags) = "yaml:\"consensus_states\"", (gogoproto.nullable) = false]; + repeated ConsensusStateWithHeight consensus_states = 2 [(gogoproto.nullable) = false]; +} + +// Height is a monotonically increasing data type +// that can be compared against another Height for the purposes of updating and +// freezing clients +// +// Normally the RevisionHeight is incremented at each height while keeping +// RevisionNumber the same. However some consensus algorithms may choose to +// reset the height in certain conditions e.g. hard forks, state-machine +// breaking changes In these cases, the RevisionNumber is incremented so that +// height continues to be monitonically increasing even as the RevisionHeight +// gets reset +message Height { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + // the revision that the client is currently on + uint64 revision_number = 1; + // the height within the given revision + uint64 revision_height = 2; +} + +// Params defines the set of IBC light client parameters. +message Params { + // allowed_clients defines the list of allowed client state types which can be created + // and interacted with. If a client type is removed from the allowed clients list, usage + // of this client will be disabled until it is added again to the list. + repeated string allowed_clients = 1; } -// ClientUpdateProposal is a governance proposal. If it passes, the substitute +// ClientUpdateProposal is a legacy governance proposal. If it passes, the substitute // client's latest consensus state is copied over to the subject client. The proposal // handler may fail if the subject and the substitute do not match in client and // chain parameters (with exception to latest height, frozen height, and chain-id). +// +// Deprecated: Please use MsgRecoverClient in favour of this message type. message ClientUpdateProposal { - option (gogoproto.goproto_getters) = false; + option deprecated = true; + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + option (gogoproto.goproto_getters) = false; + // the title of the update proposal string title = 1; // the description of the proposal @@ -57,11 +89,15 @@ message ClientUpdateProposal { // UpgradeProposal is a gov Content type for initiating an IBC breaking // upgrade. +// +// Deprecated: Please use MsgIBCSoftwareUpgrade in favour of this message type. message UpgradeProposal { + option deprecated = true; + + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; option (gogoproto.goproto_getters) = false; option (gogoproto.goproto_stringer) = false; option (gogoproto.equal) = true; - option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; string title = 1; string description = 2; @@ -75,31 +111,3 @@ message UpgradeProposal { // planned chain upgrades google.protobuf.Any upgraded_client_state = 4 [(gogoproto.moretags) = "yaml:\"upgraded_client_state\""]; } - -// Height is a monotonically increasing data type -// that can be compared against another Height for the purposes of updating and -// freezing clients -// -// Normally the RevisionHeight is incremented at each height while keeping -// RevisionNumber the same. However some consensus algorithms may choose to -// reset the height in certain conditions e.g. hard forks, state-machine -// breaking changes In these cases, the RevisionNumber is incremented so that -// height continues to be monitonically increasing even as the RevisionHeight -// gets reset -message Height { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - - // the revision that the client is currently on - uint64 revision_number = 1 [(gogoproto.moretags) = "yaml:\"revision_number\""]; - // the height within the given revision - uint64 revision_height = 2 [(gogoproto.moretags) = "yaml:\"revision_height\""]; -} - -// Params defines the set of IBC light client parameters. -message Params { - // allowed_clients defines the list of allowed client state types which can be created - // and interacted with. If a client type is removed from the allowed clients list, usage - // of this client will be disabled until it is added again to the list. - repeated string allowed_clients = 1 [(gogoproto.moretags) = "yaml:\"allowed_clients\""]; -} diff --git a/third_party/proto/ibc/core/client/v1/genesis.proto b/third_party/proto/ibc/core/client/v1/genesis.proto index b09ff1eaf..43610b0d4 100644 --- a/third_party/proto/ibc/core/client/v1/genesis.proto +++ b/third_party/proto/ibc/core/client/v1/genesis.proto @@ -13,19 +13,16 @@ message GenesisState { repeated IdentifiedClientState clients = 1 [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "IdentifiedClientStates"]; // consensus states from each client - repeated ClientConsensusStates clients_consensus = 2 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "ClientsConsensusStates", - (gogoproto.moretags) = "yaml:\"clients_consensus\"" - ]; + repeated ClientConsensusStates clients_consensus = 2 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "ClientsConsensusStates"]; // metadata from each client - repeated IdentifiedGenesisMetadata clients_metadata = 3 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"clients_metadata\""]; - Params params = 4 [(gogoproto.nullable) = false]; - // create localhost on initialization - bool create_localhost = 5 [(gogoproto.moretags) = "yaml:\"create_localhost\""]; + repeated IdentifiedGenesisMetadata clients_metadata = 3 [(gogoproto.nullable) = false]; + Params params = 4 [(gogoproto.nullable) = false]; + // Deprecated: create_localhost has been deprecated. + // The localhost client is automatically created at genesis. + bool create_localhost = 5 [deprecated = true]; // the sequence for the next generated client identifier - uint64 next_client_sequence = 6 [(gogoproto.moretags) = "yaml:\"next_client_sequence\""]; + uint64 next_client_sequence = 6; } // GenesisMetadata defines the genesis type for metadata that clients may return @@ -42,7 +39,6 @@ message GenesisMetadata { // IdentifiedGenesisMetadata has the client metadata with the corresponding // client id. message IdentifiedGenesisMetadata { - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - repeated GenesisMetadata client_metadata = 2 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"client_metadata\""]; + string client_id = 1; + repeated GenesisMetadata client_metadata = 2 [(gogoproto.nullable) = false]; } diff --git a/third_party/proto/ibc/core/client/v1/tx.proto b/third_party/proto/ibc/core/client/v1/tx.proto index 752718c11..b504ab692 100644 --- a/third_party/proto/ibc/core/client/v1/tx.proto +++ b/third_party/proto/ibc/core/client/v1/tx.proto @@ -4,11 +4,16 @@ package ibc.core.client.v1; option go_package = "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"; +import "cosmos/msg/v1/msg.proto"; +import "cosmos/upgrade/v1beta1/upgrade.proto"; import "gogoproto/gogo.proto"; import "google/protobuf/any.proto"; +import "ibc/core/client/v1/client.proto"; // Msg defines the ibc/client Msg service. service Msg { + option (cosmos.msg.v1.service) = true; + // CreateClient defines a rpc handler method for MsgCreateClient. rpc CreateClient(MsgCreateClient) returns (MsgCreateClientResponse); @@ -20,18 +25,28 @@ service Msg { // SubmitMisbehaviour defines a rpc handler method for MsgSubmitMisbehaviour. rpc SubmitMisbehaviour(MsgSubmitMisbehaviour) returns (MsgSubmitMisbehaviourResponse); + + // RecoverClient defines a rpc handler method for MsgRecoverClient. + rpc RecoverClient(MsgRecoverClient) returns (MsgRecoverClientResponse); + + // IBCSoftwareUpgrade defines a rpc handler method for MsgIBCSoftwareUpgrade. + rpc IBCSoftwareUpgrade(MsgIBCSoftwareUpgrade) returns (MsgIBCSoftwareUpgradeResponse); + + // UpdateClientParams defines a rpc handler method for MsgUpdateParams. + rpc UpdateClientParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); } // MsgCreateClient defines a message to create an IBC client message MsgCreateClient { - option (gogoproto.equal) = false; + option (cosmos.msg.v1.signer) = "signer"; + option (gogoproto.goproto_getters) = false; // light client state - google.protobuf.Any client_state = 1 [(gogoproto.moretags) = "yaml:\"client_state\""]; + google.protobuf.Any client_state = 1; // consensus state associated with the client that corresponds to a given // height. - google.protobuf.Any consensus_state = 2 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; + google.protobuf.Any consensus_state = 2; // signer address string signer = 3; } @@ -42,11 +57,12 @@ message MsgCreateClientResponse {} // MsgUpdateClient defines an sdk.Msg to update a IBC client state using // the given client message. message MsgUpdateClient { - option (gogoproto.equal) = false; + option (cosmos.msg.v1.signer) = "signer"; + option (gogoproto.goproto_getters) = false; // client unique identifier - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + string client_id = 1; // client message to update the light client google.protobuf.Any client_message = 2; // signer address @@ -59,20 +75,21 @@ message MsgUpdateClientResponse {} // MsgUpgradeClient defines an sdk.Msg to upgrade an IBC client to a new client // state message MsgUpgradeClient { - option (gogoproto.equal) = false; + option (cosmos.msg.v1.signer) = "signer"; + option (gogoproto.goproto_getters) = false; // client unique identifier - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + string client_id = 1; // upgraded client state - google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""]; + google.protobuf.Any client_state = 2; // upgraded consensus state, only contains enough information to serve as a // basis of trust in update logic - google.protobuf.Any consensus_state = 3 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; + google.protobuf.Any consensus_state = 3; // proof that old chain committed to new client - bytes proof_upgrade_client = 4 [(gogoproto.moretags) = "yaml:\"proof_upgrade_client\""]; + bytes proof_upgrade_client = 4; // proof that old chain committed to new consensus state - bytes proof_upgrade_consensus_state = 5 [(gogoproto.moretags) = "yaml:\"proof_upgrade_consensus_state\""]; + bytes proof_upgrade_consensus_state = 5; // signer address string signer = 6; } @@ -82,19 +99,77 @@ message MsgUpgradeClientResponse {} // MsgSubmitMisbehaviour defines an sdk.Msg type that submits Evidence for // light client misbehaviour. -// Warning: DEPRECATED +// This message has been deprecated. Use MsgUpdateClient instead. message MsgSubmitMisbehaviour { - option (gogoproto.equal) = false; + option deprecated = true; + option (cosmos.msg.v1.signer) = "signer"; + option (gogoproto.goproto_getters) = false; // client unique identifier - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\"", deprecated = true]; + string client_id = 1; // misbehaviour used for freezing the light client - google.protobuf.Any misbehaviour = 2 [deprecated = true]; + google.protobuf.Any misbehaviour = 2; // signer address - string signer = 3 [deprecated = true]; + string signer = 3; } // MsgSubmitMisbehaviourResponse defines the Msg/SubmitMisbehaviour response // type. message MsgSubmitMisbehaviourResponse {} + +// MsgRecoverClient defines the message used to recover a frozen or expired client. +message MsgRecoverClient { + option (gogoproto.goproto_getters) = false; + option (cosmos.msg.v1.signer) = "signer"; + + // the client identifier for the client to be updated if the proposal passes + string subject_client_id = 1; + // the substitute client identifier for the client which will replace the subject + // client + string substitute_client_id = 2; + + // signer address + string signer = 3; +} + +// MsgRecoverClientResponse defines the Msg/RecoverClient response type. +message MsgRecoverClientResponse {} + +// MsgIBCSoftwareUpgrade defines the message used to schedule an upgrade of an IBC client using a v1 governance proposal +message MsgIBCSoftwareUpgrade { + option (cosmos.msg.v1.signer) = "signer"; + cosmos.upgrade.v1beta1.Plan plan = 1 [(gogoproto.nullable) = false]; + // An UpgradedClientState must be provided to perform an IBC breaking upgrade. + // This will make the chain commit to the correct upgraded (self) client state + // before the upgrade occurs, so that connecting chains can verify that the + // new upgraded client is valid by verifying a proof on the previous version + // of the chain. This will allow IBC connections to persist smoothly across + // planned chain upgrades. Correspondingly, the UpgradedClientState field has been + // deprecated in the Cosmos SDK to allow for this logic to exist solely in + // the 02-client module. + google.protobuf.Any upgraded_client_state = 2; + // signer address + string signer = 3; +} + +// MsgIBCSoftwareUpgradeResponse defines the Msg/IBCSoftwareUpgrade response type. +message MsgIBCSoftwareUpgradeResponse {} + +// MsgUpdateParams defines the sdk.Msg type to update the client parameters. +message MsgUpdateParams { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + // signer address + string signer = 1; + + // params defines the client parameters to update. + // + // NOTE: All parameters must be supplied. + Params params = 2 [(gogoproto.nullable) = false]; +} + +// MsgUpdateParamsResponse defines the MsgUpdateParams response type. +message MsgUpdateParamsResponse {} diff --git a/third_party/proto/ibc/core/commitment/v1/commitment.proto b/third_party/proto/ibc/core/commitment/v1/commitment.proto index 60abc5d1c..b4753be2d 100644 --- a/third_party/proto/ibc/core/commitment/v1/commitment.proto +++ b/third_party/proto/ibc/core/commitment/v1/commitment.proto @@ -19,16 +19,14 @@ message MerkleRoot { // The constructed key from the Path and the key will be append(Path.KeyPath, // append(Path.KeyPrefix, key...)) message MerklePrefix { - bytes key_prefix = 1 [(gogoproto.moretags) = "yaml:\"key_prefix\""]; + bytes key_prefix = 1; } // MerklePath is the path used to verify commitment proofs, which can be an // arbitrary structured object (defined by a commitment type). // MerklePath is represented from root-to-leaf message MerklePath { - option (gogoproto.goproto_stringer) = false; - - repeated string key_path = 1 [(gogoproto.moretags) = "yaml:\"key_path\""]; + repeated string key_path = 1; } // MerkleProof is a wrapper type over a chain of CommitmentProofs. diff --git a/third_party/proto/ibc/core/connection/v1/connection.proto b/third_party/proto/ibc/core/connection/v1/connection.proto index 2cec817a0..852f3999b 100644 --- a/third_party/proto/ibc/core/connection/v1/connection.proto +++ b/third_party/proto/ibc/core/connection/v1/connection.proto @@ -17,7 +17,7 @@ import "ibc/core/commitment/v1/commitment.proto"; message ConnectionEnd { option (gogoproto.goproto_getters) = false; // client associated with this connection. - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + string client_id = 1; // IBC version which can be utilised to determine encodings or protocols for // channels or packets utilising this connection. repeated Version versions = 2; @@ -28,7 +28,7 @@ message ConnectionEnd { // delay period that must pass before a consensus state can be used for // packet-verification NOTE: delay period logic is only implemented by some // clients. - uint64 delay_period = 5 [(gogoproto.moretags) = "yaml:\"delay_period\""]; + uint64 delay_period = 5; } // IdentifiedConnection defines a connection with additional connection @@ -36,9 +36,9 @@ message ConnectionEnd { message IdentifiedConnection { option (gogoproto.goproto_getters) = false; // connection identifier. - string id = 1 [(gogoproto.moretags) = "yaml:\"id\""]; + string id = 1; // client associated with this connection. - string client_id = 2 [(gogoproto.moretags) = "yaml:\"client_id\""]; + string client_id = 2; // IBC version which can be utilised to determine encodings or protocols for // channels or packets utilising this connection repeated Version versions = 3; @@ -47,7 +47,7 @@ message IdentifiedConnection { // counterparty chain associated with this connection. Counterparty counterparty = 5 [(gogoproto.nullable) = false]; // delay period associated with this connection. - uint64 delay_period = 6 [(gogoproto.moretags) = "yaml:\"delay_period\""]; + uint64 delay_period = 6; } // State defines if a connection is in one of the following states: @@ -72,10 +72,10 @@ message Counterparty { // identifies the client on the counterparty chain associated with a given // connection. - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + string client_id = 1; // identifies the connection end on the counterparty chain associated with a // given connection. - string connection_id = 2 [(gogoproto.moretags) = "yaml:\"connection_id\""]; + string connection_id = 2; // commitment merkle prefix of the counterparty chain. ibc.core.commitment.v1.MerklePrefix prefix = 3 [(gogoproto.nullable) = false]; } @@ -89,7 +89,7 @@ message ClientPaths { // ConnectionPaths define all the connection paths for a given client state. message ConnectionPaths { // client state unique identifier - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + string client_id = 1; // list of connection paths repeated string paths = 2; } @@ -110,5 +110,5 @@ message Params { // maximum expected time per block (in nanoseconds), used to enforce block delay. This parameter should reflect the // largest amount of time that the chain might reasonably take to produce the next block under normal operating // conditions. A safe choice is 3-5x the expected time per block. - uint64 max_expected_time_per_block = 1 [(gogoproto.moretags) = "yaml:\"max_expected_time_per_block\""]; + uint64 max_expected_time_per_block = 1; } diff --git a/third_party/proto/ibc/core/connection/v1/genesis.proto b/third_party/proto/ibc/core/connection/v1/genesis.proto index 830bbe138..a5eb6b3a1 100644 --- a/third_party/proto/ibc/core/connection/v1/genesis.proto +++ b/third_party/proto/ibc/core/connection/v1/genesis.proto @@ -10,9 +10,8 @@ import "ibc/core/connection/v1/connection.proto"; // GenesisState defines the ibc connection submodule's genesis state. message GenesisState { repeated IdentifiedConnection connections = 1 [(gogoproto.nullable) = false]; - repeated ConnectionPaths client_connection_paths = 2 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"client_connection_paths\""]; + repeated ConnectionPaths client_connection_paths = 2 [(gogoproto.nullable) = false]; // the sequence for the next generated connection identifier - uint64 next_connection_sequence = 3 [(gogoproto.moretags) = "yaml:\"next_connection_sequence\""]; + uint64 next_connection_sequence = 3; Params params = 4 [(gogoproto.nullable) = false]; } diff --git a/third_party/proto/ibc/core/connection/v1/query.proto b/third_party/proto/ibc/core/connection/v1/query.proto index d1e120c92..c0f1a6f57 100644 --- a/third_party/proto/ibc/core/connection/v1/query.proto +++ b/third_party/proto/ibc/core/connection/v1/query.proto @@ -106,7 +106,7 @@ message QueryClientConnectionsResponse { // Query/ConnectionClientState RPC method message QueryConnectionClientStateRequest { // connection identifier - string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; + string connection_id = 1; } // QueryConnectionClientStateResponse is the response type for the @@ -124,7 +124,7 @@ message QueryConnectionClientStateResponse { // Query/ConnectionConsensusState RPC method message QueryConnectionConsensusStateRequest { // connection identifier - string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; + string connection_id = 1; uint64 revision_number = 2; uint64 revision_height = 3; } diff --git a/third_party/proto/ibc/core/connection/v1/tx.proto b/third_party/proto/ibc/core/connection/v1/tx.proto index d2ef2b914..3ba8ff456 100644 --- a/third_party/proto/ibc/core/connection/v1/tx.proto +++ b/third_party/proto/ibc/core/connection/v1/tx.proto @@ -5,12 +5,15 @@ package ibc.core.connection.v1; option go_package = "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types"; import "gogoproto/gogo.proto"; +import "cosmos/msg/v1/msg.proto"; import "google/protobuf/any.proto"; import "ibc/core/client/v1/client.proto"; import "ibc/core/connection/v1/connection.proto"; // Msg defines the ibc/connection Msg service. service Msg { + option (cosmos.msg.v1.service) = true; + // ConnectionOpenInit defines a rpc handler method for MsgConnectionOpenInit. rpc ConnectionOpenInit(MsgConnectionOpenInit) returns (MsgConnectionOpenInitResponse); @@ -23,18 +26,23 @@ service Msg { // ConnectionOpenConfirm defines a rpc handler method for // MsgConnectionOpenConfirm. rpc ConnectionOpenConfirm(MsgConnectionOpenConfirm) returns (MsgConnectionOpenConfirmResponse); + + // UpdateConnectionParams defines a rpc handler method for + // MsgUpdateParams. + rpc UpdateConnectionParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); } // MsgConnectionOpenInit defines the msg sent by an account on Chain A to // initialize a connection with Chain B. message MsgConnectionOpenInit { - option (gogoproto.equal) = false; + option (cosmos.msg.v1.signer) = "signer"; + option (gogoproto.goproto_getters) = false; - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + string client_id = 1; Counterparty counterparty = 2 [(gogoproto.nullable) = false]; Version version = 3; - uint64 delay_period = 4 [(gogoproto.moretags) = "yaml:\"delay_period\""]; + uint64 delay_period = 4; string signer = 5; } @@ -45,28 +53,27 @@ message MsgConnectionOpenInitResponse {} // MsgConnectionOpenTry defines a msg sent by a Relayer to try to open a // connection on Chain B. message MsgConnectionOpenTry { - option (gogoproto.equal) = false; + option (cosmos.msg.v1.signer) = "signer"; + option (gogoproto.goproto_getters) = false; - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + string client_id = 1; // Deprecated: this field is unused. Crossing hellos are no longer supported in core IBC. - string previous_connection_id = 2 [deprecated = true, (gogoproto.moretags) = "yaml:\"previous_connection_id\""]; - google.protobuf.Any client_state = 3 [(gogoproto.moretags) = "yaml:\"client_state\""]; - Counterparty counterparty = 4 [(gogoproto.nullable) = false]; - uint64 delay_period = 5 [(gogoproto.moretags) = "yaml:\"delay_period\""]; - repeated Version counterparty_versions = 6 [(gogoproto.moretags) = "yaml:\"counterparty_versions\""]; - ibc.core.client.v1.Height proof_height = 7 - [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + string previous_connection_id = 2 [deprecated = true]; + google.protobuf.Any client_state = 3; + Counterparty counterparty = 4 [(gogoproto.nullable) = false]; + uint64 delay_period = 5; + repeated Version counterparty_versions = 6; + ibc.core.client.v1.Height proof_height = 7 [(gogoproto.nullable) = false]; // proof of the initialization the connection on Chain A: `UNITIALIZED -> // INIT` - bytes proof_init = 8 [(gogoproto.moretags) = "yaml:\"proof_init\""]; + bytes proof_init = 8; // proof of client state included in message - bytes proof_client = 9 [(gogoproto.moretags) = "yaml:\"proof_client\""]; + bytes proof_client = 9; // proof of client consensus state - bytes proof_consensus = 10 [(gogoproto.moretags) = "yaml:\"proof_consensus\""]; - ibc.core.client.v1.Height consensus_height = 11 - [(gogoproto.moretags) = "yaml:\"consensus_height\"", (gogoproto.nullable) = false]; - string signer = 12; + bytes proof_consensus = 10; + ibc.core.client.v1.Height consensus_height = 11 [(gogoproto.nullable) = false]; + string signer = 12; // optional proof data for host state machines that are unable to introspect their own consensus state bytes host_consensus_state_proof = 13; } @@ -77,25 +84,24 @@ message MsgConnectionOpenTryResponse {} // MsgConnectionOpenAck defines a msg sent by a Relayer to Chain A to // acknowledge the change of connection state to TRYOPEN on Chain B. message MsgConnectionOpenAck { - option (gogoproto.equal) = false; + option (cosmos.msg.v1.signer) = "signer"; + option (gogoproto.goproto_getters) = false; - string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; - string counterparty_connection_id = 2 [(gogoproto.moretags) = "yaml:\"counterparty_connection_id\""]; - Version version = 3; - google.protobuf.Any client_state = 4 [(gogoproto.moretags) = "yaml:\"client_state\""]; - ibc.core.client.v1.Height proof_height = 5 - [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + string connection_id = 1; + string counterparty_connection_id = 2; + Version version = 3; + google.protobuf.Any client_state = 4; + ibc.core.client.v1.Height proof_height = 5 [(gogoproto.nullable) = false]; // proof of the initialization the connection on Chain B: `UNITIALIZED -> // TRYOPEN` - bytes proof_try = 6 [(gogoproto.moretags) = "yaml:\"proof_try\""]; + bytes proof_try = 6; // proof of client state included in message - bytes proof_client = 7 [(gogoproto.moretags) = "yaml:\"proof_client\""]; + bytes proof_client = 7; // proof of client consensus state - bytes proof_consensus = 8 [(gogoproto.moretags) = "yaml:\"proof_consensus\""]; - ibc.core.client.v1.Height consensus_height = 9 - [(gogoproto.moretags) = "yaml:\"consensus_height\"", (gogoproto.nullable) = false]; - string signer = 10; + bytes proof_consensus = 8; + ibc.core.client.v1.Height consensus_height = 9 [(gogoproto.nullable) = false]; + string signer = 10; // optional proof data for host state machines that are unable to introspect their own consensus state bytes host_consensus_state_proof = 11; } @@ -106,17 +112,35 @@ message MsgConnectionOpenAckResponse {} // MsgConnectionOpenConfirm defines a msg sent by a Relayer to Chain B to // acknowledge the change of connection state to OPEN on Chain A. message MsgConnectionOpenConfirm { - option (gogoproto.equal) = false; + option (cosmos.msg.v1.signer) = "signer"; + option (gogoproto.goproto_getters) = false; - string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; + string connection_id = 1; // proof for the change of the connection state on Chain A: `INIT -> OPEN` - bytes proof_ack = 2 [(gogoproto.moretags) = "yaml:\"proof_ack\""]; - ibc.core.client.v1.Height proof_height = 3 - [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; - string signer = 4; + bytes proof_ack = 2; + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; + string signer = 4; } // MsgConnectionOpenConfirmResponse defines the Msg/ConnectionOpenConfirm // response type. message MsgConnectionOpenConfirmResponse {} + +// MsgUpdateParams defines the sdk.Msg type to update the connection parameters. +message MsgUpdateParams { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + // signer address + string signer = 1; + + // params defines the connection parameters to update. + // + // NOTE: All parameters must be supplied. + Params params = 2 [(gogoproto.nullable) = false]; +} + +// MsgUpdateParamsResponse defines the MsgUpdateParams response type. +message MsgUpdateParamsResponse {} \ No newline at end of file diff --git a/third_party/proto/ibc/core/types/v1/genesis.proto b/third_party/proto/ibc/core/types/v1/genesis.proto index 51c227916..4b34f6889 100644 --- a/third_party/proto/ibc/core/types/v1/genesis.proto +++ b/third_party/proto/ibc/core/types/v1/genesis.proto @@ -12,12 +12,9 @@ import "ibc/core/channel/v1/genesis.proto"; // GenesisState defines the ibc module's genesis state. message GenesisState { // ICS002 - Clients genesis state - ibc.core.client.v1.GenesisState client_genesis = 1 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"client_genesis\""]; + ibc.core.client.v1.GenesisState client_genesis = 1 [(gogoproto.nullable) = false]; // ICS003 - Connections genesis state - ibc.core.connection.v1.GenesisState connection_genesis = 2 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"connection_genesis\""]; + ibc.core.connection.v1.GenesisState connection_genesis = 2 [(gogoproto.nullable) = false]; // ICS004 - Channel genesis state - ibc.core.channel.v1.GenesisState channel_genesis = 3 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"channel_genesis\""]; + ibc.core.channel.v1.GenesisState channel_genesis = 3 [(gogoproto.nullable) = false]; } diff --git a/third_party/proto/ibc/fee/v1/ack.proto b/third_party/proto/ibc/fee/v1/ack.proto new file mode 100644 index 000000000..2f3746d2c --- /dev/null +++ b/third_party/proto/ibc/fee/v1/ack.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package ibc.applications.fee.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"; + +// IncentivizedAcknowledgement is the acknowledgement format to be used by applications wrapped in the fee middleware +message IncentivizedAcknowledgement { + // the underlying app acknowledgement bytes + bytes app_acknowledgement = 1; + // the relayer address which submits the recv packet message + string forward_relayer_address = 2; + // success flag of the base application callback + bool underlying_app_success = 3; +} diff --git a/third_party/proto/ibc/fee/v1/fee.proto b/third_party/proto/ibc/fee/v1/fee.proto new file mode 100644 index 000000000..867e88455 --- /dev/null +++ b/third_party/proto/ibc/fee/v1/fee.proto @@ -0,0 +1,61 @@ +syntax = "proto3"; + +package ibc.applications.fee.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"; + +import "amino/amino.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "gogoproto/gogo.proto"; +import "ibc/core/channel/v1/channel.proto"; +import "cosmos/msg/v1/msg.proto"; + +// Fee defines the ICS29 receive, acknowledgement and timeout fees +message Fee { + // the packet receive fee + repeated cosmos.base.v1beta1.Coin recv_fee = 1 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (amino.encoding) = "legacy_coins" + ]; + + // the packet acknowledgement fee + repeated cosmos.base.v1beta1.Coin ack_fee = 2 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (amino.encoding) = "legacy_coins" + ]; + + // the packet timeout fee + repeated cosmos.base.v1beta1.Coin timeout_fee = 3 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (amino.encoding) = "legacy_coins" + ]; +} + +// PacketFee contains ICS29 relayer fees, refund address and optional list of permitted relayers +message PacketFee { + option (cosmos.msg.v1.signer) = "refund_address"; + + // fee encapsulates the recv, ack and timeout fees associated with an IBC packet + Fee fee = 1 [(gogoproto.nullable) = false]; + // the refund address for unspent fees + string refund_address = 2; + // optional list of relayers permitted to receive fees + repeated string relayers = 3; +} + +// PacketFees contains a list of type PacketFee +message PacketFees { + // list of packet fees + repeated PacketFee packet_fees = 1 [(gogoproto.nullable) = false]; +} + +// IdentifiedPacketFees contains a list of type PacketFee and associated PacketId +message IdentifiedPacketFees { + // unique packet identifier comprised of the channel ID, port ID and sequence + ibc.core.channel.v1.PacketId packet_id = 1 [(gogoproto.nullable) = false]; + // list of packet fees + repeated PacketFee packet_fees = 2 [(gogoproto.nullable) = false]; +} diff --git a/third_party/proto/ibc/fee/v1/genesis.proto b/third_party/proto/ibc/fee/v1/genesis.proto new file mode 100644 index 000000000..e48ceb535 --- /dev/null +++ b/third_party/proto/ibc/fee/v1/genesis.proto @@ -0,0 +1,60 @@ +syntax = "proto3"; + +package ibc.applications.fee.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"; + +import "gogoproto/gogo.proto"; +import "ibc/applications/fee/v1/fee.proto"; +import "ibc/core/channel/v1/channel.proto"; + +// GenesisState defines the ICS29 fee middleware genesis state +message GenesisState { + // list of identified packet fees + repeated IdentifiedPacketFees identified_fees = 1 [(gogoproto.nullable) = false]; + // list of fee enabled channels + repeated FeeEnabledChannel fee_enabled_channels = 2 [(gogoproto.nullable) = false]; + // list of registered payees + repeated RegisteredPayee registered_payees = 3 [(gogoproto.nullable) = false]; + // list of registered counterparty payees + repeated RegisteredCounterpartyPayee registered_counterparty_payees = 4 [(gogoproto.nullable) = false]; + // list of forward relayer addresses + repeated ForwardRelayerAddress forward_relayers = 5 [(gogoproto.nullable) = false]; +} + +// FeeEnabledChannel contains the PortID & ChannelID for a fee enabled channel +message FeeEnabledChannel { + // unique port identifier + string port_id = 1; + // unique channel identifier + string channel_id = 2; +} + +// RegisteredPayee contains the relayer address and payee address for a specific channel +message RegisteredPayee { + // unique channel identifier + string channel_id = 1; + // the relayer address + string relayer = 2; + // the payee address + string payee = 3; +} + +// RegisteredCounterpartyPayee contains the relayer address and counterparty payee address for a specific channel (used +// for recv fee distribution) +message RegisteredCounterpartyPayee { + // unique channel identifier + string channel_id = 1; + // the relayer address + string relayer = 2; + // the counterparty payee address + string counterparty_payee = 3; +} + +// ForwardRelayerAddress contains the forward relayer address and PacketId used for async acknowledgements +message ForwardRelayerAddress { + // the forward relayer address + string address = 1; + // unique packet identifer comprised of the channel ID, port ID and sequence + ibc.core.channel.v1.PacketId packet_id = 2 [(gogoproto.nullable) = false]; +} diff --git a/third_party/proto/ibc/fee/v1/metadata.proto b/third_party/proto/ibc/fee/v1/metadata.proto new file mode 100644 index 000000000..1e82e7c25 --- /dev/null +++ b/third_party/proto/ibc/fee/v1/metadata.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package ibc.applications.fee.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"; + +// Metadata defines the ICS29 channel specific metadata encoded into the channel version bytestring +// See ICS004: https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#Versioning +message Metadata { + // fee_version defines the ICS29 fee version + string fee_version = 1; + // app_version defines the underlying application version, which may or may not be a JSON encoded bytestring + string app_version = 2; +} diff --git a/third_party/proto/ibc/fee/v1/query.proto b/third_party/proto/ibc/fee/v1/query.proto new file mode 100644 index 000000000..726370ee0 --- /dev/null +++ b/third_party/proto/ibc/fee/v1/query.proto @@ -0,0 +1,218 @@ +syntax = "proto3"; + +package ibc.applications.fee.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "ibc/applications/fee/v1/fee.proto"; +import "ibc/applications/fee/v1/genesis.proto"; +import "ibc/core/channel/v1/channel.proto"; + +// Query defines the ICS29 gRPC querier service. +service Query { + // IncentivizedPackets returns all incentivized packets and their associated fees + rpc IncentivizedPackets(QueryIncentivizedPacketsRequest) returns (QueryIncentivizedPacketsResponse) { + option (google.api.http).get = "/ibc/apps/fee/v1/incentivized_packets"; + } + + // IncentivizedPacket returns all packet fees for a packet given its identifier + rpc IncentivizedPacket(QueryIncentivizedPacketRequest) returns (QueryIncentivizedPacketResponse) { + option (google.api.http).get = + "/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/sequences/" + "{packet_id.sequence}/incentivized_packet"; + } + + // Gets all incentivized packets for a specific channel + rpc IncentivizedPacketsForChannel(QueryIncentivizedPacketsForChannelRequest) + returns (QueryIncentivizedPacketsForChannelResponse) { + option (google.api.http).get = "/ibc/apps/fee/v1/channels/{channel_id}/ports/{port_id}/incentivized_packets"; + } + + // TotalRecvFees returns the total receive fees for a packet given its identifier + rpc TotalRecvFees(QueryTotalRecvFeesRequest) returns (QueryTotalRecvFeesResponse) { + option (google.api.http).get = "/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/" + "sequences/{packet_id.sequence}/total_recv_fees"; + } + + // TotalAckFees returns the total acknowledgement fees for a packet given its identifier + rpc TotalAckFees(QueryTotalAckFeesRequest) returns (QueryTotalAckFeesResponse) { + option (google.api.http).get = "/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/" + "sequences/{packet_id.sequence}/total_ack_fees"; + } + + // TotalTimeoutFees returns the total timeout fees for a packet given its identifier + rpc TotalTimeoutFees(QueryTotalTimeoutFeesRequest) returns (QueryTotalTimeoutFeesResponse) { + option (google.api.http).get = "/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/" + "sequences/{packet_id.sequence}/total_timeout_fees"; + } + + // Payee returns the registered payee address for a specific channel given the relayer address + rpc Payee(QueryPayeeRequest) returns (QueryPayeeResponse) { + option (google.api.http).get = "/ibc/apps/fee/v1/channels/{channel_id}/relayers/{relayer}/payee"; + } + + // CounterpartyPayee returns the registered counterparty payee for forward relaying + rpc CounterpartyPayee(QueryCounterpartyPayeeRequest) returns (QueryCounterpartyPayeeResponse) { + option (google.api.http).get = "/ibc/apps/fee/v1/channels/{channel_id}/relayers/{relayer}/counterparty_payee"; + } + + // FeeEnabledChannels returns a list of all fee enabled channels + rpc FeeEnabledChannels(QueryFeeEnabledChannelsRequest) returns (QueryFeeEnabledChannelsResponse) { + option (google.api.http).get = "/ibc/apps/fee/v1/fee_enabled"; + } + + // FeeEnabledChannel returns true if the provided port and channel identifiers belong to a fee enabled channel + rpc FeeEnabledChannel(QueryFeeEnabledChannelRequest) returns (QueryFeeEnabledChannelResponse) { + option (google.api.http).get = "/ibc/apps/fee/v1/channels/{channel_id}/ports/{port_id}/fee_enabled"; + } +} + +// QueryIncentivizedPacketsRequest defines the request type for the IncentivizedPackets rpc +message QueryIncentivizedPacketsRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; + // block height at which to query + uint64 query_height = 2; +} + +// QueryIncentivizedPacketsResponse defines the response type for the IncentivizedPackets rpc +message QueryIncentivizedPacketsResponse { + // list of identified fees for incentivized packets + repeated ibc.applications.fee.v1.IdentifiedPacketFees incentivized_packets = 1 [(gogoproto.nullable) = false]; + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryIncentivizedPacketRequest defines the request type for the IncentivizedPacket rpc +message QueryIncentivizedPacketRequest { + // unique packet identifier comprised of channel ID, port ID and sequence + ibc.core.channel.v1.PacketId packet_id = 1 [(gogoproto.nullable) = false]; + // block height at which to query + uint64 query_height = 2; +} + +// QueryIncentivizedPacketsResponse defines the response type for the IncentivizedPacket rpc +message QueryIncentivizedPacketResponse { + // the identified fees for the incentivized packet + ibc.applications.fee.v1.IdentifiedPacketFees incentivized_packet = 1 [(gogoproto.nullable) = false]; +} + +// QueryIncentivizedPacketsForChannelRequest defines the request type for querying for all incentivized packets +// for a specific channel +message QueryIncentivizedPacketsForChannelRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; + string port_id = 2; + string channel_id = 3; + // Height to query at + uint64 query_height = 4; +} + +// QueryIncentivizedPacketsResponse defines the response type for the incentivized packets RPC +message QueryIncentivizedPacketsForChannelResponse { + // Map of all incentivized_packets + repeated ibc.applications.fee.v1.IdentifiedPacketFees incentivized_packets = 1; + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryTotalRecvFeesRequest defines the request type for the TotalRecvFees rpc +message QueryTotalRecvFeesRequest { + // the packet identifier for the associated fees + ibc.core.channel.v1.PacketId packet_id = 1 [(gogoproto.nullable) = false]; +} + +// QueryTotalRecvFeesResponse defines the response type for the TotalRecvFees rpc +message QueryTotalRecvFeesResponse { + // the total packet receive fees + repeated cosmos.base.v1beta1.Coin recv_fees = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// QueryTotalAckFeesRequest defines the request type for the TotalAckFees rpc +message QueryTotalAckFeesRequest { + // the packet identifier for the associated fees + ibc.core.channel.v1.PacketId packet_id = 1 [(gogoproto.nullable) = false]; +} + +// QueryTotalAckFeesResponse defines the response type for the TotalAckFees rpc +message QueryTotalAckFeesResponse { + // the total packet acknowledgement fees + repeated cosmos.base.v1beta1.Coin ack_fees = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// QueryTotalTimeoutFeesRequest defines the request type for the TotalTimeoutFees rpc +message QueryTotalTimeoutFeesRequest { + // the packet identifier for the associated fees + ibc.core.channel.v1.PacketId packet_id = 1 [(gogoproto.nullable) = false]; +} + +// QueryTotalTimeoutFeesResponse defines the response type for the TotalTimeoutFees rpc +message QueryTotalTimeoutFeesResponse { + // the total packet timeout fees + repeated cosmos.base.v1beta1.Coin timeout_fees = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// QueryPayeeRequest defines the request type for the Payee rpc +message QueryPayeeRequest { + // unique channel identifier + string channel_id = 1; + // the relayer address to which the distribution address is registered + string relayer = 2; +} + +// QueryPayeeResponse defines the response type for the Payee rpc +message QueryPayeeResponse { + // the payee address to which packet fees are paid out + string payee_address = 1; +} + +// QueryCounterpartyPayeeRequest defines the request type for the CounterpartyPayee rpc +message QueryCounterpartyPayeeRequest { + // unique channel identifier + string channel_id = 1; + // the relayer address to which the counterparty is registered + string relayer = 2; +} + +// QueryCounterpartyPayeeResponse defines the response type for the CounterpartyPayee rpc +message QueryCounterpartyPayeeResponse { + // the counterparty payee address used to compensate forward relaying + string counterparty_payee = 1; +} + +// QueryFeeEnabledChannelsRequest defines the request type for the FeeEnabledChannels rpc +message QueryFeeEnabledChannelsRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; + // block height at which to query + uint64 query_height = 2; +} + +// QueryFeeEnabledChannelsResponse defines the response type for the FeeEnabledChannels rpc +message QueryFeeEnabledChannelsResponse { + // list of fee enabled channels + repeated ibc.applications.fee.v1.FeeEnabledChannel fee_enabled_channels = 1 [(gogoproto.nullable) = false]; + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryFeeEnabledChannelRequest defines the request type for the FeeEnabledChannel rpc +message QueryFeeEnabledChannelRequest { + // unique port identifier + string port_id = 1; + // unique channel identifier + string channel_id = 2; +} + +// QueryFeeEnabledChannelResponse defines the response type for the FeeEnabledChannel rpc +message QueryFeeEnabledChannelResponse { + // boolean flag representing the fee enabled channel status + bool fee_enabled = 1; +} diff --git a/third_party/proto/ibc/fee/v1/tx.proto b/third_party/proto/ibc/fee/v1/tx.proto new file mode 100644 index 000000000..e59dddfd1 --- /dev/null +++ b/third_party/proto/ibc/fee/v1/tx.proto @@ -0,0 +1,122 @@ +syntax = "proto3"; + +package ibc.applications.fee.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"; + +import "amino/amino.proto"; +import "gogoproto/gogo.proto"; +import "ibc/applications/fee/v1/fee.proto"; +import "ibc/core/channel/v1/channel.proto"; +import "cosmos/msg/v1/msg.proto"; + +// Msg defines the ICS29 Msg service. +service Msg { + option (cosmos.msg.v1.service) = true; + + // RegisterPayee defines a rpc handler method for MsgRegisterPayee + // RegisterPayee is called by the relayer on each channelEnd and allows them to set an optional + // payee to which reverse and timeout relayer packet fees will be paid out. The payee should be registered on + // the source chain from which packets originate as this is where fee distribution takes place. This function may be + // called more than once by a relayer, in which case, the latest payee is always used. + rpc RegisterPayee(MsgRegisterPayee) returns (MsgRegisterPayeeResponse); + + // RegisterCounterpartyPayee defines a rpc handler method for MsgRegisterCounterpartyPayee + // RegisterCounterpartyPayee is called by the relayer on each channelEnd and allows them to specify the counterparty + // payee address before relaying. This ensures they will be properly compensated for forward relaying since + // the destination chain must include the registered counterparty payee address in the acknowledgement. This function + // may be called more than once by a relayer, in which case, the latest counterparty payee address is always used. + rpc RegisterCounterpartyPayee(MsgRegisterCounterpartyPayee) returns (MsgRegisterCounterpartyPayeeResponse); + + // PayPacketFee defines a rpc handler method for MsgPayPacketFee + // PayPacketFee is an open callback that may be called by any module/user that wishes to escrow funds in order to + // incentivize the relaying of the packet at the next sequence + // NOTE: This method is intended to be used within a multi msg transaction, where the subsequent msg that follows + // initiates the lifecycle of the incentivized packet + rpc PayPacketFee(MsgPayPacketFee) returns (MsgPayPacketFeeResponse); + + // PayPacketFeeAsync defines a rpc handler method for MsgPayPacketFeeAsync + // PayPacketFeeAsync is an open callback that may be called by any module/user that wishes to escrow funds in order to + // incentivize the relaying of a known packet (i.e. at a particular sequence) + rpc PayPacketFeeAsync(MsgPayPacketFeeAsync) returns (MsgPayPacketFeeAsyncResponse); +} + +// MsgRegisterPayee defines the request type for the RegisterPayee rpc +message MsgRegisterPayee { + option (amino.name) = "cosmos-sdk/MsgRegisterPayee"; + option (cosmos.msg.v1.signer) = "relayer"; + + option (gogoproto.goproto_getters) = false; + + // unique port identifier + string port_id = 1; + // unique channel identifier + string channel_id = 2; + // the relayer address + string relayer = 3; + // the payee address + string payee = 4; +} + +// MsgRegisterPayeeResponse defines the response type for the RegisterPayee rpc +message MsgRegisterPayeeResponse {} + +// MsgRegisterCounterpartyPayee defines the request type for the RegisterCounterpartyPayee rpc +message MsgRegisterCounterpartyPayee { + option (amino.name) = "cosmos-sdk/MsgRegisterCounterpartyPayee"; + option (cosmos.msg.v1.signer) = "relayer"; + + option (gogoproto.goproto_getters) = false; + + // unique port identifier + string port_id = 1; + // unique channel identifier + string channel_id = 2; + // the relayer address + string relayer = 3; + // the counterparty payee address + string counterparty_payee = 4; +} + +// MsgRegisterCounterpartyPayeeResponse defines the response type for the RegisterCounterpartyPayee rpc +message MsgRegisterCounterpartyPayeeResponse {} + +// MsgPayPacketFee defines the request type for the PayPacketFee rpc +// This Msg can be used to pay for a packet at the next sequence send & should be combined with the Msg that will be +// paid for +message MsgPayPacketFee { + option (amino.name) = "cosmos-sdk/MsgPayPacketFee"; + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + // fee encapsulates the recv, ack and timeout fees associated with an IBC packet + ibc.applications.fee.v1.Fee fee = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; + // the source port unique identifier + string source_port_id = 2; + // the source channel unique identifer + string source_channel_id = 3; + // account address to refund fee if necessary + string signer = 4; + // optional list of relayers permitted to the receive packet fees + repeated string relayers = 5; +} + +// MsgPayPacketFeeResponse defines the response type for the PayPacketFee rpc +message MsgPayPacketFeeResponse {} + +// MsgPayPacketFeeAsync defines the request type for the PayPacketFeeAsync rpc +// This Msg can be used to pay for a packet at a specified sequence (instead of the next sequence send) +message MsgPayPacketFeeAsync { + option (amino.name) = "cosmos-sdk/MsgPayPacketFeeAsync"; + option (cosmos.msg.v1.signer) = "packet_fee"; + option (gogoproto.goproto_getters) = false; + + // unique packet identifier comprised of the channel ID, port ID and sequence + ibc.core.channel.v1.PacketId packet_id = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; + // the packet fee associated with a particular IBC packet + PacketFee packet_fee = 2 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; +} + +// MsgPayPacketFeeAsyncResponse defines the response type for the PayPacketFeeAsync rpc +message MsgPayPacketFeeAsyncResponse {} diff --git a/third_party/proto/ibc/interchain_accounts/controller/v1/controller.proto b/third_party/proto/ibc/interchain_accounts/controller/v1/controller.proto new file mode 100644 index 000000000..2e6bbe1a1 --- /dev/null +++ b/third_party/proto/ibc/interchain_accounts/controller/v1/controller.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +package ibc.applications.interchain_accounts.controller.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types"; + +// Params defines the set of on-chain interchain accounts parameters. +// The following parameters may be used to disable the controller submodule. +message Params { + // controller_enabled enables or disables the controller submodule. + bool controller_enabled = 1; +} diff --git a/third_party/proto/ibc/interchain_accounts/controller/v1/query.proto b/third_party/proto/ibc/interchain_accounts/controller/v1/query.proto new file mode 100644 index 000000000..31885fcb2 --- /dev/null +++ b/third_party/proto/ibc/interchain_accounts/controller/v1/query.proto @@ -0,0 +1,42 @@ +syntax = "proto3"; + +package ibc.applications.interchain_accounts.controller.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types"; + +import "ibc/applications/interchain_accounts/controller/v1/controller.proto"; +import "google/api/annotations.proto"; + +// Query provides defines the gRPC querier service. +service Query { + // InterchainAccount returns the interchain account address for a given owner address on a given connection + rpc InterchainAccount(QueryInterchainAccountRequest) returns (QueryInterchainAccountResponse) { + option (google.api.http).get = + "/ibc/apps/interchain_accounts/controller/v1/owners/{owner}/connections/{connection_id}"; + } + + // Params queries all parameters of the ICA controller submodule. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/ibc/apps/interchain_accounts/controller/v1/params"; + } +} + +// QueryInterchainAccountRequest is the request type for the Query/InterchainAccount RPC method. +message QueryInterchainAccountRequest { + string owner = 1; + string connection_id = 2; +} + +// QueryInterchainAccountResponse the response type for the Query/InterchainAccount RPC method. +message QueryInterchainAccountResponse { + string address = 1; +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // params defines the parameters of the module. + Params params = 1; +} diff --git a/third_party/proto/ibc/interchain_accounts/controller/v1/tx.proto b/third_party/proto/ibc/interchain_accounts/controller/v1/tx.proto new file mode 100644 index 000000000..ec5c2e62e --- /dev/null +++ b/third_party/proto/ibc/interchain_accounts/controller/v1/tx.proto @@ -0,0 +1,82 @@ +syntax = "proto3"; + +package ibc.applications.interchain_accounts.controller.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types"; + +import "gogoproto/gogo.proto"; +import "ibc/applications/interchain_accounts/v1/packet.proto"; +import "ibc/applications/interchain_accounts/controller/v1/controller.proto"; +import "cosmos/msg/v1/msg.proto"; +import "ibc/core/channel/v1/channel.proto"; + +// Msg defines the 27-interchain-accounts/controller Msg service. +service Msg { + option (cosmos.msg.v1.service) = true; + + // RegisterInterchainAccount defines a rpc handler for MsgRegisterInterchainAccount. + rpc RegisterInterchainAccount(MsgRegisterInterchainAccount) returns (MsgRegisterInterchainAccountResponse); + // SendTx defines a rpc handler for MsgSendTx. + rpc SendTx(MsgSendTx) returns (MsgSendTxResponse); + // UpdateParams defines a rpc handler for MsgUpdateParams. + rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); +} + +// MsgRegisterInterchainAccount defines the payload for Msg/RegisterAccount +message MsgRegisterInterchainAccount { + option (cosmos.msg.v1.signer) = "owner"; + + option (gogoproto.goproto_getters) = false; + + string owner = 1; + string connection_id = 2; + string version = 3; + ibc.core.channel.v1.Order ordering = 4; +} + +// MsgRegisterInterchainAccountResponse defines the response for Msg/RegisterAccount +message MsgRegisterInterchainAccountResponse { + option (gogoproto.goproto_getters) = false; + + string channel_id = 1; + string port_id = 2; +} + +// MsgSendTx defines the payload for Msg/SendTx +message MsgSendTx { + option (cosmos.msg.v1.signer) = "owner"; + + option (gogoproto.goproto_getters) = false; + + string owner = 1; + string connection_id = 2; + ibc.applications.interchain_accounts.v1.InterchainAccountPacketData packet_data = 3 [(gogoproto.nullable) = false]; + // Relative timeout timestamp provided will be added to the current block time during transaction execution. + // The timeout timestamp must be non-zero. + uint64 relative_timeout = 4; +} + +// MsgSendTxResponse defines the response for MsgSendTx +message MsgSendTxResponse { + option (gogoproto.goproto_getters) = false; + + uint64 sequence = 1; +} + +// MsgUpdateParams defines the payload for Msg/UpdateParams +message MsgUpdateParams { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + // signer address + string signer = 1; + + // params defines the 27-interchain-accounts/controller parameters to update. + // + // NOTE: All parameters must be supplied. + Params params = 2 [(gogoproto.nullable) = false]; +} + +// MsgUpdateParamsResponse defines the response for Msg/UpdateParams +message MsgUpdateParamsResponse {} \ No newline at end of file diff --git a/third_party/proto/ibc/interchain_accounts/genesis/v1/genesis.proto b/third_party/proto/ibc/interchain_accounts/genesis/v1/genesis.proto new file mode 100644 index 000000000..4393e5b0b --- /dev/null +++ b/third_party/proto/ibc/interchain_accounts/genesis/v1/genesis.proto @@ -0,0 +1,47 @@ +syntax = "proto3"; + +package ibc.applications.interchain_accounts.genesis.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/genesis/types"; + +import "gogoproto/gogo.proto"; +import "ibc/applications/interchain_accounts/controller/v1/controller.proto"; +import "ibc/applications/interchain_accounts/host/v1/host.proto"; + +// GenesisState defines the interchain accounts genesis state +message GenesisState { + ControllerGenesisState controller_genesis_state = 1 [(gogoproto.nullable) = false]; + HostGenesisState host_genesis_state = 2 [(gogoproto.nullable) = false]; +} + +// ControllerGenesisState defines the interchain accounts controller genesis state +message ControllerGenesisState { + repeated ActiveChannel active_channels = 1 [(gogoproto.nullable) = false]; + repeated RegisteredInterchainAccount interchain_accounts = 2 [(gogoproto.nullable) = false]; + repeated string ports = 3; + ibc.applications.interchain_accounts.controller.v1.Params params = 4 [(gogoproto.nullable) = false]; +} + +// HostGenesisState defines the interchain accounts host genesis state +message HostGenesisState { + repeated ActiveChannel active_channels = 1 [(gogoproto.nullable) = false]; + repeated RegisteredInterchainAccount interchain_accounts = 2 [(gogoproto.nullable) = false]; + string port = 3; + ibc.applications.interchain_accounts.host.v1.Params params = 4 [(gogoproto.nullable) = false]; +} + +// ActiveChannel contains a connection ID, port ID and associated active channel ID, as well as a boolean flag to +// indicate if the channel is middleware enabled +message ActiveChannel { + string connection_id = 1; + string port_id = 2; + string channel_id = 3; + bool is_middleware_enabled = 4; +} + +// RegisteredInterchainAccount contains a connection ID, port ID and associated interchain account address +message RegisteredInterchainAccount { + string connection_id = 1; + string port_id = 2; + string account_address = 3; +} \ No newline at end of file diff --git a/third_party/proto/ibc/interchain_accounts/host/v1/host.proto b/third_party/proto/ibc/interchain_accounts/host/v1/host.proto new file mode 100644 index 000000000..f03685711 --- /dev/null +++ b/third_party/proto/ibc/interchain_accounts/host/v1/host.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package ibc.applications.interchain_accounts.host.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/host/types"; + +// Params defines the set of on-chain interchain accounts parameters. +// The following parameters may be used to disable the host submodule. +message Params { + // host_enabled enables or disables the host submodule. + bool host_enabled = 1; + // allow_messages defines a list of sdk message typeURLs allowed to be executed on a host chain. + repeated string allow_messages = 2; +} diff --git a/third_party/proto/ibc/interchain_accounts/host/v1/query.proto b/third_party/proto/ibc/interchain_accounts/host/v1/query.proto new file mode 100644 index 000000000..6f206a14c --- /dev/null +++ b/third_party/proto/ibc/interchain_accounts/host/v1/query.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; + +package ibc.applications.interchain_accounts.host.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/host/types"; + +import "google/api/annotations.proto"; +import "ibc/applications/interchain_accounts/host/v1/host.proto"; + +// Query provides defines the gRPC querier service. +service Query { + // Params queries all parameters of the ICA host submodule. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/ibc/apps/interchain_accounts/host/v1/params"; + } +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // params defines the parameters of the module. + Params params = 1; +} diff --git a/third_party/proto/ibc/interchain_accounts/host/v1/tx.proto b/third_party/proto/ibc/interchain_accounts/host/v1/tx.proto new file mode 100644 index 000000000..5a8073bc9 --- /dev/null +++ b/third_party/proto/ibc/interchain_accounts/host/v1/tx.proto @@ -0,0 +1,35 @@ +syntax = "proto3"; + +package ibc.applications.interchain_accounts.host.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/host/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/msg/v1/msg.proto"; +import "ibc/applications/interchain_accounts/host/v1/host.proto"; + +// Msg defines the 27-interchain-accounts/host Msg service. +service Msg { + option (cosmos.msg.v1.service) = true; + + // UpdateParams defines a rpc handler for MsgUpdateParams. + rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); +} + +// MsgUpdateParams defines the payload for Msg/UpdateParams +message MsgUpdateParams { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + // signer address + string signer = 1; + + // params defines the 27-interchain-accounts/host parameters to update. + // + // NOTE: All parameters must be supplied. + Params params = 2 [(gogoproto.nullable) = false]; +} + +// MsgUpdateParamsResponse defines the response for Msg/UpdateParams +message MsgUpdateParamsResponse {} diff --git a/third_party/proto/ibc/interchain_accounts/v1/account.proto b/third_party/proto/ibc/interchain_accounts/v1/account.proto new file mode 100644 index 000000000..4a6947c1c --- /dev/null +++ b/third_party/proto/ibc/interchain_accounts/v1/account.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +package ibc.applications.interchain_accounts.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types"; + +import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; +import "cosmos/auth/v1beta1/auth.proto"; + +// An InterchainAccount is defined as a BaseAccount & the address of the account owner on the controller chain +message InterchainAccount { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + option (cosmos_proto.implements_interface) = "ibc.applications.interchain_accounts.v1.InterchainAccountI"; + + cosmos.auth.v1beta1.BaseAccount base_account = 1 [(gogoproto.embed) = true]; + string account_owner = 2; +} diff --git a/third_party/proto/ibc/interchain_accounts/v1/metadata.proto b/third_party/proto/ibc/interchain_accounts/v1/metadata.proto new file mode 100644 index 000000000..df72b41eb --- /dev/null +++ b/third_party/proto/ibc/interchain_accounts/v1/metadata.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; + +package ibc.applications.interchain_accounts.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types"; + +// Metadata defines a set of protocol specific data encoded into the ICS27 channel version bytestring +// See ICS004: https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#Versioning +message Metadata { + // version defines the ICS27 protocol version + string version = 1; + // controller_connection_id is the connection identifier associated with the controller chain + string controller_connection_id = 2; + // host_connection_id is the connection identifier associated with the host chain + string host_connection_id = 3; + // address defines the interchain account address to be fulfilled upon the OnChanOpenTry handshake step + // NOTE: the address field is empty on the OnChanOpenInit handshake step + string address = 4; + // encoding defines the supported codec format + string encoding = 5; + // tx_type defines the type of transactions the interchain account can execute + string tx_type = 6; +} diff --git a/third_party/proto/ibc/interchain_accounts/v1/packet.proto b/third_party/proto/ibc/interchain_accounts/v1/packet.proto new file mode 100644 index 000000000..f75a1463e --- /dev/null +++ b/third_party/proto/ibc/interchain_accounts/v1/packet.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; + +package ibc.applications.interchain_accounts.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types"; + +import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; + +// Type defines a classification of message issued from a controller chain to its associated interchain accounts +// host +enum Type { + option (gogoproto.goproto_enum_prefix) = false; + + // Default zero value enumeration + TYPE_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNSPECIFIED"]; + // Execute a transaction on an interchain accounts host chain + TYPE_EXECUTE_TX = 1 [(gogoproto.enumvalue_customname) = "EXECUTE_TX"]; +} + +// InterchainAccountPacketData is comprised of a raw transaction, type of transaction and optional memo field. +message InterchainAccountPacketData { + Type type = 1; + bytes data = 2; + string memo = 3; +} + +// CosmosTx contains a list of sdk.Msg's. It should be used when sending transactions to an SDK host chain. +message CosmosTx { + repeated google.protobuf.Any messages = 1; +} diff --git a/third_party/proto/ibc/lightclients/solomachine/v2/solomachine.proto b/third_party/proto/ibc/lightclients/solomachine/v2/solomachine.proto index fb2f076a4..9dc2690c5 100644 --- a/third_party/proto/ibc/lightclients/solomachine/v2/solomachine.proto +++ b/third_party/proto/ibc/lightclients/solomachine/v2/solomachine.proto @@ -16,11 +16,11 @@ message ClientState { // latest sequence of the client state uint64 sequence = 1; // frozen sequence of the solo machine - bool is_frozen = 2 [(gogoproto.moretags) = "yaml:\"is_frozen\""]; - ConsensusState consensus_state = 3 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; + bool is_frozen = 2; + ConsensusState consensus_state = 3; // when set to true, will allow governance to update a solo machine client. // The client will be unfrozen if it is frozen. - bool allow_update_after_proposal = 4 [(gogoproto.moretags) = "yaml:\"allow_update_after_proposal\""]; + bool allow_update_after_proposal = 4; } // ConsensusState defines a solo machine consensus state. The sequence of a @@ -29,7 +29,7 @@ message ClientState { message ConsensusState { option (gogoproto.goproto_getters) = false; // public key of the solo machine - google.protobuf.Any public_key = 1 [(gogoproto.moretags) = "yaml:\"public_key\""]; + google.protobuf.Any public_key = 1; // diversifier allows the same public key to be re-used across different solo // machine clients (potentially on different chains) without being considered // misbehaviour. @@ -44,18 +44,18 @@ message Header { uint64 sequence = 1; uint64 timestamp = 2; bytes signature = 3; - google.protobuf.Any new_public_key = 4 [(gogoproto.moretags) = "yaml:\"new_public_key\""]; - string new_diversifier = 5 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; + google.protobuf.Any new_public_key = 4; + string new_diversifier = 5; } // Misbehaviour defines misbehaviour for a solo machine which consists // of a sequence and two signatures over different messages at that sequence. message Misbehaviour { option (gogoproto.goproto_getters) = false; - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + string client_id = 1; uint64 sequence = 2; - SignatureAndData signature_one = 3 [(gogoproto.moretags) = "yaml:\"signature_one\""]; - SignatureAndData signature_two = 4 [(gogoproto.moretags) = "yaml:\"signature_two\""]; + SignatureAndData signature_one = 3; + SignatureAndData signature_two = 4; } // SignatureAndData contains a signature and the data signed over to create that @@ -63,7 +63,7 @@ message Misbehaviour { message SignatureAndData { option (gogoproto.goproto_getters) = false; bytes signature = 1; - DataType data_type = 2 [(gogoproto.moretags) = "yaml:\"data_type\""]; + DataType data_type = 2; bytes data = 3; uint64 timestamp = 4; } @@ -72,7 +72,7 @@ message SignatureAndData { // signature. message TimestampedSignatureData { option (gogoproto.goproto_getters) = false; - bytes signature_data = 1 [(gogoproto.moretags) = "yaml:\"signature_data\""]; + bytes signature_data = 1; uint64 timestamp = 2; } @@ -84,7 +84,7 @@ message SignBytes { uint64 timestamp = 2; string diversifier = 3; // type of the data used - DataType data_type = 4 [(gogoproto.moretags) = "yaml:\"data_type\""]; + DataType data_type = 4; // marshaled data bytes data = 5; } @@ -121,9 +121,9 @@ message HeaderData { option (gogoproto.goproto_getters) = false; // header public key - google.protobuf.Any new_pub_key = 1 [(gogoproto.moretags) = "yaml:\"new_pub_key\""]; + google.protobuf.Any new_pub_key = 1; // header diversifier - string new_diversifier = 2 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; + string new_diversifier = 2; } // ClientStateData returns the SignBytes data for client state verification. @@ -131,7 +131,7 @@ message ClientStateData { option (gogoproto.goproto_getters) = false; bytes path = 1; - google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""]; + google.protobuf.Any client_state = 2; } // ConsensusStateData returns the SignBytes data for consensus state @@ -140,7 +140,7 @@ message ConsensusStateData { option (gogoproto.goproto_getters) = false; bytes path = 1; - google.protobuf.Any consensus_state = 2 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; + google.protobuf.Any consensus_state = 2; } // ConnectionStateData returns the SignBytes data for connection state @@ -185,5 +185,5 @@ message PacketReceiptAbsenceData { // sequence to be received. message NextSequenceRecvData { bytes path = 1; - uint64 next_seq_recv = 2 [(gogoproto.moretags) = "yaml:\"next_seq_recv\""]; + uint64 next_seq_recv = 2; } diff --git a/third_party/proto/ibc/lightclients/solomachine/v3/solomachine.proto b/third_party/proto/ibc/lightclients/solomachine/v3/solomachine.proto index 38f9328c7..194905b38 100644 --- a/third_party/proto/ibc/lightclients/solomachine/v3/solomachine.proto +++ b/third_party/proto/ibc/lightclients/solomachine/v3/solomachine.proto @@ -14,8 +14,8 @@ message ClientState { // latest sequence of the client state uint64 sequence = 1; // frozen sequence of the solo machine - bool is_frozen = 2 [(gogoproto.moretags) = "yaml:\"is_frozen\""]; - ConsensusState consensus_state = 3 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; + bool is_frozen = 2; + ConsensusState consensus_state = 3; } // ConsensusState defines a solo machine consensus state. The sequence of a @@ -24,7 +24,7 @@ message ClientState { message ConsensusState { option (gogoproto.goproto_getters) = false; // public key of the solo machine - google.protobuf.Any public_key = 1 [(gogoproto.moretags) = "yaml:\"public_key\""]; + google.protobuf.Any public_key = 1; // diversifier allows the same public key to be re-used across different solo // machine clients (potentially on different chains) without being considered // misbehaviour. @@ -38,8 +38,8 @@ message Header { uint64 timestamp = 1; bytes signature = 2; - google.protobuf.Any new_public_key = 3 [(gogoproto.moretags) = "yaml:\"new_public_key\""]; - string new_diversifier = 4 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; + google.protobuf.Any new_public_key = 3; + string new_diversifier = 4; } // Misbehaviour defines misbehaviour for a solo machine which consists @@ -48,8 +48,8 @@ message Misbehaviour { option (gogoproto.goproto_getters) = false; uint64 sequence = 1; - SignatureAndData signature_one = 2 [(gogoproto.moretags) = "yaml:\"signature_one\""]; - SignatureAndData signature_two = 3 [(gogoproto.moretags) = "yaml:\"signature_two\""]; + SignatureAndData signature_one = 2; + SignatureAndData signature_two = 3; } // SignatureAndData contains a signature and the data signed over to create that @@ -68,7 +68,7 @@ message SignatureAndData { message TimestampedSignatureData { option (gogoproto.goproto_getters) = false; - bytes signature_data = 1 [(gogoproto.moretags) = "yaml:\"signature_data\""]; + bytes signature_data = 1; uint64 timestamp = 2; } @@ -93,7 +93,7 @@ message HeaderData { option (gogoproto.goproto_getters) = false; // header public key - google.protobuf.Any new_pub_key = 1 [(gogoproto.moretags) = "yaml:\"new_pub_key\""]; + google.protobuf.Any new_pub_key = 1; // header diversifier - string new_diversifier = 2 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; + string new_diversifier = 2; } diff --git a/third_party/proto/ibc/lightclients/tendermint/v1/tendermint.proto b/third_party/proto/ibc/lightclients/tendermint/v1/tendermint.proto index bb21775dc..505361222 100644 --- a/third_party/proto/ibc/lightclients/tendermint/v1/tendermint.proto +++ b/third_party/proto/ibc/lightclients/tendermint/v1/tendermint.proto @@ -19,29 +19,21 @@ message ClientState { option (gogoproto.goproto_getters) = false; string chain_id = 1; - Fraction trust_level = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"trust_level\""]; + Fraction trust_level = 2 [(gogoproto.nullable) = false]; // duration of the period since the LastestTimestamp during which the // submitted headers are valid for upgrade - google.protobuf.Duration trusting_period = 3 - [(gogoproto.nullable) = false, (gogoproto.stdduration) = true, (gogoproto.moretags) = "yaml:\"trusting_period\""]; + google.protobuf.Duration trusting_period = 3 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; // duration of the staking unbonding period - google.protobuf.Duration unbonding_period = 4 [ - (gogoproto.nullable) = false, - (gogoproto.stdduration) = true, - (gogoproto.moretags) = "yaml:\"unbonding_period\"" - ]; + google.protobuf.Duration unbonding_period = 4 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; // defines how much new (untrusted) header's Time can drift into the future. - google.protobuf.Duration max_clock_drift = 5 - [(gogoproto.nullable) = false, (gogoproto.stdduration) = true, (gogoproto.moretags) = "yaml:\"max_clock_drift\""]; + google.protobuf.Duration max_clock_drift = 5 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; // Block height when the client was frozen due to a misbehaviour - ibc.core.client.v1.Height frozen_height = 6 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"frozen_height\""]; + ibc.core.client.v1.Height frozen_height = 6 [(gogoproto.nullable) = false]; // Latest height the client was updated to - ibc.core.client.v1.Height latest_height = 7 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"latest_height\""]; + ibc.core.client.v1.Height latest_height = 7 [(gogoproto.nullable) = false]; // Proof specifications used in verifying counterparty state - repeated cosmos.ics23.v1.ProofSpec proof_specs = 8 [(gogoproto.moretags) = "yaml:\"proof_specs\""]; + repeated cosmos.ics23.v1.ProofSpec proof_specs = 8; // Path at which next upgraded client will be committed. // Each element corresponds to the key for a single CommitmentProof in the @@ -50,13 +42,12 @@ message ClientState { // under `{upgradepath}/{upgradeHeight}/consensusState` For SDK chains using // the default upgrade module, upgrade_path should be []string{"upgrade", // "upgradedIBCState"}` - repeated string upgrade_path = 9 [(gogoproto.moretags) = "yaml:\"upgrade_path\""]; + repeated string upgrade_path = 9; // allow_update_after_expiry is deprecated - bool allow_update_after_expiry = 10 [deprecated = true, (gogoproto.moretags) = "yaml:\"allow_update_after_expiry\""]; + bool allow_update_after_expiry = 10 [deprecated = true]; // allow_update_after_misbehaviour is deprecated - bool allow_update_after_misbehaviour = 11 - [deprecated = true, (gogoproto.moretags) = "yaml:\"allow_update_after_misbehaviour\""]; + bool allow_update_after_misbehaviour = 11 [deprecated = true]; } // ConsensusState defines the consensus state from Tendermint. @@ -67,11 +58,8 @@ message ConsensusState { // was stored. google.protobuf.Timestamp timestamp = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; // commitment root (i.e app hash) - ibc.core.commitment.v1.MerkleRoot root = 2 [(gogoproto.nullable) = false]; - bytes next_validators_hash = 3 [ - (gogoproto.casttype) = "github.com/cometbft/cometbft/libs/bytes.HexBytes", - (gogoproto.moretags) = "yaml:\"next_validators_hash\"" - ]; + ibc.core.commitment.v1.MerkleRoot root = 2 [(gogoproto.nullable) = false]; + bytes next_validators_hash = 3 [(gogoproto.casttype) = "github.com/cometbft/cometbft/libs/bytes.HexBytes"]; } // Misbehaviour is a wrapper over two conflicting Headers @@ -80,9 +68,9 @@ message Misbehaviour { option (gogoproto.goproto_getters) = false; // ClientID is deprecated - string client_id = 1 [deprecated = true, (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\""]; + string client_id = 1 [deprecated = true]; + Header header_1 = 2 [(gogoproto.customname) = "Header1"]; + Header header_2 = 3 [(gogoproto.customname) = "Header2"]; } // Header defines the Tendermint client consensus Header. @@ -98,13 +86,11 @@ message Misbehaviour { // hash to TrustedConsensusState.NextValidatorsHash since that is the last // trusted validator set at the TrustedHeight. message Header { - .tendermint.types.SignedHeader signed_header = 1 - [(gogoproto.embed) = true, (gogoproto.moretags) = "yaml:\"signed_header\""]; + .tendermint.types.SignedHeader signed_header = 1 [(gogoproto.embed) = true]; - .tendermint.types.ValidatorSet validator_set = 2 [(gogoproto.moretags) = "yaml:\"validator_set\""]; - ibc.core.client.v1.Height trusted_height = 3 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"trusted_height\""]; - .tendermint.types.ValidatorSet trusted_validators = 4 [(gogoproto.moretags) = "yaml:\"trusted_validators\""]; + .tendermint.types.ValidatorSet validator_set = 2; + ibc.core.client.v1.Height trusted_height = 3 [(gogoproto.nullable) = false]; + .tendermint.types.ValidatorSet trusted_validators = 4; } // Fraction defines the protobuf message type for tmmath.Fraction that only diff --git a/third_party/proto/ibc/lightclients/wasm/v1/genesis.proto b/third_party/proto/ibc/lightclients/wasm/v1/genesis.proto new file mode 100644 index 000000000..637ba1677 --- /dev/null +++ b/third_party/proto/ibc/lightclients/wasm/v1/genesis.proto @@ -0,0 +1,20 @@ + +syntax = "proto3"; +package ibc.lightclients.wasm.v1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"; + +// GenesisState defines 08-wasm's keeper genesis state +message GenesisState { + // uploaded light client wasm contracts + repeated Contract contracts = 1 [(gogoproto.nullable) = false]; +} + +// Contract stores contract code +message Contract { + option (gogoproto.goproto_getters) = false; + // contract byte code + bytes code_bytes = 1; +} \ No newline at end of file diff --git a/third_party/proto/ibc/lightclients/wasm/v1/query.proto b/third_party/proto/ibc/lightclients/wasm/v1/query.proto new file mode 100644 index 000000000..bbbed29dd --- /dev/null +++ b/third_party/proto/ibc/lightclients/wasm/v1/query.proto @@ -0,0 +1,46 @@ +syntax = "proto3"; +package ibc.lightclients.wasm.v1; + +import "google/api/annotations.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; + +option go_package = "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"; + +// Query service for wasm module +service Query { + // Get all Wasm checksums + rpc Checksums(QueryChecksumsRequest) returns (QueryChecksumsResponse) { + option (google.api.http).get = "/ibc/lightclients/wasm/v1/checksums"; + } + + // Get Wasm code for given checksum + rpc Code(QueryCodeRequest) returns (QueryCodeResponse) { + option (google.api.http).get = "/ibc/lightclients/wasm/v1/checksums/{checksum}/code"; + } +} + +// QueryChecksumsRequest is the request type for the Query/Checksums RPC method. +message QueryChecksumsRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryChecksumsResponse is the response type for the Query/Checksums RPC method. +message QueryChecksumsResponse { + // checksums is a list of the hex encoded checksums of all wasm codes stored. + repeated string checksums = 1; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryCodeRequest is the request type for the Query/Code RPC method. +message QueryCodeRequest { + // checksum is a hex encoded string of the code stored. + string checksum = 1; +} + +// QueryCodeResponse is the response type for the Query/Code RPC method. +message QueryCodeResponse { + bytes data = 1; +} diff --git a/third_party/proto/ibc/lightclients/wasm/v1/tx.proto b/third_party/proto/ibc/lightclients/wasm/v1/tx.proto new file mode 100644 index 000000000..d2fc46591 --- /dev/null +++ b/third_party/proto/ibc/lightclients/wasm/v1/tx.proto @@ -0,0 +1,66 @@ +syntax = "proto3"; +package ibc.lightclients.wasm.v1; + +option go_package = "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"; + +import "cosmos/msg/v1/msg.proto"; + +// Msg defines the ibc/08-wasm Msg service. +service Msg { + option (cosmos.msg.v1.service) = true; + + // StoreCode defines a rpc handler method for MsgStoreCode. + rpc StoreCode(MsgStoreCode) returns (MsgStoreCodeResponse); + + // RemoveChecksum defines a rpc handler method for MsgRemoveChecksum. + rpc RemoveChecksum(MsgRemoveChecksum) returns (MsgRemoveChecksumResponse); + + // MigrateContract defines a rpc handler method for MsgMigrateContract. + rpc MigrateContract(MsgMigrateContract) returns (MsgMigrateContractResponse); +} + +// MsgStoreCode defines the request type for the StoreCode rpc. +message MsgStoreCode { + option (cosmos.msg.v1.signer) = "signer"; + + // signer address + string signer = 1; + // wasm byte code of light client contract. It can be raw or gzip compressed + bytes wasm_byte_code = 2; +} + +// MsgStoreCodeResponse defines the response type for the StoreCode rpc +message MsgStoreCodeResponse { + // checksum is the sha256 hash of the stored code + bytes checksum = 1; +} + +// MsgRemoveChecksum defines the request type for the MsgRemoveChecksum rpc. +message MsgRemoveChecksum { + option (cosmos.msg.v1.signer) = "signer"; + + // signer address + string signer = 1; + // checksum is the sha256 hash to be removed from the store + bytes checksum = 2; +} + +// MsgStoreChecksumResponse defines the response type for the StoreCode rpc +message MsgRemoveChecksumResponse {} + +// MsgMigrateContract defines the request type for the MigrateContract rpc. +message MsgMigrateContract { + option (cosmos.msg.v1.signer) = "signer"; + + // signer address + string signer = 1; + // the client id of the contract + string client_id = 2; + // checksum is the sha256 hash of the new wasm byte code for the contract + bytes checksum = 3; + // the json encoded message to be passed to the contract on migration + bytes msg = 4; +} + +// MsgMigrateContractResponse defines the response type for the MigrateContract rpc +message MsgMigrateContractResponse {} diff --git a/third_party/proto/ibc/lightclients/wasm/v1/wasm.proto b/third_party/proto/ibc/lightclients/wasm/v1/wasm.proto new file mode 100644 index 000000000..b6a45e3d8 --- /dev/null +++ b/third_party/proto/ibc/lightclients/wasm/v1/wasm.proto @@ -0,0 +1,43 @@ + +syntax = "proto3"; +package ibc.lightclients.wasm.v1; + +import "gogoproto/gogo.proto"; +import "ibc/core/client/v1/client.proto"; + +option go_package = "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"; + +// Wasm light client's Client state +message ClientState { + option (gogoproto.goproto_getters) = false; + // bytes encoding the client state of the underlying light client + // implemented as a Wasm contract. + bytes data = 1; + bytes checksum = 2; + ibc.core.client.v1.Height latest_height = 3 [(gogoproto.nullable) = false]; +} + +// Wasm light client's ConsensusState +message ConsensusState { + option (gogoproto.goproto_getters) = false; + // bytes encoding the consensus state of the underlying light client + // implemented as a Wasm contract. + bytes data = 1; +} + +// Wasm light client message (either header(s) or misbehaviour) +message ClientMessage { + option (gogoproto.goproto_getters) = false; + + bytes data = 1; +} + +// Checksums defines a list of all checksums that are stored +// +// Deprecated: This message is deprecated in favor of storing the checksums +// using a Collections.KeySet. +message Checksums { + option deprecated = true; + + repeated bytes checksums = 1; +} \ No newline at end of file diff --git a/third_party/proto/ibc/localhost/v2/localhost.proto b/third_party/proto/ibc/localhost/v2/localhost.proto new file mode 100644 index 000000000..635db8521 --- /dev/null +++ b/third_party/proto/ibc/localhost/v2/localhost.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +package ibc.lightclients.localhost.v2; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/light-clients/09-localhost;localhost"; + +import "ibc/core/client/v1/client.proto"; +import "gogoproto/gogo.proto"; + +// ClientState defines the 09-localhost client state +message ClientState { + option (gogoproto.goproto_getters) = false; + + // the latest block height + ibc.core.client.v1.Height latest_height = 1 [(gogoproto.nullable) = false]; +} diff --git a/third_party/proto/ibc/solomachine/v2/solomachine.proto b/third_party/proto/ibc/solomachine/v2/solomachine.proto new file mode 100644 index 000000000..9dc2690c5 --- /dev/null +++ b/third_party/proto/ibc/solomachine/v2/solomachine.proto @@ -0,0 +1,189 @@ +syntax = "proto3"; + +package ibc.lightclients.solomachine.v2; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/core/02-client/migrations/v7"; + +import "ibc/core/connection/v1/connection.proto"; +import "ibc/core/channel/v1/channel.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +// ClientState defines a solo machine client that tracks the current consensus +// state and if the client is frozen. +message ClientState { + option (gogoproto.goproto_getters) = false; + // latest sequence of the client state + uint64 sequence = 1; + // frozen sequence of the solo machine + bool is_frozen = 2; + ConsensusState consensus_state = 3; + // when set to true, will allow governance to update a solo machine client. + // The client will be unfrozen if it is frozen. + bool allow_update_after_proposal = 4; +} + +// ConsensusState defines a solo machine consensus state. The sequence of a +// consensus state is contained in the "height" key used in storing the +// consensus state. +message ConsensusState { + option (gogoproto.goproto_getters) = false; + // public key of the solo machine + google.protobuf.Any public_key = 1; + // diversifier allows the same public key to be re-used across different solo + // machine clients (potentially on different chains) without being considered + // misbehaviour. + string diversifier = 2; + uint64 timestamp = 3; +} + +// Header defines a solo machine consensus header +message Header { + option (gogoproto.goproto_getters) = false; + // sequence to update solo machine public key at + uint64 sequence = 1; + uint64 timestamp = 2; + bytes signature = 3; + google.protobuf.Any new_public_key = 4; + string new_diversifier = 5; +} + +// Misbehaviour defines misbehaviour for a solo machine which consists +// of a sequence and two signatures over different messages at that sequence. +message Misbehaviour { + option (gogoproto.goproto_getters) = false; + string client_id = 1; + uint64 sequence = 2; + SignatureAndData signature_one = 3; + SignatureAndData signature_two = 4; +} + +// SignatureAndData contains a signature and the data signed over to create that +// signature. +message SignatureAndData { + option (gogoproto.goproto_getters) = false; + bytes signature = 1; + DataType data_type = 2; + bytes data = 3; + uint64 timestamp = 4; +} + +// TimestampedSignatureData contains the signature data and the timestamp of the +// signature. +message TimestampedSignatureData { + option (gogoproto.goproto_getters) = false; + bytes signature_data = 1; + uint64 timestamp = 2; +} + +// SignBytes defines the signed bytes used for signature verification. +message SignBytes { + option (gogoproto.goproto_getters) = false; + + uint64 sequence = 1; + uint64 timestamp = 2; + string diversifier = 3; + // type of the data used + DataType data_type = 4; + // marshaled data + bytes data = 5; +} + +// DataType defines the type of solo machine proof being created. This is done +// to preserve uniqueness of different data sign byte encodings. +enum DataType { + option (gogoproto.goproto_enum_prefix) = false; + + // Default State + DATA_TYPE_UNINITIALIZED_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNSPECIFIED"]; + // Data type for client state verification + DATA_TYPE_CLIENT_STATE = 1 [(gogoproto.enumvalue_customname) = "CLIENT"]; + // Data type for consensus state verification + DATA_TYPE_CONSENSUS_STATE = 2 [(gogoproto.enumvalue_customname) = "CONSENSUS"]; + // Data type for connection state verification + DATA_TYPE_CONNECTION_STATE = 3 [(gogoproto.enumvalue_customname) = "CONNECTION"]; + // Data type for channel state verification + DATA_TYPE_CHANNEL_STATE = 4 [(gogoproto.enumvalue_customname) = "CHANNEL"]; + // Data type for packet commitment verification + DATA_TYPE_PACKET_COMMITMENT = 5 [(gogoproto.enumvalue_customname) = "PACKETCOMMITMENT"]; + // Data type for packet acknowledgement verification + DATA_TYPE_PACKET_ACKNOWLEDGEMENT = 6 [(gogoproto.enumvalue_customname) = "PACKETACKNOWLEDGEMENT"]; + // Data type for packet receipt absence verification + DATA_TYPE_PACKET_RECEIPT_ABSENCE = 7 [(gogoproto.enumvalue_customname) = "PACKETRECEIPTABSENCE"]; + // Data type for next sequence recv verification + DATA_TYPE_NEXT_SEQUENCE_RECV = 8 [(gogoproto.enumvalue_customname) = "NEXTSEQUENCERECV"]; + // Data type for header verification + DATA_TYPE_HEADER = 9 [(gogoproto.enumvalue_customname) = "HEADER"]; +} + +// HeaderData returns the SignBytes data for update verification. +message HeaderData { + option (gogoproto.goproto_getters) = false; + + // header public key + google.protobuf.Any new_pub_key = 1; + // header diversifier + string new_diversifier = 2; +} + +// ClientStateData returns the SignBytes data for client state verification. +message ClientStateData { + option (gogoproto.goproto_getters) = false; + + bytes path = 1; + google.protobuf.Any client_state = 2; +} + +// ConsensusStateData returns the SignBytes data for consensus state +// verification. +message ConsensusStateData { + option (gogoproto.goproto_getters) = false; + + bytes path = 1; + google.protobuf.Any consensus_state = 2; +} + +// ConnectionStateData returns the SignBytes data for connection state +// verification. +message ConnectionStateData { + option (gogoproto.goproto_getters) = false; + + bytes path = 1; + ibc.core.connection.v1.ConnectionEnd connection = 2; +} + +// ChannelStateData returns the SignBytes data for channel state +// verification. +message ChannelStateData { + option (gogoproto.goproto_getters) = false; + + bytes path = 1; + ibc.core.channel.v1.Channel channel = 2; +} + +// PacketCommitmentData returns the SignBytes data for packet commitment +// verification. +message PacketCommitmentData { + bytes path = 1; + bytes commitment = 2; +} + +// PacketAcknowledgementData returns the SignBytes data for acknowledgement +// verification. +message PacketAcknowledgementData { + bytes path = 1; + bytes acknowledgement = 2; +} + +// PacketReceiptAbsenceData returns the SignBytes data for +// packet receipt absence verification. +message PacketReceiptAbsenceData { + bytes path = 1; +} + +// NextSequenceRecvData returns the SignBytes data for verification of the next +// sequence to be received. +message NextSequenceRecvData { + bytes path = 1; + uint64 next_seq_recv = 2; +} diff --git a/third_party/proto/ibc/solomachine/v3/solomachine.proto b/third_party/proto/ibc/solomachine/v3/solomachine.proto new file mode 100644 index 000000000..194905b38 --- /dev/null +++ b/third_party/proto/ibc/solomachine/v3/solomachine.proto @@ -0,0 +1,99 @@ +syntax = "proto3"; + +package ibc.lightclients.solomachine.v3; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/light-clients/06-solomachine;solomachine"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +// ClientState defines a solo machine client that tracks the current consensus +// state and if the client is frozen. +message ClientState { + option (gogoproto.goproto_getters) = false; + // latest sequence of the client state + uint64 sequence = 1; + // frozen sequence of the solo machine + bool is_frozen = 2; + ConsensusState consensus_state = 3; +} + +// ConsensusState defines a solo machine consensus state. The sequence of a +// consensus state is contained in the "height" key used in storing the +// consensus state. +message ConsensusState { + option (gogoproto.goproto_getters) = false; + // public key of the solo machine + google.protobuf.Any public_key = 1; + // diversifier allows the same public key to be re-used across different solo + // machine clients (potentially on different chains) without being considered + // misbehaviour. + string diversifier = 2; + uint64 timestamp = 3; +} + +// Header defines a solo machine consensus header +message Header { + option (gogoproto.goproto_getters) = false; + + uint64 timestamp = 1; + bytes signature = 2; + google.protobuf.Any new_public_key = 3; + string new_diversifier = 4; +} + +// Misbehaviour defines misbehaviour for a solo machine which consists +// of a sequence and two signatures over different messages at that sequence. +message Misbehaviour { + option (gogoproto.goproto_getters) = false; + + uint64 sequence = 1; + SignatureAndData signature_one = 2; + SignatureAndData signature_two = 3; +} + +// SignatureAndData contains a signature and the data signed over to create that +// signature. +message SignatureAndData { + option (gogoproto.goproto_getters) = false; + + bytes signature = 1; + bytes path = 2; + bytes data = 3; + uint64 timestamp = 4; +} + +// TimestampedSignatureData contains the signature data and the timestamp of the +// signature. +message TimestampedSignatureData { + option (gogoproto.goproto_getters) = false; + + bytes signature_data = 1; + uint64 timestamp = 2; +} + +// SignBytes defines the signed bytes used for signature verification. +message SignBytes { + option (gogoproto.goproto_getters) = false; + + // the sequence number + uint64 sequence = 1; + // the proof timestamp + uint64 timestamp = 2; + // the public key diversifier + string diversifier = 3; + // the standardised path bytes + bytes path = 4; + // the marshaled data bytes + bytes data = 5; +} + +// HeaderData returns the SignBytes data for update verification. +message HeaderData { + option (gogoproto.goproto_getters) = false; + + // header public key + google.protobuf.Any new_pub_key = 1; + // header diversifier + string new_diversifier = 2; +} diff --git a/third_party/proto/ibc/tendermint/v1/tendermint.proto b/third_party/proto/ibc/tendermint/v1/tendermint.proto new file mode 100644 index 000000000..505361222 --- /dev/null +++ b/third_party/proto/ibc/tendermint/v1/tendermint.proto @@ -0,0 +1,101 @@ +syntax = "proto3"; + +package ibc.lightclients.tendermint.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint;tendermint"; + +import "tendermint/types/validator.proto"; +import "tendermint/types/types.proto"; +import "cosmos/ics23/v1/proofs.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; +import "ibc/core/client/v1/client.proto"; +import "ibc/core/commitment/v1/commitment.proto"; +import "gogoproto/gogo.proto"; + +// ClientState from Tendermint tracks the current validator set, latest height, +// and a possible frozen height. +message ClientState { + option (gogoproto.goproto_getters) = false; + + string chain_id = 1; + Fraction trust_level = 2 [(gogoproto.nullable) = false]; + // duration of the period since the LastestTimestamp during which the + // submitted headers are valid for upgrade + google.protobuf.Duration trusting_period = 3 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; + // duration of the staking unbonding period + google.protobuf.Duration unbonding_period = 4 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; + // defines how much new (untrusted) header's Time can drift into the future. + google.protobuf.Duration max_clock_drift = 5 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; + // Block height when the client was frozen due to a misbehaviour + ibc.core.client.v1.Height frozen_height = 6 [(gogoproto.nullable) = false]; + // Latest height the client was updated to + ibc.core.client.v1.Height latest_height = 7 [(gogoproto.nullable) = false]; + + // Proof specifications used in verifying counterparty state + repeated cosmos.ics23.v1.ProofSpec proof_specs = 8; + + // Path at which next upgraded client will be committed. + // Each element corresponds to the key for a single CommitmentProof in the + // chained proof. NOTE: ClientState must stored under + // `{upgradePath}/{upgradeHeight}/clientState` ConsensusState must be stored + // under `{upgradepath}/{upgradeHeight}/consensusState` For SDK chains using + // the default upgrade module, upgrade_path should be []string{"upgrade", + // "upgradedIBCState"}` + repeated string upgrade_path = 9; + + // allow_update_after_expiry is deprecated + bool allow_update_after_expiry = 10 [deprecated = true]; + // allow_update_after_misbehaviour is deprecated + bool allow_update_after_misbehaviour = 11 [deprecated = true]; +} + +// ConsensusState defines the consensus state from Tendermint. +message ConsensusState { + option (gogoproto.goproto_getters) = false; + + // timestamp that corresponds to the block height in which the ConsensusState + // was stored. + google.protobuf.Timestamp timestamp = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + // commitment root (i.e app hash) + ibc.core.commitment.v1.MerkleRoot root = 2 [(gogoproto.nullable) = false]; + bytes next_validators_hash = 3 [(gogoproto.casttype) = "github.com/cometbft/cometbft/libs/bytes.HexBytes"]; +} + +// Misbehaviour is a wrapper over two conflicting Headers +// that implements Misbehaviour interface expected by ICS-02 +message Misbehaviour { + option (gogoproto.goproto_getters) = false; + + // ClientID is deprecated + string client_id = 1 [deprecated = true]; + Header header_1 = 2 [(gogoproto.customname) = "Header1"]; + Header header_2 = 3 [(gogoproto.customname) = "Header2"]; +} + +// Header defines the Tendermint client consensus Header. +// It encapsulates all the information necessary to update from a trusted +// Tendermint ConsensusState. The inclusion of TrustedHeight and +// TrustedValidators allows this update to process correctly, so long as the +// ConsensusState for the TrustedHeight exists, this removes race conditions +// among relayers The SignedHeader and ValidatorSet are the new untrusted update +// fields for the client. The TrustedHeight is the height of a stored +// ConsensusState on the client that will be used to verify the new untrusted +// header. The Trusted ConsensusState must be within the unbonding period of +// current time in order to correctly verify, and the TrustedValidators must +// hash to TrustedConsensusState.NextValidatorsHash since that is the last +// trusted validator set at the TrustedHeight. +message Header { + .tendermint.types.SignedHeader signed_header = 1 [(gogoproto.embed) = true]; + + .tendermint.types.ValidatorSet validator_set = 2; + ibc.core.client.v1.Height trusted_height = 3 [(gogoproto.nullable) = false]; + .tendermint.types.ValidatorSet trusted_validators = 4; +} + +// Fraction defines the protobuf message type for tmmath.Fraction that only +// supports positive values. +message Fraction { + uint64 numerator = 1; + uint64 denominator = 2; +} diff --git a/third_party/proto/ibc/transfer/v1/authz.proto b/third_party/proto/ibc/transfer/v1/authz.proto new file mode 100644 index 000000000..e7561b070 --- /dev/null +++ b/third_party/proto/ibc/transfer/v1/authz.proto @@ -0,0 +1,34 @@ +syntax = "proto3"; + +package ibc.applications.transfer.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"; + +import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +// Allocation defines the spend limit for a particular port and channel +message Allocation { + // the port on which the packet will be sent + string source_port = 1; + // the channel by which the packet will be sent + string source_channel = 2; + // spend limitation on the channel + repeated cosmos.base.v1beta1.Coin spend_limit = 3 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + // allow list of receivers, an empty allow list permits any receiver address + repeated string allow_list = 4; + // allow list of packet data keys, an empty list prohibits all packet data keys; + // a list only with "*" permits any packet data key + repeated string allowed_packet_data = 5; +} + +// TransferAuthorization allows the grantee to spend up to spend_limit coins from +// the granter's account for ibc transfer on a specific channel +message TransferAuthorization { + option (cosmos_proto.implements_interface) = "cosmos.authz.v1beta1.Authorization"; + + // port and channel amounts + repeated Allocation allocations = 1 [(gogoproto.nullable) = false]; +} diff --git a/third_party/proto/ibc/transfer/v1/genesis.proto b/third_party/proto/ibc/transfer/v1/genesis.proto new file mode 100644 index 000000000..f7d707f6c --- /dev/null +++ b/third_party/proto/ibc/transfer/v1/genesis.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; + +package ibc.applications.transfer.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"; + +import "ibc/applications/transfer/v1/transfer.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "gogoproto/gogo.proto"; + +// GenesisState defines the ibc-transfer genesis state +message GenesisState { + string port_id = 1; + repeated DenomTrace denom_traces = 2 [(gogoproto.castrepeated) = "Traces", (gogoproto.nullable) = false]; + Params params = 3 [(gogoproto.nullable) = false]; + // total_escrowed contains the total amount of tokens escrowed + // by the transfer module + repeated cosmos.base.v1beta1.Coin total_escrowed = 4 + [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false]; +} diff --git a/third_party/proto/ibc/transfer/v1/query.proto b/third_party/proto/ibc/transfer/v1/query.proto new file mode 100644 index 000000000..788296718 --- /dev/null +++ b/third_party/proto/ibc/transfer/v1/query.proto @@ -0,0 +1,121 @@ +syntax = "proto3"; + +package ibc.applications.transfer.v1; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "ibc/applications/transfer/v1/transfer.proto"; +import "google/api/annotations.proto"; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"; + +// Query provides defines the gRPC querier service. +service Query { + // DenomTraces queries all denomination traces. + rpc DenomTraces(QueryDenomTracesRequest) returns (QueryDenomTracesResponse) { + option (google.api.http).get = "/ibc/apps/transfer/v1/denom_traces"; + } + + // DenomTrace queries a denomination trace information. + rpc DenomTrace(QueryDenomTraceRequest) returns (QueryDenomTraceResponse) { + option (google.api.http).get = "/ibc/apps/transfer/v1/denom_traces/{hash=**}"; + } + + // Params queries all parameters of the ibc-transfer module. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/ibc/apps/transfer/v1/params"; + } + + // DenomHash queries a denomination hash information. + rpc DenomHash(QueryDenomHashRequest) returns (QueryDenomHashResponse) { + option (google.api.http).get = "/ibc/apps/transfer/v1/denom_hashes/{trace=**}"; + } + + // EscrowAddress returns the escrow address for a particular port and channel id. + rpc EscrowAddress(QueryEscrowAddressRequest) returns (QueryEscrowAddressResponse) { + option (google.api.http).get = "/ibc/apps/transfer/v1/channels/{channel_id}/ports/{port_id}/escrow_address"; + } + + // TotalEscrowForDenom returns the total amount of tokens in escrow based on the denom. + rpc TotalEscrowForDenom(QueryTotalEscrowForDenomRequest) returns (QueryTotalEscrowForDenomResponse) { + option (google.api.http).get = "/ibc/apps/transfer/v1/denoms/{denom=**}/total_escrow"; + } +} + +// QueryDenomTraceRequest is the request type for the Query/DenomTrace RPC +// method +message QueryDenomTraceRequest { + // hash (in hex format) or denom (full denom with ibc prefix) of the denomination trace information. + string hash = 1; +} + +// QueryDenomTraceResponse is the response type for the Query/DenomTrace RPC +// method. +message QueryDenomTraceResponse { + // denom_trace returns the requested denomination trace information. + DenomTrace denom_trace = 1; +} + +// QueryConnectionsRequest is the request type for the Query/DenomTraces RPC +// method +message QueryDenomTracesRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryConnectionsResponse is the response type for the Query/DenomTraces RPC +// method. +message QueryDenomTracesResponse { + // denom_traces returns all denominations trace information. + repeated DenomTrace denom_traces = 1 [(gogoproto.castrepeated) = "Traces", (gogoproto.nullable) = false]; + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // params defines the parameters of the module. + Params params = 1; +} + +// QueryDenomHashRequest is the request type for the Query/DenomHash RPC +// method +message QueryDenomHashRequest { + // The denomination trace ([port_id]/[channel_id])+/[denom] + string trace = 1; +} + +// QueryDenomHashResponse is the response type for the Query/DenomHash RPC +// method. +message QueryDenomHashResponse { + // hash (in hex format) of the denomination trace information. + string hash = 1; +} + +// QueryEscrowAddressRequest is the request type for the EscrowAddress RPC method. +message QueryEscrowAddressRequest { + // unique port identifier + string port_id = 1; + // unique channel identifier + string channel_id = 2; +} + +// QueryEscrowAddressResponse is the response type of the EscrowAddress RPC method. +message QueryEscrowAddressResponse { + // the escrow account address + string escrow_address = 1; +} + +// QueryTotalEscrowForDenomRequest is the request type for TotalEscrowForDenom RPC method. +message QueryTotalEscrowForDenomRequest { + string denom = 1; +} + +// QueryTotalEscrowForDenomResponse is the response type for TotalEscrowForDenom RPC method. +message QueryTotalEscrowForDenomResponse { + cosmos.base.v1beta1.Coin amount = 1 [(gogoproto.nullable) = false]; +} diff --git a/third_party/proto/ibc/transfer/v1/transfer.proto b/third_party/proto/ibc/transfer/v1/transfer.proto new file mode 100644 index 000000000..7f7723762 --- /dev/null +++ b/third_party/proto/ibc/transfer/v1/transfer.proto @@ -0,0 +1,28 @@ +syntax = "proto3"; + +package ibc.applications.transfer.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"; + +// DenomTrace contains the base denomination for ICS20 fungible tokens and the +// source tracing information path. +message DenomTrace { + // path defines the chain of port/channel identifiers used for tracing the + // source of the fungible token. + string path = 1; + // base denomination of the relayed fungible token. + string base_denom = 2; +} + +// Params defines the set of IBC transfer parameters. +// NOTE: To prevent a single token from being transferred, set the +// TransfersEnabled parameter to true and then set the bank module's SendEnabled +// parameter for the denomination to false. +message Params { + // send_enabled enables or disables all cross-chain token transfers from this + // chain. + bool send_enabled = 1; + // receive_enabled enables or disables all cross-chain token transfers to this + // chain. + bool receive_enabled = 2; +} diff --git a/third_party/proto/ibc/transfer/v1/tx.proto b/third_party/proto/ibc/transfer/v1/tx.proto new file mode 100644 index 000000000..42c70d3be --- /dev/null +++ b/third_party/proto/ibc/transfer/v1/tx.proto @@ -0,0 +1,79 @@ +syntax = "proto3"; + +package ibc.applications.transfer.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"; + +import "amino/amino.proto"; +import "gogoproto/gogo.proto"; +import "cosmos/msg/v1/msg.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "ibc/core/client/v1/client.proto"; +import "ibc/applications/transfer/v1/transfer.proto"; + +// Msg defines the ibc/transfer Msg service. +service Msg { + option (cosmos.msg.v1.service) = true; + + // Transfer defines a rpc handler method for MsgTransfer. + rpc Transfer(MsgTransfer) returns (MsgTransferResponse); + + // UpdateParams defines a rpc handler for MsgUpdateParams. + rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); +} + +// MsgTransfer defines a msg to transfer fungible tokens (i.e Coins) between +// ICS20 enabled chains. See ICS Spec here: +// https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structures +message MsgTransfer { + option (amino.name) = "cosmos-sdk/MsgTransfer"; + option (cosmos.msg.v1.signer) = "sender"; + + option (gogoproto.goproto_getters) = false; + + // the port on which the packet will be sent + string source_port = 1; + // the channel by which the packet will be sent + string source_channel = 2; + // the tokens to be transferred + cosmos.base.v1beta1.Coin token = 3 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; + // the sender address + string sender = 4; + // the recipient address on the destination chain + string receiver = 5; + // Timeout height relative to the current block height. + // The timeout is disabled when set to 0. + ibc.core.client.v1.Height timeout_height = 6 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; + // Timeout timestamp in absolute nanoseconds since unix epoch. + // The timeout is disabled when set to 0. + uint64 timeout_timestamp = 7; + // optional memo + string memo = 8; +} + +// MsgTransferResponse defines the Msg/Transfer response type. +message MsgTransferResponse { + option (gogoproto.goproto_getters) = false; + + // sequence number of the transfer packet sent + uint64 sequence = 1; +} + +// MsgUpdateParams is the Msg/UpdateParams request type. +message MsgUpdateParams { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + // signer address + string signer = 1; + + // params defines the transfer parameters to update. + // + // NOTE: All parameters must be supplied. + Params params = 2 [(gogoproto.nullable) = false]; +} + +// MsgUpdateParamsResponse defines the response structure for executing a +// MsgUpdateParams message. +message MsgUpdateParamsResponse {} \ No newline at end of file diff --git a/third_party/proto/ibc/transfer/v2/packet.proto b/third_party/proto/ibc/transfer/v2/packet.proto new file mode 100644 index 000000000..bff35bdd6 --- /dev/null +++ b/third_party/proto/ibc/transfer/v2/packet.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package ibc.applications.transfer.v2; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"; + +// FungibleTokenPacketData defines a struct for the packet payload +// See FungibleTokenPacketData spec: +// https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structures +message FungibleTokenPacketData { + // the token denomination to be transferred + string denom = 1; + // the token amount to be transferred + string amount = 2; + // the sender address + string sender = 3; + // the recipient address on the destination chain + string receiver = 4; + // optional memo + string memo = 5; +} diff --git a/third_party/proto/ibc/types/v1/genesis.proto b/third_party/proto/ibc/types/v1/genesis.proto new file mode 100644 index 000000000..4b34f6889 --- /dev/null +++ b/third_party/proto/ibc/types/v1/genesis.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; + +package ibc.core.types.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/core/types"; + +import "gogoproto/gogo.proto"; +import "ibc/core/client/v1/genesis.proto"; +import "ibc/core/connection/v1/genesis.proto"; +import "ibc/core/channel/v1/genesis.proto"; + +// GenesisState defines the ibc module's genesis state. +message GenesisState { + // ICS002 - Clients genesis state + ibc.core.client.v1.GenesisState client_genesis = 1 [(gogoproto.nullable) = false]; + // ICS003 - Connections genesis state + ibc.core.connection.v1.GenesisState connection_genesis = 2 [(gogoproto.nullable) = false]; + // ICS004 - Channel genesis state + ibc.core.channel.v1.GenesisState channel_genesis = 3 [(gogoproto.nullable) = false]; +} diff --git a/third_party/proto/ibc/wasm/v1/genesis.proto b/third_party/proto/ibc/wasm/v1/genesis.proto new file mode 100644 index 000000000..637ba1677 --- /dev/null +++ b/third_party/proto/ibc/wasm/v1/genesis.proto @@ -0,0 +1,20 @@ + +syntax = "proto3"; +package ibc.lightclients.wasm.v1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"; + +// GenesisState defines 08-wasm's keeper genesis state +message GenesisState { + // uploaded light client wasm contracts + repeated Contract contracts = 1 [(gogoproto.nullable) = false]; +} + +// Contract stores contract code +message Contract { + option (gogoproto.goproto_getters) = false; + // contract byte code + bytes code_bytes = 1; +} \ No newline at end of file diff --git a/third_party/proto/ibc/wasm/v1/query.proto b/third_party/proto/ibc/wasm/v1/query.proto new file mode 100644 index 000000000..bbbed29dd --- /dev/null +++ b/third_party/proto/ibc/wasm/v1/query.proto @@ -0,0 +1,46 @@ +syntax = "proto3"; +package ibc.lightclients.wasm.v1; + +import "google/api/annotations.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; + +option go_package = "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"; + +// Query service for wasm module +service Query { + // Get all Wasm checksums + rpc Checksums(QueryChecksumsRequest) returns (QueryChecksumsResponse) { + option (google.api.http).get = "/ibc/lightclients/wasm/v1/checksums"; + } + + // Get Wasm code for given checksum + rpc Code(QueryCodeRequest) returns (QueryCodeResponse) { + option (google.api.http).get = "/ibc/lightclients/wasm/v1/checksums/{checksum}/code"; + } +} + +// QueryChecksumsRequest is the request type for the Query/Checksums RPC method. +message QueryChecksumsRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryChecksumsResponse is the response type for the Query/Checksums RPC method. +message QueryChecksumsResponse { + // checksums is a list of the hex encoded checksums of all wasm codes stored. + repeated string checksums = 1; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryCodeRequest is the request type for the Query/Code RPC method. +message QueryCodeRequest { + // checksum is a hex encoded string of the code stored. + string checksum = 1; +} + +// QueryCodeResponse is the response type for the Query/Code RPC method. +message QueryCodeResponse { + bytes data = 1; +} diff --git a/third_party/proto/ibc/wasm/v1/tx.proto b/third_party/proto/ibc/wasm/v1/tx.proto new file mode 100644 index 000000000..d2fc46591 --- /dev/null +++ b/third_party/proto/ibc/wasm/v1/tx.proto @@ -0,0 +1,66 @@ +syntax = "proto3"; +package ibc.lightclients.wasm.v1; + +option go_package = "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"; + +import "cosmos/msg/v1/msg.proto"; + +// Msg defines the ibc/08-wasm Msg service. +service Msg { + option (cosmos.msg.v1.service) = true; + + // StoreCode defines a rpc handler method for MsgStoreCode. + rpc StoreCode(MsgStoreCode) returns (MsgStoreCodeResponse); + + // RemoveChecksum defines a rpc handler method for MsgRemoveChecksum. + rpc RemoveChecksum(MsgRemoveChecksum) returns (MsgRemoveChecksumResponse); + + // MigrateContract defines a rpc handler method for MsgMigrateContract. + rpc MigrateContract(MsgMigrateContract) returns (MsgMigrateContractResponse); +} + +// MsgStoreCode defines the request type for the StoreCode rpc. +message MsgStoreCode { + option (cosmos.msg.v1.signer) = "signer"; + + // signer address + string signer = 1; + // wasm byte code of light client contract. It can be raw or gzip compressed + bytes wasm_byte_code = 2; +} + +// MsgStoreCodeResponse defines the response type for the StoreCode rpc +message MsgStoreCodeResponse { + // checksum is the sha256 hash of the stored code + bytes checksum = 1; +} + +// MsgRemoveChecksum defines the request type for the MsgRemoveChecksum rpc. +message MsgRemoveChecksum { + option (cosmos.msg.v1.signer) = "signer"; + + // signer address + string signer = 1; + // checksum is the sha256 hash to be removed from the store + bytes checksum = 2; +} + +// MsgStoreChecksumResponse defines the response type for the StoreCode rpc +message MsgRemoveChecksumResponse {} + +// MsgMigrateContract defines the request type for the MigrateContract rpc. +message MsgMigrateContract { + option (cosmos.msg.v1.signer) = "signer"; + + // signer address + string signer = 1; + // the client id of the contract + string client_id = 2; + // checksum is the sha256 hash of the new wasm byte code for the contract + bytes checksum = 3; + // the json encoded message to be passed to the contract on migration + bytes msg = 4; +} + +// MsgMigrateContractResponse defines the response type for the MigrateContract rpc +message MsgMigrateContractResponse {} diff --git a/third_party/proto/ibc/wasm/v1/wasm.proto b/third_party/proto/ibc/wasm/v1/wasm.proto new file mode 100644 index 000000000..b6a45e3d8 --- /dev/null +++ b/third_party/proto/ibc/wasm/v1/wasm.proto @@ -0,0 +1,43 @@ + +syntax = "proto3"; +package ibc.lightclients.wasm.v1; + +import "gogoproto/gogo.proto"; +import "ibc/core/client/v1/client.proto"; + +option go_package = "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"; + +// Wasm light client's Client state +message ClientState { + option (gogoproto.goproto_getters) = false; + // bytes encoding the client state of the underlying light client + // implemented as a Wasm contract. + bytes data = 1; + bytes checksum = 2; + ibc.core.client.v1.Height latest_height = 3 [(gogoproto.nullable) = false]; +} + +// Wasm light client's ConsensusState +message ConsensusState { + option (gogoproto.goproto_getters) = false; + // bytes encoding the consensus state of the underlying light client + // implemented as a Wasm contract. + bytes data = 1; +} + +// Wasm light client message (either header(s) or misbehaviour) +message ClientMessage { + option (gogoproto.goproto_getters) = false; + + bytes data = 1; +} + +// Checksums defines a list of all checksums that are stored +// +// Deprecated: This message is deprecated in favor of storing the checksums +// using a Collections.KeySet. +message Checksums { + option deprecated = true; + + repeated bytes checksums = 1; +} \ No newline at end of file diff --git a/x/interchaintxs/keeper/msg_server.go b/x/interchaintxs/keeper/msg_server.go index 54c64e9e8..53f47483d 100644 --- a/x/interchaintxs/keeper/msg_server.go +++ b/x/interchaintxs/keeper/msg_server.go @@ -66,7 +66,7 @@ func (k Keeper) RegisterInterchainAccount(goCtx context.Context, msg *ictxtypes. Owner: icaOwner, ConnectionId: msg.ConnectionId, Version: "", // FIXME: empty version string doesn't look good - // underlying controller uses ORDER_ORDERED as default in case msg's ordering is NONE + // underlying controller uses ORDER_ORDERED as default in case msg's ordering is NONE // TODO: check now Ordering: msg.Ordering, }) if err != nil { diff --git a/x/interchaintxs/keeper/msg_server_test.go b/x/interchaintxs/keeper/msg_server_test.go index afd182224..5cecf14fa 100644 --- a/x/interchaintxs/keeper/msg_server_test.go +++ b/x/interchaintxs/keeper/msg_server_test.go @@ -2,6 +2,7 @@ package keeper_test import ( "fmt" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" "testing" "time" @@ -12,8 +13,6 @@ import ( wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" icacontrollertypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types" icatypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types" - channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" - feerefundertypes "github.com/neutron-org/neutron/v4/x/feerefunder/types" "github.com/neutron-org/neutron/v4/x/interchaintxs/keeper" diff --git a/x/interchaintxs/types/tx.pb.go b/x/interchaintxs/types/tx.pb.go index 4b18fd1a1..8db65cb59 100644 --- a/x/interchaintxs/types/tx.pb.go +++ b/x/interchaintxs/types/tx.pb.go @@ -341,56 +341,56 @@ var fileDescriptor_50f087790e59c806 = []byte{ 0xbd, 0xa3, 0xa1, 0xb1, 0x66, 0x77, 0xc7, 0xeb, 0x11, 0xd9, 0x19, 0x33, 0x33, 0x6b, 0xc5, 0x1d, 0xa2, 0x42, 0x54, 0x34, 0x14, 0x74, 0x57, 0x22, 0x0a, 0x94, 0x82, 0x1f, 0x40, 0x79, 0xe5, 0x89, 0x8a, 0x2a, 0xa0, 0xa4, 0x08, 0xf5, 0x15, 0xd4, 0x68, 0x76, 0x67, 0x1c, 0xdb, 0x3a, 0x5b, 0x11, - 0x8d, 0x3d, 0xef, 0xbd, 0x6f, 0xde, 0x37, 0xf3, 0xbe, 0x37, 0x6f, 0xc1, 0x1e, 0xc5, 0xa9, 0xe4, - 0x8c, 0x7a, 0x84, 0x4a, 0xcc, 0xc3, 0x21, 0x22, 0x54, 0x9e, 0x0b, 0x6f, 0xdc, 0xf6, 0xe4, 0x39, - 0x1c, 0x71, 0x26, 0x99, 0xed, 0x68, 0x08, 0x9c, 0x83, 0xc0, 0x71, 0xbb, 0xf6, 0x2e, 0x4a, 0x08, - 0x65, 0x5e, 0xf6, 0x9b, 0x83, 0x6b, 0xf5, 0x90, 0x89, 0x84, 0x09, 0x2f, 0x40, 0x02, 0x7b, 0xe3, - 0x76, 0x80, 0x25, 0x6a, 0x7b, 0x21, 0x23, 0x54, 0xc7, 0xb7, 0x75, 0x3c, 0x11, 0xb1, 0x22, 0x49, - 0x44, 0xac, 0x03, 0xd5, 0x3c, 0xd0, 0xcf, 0x2c, 0x2f, 0x37, 0x74, 0x68, 0x2b, 0x66, 0x31, 0xcb, - 0xfd, 0x6a, 0xa5, 0xbd, 0x3b, 0x31, 0x63, 0xf1, 0x19, 0xf6, 0xd0, 0x88, 0x78, 0x88, 0x52, 0x26, - 0x91, 0x24, 0x8c, 0x9a, 0x3d, 0x0f, 0x67, 0xa2, 0x43, 0x29, 0x47, 0x86, 0x45, 0xbb, 0x33, 0x2b, - 0x48, 0x07, 0x1e, 0xa2, 0x13, 0x1d, 0xda, 0x35, 0x95, 0x18, 0x60, 0xcc, 0xf1, 0x20, 0xa5, 0x11, - 0xe6, 0x6a, 0xad, 0xc3, 0x8f, 0x96, 0x16, 0x6a, 0x84, 0x38, 0x4a, 0x0c, 0xef, 0x1e, 0x09, 0x42, - 0x2f, 0x64, 0x1c, 0x7b, 0xe1, 0x10, 0x51, 0x8a, 0xcf, 0x14, 0x42, 0x2f, 0x73, 0x88, 0xfb, 0x53, - 0x11, 0xec, 0x9c, 0x8a, 0xd8, 0xc7, 0x31, 0x11, 0x12, 0xf3, 0xde, 0x34, 0xdf, 0x49, 0x18, 0xb2, - 0x94, 0x4a, 0x7b, 0x0f, 0x6c, 0x0e, 0x38, 0x4b, 0xfa, 0x28, 0x8a, 0x38, 0x16, 0xc2, 0xb1, 0x9a, - 0x56, 0xab, 0xec, 0x57, 0x94, 0xef, 0x24, 0x77, 0xd9, 0x9f, 0x80, 0xb7, 0x42, 0x46, 0x29, 0x0e, - 0xd5, 0x9d, 0xfb, 0x24, 0x72, 0xd6, 0x14, 0xa6, 0xeb, 0xbc, 0xbe, 0x6c, 0x6c, 0x4d, 0x50, 0x72, - 0x76, 0xec, 0xce, 0x85, 0x5d, 0x7f, 0xf3, 0xd6, 0xee, 0x45, 0xf6, 0x73, 0xf0, 0xf0, 0xf6, 0x1a, - 0x7d, 0x94, 0xf3, 0xaa, 0x34, 0xc5, 0x2c, 0x4d, 0xf3, 0xf5, 0x65, 0x63, 0x27, 0x4f, 0xf3, 0x46, - 0x98, 0xeb, 0x3f, 0x20, 0x8b, 0xa7, 0xee, 0x45, 0x36, 0x05, 0x9b, 0x5c, 0x5f, 0xaa, 0x3f, 0xc0, - 0xd8, 0x29, 0x35, 0x8b, 0xad, 0x4a, 0xa7, 0x0a, 0xb5, 0x98, 0xaa, 0x25, 0xa0, 0x6e, 0x09, 0xf8, - 0x98, 0x11, 0xda, 0x3d, 0x7c, 0x79, 0xd9, 0x28, 0xfc, 0xf2, 0x57, 0xa3, 0x15, 0x13, 0x39, 0x4c, - 0x03, 0x18, 0xb2, 0x44, 0x2b, 0xaf, 0xff, 0x0e, 0x44, 0xf4, 0x95, 0x27, 0x27, 0x23, 0x2c, 0xb2, - 0x0d, 0xc2, 0xaf, 0x18, 0x82, 0x27, 0x18, 0xdb, 0x47, 0xe0, 0x3e, 0xe3, 0x11, 0xe6, 0x84, 0xc6, - 0xce, 0xbd, 0xa6, 0xd5, 0x7a, 0xbb, 0x53, 0x83, 0x24, 0x08, 0xa1, 0x2a, 0x3f, 0x34, 0x35, 0x1f, - 0xb7, 0xe1, 0x67, 0x0a, 0xe4, 0x4f, 0xb1, 0xc7, 0xd5, 0xef, 0x5e, 0x34, 0x0a, 0xff, 0xbc, 0x68, - 0x14, 0xbe, 0xbd, 0xb9, 0xd8, 0x9f, 0x2b, 0xb5, 0x1b, 0x81, 0xf7, 0x57, 0x49, 0xe3, 0x63, 0x31, - 0x62, 0x54, 0x60, 0x7b, 0x17, 0x00, 0x4d, 0xa0, 0xaa, 0x96, 0x0b, 0x54, 0xd6, 0x9e, 0x5e, 0x64, - 0x6f, 0x83, 0x8d, 0x11, 0xe3, 0x72, 0x2a, 0x8c, 0xbf, 0xae, 0xcc, 0x5e, 0x74, 0x5c, 0x52, 0xd4, - 0xee, 0xaf, 0x6b, 0xa0, 0x72, 0x2a, 0xe2, 0x67, 0x69, 0x90, 0x10, 0xf9, 0xfc, 0xfc, 0x2e, 0x82, - 0x77, 0x96, 0x29, 0x96, 0xe7, 0x7f, 0xa3, 0x1e, 0xef, 0x2d, 0x36, 0x49, 0xa6, 0xee, 0x42, 0x2b, - 0xb4, 0x40, 0x29, 0x11, 0xb1, 0xd0, 0x62, 0x6d, 0xc1, 0xfc, 0x81, 0x40, 0xf3, 0x40, 0xe0, 0x09, - 0x9d, 0xf8, 0x19, 0xc2, 0xb6, 0x41, 0x29, 0xc1, 0x09, 0xcb, 0x4a, 0x5d, 0xf6, 0xb3, 0xb5, 0xed, - 0x80, 0x0d, 0x49, 0x12, 0xcc, 0x52, 0xe9, 0xac, 0x37, 0xad, 0x56, 0xc9, 0x37, 0xa6, 0x7d, 0x08, - 0x8a, 0xaa, 0x07, 0x36, 0x9a, 0x56, 0xab, 0xd2, 0x71, 0xa0, 0x99, 0x21, 0x33, 0x8f, 0x0b, 0x3e, - 0xc1, 0xb8, 0x5b, 0x52, 0x2d, 0xe0, 0x2b, 0xe8, 0x2a, 0x59, 0x9e, 0x82, 0x07, 0x33, 0xf5, 0x9a, - 0xaa, 0xd0, 0x00, 0x15, 0x81, 0xbf, 0x4e, 0x31, 0x0d, 0xb1, 0x91, 0xa1, 0xe4, 0x03, 0xe3, 0xea, - 0x45, 0xea, 0x78, 0x5a, 0x14, 0x5d, 0x27, 0x63, 0xba, 0xbf, 0x5b, 0xe0, 0x9d, 0x53, 0x11, 0x7f, - 0x31, 0x8a, 0x90, 0xc4, 0x4f, 0xb3, 0x17, 0x6c, 0x1f, 0x81, 0x32, 0x4a, 0xe5, 0x90, 0x71, 0x22, - 0x27, 0xb9, 0x06, 0x5d, 0xe7, 0x8f, 0xdf, 0x0e, 0xb6, 0x74, 0xff, 0x6a, 0x29, 0x9e, 0x49, 0xd5, - 0x44, 0xfe, 0x2d, 0xd4, 0x7e, 0x0c, 0xd6, 0xf3, 0x19, 0x90, 0x91, 0x54, 0x3a, 0x4d, 0xb8, 0x6c, - 0x62, 0xc2, 0x9c, 0xa9, 0x5b, 0x56, 0xb7, 0xfe, 0xf9, 0xe6, 0x62, 0xdf, 0xf2, 0xf5, 0xd6, 0xe3, - 0x43, 0x75, 0xeb, 0xdb, 0xa4, 0xdf, 0xdf, 0x5c, 0xec, 0xef, 0xce, 0x8f, 0x9a, 0x85, 0xe3, 0xba, - 0x55, 0xb0, 0xbd, 0xe0, 0x32, 0x85, 0xe9, 0xfc, 0xbb, 0x06, 0x8a, 0xa7, 0x22, 0xb6, 0x7f, 0xb4, - 0x40, 0x75, 0xf9, 0x9c, 0x39, 0x5a, 0x7e, 0xce, 0x55, 0x8f, 0xa0, 0xf6, 0xe9, 0xff, 0xdb, 0x67, - 0x4e, 0xe7, 0x16, 0xec, 0x00, 0xdc, 0x9f, 0x36, 0xff, 0xa3, 0x95, 0xd9, 0x0c, 0xac, 0x76, 0x70, - 0x27, 0xd8, 0x0c, 0xc7, 0x19, 0xd8, 0x9c, 0x53, 0xf7, 0x83, 0x95, 0x09, 0x66, 0xa1, 0xb5, 0xf6, - 0x9d, 0xa1, 0x86, 0xaf, 0x76, 0xef, 0x1b, 0xa5, 0x66, 0xf7, 0xf3, 0x97, 0x57, 0x75, 0xeb, 0xd5, - 0x55, 0xdd, 0xfa, 0xfb, 0xaa, 0x6e, 0xfd, 0x70, 0x5d, 0x2f, 0xbc, 0xba, 0xae, 0x17, 0xfe, 0xbc, - 0xae, 0x17, 0xbe, 0xfc, 0x78, 0x66, 0xc6, 0xe9, 0xec, 0x07, 0x8c, 0xc7, 0x66, 0xed, 0x8d, 0x3f, - 0xf2, 0xce, 0x17, 0xbe, 0x2d, 0xd9, 0xe0, 0x0b, 0xd6, 0xb3, 0xa7, 0xf8, 0xe1, 0x7f, 0x01, 0x00, - 0x00, 0xff, 0xff, 0x03, 0x83, 0x36, 0x64, 0xaa, 0x07, 0x00, 0x00, + 0x8d, 0x3d, 0xef, 0xbd, 0x6f, 0xde, 0x7b, 0xf3, 0xbe, 0xf7, 0xde, 0x82, 0x3d, 0x8a, 0x53, 0xc9, + 0x19, 0xf5, 0x08, 0x95, 0x98, 0x87, 0x43, 0x44, 0xa8, 0x3c, 0x17, 0xde, 0xb8, 0xed, 0xc9, 0x73, + 0x38, 0xe2, 0x4c, 0x32, 0xdb, 0xd1, 0x10, 0x38, 0x07, 0x81, 0xe3, 0x76, 0xed, 0x5d, 0x94, 0x10, + 0xca, 0xbc, 0xec, 0x37, 0x07, 0xd7, 0xea, 0x21, 0x13, 0x09, 0x13, 0x5e, 0x80, 0x04, 0xf6, 0xc6, + 0xed, 0x00, 0x4b, 0xd4, 0xf6, 0x42, 0x46, 0xa8, 0xb6, 0x6f, 0x6b, 0x7b, 0x22, 0x62, 0x15, 0x24, + 0x11, 0xb1, 0x36, 0x54, 0x73, 0x43, 0x3f, 0x93, 0xbc, 0x5c, 0xd0, 0xa6, 0xad, 0x98, 0xc5, 0x2c, + 0xd7, 0xab, 0x93, 0xd6, 0xee, 0xc4, 0x8c, 0xc5, 0x67, 0xd8, 0x43, 0x23, 0xe2, 0x21, 0x4a, 0x99, + 0x44, 0x92, 0x30, 0x6a, 0xee, 0x3c, 0x9c, 0xb1, 0x0e, 0xa5, 0x1c, 0x99, 0x28, 0x5a, 0x9d, 0x49, + 0x41, 0x3a, 0xf0, 0x10, 0x9d, 0x68, 0xd3, 0x1e, 0x09, 0x42, 0x2f, 0x64, 0x1c, 0x7b, 0xe1, 0x10, + 0x51, 0x8a, 0xcf, 0x54, 0x7e, 0xfa, 0xa8, 0x21, 0xbb, 0xa6, 0x58, 0x03, 0x8c, 0x39, 0x1e, 0xa4, + 0x34, 0xc2, 0x5c, 0x9d, 0xb5, 0xf9, 0xd1, 0xd2, 0x5a, 0x8e, 0x10, 0x47, 0x89, 0x4e, 0xcd, 0xfd, + 0xa9, 0x08, 0x76, 0x4e, 0x45, 0xec, 0xe3, 0x98, 0x08, 0x89, 0x79, 0x6f, 0x0a, 0x3e, 0x09, 0x43, + 0x96, 0x52, 0x69, 0xef, 0x81, 0xcd, 0x01, 0x67, 0x49, 0x1f, 0x45, 0x11, 0xc7, 0x42, 0x38, 0x56, + 0xd3, 0x6a, 0x95, 0xfd, 0x8a, 0xd2, 0x9d, 0xe4, 0x2a, 0xfb, 0x13, 0xf0, 0x56, 0xc8, 0x28, 0xc5, + 0xa1, 0x7a, 0x73, 0x9f, 0x44, 0xce, 0x9a, 0xc2, 0x74, 0x9d, 0xd7, 0x97, 0x8d, 0xad, 0x09, 0x4a, + 0xce, 0x8e, 0xdd, 0x39, 0xb3, 0xeb, 0x6f, 0xde, 0xca, 0xbd, 0xc8, 0x7e, 0x0e, 0x1e, 0xde, 0xe6, + 0xd8, 0x47, 0x79, 0x5c, 0xe5, 0xa6, 0x98, 0xb9, 0x69, 0xbe, 0xbe, 0x6c, 0xec, 0xe4, 0x6e, 0xde, + 0x08, 0x73, 0xfd, 0x07, 0x64, 0x31, 0xeb, 0x5e, 0x64, 0x53, 0xb0, 0xc9, 0xf5, 0xa3, 0xfa, 0x03, + 0x8c, 0x9d, 0x52, 0xb3, 0xd8, 0xaa, 0x74, 0xaa, 0x50, 0x93, 0xa9, 0x5a, 0x02, 0xea, 0x96, 0x80, + 0x8f, 0x19, 0xa1, 0xdd, 0xc3, 0x97, 0x97, 0x8d, 0xc2, 0x2f, 0x7f, 0x35, 0x5a, 0x31, 0x91, 0xc3, + 0x34, 0x80, 0x21, 0x4b, 0x34, 0xf3, 0xfa, 0xef, 0x40, 0x44, 0x5f, 0x79, 0x72, 0x32, 0xc2, 0x22, + 0xbb, 0x20, 0xfc, 0x8a, 0x09, 0xf0, 0x04, 0x63, 0xfb, 0x08, 0xdc, 0x67, 0x3c, 0xc2, 0x9c, 0xd0, + 0xd8, 0xb9, 0xd7, 0xb4, 0x5a, 0x6f, 0x77, 0x6a, 0x90, 0x04, 0x21, 0x54, 0x24, 0x42, 0xc3, 0xdc, + 0xb8, 0x0d, 0x3f, 0x53, 0x20, 0x7f, 0x8a, 0x3d, 0xae, 0x7e, 0xf7, 0xa2, 0x51, 0xf8, 0xe7, 0x45, + 0xa3, 0xf0, 0xed, 0xcd, 0xc5, 0xfe, 0x5c, 0xa9, 0xdd, 0x08, 0xbc, 0xbf, 0x8a, 0x1a, 0x1f, 0x8b, + 0x11, 0xa3, 0x02, 0xdb, 0xbb, 0x00, 0xe8, 0x00, 0xaa, 0x6a, 0x39, 0x41, 0x65, 0xad, 0xe9, 0x45, + 0xf6, 0x36, 0xd8, 0x18, 0x31, 0x2e, 0xa7, 0xc4, 0xf8, 0xeb, 0x4a, 0xec, 0x45, 0xc7, 0x25, 0x15, + 0xda, 0xfd, 0x75, 0x0d, 0x54, 0x4e, 0x45, 0xfc, 0x2c, 0x0d, 0x12, 0x22, 0x9f, 0x9f, 0xdf, 0x85, + 0xf0, 0xce, 0x32, 0xc6, 0x72, 0xff, 0x6f, 0xe4, 0xe3, 0xbd, 0xc5, 0x26, 0xc9, 0xd8, 0x5d, 0x68, + 0x85, 0x16, 0x28, 0x25, 0x22, 0x16, 0x9a, 0xac, 0x2d, 0x98, 0x0f, 0x08, 0x34, 0x03, 0x02, 0x4f, + 0xe8, 0xc4, 0xcf, 0x10, 0xb6, 0x0d, 0x4a, 0x09, 0x4e, 0x58, 0x56, 0xea, 0xb2, 0x9f, 0x9d, 0x6d, + 0x07, 0x6c, 0x48, 0x92, 0x60, 0x96, 0x4a, 0x67, 0xbd, 0x69, 0xb5, 0x4a, 0xbe, 0x11, 0xed, 0x43, + 0x50, 0x54, 0x3d, 0xb0, 0xd1, 0xb4, 0x5a, 0x95, 0x8e, 0x03, 0xcd, 0x0e, 0x99, 0x99, 0x1c, 0xf8, + 0x04, 0xe3, 0x6e, 0x49, 0xb5, 0x80, 0xaf, 0xa0, 0xab, 0x68, 0x79, 0x0a, 0x1e, 0xcc, 0xd4, 0x6b, + 0xca, 0x42, 0x03, 0x54, 0x04, 0xfe, 0x3a, 0xc5, 0x34, 0xc4, 0x86, 0x86, 0x92, 0x0f, 0x8c, 0xaa, + 0x17, 0xa9, 0xf4, 0x34, 0x29, 0xba, 0x4e, 0x46, 0x74, 0x7f, 0xb7, 0xc0, 0x3b, 0xa7, 0x22, 0xfe, + 0x62, 0x14, 0x21, 0x89, 0x9f, 0x66, 0xe3, 0x69, 0x1f, 0x81, 0x32, 0x4a, 0xe5, 0x90, 0x71, 0x22, + 0x27, 0x39, 0x07, 0x5d, 0xe7, 0x8f, 0xdf, 0x0e, 0xb6, 0x74, 0xff, 0x6a, 0x2a, 0x9e, 0x49, 0xd5, + 0x44, 0xfe, 0x2d, 0xd4, 0x7e, 0x0c, 0xd6, 0xf3, 0x01, 0xcf, 0x82, 0x54, 0x3a, 0x4d, 0xb8, 0x6c, + 0x63, 0xc2, 0x3c, 0x52, 0xb7, 0xac, 0x5e, 0xfd, 0xf3, 0xcd, 0xc5, 0xbe, 0xe5, 0xeb, 0xab, 0xc7, + 0x87, 0xea, 0xd5, 0xb7, 0x4e, 0xbf, 0xbf, 0xb9, 0xd8, 0xdf, 0x9d, 0xdf, 0x23, 0x0b, 0xe9, 0xba, + 0x55, 0xb0, 0xbd, 0xa0, 0x32, 0x85, 0xe9, 0xfc, 0xbb, 0x06, 0x8a, 0xa7, 0x22, 0xb6, 0x7f, 0xb4, + 0x40, 0x75, 0xf9, 0x9e, 0x39, 0x5a, 0x9e, 0xe7, 0xaa, 0x21, 0xa8, 0x7d, 0xfa, 0xff, 0xee, 0x99, + 0xec, 0xdc, 0x82, 0x1d, 0x80, 0xfb, 0xd3, 0xe6, 0x7f, 0xb4, 0xd2, 0x9b, 0x81, 0xd5, 0x0e, 0xee, + 0x04, 0x9b, 0x89, 0x71, 0x06, 0x36, 0xe7, 0xd8, 0xfd, 0x60, 0xa5, 0x83, 0x59, 0x68, 0xad, 0x7d, + 0x67, 0xa8, 0x89, 0x57, 0xbb, 0xf7, 0x8d, 0x62, 0xb3, 0xfb, 0xf9, 0xcb, 0xab, 0xba, 0xf5, 0xea, + 0xaa, 0x6e, 0xfd, 0x7d, 0x55, 0xb7, 0x7e, 0xb8, 0xae, 0x17, 0x5e, 0x5d, 0xd7, 0x0b, 0x7f, 0x5e, + 0xd7, 0x0b, 0x5f, 0x7e, 0x3c, 0xb3, 0xe3, 0xb4, 0xf7, 0x03, 0xc6, 0x63, 0x73, 0xf6, 0xc6, 0x1f, + 0x79, 0xe7, 0x0b, 0x1f, 0x8e, 0x6c, 0xf1, 0x05, 0xeb, 0xd9, 0x28, 0x7e, 0xf8, 0x5f, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xda, 0x2c, 0x63, 0xb9, 0xaa, 0x07, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. From 1f88c5c26438c2642343486c9f1fbd13476475dd Mon Sep 17 00:00:00 2001 From: nhpd Date: Thu, 15 Aug 2024 15:33:03 +0400 Subject: [PATCH 09/15] fix tests --- x/interchaintxs/keeper/msg_server_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/interchaintxs/keeper/msg_server_test.go b/x/interchaintxs/keeper/msg_server_test.go index 5cecf14fa..a4aa8369f 100644 --- a/x/interchaintxs/keeper/msg_server_test.go +++ b/x/interchaintxs/keeper/msg_server_test.go @@ -113,6 +113,7 @@ func TestRegisterInterchainAccount(t *testing.T) { FromAddress: testutil.TestOwnerAddress, ConnectionId: "connection-0", InterchainAccountId: "ica0", + Ordering: channeltypes.ORDERED, } contractAddress := sdk.MustAccAddressFromBech32(msgRegAcc.FromAddress) icaOwner := types.NewICAOwnerFromAddress(contractAddress, msgRegAcc.InterchainAccountId) From 5ce70b5daaa45fdc875604275c28cec61fb09f3a Mon Sep 17 00:00:00 2001 From: nhpd Date: Thu, 15 Aug 2024 15:40:38 +0400 Subject: [PATCH 10/15] lint --- x/interchaintxs/keeper/msg_server_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/x/interchaintxs/keeper/msg_server_test.go b/x/interchaintxs/keeper/msg_server_test.go index a4aa8369f..d06aa20ae 100644 --- a/x/interchaintxs/keeper/msg_server_test.go +++ b/x/interchaintxs/keeper/msg_server_test.go @@ -2,10 +2,11 @@ package keeper_test import ( "fmt" - channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" "testing" "time" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + "cosmossdk.io/math" "github.com/neutron-org/neutron/v4/app/params" @@ -13,6 +14,7 @@ import ( wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" icacontrollertypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types" icatypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types" + feerefundertypes "github.com/neutron-org/neutron/v4/x/feerefunder/types" "github.com/neutron-org/neutron/v4/x/interchaintxs/keeper" From b25dfebc41122d2b849827d1bef4a476f83e9d5e Mon Sep 17 00:00:00 2001 From: nhpd Date: Thu, 22 Aug 2024 14:43:06 +0400 Subject: [PATCH 11/15] unordered test --- wasmbinding/message_plugin.go | 11 +++--- wasmbinding/test/custom_message_test.go | 49 +++++++++++++++++++++++- wasmbinding/testdata/reflect.wasm | Bin 422710 -> 579620 bytes 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/wasmbinding/message_plugin.go b/wasmbinding/message_plugin.go index 81e05eed0..89307562a 100644 --- a/wasmbinding/message_plugin.go +++ b/wasmbinding/message_plugin.go @@ -7,7 +7,7 @@ import ( "strings" "time" - types1 "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" "github.com/cosmos/gogoproto/proto" @@ -868,15 +868,16 @@ func (m *CustomMessenger) registerInterchainAccount(ctx sdk.Context, contractAdd func (m *CustomMessenger) performRegisterInterchainAccount(ctx sdk.Context, contractAddr sdk.AccAddress, reg *bindings.RegisterInterchainAccount) (*ictxtypes.MsgRegisterInterchainAccountResponse, error) { // parse incoming ordering. If nothing passed, use ORDERED by default - var orderValue types1.Order + var orderValue channeltypes.Order if reg.Ordering == "" { - orderValue = types1.ORDERED + orderValue = channeltypes.ORDERED } else { - orderValueInt, ok := types1.Order_value[reg.Ordering] + orderValueInt, ok := channeltypes.Order_value[reg.Ordering] + if !ok { return nil, fmt.Errorf("failed to register interchain account: incorrect order value passed: %s", reg.Ordering) } - orderValue = types1.Order(orderValueInt) + orderValue = channeltypes.Order(orderValueInt) } msg := ictxtypes.MsgRegisterInterchainAccount{ diff --git a/wasmbinding/test/custom_message_test.go b/wasmbinding/test/custom_message_test.go index 760417c16..e6726d219 100644 --- a/wasmbinding/test/custom_message_test.go +++ b/wasmbinding/test/custom_message_test.go @@ -102,13 +102,23 @@ func (suite *CustomMessengerTestSuite) TestRegisterInterchainAccount() { } bankKeeper := suite.neutron.BankKeeper + channelKeeper := suite.neutron.IBCKeeper.ChannelKeeper senderAddress := suite.ChainA.SenderAccounts[0].SenderAccount.GetAddress() err = bankKeeper.SendCoins(suite.ctx, senderAddress, suite.contractAddress, sdk.NewCoins(sdk.NewCoin(params.DefaultDenom, math.NewInt(1_000_000)))) suite.NoError(err) // Dispatch RegisterInterchainAccount message - _, err = suite.executeNeutronMsg(suite.contractAddress, msg) + data, err := suite.executeNeutronMsg(suite.contractAddress, msg) + suite.NoError(err) + suite.NotEmpty(data) + + // default method should be ordered + var response ictxtypes.MsgRegisterInterchainAccountResponse + err = response.Unmarshal(data) suite.NoError(err) + channel, found := channelKeeper.GetChannel(suite.ctx, response.PortId, response.ChannelId) + suite.True(found) + suite.Equal(channel.Ordering, ibcchanneltypes.ORDERED) } func (suite *CustomMessengerTestSuite) TestRegisterInterchainAccountLongID() { @@ -130,6 +140,43 @@ func (suite *CustomMessengerTestSuite) TestRegisterInterchainAccountLongID() { suite.ErrorIs(err, ictxtypes.ErrLongInterchainAccountID) } +func (suite *CustomMessengerTestSuite) TestRegisterInterchainAccountUnordered() { + err := suite.neutron.FeeBurnerKeeper.SetParams(suite.ctx, feeburnertypes.Params{ + NeutronDenom: "untrn", + TreasuryAddress: "neutron13jrwrtsyjjuynlug65r76r2zvfw5xjcq6532h2", + }) + suite.Require().NoError(err) + + // Craft RegisterInterchainAccount message + msg := bindings.NeutronMsg{ + RegisterInterchainAccount: &bindings.RegisterInterchainAccount{ + ConnectionId: suite.Path.EndpointA.ConnectionID, + InterchainAccountId: testutil.TestInterchainID, + RegisterFee: sdk.NewCoins(sdk.NewCoin(params.DefaultDenom, math.NewInt(1_000_000))), + Ordering: ibcchanneltypes.Order_name[int32(ibcchanneltypes.UNORDERED)], + }, + } + + bankKeeper := suite.neutron.BankKeeper + channelKeeper := suite.neutron.IBCKeeper.ChannelKeeper + senderAddress := suite.ChainA.SenderAccounts[0].SenderAccount.GetAddress() + err = bankKeeper.SendCoins(suite.ctx, senderAddress, suite.contractAddress, sdk.NewCoins(sdk.NewCoin(params.DefaultDenom, math.NewInt(1_000_000)))) + suite.NoError(err) + + // Dispatch RegisterInterchainAccount message + data, err := suite.executeNeutronMsg(suite.contractAddress, msg) + suite.NoError(err) + suite.NotEmpty(data) + + // default method should be ordered + var response ictxtypes.MsgRegisterInterchainAccountResponse + err = response.Unmarshal(data) + suite.NoError(err) + channel, found := channelKeeper.GetChannel(suite.ctx, response.PortId, response.ChannelId) + suite.True(found) + suite.Equal(channel.Ordering, ibcchanneltypes.UNORDERED) +} + func (suite *CustomMessengerTestSuite) TestRegisterInterchainQuery() { err := testutil.SetupICAPath(suite.Path, suite.contractAddress.String()) suite.Require().NoError(err) diff --git a/wasmbinding/testdata/reflect.wasm b/wasmbinding/testdata/reflect.wasm index 174232f4b63e9248ea5719711dfc9cc8ace8254e..df893365f3253e94b0369edb5598cc4fc88bafcc 100644 GIT binary patch literal 579620 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 z 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

gV;<05yB4)#Lhkow6r}u(1%Ivd*W9 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 {lJ5$Qeq&%$))j*&y*&2Jp0-_ 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 I*Ie`e2ZBqFRsaA1 literal 422710 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Μ8b7 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�CQgU+Um%JNUG~IRL(q8hkg4 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 From b8530be6bf7db1c6398cd8bed60698fd1d637907 Mon Sep 17 00:00:00 2001 From: nhpd Date: Thu, 22 Aug 2024 17:12:57 +0400 Subject: [PATCH 12/15] fix tests after changing reflect.wasm file --- wasmbinding/test/custom_message_test.go | 27 ++++++++++++------------ wasmbinding/testdata/reflect.wasm | Bin 579620 -> 579805 bytes 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/wasmbinding/test/custom_message_test.go b/wasmbinding/test/custom_message_test.go index e6726d219..da6a314ad 100644 --- a/wasmbinding/test/custom_message_test.go +++ b/wasmbinding/test/custom_message_test.go @@ -3,6 +3,7 @@ package test import ( "encoding/json" "fmt" + contractmanagertypes "github.com/neutron-org/neutron/v4/x/contractmanager/types" "testing" "cosmossdk.io/math" @@ -543,7 +544,7 @@ func (suite *CustomMessengerTestSuite) TestSubmitTx() { suite.NoError(err) var response ictxtypes.MsgSubmitTxResponse - err = json.Unmarshal(data, &response) + err = response.Unmarshal(data) suite.NoError(err) suite.Equal(uint64(1), response.SequenceId) suite.Equal("channel-2", response.Channel) @@ -594,11 +595,10 @@ func (suite *CustomMessengerTestSuite) TestSoftwareUpgradeProposal() { data, err := suite.executeNeutronMsg(suite.contractAddress, msg) suite.NoError(err) - expected, err := json.Marshal(&admintypes.MsgSubmitProposalResponse{ - ProposalId: 1, - }) + var expected admintypes.MsgSubmitProposalResponse + err = expected.Unmarshal(data) suite.NoError(err) - suite.Equal(expected, data) + suite.Equal(expected.ProposalId, uint64(1)) // Test with other proposer that is not admin should return failure _, err = suite.executeNeutronMsg(anotherContract, msg) @@ -623,11 +623,10 @@ func (suite *CustomMessengerTestSuite) TestSoftwareUpgradeProposal() { data, err = suite.executeNeutronMsg(suite.contractAddress, msg) suite.NoError(err) - expected, err = json.Marshal(&admintypes.MsgSubmitProposalResponse{ - ProposalId: 2, - }) + var expected2 admintypes.MsgSubmitProposalResponse + err = expected2.Unmarshal(data) suite.NoError(err) - suite.Equal(expected, data) + suite.Equal(expected2.ProposalId, uint64(2)) } func (suite *CustomMessengerTestSuite) TestTooMuchProposals() { @@ -745,9 +744,10 @@ func (suite *CustomMessengerTestSuite) TestResubmitFailureAck() { data, err := suite.executeNeutronMsg(suite.contractAddress, msg) suite.NoError(err) - expected, err := json.Marshal(&bindings.ResubmitFailureResponse{}) + var expected contractmanagertypes.Failure + err = expected.Unmarshal(data) suite.NoError(err) - suite.Equal(expected, data) + suite.Equal(expected.Id, failureID) } func (suite *CustomMessengerTestSuite) TestResubmitFailureTimeout() { @@ -769,9 +769,10 @@ func (suite *CustomMessengerTestSuite) TestResubmitFailureTimeout() { data, err := suite.executeNeutronMsg(suite.contractAddress, msg) suite.NoError(err) - expected, err := json.Marshal(&bindings.ResubmitFailureResponse{FailureId: failureID}) + var expected contractmanagertypes.Failure + err = expected.Unmarshal(data) suite.NoError(err) - suite.Equal(expected, data) + suite.Equal(expected.Id, failureID) } func (suite *CustomMessengerTestSuite) TestResubmitFailureFromDifferentContract() { diff --git a/wasmbinding/testdata/reflect.wasm b/wasmbinding/testdata/reflect.wasm index df893365f3253e94b0369edb5598cc4fc88bafcc..808c6572bcd92c255baf896be4b598c1b6f12dd7 100644 GIT binary patch delta 28585 zcmc(|d3+Q_^FO{byVKpd$c6-xK!Dxl3io{@FbK+_0^SF5BM^`qR6G(9H3&#Jq(CB< zsGw0$j^zjtG(bSmps1ihqXq#1K}8KdJo0_l%qW;<`W;5=V2eA91)8=hxbIG*Zg>6X&2(Xj zQKV-Esqi(UH&tI|L{MO27_|Mcu@fZIJ~6ffwEolxTunLbQ=<_I=6`B@qIrYEj~J~qEs>UfW;Cjh=+jg6 zVo#J`_;g<)eg2uz07d%eMjF7wpBp}a7e6YO!?WxUnlbHo7vHm{+t3{#aW6wNV=dd%iY0CdabmM?HZGX62hb zU3?Y%k7_(fj~qBkM7n4Jc6xmX>w!H+=)Dc zJ24NPu;fwnN{Mk3^f&l~;UmupBOd9b6Gjg^s|CPICoEgpcfzO{ty=3vo@f>2i}y?V z{e)2mCRObR7_X#GKNyb#Z2Q4z3~>4fBY?WmCyi=eOVN*F3}al7(J!eTaw9P2srqWe zuV~;&qjo2YGmmgIq}F}1y{p&*aliMZp?67B+q+ zYOyTxz$_wSG@tax`&<~u1n64P&8Ljk@k!iffq@J_j7mHTvQ8P*An7}&jNVGN)|JnL zOzku@5KFyI8>#I=_U|$)-vq7ezQ(QfYy;5KT3^gCwza;HA!cBffi6^s?O|9Iy>;5~ z^)C|&ZDJY;n@#oZY!g1i;f0nhUg(*{OE51V)`fUqEKl)xRtkt$a6=%r1W;7>M`LKs za0}5Q3cZEp`avGgmf)*ws>u_f|-5_AVCGB-m3dO*m`#tHhdWY6sU#2COc|WomvGb2H#F z!VN~obG8qyx~x{&dSmIYvoM)hYIM#5{m&UqYr$md@j&(DxrTv47tN!dG;crlb_vz}rz)tf*bTgpaoQ(o2uvtI15UI^B~Z$|2!mT}HD;I}N}jJB<+wlhyKU#xio z3$=JylZ>q@(q}Ckkvza4KFbY+CRZ%I{hRR-ckXwic4BOIUqttbF*jh` zkk>nmtFAZv)fsLv{N5;Eb)VNv8j}`q`J!9v2^d+3@8tpJXv^hG=E>^vMcShdHL=Zc zM=*qG0WbadhtZ6F|K0G4Xr35QSSiNSOMOd?jsi5JK{LP9XpOA>rABjrjLSy5CUyy2 zRg^E8XGgR%J0kpEw&yD76r}S-`jc6C-r%rH@ShbezYA~6vrYO8j5j^~FQXbA`_pKG zk&O5k0)s?q^DpCRU|auX3_)`#myMxLt08%IT{aq5O@vy6-{r>2;O*ygnMrAwGl?v4 zVo?3tILtA{mw#chBvQl`V6I9^ znq|?1+%!RCYZ&DUx?q#LR|l%-H(lHeaD!WPLgo{0Q3V*e1zcoslUp>=kbA--Mj^M4 zA$TUdYKT(_Nj|sfOJf1th(XOfJuMJP%Y~SbE`YAr)BK*AF0;@zIuKFIWv_L57nEeU z(*g#n^+lH>%mP=M&oG;&rRp$t7c#nx2A-N$Pq+9+m~FWn?S$~Aj3p+#@{=z!!Fk(CNd0_Ol*Aeg<96ync;AbRZfcOaC<%5zQ76Z5b+vxL4K;Iv1)oB& z;S*h0iM#j&)vH!my~ji(lfOF0ntemF;YYqAHa+(p&tFkkf^iB;())&gJ_C%WN;7kFkv_xu7&kL}7ZN{PRB+_cY36J?KR^tLS^OdL5q)u14h&EBt{f0w0uj4K!eqVg~_6(gCO4u&Z=lzUN>x$J>h zyd4;LvC!7Ylzxm1tje5mglMp6+{0FUS;e*vX}E5_%gOo89!Oqr%*&jf&D<*4+zwLA z5Yeog-QhBBR;yuFAu+zO#jrTpa%}-8*e}afLeqzc0a_7#I|Md%gd2)7zhQvo-0sFP zo4l-FGq|H1$f5ph8aPxupwHe)JD(K|=z$E8NPi6#D)3$*6PYKuGMlT_vct-0Idz!0 zhl+=YNSZlJ+>mUWm${e44vQx8ZtsOgK*v{BB?@o;b5oRMu>q4XLqA|jCqMcv@LfAH5w^~b+f1Y ze`|gv>n^Tb^Y3v+f-^Yu*+|hTV9)34b8^INHA;-?a~aMGo({}9rkQ8MNXs;{D2y~r zGY^K5TIG=xds^5G5`fUTQKCm()`=Z}>QJ^FgJOt~;$?C64oEA_%iF1cnh10_0@P-J zcFG$4&+XXaP(+$&Sm&QxYl_xNxV1=gHARgUwH{>CwHxCpT?F48?)Hpj3t>1@&MQwVVRgs&BloM^ktmo zy}HDjUmh!9z@Q#2onMBRjE*$u>)^BFkvbum>OE4sI~7pOA6KBs44uZdCM zVKyEAYq35>bH<8JE$o${tgb~Dt_TsVjH_qpUt>kHmKnV2c>i0)tCou$)OomQ8hC@} zf0Q}X9tg*amiNCU!A;{tjs{y8GC_>j4?3D1KT$MXG*~1#D^>$SMmI_y1{b$;q8MSv z6b(7oBBO0XQ4$y|YFb$o`>;p~J47dM&}6Wiz0LOXMJurv3CAka9zv`F*B?_sPe+(- z?;teH(d#*;11rN0^(voraU1o_5H+sH;ws0ROGl@O&Pf@E!%q6FYtSlja!)d_<4onN9ai6;I!s@d2`u%_R(CeAW!H2JUsvsDuo5FKhzaIU^bwFp>gJ zALTzhA3SMhG5H@6$*uD8?MZ6Qku|V4p0PUDU=}ulxv@S>=0ypOd&KhFD<2WnRUwK@ z#Z%)EQRBX&j3t`q8ASSEHI6KoIKzVs_=1c*NN4dMj$}e}Gu$6`DlGo1Ou>@_(qcjA z{HUmuzMk_cnR^&G3ls}&9tveZ@S~hQ#edlIW7e|2GB0rk&dr%y)?Q4t4?NKoc+<@! zyzAG@7051Q?zGDbxFQqbD90Rr-V$QXRX( za#jMvC^MP=Xc%Q=FpR}?;&JT1a;ec1qI&w818B}`9_3b@aa3#=9$Nt^jsmtYSyb89 ziw%rt*aw{NjEpsnF0g~(1qUN@5QSbS6PuLsrc=aqD%ia4a!4)Z!OE~%DNp(%lg65t z7)07kFGJ;QkJz)6r+kJtZyeF1-AtUF|V1av^7+Z#nc+x@gI5#!V54SG75V zdSr;^feenvBh42W@chf-#0o1&2Ma6$Ih36tZmgBdS+VAa4A>DKEQR==GR94T?!uM4 zp!;djLDS|?=jkF<%b}6e#W!Wxgl9y}*y5{e(5uggCY^IxVmDSJTvTc1F2?i_wwo~- z!U`CRXY)E|0y%SS@b9uFJ>A9gSRkhy+ox zxK?7Q)*IC8IjmSk^u%)_4a0cyIq_8Iqr9_;2ML?FW}aa*iBXubWh_nJMnn3WDQiiq&pyJtfQ$fhu{H zh9^VnIS_U{Ai%u<3#soMF&mfo$LEMf8uSn~SG0=1a0ESVgW|JT)7E?jWCqb>p(UPjYBD%nj z4tPc2^@;@@c0EkqWjK<~<*^jXJEfH`h)q88Zp-W$v@c>%LM9 zxbA%3Nc&fcM%Q;Q!Q@qOUeqNO)~|0 zJiJz1!2#RhH^m|ww505}#PRr_;Fe(j{z~RKCsmnN?iZD4WsazeHzM}uh-n?x6(j6y z=5hs+x?a)x#b|tdjseorP&42*!^O!cz8y2kW9p$Idg^UarA?TkYM8eO zY+Y;SI?4bA2$yaYbDCcu@WaT1t<6vK#h4ozTgu$|U?iWhc~)CK-b&xUNj#3~pKlUv z0b)0cPZJz2v$I27bTsq(X7L>ejs?Y6Ne;o~r49kE`S}H)b#!ox=uq(>XJ@gMI&?*p zyj3(+4t6%!Z>yN7DW~r_^x-zqsJ>H}8)oTb%)T}whXUJ0_Ykve8n<2eD?7x+=)T== z4kA|5>)XXa_>oDuVh|SbnL99-)ehmqdQoqO7zi(dtX@&2EBHmKBy?aleZ51p!m)Y6 zPVppW%>13=rtX7N#_^7yqlhnD z7R*n7lFsziQbgeu%uR#(-KSNf`u(&Nz3>Y4=%3do)_YkxFGuJTlf*L#);+T_ z?;9XMdlxU+Sc##h6*TO9_}jCz=zZ~X#k0$xL$;5y(OdF?sI8r+T_1=5z;_>rIsg&* zqJGu$a35^+?OnX6yVHE`uBn-Cn4Kq>=jpb5(XGnW1Tqcg=$&ep=j4kN@Y$a)Y66_g zx40(k5v_ss-XoHeuC9yQFHhG1n4hO7_K5D)t}d;Bmw4U?#F&*G=3no@ns=W5*kduT zy4Pafb+2gM{OWq~DbjS%6;O?xXlZiL;m4maj&+9 zYJDO$qt;iSpwWMq5o#Pf{Z<}7SB8{pw9cpEZg6?>Q}L%N`T`nhfN(GU2$ZpgK06{l zh<9#{t%l7R-~m_q)@N`LYw7rB|C^*qpNppbLszmmg2I)o7SQb1P2oBZf@#=oz+2{* z32OBsw>-YF3@N9JjB}zgZTlS2X&#;WT+FnE_tSzegul{yE3Unu;l^|^BHCTO=M&DnMs*sp>WyKRVID>wMa?Yf_oWm=95Sjh?T1j+{gAf5+y`UlGa zbUrDPZ{PTHc=Fmu{J@>bYss;?JPtXs%i{~n5RK3KY(d^UDY~Mub0-mf%%(vk%HezDQX|hD4_=nLj=)vN$ZT>o55+RDZ;Os(MDuM`PzM zh-B(>9x;6$?LLS5$`{Xzrb$`9uq~v9TjU#^R6Z{{a278OtR>8>E_Q{H4lTz zGB-pe601Jc=Nk0T&!S?o-O}GxeTwG&EUG2jO#fb7%3SNvxu3=8 ze^z;L!Y|@aL%&i=50{GH8Qu^n_XO+zDGDXtf%umus{>TgWgqQSFin@|HNg8l^0Y@U zxnkAPN`f6DWswJCog6EB0St?kF9TeOm3_6MU|+9vYe4UelOurU#>v)3RXd#I=uX3X zR*KIj4D&M%`6PAW*8v+R%7{u=QSqTg6lf@Km6kw*66M2S`cWd<_$*i>sjLm*u-P3a zCj_-B@+$*=@puiHs&{bw+zhPNwj2D%E$Fp-(iy=n0ePe5_%c3zvF(brj-&BRT3S=y zjsg6srcBf?oF-XI*2enVsFv)2+)=gUml)P=wPihIj;$@94joBo=5j3*bdz334$w<4 z(U3Z_C-(3;b!0Dn{h#z=s%$|G>dMM`p@U4VD;q>z{*!HqZ+h|KLOt1%ib0~SpgE~X zH%LXg&`wX~bP1;iYPi}?m7}yR3_8(E^<*ppir4C4*v`_0da{dt@iH~9FCTEGhzfVq zixk{Pc#4olgPO?7w5PtT*#9fOTaV*|9qZ`kETfefwa%HQ^Px}zqvg&-qrq4kh?6>EOOfX{Rh8J*(vRrILq#mPOtybY4j zi!r54=e??GCZ8u>uc~vC;Kk80OSzcoBF$B$DS&RDC1&=?YwJ?ehO%<{YfKvh+W$oA zNXT#If*aq7b2IO8omg`>13vDAvaJ)(BF^C6Vo|X&{w8v{yM>U<-*F|D8Q>p9cI0rb z5<*qaa-FFEttw9SxC^1Gf24C=yh6`_Pl_?1f7g`LERF!VE+61?_n*0BRh`9vFU3Pu z!(Bl4ug?qJ4_yY_;4oXnT%yfY|2Jlf8e;_Cw&e)h7-pvxN&ZdiurcQ{AY@~k>{iQH z%||?UT^n;|0^i?o?{{-myaDqE+ZYcvx_^Z8u4-G%ZR682Aj-40M4NYXCwwms0B5zOsn2(n6Dv>>%tke4k!nZkYGpqsD z2jAv|6#(~ILd%=W%9SscqYoFC(1*=sxAamjQ_Kq|GMwgjp`6)!6+28|)+h43IhM{i z><;KqSjO|H7Wsc>0ZqA0da(t*HF%*MhlQMuxmt*op*+WnTqT$fg3;$KWVc@LFqw7B zh0Cqbu$T4aTDkL>Jn_16)6*?vLh=_(5N8vF^#*<=G_R%XRR0tg3odqx)%d2M+eqJgbsRj0*P|6_~h z#*h@4TG=$WwXAGz<*excp;ZJ~y!vrx!fbdjLtS^bkxkP7qabM1>AJaxTV<`|MGT&Z zjym9r!s^)1B-himGfN7&oEIusk0Y3$hPRTH9Hm@O7RP>gWGt0`W%0Pqcsgx_hoQ`B znFV`@5Q`s}g*A1qHHj&0W!uIVxY(KK7ef-mt%g+TT;*cdj?iup+4~oz+~<{t(8IL)F^J<_-Q2*QqqEoqRbx7k8%E2blqU8i~$)?V!og35@>Xpefd8 zT;_sVHgVPHid_1RgVx|r7IpKGgVu@0CosDCtAnQ6-yklXZP#sMy$NG}Vx#G1UF&@p z^O95C*8bS<-8nXOTkCBS^R$CD=JgO^_KS9DlJ#1Mxz0gjtq-Tnoemmpy_;bkaL}s! zEsbuT2%|jbnwlANZC)R{tl-7`*ugvUf~cFbvh3n^R*Zo+S-Wr3JEjffPfE`_x&TecV}os9#<{*nq2_ z(MxzO-{l-9!bX+`|LiLVmE$?&cKLOvg`8lIJ7iUlmO;brk<;|tmuOyF6;I>ZsA#%! zj~pw`ErKLxY0|y2A&z@j+>0&I#YJ@XUU^$$E*gR-^rd+h<($W&Fx z^-|0&^z?o5KK-vnRCJ%Ls$W?|m+q5yV~+N{U-C&;`u(yNu+{ft$5lu_-7o872bKJQ z>|ObbRbap`1z0CM_yQmW-CaS`9*~1UQuF}!om;3;f7!EQ7AQH4!%HI^0JzN8D6>D< zX3*RHS<4w03;&LPmkDmh9bgHPKAcbRr^xuo0SJ17*UOMHPf`D&vTCz1 zHD21|Y>R+1tyFB3X?;Cmv}UMm8g=9}-i+|;db(LeebR7{P(=DLS%gEwZ-&X1 zqL>*JQ}S@RGA{p=P1?o&*a_Jm4wucfV)|>iTpV){j38}5$JaCY^y)*hHLk_Jd`RB= zkBaE@-*qr3+$&F+4$zltRRAf`wh!OP@n;}DzM$78S|8C_-A36>F&gXcZ%WuXQYIx| zM`1j}FQ1|FBV|7wUzKzn1*eL8>H#3PC_{+0?+wztqd($puT zCkMvJaWK~Q56i}ti`Xcb$c^xip@tcAgr0g>Rt;I`a?sUt+6lN~boPlZ^U(>WZBR0# zcfYVq>-UE()2cL9cCB=MiZNp?idkd9*BT}JLmx9Gi;~F_`Dsn+C6o0z%_yA9HzCcvtP!^yS(AP^hTKn zv+ADlGW|yWe#sXF%0Oi3Tc)%CPsGs2N{%vp(2!5FK4W5KTLucnS#u$If~)~Y({6%n z#HKWIf~+R&kDzGQ1Vm{0^u`3)Dr{B}7>tt>57 z>Z5Km9|MJN`0(v!1?w=vM)?h)3O;-Th!@F`!{1I~JH@F;PH`pcTS4<6nUmyw|DYsl22)mzv_l}?s5D_h@b;ajlLwg!0~K~dCf zifjZYF>s2k8O5VuIXZBiGe!ELw{=rwa;!7Oe3AGDlIwgiMOKfq_(Acb1C}))TTGQ* zedQH}mD{!#OBm*kz<%UZ>8r#xW;;n|uzeVRDJ-8@Jur^$fd@|p@?sULR-ct7|Nj-5saT;8wT z0k@#NN+>d2HcrX|cL;A@!9O_xUyXV>>XULs1t0N0jTZ#c0UnAJ+N?+C(zeoU9E z@b=c644I0nq0Jex6R_Vhf75u5JuMO4{m_>URfBswx+p*x#XK=3& zk+&V}h4*6*9X=r|2M^DX<8;JW=JT>j?D}3ZrrQy!>uHBlGjG7l2iBK_n}Hk*c9~Cc)WUK!MN4E4m_Y59r4Qhym*q{`8k+O6?80|GFUwkb=^J$M zWz2&-sJ{0c(uyzz z3lJ60PHY8rT80pT)dDjbyi8U}pN*Ii9ujVgQ>F$f%uG)4A9im1K?wW>he}D92S+Wo zUZiaIgx`1YdD^>D03b<%)d5rs==^=V%R(WY#l-HMqieh@1ApP8KbOghjh#F&g`0J> znyM$nX*L5(jL{Gw3Zj^^gYB2gxw^^>LdsNgeem!~dCUV-cnZ&DbXwpNbUDrT?e+ISBKqo2PK z=_A3*Z_3*=3`g%A*{EGHxZCbVLj(a8^H^kT2xT&+;h7O4D--A49Jy7?3XXnTHrL}f zhHK!5a!|vANNxQ(*)i$tp^zbFeZVQl5RZ^&y&Q7iTu9{C_VE_i235x zxu49oa_3x~dvJ}FJNxR~eRl3F+O=L*N_^q!!cSIcH)9UXq%-Sr9Fa*)-j&PY7CwF# z_nKLB>0Nna=M|`7t0UBpjiDTPSp%-n?Ta?oBM)y-@PedS$0z77FBq%o@%OMzFWnGa z{GKEoW7%{Qjwcq<$W5|Iy^?Emgs}+c*vhxAlrFqSd7I>7NOa$3guuBpWiz(n8FYR# zd|3uX2IUHEFTE8+=ccfgW!Ww(lsXV=YG7%@Bc92%F4efn&AJ{SJ^D7}{}1HM^S=doe? z&=VstbkGZ?F@C;+UoL-Nk1Se8&@41QpmX)M|b{=RZr^K9(sdzp-X`@Zk`BnlH}Bkp&_W&4i4g>wP}?zLJBhWR|PXFS$Av5rg@*^ea%GrmbHgG|Q!d-^r@M0Yy^Nv~x7* zIM&9U^u}@7UVEQj_#WKz>Fw`jd+Pi(qL6b$U&C8vP=yldC;1Id;?4y}euKR%7;P#p zGwz>@gOWX;5Vw#C`CC61Y$_8vTk7G9vI&ROGs;+!1Xvi$htz&SMj9&=`y zVc>l;oIZ1V4xcA}lA}_}o3)$Iu0wT&nL*lls6K z616GCIxw3GOVRgyI#UXgC3M#%c^9y^E@1{Qp`<_IDs!pFpJgs};-8ovvx2++ge^eC zHkV~4JY?Qw`I8n}3O4>F?*LiP0QjxQ8ttPg3c0)_+4O!cV7+97()qncL#ycjL>HggRUe6jW|XE@ilXX#gu zYOnuVKurvlr2kS7>}jZ5b$#J3YlR5DB^6?zwe+V_O#tdgs4>{SP=sokRFoHrShB5@ z6S0)g_YrCjXxB!ndGW=&ce@a=1dI+YEGGCY#QZLJYm~YR-!KJVjaD_7_XjbmU5$mi zu(j2&uf^WgyaV{piWbwzSk*4-$X+|1!f$C(PON$s0Znr+db6IgyefsB@~SwP3DVV)oqhX-HID6t zHu4#?*Q@%#RaTBu1M$k%Q~>?*!QdBhYMmR7?)gfpb@bVj&boom(`kPt^+eKzJ+_9h z*gG+u^=j=wda$y}hTj=DSXCx(qUvv_Yf@ICQr@zU)zBv_N5M6T>Qy6ZvDFPe`N*QX ztEs27^})}osh70GjBn5`BK!8P3a};3^h`BlCzu)ZbPZLhQCT7H$?;oNc44>*0!rlK zy?(1oo=;VR@%5{vs#cHTlTLvjxx#_CnTrY-Mjk}$iPOxT6zf;bshdyL{Qs~0cCk4S zEA(AoB%-i;{HmjVxtLz^tKkeU`;|YY_-hbZM+74=Wa5V1}~u?Q}%g$bo!JQO@%TlLe$ znF2_9if&3(?QnOMkqTFEj@G5B`uJqy%T$$y%U~R&1s?VdEgi2Get)A0dab&)$xvB+F(p=R9P%SL1 zQ45$_ZfPS68*7MkyPU2D`L=kq^g>ak?u;tAdCg`*yRK5^ltZuMKv-QB`-x z=ka{BrW$-Xtl7X@+v9Ii6X0^cyGdmxpD5hz@(Yf*4L+ey;FAGtb+My(=4Q25tFrzR zG{y&a{Nk3|yU2Rw&y9nu5*pf54bw{x2lw|>!?nsehe2pKga#Ah&?PI_t+%>^cMpqi zfi%!^u#b8Z`W@0&?RMX_5RKbk77A2c&6xGoA&xa{%=+pOKR|5ebD7nR2w+FT*wtk* zTt<)Hsir4f#O9q{u&MLU6l*%dzY?l&7p$U$THK}T0X%q@S_1ILUCIxTe7BVetVVFi z-7uoq9QYnv9{kiUT-m~V)D*?b297kcDehi1?{B9VxIFHJ(EGx@s%cCiG>_=jdX4BT zHM$Reu*{x<&)%ov+%QJ!kJfW(Yk&11K;nazfp>mTrD6>m`Jj67dQH@%)B$SD^-J~+ zKsO5L!T{AxTSl!0!qcpxVFOhQ{c-^<8K`d4OAF}qKvfkxd}EMm6}|9Oc#X`Un+BCoV9^m@A5-fTiu zuPf2za%BQm0bB=I4e%gfRlt*gQGmYyMgpqf{0tS;+U=<3bt&L`043l-2Yw0|0ldh8 zCjjGtmjZeK=h5`(YFzz)s=lDQ*X0FSSv9KqjC#%t(f@>UZuWOTZsrPL0$_X%8&3gb zG3x-v0=5FI0C;2YyJysBz1|YP7e{(7*Xw|l051TtSQi~w3dr5b3Qm0v5scZYrrrH6 zfXwGMKm+g&Kmiz%>prJ^1YjKUL;SLWA`?+tyT#}}t8r5;8{Xoymj|5N>*3)0fHU7i zfNsFT;DDK`kGo?>)PEPxt9V#H+(&MQA@g1B^SUl)oKOr=y9 zHFoOYF{6h022UI@DL0k2Z&Lke*c{bJ@XP*Deu{ZgA#ll{?Q_&a#>#qLS4aAKn(9D< zUxc}zq8DCN+vB#>_quwcwQQ)KwUJAA&sBZ&!c>aduKLjLb5)`?nJQ$d-jTAQJph#( zQu^bnN<=Df7PvA!m!;}P+~S}Q(&jAn7UIbv^Hc|bW%E=6Z44clr&?f+{WVXGK;}d9 zRcCId2W+(*!UsEe z*HL2!Pkb!ZwGebX1oiN&Mj9MlA!Q92JZX6AmhFA(kLm|<%u>HkS*x8alT1YhK}?N9XEFJ z#KA)+xA(bRIVh`mRoSrNoL@jy7FkZA^&(ZnxD2W!?sHf2O;w4sVUY^Nr8M`thNEh2 zh|&-+g??D1W{e4~8mXH8JAv}_3H7t@;E9t)jUC~e(yVz~ZfFecB()Sfmirg0 zNpYzyy{^HaWn#M@fl-HgafsT%gCU&SFH?05)gI$ePF=f}L7G%LuuL_HSd23EcBw&qIqxU8 z1|wHstAiD%{Yq7%o$CgB2yY%fcKF0mLw&<1P8>H8dh#Kky-QDLPIa}+#5Za3L?{#G zZE5~W)u8shAWH$+WI)z>hARJxNwqZ~sRI(<*m0A64~?5Lb{J+?Dl6UP zI!cXKshSZNL6QVCn(kkvYP9lovPU)=5FK{)nL2#pLu1B0g63U4kjI{(+o-9dh7I=( zdCWI$_{4GTef{a3Rcc&B9*WuG_fef!)%JS5I@`Uu50G0N<-o@Pqk%sQ$mFwwk*gK{ zXB<6f*=s6Y3kIvdt|n;_x7}z9P#Apq4NT=`&w=|)JhSo4#WNqzOL%xr^1}mra~H4c zPCSG0v}KdFVp;0Hhn2!+8dA zzeD9bOSw)6AB8k~#t?o3(yW7M>h!L9K0V=9uj^5uEF6zc2!91>R%Hn1PIEIM`~jq~ zDG1|tBF#z)mG?usSvmY>r0bW%Sq$*gT?us4dn!FWfPXX+Jv(SWVM6sWwu5t- z#@J*!0IXil9d;bF8<0n7%%~v~u_`v1GD+u z#E-SC(p9-?bhF3r^}6l_%JYXKvk=Y#md9I%aO$)}bx049jYD?ba@EEoU9B8G5owks zL_Z1XD&_FWNGIcIkM=?|PXRB_VRbZT_%#G#p zUO~DQo`&^OJ9Vs6ze|XAI_H(6n}IY>S9Xyhn&(~g$WB#Rdz@a}sYWy#aX(fE6gS7i z79PU6$?|xE5KeV=se$c6WWABi(P;?h-mnRcpECBbq2q=Pf4tF?O+#hXVJFS#BSf8X zp{!=e;<#-D{kcn}H!FO=>uLuyqQAXUhye@$Zvx0}J5;Sds_{UKpf~eWpKu>`A)8ef zBC8I=uU-zX37pxDp!&NJ0gs@Ec4MlKpl!Pmhm4>fcdOCbl?N^OoSX{M+n#lc+SYK)KEbfZX1f)VM&^Y!u4A>=Z{2vmMHpz}d01_mwr! zmYyoW&SNh9P@sMV_;SB$pqCCIc|cWfTnc%uQINLtduZ^ONy8^koWkpRsH`eDvN52} z9S2m`h}4Jdz`i{#JD?IH#sIaP7VSKs8br(n$`-eZemQ`%u{@x>5>vAe)e{T6H+b-W ze%MUwKUD4I#g7q|Y)GQG1f4+1T|vRpr|O{PtCDO(C2-9e}DXVo=H!2S65e8S5;RZ zvz~sd;ktr`1t&crtIBt~!ZKV&{-!d|JMNHY0{-Kk1B&9N_h&1KoA&A(hAZ1PO&#}& zilpv@^%2UprFAFNU;4$vH-{B2+wJP0hWiv_@6wKsv{LqNy8n@5Hz?a^!fG*b)B0UI z-chy%M$cB7yOms8G)JkY?4s8>IYoz&cz+2Lxr{LHIZy8hH;ClYW#ooEu@$+Y$c<2F z#7#;}>>NgmH__BEpUbECRAU|WeL{I5_RJO(NwY}dA|`Wz{(M47R?d+BNhL@#X(N!_e5>|K=tgET!rLr7f--K?It1F?rY%*Jje-5Q zYfXEra{^ScTsx)a2B_peT0g44S_`4%m0ELP^k1pLO zwDJobU4?v0C{*#P)`u%cP|j+tiCDm*3a18}v{)LuQtL@kYqUp{+`xi0T9Z`tanoV# zdG*&!>Q}7YqUe-ctX)E~@O`bRTMrjBY_1YZ@4v5gRP=y$M7zhWMAGo1nm;_!aQS1x z)i5K%A4$(1)taFoa8!F2$s-?XJCJnvNK3AXHu@v2B?^{&q)Z>9oL#7Ie%QskI{W$2K1}F zFU)syM>im!PAfjq>Z1$WKGE)r*1bF3;UQtj2UaJuIOT*^1|}jt)%t*mJ3iGqsZ9H% z_6;gMd`inzBt@Ur+90{%w6;j`(y`Opu5fR79EccKm8pI&tvRDLM!~)_TDL?mbAG~; zT+4{-0~JsNe0qB*Lo>kb!c;rlFkj~D#;DJOWlU*kH-Mi@~JIdIf|i7 z?d|CaxHcX=+#SZ*ixt0wG+zHgYeXL`S44*pBb6BpG5&CIn#?Uls78oCK0FF?GcspS z^@kX4=FltyMXx`eBEHn>43kVT+iWNTq9 zhe40Yv~FUwbj?w$`nAx=+%L7{L1-jJ-K+UsoEB-x9!sL=k`Fae3sQBVqpJBobi_Tr zmfNK&CPO4)0;oONLjXSXzoiO>4w5m+I5hFF?oaQ6XIV}e73FoxFR#rPC&z&V}`!>Um8;KZF5| zaDhj^PMwh(0tHA>*J*x9!_I4syPK4GxWmD<>eIWpNPUD#!#-?}AYw2}OlBYb-k&p<*r~6}kE{tPs$XZgL3tESmcy9B6h76<_l^7J{ zT+r%)(>E??{dB#9ig7`v@--yjrJKLjQaU@v;46G-NHVj(x*pFIUByawx`H>v`QLDZ5;LnLPpt+hvb$-(7BuQT=ch+N@YNBJR5~fN6 zf6{h>eyvJv7LvJ@+D)KbQmLgN`L$B>C7?%a1*}=8Jm4uDeS&6rsm&!V<#tms7ijQV zrecO$8r9gg5!i}pBhXHhhG}4|QK3F_1_|ZC1#&qz;24&dUcaOr;g0>RHIDc8_J#DG z7NLZhqsDs31E$l~pS2E6A;%Q7;5WG__4pI*aRGVgRH8o|Y8V1mV}H>GhH;Bf3+RHE zru?EM4UN1J@2XJ%?TPe`=Bfpnzdom1H9x#9#2VO2; zA{(m97ix_-#Kii>9l`LWCr8pZzi4gf=btsN2xp^!z%FAfBWd7et(ySOc;GC#taU)v z!OIxJNXopTbxyNN;HJWSiEJ6+wq=C)BUzX0pi|(^7wS)B;Y9{U{|et3ZTehzTDCOZ zr(wKl&hJ`1`t&y~4I>%yJ0gSx>iD}h2hg_PwUKBp>54YWZq?yu*A=Z*-2{k5_+4(y z3f@6JmywVTdr4r169W1l+EETJKKm1fl0YF>wFf|A+Er~tOk^{+tE0*e1>!me=Z<*e ztE=$a3C|^no4h)PtzlJIp}##<5?k?Ao-VDbVuf6Zczsixdq%~ z;BB`^Q;>VkBgP?jfF{@qUev^e+S2DXeCf=98YfY;#CYw)BA3y^=P@>%$IJQ)MK144 z9?XM0wBX6?eM-8|m7;o+L%h#;oCf?JupVO6W~Ag04uurIU?mJOTzw2@Pwf=AmD{n3Q%mKrotvbIR$fq!Zx02B`HWS!8F3E0pcd_BBf!52b{#4 zR>~su=41YZ&@B%26t%rsq!~$emS(YU=cYQjXv?Ni;$qo&;4tvN4Op*ubI@%g`vpiL z(kSGNrO5C;&ADJF#5)&n)F@Ou9~ln4xvV%UB?AXTMY&?HT>>A5i$T2|py#dPfTk1& zLhcf810#Ud&2FVuCf0V~{Kg1~!?;2V?-d(6XCcqvKPZ5Z#CZ4?b{jdI&wp6XY&fdV z-LEc}WOGS&IXyf?bQk5{0w|}QL!kGS6m_2%8FmF(JS8I(rrGzwbS~3-_lf@DmpNbM z{LFG{FjTBmi?`G6wW4-J$#!%eUJ5E?h{)K= zW${*7iCqRiT)lcJqtvrdGT*maKgBN6!(eRO?RbNZ^RTVqgsKL5>U3Sh>*5ID5u9U;8rdP?+&O zCtSls|C$%vZa@yfW!zB?tdNnnjYf=wDo?s!q|wB=B7ugnJ};UJeJ&U+8YI8VLePv~ zm?=I zE;1wmfh9BJ5@%qZ=8UrKlsZMUPCm^Pqm7_E{vwP#y61jzuTn@yd8F@uN<@cOfPMCF zAYJzSSdr?Ovre)LGnqjQVByawSElFwdU=Y7r2`L$ zI<>Ft27w4;9t$Si5=;*L{D2sJgJtgj8v}2#^rEUU@GfW6wg-q-j}zUKEwlc6N;ac^ zjuYbsEZA9OPxal>jVthMaG0RnKHVq}0;%c7sUXm(I*??Uh*hUH0NRo+`l9z&(?z|I zJkU0zv7nF|j~B_;l?9su!7A$i3&F?6i?$&6=6F$0uVjLu#%4M;UNpKd55{A)%%)ln zKWsth$f+QJjuZz0v|AVi&@TIKtIl6La>oQQpa~DJ73r!7g{)u~#slZv7nAlCRL3M* zMu#Sdq^|Re03{eNa>Bj`GX-<#E%NZT2V5FgSBy8f+*=ck{1Zj|UGH#7xbZ&QH2bO) zOSr}%&d1&r4@wEYzxWRRgdl_UnRzHRX(FTNc%y>fGg-rUW&sm9lrvEbr{>dO)xS*? z*LfEdL;E%F64TWx#$xI*Ni=I`%~yY~FjWp`AN!*Sv;<>5Mk^lKQ=-t7ZeX2<$I}BF4isAlt*5R4>!u$)bBF%k5XyHSvNK(Yl#Y!}3_z@0y;e zoi$_qZ?$XA3N5CHHpv0D?J#4xH3qhitnOti1GA@y4GOJfakif(#$q@5hlwJUieA8< zgCk({=Ja$IjhQYI)CJoqW4f3e3@ye|#Y9vbHv<(-=Qf2dvb#0C^rQzx9mlKH2vW-E z-!nx^SV48C@}IR;*tM#MG+8@nz)X>9qt_r*%+XGd@SLMTS9*oYXNu(7m8>w*_?;8p z;D&(nD0!Bclaa$tJ<)iDlL()wQKsm(a7HXL*z92@#$nC~M+S!Z1ixS4Kdi`}bfW_A z-aQ`P4a73qw53~6(i$4Q*RnxV-?u`E*dSFV!c;rNnGh7cD2V4p5p{aV^s?y>iTZje ziVU3<{UOmH;{rqR##K&2(H5gKfAjX?j|UmB^&EcB=RX{LIEEJNBRdVQvWYQR+tGss ztX_LP<_06`q{0VyV9rI15^H?Si8;lLNH@3_#%U)9J-NW|m-!ESZP+CHCu81w_=Bx5 zrk;;?mQO89J{%!3^#Vo-Qn&e_MGuQQL#pHkqc=rmN~)99yd^{y?|w(3b}ws+*OBfz z47^ohN>_VC421p+end0~DFp?XMD~7~{fMX^`z?bp#-E&EkJuE=0eb5Z5u1^Bz{Gr+ z6MNhp4`}Xku&!ABdeg!z=TJoRnIbU-zMb=ljyTvZ>gnkZF_pjnfV-?>w^ z(l~uU%&mg6jMjE1at<<1Ro$viT*JpIMr13)Y-Lj4$Qd!!Bm|{FxX#p1xj>z*3JSpu zTjL3Z;EE>DnGG%oIeP#18c~G?jaW}_JcgB3G5!1)>}~5I@ZiNsSJLC6L5Bkjg;lMP zSb^AhKH_|PJWPwoWQ*h(0{VW6rams>MwBy7EvK$o;%E%!OzxCp3BNIBq%n`zL!lN8 z(;_juV!==yb19>6OpRu8>B8fp)&HkO+)c9)r|#$JppLPelSm&#%yzrpf=nlQfL6|i zt6fG1W@9D4;8SaXne!>o?746+`7=a^unlK<3|fP&Vj7tt`YG$^jSP_$wzXRRzcR(Z zwqMM{>>Tag#hz*rzw^vri5KrWkCF9^oq@g;a^SkoZJrcotDr7fqG4o3%^EZzOQiKE=B~KC+dbG+RE!T8QXS|hL(+jx zFcbr}@ z6-#}^xXNGzgILz%^f*Wt-ljTTco4-{@Fb8E85t&zW`04d9T>!FTrvK`r6wtpr;QB8 zaw&(Oh!w9_ur)c8aoqkp%D<#h_MDVhX5*LaEIJbUjAtDZd z#}hV!acV+AB{!V{ zB&%sQOH7ZsfzMZpOa%;%T!q%wQ^*?8p1xWodcyNHT`lap1$lr_GD*2Y53RwD*tWo! ze9=l#%Z}5kX;?p(zktB+*m0_uE?Q8VwW90a+U8!i%@{JHxc}-mVgi@e3ZJY~%Db0- zBMZ*L+^#bUATlEf8B2TK&}``+y_z{Fm1nL&sXPOec68)baTv?dHXG2RBd>{(N=X3k zQA*gKpxM&p^2Zu~Q2*D_$6d7Kb@2$2h&M!iB&lzRIvsbFB4TXgawXTf{;F~-_9#7u zI~~=M-A1seZm`JX6w%`~D%T5Q2nWNVTOUP(%#A|n6w#44#Cb5V*m|*?}MT8h(W^vfH#mplYhnvOW*A^$)#Svz4L{%}}Rv?nV%aj6BCW{Kh zD}Xw`WkPpZ$t){*9?8%kyAH)zlVWTYMN6D45#}e(ERMUj*pf*OqlWAGcxR={+5@7Kqh$i7-e)(U!Rvv@Yi zUZJSD7ohzrYpfiE;ApaXgI@;l->?5>}FM?4O*y?2+mv0Ls*_F4%z;Y!7(xls%d z?+6_g%gt>*1=C+>vTV6)$!j0mTc6$~)}pb@A{;7}(yk&LAC*$G-SAsxQg}@` zxd-0+3Ju#Meu%!Z8e-rfc7#|?Bln8N%2mqViy7xCy|!00LGs~V(HzMidqpCW_6Cyc6qQ7Z=9@IHkm~K-Tq1*)JPCrW#ji$v)8#s9W}#WKQoB9qQJs5tiyauDS z(|w-nlhN!|n!aD$a7`=m)mu5bA7Z^q7x$ZuMISI5>wEw~%~hImKqMyAY%{5f@(TyB z$5OMjJ_Ph~a+nckb)g1N4bowzPT!Iaie}ikxbdK9<7jXmWgs)U_}Vcmr0oY0%v`0< z4q`&SN|z6sEH*dt_b?<3&bMmydYH>o9G(7-Q5ZK`ubJg8=UNsEt&g@`SDABZt( z$(M9*iD*fiKY-C(pyMBi-eFl~!Kj3ql!$i9y1+dpqKDGSIb+1K+dN}baK;F0h{UGn zxguAJ%hkcO4g^o<05@~FI-2llI(k&ZfSYqi#q@4LA`uo5m5Hb@DdSRACDo{?0^CN0 zlJ4DuGfrCep}0$VmA?B>Y^mY~$Kib932t!lh+WOIUsY=z+&ons{=?zs`;Ww6(7N%M z_)RbW1j1`!;5y~UklU-Y`eU&t#y+Ywn>Ut$A2`q%$3>gJ>jKUR|6vzCKQ3Ai2?`-G z$UDy$@S&&BPSDSwFUP9npm11PTpiw91ymE##805`CG^%OVxH9%KMgq{{INw4LkG2j zPvLVFTp5B3GfHU53HZEiwDSa{Q9`vp75VCd^R(qtn8`N!?o-q4kN-^khVb(KlQ5y? zcF4Ek>uUnMQ;?xGQ{^D=HT-bJn@@=qx*aoC(BRYX^4sXC)8f&D6R6EWw-yY#HSS$0 zC7eM_SV)haK~u*l|BUDm?+D9>EkPb=XbkRTg1IwdX#*>S<_&EpdN;+Ci-Q-QgUDzh zV-pSlvUa^|AeB(@S&^NP^F5b_gS=I09}Qln38ms^Fg)sWIGSu4@P&9DkpBy;N7hw? z8bm5xu$+N3c>}`*B?4wFHTzO*3^wcza_8o5me5aMisJuX`bn9%=U%7VhA-G{HWcW{ z<%*zwtE}%8)nSmoP#rF<0u-F!TXwYIoG>ujN6v{B=+bZJ5NDsD2fq>>0S)|GB+`3d ziBUjkeqKC{tc~Zz9T`D>8U^{`-3@Fj?)@QX{nl9kVB7jl{x(;K!QY1J@VY8M;d>t@ zgZ5X1l1xNj{|5Md+u>_4>{T?f@66#qY`XuE4$V!tEY^OEe zQh0-E>36t#u#IlI=-|fF3m3&8y8;JQ7GplVVJx>&==b7gdnNdn(p;MG{a>11@YCNm zy^PjWh@^zlzc0N&IX^;1zgCDst0#%{!4H^w&F*xdv>!!ueT(p4Wp^1Qy$dPr8<9}Q zBL7#M>`GevqsaO1LJV~IN&Kd%i+-hAq4H;>fmXkX=XBrYt3|x&a?WG8`ru-(!k5c* zOlgvDgyG%?eW}U;%H=>ixBOl~+E9~Udz4Cw2$jF6l~)N=_5}`y$v6*2^@~V(Gm@5G zxdO=nuNOpC2i#=90_#<{Ch zv{tE2_ju(*kfH=oJ{P!=obYn`BF^6h2YL-OHC<~LN*NH)g2{&OSQ z6~o@PvHT1p9??WLLuSV&a*ng3q8MwGV2pmai5#kC|3)pE%A2tJ@L*F2wTOy1DdnU+ z^+=H|)CIrOgcNxjV(p?7d9zyjJMC^N+fk2ZGES|ufoGb@7D_((n#=A~$?pgFy+0z9 zNzFm-3T>VCU^l&ZgTKh7NiAgC2H(Pq8&SNGWbP|nVKC0#S5k~6 zw5x?oX#5gyT!k71X5z!{Cw3M2y_o;lTXH98L>n1Hk*RXP@KWBpiZs6Ggg1#1NnPgm z8u+N|#R&jkm<9?TyYkl_*}N_3tx+|XvuaeOcT#0s#(K^VH8yhM_L*FnHv(#)+O60} z6kfZPx4BNlKdZ`@VL?5?uKF%ljWmv4Zi$pPQXxxoFSVQtxVM-*%#0d*P-aW8{3GN1 zLze9m35Vq?Ts7>Uv2346I8~qi6;*X((XUBJd5;j|_g6_#n^xd(sfD|e6W&>LP=iuN z@BUhsrHn%q>{PO-l5A1E#6-f4jsFK)88}|Fi9sK$E5=TXv7k=Dvdr+YhLr8mwvQJa zo!V#dQN8Lhgl#o-%Bo7e)1D3NO(BaD z^Vp*tS$yvRDvbpWm+Ne==7zIn5)7If&Q->3Za7yNx4Ge*#k(q88`Nr zNu!E*Yn%2N3)N-d#z`5!+my@>Rw9EH{+bSE@!?3gL(3fBy~i=WMV>HvCr#FG?l_Tu zaA@;!TiGn)YbI#lWx7mZ?PR;b6?3@@e1wD*hsirS$I{>M{C-nH}5c-dDwOry7%k5?GmKlz;x&`r(2n9a>b24C|- z<#qJ#b@GlzcP=7Gmj~XFMR7-&cHRHT8Mv@V#rT+;+FHefVoLj4v-aN%rA<9J0%n&YJIlDlpSg-@Lf4Ld_s+6YMkXJj z+72L#-`U6;w!dah;*KS%-$I3zZ6IXg|LMPZPH<&)`B zXW6jD|KY@!dUcU2GKz6}i=~~BjE@|_$VD4W46n`L)AOy;B=Z|A<3$^+8y?N2@7Q1i z^M;Xe+6J41d%5(<1yjT2qY_Oww-NyLB0yB)J;Sr2I?^z4Gll7(E?jVTIQB>ns z8*Ih1t7^Qw&_Yfy@2MEOY%r2%SJgOTgW=}o5#uu(tjiz6sK%ur$Tv7z8##+CS|9L* zeUzWI;ch&=s>aG3tGF{Sjc|TKVcoDs*-Hbu$w&2^B^Zw+<4WMeZt^iD(E*oYaLrQ; zCxgazmtR$3-_ZjLlpsjCJ>_9_!7>_SNNh<2RvGd=toZ_?Zrry3E2vV1ir{{^VPHkM0M_wDS9c_OEM17&G*Q=8!W{643=!$@fjAB9)VRC z7yK=*CU9J}i0IvWDR8fBE(_M0-KK#<{B;C>gMmdoKI+1$?Nr0v2cPCvQpHGli}O9j{SU}w8a+zJ zdF^jDd@6s(t3uMxjFJN#w9-+sUWQGv4?cdW1aTj>H2KqGd}RRux`3N*$Tt7*ZEbu9 z#u%n#m1%ta3*%=o)dycKGYP}2#hK;?eq4u=Cc|!KG`(<0Dg7)7pb0bcH5J)Gh z__F61O&BXX;DGMMvGT5eF1haiyU>~jd+eza8v1#y%;?|aWZgS#WE`xrTp9X%S@6d# zti0Y&-Jtb1l4Lirz|x%l6qPQM=(BM$P0cK)uyolRAIfw{mu=?ntpGdmACGH0dbp}{lI#Esrj(d`9)iFrT zZBtX28aI(_et-_py0#6~GxxUa?}i>gLskS9)!-Y>{C1 zcPe)ndlXe2zBpOlf)00`A_v!yb>0+{tE029mvUr^yxtq^P(RqL2U~Z(sWQXQA6far zz*=&s^TCy6ioq|cil)l=7WU|~`a^zxm%Ar;_`>beZ;Zg&nyb6;Atozg4yn^*OV*w? z(`3Em8eeSTV`6BceiMJOh1bw@Q=6ttlh*~+D+FU$FikG@n@X?a>(|q6oWJSbBUp2c zPgcAq-O2d66rO`dPM5de&Wej0XPKt=h`{HmC)_5B`1TMVyVf$}8F0*>BBIS&K72)p zoAAitZ!dA_hu=c^jr+ylYU4s1h0c(7*AONKke!Dq%={U0cF>khJ>sdR)q`@d;{cy| zP&PF&_&Zp~(b4V)Wy3i0b2EI>hMsT{cM^Z-w+CfQY`3M%lnujpoJ@BKs)J`re=`=L z$r;c0Fl9Jshz>q7=sitAf=vEQSwG5b0;)Ye+0-9oe=t*C@2f5-5VADP3k+}$*DEst`T?kc z=ttzON|#dZ)-n9yVor@>8@Ry0DI4H4h*oBnQ2L`XnYDT0qfmj%^!lUn_KwwM$sbu` zBOJ)4JMww@<8%7|KFrMmBOZgl^KM>;rp#-22-6f}H~DAFd&08+!z}WmE|=!cmYs1B zTr^t_3EPg@3FnS5m+jOv1DnPr)IURZ7?}GadKB^GlqOV0}{SY6NXDDoq>& z5-5&0w_407|1z>s$~&t3X2xTc^ic+4nG)KSC*zbIl$eQtV>@-vlr3WxY%nRaiDxtK zEpVJYJ5wel7Fz{8i&U|L;I5oDWy-Y*?uXBjDLBB&m?OIbdS?zcm`_mn6S98lu|g2y zog$nWnrq?+e4~kA%ecS=e3S4j_G9vQ0w|!tPsn))vr3=9tg(SopOoFag%DTp@}goK zrH7uB)08s$_DSi-%o34>A*&3eX5okeH`yM0N=Tx;E6?AcZGMJ8@;EjcH zhN4^vG|Z8AD$y2gOiG4=pBce;ETaXB<(QZSTOf^p;nIWoO(FxQ0-h!ELscz&m9FN> zdUR=-?2EI4?$1ddLeyc;N&fciq37h3u<}=Vbo-)mF8%ZzW_=5*aiy8>MgI5DF#Jk@ zk!@-iex!p{F4fFn;@4B%=VU0o`Mg}AX1_%JNEUG#kt_Q*xm-ou)J2^7p&p+m?!fOS z;g?@vImRZ+%!R_+?Uw%2b|-}8yjI2f%;j*rR>QkM=NC`HG4hnTq#pVmB8qjv#aj6* z27HQ7iSQUT@u9`VK}3EtmYpwxjIrxzXRBCe^v#nE?kZl-J>VGMG9WMBunw<4ws}(v z4a3F!@6@;vo>qJopOzVi?=`b=H42>5=Xr7tCbChhu-@24`&L2C^U1wh@)xBeS3~~! zl($;eL0Mq6>>69}3Uh{F+?kB%}PTV7#YF)!fGmy1+AH-MH?jH1AbwenLBGrE#ULHqjQ6s@ zzSrcx6$r2P>#}9%3Q)E@g@TD1B4hWOv&qS1hz|glIcQa^Jo38SrsN0OzaiVIF?)kG z@ar|G;X!EhaDnWWaOHhRU-I|xo2@Tp^nQUHsjQ*aZ^_t<)nLr8@D*@(8iwP;1qxPo z#;TgR#p})7yqdZDt=yG0bBps$+!Zx*Kg?HnfwtVrbNC9vy@i_h3>*T;;YVc}qU${|(JZJH3Zj+$@yl~%KB^4+Peq{l{ zId4ZRc(OMKMr@L#Vz7UG8+#M$sLd9c)~vFsiYZ78STM&LA@hJJa}&+mB6I8IZ%50C zKE-?3oR@H}2shy6z&p$+rtSgxa8eGV;QSLP5z)LqWMbfsQv~AQj{-8k_i@JHy@QBo zFpZnDjNv`WAio)(RF(5)l)I&?jUW4`+>nBCGI_|M7v4eiet4^FDXL`zqP9u=7+Wz7 z+Acc?la+jWcDr1Ttfo8UBy15pze7F%abMjbzX0?_p}e8FJv*p;A*`4uheB{*{?o!$cglr;roAJZRpW_2W&Y?L*{E7p z40(6Sc+B)EyX2$3liXc6To#!5!x)ahASAT;1?|}-)0D61r(LqWa-LF(5Sh*m(C{K` zJmpbdksOBk{Edq;j-q!XnpjC)cVm2y1*Y$o16B3J25T?l#2$GRA0@oHS1#j;zQ_I= z6FpWdMtx7-GAU>_DLXhd4z?tTFr}`G5z3#KBKczKp_7$WIzquff97*&2MCtv_Ze1_pz zMNfYw?}=wqXZ>g4;s<{4>n(i{aQr}*Kf~70af&;M;rxY+lQOx1rFIr-WR>FDL%)Ka zI4SRkq`y8XM|8@qMwU0dOx1U{sxubqD$YP*EuxnTiMvg3#|PXC9!#!U`(y-4et`e zah@B2|M7Ad&}#an95K#zn*1H0Rh09cY!v?;TNf^SnjR|z+t+rD!;EvB%D=uVd{c#-3L=evke`Cc)gNHgJ80OCvXvvHr9UFR z-Adp7DF4Mq*8C@#UHg6R8*W9ia=UyAeu2n1MDP6sl|Dp2{Dh9>P;90AUd`G};u5?? z4qblb&x_N)di;Cmy zAHRx=J$ZEWs(eH__Vz7$ci_={MXv`+uP8b@jsuE**$GrsK5;t1K}!*RsOs%wg8Ic5 zs^NV(Vwj8e}4Ap&3q+}D|14ZB1eR^Fh*#mho-ku zPSYe!Z(aYZQnbv=!>xGX%CF#k7$bth-Q4>vmy9tl)qEZotSwEu$Uq z8{i5Szn4;3Eikf;`b6q;z`(&s{l?@>L}IwPQT8qpJ_pTV_-hL?4^}IvjaTm+R`#A1 zv8hHrJ?Pb+LWuOc7u_kM7EyXj=mnCbI?fV16M?gJGLvnsxpQbyls*7H@NASm47a~} zMC-%U1@8y)qxCo4@J<8c^bX-y&fD_^zOJVwar$EknP#heq1TBR%?rJ!s7bt@2QN}M zLa$3_;`KZ6o-$Hzn85zt$W)A~FZV1kFf~DcQ43pd)8k$=sISjfi{7WwC_O%~rM~_+ zD`OkK9vh!?7JOh`(8U#DhG_asBXX*dL&JS~Y|E-bD}KW_2V5Ae5^7edZC6?2*Hfa3 zQHb&5(NlT!j?hUTM(_X6*4oCI+clv^A$V~46QrJRQPVsG(BP@`01 z-7zG4`DcUMG}2poU;Pwdit!sKYgBmYNsaV>WmL%yU)+PT=NgIPYjfn| z>qua06Mc{>em{WzT&BoodS{%1-P8;&x<#6 z_B7Y~BhZU#q2GmhBfW(_1Y6tJW~tQ-snxX?z8*e=!4;#Pqxt!1JRhaI!Dd(+rqmP(`#08xGk5QU0(zsp zj$ii(oNTW@ij`^L&JKF9qV7E$JS7be+|Ws{9n1<$?5uz8QJ*|W1H0=9>JtYky}SNO zbvUhuzPUPlwTHf|I{aBr{ZMtd$j}$SQ}w@IA5uMg-}U+pu?H{(z{6lwZ@%H@81cJ8 zRKJ&=uVx>lqF#Cu)^MkLLHOGO`VD%0cT5QzoM}t29cZV9+uWV|=u_c9U+bf1CtfPq z?ZRph=Be>!MQtR!G)BaKOJDsxrB2a@5G3!>@ue@f_j&Uci5vS+m6Uq3K3dKGFtFri zeT))Ucoc}5ji@mqVu1WW#4Y-59NCZP4{mUto;gr|RoNS8F-YI-zGEF4x4u#osJNLS z^9x4&D69pUUoc8Q$GFVwMhKv?AXKv~g3HLbLw}-n))C8z8Y=(Ru%d?J439p!10!8Y zSMJc8A!#yLUyh_`F!ZUCz8Gv~0%{OwaVOLyvJg(h;s?K%3tx5LUHXGMPXyTh*g&7% zr7ymA!-LO@8`7$~^}2|Sx81F`jwprroeOVQ=;yoP?W$BI@b7!{C^vL&_Zi&yg`2sgEQDjEr;vv)CC7= z`U37{pV2R2z`S!y^XhKwp8z5X0*{G_2<;^AI>W} zrnt-^SJ;aIZH#_h-KhR9m+RknF4yt8{745<*G!0WC=JWhceI&P*XxQ$ZZ6U~NOvKv zhx8QEx=4RP8irI&^14EiCItG;(F027_v?9GI^d6yN~EXk^h=~6fXnUl64DsJdVR0U zgY*UJ`lLR&`G2eaBG9}*tExuFp48_W4*s7g=VnC%tC>iowE;J@;Z&r|W(TB^NP8o# zh4i+-$}D}n+Uym-7yElI*A}F)NL|SmTOK>rk#cwP18GkqKrwnZw7NeKDbpE>R6{xn zsX*%RHO?-dg)|EJ4!!)qu59?s&g&rt7URA~RyqXjvp7lsb9;B$@F#$o?rEfMq@{uQ zXY>K?kXulHH=a#2`B^v)P`@8*wUZ0=u{i$ewMgF)b)dP|)emjtVZ69+#T1!?K4V8c2S{18KS%Eu5}#@b zvI*5)tk(_c1d#jJgnBI2n}!Ur!HG0^vHlvuzPd~Fu1M}&qPNfKk`1$_@nYIs}nl0G{s zwXN4R2B?kEcq-CVT0{E$kl1!sL#fm*S8o_H8X#->W*U~O$19J~tXzF1!t|Ks`t+zy z?Y*uMC}a!e?sXzsuD3`mL^d0-Q``yfY>b@(CztDMRD56dXdZ?(m%hx?hiN@Kp+TCz z3NiD@RdB?a^zq{R zU@eO>)?y;aqm^s*w0c{S+XT73Nt0*z?w|bNq|q>d6qcpSb%D;W)f@KqboaUv045;? z`>x(RmcHp|3M%%-!mfV7BGo& zRzV&o2Of&|R@Gp(0`8ns&W6Qx9C#ew*1k(x1*~)ZgoR2q3e=L*T%x z@XqpbVD29`izXTF^B71zLd*TAcn)-#53n>}4z#9mFUhy{2E9`Ovg^Ic_Tm#p zOrHTyI&tLW3BFrU#xs4e3Sgxg?vxRuN5dvv57GFy@n3t`gW`Kod=5U82XeEG?xe$g zu;t-Z`8@|&6Ypl~x<&7(W)0#=^j5ga{af^>m3}lJ0N?Q#jSnDn!tO;t?}%hSL%H;A z08>~r#c#!g){XAm3Mh-71Qb$un-yjp#pwskqJqBN3J;q=Y1{OM{@ZW2921L}b;p4R zsV-LohH3gXePzaFptT1$6TNMXG#8xmKQCwl)8%XF3+CN&hZQz(2;?*Wxm=@>#~}r) zNdf9`Q&yS%cf<@|CUBT4k8Cd9S+MPHHB%hPAcEaMf$ivWDSf{kovcl1JCJ13axK!9D##(@|5Xm_dhsk)QoYHC$*Y3y@DDR>cjj4@ASF`fZQg8O+0?pVL!w4VxfL7 zjyJCs>iwde(vAp@8kwc{?$pP(nSYnpbr(Q38xEr!nE9;^cW_|(WvAXX!$F&j?55SK zO~HG;YVb6?GcOMQbiCK82G78IBAza2&%v1uxH^r^fZ0(w|9c8Cr^HJ0-%8ns&=5M*%|vRN_?T79T_{c3PS zz)WryeYqRq<}7OPE*7=3X!^T|8fMXp@9N|I$M5sH?f}k6JnWAgcpTojyUQqTk3I^g z3QPCs^D|b0u^c?h@Vtj77tbC%ocAW4SMj`K!}&-z<9P|sc07mhFdjdv@VtfR_Q77) zVLR_dqyan!@!-VY4Ev$ou4uf+;Hj;+Xw_bQTuA(IYuZN~z7M|RE`Tg7c$9tcoCj#n zKKM6Gm&z?SHkS@e^)anG9EE)EUWhq zDCZc1<{Z>x>FRzxtZ~CpmP5%0Y5vy*lbrM331!?&CrUe@-y1Rmpby|OT6#e56}1N- z*ZBx3GxZIfKcF{k>12nGwu+OGviJE0Xqkab559`-A>vX>rl;4b$6=T|nNn^+O#!MRR8#ih6n1_6i zA)ooXnPweEM3@JVwRI!Cc35u**K_u;K2N;&0siA`?PzK-;^BG4dL5aCU5&6!33Omf{@PpZQy)!^&kYI$Mll#dF+6#l+G*#8LVgrWQ?r0gzULy9TNwFxOu zUEAo%_YujL0c3Og5h*Ln&q%ok+i3s$dV?s3O3FB^C)?WIEci|RYs%ikrq2IAqgFEu@;ca6kQ?@KLOPXC2d9c)A{jF8qL} i7SyFZo_p}HI Date: Thu, 22 Aug 2024 17:36:21 +0400 Subject: [PATCH 13/15] add new tests for unordered --- wasmbinding/test/custom_message_test.go | 3 +- x/feeburner/genesis_test.go | 1 + x/interchaintxs/keeper/msg_server_test.go | 62 +++++++++++++++++++++-- 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/wasmbinding/test/custom_message_test.go b/wasmbinding/test/custom_message_test.go index da6a314ad..446c7159f 100644 --- a/wasmbinding/test/custom_message_test.go +++ b/wasmbinding/test/custom_message_test.go @@ -3,9 +3,10 @@ package test import ( "encoding/json" "fmt" - contractmanagertypes "github.com/neutron-org/neutron/v4/x/contractmanager/types" "testing" + contractmanagertypes "github.com/neutron-org/neutron/v4/x/contractmanager/types" + "cosmossdk.io/math" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" admintypes "github.com/cosmos/admin-module/v2/x/adminmodule/types" diff --git a/x/feeburner/genesis_test.go b/x/feeburner/genesis_test.go index 39cac8755..4287929a5 100644 --- a/x/feeburner/genesis_test.go +++ b/x/feeburner/genesis_test.go @@ -4,6 +4,7 @@ import ( "testing" "cosmossdk.io/math" + "github.com/neutron-org/neutron/v4/app/config" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/x/interchaintxs/keeper/msg_server_test.go b/x/interchaintxs/keeper/msg_server_test.go index d06aa20ae..a04afe5bb 100644 --- a/x/interchaintxs/keeper/msg_server_test.go +++ b/x/interchaintxs/keeper/msg_server_test.go @@ -33,6 +33,10 @@ import ( const TestFeeCollectorAddr = "neutron1dua3d89szsmd3vwg0y5a2689ah0g4x68ps8vew" +const channelID = "channel-0" + +var portID = "icacontroller-" + testutil.TestOwnerAddress + ICAId + func TestMsgRegisterInterchainAccountValidate(t *testing.T) { icak, ctx := testkeeper.InterchainTxsKeeper(t, nil, nil, nil, nil, nil, nil, func(_ sdk.Context) string { return TestFeeCollectorAddr @@ -157,8 +161,61 @@ func TestRegisterInterchainAccount(t *testing.T) { require.ErrorContains(t, err, "failed to charge fees to pay for RegisterInterchainAccount msg") require.Nil(t, resp) - channelID := "channel-0" - portID := "icacontroller-" + testutil.TestOwnerAddress + ICAId + wmKeeper.EXPECT().HasContractInfo(ctx, contractAddress).Return(true) + wmKeeper.EXPECT().GetContractInfo(ctx, contractAddress).Return(&wasmtypes.ContractInfo{CodeID: 1}) + bankKeeper.EXPECT().SendCoins(ctx, sdk.MustAccAddressFromBech32(msgRegAcc.FromAddress), sdk.MustAccAddressFromBech32(TestFeeCollectorAddr), msgRegAcc.RegisterFee) + icaMsgServer.EXPECT().RegisterInterchainAccount(ctx, msgRegICA).Return(&icacontrollertypes.MsgRegisterInterchainAccountResponse{ + ChannelId: channelID, + PortId: portID, + }, nil) + icaKeeper.EXPECT().SetMiddlewareEnabled(ctx, portID, msgRegAcc.ConnectionId) + resp, err = icak.RegisterInterchainAccount(ctx, &msgRegAcc) + require.NoError(t, err) + require.Equal(t, types.MsgRegisterInterchainAccountResponse{ + ChannelId: channelID, + PortId: portID, + }, *resp) +} + +func TestRegisterInterchainAccountUnordered(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + icaKeeper := mock_types.NewMockICAControllerKeeper(ctrl) + icaMsgServer := mock_types.NewMockICAControllerMsgServer(ctrl) + wmKeeper := mock_types.NewMockWasmKeeper(ctrl) + bankKeeper := mock_types.NewMockBankKeeper(ctrl) + icak, ctx := testkeeper.InterchainTxsKeeper(t, wmKeeper, nil, icaKeeper, icaMsgServer, nil, bankKeeper, func(_ sdk.Context) string { + return TestFeeCollectorAddr + }) + + msgRegAcc := types.MsgRegisterInterchainAccount{ + FromAddress: testutil.TestOwnerAddress, + ConnectionId: "connection-0", + InterchainAccountId: "ica0", + Ordering: channeltypes.UNORDERED, // return unordered + } + contractAddress := sdk.MustAccAddressFromBech32(msgRegAcc.FromAddress) + icaOwner := types.NewICAOwnerFromAddress(contractAddress, msgRegAcc.InterchainAccountId) + + wmKeeper.EXPECT().HasContractInfo(ctx, contractAddress).Return(false) + resp, err := icak.RegisterInterchainAccount(ctx, &msgRegAcc) + require.ErrorContains(t, err, "is not a contract address") + require.Nil(t, resp) + + wmKeeper.EXPECT().HasContractInfo(ctx, contractAddress).Return(true) + wmKeeper.EXPECT().GetContractInfo(ctx, contractAddress).Return(&wasmtypes.ContractInfo{CodeID: 1}) + resp, err = icak.RegisterInterchainAccount(ctx, &msgRegAcc) + require.ErrorContains(t, err, "failed to charge fees to pay for RegisterInterchainAccount msg") + require.Nil(t, resp) + + msgRegAcc.RegisterFee = sdk.NewCoins(sdk.NewCoin(params.DefaultDenom, math.NewInt(1_000_000))) + + msgRegICA := &icacontrollertypes.MsgRegisterInterchainAccount{ + Owner: icaOwner.String(), + ConnectionId: msgRegAcc.ConnectionId, + Version: "", + Ordering: channeltypes.UNORDERED, + } wmKeeper.EXPECT().HasContractInfo(ctx, contractAddress).Return(true) wmKeeper.EXPECT().GetContractInfo(ctx, contractAddress).Return(&wasmtypes.ContractInfo{CodeID: 1}) @@ -441,7 +498,6 @@ func TestSubmitTx(t *testing.T) { require.ErrorContains(t, err, "MsgSubmitTx contains more messages than allowed") submitMsg.Msgs = []*codectypes.Any{&cosmosMsg} - portID := "icacontroller-" + testutil.TestOwnerAddress + ICAId wmKeeper.EXPECT().HasContractInfo(ctx, contractAddress).Return(true) icaKeeper.EXPECT().GetActiveChannelID(ctx, "connection-0", portID).Return("", false) resp, err = icak.SubmitTx(ctx, &submitMsg) From 9c66eb6a7e3d5753dc432abdc3bc83bf9c869eff Mon Sep 17 00:00:00 2001 From: nhpd Date: Fri, 30 Aug 2024 17:11:39 +0400 Subject: [PATCH 14/15] cleanup unused thirdparty/proto files --- .../proto/ibc/applications/fee/v1/ack.proto | 15 - .../proto/ibc/applications/fee/v1/fee.proto | 61 --- .../ibc/applications/fee/v1/genesis.proto | 60 --- .../ibc/applications/fee/v1/metadata.proto | 14 - .../proto/ibc/applications/fee/v1/query.proto | 218 -------- .../proto/ibc/applications/fee/v1/tx.proto | 122 ----- .../controller/v1/controller.proto | 12 - .../controller/v1/query.proto | 42 -- .../controller/v1/tx.proto | 82 --- .../genesis/v1/genesis.proto | 47 -- .../interchain_accounts/host/v1/host.proto | 14 - .../interchain_accounts/host/v1/query.proto | 25 - .../interchain_accounts/host/v1/tx.proto | 35 -- .../interchain_accounts/v1/account.proto | 19 - .../interchain_accounts/v1/metadata.proto | 23 - .../interchain_accounts/v1/packet.proto | 31 -- .../proto/ibc/channel/v1/channel.proto | 187 ------- .../proto/ibc/channel/v1/genesis.proto | 30 -- third_party/proto/ibc/channel/v1/query.proto | 459 ----------------- third_party/proto/ibc/channel/v1/tx.proto | 469 ------------------ .../proto/ibc/channel/v1/upgrade.proto | 43 -- third_party/proto/ibc/client/v1/client.proto | 113 ----- third_party/proto/ibc/client/v1/genesis.proto | 44 -- third_party/proto/ibc/client/v1/query.proto | 207 -------- third_party/proto/ibc/client/v1/tx.proto | 175 ------- .../proto/ibc/commitment/v1/commitment.proto | 39 -- .../proto/ibc/connection/v1/connection.proto | 114 ----- .../proto/ibc/connection/v1/genesis.proto | 17 - .../proto/ibc/connection/v1/query.proto | 152 ------ third_party/proto/ibc/connection/v1/tx.proto | 146 ------ .../proto/ibc/core/client/v1/genesis.proto | 44 -- .../proto/ibc/core/client/v1/query.proto | 207 -------- third_party/proto/ibc/core/client/v1/tx.proto | 175 ------- .../ibc/core/commitment/v1/commitment.proto | 39 -- third_party/proto/ibc/fee/v1/ack.proto | 15 - third_party/proto/ibc/fee/v1/fee.proto | 61 --- third_party/proto/ibc/fee/v1/genesis.proto | 60 --- third_party/proto/ibc/fee/v1/metadata.proto | 14 - third_party/proto/ibc/fee/v1/query.proto | 218 -------- third_party/proto/ibc/fee/v1/tx.proto | 122 ----- .../controller/v1/controller.proto | 12 - .../controller/v1/query.proto | 42 -- .../controller/v1/tx.proto | 82 --- .../genesis/v1/genesis.proto | 47 -- .../interchain_accounts/host/v1/host.proto | 14 - .../interchain_accounts/host/v1/query.proto | 25 - .../ibc/interchain_accounts/host/v1/tx.proto | 35 -- .../ibc/interchain_accounts/v1/account.proto | 19 - .../ibc/interchain_accounts/v1/metadata.proto | 23 - .../ibc/interchain_accounts/v1/packet.proto | 31 -- .../lightclients/localhost/v2/localhost.proto | 16 - .../solomachine/v2/solomachine.proto | 189 ------- .../solomachine/v3/solomachine.proto | 99 ---- .../tendermint/v1/tendermint.proto | 101 ---- .../ibc/lightclients/wasm/v1/genesis.proto | 20 - .../ibc/lightclients/wasm/v1/query.proto | 46 -- .../proto/ibc/lightclients/wasm/v1/tx.proto | 66 --- .../proto/ibc/lightclients/wasm/v1/wasm.proto | 43 -- .../proto/ibc/localhost/v2/localhost.proto | 16 - .../ibc/solomachine/v2/solomachine.proto | 189 ------- .../ibc/solomachine/v3/solomachine.proto | 99 ---- .../proto/ibc/tendermint/v1/tendermint.proto | 101 ---- third_party/proto/ibc/transfer/v1/authz.proto | 34 -- .../proto/ibc/transfer/v1/genesis.proto | 20 - third_party/proto/ibc/transfer/v1/query.proto | 121 ----- .../proto/ibc/transfer/v1/transfer.proto | 28 -- third_party/proto/ibc/transfer/v1/tx.proto | 79 --- .../proto/ibc/transfer/v2/packet.proto | 21 - third_party/proto/ibc/types/v1/genesis.proto | 20 - third_party/proto/ibc/wasm/v1/genesis.proto | 20 - third_party/proto/ibc/wasm/v1/query.proto | 46 -- third_party/proto/ibc/wasm/v1/tx.proto | 66 --- third_party/proto/ibc/wasm/v1/wasm.proto | 43 -- 73 files changed, 5783 deletions(-) delete mode 100644 third_party/proto/ibc/applications/fee/v1/ack.proto delete mode 100644 third_party/proto/ibc/applications/fee/v1/fee.proto delete mode 100644 third_party/proto/ibc/applications/fee/v1/genesis.proto delete mode 100644 third_party/proto/ibc/applications/fee/v1/metadata.proto delete mode 100644 third_party/proto/ibc/applications/fee/v1/query.proto delete mode 100644 third_party/proto/ibc/applications/fee/v1/tx.proto delete mode 100644 third_party/proto/ibc/applications/interchain_accounts/controller/v1/controller.proto delete mode 100644 third_party/proto/ibc/applications/interchain_accounts/controller/v1/query.proto delete mode 100644 third_party/proto/ibc/applications/interchain_accounts/controller/v1/tx.proto delete mode 100644 third_party/proto/ibc/applications/interchain_accounts/genesis/v1/genesis.proto delete mode 100644 third_party/proto/ibc/applications/interchain_accounts/host/v1/host.proto delete mode 100644 third_party/proto/ibc/applications/interchain_accounts/host/v1/query.proto delete mode 100644 third_party/proto/ibc/applications/interchain_accounts/host/v1/tx.proto delete mode 100644 third_party/proto/ibc/applications/interchain_accounts/v1/account.proto delete mode 100644 third_party/proto/ibc/applications/interchain_accounts/v1/metadata.proto delete mode 100644 third_party/proto/ibc/applications/interchain_accounts/v1/packet.proto delete mode 100644 third_party/proto/ibc/channel/v1/channel.proto delete mode 100644 third_party/proto/ibc/channel/v1/genesis.proto delete mode 100644 third_party/proto/ibc/channel/v1/query.proto delete mode 100644 third_party/proto/ibc/channel/v1/tx.proto delete mode 100644 third_party/proto/ibc/channel/v1/upgrade.proto delete mode 100644 third_party/proto/ibc/client/v1/client.proto delete mode 100644 third_party/proto/ibc/client/v1/genesis.proto delete mode 100644 third_party/proto/ibc/client/v1/query.proto delete mode 100644 third_party/proto/ibc/client/v1/tx.proto delete mode 100644 third_party/proto/ibc/commitment/v1/commitment.proto delete mode 100644 third_party/proto/ibc/connection/v1/connection.proto delete mode 100644 third_party/proto/ibc/connection/v1/genesis.proto delete mode 100644 third_party/proto/ibc/connection/v1/query.proto delete mode 100644 third_party/proto/ibc/connection/v1/tx.proto delete mode 100644 third_party/proto/ibc/core/client/v1/genesis.proto delete mode 100644 third_party/proto/ibc/core/client/v1/query.proto delete mode 100644 third_party/proto/ibc/core/client/v1/tx.proto delete mode 100644 third_party/proto/ibc/core/commitment/v1/commitment.proto delete mode 100644 third_party/proto/ibc/fee/v1/ack.proto delete mode 100644 third_party/proto/ibc/fee/v1/fee.proto delete mode 100644 third_party/proto/ibc/fee/v1/genesis.proto delete mode 100644 third_party/proto/ibc/fee/v1/metadata.proto delete mode 100644 third_party/proto/ibc/fee/v1/query.proto delete mode 100644 third_party/proto/ibc/fee/v1/tx.proto delete mode 100644 third_party/proto/ibc/interchain_accounts/controller/v1/controller.proto delete mode 100644 third_party/proto/ibc/interchain_accounts/controller/v1/query.proto delete mode 100644 third_party/proto/ibc/interchain_accounts/controller/v1/tx.proto delete mode 100644 third_party/proto/ibc/interchain_accounts/genesis/v1/genesis.proto delete mode 100644 third_party/proto/ibc/interchain_accounts/host/v1/host.proto delete mode 100644 third_party/proto/ibc/interchain_accounts/host/v1/query.proto delete mode 100644 third_party/proto/ibc/interchain_accounts/host/v1/tx.proto delete mode 100644 third_party/proto/ibc/interchain_accounts/v1/account.proto delete mode 100644 third_party/proto/ibc/interchain_accounts/v1/metadata.proto delete mode 100644 third_party/proto/ibc/interchain_accounts/v1/packet.proto delete mode 100644 third_party/proto/ibc/lightclients/localhost/v2/localhost.proto delete mode 100644 third_party/proto/ibc/lightclients/solomachine/v2/solomachine.proto delete mode 100644 third_party/proto/ibc/lightclients/solomachine/v3/solomachine.proto delete mode 100644 third_party/proto/ibc/lightclients/tendermint/v1/tendermint.proto delete mode 100644 third_party/proto/ibc/lightclients/wasm/v1/genesis.proto delete mode 100644 third_party/proto/ibc/lightclients/wasm/v1/query.proto delete mode 100644 third_party/proto/ibc/lightclients/wasm/v1/tx.proto delete mode 100644 third_party/proto/ibc/lightclients/wasm/v1/wasm.proto delete mode 100644 third_party/proto/ibc/localhost/v2/localhost.proto delete mode 100644 third_party/proto/ibc/solomachine/v2/solomachine.proto delete mode 100644 third_party/proto/ibc/solomachine/v3/solomachine.proto delete mode 100644 third_party/proto/ibc/tendermint/v1/tendermint.proto delete mode 100644 third_party/proto/ibc/transfer/v1/authz.proto delete mode 100644 third_party/proto/ibc/transfer/v1/genesis.proto delete mode 100644 third_party/proto/ibc/transfer/v1/query.proto delete mode 100644 third_party/proto/ibc/transfer/v1/transfer.proto delete mode 100644 third_party/proto/ibc/transfer/v1/tx.proto delete mode 100644 third_party/proto/ibc/transfer/v2/packet.proto delete mode 100644 third_party/proto/ibc/types/v1/genesis.proto delete mode 100644 third_party/proto/ibc/wasm/v1/genesis.proto delete mode 100644 third_party/proto/ibc/wasm/v1/query.proto delete mode 100644 third_party/proto/ibc/wasm/v1/tx.proto delete mode 100644 third_party/proto/ibc/wasm/v1/wasm.proto diff --git a/third_party/proto/ibc/applications/fee/v1/ack.proto b/third_party/proto/ibc/applications/fee/v1/ack.proto deleted file mode 100644 index 2f3746d2c..000000000 --- a/third_party/proto/ibc/applications/fee/v1/ack.proto +++ /dev/null @@ -1,15 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.fee.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"; - -// IncentivizedAcknowledgement is the acknowledgement format to be used by applications wrapped in the fee middleware -message IncentivizedAcknowledgement { - // the underlying app acknowledgement bytes - bytes app_acknowledgement = 1; - // the relayer address which submits the recv packet message - string forward_relayer_address = 2; - // success flag of the base application callback - bool underlying_app_success = 3; -} diff --git a/third_party/proto/ibc/applications/fee/v1/fee.proto b/third_party/proto/ibc/applications/fee/v1/fee.proto deleted file mode 100644 index 867e88455..000000000 --- a/third_party/proto/ibc/applications/fee/v1/fee.proto +++ /dev/null @@ -1,61 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.fee.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"; - -import "amino/amino.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "gogoproto/gogo.proto"; -import "ibc/core/channel/v1/channel.proto"; -import "cosmos/msg/v1/msg.proto"; - -// Fee defines the ICS29 receive, acknowledgement and timeout fees -message Fee { - // the packet receive fee - repeated cosmos.base.v1beta1.Coin recv_fee = 1 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (amino.encoding) = "legacy_coins" - ]; - - // the packet acknowledgement fee - repeated cosmos.base.v1beta1.Coin ack_fee = 2 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (amino.encoding) = "legacy_coins" - ]; - - // the packet timeout fee - repeated cosmos.base.v1beta1.Coin timeout_fee = 3 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (amino.encoding) = "legacy_coins" - ]; -} - -// PacketFee contains ICS29 relayer fees, refund address and optional list of permitted relayers -message PacketFee { - option (cosmos.msg.v1.signer) = "refund_address"; - - // fee encapsulates the recv, ack and timeout fees associated with an IBC packet - Fee fee = 1 [(gogoproto.nullable) = false]; - // the refund address for unspent fees - string refund_address = 2; - // optional list of relayers permitted to receive fees - repeated string relayers = 3; -} - -// PacketFees contains a list of type PacketFee -message PacketFees { - // list of packet fees - repeated PacketFee packet_fees = 1 [(gogoproto.nullable) = false]; -} - -// IdentifiedPacketFees contains a list of type PacketFee and associated PacketId -message IdentifiedPacketFees { - // unique packet identifier comprised of the channel ID, port ID and sequence - ibc.core.channel.v1.PacketId packet_id = 1 [(gogoproto.nullable) = false]; - // list of packet fees - repeated PacketFee packet_fees = 2 [(gogoproto.nullable) = false]; -} diff --git a/third_party/proto/ibc/applications/fee/v1/genesis.proto b/third_party/proto/ibc/applications/fee/v1/genesis.proto deleted file mode 100644 index e48ceb535..000000000 --- a/third_party/proto/ibc/applications/fee/v1/genesis.proto +++ /dev/null @@ -1,60 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.fee.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"; - -import "gogoproto/gogo.proto"; -import "ibc/applications/fee/v1/fee.proto"; -import "ibc/core/channel/v1/channel.proto"; - -// GenesisState defines the ICS29 fee middleware genesis state -message GenesisState { - // list of identified packet fees - repeated IdentifiedPacketFees identified_fees = 1 [(gogoproto.nullable) = false]; - // list of fee enabled channels - repeated FeeEnabledChannel fee_enabled_channels = 2 [(gogoproto.nullable) = false]; - // list of registered payees - repeated RegisteredPayee registered_payees = 3 [(gogoproto.nullable) = false]; - // list of registered counterparty payees - repeated RegisteredCounterpartyPayee registered_counterparty_payees = 4 [(gogoproto.nullable) = false]; - // list of forward relayer addresses - repeated ForwardRelayerAddress forward_relayers = 5 [(gogoproto.nullable) = false]; -} - -// FeeEnabledChannel contains the PortID & ChannelID for a fee enabled channel -message FeeEnabledChannel { - // unique port identifier - string port_id = 1; - // unique channel identifier - string channel_id = 2; -} - -// RegisteredPayee contains the relayer address and payee address for a specific channel -message RegisteredPayee { - // unique channel identifier - string channel_id = 1; - // the relayer address - string relayer = 2; - // the payee address - string payee = 3; -} - -// RegisteredCounterpartyPayee contains the relayer address and counterparty payee address for a specific channel (used -// for recv fee distribution) -message RegisteredCounterpartyPayee { - // unique channel identifier - string channel_id = 1; - // the relayer address - string relayer = 2; - // the counterparty payee address - string counterparty_payee = 3; -} - -// ForwardRelayerAddress contains the forward relayer address and PacketId used for async acknowledgements -message ForwardRelayerAddress { - // the forward relayer address - string address = 1; - // unique packet identifer comprised of the channel ID, port ID and sequence - ibc.core.channel.v1.PacketId packet_id = 2 [(gogoproto.nullable) = false]; -} diff --git a/third_party/proto/ibc/applications/fee/v1/metadata.proto b/third_party/proto/ibc/applications/fee/v1/metadata.proto deleted file mode 100644 index 1e82e7c25..000000000 --- a/third_party/proto/ibc/applications/fee/v1/metadata.proto +++ /dev/null @@ -1,14 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.fee.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"; - -// Metadata defines the ICS29 channel specific metadata encoded into the channel version bytestring -// See ICS004: https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#Versioning -message Metadata { - // fee_version defines the ICS29 fee version - string fee_version = 1; - // app_version defines the underlying application version, which may or may not be a JSON encoded bytestring - string app_version = 2; -} diff --git a/third_party/proto/ibc/applications/fee/v1/query.proto b/third_party/proto/ibc/applications/fee/v1/query.proto deleted file mode 100644 index 726370ee0..000000000 --- a/third_party/proto/ibc/applications/fee/v1/query.proto +++ /dev/null @@ -1,218 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.fee.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"; - -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "cosmos/base/query/v1beta1/pagination.proto"; -import "ibc/applications/fee/v1/fee.proto"; -import "ibc/applications/fee/v1/genesis.proto"; -import "ibc/core/channel/v1/channel.proto"; - -// Query defines the ICS29 gRPC querier service. -service Query { - // IncentivizedPackets returns all incentivized packets and their associated fees - rpc IncentivizedPackets(QueryIncentivizedPacketsRequest) returns (QueryIncentivizedPacketsResponse) { - option (google.api.http).get = "/ibc/apps/fee/v1/incentivized_packets"; - } - - // IncentivizedPacket returns all packet fees for a packet given its identifier - rpc IncentivizedPacket(QueryIncentivizedPacketRequest) returns (QueryIncentivizedPacketResponse) { - option (google.api.http).get = - "/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/sequences/" - "{packet_id.sequence}/incentivized_packet"; - } - - // Gets all incentivized packets for a specific channel - rpc IncentivizedPacketsForChannel(QueryIncentivizedPacketsForChannelRequest) - returns (QueryIncentivizedPacketsForChannelResponse) { - option (google.api.http).get = "/ibc/apps/fee/v1/channels/{channel_id}/ports/{port_id}/incentivized_packets"; - } - - // TotalRecvFees returns the total receive fees for a packet given its identifier - rpc TotalRecvFees(QueryTotalRecvFeesRequest) returns (QueryTotalRecvFeesResponse) { - option (google.api.http).get = "/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/" - "sequences/{packet_id.sequence}/total_recv_fees"; - } - - // TotalAckFees returns the total acknowledgement fees for a packet given its identifier - rpc TotalAckFees(QueryTotalAckFeesRequest) returns (QueryTotalAckFeesResponse) { - option (google.api.http).get = "/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/" - "sequences/{packet_id.sequence}/total_ack_fees"; - } - - // TotalTimeoutFees returns the total timeout fees for a packet given its identifier - rpc TotalTimeoutFees(QueryTotalTimeoutFeesRequest) returns (QueryTotalTimeoutFeesResponse) { - option (google.api.http).get = "/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/" - "sequences/{packet_id.sequence}/total_timeout_fees"; - } - - // Payee returns the registered payee address for a specific channel given the relayer address - rpc Payee(QueryPayeeRequest) returns (QueryPayeeResponse) { - option (google.api.http).get = "/ibc/apps/fee/v1/channels/{channel_id}/relayers/{relayer}/payee"; - } - - // CounterpartyPayee returns the registered counterparty payee for forward relaying - rpc CounterpartyPayee(QueryCounterpartyPayeeRequest) returns (QueryCounterpartyPayeeResponse) { - option (google.api.http).get = "/ibc/apps/fee/v1/channels/{channel_id}/relayers/{relayer}/counterparty_payee"; - } - - // FeeEnabledChannels returns a list of all fee enabled channels - rpc FeeEnabledChannels(QueryFeeEnabledChannelsRequest) returns (QueryFeeEnabledChannelsResponse) { - option (google.api.http).get = "/ibc/apps/fee/v1/fee_enabled"; - } - - // FeeEnabledChannel returns true if the provided port and channel identifiers belong to a fee enabled channel - rpc FeeEnabledChannel(QueryFeeEnabledChannelRequest) returns (QueryFeeEnabledChannelResponse) { - option (google.api.http).get = "/ibc/apps/fee/v1/channels/{channel_id}/ports/{port_id}/fee_enabled"; - } -} - -// QueryIncentivizedPacketsRequest defines the request type for the IncentivizedPackets rpc -message QueryIncentivizedPacketsRequest { - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 1; - // block height at which to query - uint64 query_height = 2; -} - -// QueryIncentivizedPacketsResponse defines the response type for the IncentivizedPackets rpc -message QueryIncentivizedPacketsResponse { - // list of identified fees for incentivized packets - repeated ibc.applications.fee.v1.IdentifiedPacketFees incentivized_packets = 1 [(gogoproto.nullable) = false]; - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryIncentivizedPacketRequest defines the request type for the IncentivizedPacket rpc -message QueryIncentivizedPacketRequest { - // unique packet identifier comprised of channel ID, port ID and sequence - ibc.core.channel.v1.PacketId packet_id = 1 [(gogoproto.nullable) = false]; - // block height at which to query - uint64 query_height = 2; -} - -// QueryIncentivizedPacketsResponse defines the response type for the IncentivizedPacket rpc -message QueryIncentivizedPacketResponse { - // the identified fees for the incentivized packet - ibc.applications.fee.v1.IdentifiedPacketFees incentivized_packet = 1 [(gogoproto.nullable) = false]; -} - -// QueryIncentivizedPacketsForChannelRequest defines the request type for querying for all incentivized packets -// for a specific channel -message QueryIncentivizedPacketsForChannelRequest { - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 1; - string port_id = 2; - string channel_id = 3; - // Height to query at - uint64 query_height = 4; -} - -// QueryIncentivizedPacketsResponse defines the response type for the incentivized packets RPC -message QueryIncentivizedPacketsForChannelResponse { - // Map of all incentivized_packets - repeated ibc.applications.fee.v1.IdentifiedPacketFees incentivized_packets = 1; - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryTotalRecvFeesRequest defines the request type for the TotalRecvFees rpc -message QueryTotalRecvFeesRequest { - // the packet identifier for the associated fees - ibc.core.channel.v1.PacketId packet_id = 1 [(gogoproto.nullable) = false]; -} - -// QueryTotalRecvFeesResponse defines the response type for the TotalRecvFees rpc -message QueryTotalRecvFeesResponse { - // the total packet receive fees - repeated cosmos.base.v1beta1.Coin recv_fees = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; -} - -// QueryTotalAckFeesRequest defines the request type for the TotalAckFees rpc -message QueryTotalAckFeesRequest { - // the packet identifier for the associated fees - ibc.core.channel.v1.PacketId packet_id = 1 [(gogoproto.nullable) = false]; -} - -// QueryTotalAckFeesResponse defines the response type for the TotalAckFees rpc -message QueryTotalAckFeesResponse { - // the total packet acknowledgement fees - repeated cosmos.base.v1beta1.Coin ack_fees = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; -} - -// QueryTotalTimeoutFeesRequest defines the request type for the TotalTimeoutFees rpc -message QueryTotalTimeoutFeesRequest { - // the packet identifier for the associated fees - ibc.core.channel.v1.PacketId packet_id = 1 [(gogoproto.nullable) = false]; -} - -// QueryTotalTimeoutFeesResponse defines the response type for the TotalTimeoutFees rpc -message QueryTotalTimeoutFeesResponse { - // the total packet timeout fees - repeated cosmos.base.v1beta1.Coin timeout_fees = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; -} - -// QueryPayeeRequest defines the request type for the Payee rpc -message QueryPayeeRequest { - // unique channel identifier - string channel_id = 1; - // the relayer address to which the distribution address is registered - string relayer = 2; -} - -// QueryPayeeResponse defines the response type for the Payee rpc -message QueryPayeeResponse { - // the payee address to which packet fees are paid out - string payee_address = 1; -} - -// QueryCounterpartyPayeeRequest defines the request type for the CounterpartyPayee rpc -message QueryCounterpartyPayeeRequest { - // unique channel identifier - string channel_id = 1; - // the relayer address to which the counterparty is registered - string relayer = 2; -} - -// QueryCounterpartyPayeeResponse defines the response type for the CounterpartyPayee rpc -message QueryCounterpartyPayeeResponse { - // the counterparty payee address used to compensate forward relaying - string counterparty_payee = 1; -} - -// QueryFeeEnabledChannelsRequest defines the request type for the FeeEnabledChannels rpc -message QueryFeeEnabledChannelsRequest { - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 1; - // block height at which to query - uint64 query_height = 2; -} - -// QueryFeeEnabledChannelsResponse defines the response type for the FeeEnabledChannels rpc -message QueryFeeEnabledChannelsResponse { - // list of fee enabled channels - repeated ibc.applications.fee.v1.FeeEnabledChannel fee_enabled_channels = 1 [(gogoproto.nullable) = false]; - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryFeeEnabledChannelRequest defines the request type for the FeeEnabledChannel rpc -message QueryFeeEnabledChannelRequest { - // unique port identifier - string port_id = 1; - // unique channel identifier - string channel_id = 2; -} - -// QueryFeeEnabledChannelResponse defines the response type for the FeeEnabledChannel rpc -message QueryFeeEnabledChannelResponse { - // boolean flag representing the fee enabled channel status - bool fee_enabled = 1; -} diff --git a/third_party/proto/ibc/applications/fee/v1/tx.proto b/third_party/proto/ibc/applications/fee/v1/tx.proto deleted file mode 100644 index e59dddfd1..000000000 --- a/third_party/proto/ibc/applications/fee/v1/tx.proto +++ /dev/null @@ -1,122 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.fee.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"; - -import "amino/amino.proto"; -import "gogoproto/gogo.proto"; -import "ibc/applications/fee/v1/fee.proto"; -import "ibc/core/channel/v1/channel.proto"; -import "cosmos/msg/v1/msg.proto"; - -// Msg defines the ICS29 Msg service. -service Msg { - option (cosmos.msg.v1.service) = true; - - // RegisterPayee defines a rpc handler method for MsgRegisterPayee - // RegisterPayee is called by the relayer on each channelEnd and allows them to set an optional - // payee to which reverse and timeout relayer packet fees will be paid out. The payee should be registered on - // the source chain from which packets originate as this is where fee distribution takes place. This function may be - // called more than once by a relayer, in which case, the latest payee is always used. - rpc RegisterPayee(MsgRegisterPayee) returns (MsgRegisterPayeeResponse); - - // RegisterCounterpartyPayee defines a rpc handler method for MsgRegisterCounterpartyPayee - // RegisterCounterpartyPayee is called by the relayer on each channelEnd and allows them to specify the counterparty - // payee address before relaying. This ensures they will be properly compensated for forward relaying since - // the destination chain must include the registered counterparty payee address in the acknowledgement. This function - // may be called more than once by a relayer, in which case, the latest counterparty payee address is always used. - rpc RegisterCounterpartyPayee(MsgRegisterCounterpartyPayee) returns (MsgRegisterCounterpartyPayeeResponse); - - // PayPacketFee defines a rpc handler method for MsgPayPacketFee - // PayPacketFee is an open callback that may be called by any module/user that wishes to escrow funds in order to - // incentivize the relaying of the packet at the next sequence - // NOTE: This method is intended to be used within a multi msg transaction, where the subsequent msg that follows - // initiates the lifecycle of the incentivized packet - rpc PayPacketFee(MsgPayPacketFee) returns (MsgPayPacketFeeResponse); - - // PayPacketFeeAsync defines a rpc handler method for MsgPayPacketFeeAsync - // PayPacketFeeAsync is an open callback that may be called by any module/user that wishes to escrow funds in order to - // incentivize the relaying of a known packet (i.e. at a particular sequence) - rpc PayPacketFeeAsync(MsgPayPacketFeeAsync) returns (MsgPayPacketFeeAsyncResponse); -} - -// MsgRegisterPayee defines the request type for the RegisterPayee rpc -message MsgRegisterPayee { - option (amino.name) = "cosmos-sdk/MsgRegisterPayee"; - option (cosmos.msg.v1.signer) = "relayer"; - - option (gogoproto.goproto_getters) = false; - - // unique port identifier - string port_id = 1; - // unique channel identifier - string channel_id = 2; - // the relayer address - string relayer = 3; - // the payee address - string payee = 4; -} - -// MsgRegisterPayeeResponse defines the response type for the RegisterPayee rpc -message MsgRegisterPayeeResponse {} - -// MsgRegisterCounterpartyPayee defines the request type for the RegisterCounterpartyPayee rpc -message MsgRegisterCounterpartyPayee { - option (amino.name) = "cosmos-sdk/MsgRegisterCounterpartyPayee"; - option (cosmos.msg.v1.signer) = "relayer"; - - option (gogoproto.goproto_getters) = false; - - // unique port identifier - string port_id = 1; - // unique channel identifier - string channel_id = 2; - // the relayer address - string relayer = 3; - // the counterparty payee address - string counterparty_payee = 4; -} - -// MsgRegisterCounterpartyPayeeResponse defines the response type for the RegisterCounterpartyPayee rpc -message MsgRegisterCounterpartyPayeeResponse {} - -// MsgPayPacketFee defines the request type for the PayPacketFee rpc -// This Msg can be used to pay for a packet at the next sequence send & should be combined with the Msg that will be -// paid for -message MsgPayPacketFee { - option (amino.name) = "cosmos-sdk/MsgPayPacketFee"; - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - // fee encapsulates the recv, ack and timeout fees associated with an IBC packet - ibc.applications.fee.v1.Fee fee = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; - // the source port unique identifier - string source_port_id = 2; - // the source channel unique identifer - string source_channel_id = 3; - // account address to refund fee if necessary - string signer = 4; - // optional list of relayers permitted to the receive packet fees - repeated string relayers = 5; -} - -// MsgPayPacketFeeResponse defines the response type for the PayPacketFee rpc -message MsgPayPacketFeeResponse {} - -// MsgPayPacketFeeAsync defines the request type for the PayPacketFeeAsync rpc -// This Msg can be used to pay for a packet at a specified sequence (instead of the next sequence send) -message MsgPayPacketFeeAsync { - option (amino.name) = "cosmos-sdk/MsgPayPacketFeeAsync"; - option (cosmos.msg.v1.signer) = "packet_fee"; - option (gogoproto.goproto_getters) = false; - - // unique packet identifier comprised of the channel ID, port ID and sequence - ibc.core.channel.v1.PacketId packet_id = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; - // the packet fee associated with a particular IBC packet - PacketFee packet_fee = 2 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; -} - -// MsgPayPacketFeeAsyncResponse defines the response type for the PayPacketFeeAsync rpc -message MsgPayPacketFeeAsyncResponse {} diff --git a/third_party/proto/ibc/applications/interchain_accounts/controller/v1/controller.proto b/third_party/proto/ibc/applications/interchain_accounts/controller/v1/controller.proto deleted file mode 100644 index 2e6bbe1a1..000000000 --- a/third_party/proto/ibc/applications/interchain_accounts/controller/v1/controller.proto +++ /dev/null @@ -1,12 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.interchain_accounts.controller.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types"; - -// Params defines the set of on-chain interchain accounts parameters. -// The following parameters may be used to disable the controller submodule. -message Params { - // controller_enabled enables or disables the controller submodule. - bool controller_enabled = 1; -} diff --git a/third_party/proto/ibc/applications/interchain_accounts/controller/v1/query.proto b/third_party/proto/ibc/applications/interchain_accounts/controller/v1/query.proto deleted file mode 100644 index 31885fcb2..000000000 --- a/third_party/proto/ibc/applications/interchain_accounts/controller/v1/query.proto +++ /dev/null @@ -1,42 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.interchain_accounts.controller.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types"; - -import "ibc/applications/interchain_accounts/controller/v1/controller.proto"; -import "google/api/annotations.proto"; - -// Query provides defines the gRPC querier service. -service Query { - // InterchainAccount returns the interchain account address for a given owner address on a given connection - rpc InterchainAccount(QueryInterchainAccountRequest) returns (QueryInterchainAccountResponse) { - option (google.api.http).get = - "/ibc/apps/interchain_accounts/controller/v1/owners/{owner}/connections/{connection_id}"; - } - - // Params queries all parameters of the ICA controller submodule. - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/ibc/apps/interchain_accounts/controller/v1/params"; - } -} - -// QueryInterchainAccountRequest is the request type for the Query/InterchainAccount RPC method. -message QueryInterchainAccountRequest { - string owner = 1; - string connection_id = 2; -} - -// QueryInterchainAccountResponse the response type for the Query/InterchainAccount RPC method. -message QueryInterchainAccountResponse { - string address = 1; -} - -// QueryParamsRequest is the request type for the Query/Params RPC method. -message QueryParamsRequest {} - -// QueryParamsResponse is the response type for the Query/Params RPC method. -message QueryParamsResponse { - // params defines the parameters of the module. - Params params = 1; -} diff --git a/third_party/proto/ibc/applications/interchain_accounts/controller/v1/tx.proto b/third_party/proto/ibc/applications/interchain_accounts/controller/v1/tx.proto deleted file mode 100644 index ec5c2e62e..000000000 --- a/third_party/proto/ibc/applications/interchain_accounts/controller/v1/tx.proto +++ /dev/null @@ -1,82 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.interchain_accounts.controller.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types"; - -import "gogoproto/gogo.proto"; -import "ibc/applications/interchain_accounts/v1/packet.proto"; -import "ibc/applications/interchain_accounts/controller/v1/controller.proto"; -import "cosmos/msg/v1/msg.proto"; -import "ibc/core/channel/v1/channel.proto"; - -// Msg defines the 27-interchain-accounts/controller Msg service. -service Msg { - option (cosmos.msg.v1.service) = true; - - // RegisterInterchainAccount defines a rpc handler for MsgRegisterInterchainAccount. - rpc RegisterInterchainAccount(MsgRegisterInterchainAccount) returns (MsgRegisterInterchainAccountResponse); - // SendTx defines a rpc handler for MsgSendTx. - rpc SendTx(MsgSendTx) returns (MsgSendTxResponse); - // UpdateParams defines a rpc handler for MsgUpdateParams. - rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); -} - -// MsgRegisterInterchainAccount defines the payload for Msg/RegisterAccount -message MsgRegisterInterchainAccount { - option (cosmos.msg.v1.signer) = "owner"; - - option (gogoproto.goproto_getters) = false; - - string owner = 1; - string connection_id = 2; - string version = 3; - ibc.core.channel.v1.Order ordering = 4; -} - -// MsgRegisterInterchainAccountResponse defines the response for Msg/RegisterAccount -message MsgRegisterInterchainAccountResponse { - option (gogoproto.goproto_getters) = false; - - string channel_id = 1; - string port_id = 2; -} - -// MsgSendTx defines the payload for Msg/SendTx -message MsgSendTx { - option (cosmos.msg.v1.signer) = "owner"; - - option (gogoproto.goproto_getters) = false; - - string owner = 1; - string connection_id = 2; - ibc.applications.interchain_accounts.v1.InterchainAccountPacketData packet_data = 3 [(gogoproto.nullable) = false]; - // Relative timeout timestamp provided will be added to the current block time during transaction execution. - // The timeout timestamp must be non-zero. - uint64 relative_timeout = 4; -} - -// MsgSendTxResponse defines the response for MsgSendTx -message MsgSendTxResponse { - option (gogoproto.goproto_getters) = false; - - uint64 sequence = 1; -} - -// MsgUpdateParams defines the payload for Msg/UpdateParams -message MsgUpdateParams { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - // signer address - string signer = 1; - - // params defines the 27-interchain-accounts/controller parameters to update. - // - // NOTE: All parameters must be supplied. - Params params = 2 [(gogoproto.nullable) = false]; -} - -// MsgUpdateParamsResponse defines the response for Msg/UpdateParams -message MsgUpdateParamsResponse {} \ No newline at end of file diff --git a/third_party/proto/ibc/applications/interchain_accounts/genesis/v1/genesis.proto b/third_party/proto/ibc/applications/interchain_accounts/genesis/v1/genesis.proto deleted file mode 100644 index 4393e5b0b..000000000 --- a/third_party/proto/ibc/applications/interchain_accounts/genesis/v1/genesis.proto +++ /dev/null @@ -1,47 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.interchain_accounts.genesis.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/genesis/types"; - -import "gogoproto/gogo.proto"; -import "ibc/applications/interchain_accounts/controller/v1/controller.proto"; -import "ibc/applications/interchain_accounts/host/v1/host.proto"; - -// GenesisState defines the interchain accounts genesis state -message GenesisState { - ControllerGenesisState controller_genesis_state = 1 [(gogoproto.nullable) = false]; - HostGenesisState host_genesis_state = 2 [(gogoproto.nullable) = false]; -} - -// ControllerGenesisState defines the interchain accounts controller genesis state -message ControllerGenesisState { - repeated ActiveChannel active_channels = 1 [(gogoproto.nullable) = false]; - repeated RegisteredInterchainAccount interchain_accounts = 2 [(gogoproto.nullable) = false]; - repeated string ports = 3; - ibc.applications.interchain_accounts.controller.v1.Params params = 4 [(gogoproto.nullable) = false]; -} - -// HostGenesisState defines the interchain accounts host genesis state -message HostGenesisState { - repeated ActiveChannel active_channels = 1 [(gogoproto.nullable) = false]; - repeated RegisteredInterchainAccount interchain_accounts = 2 [(gogoproto.nullable) = false]; - string port = 3; - ibc.applications.interchain_accounts.host.v1.Params params = 4 [(gogoproto.nullable) = false]; -} - -// ActiveChannel contains a connection ID, port ID and associated active channel ID, as well as a boolean flag to -// indicate if the channel is middleware enabled -message ActiveChannel { - string connection_id = 1; - string port_id = 2; - string channel_id = 3; - bool is_middleware_enabled = 4; -} - -// RegisteredInterchainAccount contains a connection ID, port ID and associated interchain account address -message RegisteredInterchainAccount { - string connection_id = 1; - string port_id = 2; - string account_address = 3; -} \ No newline at end of file diff --git a/third_party/proto/ibc/applications/interchain_accounts/host/v1/host.proto b/third_party/proto/ibc/applications/interchain_accounts/host/v1/host.proto deleted file mode 100644 index f03685711..000000000 --- a/third_party/proto/ibc/applications/interchain_accounts/host/v1/host.proto +++ /dev/null @@ -1,14 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.interchain_accounts.host.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/host/types"; - -// Params defines the set of on-chain interchain accounts parameters. -// The following parameters may be used to disable the host submodule. -message Params { - // host_enabled enables or disables the host submodule. - bool host_enabled = 1; - // allow_messages defines a list of sdk message typeURLs allowed to be executed on a host chain. - repeated string allow_messages = 2; -} diff --git a/third_party/proto/ibc/applications/interchain_accounts/host/v1/query.proto b/third_party/proto/ibc/applications/interchain_accounts/host/v1/query.proto deleted file mode 100644 index 6f206a14c..000000000 --- a/third_party/proto/ibc/applications/interchain_accounts/host/v1/query.proto +++ /dev/null @@ -1,25 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.interchain_accounts.host.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/host/types"; - -import "google/api/annotations.proto"; -import "ibc/applications/interchain_accounts/host/v1/host.proto"; - -// Query provides defines the gRPC querier service. -service Query { - // Params queries all parameters of the ICA host submodule. - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/ibc/apps/interchain_accounts/host/v1/params"; - } -} - -// QueryParamsRequest is the request type for the Query/Params RPC method. -message QueryParamsRequest {} - -// QueryParamsResponse is the response type for the Query/Params RPC method. -message QueryParamsResponse { - // params defines the parameters of the module. - Params params = 1; -} diff --git a/third_party/proto/ibc/applications/interchain_accounts/host/v1/tx.proto b/third_party/proto/ibc/applications/interchain_accounts/host/v1/tx.proto deleted file mode 100644 index 5a8073bc9..000000000 --- a/third_party/proto/ibc/applications/interchain_accounts/host/v1/tx.proto +++ /dev/null @@ -1,35 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.interchain_accounts.host.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/host/types"; - -import "gogoproto/gogo.proto"; -import "cosmos/msg/v1/msg.proto"; -import "ibc/applications/interchain_accounts/host/v1/host.proto"; - -// Msg defines the 27-interchain-accounts/host Msg service. -service Msg { - option (cosmos.msg.v1.service) = true; - - // UpdateParams defines a rpc handler for MsgUpdateParams. - rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); -} - -// MsgUpdateParams defines the payload for Msg/UpdateParams -message MsgUpdateParams { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - // signer address - string signer = 1; - - // params defines the 27-interchain-accounts/host parameters to update. - // - // NOTE: All parameters must be supplied. - Params params = 2 [(gogoproto.nullable) = false]; -} - -// MsgUpdateParamsResponse defines the response for Msg/UpdateParams -message MsgUpdateParamsResponse {} diff --git a/third_party/proto/ibc/applications/interchain_accounts/v1/account.proto b/third_party/proto/ibc/applications/interchain_accounts/v1/account.proto deleted file mode 100644 index 4a6947c1c..000000000 --- a/third_party/proto/ibc/applications/interchain_accounts/v1/account.proto +++ /dev/null @@ -1,19 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.interchain_accounts.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types"; - -import "cosmos_proto/cosmos.proto"; -import "gogoproto/gogo.proto"; -import "cosmos/auth/v1beta1/auth.proto"; - -// An InterchainAccount is defined as a BaseAccount & the address of the account owner on the controller chain -message InterchainAccount { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - option (cosmos_proto.implements_interface) = "ibc.applications.interchain_accounts.v1.InterchainAccountI"; - - cosmos.auth.v1beta1.BaseAccount base_account = 1 [(gogoproto.embed) = true]; - string account_owner = 2; -} diff --git a/third_party/proto/ibc/applications/interchain_accounts/v1/metadata.proto b/third_party/proto/ibc/applications/interchain_accounts/v1/metadata.proto deleted file mode 100644 index df72b41eb..000000000 --- a/third_party/proto/ibc/applications/interchain_accounts/v1/metadata.proto +++ /dev/null @@ -1,23 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.interchain_accounts.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types"; - -// Metadata defines a set of protocol specific data encoded into the ICS27 channel version bytestring -// See ICS004: https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#Versioning -message Metadata { - // version defines the ICS27 protocol version - string version = 1; - // controller_connection_id is the connection identifier associated with the controller chain - string controller_connection_id = 2; - // host_connection_id is the connection identifier associated with the host chain - string host_connection_id = 3; - // address defines the interchain account address to be fulfilled upon the OnChanOpenTry handshake step - // NOTE: the address field is empty on the OnChanOpenInit handshake step - string address = 4; - // encoding defines the supported codec format - string encoding = 5; - // tx_type defines the type of transactions the interchain account can execute - string tx_type = 6; -} diff --git a/third_party/proto/ibc/applications/interchain_accounts/v1/packet.proto b/third_party/proto/ibc/applications/interchain_accounts/v1/packet.proto deleted file mode 100644 index f75a1463e..000000000 --- a/third_party/proto/ibc/applications/interchain_accounts/v1/packet.proto +++ /dev/null @@ -1,31 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.interchain_accounts.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types"; - -import "google/protobuf/any.proto"; -import "gogoproto/gogo.proto"; - -// Type defines a classification of message issued from a controller chain to its associated interchain accounts -// host -enum Type { - option (gogoproto.goproto_enum_prefix) = false; - - // Default zero value enumeration - TYPE_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNSPECIFIED"]; - // Execute a transaction on an interchain accounts host chain - TYPE_EXECUTE_TX = 1 [(gogoproto.enumvalue_customname) = "EXECUTE_TX"]; -} - -// InterchainAccountPacketData is comprised of a raw transaction, type of transaction and optional memo field. -message InterchainAccountPacketData { - Type type = 1; - bytes data = 2; - string memo = 3; -} - -// CosmosTx contains a list of sdk.Msg's. It should be used when sending transactions to an SDK host chain. -message CosmosTx { - repeated google.protobuf.Any messages = 1; -} diff --git a/third_party/proto/ibc/channel/v1/channel.proto b/third_party/proto/ibc/channel/v1/channel.proto deleted file mode 100644 index 05a18fefb..000000000 --- a/third_party/proto/ibc/channel/v1/channel.proto +++ /dev/null @@ -1,187 +0,0 @@ -syntax = "proto3"; - -package ibc.core.channel.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"; - -import "gogoproto/gogo.proto"; -import "ibc/core/client/v1/client.proto"; - -// Channel defines pipeline for exactly-once packet delivery between specific -// modules on separate blockchains, which has at least one end capable of -// sending packets and one end capable of receiving packets. -message Channel { - option (gogoproto.goproto_getters) = false; - - // current state of the channel end - State state = 1; - // whether the channel is ordered or unordered - Order ordering = 2; - // counterparty channel end - Counterparty counterparty = 3 [(gogoproto.nullable) = false]; - // list of connection identifiers, in order, along which packets sent on - // this channel will travel - repeated string connection_hops = 4; - // opaque channel version, which is agreed upon during the handshake - string version = 5; - // upgrade sequence indicates the latest upgrade attempt performed by this channel - // the value of 0 indicates the channel has never been upgraded - uint64 upgrade_sequence = 6; -} - -// IdentifiedChannel defines a channel with additional port and channel -// identifier fields. -message IdentifiedChannel { - option (gogoproto.goproto_getters) = false; - - // current state of the channel end - State state = 1; - // whether the channel is ordered or unordered - Order ordering = 2; - // counterparty channel end - Counterparty counterparty = 3 [(gogoproto.nullable) = false]; - // list of connection identifiers, in order, along which packets sent on - // this channel will travel - repeated string connection_hops = 4; - // opaque channel version, which is agreed upon during the handshake - string version = 5; - // port identifier - string port_id = 6; - // channel identifier - string channel_id = 7; - // upgrade sequence indicates the latest upgrade attempt performed by this channel - // the value of 0 indicates the channel has never been upgraded - uint64 upgrade_sequence = 8; -} - -// State defines if a channel is in one of the following states: -// CLOSED, INIT, TRYOPEN, OPEN, FLUSHING, FLUSHCOMPLETE or UNINITIALIZED. -enum State { - option (gogoproto.goproto_enum_prefix) = false; - - // Default State - STATE_UNINITIALIZED_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNINITIALIZED"]; - // A channel has just started the opening handshake. - STATE_INIT = 1 [(gogoproto.enumvalue_customname) = "INIT"]; - // A channel has acknowledged the handshake step on the counterparty chain. - STATE_TRYOPEN = 2 [(gogoproto.enumvalue_customname) = "TRYOPEN"]; - // A channel has completed the handshake. Open channels are - // ready to send and receive packets. - STATE_OPEN = 3 [(gogoproto.enumvalue_customname) = "OPEN"]; - // A channel has been closed and can no longer be used to send or receive - // packets. - STATE_CLOSED = 4 [(gogoproto.enumvalue_customname) = "CLOSED"]; - // A channel has just accepted the upgrade handshake attempt and is flushing in-flight packets. - STATE_FLUSHING = 5 [(gogoproto.enumvalue_customname) = "FLUSHING"]; - // A channel has just completed flushing any in-flight packets. - STATE_FLUSHCOMPLETE = 6 [(gogoproto.enumvalue_customname) = "FLUSHCOMPLETE"]; -} - -// Order defines if a channel is ORDERED or UNORDERED -enum Order { - option (gogoproto.goproto_enum_prefix) = false; - - // zero-value for channel ordering - ORDER_NONE_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "NONE"]; - // packets can be delivered in any order, which may differ from the order in - // which they were sent. - ORDER_UNORDERED = 1 [(gogoproto.enumvalue_customname) = "UNORDERED"]; - // packets are delivered exactly in the order which they were sent - ORDER_ORDERED = 2 [(gogoproto.enumvalue_customname) = "ORDERED"]; -} - -// Counterparty defines a channel end counterparty -message Counterparty { - option (gogoproto.goproto_getters) = false; - - // port on the counterparty chain which owns the other end of the channel. - string port_id = 1; - // channel end on the counterparty chain - string channel_id = 2; -} - -// Packet defines a type that carries data across different chains through IBC -message Packet { - option (gogoproto.goproto_getters) = false; - - // number corresponds to the order of sends and receives, where a Packet - // with an earlier sequence number must be sent and received before a Packet - // with a later sequence number. - uint64 sequence = 1; - // identifies the port on the sending chain. - string source_port = 2; - // identifies the channel end on the sending chain. - string source_channel = 3; - // identifies the port on the receiving chain. - string destination_port = 4; - // identifies the channel end on the receiving chain. - string destination_channel = 5; - // actual opaque bytes transferred directly to the application module - bytes data = 6; - // block height after which the packet times out - ibc.core.client.v1.Height timeout_height = 7 [(gogoproto.nullable) = false]; - // block timestamp (in nanoseconds) after which the packet times out - uint64 timeout_timestamp = 8; -} - -// PacketState defines the generic type necessary to retrieve and store -// packet commitments, acknowledgements, and receipts. -// Caller is responsible for knowing the context necessary to interpret this -// state as a commitment, acknowledgement, or a receipt. -message PacketState { - option (gogoproto.goproto_getters) = false; - - // channel port identifier. - string port_id = 1; - // channel unique identifier. - string channel_id = 2; - // packet sequence. - uint64 sequence = 3; - // embedded data that represents packet state. - bytes data = 4; -} - -// PacketId is an identifer for a unique Packet -// Source chains refer to packets by source port/channel -// Destination chains refer to packets by destination port/channel -message PacketId { - option (gogoproto.goproto_getters) = false; - - // channel port identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; - // packet sequence - uint64 sequence = 3; -} - -// Acknowledgement is the recommended acknowledgement format to be used by -// app-specific protocols. -// NOTE: The field numbers 21 and 22 were explicitly chosen to avoid accidental -// conflicts with other protobuf message formats used for acknowledgements. -// The first byte of any message with this format will be the non-ASCII values -// `0xaa` (result) or `0xb2` (error). Implemented as defined by ICS: -// https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#acknowledgement-envelope -message Acknowledgement { - // response contains either a result or an error and must be non-empty - oneof response { - bytes result = 21; - string error = 22; - } -} - -// Timeout defines an execution deadline structure for 04-channel handlers. -// This includes packet lifecycle handlers as well as the upgrade handshake handlers. -// A valid Timeout contains either one or both of a timestamp and block height (sequence). -message Timeout { - // block height after which the packet or upgrade times out - ibc.core.client.v1.Height height = 1 [(gogoproto.nullable) = false]; - // block timestamp (in nanoseconds) after which the packet or upgrade times out - uint64 timestamp = 2; -} - -// Params defines the set of IBC channel parameters. -message Params { - // the relative timeout after which channel upgrades will time out. - Timeout upgrade_timeout = 1 [(gogoproto.nullable) = false]; -} diff --git a/third_party/proto/ibc/channel/v1/genesis.proto b/third_party/proto/ibc/channel/v1/genesis.proto deleted file mode 100644 index 665b2b156..000000000 --- a/third_party/proto/ibc/channel/v1/genesis.proto +++ /dev/null @@ -1,30 +0,0 @@ -syntax = "proto3"; - -package ibc.core.channel.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"; - -import "gogoproto/gogo.proto"; -import "ibc/core/channel/v1/channel.proto"; - -// GenesisState defines the ibc channel submodule's genesis state. -message GenesisState { - repeated IdentifiedChannel channels = 1 [(gogoproto.casttype) = "IdentifiedChannel", (gogoproto.nullable) = false]; - repeated PacketState acknowledgements = 2 [(gogoproto.nullable) = false]; - repeated PacketState commitments = 3 [(gogoproto.nullable) = false]; - repeated PacketState receipts = 4 [(gogoproto.nullable) = false]; - repeated PacketSequence send_sequences = 5 [(gogoproto.nullable) = false]; - repeated PacketSequence recv_sequences = 6 [(gogoproto.nullable) = false]; - repeated PacketSequence ack_sequences = 7 [(gogoproto.nullable) = false]; - // the sequence for the next generated channel identifier - uint64 next_channel_sequence = 8; - Params params = 9 [(gogoproto.nullable) = false]; -} - -// PacketSequence defines the genesis type necessary to retrieve and store -// next send and receive sequences. -message PacketSequence { - string port_id = 1; - string channel_id = 2; - uint64 sequence = 3; -} diff --git a/third_party/proto/ibc/channel/v1/query.proto b/third_party/proto/ibc/channel/v1/query.proto deleted file mode 100644 index f89d21273..000000000 --- a/third_party/proto/ibc/channel/v1/query.proto +++ /dev/null @@ -1,459 +0,0 @@ -syntax = "proto3"; - -package ibc.core.channel.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"; - -import "ibc/core/client/v1/client.proto"; -import "cosmos/base/query/v1beta1/pagination.proto"; -import "ibc/core/channel/v1/channel.proto"; -import "google/api/annotations.proto"; -import "google/protobuf/any.proto"; -import "gogoproto/gogo.proto"; -import "ibc/core/channel/v1/upgrade.proto"; - -// Query provides defines the gRPC querier service -service Query { - // Channel queries an IBC Channel. - rpc Channel(QueryChannelRequest) returns (QueryChannelResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}"; - } - - // Channels queries all the IBC channels of a chain. - rpc Channels(QueryChannelsRequest) returns (QueryChannelsResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels"; - } - - // ConnectionChannels queries all the channels associated with a connection - // end. - rpc ConnectionChannels(QueryConnectionChannelsRequest) returns (QueryConnectionChannelsResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/connections/{connection}/channels"; - } - - // ChannelClientState queries for the client state for the channel associated - // with the provided channel identifiers. - rpc ChannelClientState(QueryChannelClientStateRequest) returns (QueryChannelClientStateResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" - "ports/{port_id}/client_state"; - } - - // ChannelConsensusState queries for the consensus state for the channel - // associated with the provided channel identifiers. - rpc ChannelConsensusState(QueryChannelConsensusStateRequest) returns (QueryChannelConsensusStateResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" - "ports/{port_id}/consensus_state/revision/" - "{revision_number}/height/{revision_height}"; - } - - // PacketCommitment queries a stored packet commitment hash. - rpc PacketCommitment(QueryPacketCommitmentRequest) returns (QueryPacketCommitmentResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/" - "packet_commitments/{sequence}"; - } - - // PacketCommitments returns all the packet commitments hashes associated - // with a channel. - rpc PacketCommitments(QueryPacketCommitmentsRequest) returns (QueryPacketCommitmentsResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" - "ports/{port_id}/packet_commitments"; - } - - // PacketReceipt queries if a given packet sequence has been received on the - // queried chain - rpc PacketReceipt(QueryPacketReceiptRequest) returns (QueryPacketReceiptResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" - "ports/{port_id}/packet_receipts/{sequence}"; - } - - // PacketAcknowledgement queries a stored packet acknowledgement hash. - rpc PacketAcknowledgement(QueryPacketAcknowledgementRequest) returns (QueryPacketAcknowledgementResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" - "ports/{port_id}/packet_acks/{sequence}"; - } - - // PacketAcknowledgements returns all the packet acknowledgements associated - // with a channel. - rpc PacketAcknowledgements(QueryPacketAcknowledgementsRequest) returns (QueryPacketAcknowledgementsResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" - "ports/{port_id}/packet_acknowledgements"; - } - - // UnreceivedPackets returns all the unreceived IBC packets associated with a - // channel and sequences. - rpc UnreceivedPackets(QueryUnreceivedPacketsRequest) returns (QueryUnreceivedPacketsResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/" - "packet_commitments/" - "{packet_commitment_sequences}/unreceived_packets"; - } - - // UnreceivedAcks returns all the unreceived IBC acknowledgements associated - // with a channel and sequences. - rpc UnreceivedAcks(QueryUnreceivedAcksRequest) returns (QueryUnreceivedAcksResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" - "ports/{port_id}/packet_commitments/" - "{packet_ack_sequences}/unreceived_acks"; - } - - // NextSequenceReceive returns the next receive sequence for a given channel. - rpc NextSequenceReceive(QueryNextSequenceReceiveRequest) returns (QueryNextSequenceReceiveResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" - "ports/{port_id}/next_sequence"; - } - - // NextSequenceSend returns the next send sequence for a given channel. - rpc NextSequenceSend(QueryNextSequenceSendRequest) returns (QueryNextSequenceSendResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" - "ports/{port_id}/next_sequence_send"; - } - - // UpgradeError returns the error receipt if the upgrade handshake failed. - rpc UpgradeError(QueryUpgradeErrorRequest) returns (QueryUpgradeErrorResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" - "ports/{port_id}/upgrade_error"; - } - - // Upgrade returns the upgrade for a given port and channel id. - rpc Upgrade(QueryUpgradeRequest) returns (QueryUpgradeResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" - "ports/{port_id}/upgrade"; - } - - // ChannelParams queries all parameters of the ibc channel submodule. - rpc ChannelParams(QueryChannelParamsRequest) returns (QueryChannelParamsResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/params"; - } -} - -// QueryChannelRequest is the request type for the Query/Channel RPC method -message QueryChannelRequest { - // port unique identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; -} - -// QueryChannelResponse is the response type for the Query/Channel RPC method. -// Besides the Channel end, it includes a proof and the height from which the -// proof was retrieved. -message QueryChannelResponse { - // channel associated with the request identifiers - ibc.core.channel.v1.Channel channel = 1; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryChannelsRequest is the request type for the Query/Channels RPC method -message QueryChannelsRequest { - // pagination request - cosmos.base.query.v1beta1.PageRequest pagination = 1; -} - -// QueryChannelsResponse is the response type for the Query/Channels RPC method. -message QueryChannelsResponse { - // list of stored channels of the chain. - repeated ibc.core.channel.v1.IdentifiedChannel channels = 1; - // pagination response - cosmos.base.query.v1beta1.PageResponse pagination = 2; - // query block height - ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; -} - -// QueryConnectionChannelsRequest is the request type for the -// Query/QueryConnectionChannels RPC method -message QueryConnectionChannelsRequest { - // connection unique identifier - string connection = 1; - // pagination request - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryConnectionChannelsResponse is the Response type for the -// Query/QueryConnectionChannels RPC method -message QueryConnectionChannelsResponse { - // list of channels associated with a connection. - repeated ibc.core.channel.v1.IdentifiedChannel channels = 1; - // pagination response - cosmos.base.query.v1beta1.PageResponse pagination = 2; - // query block height - ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; -} - -// QueryChannelClientStateRequest is the request type for the Query/ClientState -// RPC method -message QueryChannelClientStateRequest { - // port unique identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; -} - -// QueryChannelClientStateResponse is the Response type for the -// Query/QueryChannelClientState RPC method -message QueryChannelClientStateResponse { - // client state associated with the channel - ibc.core.client.v1.IdentifiedClientState identified_client_state = 1; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryChannelConsensusStateRequest is the request type for the -// Query/ConsensusState RPC method -message QueryChannelConsensusStateRequest { - // port unique identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; - // revision number of the consensus state - uint64 revision_number = 3; - // revision height of the consensus state - uint64 revision_height = 4; -} - -// QueryChannelClientStateResponse is the Response type for the -// Query/QueryChannelClientState RPC method -message QueryChannelConsensusStateResponse { - // consensus state associated with the channel - google.protobuf.Any consensus_state = 1; - // client ID associated with the consensus state - string client_id = 2; - // merkle proof of existence - bytes proof = 3; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; -} - -// QueryPacketCommitmentRequest is the request type for the -// Query/PacketCommitment RPC method -message QueryPacketCommitmentRequest { - // port unique identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; - // packet sequence - uint64 sequence = 3; -} - -// QueryPacketCommitmentResponse defines the client query response for a packet -// which also includes a proof and the height from which the proof was -// retrieved -message QueryPacketCommitmentResponse { - // packet associated with the request fields - bytes commitment = 1; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryPacketCommitmentsRequest is the request type for the -// Query/QueryPacketCommitments RPC method -message QueryPacketCommitmentsRequest { - // port unique identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; - // pagination request - cosmos.base.query.v1beta1.PageRequest pagination = 3; -} - -// QueryPacketCommitmentsResponse is the request type for the -// Query/QueryPacketCommitments RPC method -message QueryPacketCommitmentsResponse { - repeated ibc.core.channel.v1.PacketState commitments = 1; - // pagination response - cosmos.base.query.v1beta1.PageResponse pagination = 2; - // query block height - ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; -} - -// QueryPacketReceiptRequest is the request type for the -// Query/PacketReceipt RPC method -message QueryPacketReceiptRequest { - // port unique identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; - // packet sequence - uint64 sequence = 3; -} - -// QueryPacketReceiptResponse defines the client query response for a packet -// receipt which also includes a proof, and the height from which the proof was -// retrieved -message QueryPacketReceiptResponse { - // success flag for if receipt exists - bool received = 2; - // merkle proof of existence - bytes proof = 3; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; -} - -// QueryPacketAcknowledgementRequest is the request type for the -// Query/PacketAcknowledgement RPC method -message QueryPacketAcknowledgementRequest { - // port unique identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; - // packet sequence - uint64 sequence = 3; -} - -// QueryPacketAcknowledgementResponse defines the client query response for a -// packet which also includes a proof and the height from which the -// proof was retrieved -message QueryPacketAcknowledgementResponse { - // packet associated with the request fields - bytes acknowledgement = 1; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryPacketAcknowledgementsRequest is the request type for the -// Query/QueryPacketCommitments RPC method -message QueryPacketAcknowledgementsRequest { - // port unique identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; - // pagination request - cosmos.base.query.v1beta1.PageRequest pagination = 3; - // list of packet sequences - repeated uint64 packet_commitment_sequences = 4; -} - -// QueryPacketAcknowledgemetsResponse is the request type for the -// Query/QueryPacketAcknowledgements RPC method -message QueryPacketAcknowledgementsResponse { - repeated ibc.core.channel.v1.PacketState acknowledgements = 1; - // pagination response - cosmos.base.query.v1beta1.PageResponse pagination = 2; - // query block height - ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; -} - -// QueryUnreceivedPacketsRequest is the request type for the -// Query/UnreceivedPackets RPC method -message QueryUnreceivedPacketsRequest { - // port unique identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; - // list of packet sequences - repeated uint64 packet_commitment_sequences = 3; -} - -// QueryUnreceivedPacketsResponse is the response type for the -// Query/UnreceivedPacketCommitments RPC method -message QueryUnreceivedPacketsResponse { - // list of unreceived packet sequences - repeated uint64 sequences = 1; - // query block height - ibc.core.client.v1.Height height = 2 [(gogoproto.nullable) = false]; -} - -// QueryUnreceivedAcks is the request type for the -// Query/UnreceivedAcks RPC method -message QueryUnreceivedAcksRequest { - // port unique identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; - // list of acknowledgement sequences - repeated uint64 packet_ack_sequences = 3; -} - -// QueryUnreceivedAcksResponse is the response type for the -// Query/UnreceivedAcks RPC method -message QueryUnreceivedAcksResponse { - // list of unreceived acknowledgement sequences - repeated uint64 sequences = 1; - // query block height - ibc.core.client.v1.Height height = 2 [(gogoproto.nullable) = false]; -} - -// QueryNextSequenceReceiveRequest is the request type for the -// Query/QueryNextSequenceReceiveRequest RPC method -message QueryNextSequenceReceiveRequest { - // port unique identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; -} - -// QuerySequenceResponse is the response type for the -// Query/QueryNextSequenceReceiveResponse RPC method -message QueryNextSequenceReceiveResponse { - // next sequence receive number - uint64 next_sequence_receive = 1; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryNextSequenceSendRequest is the request type for the -// Query/QueryNextSequenceSend RPC method -message QueryNextSequenceSendRequest { - // port unique identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; -} - -// QueryNextSequenceSendResponse is the request type for the -// Query/QueryNextSequenceSend RPC method -message QueryNextSequenceSendResponse { - // next sequence send number - uint64 next_sequence_send = 1; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryUpgradeErrorRequest is the request type for the Query/QueryUpgradeError RPC method -message QueryUpgradeErrorRequest { - string port_id = 1; - string channel_id = 2; -} - -// QueryUpgradeErrorResponse is the response type for the Query/QueryUpgradeError RPC method -message QueryUpgradeErrorResponse { - ErrorReceipt error_receipt = 1 [(gogoproto.nullable) = false]; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryUpgradeRequest is the request type for the QueryUpgradeRequest RPC method -message QueryUpgradeRequest { - string port_id = 1; - string channel_id = 2; -} - -// QueryUpgradeResponse is the response type for the QueryUpgradeResponse RPC method -message QueryUpgradeResponse { - Upgrade upgrade = 1 [(gogoproto.nullable) = false]; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryChannelParamsRequest is the request type for the Query/ChannelParams RPC method. -message QueryChannelParamsRequest {} - -// QueryChannelParamsResponse is the response type for the Query/ChannelParams RPC method. -message QueryChannelParamsResponse { - // params defines the parameters of the module. - Params params = 1; -} \ No newline at end of file diff --git a/third_party/proto/ibc/channel/v1/tx.proto b/third_party/proto/ibc/channel/v1/tx.proto deleted file mode 100644 index 3f30e8b8c..000000000 --- a/third_party/proto/ibc/channel/v1/tx.proto +++ /dev/null @@ -1,469 +0,0 @@ -syntax = "proto3"; - -package ibc.core.channel.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"; - -import "gogoproto/gogo.proto"; -import "cosmos/msg/v1/msg.proto"; -import "ibc/core/client/v1/client.proto"; -import "ibc/core/channel/v1/channel.proto"; -import "ibc/core/channel/v1/upgrade.proto"; - -// Msg defines the ibc/channel Msg service. -service Msg { - option (cosmos.msg.v1.service) = true; - - // ChannelOpenInit defines a rpc handler method for MsgChannelOpenInit. - rpc ChannelOpenInit(MsgChannelOpenInit) returns (MsgChannelOpenInitResponse); - - // ChannelOpenTry defines a rpc handler method for MsgChannelOpenTry. - rpc ChannelOpenTry(MsgChannelOpenTry) returns (MsgChannelOpenTryResponse); - - // ChannelOpenAck defines a rpc handler method for MsgChannelOpenAck. - rpc ChannelOpenAck(MsgChannelOpenAck) returns (MsgChannelOpenAckResponse); - - // ChannelOpenConfirm defines a rpc handler method for MsgChannelOpenConfirm. - rpc ChannelOpenConfirm(MsgChannelOpenConfirm) returns (MsgChannelOpenConfirmResponse); - - // ChannelCloseInit defines a rpc handler method for MsgChannelCloseInit. - rpc ChannelCloseInit(MsgChannelCloseInit) returns (MsgChannelCloseInitResponse); - - // ChannelCloseConfirm defines a rpc handler method for - // MsgChannelCloseConfirm. - rpc ChannelCloseConfirm(MsgChannelCloseConfirm) returns (MsgChannelCloseConfirmResponse); - - // RecvPacket defines a rpc handler method for MsgRecvPacket. - rpc RecvPacket(MsgRecvPacket) returns (MsgRecvPacketResponse); - - // Timeout defines a rpc handler method for MsgTimeout. - rpc Timeout(MsgTimeout) returns (MsgTimeoutResponse); - - // TimeoutOnClose defines a rpc handler method for MsgTimeoutOnClose. - rpc TimeoutOnClose(MsgTimeoutOnClose) returns (MsgTimeoutOnCloseResponse); - - // Acknowledgement defines a rpc handler method for MsgAcknowledgement. - rpc Acknowledgement(MsgAcknowledgement) returns (MsgAcknowledgementResponse); - - // ChannelUpgradeInit defines a rpc handler method for MsgChannelUpgradeInit. - rpc ChannelUpgradeInit(MsgChannelUpgradeInit) returns (MsgChannelUpgradeInitResponse); - - // ChannelUpgradeTry defines a rpc handler method for MsgChannelUpgradeTry. - rpc ChannelUpgradeTry(MsgChannelUpgradeTry) returns (MsgChannelUpgradeTryResponse); - - // ChannelUpgradeAck defines a rpc handler method for MsgChannelUpgradeAck. - rpc ChannelUpgradeAck(MsgChannelUpgradeAck) returns (MsgChannelUpgradeAckResponse); - - // ChannelUpgradeConfirm defines a rpc handler method for MsgChannelUpgradeConfirm. - rpc ChannelUpgradeConfirm(MsgChannelUpgradeConfirm) returns (MsgChannelUpgradeConfirmResponse); - - // ChannelUpgradeOpen defines a rpc handler method for MsgChannelUpgradeOpen. - rpc ChannelUpgradeOpen(MsgChannelUpgradeOpen) returns (MsgChannelUpgradeOpenResponse); - - // ChannelUpgradeTimeout defines a rpc handler method for MsgChannelUpgradeTimeout. - rpc ChannelUpgradeTimeout(MsgChannelUpgradeTimeout) returns (MsgChannelUpgradeTimeoutResponse); - - // ChannelUpgradeCancel defines a rpc handler method for MsgChannelUpgradeCancel. - rpc ChannelUpgradeCancel(MsgChannelUpgradeCancel) returns (MsgChannelUpgradeCancelResponse); - - // UpdateChannelParams defines a rpc handler method for MsgUpdateParams. - rpc UpdateChannelParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); - - // PruneAcknowledgements defines a rpc handler method for MsgPruneAcknowledgements. - rpc PruneAcknowledgements(MsgPruneAcknowledgements) returns (MsgPruneAcknowledgementsResponse); -} - -// ResponseResultType defines the possible outcomes of the execution of a message -enum ResponseResultType { - option (gogoproto.goproto_enum_prefix) = false; - - // Default zero value enumeration - RESPONSE_RESULT_TYPE_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNSPECIFIED"]; - // The message did not call the IBC application callbacks (because, for example, the packet had already been relayed) - RESPONSE_RESULT_TYPE_NOOP = 1 [(gogoproto.enumvalue_customname) = "NOOP"]; - // The message was executed successfully - RESPONSE_RESULT_TYPE_SUCCESS = 2 [(gogoproto.enumvalue_customname) = "SUCCESS"]; - // The message was executed unsuccessfully - RESPONSE_RESULT_TYPE_FAILURE = 3 [(gogoproto.enumvalue_customname) = "FAILURE"]; -} - -// MsgChannelOpenInit defines an sdk.Msg to initialize a channel handshake. It -// is called by a relayer on Chain A. -message MsgChannelOpenInit { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - string port_id = 1; - Channel channel = 2 [(gogoproto.nullable) = false]; - string signer = 3; -} - -// MsgChannelOpenInitResponse defines the Msg/ChannelOpenInit response type. -message MsgChannelOpenInitResponse { - option (gogoproto.goproto_getters) = false; - - string channel_id = 1; - string version = 2; -} - -// MsgChannelOpenInit defines a msg sent by a Relayer to try to open a channel -// on Chain B. The version field within the Channel field has been deprecated. Its -// value will be ignored by core IBC. -message MsgChannelOpenTry { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - string port_id = 1; - // Deprecated: this field is unused. Crossing hello's are no longer supported in core IBC. - string previous_channel_id = 2 [deprecated = true]; - // NOTE: the version field within the channel has been deprecated. Its value will be ignored by core IBC. - Channel channel = 3 [(gogoproto.nullable) = false]; - string counterparty_version = 4; - bytes proof_init = 5; - ibc.core.client.v1.Height proof_height = 6 [(gogoproto.nullable) = false]; - string signer = 7; -} - -// MsgChannelOpenTryResponse defines the Msg/ChannelOpenTry response type. -message MsgChannelOpenTryResponse { - option (gogoproto.goproto_getters) = false; - - string version = 1; - string channel_id = 2; -} - -// MsgChannelOpenAck defines a msg sent by a Relayer to Chain A to acknowledge -// the change of channel state to TRYOPEN on Chain B. -// WARNING: a channel upgrade MUST NOT initialize an upgrade for this channel -// in the same block as executing this message otherwise the counterparty will -// be incapable of opening. -message MsgChannelOpenAck { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - string port_id = 1; - string channel_id = 2; - string counterparty_channel_id = 3; - string counterparty_version = 4; - bytes proof_try = 5; - ibc.core.client.v1.Height proof_height = 6 [(gogoproto.nullable) = false]; - string signer = 7; -} - -// MsgChannelOpenAckResponse defines the Msg/ChannelOpenAck response type. -message MsgChannelOpenAckResponse {} - -// MsgChannelOpenConfirm defines a msg sent by a Relayer to Chain B to -// acknowledge the change of channel state to OPEN on Chain A. -message MsgChannelOpenConfirm { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - string port_id = 1; - string channel_id = 2; - bytes proof_ack = 3; - ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; - string signer = 5; -} - -// MsgChannelOpenConfirmResponse defines the Msg/ChannelOpenConfirm response -// type. -message MsgChannelOpenConfirmResponse {} - -// MsgChannelCloseInit defines a msg sent by a Relayer to Chain A -// to close a channel with Chain B. -message MsgChannelCloseInit { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - string port_id = 1; - string channel_id = 2; - string signer = 3; -} - -// MsgChannelCloseInitResponse defines the Msg/ChannelCloseInit response type. -message MsgChannelCloseInitResponse {} - -// MsgChannelCloseConfirm defines a msg sent by a Relayer to Chain B -// to acknowledge the change of channel state to CLOSED on Chain A. -message MsgChannelCloseConfirm { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - string port_id = 1; - string channel_id = 2; - bytes proof_init = 3; - ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; - string signer = 5; - uint64 counterparty_upgrade_sequence = 6; -} - -// MsgChannelCloseConfirmResponse defines the Msg/ChannelCloseConfirm response -// type. -message MsgChannelCloseConfirmResponse {} - -// MsgRecvPacket receives incoming IBC packet -message MsgRecvPacket { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - Packet packet = 1 [(gogoproto.nullable) = false]; - bytes proof_commitment = 2; - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; - string signer = 4; -} - -// MsgRecvPacketResponse defines the Msg/RecvPacket response type. -message MsgRecvPacketResponse { - option (gogoproto.goproto_getters) = false; - - ResponseResultType result = 1; -} - -// MsgTimeout receives timed-out packet -message MsgTimeout { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - Packet packet = 1 [(gogoproto.nullable) = false]; - bytes proof_unreceived = 2; - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; - uint64 next_sequence_recv = 4; - string signer = 5; -} - -// MsgTimeoutResponse defines the Msg/Timeout response type. -message MsgTimeoutResponse { - option (gogoproto.goproto_getters) = false; - - ResponseResultType result = 1; -} - -// MsgTimeoutOnClose timed-out packet upon counterparty channel closure. -message MsgTimeoutOnClose { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - Packet packet = 1 [(gogoproto.nullable) = false]; - bytes proof_unreceived = 2; - bytes proof_close = 3; - ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; - uint64 next_sequence_recv = 5; - string signer = 6; - uint64 counterparty_upgrade_sequence = 7; -} - -// MsgTimeoutOnCloseResponse defines the Msg/TimeoutOnClose response type. -message MsgTimeoutOnCloseResponse { - option (gogoproto.goproto_getters) = false; - - ResponseResultType result = 1; -} - -// MsgAcknowledgement receives incoming IBC acknowledgement -message MsgAcknowledgement { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - Packet packet = 1 [(gogoproto.nullable) = false]; - bytes acknowledgement = 2; - bytes proof_acked = 3; - ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; - string signer = 5; -} - -// MsgAcknowledgementResponse defines the Msg/Acknowledgement response type. -message MsgAcknowledgementResponse { - option (gogoproto.goproto_getters) = false; - - ResponseResultType result = 1; -} - -// MsgChannelUpgradeInit defines the request type for the ChannelUpgradeInit rpc -// WARNING: Initializing a channel upgrade in the same block as opening the channel -// may result in the counterparty being incapable of opening. -message MsgChannelUpgradeInit { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - string port_id = 1; - string channel_id = 2; - UpgradeFields fields = 3 [(gogoproto.nullable) = false]; - string signer = 4; -} - -// MsgChannelUpgradeInitResponse defines the MsgChannelUpgradeInit response type -message MsgChannelUpgradeInitResponse { - option (gogoproto.goproto_getters) = false; - - Upgrade upgrade = 1 [(gogoproto.nullable) = false]; - uint64 upgrade_sequence = 2; -} - -// MsgChannelUpgradeTry defines the request type for the ChannelUpgradeTry rpc -message MsgChannelUpgradeTry { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - string port_id = 1; - string channel_id = 2; - repeated string proposed_upgrade_connection_hops = 3; - UpgradeFields counterparty_upgrade_fields = 4 [(gogoproto.nullable) = false]; - uint64 counterparty_upgrade_sequence = 5; - bytes proof_channel = 6; - bytes proof_upgrade = 7; - ibc.core.client.v1.Height proof_height = 8 [(gogoproto.nullable) = false]; - string signer = 9; -} - -// MsgChannelUpgradeTryResponse defines the MsgChannelUpgradeTry response type -message MsgChannelUpgradeTryResponse { - option (gogoproto.goproto_getters) = false; - - Upgrade upgrade = 1 [(gogoproto.nullable) = false]; - uint64 upgrade_sequence = 2; - ResponseResultType result = 3; -} - -// MsgChannelUpgradeAck defines the request type for the ChannelUpgradeAck rpc -message MsgChannelUpgradeAck { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - string port_id = 1; - string channel_id = 2; - Upgrade counterparty_upgrade = 3 [(gogoproto.nullable) = false]; - bytes proof_channel = 4; - bytes proof_upgrade = 5; - ibc.core.client.v1.Height proof_height = 6 [(gogoproto.nullable) = false]; - string signer = 7; -} - -// MsgChannelUpgradeAckResponse defines MsgChannelUpgradeAck response type -message MsgChannelUpgradeAckResponse { - option (gogoproto.goproto_getters) = false; - - ResponseResultType result = 1; -} - -// MsgChannelUpgradeConfirm defines the request type for the ChannelUpgradeConfirm rpc -message MsgChannelUpgradeConfirm { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - string port_id = 1; - string channel_id = 2; - State counterparty_channel_state = 3; - Upgrade counterparty_upgrade = 4 [(gogoproto.nullable) = false]; - bytes proof_channel = 5; - bytes proof_upgrade = 6; - ibc.core.client.v1.Height proof_height = 7 [(gogoproto.nullable) = false]; - string signer = 8; -} - -// MsgChannelUpgradeConfirmResponse defines MsgChannelUpgradeConfirm response type -message MsgChannelUpgradeConfirmResponse { - option (gogoproto.goproto_getters) = false; - - ResponseResultType result = 1; -} - -// MsgChannelUpgradeOpen defines the request type for the ChannelUpgradeOpen rpc -message MsgChannelUpgradeOpen { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - string port_id = 1; - string channel_id = 2; - State counterparty_channel_state = 3; - uint64 counterparty_upgrade_sequence = 4; - bytes proof_channel = 5; - ibc.core.client.v1.Height proof_height = 6 [(gogoproto.nullable) = false]; - string signer = 7; -} - -// MsgChannelUpgradeOpenResponse defines the MsgChannelUpgradeOpen response type -message MsgChannelUpgradeOpenResponse {} - -// MsgChannelUpgradeTimeout defines the request type for the ChannelUpgradeTimeout rpc -message MsgChannelUpgradeTimeout { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - string port_id = 1; - string channel_id = 2; - Channel counterparty_channel = 3 [(gogoproto.nullable) = false]; - bytes proof_channel = 4; - ibc.core.client.v1.Height proof_height = 5 [(gogoproto.nullable) = false]; - string signer = 6; -} - -// MsgChannelUpgradeTimeoutRepsonse defines the MsgChannelUpgradeTimeout response type -message MsgChannelUpgradeTimeoutResponse {} - -// MsgChannelUpgradeCancel defines the request type for the ChannelUpgradeCancel rpc -message MsgChannelUpgradeCancel { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - string port_id = 1; - string channel_id = 2; - ErrorReceipt error_receipt = 3 [(gogoproto.nullable) = false]; - bytes proof_error_receipt = 4; - ibc.core.client.v1.Height proof_height = 5 [(gogoproto.nullable) = false]; - string signer = 6; -} - -// MsgChannelUpgradeCancelResponse defines the MsgChannelUpgradeCancel response type -message MsgChannelUpgradeCancelResponse {} - -// MsgUpdateParams is the MsgUpdateParams request type. -message MsgUpdateParams { - option (cosmos.msg.v1.signer) = "authority"; - - option (gogoproto.goproto_getters) = false; - - // authority is the address that controls the module (defaults to x/gov unless overwritten). - string authority = 1; - - // params defines the channel parameters to update. - // - // NOTE: All parameters must be supplied. - Params params = 2 [(gogoproto.nullable) = false]; -} - -// MsgUpdateParamsResponse defines the MsgUpdateParams response type. -message MsgUpdateParamsResponse {} - -// MsgPruneAcknowledgements defines the request type for the PruneAcknowledgements rpc. -message MsgPruneAcknowledgements { - option (cosmos.msg.v1.signer) = "signer"; - option (gogoproto.goproto_getters) = false; - - string port_id = 1; - string channel_id = 2; - uint64 limit = 3; - string signer = 4; -} - -// MsgPruneAcknowledgementsResponse defines the response type for the PruneAcknowledgements rpc. -message MsgPruneAcknowledgementsResponse { - // Number of sequences pruned (includes both packet acknowledgements and packet receipts where appropriate). - uint64 total_pruned_sequences = 1; - // Number of sequences left after pruning. - uint64 total_remaining_sequences = 2; -} diff --git a/third_party/proto/ibc/channel/v1/upgrade.proto b/third_party/proto/ibc/channel/v1/upgrade.proto deleted file mode 100644 index 81530ed2a..000000000 --- a/third_party/proto/ibc/channel/v1/upgrade.proto +++ /dev/null @@ -1,43 +0,0 @@ -syntax = "proto3"; - -package ibc.core.channel.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"; - -import "gogoproto/gogo.proto"; -import "ibc/core/channel/v1/channel.proto"; - -// Upgrade is a verifiable type which contains the relevant information -// for an attempted upgrade. It provides the proposed changes to the channel -// end, the timeout for this upgrade attempt and the next packet sequence -// which allows the counterparty to efficiently know the highest sequence it has received. -// The next sequence send is used for pruning and upgrading from unordered to ordered channels. -message Upgrade { - option (gogoproto.goproto_getters) = false; - - UpgradeFields fields = 1 [(gogoproto.nullable) = false]; - Timeout timeout = 2 [(gogoproto.nullable) = false]; - uint64 next_sequence_send = 3; -} - -// UpgradeFields are the fields in a channel end which may be changed -// during a channel upgrade. -message UpgradeFields { - option (gogoproto.goproto_getters) = false; - - Order ordering = 1; - repeated string connection_hops = 2; - string version = 3; -} - -// ErrorReceipt defines a type which encapsulates the upgrade sequence and error associated with the -// upgrade handshake failure. When a channel upgrade handshake is aborted both chains are expected to increment to the -// next sequence. -message ErrorReceipt { - option (gogoproto.goproto_getters) = false; - - // the channel upgrade sequence - uint64 sequence = 1; - // the error message detailing the cause of failure - string message = 2; -} diff --git a/third_party/proto/ibc/client/v1/client.proto b/third_party/proto/ibc/client/v1/client.proto deleted file mode 100644 index 7a09e360a..000000000 --- a/third_party/proto/ibc/client/v1/client.proto +++ /dev/null @@ -1,113 +0,0 @@ -syntax = "proto3"; - -package ibc.core.client.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"; - -import "cosmos/upgrade/v1beta1/upgrade.proto"; -import "cosmos_proto/cosmos.proto"; -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; - -// IdentifiedClientState defines a client state with an additional client -// identifier field. -message IdentifiedClientState { - // client identifier - string client_id = 1; - // client state - google.protobuf.Any client_state = 2; -} - -// ConsensusStateWithHeight defines a consensus state with an additional height -// field. -message ConsensusStateWithHeight { - // consensus state height - Height height = 1 [(gogoproto.nullable) = false]; - // consensus state - google.protobuf.Any consensus_state = 2; -} - -// ClientConsensusStates defines all the stored consensus states for a given -// client. -message ClientConsensusStates { - // client identifier - string client_id = 1; - // consensus states and their heights associated with the client - repeated ConsensusStateWithHeight consensus_states = 2 [(gogoproto.nullable) = false]; -} - -// Height is a monotonically increasing data type -// that can be compared against another Height for the purposes of updating and -// freezing clients -// -// Normally the RevisionHeight is incremented at each height while keeping -// RevisionNumber the same. However some consensus algorithms may choose to -// reset the height in certain conditions e.g. hard forks, state-machine -// breaking changes In these cases, the RevisionNumber is incremented so that -// height continues to be monitonically increasing even as the RevisionHeight -// gets reset -message Height { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - - // the revision that the client is currently on - uint64 revision_number = 1; - // the height within the given revision - uint64 revision_height = 2; -} - -// Params defines the set of IBC light client parameters. -message Params { - // allowed_clients defines the list of allowed client state types which can be created - // and interacted with. If a client type is removed from the allowed clients list, usage - // of this client will be disabled until it is added again to the list. - repeated string allowed_clients = 1; -} - -// ClientUpdateProposal is a legacy governance proposal. If it passes, the substitute -// client's latest consensus state is copied over to the subject client. The proposal -// handler may fail if the subject and the substitute do not match in client and -// chain parameters (with exception to latest height, frozen height, and chain-id). -// -// Deprecated: Please use MsgRecoverClient in favour of this message type. -message ClientUpdateProposal { - option deprecated = true; - - option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; - option (gogoproto.goproto_getters) = false; - - // the title of the update proposal - string title = 1; - // the description of the proposal - string description = 2; - // the client identifier for the client to be updated if the proposal passes - string subject_client_id = 3 [(gogoproto.moretags) = "yaml:\"subject_client_id\""]; - // the substitute client identifier for the client standing in for the subject - // client - string substitute_client_id = 4 [(gogoproto.moretags) = "yaml:\"substitute_client_id\""]; -} - -// UpgradeProposal is a gov Content type for initiating an IBC breaking -// upgrade. -// -// Deprecated: Please use MsgIBCSoftwareUpgrade in favour of this message type. -message UpgradeProposal { - option deprecated = true; - - option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - option (gogoproto.equal) = true; - - string title = 1; - string description = 2; - cosmos.upgrade.v1beta1.Plan plan = 3 [(gogoproto.nullable) = false]; - - // An UpgradedClientState must be provided to perform an IBC breaking upgrade. - // This will make the chain commit to the correct upgraded (self) client state - // before the upgrade occurs, so that connecting chains can verify that the - // new upgraded client is valid by verifying a proof on the previous version - // of the chain. This will allow IBC connections to persist smoothly across - // planned chain upgrades - google.protobuf.Any upgraded_client_state = 4 [(gogoproto.moretags) = "yaml:\"upgraded_client_state\""]; -} diff --git a/third_party/proto/ibc/client/v1/genesis.proto b/third_party/proto/ibc/client/v1/genesis.proto deleted file mode 100644 index 43610b0d4..000000000 --- a/third_party/proto/ibc/client/v1/genesis.proto +++ /dev/null @@ -1,44 +0,0 @@ -syntax = "proto3"; - -package ibc.core.client.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"; - -import "ibc/core/client/v1/client.proto"; -import "gogoproto/gogo.proto"; - -// GenesisState defines the ibc client submodule's genesis state. -message GenesisState { - // client states with their corresponding identifiers - repeated IdentifiedClientState clients = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "IdentifiedClientStates"]; - // consensus states from each client - repeated ClientConsensusStates clients_consensus = 2 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "ClientsConsensusStates"]; - // metadata from each client - repeated IdentifiedGenesisMetadata clients_metadata = 3 [(gogoproto.nullable) = false]; - Params params = 4 [(gogoproto.nullable) = false]; - // Deprecated: create_localhost has been deprecated. - // The localhost client is automatically created at genesis. - bool create_localhost = 5 [deprecated = true]; - // the sequence for the next generated client identifier - uint64 next_client_sequence = 6; -} - -// GenesisMetadata defines the genesis type for metadata that clients may return -// with ExportMetadata -message GenesisMetadata { - option (gogoproto.goproto_getters) = false; - - // store key of metadata without clientID-prefix - bytes key = 1; - // metadata value - bytes value = 2; -} - -// IdentifiedGenesisMetadata has the client metadata with the corresponding -// client id. -message IdentifiedGenesisMetadata { - string client_id = 1; - repeated GenesisMetadata client_metadata = 2 [(gogoproto.nullable) = false]; -} diff --git a/third_party/proto/ibc/client/v1/query.proto b/third_party/proto/ibc/client/v1/query.proto deleted file mode 100644 index 0032306ec..000000000 --- a/third_party/proto/ibc/client/v1/query.proto +++ /dev/null @@ -1,207 +0,0 @@ -syntax = "proto3"; - -package ibc.core.client.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"; - -import "cosmos/base/query/v1beta1/pagination.proto"; -import "ibc/core/client/v1/client.proto"; -import "google/protobuf/any.proto"; -import "google/api/annotations.proto"; -import "gogoproto/gogo.proto"; - -// Query provides defines the gRPC querier service -service Query { - // ClientState queries an IBC light client. - rpc ClientState(QueryClientStateRequest) returns (QueryClientStateResponse) { - option (google.api.http).get = "/ibc/core/client/v1/client_states/{client_id}"; - } - - // ClientStates queries all the IBC light clients of a chain. - rpc ClientStates(QueryClientStatesRequest) returns (QueryClientStatesResponse) { - option (google.api.http).get = "/ibc/core/client/v1/client_states"; - } - - // ConsensusState queries a consensus state associated with a client state at - // a given height. - rpc ConsensusState(QueryConsensusStateRequest) returns (QueryConsensusStateResponse) { - option (google.api.http).get = "/ibc/core/client/v1/consensus_states/" - "{client_id}/revision/{revision_number}/" - "height/{revision_height}"; - } - - // ConsensusStates queries all the consensus state associated with a given - // client. - rpc ConsensusStates(QueryConsensusStatesRequest) returns (QueryConsensusStatesResponse) { - option (google.api.http).get = "/ibc/core/client/v1/consensus_states/{client_id}"; - } - - // ConsensusStateHeights queries the height of every consensus states associated with a given client. - rpc ConsensusStateHeights(QueryConsensusStateHeightsRequest) returns (QueryConsensusStateHeightsResponse) { - option (google.api.http).get = "/ibc/core/client/v1/consensus_states/{client_id}/heights"; - } - - // Status queries the status of an IBC client. - rpc ClientStatus(QueryClientStatusRequest) returns (QueryClientStatusResponse) { - option (google.api.http).get = "/ibc/core/client/v1/client_status/{client_id}"; - } - - // ClientParams queries all parameters of the ibc client submodule. - rpc ClientParams(QueryClientParamsRequest) returns (QueryClientParamsResponse) { - option (google.api.http).get = "/ibc/core/client/v1/params"; - } - - // UpgradedClientState queries an Upgraded IBC light client. - rpc UpgradedClientState(QueryUpgradedClientStateRequest) returns (QueryUpgradedClientStateResponse) { - option (google.api.http).get = "/ibc/core/client/v1/upgraded_client_states"; - } - - // UpgradedConsensusState queries an Upgraded IBC consensus state. - rpc UpgradedConsensusState(QueryUpgradedConsensusStateRequest) returns (QueryUpgradedConsensusStateResponse) { - option (google.api.http).get = "/ibc/core/client/v1/upgraded_consensus_states"; - } -} - -// QueryClientStateRequest is the request type for the Query/ClientState RPC -// method -message QueryClientStateRequest { - // client state unique identifier - string client_id = 1; -} - -// QueryClientStateResponse is the response type for the Query/ClientState RPC -// method. Besides the client state, it includes a proof and the height from -// which the proof was retrieved. -message QueryClientStateResponse { - // client state associated with the request identifier - google.protobuf.Any client_state = 1; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryClientStatesRequest is the request type for the Query/ClientStates RPC -// method -message QueryClientStatesRequest { - // pagination request - cosmos.base.query.v1beta1.PageRequest pagination = 1; -} - -// QueryClientStatesResponse is the response type for the Query/ClientStates RPC -// method. -message QueryClientStatesResponse { - // list of stored ClientStates of the chain. - repeated IdentifiedClientState client_states = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "IdentifiedClientStates"]; - // pagination response - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryConsensusStateRequest is the request type for the Query/ConsensusState -// RPC method. Besides the consensus state, it includes a proof and the height -// from which the proof was retrieved. -message QueryConsensusStateRequest { - // client identifier - string client_id = 1; - // consensus state revision number - uint64 revision_number = 2; - // consensus state revision height - uint64 revision_height = 3; - // latest_height overrrides the height field and queries the latest stored - // ConsensusState - bool latest_height = 4; -} - -// QueryConsensusStateResponse is the response type for the Query/ConsensusState -// RPC method -message QueryConsensusStateResponse { - // consensus state associated with the client identifier at the given height - google.protobuf.Any consensus_state = 1; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryConsensusStatesRequest is the request type for the Query/ConsensusStates -// RPC method. -message QueryConsensusStatesRequest { - // client identifier - string client_id = 1; - // pagination request - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryConsensusStatesResponse is the response type for the -// Query/ConsensusStates RPC method -message QueryConsensusStatesResponse { - // consensus states associated with the identifier - repeated ConsensusStateWithHeight consensus_states = 1 [(gogoproto.nullable) = false]; - // pagination response - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryConsensusStateHeightsRequest is the request type for Query/ConsensusStateHeights -// RPC method. -message QueryConsensusStateHeightsRequest { - // client identifier - string client_id = 1; - // pagination request - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryConsensusStateHeightsResponse is the response type for the -// Query/ConsensusStateHeights RPC method -message QueryConsensusStateHeightsResponse { - // consensus state heights - repeated Height consensus_state_heights = 1 [(gogoproto.nullable) = false]; - // pagination response - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryClientStatusRequest is the request type for the Query/ClientStatus RPC -// method -message QueryClientStatusRequest { - // client unique identifier - string client_id = 1; -} - -// QueryClientStatusResponse is the response type for the Query/ClientStatus RPC -// method. It returns the current status of the IBC client. -message QueryClientStatusResponse { - string status = 1; -} - -// QueryClientParamsRequest is the request type for the Query/ClientParams RPC -// method. -message QueryClientParamsRequest {} - -// QueryClientParamsResponse is the response type for the Query/ClientParams RPC -// method. -message QueryClientParamsResponse { - // params defines the parameters of the module. - Params params = 1; -} - -// QueryUpgradedClientStateRequest is the request type for the -// Query/UpgradedClientState RPC method -message QueryUpgradedClientStateRequest {} - -// QueryUpgradedClientStateResponse is the response type for the -// Query/UpgradedClientState RPC method. -message QueryUpgradedClientStateResponse { - // client state associated with the request identifier - google.protobuf.Any upgraded_client_state = 1; -} - -// QueryUpgradedConsensusStateRequest is the request type for the -// Query/UpgradedConsensusState RPC method -message QueryUpgradedConsensusStateRequest {} - -// QueryUpgradedConsensusStateResponse is the response type for the -// Query/UpgradedConsensusState RPC method. -message QueryUpgradedConsensusStateResponse { - // Consensus state associated with the request identifier - google.protobuf.Any upgraded_consensus_state = 1; -} diff --git a/third_party/proto/ibc/client/v1/tx.proto b/third_party/proto/ibc/client/v1/tx.proto deleted file mode 100644 index b504ab692..000000000 --- a/third_party/proto/ibc/client/v1/tx.proto +++ /dev/null @@ -1,175 +0,0 @@ -syntax = "proto3"; - -package ibc.core.client.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"; - -import "cosmos/msg/v1/msg.proto"; -import "cosmos/upgrade/v1beta1/upgrade.proto"; -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; -import "ibc/core/client/v1/client.proto"; - -// Msg defines the ibc/client Msg service. -service Msg { - option (cosmos.msg.v1.service) = true; - - // CreateClient defines a rpc handler method for MsgCreateClient. - rpc CreateClient(MsgCreateClient) returns (MsgCreateClientResponse); - - // UpdateClient defines a rpc handler method for MsgUpdateClient. - rpc UpdateClient(MsgUpdateClient) returns (MsgUpdateClientResponse); - - // UpgradeClient defines a rpc handler method for MsgUpgradeClient. - rpc UpgradeClient(MsgUpgradeClient) returns (MsgUpgradeClientResponse); - - // SubmitMisbehaviour defines a rpc handler method for MsgSubmitMisbehaviour. - rpc SubmitMisbehaviour(MsgSubmitMisbehaviour) returns (MsgSubmitMisbehaviourResponse); - - // RecoverClient defines a rpc handler method for MsgRecoverClient. - rpc RecoverClient(MsgRecoverClient) returns (MsgRecoverClientResponse); - - // IBCSoftwareUpgrade defines a rpc handler method for MsgIBCSoftwareUpgrade. - rpc IBCSoftwareUpgrade(MsgIBCSoftwareUpgrade) returns (MsgIBCSoftwareUpgradeResponse); - - // UpdateClientParams defines a rpc handler method for MsgUpdateParams. - rpc UpdateClientParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); -} - -// MsgCreateClient defines a message to create an IBC client -message MsgCreateClient { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - // light client state - google.protobuf.Any client_state = 1; - // consensus state associated with the client that corresponds to a given - // height. - google.protobuf.Any consensus_state = 2; - // signer address - string signer = 3; -} - -// MsgCreateClientResponse defines the Msg/CreateClient response type. -message MsgCreateClientResponse {} - -// MsgUpdateClient defines an sdk.Msg to update a IBC client state using -// the given client message. -message MsgUpdateClient { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - // client unique identifier - string client_id = 1; - // client message to update the light client - google.protobuf.Any client_message = 2; - // signer address - string signer = 3; -} - -// MsgUpdateClientResponse defines the Msg/UpdateClient response type. -message MsgUpdateClientResponse {} - -// MsgUpgradeClient defines an sdk.Msg to upgrade an IBC client to a new client -// state -message MsgUpgradeClient { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - // client unique identifier - string client_id = 1; - // upgraded client state - google.protobuf.Any client_state = 2; - // upgraded consensus state, only contains enough information to serve as a - // basis of trust in update logic - google.protobuf.Any consensus_state = 3; - // proof that old chain committed to new client - bytes proof_upgrade_client = 4; - // proof that old chain committed to new consensus state - bytes proof_upgrade_consensus_state = 5; - // signer address - string signer = 6; -} - -// MsgUpgradeClientResponse defines the Msg/UpgradeClient response type. -message MsgUpgradeClientResponse {} - -// MsgSubmitMisbehaviour defines an sdk.Msg type that submits Evidence for -// light client misbehaviour. -// This message has been deprecated. Use MsgUpdateClient instead. -message MsgSubmitMisbehaviour { - option deprecated = true; - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - // client unique identifier - string client_id = 1; - // misbehaviour used for freezing the light client - google.protobuf.Any misbehaviour = 2; - // signer address - string signer = 3; -} - -// MsgSubmitMisbehaviourResponse defines the Msg/SubmitMisbehaviour response -// type. -message MsgSubmitMisbehaviourResponse {} - -// MsgRecoverClient defines the message used to recover a frozen or expired client. -message MsgRecoverClient { - option (gogoproto.goproto_getters) = false; - option (cosmos.msg.v1.signer) = "signer"; - - // the client identifier for the client to be updated if the proposal passes - string subject_client_id = 1; - // the substitute client identifier for the client which will replace the subject - // client - string substitute_client_id = 2; - - // signer address - string signer = 3; -} - -// MsgRecoverClientResponse defines the Msg/RecoverClient response type. -message MsgRecoverClientResponse {} - -// MsgIBCSoftwareUpgrade defines the message used to schedule an upgrade of an IBC client using a v1 governance proposal -message MsgIBCSoftwareUpgrade { - option (cosmos.msg.v1.signer) = "signer"; - cosmos.upgrade.v1beta1.Plan plan = 1 [(gogoproto.nullable) = false]; - // An UpgradedClientState must be provided to perform an IBC breaking upgrade. - // This will make the chain commit to the correct upgraded (self) client state - // before the upgrade occurs, so that connecting chains can verify that the - // new upgraded client is valid by verifying a proof on the previous version - // of the chain. This will allow IBC connections to persist smoothly across - // planned chain upgrades. Correspondingly, the UpgradedClientState field has been - // deprecated in the Cosmos SDK to allow for this logic to exist solely in - // the 02-client module. - google.protobuf.Any upgraded_client_state = 2; - // signer address - string signer = 3; -} - -// MsgIBCSoftwareUpgradeResponse defines the Msg/IBCSoftwareUpgrade response type. -message MsgIBCSoftwareUpgradeResponse {} - -// MsgUpdateParams defines the sdk.Msg type to update the client parameters. -message MsgUpdateParams { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - // signer address - string signer = 1; - - // params defines the client parameters to update. - // - // NOTE: All parameters must be supplied. - Params params = 2 [(gogoproto.nullable) = false]; -} - -// MsgUpdateParamsResponse defines the MsgUpdateParams response type. -message MsgUpdateParamsResponse {} diff --git a/third_party/proto/ibc/commitment/v1/commitment.proto b/third_party/proto/ibc/commitment/v1/commitment.proto deleted file mode 100644 index b4753be2d..000000000 --- a/third_party/proto/ibc/commitment/v1/commitment.proto +++ /dev/null @@ -1,39 +0,0 @@ -syntax = "proto3"; - -package ibc.core.commitment.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types"; - -import "gogoproto/gogo.proto"; -import "cosmos/ics23/v1/proofs.proto"; - -// MerkleRoot defines a merkle root hash. -// In the Cosmos SDK, the AppHash of a block header becomes the root. -message MerkleRoot { - option (gogoproto.goproto_getters) = false; - - bytes hash = 1; -} - -// MerklePrefix is merkle path prefixed to the key. -// The constructed key from the Path and the key will be append(Path.KeyPath, -// append(Path.KeyPrefix, key...)) -message MerklePrefix { - bytes key_prefix = 1; -} - -// MerklePath is the path used to verify commitment proofs, which can be an -// arbitrary structured object (defined by a commitment type). -// MerklePath is represented from root-to-leaf -message MerklePath { - repeated string key_path = 1; -} - -// MerkleProof is a wrapper type over a chain of CommitmentProofs. -// It demonstrates membership or non-membership for an element or set of -// elements, verifiable in conjunction with a known commitment root. Proofs -// should be succinct. -// MerkleProofs are ordered from leaf-to-root -message MerkleProof { - repeated cosmos.ics23.v1.CommitmentProof proofs = 1; -} diff --git a/third_party/proto/ibc/connection/v1/connection.proto b/third_party/proto/ibc/connection/v1/connection.proto deleted file mode 100644 index 852f3999b..000000000 --- a/third_party/proto/ibc/connection/v1/connection.proto +++ /dev/null @@ -1,114 +0,0 @@ -syntax = "proto3"; - -package ibc.core.connection.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types"; - -import "gogoproto/gogo.proto"; -import "ibc/core/commitment/v1/commitment.proto"; - -// ICS03 - Connection Data Structures as defined in -// https://github.com/cosmos/ibc/blob/master/spec/core/ics-003-connection-semantics#data-structures - -// ConnectionEnd defines a stateful object on a chain connected to another -// separate one. -// NOTE: there must only be 2 defined ConnectionEnds to establish -// a connection between two chains. -message ConnectionEnd { - option (gogoproto.goproto_getters) = false; - // client associated with this connection. - string client_id = 1; - // IBC version which can be utilised to determine encodings or protocols for - // channels or packets utilising this connection. - repeated Version versions = 2; - // current state of the connection end. - State state = 3; - // counterparty chain associated with this connection. - Counterparty counterparty = 4 [(gogoproto.nullable) = false]; - // delay period that must pass before a consensus state can be used for - // packet-verification NOTE: delay period logic is only implemented by some - // clients. - uint64 delay_period = 5; -} - -// IdentifiedConnection defines a connection with additional connection -// identifier field. -message IdentifiedConnection { - option (gogoproto.goproto_getters) = false; - // connection identifier. - string id = 1; - // client associated with this connection. - string client_id = 2; - // IBC version which can be utilised to determine encodings or protocols for - // channels or packets utilising this connection - repeated Version versions = 3; - // current state of the connection end. - State state = 4; - // counterparty chain associated with this connection. - Counterparty counterparty = 5 [(gogoproto.nullable) = false]; - // delay period associated with this connection. - uint64 delay_period = 6; -} - -// State defines if a connection is in one of the following states: -// INIT, TRYOPEN, OPEN or UNINITIALIZED. -enum State { - option (gogoproto.goproto_enum_prefix) = false; - - // Default State - STATE_UNINITIALIZED_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNINITIALIZED"]; - // A connection end has just started the opening handshake. - STATE_INIT = 1 [(gogoproto.enumvalue_customname) = "INIT"]; - // A connection end has acknowledged the handshake step on the counterparty - // chain. - STATE_TRYOPEN = 2 [(gogoproto.enumvalue_customname) = "TRYOPEN"]; - // A connection end has completed the handshake. - STATE_OPEN = 3 [(gogoproto.enumvalue_customname) = "OPEN"]; -} - -// Counterparty defines the counterparty chain associated with a connection end. -message Counterparty { - option (gogoproto.goproto_getters) = false; - - // identifies the client on the counterparty chain associated with a given - // connection. - string client_id = 1; - // identifies the connection end on the counterparty chain associated with a - // given connection. - string connection_id = 2; - // commitment merkle prefix of the counterparty chain. - ibc.core.commitment.v1.MerklePrefix prefix = 3 [(gogoproto.nullable) = false]; -} - -// ClientPaths define all the connection paths for a client state. -message ClientPaths { - // list of connection paths - repeated string paths = 1; -} - -// ConnectionPaths define all the connection paths for a given client state. -message ConnectionPaths { - // client state unique identifier - string client_id = 1; - // list of connection paths - repeated string paths = 2; -} - -// Version defines the versioning scheme used to negotiate the IBC verison in -// the connection handshake. -message Version { - option (gogoproto.goproto_getters) = false; - - // unique version identifier - string identifier = 1; - // list of features compatible with the specified identifier - repeated string features = 2; -} - -// Params defines the set of Connection parameters. -message Params { - // maximum expected time per block (in nanoseconds), used to enforce block delay. This parameter should reflect the - // largest amount of time that the chain might reasonably take to produce the next block under normal operating - // conditions. A safe choice is 3-5x the expected time per block. - uint64 max_expected_time_per_block = 1; -} diff --git a/third_party/proto/ibc/connection/v1/genesis.proto b/third_party/proto/ibc/connection/v1/genesis.proto deleted file mode 100644 index a5eb6b3a1..000000000 --- a/third_party/proto/ibc/connection/v1/genesis.proto +++ /dev/null @@ -1,17 +0,0 @@ -syntax = "proto3"; - -package ibc.core.connection.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types"; - -import "gogoproto/gogo.proto"; -import "ibc/core/connection/v1/connection.proto"; - -// GenesisState defines the ibc connection submodule's genesis state. -message GenesisState { - repeated IdentifiedConnection connections = 1 [(gogoproto.nullable) = false]; - repeated ConnectionPaths client_connection_paths = 2 [(gogoproto.nullable) = false]; - // the sequence for the next generated connection identifier - uint64 next_connection_sequence = 3; - Params params = 4 [(gogoproto.nullable) = false]; -} diff --git a/third_party/proto/ibc/connection/v1/query.proto b/third_party/proto/ibc/connection/v1/query.proto deleted file mode 100644 index c0f1a6f57..000000000 --- a/third_party/proto/ibc/connection/v1/query.proto +++ /dev/null @@ -1,152 +0,0 @@ -syntax = "proto3"; - -package ibc.core.connection.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types"; - -import "gogoproto/gogo.proto"; -import "cosmos/base/query/v1beta1/pagination.proto"; -import "ibc/core/client/v1/client.proto"; -import "ibc/core/connection/v1/connection.proto"; -import "google/api/annotations.proto"; -import "google/protobuf/any.proto"; - -// Query provides defines the gRPC querier service -service Query { - // Connection queries an IBC connection end. - rpc Connection(QueryConnectionRequest) returns (QueryConnectionResponse) { - option (google.api.http).get = "/ibc/core/connection/v1/connections/{connection_id}"; - } - - // Connections queries all the IBC connections of a chain. - rpc Connections(QueryConnectionsRequest) returns (QueryConnectionsResponse) { - option (google.api.http).get = "/ibc/core/connection/v1/connections"; - } - - // ClientConnections queries the connection paths associated with a client - // state. - rpc ClientConnections(QueryClientConnectionsRequest) returns (QueryClientConnectionsResponse) { - option (google.api.http).get = "/ibc/core/connection/v1/client_connections/{client_id}"; - } - - // ConnectionClientState queries the client state associated with the - // connection. - rpc ConnectionClientState(QueryConnectionClientStateRequest) returns (QueryConnectionClientStateResponse) { - option (google.api.http).get = "/ibc/core/connection/v1/connections/{connection_id}/client_state"; - } - - // ConnectionConsensusState queries the consensus state associated with the - // connection. - rpc ConnectionConsensusState(QueryConnectionConsensusStateRequest) returns (QueryConnectionConsensusStateResponse) { - option (google.api.http).get = "/ibc/core/connection/v1/connections/{connection_id}/consensus_state/" - "revision/{revision_number}/height/{revision_height}"; - } - - // ConnectionParams queries all parameters of the ibc connection submodule. - rpc ConnectionParams(QueryConnectionParamsRequest) returns (QueryConnectionParamsResponse) { - option (google.api.http).get = "/ibc/core/connection/v1/params"; - } -} - -// QueryConnectionRequest is the request type for the Query/Connection RPC -// method -message QueryConnectionRequest { - // connection unique identifier - string connection_id = 1; -} - -// QueryConnectionResponse is the response type for the Query/Connection RPC -// method. Besides the connection end, it includes a proof and the height from -// which the proof was retrieved. -message QueryConnectionResponse { - // connection associated with the request identifier - ibc.core.connection.v1.ConnectionEnd connection = 1; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryConnectionsRequest is the request type for the Query/Connections RPC -// method -message QueryConnectionsRequest { - cosmos.base.query.v1beta1.PageRequest pagination = 1; -} - -// QueryConnectionsResponse is the response type for the Query/Connections RPC -// method. -message QueryConnectionsResponse { - // list of stored connections of the chain. - repeated ibc.core.connection.v1.IdentifiedConnection connections = 1; - // pagination response - cosmos.base.query.v1beta1.PageResponse pagination = 2; - // query block height - ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; -} - -// QueryClientConnectionsRequest is the request type for the -// Query/ClientConnections RPC method -message QueryClientConnectionsRequest { - // client identifier associated with a connection - string client_id = 1; -} - -// QueryClientConnectionsResponse is the response type for the -// Query/ClientConnections RPC method -message QueryClientConnectionsResponse { - // slice of all the connection paths associated with a client. - repeated string connection_paths = 1; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was generated - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryConnectionClientStateRequest is the request type for the -// Query/ConnectionClientState RPC method -message QueryConnectionClientStateRequest { - // connection identifier - string connection_id = 1; -} - -// QueryConnectionClientStateResponse is the response type for the -// Query/ConnectionClientState RPC method -message QueryConnectionClientStateResponse { - // client state associated with the channel - ibc.core.client.v1.IdentifiedClientState identified_client_state = 1; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryConnectionConsensusStateRequest is the request type for the -// Query/ConnectionConsensusState RPC method -message QueryConnectionConsensusStateRequest { - // connection identifier - string connection_id = 1; - uint64 revision_number = 2; - uint64 revision_height = 3; -} - -// QueryConnectionConsensusStateResponse is the response type for the -// Query/ConnectionConsensusState RPC method -message QueryConnectionConsensusStateResponse { - // consensus state associated with the channel - google.protobuf.Any consensus_state = 1; - // client ID associated with the consensus state - string client_id = 2; - // merkle proof of existence - bytes proof = 3; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; -} - -// QueryConnectionParamsRequest is the request type for the Query/ConnectionParams RPC method. -message QueryConnectionParamsRequest {} - -// QueryConnectionParamsResponse is the response type for the Query/ConnectionParams RPC method. -message QueryConnectionParamsResponse { - // params defines the parameters of the module. - Params params = 1; -} \ No newline at end of file diff --git a/third_party/proto/ibc/connection/v1/tx.proto b/third_party/proto/ibc/connection/v1/tx.proto deleted file mode 100644 index 3ba8ff456..000000000 --- a/third_party/proto/ibc/connection/v1/tx.proto +++ /dev/null @@ -1,146 +0,0 @@ -syntax = "proto3"; - -package ibc.core.connection.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types"; - -import "gogoproto/gogo.proto"; -import "cosmos/msg/v1/msg.proto"; -import "google/protobuf/any.proto"; -import "ibc/core/client/v1/client.proto"; -import "ibc/core/connection/v1/connection.proto"; - -// Msg defines the ibc/connection Msg service. -service Msg { - option (cosmos.msg.v1.service) = true; - - // ConnectionOpenInit defines a rpc handler method for MsgConnectionOpenInit. - rpc ConnectionOpenInit(MsgConnectionOpenInit) returns (MsgConnectionOpenInitResponse); - - // ConnectionOpenTry defines a rpc handler method for MsgConnectionOpenTry. - rpc ConnectionOpenTry(MsgConnectionOpenTry) returns (MsgConnectionOpenTryResponse); - - // ConnectionOpenAck defines a rpc handler method for MsgConnectionOpenAck. - rpc ConnectionOpenAck(MsgConnectionOpenAck) returns (MsgConnectionOpenAckResponse); - - // ConnectionOpenConfirm defines a rpc handler method for - // MsgConnectionOpenConfirm. - rpc ConnectionOpenConfirm(MsgConnectionOpenConfirm) returns (MsgConnectionOpenConfirmResponse); - - // UpdateConnectionParams defines a rpc handler method for - // MsgUpdateParams. - rpc UpdateConnectionParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); -} - -// MsgConnectionOpenInit defines the msg sent by an account on Chain A to -// initialize a connection with Chain B. -message MsgConnectionOpenInit { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - string client_id = 1; - Counterparty counterparty = 2 [(gogoproto.nullable) = false]; - Version version = 3; - uint64 delay_period = 4; - string signer = 5; -} - -// MsgConnectionOpenInitResponse defines the Msg/ConnectionOpenInit response -// type. -message MsgConnectionOpenInitResponse {} - -// MsgConnectionOpenTry defines a msg sent by a Relayer to try to open a -// connection on Chain B. -message MsgConnectionOpenTry { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - string client_id = 1; - // Deprecated: this field is unused. Crossing hellos are no longer supported in core IBC. - string previous_connection_id = 2 [deprecated = true]; - google.protobuf.Any client_state = 3; - Counterparty counterparty = 4 [(gogoproto.nullable) = false]; - uint64 delay_period = 5; - repeated Version counterparty_versions = 6; - ibc.core.client.v1.Height proof_height = 7 [(gogoproto.nullable) = false]; - // proof of the initialization the connection on Chain A: `UNITIALIZED -> - // INIT` - bytes proof_init = 8; - // proof of client state included in message - bytes proof_client = 9; - // proof of client consensus state - bytes proof_consensus = 10; - ibc.core.client.v1.Height consensus_height = 11 [(gogoproto.nullable) = false]; - string signer = 12; - // optional proof data for host state machines that are unable to introspect their own consensus state - bytes host_consensus_state_proof = 13; -} - -// MsgConnectionOpenTryResponse defines the Msg/ConnectionOpenTry response type. -message MsgConnectionOpenTryResponse {} - -// MsgConnectionOpenAck defines a msg sent by a Relayer to Chain A to -// acknowledge the change of connection state to TRYOPEN on Chain B. -message MsgConnectionOpenAck { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - string connection_id = 1; - string counterparty_connection_id = 2; - Version version = 3; - google.protobuf.Any client_state = 4; - ibc.core.client.v1.Height proof_height = 5 [(gogoproto.nullable) = false]; - // proof of the initialization the connection on Chain B: `UNITIALIZED -> - // TRYOPEN` - bytes proof_try = 6; - // proof of client state included in message - bytes proof_client = 7; - // proof of client consensus state - bytes proof_consensus = 8; - ibc.core.client.v1.Height consensus_height = 9 [(gogoproto.nullable) = false]; - string signer = 10; - // optional proof data for host state machines that are unable to introspect their own consensus state - bytes host_consensus_state_proof = 11; -} - -// MsgConnectionOpenAckResponse defines the Msg/ConnectionOpenAck response type. -message MsgConnectionOpenAckResponse {} - -// MsgConnectionOpenConfirm defines a msg sent by a Relayer to Chain B to -// acknowledge the change of connection state to OPEN on Chain A. -message MsgConnectionOpenConfirm { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - string connection_id = 1; - // proof for the change of the connection state on Chain A: `INIT -> OPEN` - bytes proof_ack = 2; - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; - string signer = 4; -} - -// MsgConnectionOpenConfirmResponse defines the Msg/ConnectionOpenConfirm -// response type. -message MsgConnectionOpenConfirmResponse {} - -// MsgUpdateParams defines the sdk.Msg type to update the connection parameters. -message MsgUpdateParams { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - // signer address - string signer = 1; - - // params defines the connection parameters to update. - // - // NOTE: All parameters must be supplied. - Params params = 2 [(gogoproto.nullable) = false]; -} - -// MsgUpdateParamsResponse defines the MsgUpdateParams response type. -message MsgUpdateParamsResponse {} \ No newline at end of file diff --git a/third_party/proto/ibc/core/client/v1/genesis.proto b/third_party/proto/ibc/core/client/v1/genesis.proto deleted file mode 100644 index 43610b0d4..000000000 --- a/third_party/proto/ibc/core/client/v1/genesis.proto +++ /dev/null @@ -1,44 +0,0 @@ -syntax = "proto3"; - -package ibc.core.client.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"; - -import "ibc/core/client/v1/client.proto"; -import "gogoproto/gogo.proto"; - -// GenesisState defines the ibc client submodule's genesis state. -message GenesisState { - // client states with their corresponding identifiers - repeated IdentifiedClientState clients = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "IdentifiedClientStates"]; - // consensus states from each client - repeated ClientConsensusStates clients_consensus = 2 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "ClientsConsensusStates"]; - // metadata from each client - repeated IdentifiedGenesisMetadata clients_metadata = 3 [(gogoproto.nullable) = false]; - Params params = 4 [(gogoproto.nullable) = false]; - // Deprecated: create_localhost has been deprecated. - // The localhost client is automatically created at genesis. - bool create_localhost = 5 [deprecated = true]; - // the sequence for the next generated client identifier - uint64 next_client_sequence = 6; -} - -// GenesisMetadata defines the genesis type for metadata that clients may return -// with ExportMetadata -message GenesisMetadata { - option (gogoproto.goproto_getters) = false; - - // store key of metadata without clientID-prefix - bytes key = 1; - // metadata value - bytes value = 2; -} - -// IdentifiedGenesisMetadata has the client metadata with the corresponding -// client id. -message IdentifiedGenesisMetadata { - string client_id = 1; - repeated GenesisMetadata client_metadata = 2 [(gogoproto.nullable) = false]; -} diff --git a/third_party/proto/ibc/core/client/v1/query.proto b/third_party/proto/ibc/core/client/v1/query.proto deleted file mode 100644 index 0032306ec..000000000 --- a/third_party/proto/ibc/core/client/v1/query.proto +++ /dev/null @@ -1,207 +0,0 @@ -syntax = "proto3"; - -package ibc.core.client.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"; - -import "cosmos/base/query/v1beta1/pagination.proto"; -import "ibc/core/client/v1/client.proto"; -import "google/protobuf/any.proto"; -import "google/api/annotations.proto"; -import "gogoproto/gogo.proto"; - -// Query provides defines the gRPC querier service -service Query { - // ClientState queries an IBC light client. - rpc ClientState(QueryClientStateRequest) returns (QueryClientStateResponse) { - option (google.api.http).get = "/ibc/core/client/v1/client_states/{client_id}"; - } - - // ClientStates queries all the IBC light clients of a chain. - rpc ClientStates(QueryClientStatesRequest) returns (QueryClientStatesResponse) { - option (google.api.http).get = "/ibc/core/client/v1/client_states"; - } - - // ConsensusState queries a consensus state associated with a client state at - // a given height. - rpc ConsensusState(QueryConsensusStateRequest) returns (QueryConsensusStateResponse) { - option (google.api.http).get = "/ibc/core/client/v1/consensus_states/" - "{client_id}/revision/{revision_number}/" - "height/{revision_height}"; - } - - // ConsensusStates queries all the consensus state associated with a given - // client. - rpc ConsensusStates(QueryConsensusStatesRequest) returns (QueryConsensusStatesResponse) { - option (google.api.http).get = "/ibc/core/client/v1/consensus_states/{client_id}"; - } - - // ConsensusStateHeights queries the height of every consensus states associated with a given client. - rpc ConsensusStateHeights(QueryConsensusStateHeightsRequest) returns (QueryConsensusStateHeightsResponse) { - option (google.api.http).get = "/ibc/core/client/v1/consensus_states/{client_id}/heights"; - } - - // Status queries the status of an IBC client. - rpc ClientStatus(QueryClientStatusRequest) returns (QueryClientStatusResponse) { - option (google.api.http).get = "/ibc/core/client/v1/client_status/{client_id}"; - } - - // ClientParams queries all parameters of the ibc client submodule. - rpc ClientParams(QueryClientParamsRequest) returns (QueryClientParamsResponse) { - option (google.api.http).get = "/ibc/core/client/v1/params"; - } - - // UpgradedClientState queries an Upgraded IBC light client. - rpc UpgradedClientState(QueryUpgradedClientStateRequest) returns (QueryUpgradedClientStateResponse) { - option (google.api.http).get = "/ibc/core/client/v1/upgraded_client_states"; - } - - // UpgradedConsensusState queries an Upgraded IBC consensus state. - rpc UpgradedConsensusState(QueryUpgradedConsensusStateRequest) returns (QueryUpgradedConsensusStateResponse) { - option (google.api.http).get = "/ibc/core/client/v1/upgraded_consensus_states"; - } -} - -// QueryClientStateRequest is the request type for the Query/ClientState RPC -// method -message QueryClientStateRequest { - // client state unique identifier - string client_id = 1; -} - -// QueryClientStateResponse is the response type for the Query/ClientState RPC -// method. Besides the client state, it includes a proof and the height from -// which the proof was retrieved. -message QueryClientStateResponse { - // client state associated with the request identifier - google.protobuf.Any client_state = 1; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryClientStatesRequest is the request type for the Query/ClientStates RPC -// method -message QueryClientStatesRequest { - // pagination request - cosmos.base.query.v1beta1.PageRequest pagination = 1; -} - -// QueryClientStatesResponse is the response type for the Query/ClientStates RPC -// method. -message QueryClientStatesResponse { - // list of stored ClientStates of the chain. - repeated IdentifiedClientState client_states = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "IdentifiedClientStates"]; - // pagination response - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryConsensusStateRequest is the request type for the Query/ConsensusState -// RPC method. Besides the consensus state, it includes a proof and the height -// from which the proof was retrieved. -message QueryConsensusStateRequest { - // client identifier - string client_id = 1; - // consensus state revision number - uint64 revision_number = 2; - // consensus state revision height - uint64 revision_height = 3; - // latest_height overrrides the height field and queries the latest stored - // ConsensusState - bool latest_height = 4; -} - -// QueryConsensusStateResponse is the response type for the Query/ConsensusState -// RPC method -message QueryConsensusStateResponse { - // consensus state associated with the client identifier at the given height - google.protobuf.Any consensus_state = 1; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryConsensusStatesRequest is the request type for the Query/ConsensusStates -// RPC method. -message QueryConsensusStatesRequest { - // client identifier - string client_id = 1; - // pagination request - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryConsensusStatesResponse is the response type for the -// Query/ConsensusStates RPC method -message QueryConsensusStatesResponse { - // consensus states associated with the identifier - repeated ConsensusStateWithHeight consensus_states = 1 [(gogoproto.nullable) = false]; - // pagination response - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryConsensusStateHeightsRequest is the request type for Query/ConsensusStateHeights -// RPC method. -message QueryConsensusStateHeightsRequest { - // client identifier - string client_id = 1; - // pagination request - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryConsensusStateHeightsResponse is the response type for the -// Query/ConsensusStateHeights RPC method -message QueryConsensusStateHeightsResponse { - // consensus state heights - repeated Height consensus_state_heights = 1 [(gogoproto.nullable) = false]; - // pagination response - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryClientStatusRequest is the request type for the Query/ClientStatus RPC -// method -message QueryClientStatusRequest { - // client unique identifier - string client_id = 1; -} - -// QueryClientStatusResponse is the response type for the Query/ClientStatus RPC -// method. It returns the current status of the IBC client. -message QueryClientStatusResponse { - string status = 1; -} - -// QueryClientParamsRequest is the request type for the Query/ClientParams RPC -// method. -message QueryClientParamsRequest {} - -// QueryClientParamsResponse is the response type for the Query/ClientParams RPC -// method. -message QueryClientParamsResponse { - // params defines the parameters of the module. - Params params = 1; -} - -// QueryUpgradedClientStateRequest is the request type for the -// Query/UpgradedClientState RPC method -message QueryUpgradedClientStateRequest {} - -// QueryUpgradedClientStateResponse is the response type for the -// Query/UpgradedClientState RPC method. -message QueryUpgradedClientStateResponse { - // client state associated with the request identifier - google.protobuf.Any upgraded_client_state = 1; -} - -// QueryUpgradedConsensusStateRequest is the request type for the -// Query/UpgradedConsensusState RPC method -message QueryUpgradedConsensusStateRequest {} - -// QueryUpgradedConsensusStateResponse is the response type for the -// Query/UpgradedConsensusState RPC method. -message QueryUpgradedConsensusStateResponse { - // Consensus state associated with the request identifier - google.protobuf.Any upgraded_consensus_state = 1; -} diff --git a/third_party/proto/ibc/core/client/v1/tx.proto b/third_party/proto/ibc/core/client/v1/tx.proto deleted file mode 100644 index b504ab692..000000000 --- a/third_party/proto/ibc/core/client/v1/tx.proto +++ /dev/null @@ -1,175 +0,0 @@ -syntax = "proto3"; - -package ibc.core.client.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"; - -import "cosmos/msg/v1/msg.proto"; -import "cosmos/upgrade/v1beta1/upgrade.proto"; -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; -import "ibc/core/client/v1/client.proto"; - -// Msg defines the ibc/client Msg service. -service Msg { - option (cosmos.msg.v1.service) = true; - - // CreateClient defines a rpc handler method for MsgCreateClient. - rpc CreateClient(MsgCreateClient) returns (MsgCreateClientResponse); - - // UpdateClient defines a rpc handler method for MsgUpdateClient. - rpc UpdateClient(MsgUpdateClient) returns (MsgUpdateClientResponse); - - // UpgradeClient defines a rpc handler method for MsgUpgradeClient. - rpc UpgradeClient(MsgUpgradeClient) returns (MsgUpgradeClientResponse); - - // SubmitMisbehaviour defines a rpc handler method for MsgSubmitMisbehaviour. - rpc SubmitMisbehaviour(MsgSubmitMisbehaviour) returns (MsgSubmitMisbehaviourResponse); - - // RecoverClient defines a rpc handler method for MsgRecoverClient. - rpc RecoverClient(MsgRecoverClient) returns (MsgRecoverClientResponse); - - // IBCSoftwareUpgrade defines a rpc handler method for MsgIBCSoftwareUpgrade. - rpc IBCSoftwareUpgrade(MsgIBCSoftwareUpgrade) returns (MsgIBCSoftwareUpgradeResponse); - - // UpdateClientParams defines a rpc handler method for MsgUpdateParams. - rpc UpdateClientParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); -} - -// MsgCreateClient defines a message to create an IBC client -message MsgCreateClient { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - // light client state - google.protobuf.Any client_state = 1; - // consensus state associated with the client that corresponds to a given - // height. - google.protobuf.Any consensus_state = 2; - // signer address - string signer = 3; -} - -// MsgCreateClientResponse defines the Msg/CreateClient response type. -message MsgCreateClientResponse {} - -// MsgUpdateClient defines an sdk.Msg to update a IBC client state using -// the given client message. -message MsgUpdateClient { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - // client unique identifier - string client_id = 1; - // client message to update the light client - google.protobuf.Any client_message = 2; - // signer address - string signer = 3; -} - -// MsgUpdateClientResponse defines the Msg/UpdateClient response type. -message MsgUpdateClientResponse {} - -// MsgUpgradeClient defines an sdk.Msg to upgrade an IBC client to a new client -// state -message MsgUpgradeClient { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - // client unique identifier - string client_id = 1; - // upgraded client state - google.protobuf.Any client_state = 2; - // upgraded consensus state, only contains enough information to serve as a - // basis of trust in update logic - google.protobuf.Any consensus_state = 3; - // proof that old chain committed to new client - bytes proof_upgrade_client = 4; - // proof that old chain committed to new consensus state - bytes proof_upgrade_consensus_state = 5; - // signer address - string signer = 6; -} - -// MsgUpgradeClientResponse defines the Msg/UpgradeClient response type. -message MsgUpgradeClientResponse {} - -// MsgSubmitMisbehaviour defines an sdk.Msg type that submits Evidence for -// light client misbehaviour. -// This message has been deprecated. Use MsgUpdateClient instead. -message MsgSubmitMisbehaviour { - option deprecated = true; - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - // client unique identifier - string client_id = 1; - // misbehaviour used for freezing the light client - google.protobuf.Any misbehaviour = 2; - // signer address - string signer = 3; -} - -// MsgSubmitMisbehaviourResponse defines the Msg/SubmitMisbehaviour response -// type. -message MsgSubmitMisbehaviourResponse {} - -// MsgRecoverClient defines the message used to recover a frozen or expired client. -message MsgRecoverClient { - option (gogoproto.goproto_getters) = false; - option (cosmos.msg.v1.signer) = "signer"; - - // the client identifier for the client to be updated if the proposal passes - string subject_client_id = 1; - // the substitute client identifier for the client which will replace the subject - // client - string substitute_client_id = 2; - - // signer address - string signer = 3; -} - -// MsgRecoverClientResponse defines the Msg/RecoverClient response type. -message MsgRecoverClientResponse {} - -// MsgIBCSoftwareUpgrade defines the message used to schedule an upgrade of an IBC client using a v1 governance proposal -message MsgIBCSoftwareUpgrade { - option (cosmos.msg.v1.signer) = "signer"; - cosmos.upgrade.v1beta1.Plan plan = 1 [(gogoproto.nullable) = false]; - // An UpgradedClientState must be provided to perform an IBC breaking upgrade. - // This will make the chain commit to the correct upgraded (self) client state - // before the upgrade occurs, so that connecting chains can verify that the - // new upgraded client is valid by verifying a proof on the previous version - // of the chain. This will allow IBC connections to persist smoothly across - // planned chain upgrades. Correspondingly, the UpgradedClientState field has been - // deprecated in the Cosmos SDK to allow for this logic to exist solely in - // the 02-client module. - google.protobuf.Any upgraded_client_state = 2; - // signer address - string signer = 3; -} - -// MsgIBCSoftwareUpgradeResponse defines the Msg/IBCSoftwareUpgrade response type. -message MsgIBCSoftwareUpgradeResponse {} - -// MsgUpdateParams defines the sdk.Msg type to update the client parameters. -message MsgUpdateParams { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - // signer address - string signer = 1; - - // params defines the client parameters to update. - // - // NOTE: All parameters must be supplied. - Params params = 2 [(gogoproto.nullable) = false]; -} - -// MsgUpdateParamsResponse defines the MsgUpdateParams response type. -message MsgUpdateParamsResponse {} diff --git a/third_party/proto/ibc/core/commitment/v1/commitment.proto b/third_party/proto/ibc/core/commitment/v1/commitment.proto deleted file mode 100644 index b4753be2d..000000000 --- a/third_party/proto/ibc/core/commitment/v1/commitment.proto +++ /dev/null @@ -1,39 +0,0 @@ -syntax = "proto3"; - -package ibc.core.commitment.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types"; - -import "gogoproto/gogo.proto"; -import "cosmos/ics23/v1/proofs.proto"; - -// MerkleRoot defines a merkle root hash. -// In the Cosmos SDK, the AppHash of a block header becomes the root. -message MerkleRoot { - option (gogoproto.goproto_getters) = false; - - bytes hash = 1; -} - -// MerklePrefix is merkle path prefixed to the key. -// The constructed key from the Path and the key will be append(Path.KeyPath, -// append(Path.KeyPrefix, key...)) -message MerklePrefix { - bytes key_prefix = 1; -} - -// MerklePath is the path used to verify commitment proofs, which can be an -// arbitrary structured object (defined by a commitment type). -// MerklePath is represented from root-to-leaf -message MerklePath { - repeated string key_path = 1; -} - -// MerkleProof is a wrapper type over a chain of CommitmentProofs. -// It demonstrates membership or non-membership for an element or set of -// elements, verifiable in conjunction with a known commitment root. Proofs -// should be succinct. -// MerkleProofs are ordered from leaf-to-root -message MerkleProof { - repeated cosmos.ics23.v1.CommitmentProof proofs = 1; -} diff --git a/third_party/proto/ibc/fee/v1/ack.proto b/third_party/proto/ibc/fee/v1/ack.proto deleted file mode 100644 index 2f3746d2c..000000000 --- a/third_party/proto/ibc/fee/v1/ack.proto +++ /dev/null @@ -1,15 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.fee.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"; - -// IncentivizedAcknowledgement is the acknowledgement format to be used by applications wrapped in the fee middleware -message IncentivizedAcknowledgement { - // the underlying app acknowledgement bytes - bytes app_acknowledgement = 1; - // the relayer address which submits the recv packet message - string forward_relayer_address = 2; - // success flag of the base application callback - bool underlying_app_success = 3; -} diff --git a/third_party/proto/ibc/fee/v1/fee.proto b/third_party/proto/ibc/fee/v1/fee.proto deleted file mode 100644 index 867e88455..000000000 --- a/third_party/proto/ibc/fee/v1/fee.proto +++ /dev/null @@ -1,61 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.fee.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"; - -import "amino/amino.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "gogoproto/gogo.proto"; -import "ibc/core/channel/v1/channel.proto"; -import "cosmos/msg/v1/msg.proto"; - -// Fee defines the ICS29 receive, acknowledgement and timeout fees -message Fee { - // the packet receive fee - repeated cosmos.base.v1beta1.Coin recv_fee = 1 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (amino.encoding) = "legacy_coins" - ]; - - // the packet acknowledgement fee - repeated cosmos.base.v1beta1.Coin ack_fee = 2 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (amino.encoding) = "legacy_coins" - ]; - - // the packet timeout fee - repeated cosmos.base.v1beta1.Coin timeout_fee = 3 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (amino.encoding) = "legacy_coins" - ]; -} - -// PacketFee contains ICS29 relayer fees, refund address and optional list of permitted relayers -message PacketFee { - option (cosmos.msg.v1.signer) = "refund_address"; - - // fee encapsulates the recv, ack and timeout fees associated with an IBC packet - Fee fee = 1 [(gogoproto.nullable) = false]; - // the refund address for unspent fees - string refund_address = 2; - // optional list of relayers permitted to receive fees - repeated string relayers = 3; -} - -// PacketFees contains a list of type PacketFee -message PacketFees { - // list of packet fees - repeated PacketFee packet_fees = 1 [(gogoproto.nullable) = false]; -} - -// IdentifiedPacketFees contains a list of type PacketFee and associated PacketId -message IdentifiedPacketFees { - // unique packet identifier comprised of the channel ID, port ID and sequence - ibc.core.channel.v1.PacketId packet_id = 1 [(gogoproto.nullable) = false]; - // list of packet fees - repeated PacketFee packet_fees = 2 [(gogoproto.nullable) = false]; -} diff --git a/third_party/proto/ibc/fee/v1/genesis.proto b/third_party/proto/ibc/fee/v1/genesis.proto deleted file mode 100644 index e48ceb535..000000000 --- a/third_party/proto/ibc/fee/v1/genesis.proto +++ /dev/null @@ -1,60 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.fee.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"; - -import "gogoproto/gogo.proto"; -import "ibc/applications/fee/v1/fee.proto"; -import "ibc/core/channel/v1/channel.proto"; - -// GenesisState defines the ICS29 fee middleware genesis state -message GenesisState { - // list of identified packet fees - repeated IdentifiedPacketFees identified_fees = 1 [(gogoproto.nullable) = false]; - // list of fee enabled channels - repeated FeeEnabledChannel fee_enabled_channels = 2 [(gogoproto.nullable) = false]; - // list of registered payees - repeated RegisteredPayee registered_payees = 3 [(gogoproto.nullable) = false]; - // list of registered counterparty payees - repeated RegisteredCounterpartyPayee registered_counterparty_payees = 4 [(gogoproto.nullable) = false]; - // list of forward relayer addresses - repeated ForwardRelayerAddress forward_relayers = 5 [(gogoproto.nullable) = false]; -} - -// FeeEnabledChannel contains the PortID & ChannelID for a fee enabled channel -message FeeEnabledChannel { - // unique port identifier - string port_id = 1; - // unique channel identifier - string channel_id = 2; -} - -// RegisteredPayee contains the relayer address and payee address for a specific channel -message RegisteredPayee { - // unique channel identifier - string channel_id = 1; - // the relayer address - string relayer = 2; - // the payee address - string payee = 3; -} - -// RegisteredCounterpartyPayee contains the relayer address and counterparty payee address for a specific channel (used -// for recv fee distribution) -message RegisteredCounterpartyPayee { - // unique channel identifier - string channel_id = 1; - // the relayer address - string relayer = 2; - // the counterparty payee address - string counterparty_payee = 3; -} - -// ForwardRelayerAddress contains the forward relayer address and PacketId used for async acknowledgements -message ForwardRelayerAddress { - // the forward relayer address - string address = 1; - // unique packet identifer comprised of the channel ID, port ID and sequence - ibc.core.channel.v1.PacketId packet_id = 2 [(gogoproto.nullable) = false]; -} diff --git a/third_party/proto/ibc/fee/v1/metadata.proto b/third_party/proto/ibc/fee/v1/metadata.proto deleted file mode 100644 index 1e82e7c25..000000000 --- a/third_party/proto/ibc/fee/v1/metadata.proto +++ /dev/null @@ -1,14 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.fee.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"; - -// Metadata defines the ICS29 channel specific metadata encoded into the channel version bytestring -// See ICS004: https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#Versioning -message Metadata { - // fee_version defines the ICS29 fee version - string fee_version = 1; - // app_version defines the underlying application version, which may or may not be a JSON encoded bytestring - string app_version = 2; -} diff --git a/third_party/proto/ibc/fee/v1/query.proto b/third_party/proto/ibc/fee/v1/query.proto deleted file mode 100644 index 726370ee0..000000000 --- a/third_party/proto/ibc/fee/v1/query.proto +++ /dev/null @@ -1,218 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.fee.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"; - -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "cosmos/base/query/v1beta1/pagination.proto"; -import "ibc/applications/fee/v1/fee.proto"; -import "ibc/applications/fee/v1/genesis.proto"; -import "ibc/core/channel/v1/channel.proto"; - -// Query defines the ICS29 gRPC querier service. -service Query { - // IncentivizedPackets returns all incentivized packets and their associated fees - rpc IncentivizedPackets(QueryIncentivizedPacketsRequest) returns (QueryIncentivizedPacketsResponse) { - option (google.api.http).get = "/ibc/apps/fee/v1/incentivized_packets"; - } - - // IncentivizedPacket returns all packet fees for a packet given its identifier - rpc IncentivizedPacket(QueryIncentivizedPacketRequest) returns (QueryIncentivizedPacketResponse) { - option (google.api.http).get = - "/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/sequences/" - "{packet_id.sequence}/incentivized_packet"; - } - - // Gets all incentivized packets for a specific channel - rpc IncentivizedPacketsForChannel(QueryIncentivizedPacketsForChannelRequest) - returns (QueryIncentivizedPacketsForChannelResponse) { - option (google.api.http).get = "/ibc/apps/fee/v1/channels/{channel_id}/ports/{port_id}/incentivized_packets"; - } - - // TotalRecvFees returns the total receive fees for a packet given its identifier - rpc TotalRecvFees(QueryTotalRecvFeesRequest) returns (QueryTotalRecvFeesResponse) { - option (google.api.http).get = "/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/" - "sequences/{packet_id.sequence}/total_recv_fees"; - } - - // TotalAckFees returns the total acknowledgement fees for a packet given its identifier - rpc TotalAckFees(QueryTotalAckFeesRequest) returns (QueryTotalAckFeesResponse) { - option (google.api.http).get = "/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/" - "sequences/{packet_id.sequence}/total_ack_fees"; - } - - // TotalTimeoutFees returns the total timeout fees for a packet given its identifier - rpc TotalTimeoutFees(QueryTotalTimeoutFeesRequest) returns (QueryTotalTimeoutFeesResponse) { - option (google.api.http).get = "/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/" - "sequences/{packet_id.sequence}/total_timeout_fees"; - } - - // Payee returns the registered payee address for a specific channel given the relayer address - rpc Payee(QueryPayeeRequest) returns (QueryPayeeResponse) { - option (google.api.http).get = "/ibc/apps/fee/v1/channels/{channel_id}/relayers/{relayer}/payee"; - } - - // CounterpartyPayee returns the registered counterparty payee for forward relaying - rpc CounterpartyPayee(QueryCounterpartyPayeeRequest) returns (QueryCounterpartyPayeeResponse) { - option (google.api.http).get = "/ibc/apps/fee/v1/channels/{channel_id}/relayers/{relayer}/counterparty_payee"; - } - - // FeeEnabledChannels returns a list of all fee enabled channels - rpc FeeEnabledChannels(QueryFeeEnabledChannelsRequest) returns (QueryFeeEnabledChannelsResponse) { - option (google.api.http).get = "/ibc/apps/fee/v1/fee_enabled"; - } - - // FeeEnabledChannel returns true if the provided port and channel identifiers belong to a fee enabled channel - rpc FeeEnabledChannel(QueryFeeEnabledChannelRequest) returns (QueryFeeEnabledChannelResponse) { - option (google.api.http).get = "/ibc/apps/fee/v1/channels/{channel_id}/ports/{port_id}/fee_enabled"; - } -} - -// QueryIncentivizedPacketsRequest defines the request type for the IncentivizedPackets rpc -message QueryIncentivizedPacketsRequest { - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 1; - // block height at which to query - uint64 query_height = 2; -} - -// QueryIncentivizedPacketsResponse defines the response type for the IncentivizedPackets rpc -message QueryIncentivizedPacketsResponse { - // list of identified fees for incentivized packets - repeated ibc.applications.fee.v1.IdentifiedPacketFees incentivized_packets = 1 [(gogoproto.nullable) = false]; - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryIncentivizedPacketRequest defines the request type for the IncentivizedPacket rpc -message QueryIncentivizedPacketRequest { - // unique packet identifier comprised of channel ID, port ID and sequence - ibc.core.channel.v1.PacketId packet_id = 1 [(gogoproto.nullable) = false]; - // block height at which to query - uint64 query_height = 2; -} - -// QueryIncentivizedPacketsResponse defines the response type for the IncentivizedPacket rpc -message QueryIncentivizedPacketResponse { - // the identified fees for the incentivized packet - ibc.applications.fee.v1.IdentifiedPacketFees incentivized_packet = 1 [(gogoproto.nullable) = false]; -} - -// QueryIncentivizedPacketsForChannelRequest defines the request type for querying for all incentivized packets -// for a specific channel -message QueryIncentivizedPacketsForChannelRequest { - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 1; - string port_id = 2; - string channel_id = 3; - // Height to query at - uint64 query_height = 4; -} - -// QueryIncentivizedPacketsResponse defines the response type for the incentivized packets RPC -message QueryIncentivizedPacketsForChannelResponse { - // Map of all incentivized_packets - repeated ibc.applications.fee.v1.IdentifiedPacketFees incentivized_packets = 1; - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryTotalRecvFeesRequest defines the request type for the TotalRecvFees rpc -message QueryTotalRecvFeesRequest { - // the packet identifier for the associated fees - ibc.core.channel.v1.PacketId packet_id = 1 [(gogoproto.nullable) = false]; -} - -// QueryTotalRecvFeesResponse defines the response type for the TotalRecvFees rpc -message QueryTotalRecvFeesResponse { - // the total packet receive fees - repeated cosmos.base.v1beta1.Coin recv_fees = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; -} - -// QueryTotalAckFeesRequest defines the request type for the TotalAckFees rpc -message QueryTotalAckFeesRequest { - // the packet identifier for the associated fees - ibc.core.channel.v1.PacketId packet_id = 1 [(gogoproto.nullable) = false]; -} - -// QueryTotalAckFeesResponse defines the response type for the TotalAckFees rpc -message QueryTotalAckFeesResponse { - // the total packet acknowledgement fees - repeated cosmos.base.v1beta1.Coin ack_fees = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; -} - -// QueryTotalTimeoutFeesRequest defines the request type for the TotalTimeoutFees rpc -message QueryTotalTimeoutFeesRequest { - // the packet identifier for the associated fees - ibc.core.channel.v1.PacketId packet_id = 1 [(gogoproto.nullable) = false]; -} - -// QueryTotalTimeoutFeesResponse defines the response type for the TotalTimeoutFees rpc -message QueryTotalTimeoutFeesResponse { - // the total packet timeout fees - repeated cosmos.base.v1beta1.Coin timeout_fees = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; -} - -// QueryPayeeRequest defines the request type for the Payee rpc -message QueryPayeeRequest { - // unique channel identifier - string channel_id = 1; - // the relayer address to which the distribution address is registered - string relayer = 2; -} - -// QueryPayeeResponse defines the response type for the Payee rpc -message QueryPayeeResponse { - // the payee address to which packet fees are paid out - string payee_address = 1; -} - -// QueryCounterpartyPayeeRequest defines the request type for the CounterpartyPayee rpc -message QueryCounterpartyPayeeRequest { - // unique channel identifier - string channel_id = 1; - // the relayer address to which the counterparty is registered - string relayer = 2; -} - -// QueryCounterpartyPayeeResponse defines the response type for the CounterpartyPayee rpc -message QueryCounterpartyPayeeResponse { - // the counterparty payee address used to compensate forward relaying - string counterparty_payee = 1; -} - -// QueryFeeEnabledChannelsRequest defines the request type for the FeeEnabledChannels rpc -message QueryFeeEnabledChannelsRequest { - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 1; - // block height at which to query - uint64 query_height = 2; -} - -// QueryFeeEnabledChannelsResponse defines the response type for the FeeEnabledChannels rpc -message QueryFeeEnabledChannelsResponse { - // list of fee enabled channels - repeated ibc.applications.fee.v1.FeeEnabledChannel fee_enabled_channels = 1 [(gogoproto.nullable) = false]; - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryFeeEnabledChannelRequest defines the request type for the FeeEnabledChannel rpc -message QueryFeeEnabledChannelRequest { - // unique port identifier - string port_id = 1; - // unique channel identifier - string channel_id = 2; -} - -// QueryFeeEnabledChannelResponse defines the response type for the FeeEnabledChannel rpc -message QueryFeeEnabledChannelResponse { - // boolean flag representing the fee enabled channel status - bool fee_enabled = 1; -} diff --git a/third_party/proto/ibc/fee/v1/tx.proto b/third_party/proto/ibc/fee/v1/tx.proto deleted file mode 100644 index e59dddfd1..000000000 --- a/third_party/proto/ibc/fee/v1/tx.proto +++ /dev/null @@ -1,122 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.fee.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"; - -import "amino/amino.proto"; -import "gogoproto/gogo.proto"; -import "ibc/applications/fee/v1/fee.proto"; -import "ibc/core/channel/v1/channel.proto"; -import "cosmos/msg/v1/msg.proto"; - -// Msg defines the ICS29 Msg service. -service Msg { - option (cosmos.msg.v1.service) = true; - - // RegisterPayee defines a rpc handler method for MsgRegisterPayee - // RegisterPayee is called by the relayer on each channelEnd and allows them to set an optional - // payee to which reverse and timeout relayer packet fees will be paid out. The payee should be registered on - // the source chain from which packets originate as this is where fee distribution takes place. This function may be - // called more than once by a relayer, in which case, the latest payee is always used. - rpc RegisterPayee(MsgRegisterPayee) returns (MsgRegisterPayeeResponse); - - // RegisterCounterpartyPayee defines a rpc handler method for MsgRegisterCounterpartyPayee - // RegisterCounterpartyPayee is called by the relayer on each channelEnd and allows them to specify the counterparty - // payee address before relaying. This ensures they will be properly compensated for forward relaying since - // the destination chain must include the registered counterparty payee address in the acknowledgement. This function - // may be called more than once by a relayer, in which case, the latest counterparty payee address is always used. - rpc RegisterCounterpartyPayee(MsgRegisterCounterpartyPayee) returns (MsgRegisterCounterpartyPayeeResponse); - - // PayPacketFee defines a rpc handler method for MsgPayPacketFee - // PayPacketFee is an open callback that may be called by any module/user that wishes to escrow funds in order to - // incentivize the relaying of the packet at the next sequence - // NOTE: This method is intended to be used within a multi msg transaction, where the subsequent msg that follows - // initiates the lifecycle of the incentivized packet - rpc PayPacketFee(MsgPayPacketFee) returns (MsgPayPacketFeeResponse); - - // PayPacketFeeAsync defines a rpc handler method for MsgPayPacketFeeAsync - // PayPacketFeeAsync is an open callback that may be called by any module/user that wishes to escrow funds in order to - // incentivize the relaying of a known packet (i.e. at a particular sequence) - rpc PayPacketFeeAsync(MsgPayPacketFeeAsync) returns (MsgPayPacketFeeAsyncResponse); -} - -// MsgRegisterPayee defines the request type for the RegisterPayee rpc -message MsgRegisterPayee { - option (amino.name) = "cosmos-sdk/MsgRegisterPayee"; - option (cosmos.msg.v1.signer) = "relayer"; - - option (gogoproto.goproto_getters) = false; - - // unique port identifier - string port_id = 1; - // unique channel identifier - string channel_id = 2; - // the relayer address - string relayer = 3; - // the payee address - string payee = 4; -} - -// MsgRegisterPayeeResponse defines the response type for the RegisterPayee rpc -message MsgRegisterPayeeResponse {} - -// MsgRegisterCounterpartyPayee defines the request type for the RegisterCounterpartyPayee rpc -message MsgRegisterCounterpartyPayee { - option (amino.name) = "cosmos-sdk/MsgRegisterCounterpartyPayee"; - option (cosmos.msg.v1.signer) = "relayer"; - - option (gogoproto.goproto_getters) = false; - - // unique port identifier - string port_id = 1; - // unique channel identifier - string channel_id = 2; - // the relayer address - string relayer = 3; - // the counterparty payee address - string counterparty_payee = 4; -} - -// MsgRegisterCounterpartyPayeeResponse defines the response type for the RegisterCounterpartyPayee rpc -message MsgRegisterCounterpartyPayeeResponse {} - -// MsgPayPacketFee defines the request type for the PayPacketFee rpc -// This Msg can be used to pay for a packet at the next sequence send & should be combined with the Msg that will be -// paid for -message MsgPayPacketFee { - option (amino.name) = "cosmos-sdk/MsgPayPacketFee"; - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - // fee encapsulates the recv, ack and timeout fees associated with an IBC packet - ibc.applications.fee.v1.Fee fee = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; - // the source port unique identifier - string source_port_id = 2; - // the source channel unique identifer - string source_channel_id = 3; - // account address to refund fee if necessary - string signer = 4; - // optional list of relayers permitted to the receive packet fees - repeated string relayers = 5; -} - -// MsgPayPacketFeeResponse defines the response type for the PayPacketFee rpc -message MsgPayPacketFeeResponse {} - -// MsgPayPacketFeeAsync defines the request type for the PayPacketFeeAsync rpc -// This Msg can be used to pay for a packet at a specified sequence (instead of the next sequence send) -message MsgPayPacketFeeAsync { - option (amino.name) = "cosmos-sdk/MsgPayPacketFeeAsync"; - option (cosmos.msg.v1.signer) = "packet_fee"; - option (gogoproto.goproto_getters) = false; - - // unique packet identifier comprised of the channel ID, port ID and sequence - ibc.core.channel.v1.PacketId packet_id = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; - // the packet fee associated with a particular IBC packet - PacketFee packet_fee = 2 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; -} - -// MsgPayPacketFeeAsyncResponse defines the response type for the PayPacketFeeAsync rpc -message MsgPayPacketFeeAsyncResponse {} diff --git a/third_party/proto/ibc/interchain_accounts/controller/v1/controller.proto b/third_party/proto/ibc/interchain_accounts/controller/v1/controller.proto deleted file mode 100644 index 2e6bbe1a1..000000000 --- a/third_party/proto/ibc/interchain_accounts/controller/v1/controller.proto +++ /dev/null @@ -1,12 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.interchain_accounts.controller.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types"; - -// Params defines the set of on-chain interchain accounts parameters. -// The following parameters may be used to disable the controller submodule. -message Params { - // controller_enabled enables or disables the controller submodule. - bool controller_enabled = 1; -} diff --git a/third_party/proto/ibc/interchain_accounts/controller/v1/query.proto b/third_party/proto/ibc/interchain_accounts/controller/v1/query.proto deleted file mode 100644 index 31885fcb2..000000000 --- a/third_party/proto/ibc/interchain_accounts/controller/v1/query.proto +++ /dev/null @@ -1,42 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.interchain_accounts.controller.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types"; - -import "ibc/applications/interchain_accounts/controller/v1/controller.proto"; -import "google/api/annotations.proto"; - -// Query provides defines the gRPC querier service. -service Query { - // InterchainAccount returns the interchain account address for a given owner address on a given connection - rpc InterchainAccount(QueryInterchainAccountRequest) returns (QueryInterchainAccountResponse) { - option (google.api.http).get = - "/ibc/apps/interchain_accounts/controller/v1/owners/{owner}/connections/{connection_id}"; - } - - // Params queries all parameters of the ICA controller submodule. - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/ibc/apps/interchain_accounts/controller/v1/params"; - } -} - -// QueryInterchainAccountRequest is the request type for the Query/InterchainAccount RPC method. -message QueryInterchainAccountRequest { - string owner = 1; - string connection_id = 2; -} - -// QueryInterchainAccountResponse the response type for the Query/InterchainAccount RPC method. -message QueryInterchainAccountResponse { - string address = 1; -} - -// QueryParamsRequest is the request type for the Query/Params RPC method. -message QueryParamsRequest {} - -// QueryParamsResponse is the response type for the Query/Params RPC method. -message QueryParamsResponse { - // params defines the parameters of the module. - Params params = 1; -} diff --git a/third_party/proto/ibc/interchain_accounts/controller/v1/tx.proto b/third_party/proto/ibc/interchain_accounts/controller/v1/tx.proto deleted file mode 100644 index ec5c2e62e..000000000 --- a/third_party/proto/ibc/interchain_accounts/controller/v1/tx.proto +++ /dev/null @@ -1,82 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.interchain_accounts.controller.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types"; - -import "gogoproto/gogo.proto"; -import "ibc/applications/interchain_accounts/v1/packet.proto"; -import "ibc/applications/interchain_accounts/controller/v1/controller.proto"; -import "cosmos/msg/v1/msg.proto"; -import "ibc/core/channel/v1/channel.proto"; - -// Msg defines the 27-interchain-accounts/controller Msg service. -service Msg { - option (cosmos.msg.v1.service) = true; - - // RegisterInterchainAccount defines a rpc handler for MsgRegisterInterchainAccount. - rpc RegisterInterchainAccount(MsgRegisterInterchainAccount) returns (MsgRegisterInterchainAccountResponse); - // SendTx defines a rpc handler for MsgSendTx. - rpc SendTx(MsgSendTx) returns (MsgSendTxResponse); - // UpdateParams defines a rpc handler for MsgUpdateParams. - rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); -} - -// MsgRegisterInterchainAccount defines the payload for Msg/RegisterAccount -message MsgRegisterInterchainAccount { - option (cosmos.msg.v1.signer) = "owner"; - - option (gogoproto.goproto_getters) = false; - - string owner = 1; - string connection_id = 2; - string version = 3; - ibc.core.channel.v1.Order ordering = 4; -} - -// MsgRegisterInterchainAccountResponse defines the response for Msg/RegisterAccount -message MsgRegisterInterchainAccountResponse { - option (gogoproto.goproto_getters) = false; - - string channel_id = 1; - string port_id = 2; -} - -// MsgSendTx defines the payload for Msg/SendTx -message MsgSendTx { - option (cosmos.msg.v1.signer) = "owner"; - - option (gogoproto.goproto_getters) = false; - - string owner = 1; - string connection_id = 2; - ibc.applications.interchain_accounts.v1.InterchainAccountPacketData packet_data = 3 [(gogoproto.nullable) = false]; - // Relative timeout timestamp provided will be added to the current block time during transaction execution. - // The timeout timestamp must be non-zero. - uint64 relative_timeout = 4; -} - -// MsgSendTxResponse defines the response for MsgSendTx -message MsgSendTxResponse { - option (gogoproto.goproto_getters) = false; - - uint64 sequence = 1; -} - -// MsgUpdateParams defines the payload for Msg/UpdateParams -message MsgUpdateParams { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - // signer address - string signer = 1; - - // params defines the 27-interchain-accounts/controller parameters to update. - // - // NOTE: All parameters must be supplied. - Params params = 2 [(gogoproto.nullable) = false]; -} - -// MsgUpdateParamsResponse defines the response for Msg/UpdateParams -message MsgUpdateParamsResponse {} \ No newline at end of file diff --git a/third_party/proto/ibc/interchain_accounts/genesis/v1/genesis.proto b/third_party/proto/ibc/interchain_accounts/genesis/v1/genesis.proto deleted file mode 100644 index 4393e5b0b..000000000 --- a/third_party/proto/ibc/interchain_accounts/genesis/v1/genesis.proto +++ /dev/null @@ -1,47 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.interchain_accounts.genesis.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/genesis/types"; - -import "gogoproto/gogo.proto"; -import "ibc/applications/interchain_accounts/controller/v1/controller.proto"; -import "ibc/applications/interchain_accounts/host/v1/host.proto"; - -// GenesisState defines the interchain accounts genesis state -message GenesisState { - ControllerGenesisState controller_genesis_state = 1 [(gogoproto.nullable) = false]; - HostGenesisState host_genesis_state = 2 [(gogoproto.nullable) = false]; -} - -// ControllerGenesisState defines the interchain accounts controller genesis state -message ControllerGenesisState { - repeated ActiveChannel active_channels = 1 [(gogoproto.nullable) = false]; - repeated RegisteredInterchainAccount interchain_accounts = 2 [(gogoproto.nullable) = false]; - repeated string ports = 3; - ibc.applications.interchain_accounts.controller.v1.Params params = 4 [(gogoproto.nullable) = false]; -} - -// HostGenesisState defines the interchain accounts host genesis state -message HostGenesisState { - repeated ActiveChannel active_channels = 1 [(gogoproto.nullable) = false]; - repeated RegisteredInterchainAccount interchain_accounts = 2 [(gogoproto.nullable) = false]; - string port = 3; - ibc.applications.interchain_accounts.host.v1.Params params = 4 [(gogoproto.nullable) = false]; -} - -// ActiveChannel contains a connection ID, port ID and associated active channel ID, as well as a boolean flag to -// indicate if the channel is middleware enabled -message ActiveChannel { - string connection_id = 1; - string port_id = 2; - string channel_id = 3; - bool is_middleware_enabled = 4; -} - -// RegisteredInterchainAccount contains a connection ID, port ID and associated interchain account address -message RegisteredInterchainAccount { - string connection_id = 1; - string port_id = 2; - string account_address = 3; -} \ No newline at end of file diff --git a/third_party/proto/ibc/interchain_accounts/host/v1/host.proto b/third_party/proto/ibc/interchain_accounts/host/v1/host.proto deleted file mode 100644 index f03685711..000000000 --- a/third_party/proto/ibc/interchain_accounts/host/v1/host.proto +++ /dev/null @@ -1,14 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.interchain_accounts.host.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/host/types"; - -// Params defines the set of on-chain interchain accounts parameters. -// The following parameters may be used to disable the host submodule. -message Params { - // host_enabled enables or disables the host submodule. - bool host_enabled = 1; - // allow_messages defines a list of sdk message typeURLs allowed to be executed on a host chain. - repeated string allow_messages = 2; -} diff --git a/third_party/proto/ibc/interchain_accounts/host/v1/query.proto b/third_party/proto/ibc/interchain_accounts/host/v1/query.proto deleted file mode 100644 index 6f206a14c..000000000 --- a/third_party/proto/ibc/interchain_accounts/host/v1/query.proto +++ /dev/null @@ -1,25 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.interchain_accounts.host.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/host/types"; - -import "google/api/annotations.proto"; -import "ibc/applications/interchain_accounts/host/v1/host.proto"; - -// Query provides defines the gRPC querier service. -service Query { - // Params queries all parameters of the ICA host submodule. - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/ibc/apps/interchain_accounts/host/v1/params"; - } -} - -// QueryParamsRequest is the request type for the Query/Params RPC method. -message QueryParamsRequest {} - -// QueryParamsResponse is the response type for the Query/Params RPC method. -message QueryParamsResponse { - // params defines the parameters of the module. - Params params = 1; -} diff --git a/third_party/proto/ibc/interchain_accounts/host/v1/tx.proto b/third_party/proto/ibc/interchain_accounts/host/v1/tx.proto deleted file mode 100644 index 5a8073bc9..000000000 --- a/third_party/proto/ibc/interchain_accounts/host/v1/tx.proto +++ /dev/null @@ -1,35 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.interchain_accounts.host.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/host/types"; - -import "gogoproto/gogo.proto"; -import "cosmos/msg/v1/msg.proto"; -import "ibc/applications/interchain_accounts/host/v1/host.proto"; - -// Msg defines the 27-interchain-accounts/host Msg service. -service Msg { - option (cosmos.msg.v1.service) = true; - - // UpdateParams defines a rpc handler for MsgUpdateParams. - rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); -} - -// MsgUpdateParams defines the payload for Msg/UpdateParams -message MsgUpdateParams { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - // signer address - string signer = 1; - - // params defines the 27-interchain-accounts/host parameters to update. - // - // NOTE: All parameters must be supplied. - Params params = 2 [(gogoproto.nullable) = false]; -} - -// MsgUpdateParamsResponse defines the response for Msg/UpdateParams -message MsgUpdateParamsResponse {} diff --git a/third_party/proto/ibc/interchain_accounts/v1/account.proto b/third_party/proto/ibc/interchain_accounts/v1/account.proto deleted file mode 100644 index 4a6947c1c..000000000 --- a/third_party/proto/ibc/interchain_accounts/v1/account.proto +++ /dev/null @@ -1,19 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.interchain_accounts.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types"; - -import "cosmos_proto/cosmos.proto"; -import "gogoproto/gogo.proto"; -import "cosmos/auth/v1beta1/auth.proto"; - -// An InterchainAccount is defined as a BaseAccount & the address of the account owner on the controller chain -message InterchainAccount { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - option (cosmos_proto.implements_interface) = "ibc.applications.interchain_accounts.v1.InterchainAccountI"; - - cosmos.auth.v1beta1.BaseAccount base_account = 1 [(gogoproto.embed) = true]; - string account_owner = 2; -} diff --git a/third_party/proto/ibc/interchain_accounts/v1/metadata.proto b/third_party/proto/ibc/interchain_accounts/v1/metadata.proto deleted file mode 100644 index df72b41eb..000000000 --- a/third_party/proto/ibc/interchain_accounts/v1/metadata.proto +++ /dev/null @@ -1,23 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.interchain_accounts.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types"; - -// Metadata defines a set of protocol specific data encoded into the ICS27 channel version bytestring -// See ICS004: https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#Versioning -message Metadata { - // version defines the ICS27 protocol version - string version = 1; - // controller_connection_id is the connection identifier associated with the controller chain - string controller_connection_id = 2; - // host_connection_id is the connection identifier associated with the host chain - string host_connection_id = 3; - // address defines the interchain account address to be fulfilled upon the OnChanOpenTry handshake step - // NOTE: the address field is empty on the OnChanOpenInit handshake step - string address = 4; - // encoding defines the supported codec format - string encoding = 5; - // tx_type defines the type of transactions the interchain account can execute - string tx_type = 6; -} diff --git a/third_party/proto/ibc/interchain_accounts/v1/packet.proto b/third_party/proto/ibc/interchain_accounts/v1/packet.proto deleted file mode 100644 index f75a1463e..000000000 --- a/third_party/proto/ibc/interchain_accounts/v1/packet.proto +++ /dev/null @@ -1,31 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.interchain_accounts.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types"; - -import "google/protobuf/any.proto"; -import "gogoproto/gogo.proto"; - -// Type defines a classification of message issued from a controller chain to its associated interchain accounts -// host -enum Type { - option (gogoproto.goproto_enum_prefix) = false; - - // Default zero value enumeration - TYPE_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNSPECIFIED"]; - // Execute a transaction on an interchain accounts host chain - TYPE_EXECUTE_TX = 1 [(gogoproto.enumvalue_customname) = "EXECUTE_TX"]; -} - -// InterchainAccountPacketData is comprised of a raw transaction, type of transaction and optional memo field. -message InterchainAccountPacketData { - Type type = 1; - bytes data = 2; - string memo = 3; -} - -// CosmosTx contains a list of sdk.Msg's. It should be used when sending transactions to an SDK host chain. -message CosmosTx { - repeated google.protobuf.Any messages = 1; -} diff --git a/third_party/proto/ibc/lightclients/localhost/v2/localhost.proto b/third_party/proto/ibc/lightclients/localhost/v2/localhost.proto deleted file mode 100644 index 635db8521..000000000 --- a/third_party/proto/ibc/lightclients/localhost/v2/localhost.proto +++ /dev/null @@ -1,16 +0,0 @@ -syntax = "proto3"; - -package ibc.lightclients.localhost.v2; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/light-clients/09-localhost;localhost"; - -import "ibc/core/client/v1/client.proto"; -import "gogoproto/gogo.proto"; - -// ClientState defines the 09-localhost client state -message ClientState { - option (gogoproto.goproto_getters) = false; - - // the latest block height - ibc.core.client.v1.Height latest_height = 1 [(gogoproto.nullable) = false]; -} diff --git a/third_party/proto/ibc/lightclients/solomachine/v2/solomachine.proto b/third_party/proto/ibc/lightclients/solomachine/v2/solomachine.proto deleted file mode 100644 index 9dc2690c5..000000000 --- a/third_party/proto/ibc/lightclients/solomachine/v2/solomachine.proto +++ /dev/null @@ -1,189 +0,0 @@ -syntax = "proto3"; - -package ibc.lightclients.solomachine.v2; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/core/02-client/migrations/v7"; - -import "ibc/core/connection/v1/connection.proto"; -import "ibc/core/channel/v1/channel.proto"; -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; - -// ClientState defines a solo machine client that tracks the current consensus -// state and if the client is frozen. -message ClientState { - option (gogoproto.goproto_getters) = false; - // latest sequence of the client state - uint64 sequence = 1; - // frozen sequence of the solo machine - bool is_frozen = 2; - ConsensusState consensus_state = 3; - // when set to true, will allow governance to update a solo machine client. - // The client will be unfrozen if it is frozen. - bool allow_update_after_proposal = 4; -} - -// ConsensusState defines a solo machine consensus state. The sequence of a -// consensus state is contained in the "height" key used in storing the -// consensus state. -message ConsensusState { - option (gogoproto.goproto_getters) = false; - // public key of the solo machine - google.protobuf.Any public_key = 1; - // diversifier allows the same public key to be re-used across different solo - // machine clients (potentially on different chains) without being considered - // misbehaviour. - string diversifier = 2; - uint64 timestamp = 3; -} - -// Header defines a solo machine consensus header -message Header { - option (gogoproto.goproto_getters) = false; - // sequence to update solo machine public key at - uint64 sequence = 1; - uint64 timestamp = 2; - bytes signature = 3; - google.protobuf.Any new_public_key = 4; - string new_diversifier = 5; -} - -// Misbehaviour defines misbehaviour for a solo machine which consists -// of a sequence and two signatures over different messages at that sequence. -message Misbehaviour { - option (gogoproto.goproto_getters) = false; - string client_id = 1; - uint64 sequence = 2; - SignatureAndData signature_one = 3; - SignatureAndData signature_two = 4; -} - -// SignatureAndData contains a signature and the data signed over to create that -// signature. -message SignatureAndData { - option (gogoproto.goproto_getters) = false; - bytes signature = 1; - DataType data_type = 2; - bytes data = 3; - uint64 timestamp = 4; -} - -// TimestampedSignatureData contains the signature data and the timestamp of the -// signature. -message TimestampedSignatureData { - option (gogoproto.goproto_getters) = false; - bytes signature_data = 1; - uint64 timestamp = 2; -} - -// SignBytes defines the signed bytes used for signature verification. -message SignBytes { - option (gogoproto.goproto_getters) = false; - - uint64 sequence = 1; - uint64 timestamp = 2; - string diversifier = 3; - // type of the data used - DataType data_type = 4; - // marshaled data - bytes data = 5; -} - -// DataType defines the type of solo machine proof being created. This is done -// to preserve uniqueness of different data sign byte encodings. -enum DataType { - option (gogoproto.goproto_enum_prefix) = false; - - // Default State - DATA_TYPE_UNINITIALIZED_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNSPECIFIED"]; - // Data type for client state verification - DATA_TYPE_CLIENT_STATE = 1 [(gogoproto.enumvalue_customname) = "CLIENT"]; - // Data type for consensus state verification - DATA_TYPE_CONSENSUS_STATE = 2 [(gogoproto.enumvalue_customname) = "CONSENSUS"]; - // Data type for connection state verification - DATA_TYPE_CONNECTION_STATE = 3 [(gogoproto.enumvalue_customname) = "CONNECTION"]; - // Data type for channel state verification - DATA_TYPE_CHANNEL_STATE = 4 [(gogoproto.enumvalue_customname) = "CHANNEL"]; - // Data type for packet commitment verification - DATA_TYPE_PACKET_COMMITMENT = 5 [(gogoproto.enumvalue_customname) = "PACKETCOMMITMENT"]; - // Data type for packet acknowledgement verification - DATA_TYPE_PACKET_ACKNOWLEDGEMENT = 6 [(gogoproto.enumvalue_customname) = "PACKETACKNOWLEDGEMENT"]; - // Data type for packet receipt absence verification - DATA_TYPE_PACKET_RECEIPT_ABSENCE = 7 [(gogoproto.enumvalue_customname) = "PACKETRECEIPTABSENCE"]; - // Data type for next sequence recv verification - DATA_TYPE_NEXT_SEQUENCE_RECV = 8 [(gogoproto.enumvalue_customname) = "NEXTSEQUENCERECV"]; - // Data type for header verification - DATA_TYPE_HEADER = 9 [(gogoproto.enumvalue_customname) = "HEADER"]; -} - -// HeaderData returns the SignBytes data for update verification. -message HeaderData { - option (gogoproto.goproto_getters) = false; - - // header public key - google.protobuf.Any new_pub_key = 1; - // header diversifier - string new_diversifier = 2; -} - -// ClientStateData returns the SignBytes data for client state verification. -message ClientStateData { - option (gogoproto.goproto_getters) = false; - - bytes path = 1; - google.protobuf.Any client_state = 2; -} - -// ConsensusStateData returns the SignBytes data for consensus state -// verification. -message ConsensusStateData { - option (gogoproto.goproto_getters) = false; - - bytes path = 1; - google.protobuf.Any consensus_state = 2; -} - -// ConnectionStateData returns the SignBytes data for connection state -// verification. -message ConnectionStateData { - option (gogoproto.goproto_getters) = false; - - bytes path = 1; - ibc.core.connection.v1.ConnectionEnd connection = 2; -} - -// ChannelStateData returns the SignBytes data for channel state -// verification. -message ChannelStateData { - option (gogoproto.goproto_getters) = false; - - bytes path = 1; - ibc.core.channel.v1.Channel channel = 2; -} - -// PacketCommitmentData returns the SignBytes data for packet commitment -// verification. -message PacketCommitmentData { - bytes path = 1; - bytes commitment = 2; -} - -// PacketAcknowledgementData returns the SignBytes data for acknowledgement -// verification. -message PacketAcknowledgementData { - bytes path = 1; - bytes acknowledgement = 2; -} - -// PacketReceiptAbsenceData returns the SignBytes data for -// packet receipt absence verification. -message PacketReceiptAbsenceData { - bytes path = 1; -} - -// NextSequenceRecvData returns the SignBytes data for verification of the next -// sequence to be received. -message NextSequenceRecvData { - bytes path = 1; - uint64 next_seq_recv = 2; -} diff --git a/third_party/proto/ibc/lightclients/solomachine/v3/solomachine.proto b/third_party/proto/ibc/lightclients/solomachine/v3/solomachine.proto deleted file mode 100644 index 194905b38..000000000 --- a/third_party/proto/ibc/lightclients/solomachine/v3/solomachine.proto +++ /dev/null @@ -1,99 +0,0 @@ -syntax = "proto3"; - -package ibc.lightclients.solomachine.v3; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/light-clients/06-solomachine;solomachine"; - -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; - -// ClientState defines a solo machine client that tracks the current consensus -// state and if the client is frozen. -message ClientState { - option (gogoproto.goproto_getters) = false; - // latest sequence of the client state - uint64 sequence = 1; - // frozen sequence of the solo machine - bool is_frozen = 2; - ConsensusState consensus_state = 3; -} - -// ConsensusState defines a solo machine consensus state. The sequence of a -// consensus state is contained in the "height" key used in storing the -// consensus state. -message ConsensusState { - option (gogoproto.goproto_getters) = false; - // public key of the solo machine - google.protobuf.Any public_key = 1; - // diversifier allows the same public key to be re-used across different solo - // machine clients (potentially on different chains) without being considered - // misbehaviour. - string diversifier = 2; - uint64 timestamp = 3; -} - -// Header defines a solo machine consensus header -message Header { - option (gogoproto.goproto_getters) = false; - - uint64 timestamp = 1; - bytes signature = 2; - google.protobuf.Any new_public_key = 3; - string new_diversifier = 4; -} - -// Misbehaviour defines misbehaviour for a solo machine which consists -// of a sequence and two signatures over different messages at that sequence. -message Misbehaviour { - option (gogoproto.goproto_getters) = false; - - uint64 sequence = 1; - SignatureAndData signature_one = 2; - SignatureAndData signature_two = 3; -} - -// SignatureAndData contains a signature and the data signed over to create that -// signature. -message SignatureAndData { - option (gogoproto.goproto_getters) = false; - - bytes signature = 1; - bytes path = 2; - bytes data = 3; - uint64 timestamp = 4; -} - -// TimestampedSignatureData contains the signature data and the timestamp of the -// signature. -message TimestampedSignatureData { - option (gogoproto.goproto_getters) = false; - - bytes signature_data = 1; - uint64 timestamp = 2; -} - -// SignBytes defines the signed bytes used for signature verification. -message SignBytes { - option (gogoproto.goproto_getters) = false; - - // the sequence number - uint64 sequence = 1; - // the proof timestamp - uint64 timestamp = 2; - // the public key diversifier - string diversifier = 3; - // the standardised path bytes - bytes path = 4; - // the marshaled data bytes - bytes data = 5; -} - -// HeaderData returns the SignBytes data for update verification. -message HeaderData { - option (gogoproto.goproto_getters) = false; - - // header public key - google.protobuf.Any new_pub_key = 1; - // header diversifier - string new_diversifier = 2; -} diff --git a/third_party/proto/ibc/lightclients/tendermint/v1/tendermint.proto b/third_party/proto/ibc/lightclients/tendermint/v1/tendermint.proto deleted file mode 100644 index 505361222..000000000 --- a/third_party/proto/ibc/lightclients/tendermint/v1/tendermint.proto +++ /dev/null @@ -1,101 +0,0 @@ -syntax = "proto3"; - -package ibc.lightclients.tendermint.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint;tendermint"; - -import "tendermint/types/validator.proto"; -import "tendermint/types/types.proto"; -import "cosmos/ics23/v1/proofs.proto"; -import "google/protobuf/duration.proto"; -import "google/protobuf/timestamp.proto"; -import "ibc/core/client/v1/client.proto"; -import "ibc/core/commitment/v1/commitment.proto"; -import "gogoproto/gogo.proto"; - -// ClientState from Tendermint tracks the current validator set, latest height, -// and a possible frozen height. -message ClientState { - option (gogoproto.goproto_getters) = false; - - string chain_id = 1; - Fraction trust_level = 2 [(gogoproto.nullable) = false]; - // duration of the period since the LastestTimestamp during which the - // submitted headers are valid for upgrade - google.protobuf.Duration trusting_period = 3 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; - // duration of the staking unbonding period - google.protobuf.Duration unbonding_period = 4 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; - // defines how much new (untrusted) header's Time can drift into the future. - google.protobuf.Duration max_clock_drift = 5 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; - // Block height when the client was frozen due to a misbehaviour - ibc.core.client.v1.Height frozen_height = 6 [(gogoproto.nullable) = false]; - // Latest height the client was updated to - ibc.core.client.v1.Height latest_height = 7 [(gogoproto.nullable) = false]; - - // Proof specifications used in verifying counterparty state - repeated cosmos.ics23.v1.ProofSpec proof_specs = 8; - - // Path at which next upgraded client will be committed. - // Each element corresponds to the key for a single CommitmentProof in the - // chained proof. NOTE: ClientState must stored under - // `{upgradePath}/{upgradeHeight}/clientState` ConsensusState must be stored - // under `{upgradepath}/{upgradeHeight}/consensusState` For SDK chains using - // the default upgrade module, upgrade_path should be []string{"upgrade", - // "upgradedIBCState"}` - repeated string upgrade_path = 9; - - // allow_update_after_expiry is deprecated - bool allow_update_after_expiry = 10 [deprecated = true]; - // allow_update_after_misbehaviour is deprecated - bool allow_update_after_misbehaviour = 11 [deprecated = true]; -} - -// ConsensusState defines the consensus state from Tendermint. -message ConsensusState { - option (gogoproto.goproto_getters) = false; - - // timestamp that corresponds to the block height in which the ConsensusState - // was stored. - google.protobuf.Timestamp timestamp = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - // commitment root (i.e app hash) - ibc.core.commitment.v1.MerkleRoot root = 2 [(gogoproto.nullable) = false]; - bytes next_validators_hash = 3 [(gogoproto.casttype) = "github.com/cometbft/cometbft/libs/bytes.HexBytes"]; -} - -// Misbehaviour is a wrapper over two conflicting Headers -// that implements Misbehaviour interface expected by ICS-02 -message Misbehaviour { - option (gogoproto.goproto_getters) = false; - - // ClientID is deprecated - string client_id = 1 [deprecated = true]; - Header header_1 = 2 [(gogoproto.customname) = "Header1"]; - Header header_2 = 3 [(gogoproto.customname) = "Header2"]; -} - -// Header defines the Tendermint client consensus Header. -// It encapsulates all the information necessary to update from a trusted -// Tendermint ConsensusState. The inclusion of TrustedHeight and -// TrustedValidators allows this update to process correctly, so long as the -// ConsensusState for the TrustedHeight exists, this removes race conditions -// among relayers The SignedHeader and ValidatorSet are the new untrusted update -// fields for the client. The TrustedHeight is the height of a stored -// ConsensusState on the client that will be used to verify the new untrusted -// header. The Trusted ConsensusState must be within the unbonding period of -// current time in order to correctly verify, and the TrustedValidators must -// hash to TrustedConsensusState.NextValidatorsHash since that is the last -// trusted validator set at the TrustedHeight. -message Header { - .tendermint.types.SignedHeader signed_header = 1 [(gogoproto.embed) = true]; - - .tendermint.types.ValidatorSet validator_set = 2; - ibc.core.client.v1.Height trusted_height = 3 [(gogoproto.nullable) = false]; - .tendermint.types.ValidatorSet trusted_validators = 4; -} - -// Fraction defines the protobuf message type for tmmath.Fraction that only -// supports positive values. -message Fraction { - uint64 numerator = 1; - uint64 denominator = 2; -} diff --git a/third_party/proto/ibc/lightclients/wasm/v1/genesis.proto b/third_party/proto/ibc/lightclients/wasm/v1/genesis.proto deleted file mode 100644 index 637ba1677..000000000 --- a/third_party/proto/ibc/lightclients/wasm/v1/genesis.proto +++ /dev/null @@ -1,20 +0,0 @@ - -syntax = "proto3"; -package ibc.lightclients.wasm.v1; - -import "gogoproto/gogo.proto"; - -option go_package = "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"; - -// GenesisState defines 08-wasm's keeper genesis state -message GenesisState { - // uploaded light client wasm contracts - repeated Contract contracts = 1 [(gogoproto.nullable) = false]; -} - -// Contract stores contract code -message Contract { - option (gogoproto.goproto_getters) = false; - // contract byte code - bytes code_bytes = 1; -} \ No newline at end of file diff --git a/third_party/proto/ibc/lightclients/wasm/v1/query.proto b/third_party/proto/ibc/lightclients/wasm/v1/query.proto deleted file mode 100644 index bbbed29dd..000000000 --- a/third_party/proto/ibc/lightclients/wasm/v1/query.proto +++ /dev/null @@ -1,46 +0,0 @@ -syntax = "proto3"; -package ibc.lightclients.wasm.v1; - -import "google/api/annotations.proto"; -import "cosmos/base/query/v1beta1/pagination.proto"; - -option go_package = "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"; - -// Query service for wasm module -service Query { - // Get all Wasm checksums - rpc Checksums(QueryChecksumsRequest) returns (QueryChecksumsResponse) { - option (google.api.http).get = "/ibc/lightclients/wasm/v1/checksums"; - } - - // Get Wasm code for given checksum - rpc Code(QueryCodeRequest) returns (QueryCodeResponse) { - option (google.api.http).get = "/ibc/lightclients/wasm/v1/checksums/{checksum}/code"; - } -} - -// QueryChecksumsRequest is the request type for the Query/Checksums RPC method. -message QueryChecksumsRequest { - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 1; -} - -// QueryChecksumsResponse is the response type for the Query/Checksums RPC method. -message QueryChecksumsResponse { - // checksums is a list of the hex encoded checksums of all wasm codes stored. - repeated string checksums = 1; - - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryCodeRequest is the request type for the Query/Code RPC method. -message QueryCodeRequest { - // checksum is a hex encoded string of the code stored. - string checksum = 1; -} - -// QueryCodeResponse is the response type for the Query/Code RPC method. -message QueryCodeResponse { - bytes data = 1; -} diff --git a/third_party/proto/ibc/lightclients/wasm/v1/tx.proto b/third_party/proto/ibc/lightclients/wasm/v1/tx.proto deleted file mode 100644 index d2fc46591..000000000 --- a/third_party/proto/ibc/lightclients/wasm/v1/tx.proto +++ /dev/null @@ -1,66 +0,0 @@ -syntax = "proto3"; -package ibc.lightclients.wasm.v1; - -option go_package = "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"; - -import "cosmos/msg/v1/msg.proto"; - -// Msg defines the ibc/08-wasm Msg service. -service Msg { - option (cosmos.msg.v1.service) = true; - - // StoreCode defines a rpc handler method for MsgStoreCode. - rpc StoreCode(MsgStoreCode) returns (MsgStoreCodeResponse); - - // RemoveChecksum defines a rpc handler method for MsgRemoveChecksum. - rpc RemoveChecksum(MsgRemoveChecksum) returns (MsgRemoveChecksumResponse); - - // MigrateContract defines a rpc handler method for MsgMigrateContract. - rpc MigrateContract(MsgMigrateContract) returns (MsgMigrateContractResponse); -} - -// MsgStoreCode defines the request type for the StoreCode rpc. -message MsgStoreCode { - option (cosmos.msg.v1.signer) = "signer"; - - // signer address - string signer = 1; - // wasm byte code of light client contract. It can be raw or gzip compressed - bytes wasm_byte_code = 2; -} - -// MsgStoreCodeResponse defines the response type for the StoreCode rpc -message MsgStoreCodeResponse { - // checksum is the sha256 hash of the stored code - bytes checksum = 1; -} - -// MsgRemoveChecksum defines the request type for the MsgRemoveChecksum rpc. -message MsgRemoveChecksum { - option (cosmos.msg.v1.signer) = "signer"; - - // signer address - string signer = 1; - // checksum is the sha256 hash to be removed from the store - bytes checksum = 2; -} - -// MsgStoreChecksumResponse defines the response type for the StoreCode rpc -message MsgRemoveChecksumResponse {} - -// MsgMigrateContract defines the request type for the MigrateContract rpc. -message MsgMigrateContract { - option (cosmos.msg.v1.signer) = "signer"; - - // signer address - string signer = 1; - // the client id of the contract - string client_id = 2; - // checksum is the sha256 hash of the new wasm byte code for the contract - bytes checksum = 3; - // the json encoded message to be passed to the contract on migration - bytes msg = 4; -} - -// MsgMigrateContractResponse defines the response type for the MigrateContract rpc -message MsgMigrateContractResponse {} diff --git a/third_party/proto/ibc/lightclients/wasm/v1/wasm.proto b/third_party/proto/ibc/lightclients/wasm/v1/wasm.proto deleted file mode 100644 index b6a45e3d8..000000000 --- a/third_party/proto/ibc/lightclients/wasm/v1/wasm.proto +++ /dev/null @@ -1,43 +0,0 @@ - -syntax = "proto3"; -package ibc.lightclients.wasm.v1; - -import "gogoproto/gogo.proto"; -import "ibc/core/client/v1/client.proto"; - -option go_package = "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"; - -// Wasm light client's Client state -message ClientState { - option (gogoproto.goproto_getters) = false; - // bytes encoding the client state of the underlying light client - // implemented as a Wasm contract. - bytes data = 1; - bytes checksum = 2; - ibc.core.client.v1.Height latest_height = 3 [(gogoproto.nullable) = false]; -} - -// Wasm light client's ConsensusState -message ConsensusState { - option (gogoproto.goproto_getters) = false; - // bytes encoding the consensus state of the underlying light client - // implemented as a Wasm contract. - bytes data = 1; -} - -// Wasm light client message (either header(s) or misbehaviour) -message ClientMessage { - option (gogoproto.goproto_getters) = false; - - bytes data = 1; -} - -// Checksums defines a list of all checksums that are stored -// -// Deprecated: This message is deprecated in favor of storing the checksums -// using a Collections.KeySet. -message Checksums { - option deprecated = true; - - repeated bytes checksums = 1; -} \ No newline at end of file diff --git a/third_party/proto/ibc/localhost/v2/localhost.proto b/third_party/proto/ibc/localhost/v2/localhost.proto deleted file mode 100644 index 635db8521..000000000 --- a/third_party/proto/ibc/localhost/v2/localhost.proto +++ /dev/null @@ -1,16 +0,0 @@ -syntax = "proto3"; - -package ibc.lightclients.localhost.v2; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/light-clients/09-localhost;localhost"; - -import "ibc/core/client/v1/client.proto"; -import "gogoproto/gogo.proto"; - -// ClientState defines the 09-localhost client state -message ClientState { - option (gogoproto.goproto_getters) = false; - - // the latest block height - ibc.core.client.v1.Height latest_height = 1 [(gogoproto.nullable) = false]; -} diff --git a/third_party/proto/ibc/solomachine/v2/solomachine.proto b/third_party/proto/ibc/solomachine/v2/solomachine.proto deleted file mode 100644 index 9dc2690c5..000000000 --- a/third_party/proto/ibc/solomachine/v2/solomachine.proto +++ /dev/null @@ -1,189 +0,0 @@ -syntax = "proto3"; - -package ibc.lightclients.solomachine.v2; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/core/02-client/migrations/v7"; - -import "ibc/core/connection/v1/connection.proto"; -import "ibc/core/channel/v1/channel.proto"; -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; - -// ClientState defines a solo machine client that tracks the current consensus -// state and if the client is frozen. -message ClientState { - option (gogoproto.goproto_getters) = false; - // latest sequence of the client state - uint64 sequence = 1; - // frozen sequence of the solo machine - bool is_frozen = 2; - ConsensusState consensus_state = 3; - // when set to true, will allow governance to update a solo machine client. - // The client will be unfrozen if it is frozen. - bool allow_update_after_proposal = 4; -} - -// ConsensusState defines a solo machine consensus state. The sequence of a -// consensus state is contained in the "height" key used in storing the -// consensus state. -message ConsensusState { - option (gogoproto.goproto_getters) = false; - // public key of the solo machine - google.protobuf.Any public_key = 1; - // diversifier allows the same public key to be re-used across different solo - // machine clients (potentially on different chains) without being considered - // misbehaviour. - string diversifier = 2; - uint64 timestamp = 3; -} - -// Header defines a solo machine consensus header -message Header { - option (gogoproto.goproto_getters) = false; - // sequence to update solo machine public key at - uint64 sequence = 1; - uint64 timestamp = 2; - bytes signature = 3; - google.protobuf.Any new_public_key = 4; - string new_diversifier = 5; -} - -// Misbehaviour defines misbehaviour for a solo machine which consists -// of a sequence and two signatures over different messages at that sequence. -message Misbehaviour { - option (gogoproto.goproto_getters) = false; - string client_id = 1; - uint64 sequence = 2; - SignatureAndData signature_one = 3; - SignatureAndData signature_two = 4; -} - -// SignatureAndData contains a signature and the data signed over to create that -// signature. -message SignatureAndData { - option (gogoproto.goproto_getters) = false; - bytes signature = 1; - DataType data_type = 2; - bytes data = 3; - uint64 timestamp = 4; -} - -// TimestampedSignatureData contains the signature data and the timestamp of the -// signature. -message TimestampedSignatureData { - option (gogoproto.goproto_getters) = false; - bytes signature_data = 1; - uint64 timestamp = 2; -} - -// SignBytes defines the signed bytes used for signature verification. -message SignBytes { - option (gogoproto.goproto_getters) = false; - - uint64 sequence = 1; - uint64 timestamp = 2; - string diversifier = 3; - // type of the data used - DataType data_type = 4; - // marshaled data - bytes data = 5; -} - -// DataType defines the type of solo machine proof being created. This is done -// to preserve uniqueness of different data sign byte encodings. -enum DataType { - option (gogoproto.goproto_enum_prefix) = false; - - // Default State - DATA_TYPE_UNINITIALIZED_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNSPECIFIED"]; - // Data type for client state verification - DATA_TYPE_CLIENT_STATE = 1 [(gogoproto.enumvalue_customname) = "CLIENT"]; - // Data type for consensus state verification - DATA_TYPE_CONSENSUS_STATE = 2 [(gogoproto.enumvalue_customname) = "CONSENSUS"]; - // Data type for connection state verification - DATA_TYPE_CONNECTION_STATE = 3 [(gogoproto.enumvalue_customname) = "CONNECTION"]; - // Data type for channel state verification - DATA_TYPE_CHANNEL_STATE = 4 [(gogoproto.enumvalue_customname) = "CHANNEL"]; - // Data type for packet commitment verification - DATA_TYPE_PACKET_COMMITMENT = 5 [(gogoproto.enumvalue_customname) = "PACKETCOMMITMENT"]; - // Data type for packet acknowledgement verification - DATA_TYPE_PACKET_ACKNOWLEDGEMENT = 6 [(gogoproto.enumvalue_customname) = "PACKETACKNOWLEDGEMENT"]; - // Data type for packet receipt absence verification - DATA_TYPE_PACKET_RECEIPT_ABSENCE = 7 [(gogoproto.enumvalue_customname) = "PACKETRECEIPTABSENCE"]; - // Data type for next sequence recv verification - DATA_TYPE_NEXT_SEQUENCE_RECV = 8 [(gogoproto.enumvalue_customname) = "NEXTSEQUENCERECV"]; - // Data type for header verification - DATA_TYPE_HEADER = 9 [(gogoproto.enumvalue_customname) = "HEADER"]; -} - -// HeaderData returns the SignBytes data for update verification. -message HeaderData { - option (gogoproto.goproto_getters) = false; - - // header public key - google.protobuf.Any new_pub_key = 1; - // header diversifier - string new_diversifier = 2; -} - -// ClientStateData returns the SignBytes data for client state verification. -message ClientStateData { - option (gogoproto.goproto_getters) = false; - - bytes path = 1; - google.protobuf.Any client_state = 2; -} - -// ConsensusStateData returns the SignBytes data for consensus state -// verification. -message ConsensusStateData { - option (gogoproto.goproto_getters) = false; - - bytes path = 1; - google.protobuf.Any consensus_state = 2; -} - -// ConnectionStateData returns the SignBytes data for connection state -// verification. -message ConnectionStateData { - option (gogoproto.goproto_getters) = false; - - bytes path = 1; - ibc.core.connection.v1.ConnectionEnd connection = 2; -} - -// ChannelStateData returns the SignBytes data for channel state -// verification. -message ChannelStateData { - option (gogoproto.goproto_getters) = false; - - bytes path = 1; - ibc.core.channel.v1.Channel channel = 2; -} - -// PacketCommitmentData returns the SignBytes data for packet commitment -// verification. -message PacketCommitmentData { - bytes path = 1; - bytes commitment = 2; -} - -// PacketAcknowledgementData returns the SignBytes data for acknowledgement -// verification. -message PacketAcknowledgementData { - bytes path = 1; - bytes acknowledgement = 2; -} - -// PacketReceiptAbsenceData returns the SignBytes data for -// packet receipt absence verification. -message PacketReceiptAbsenceData { - bytes path = 1; -} - -// NextSequenceRecvData returns the SignBytes data for verification of the next -// sequence to be received. -message NextSequenceRecvData { - bytes path = 1; - uint64 next_seq_recv = 2; -} diff --git a/third_party/proto/ibc/solomachine/v3/solomachine.proto b/third_party/proto/ibc/solomachine/v3/solomachine.proto deleted file mode 100644 index 194905b38..000000000 --- a/third_party/proto/ibc/solomachine/v3/solomachine.proto +++ /dev/null @@ -1,99 +0,0 @@ -syntax = "proto3"; - -package ibc.lightclients.solomachine.v3; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/light-clients/06-solomachine;solomachine"; - -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; - -// ClientState defines a solo machine client that tracks the current consensus -// state and if the client is frozen. -message ClientState { - option (gogoproto.goproto_getters) = false; - // latest sequence of the client state - uint64 sequence = 1; - // frozen sequence of the solo machine - bool is_frozen = 2; - ConsensusState consensus_state = 3; -} - -// ConsensusState defines a solo machine consensus state. The sequence of a -// consensus state is contained in the "height" key used in storing the -// consensus state. -message ConsensusState { - option (gogoproto.goproto_getters) = false; - // public key of the solo machine - google.protobuf.Any public_key = 1; - // diversifier allows the same public key to be re-used across different solo - // machine clients (potentially on different chains) without being considered - // misbehaviour. - string diversifier = 2; - uint64 timestamp = 3; -} - -// Header defines a solo machine consensus header -message Header { - option (gogoproto.goproto_getters) = false; - - uint64 timestamp = 1; - bytes signature = 2; - google.protobuf.Any new_public_key = 3; - string new_diversifier = 4; -} - -// Misbehaviour defines misbehaviour for a solo machine which consists -// of a sequence and two signatures over different messages at that sequence. -message Misbehaviour { - option (gogoproto.goproto_getters) = false; - - uint64 sequence = 1; - SignatureAndData signature_one = 2; - SignatureAndData signature_two = 3; -} - -// SignatureAndData contains a signature and the data signed over to create that -// signature. -message SignatureAndData { - option (gogoproto.goproto_getters) = false; - - bytes signature = 1; - bytes path = 2; - bytes data = 3; - uint64 timestamp = 4; -} - -// TimestampedSignatureData contains the signature data and the timestamp of the -// signature. -message TimestampedSignatureData { - option (gogoproto.goproto_getters) = false; - - bytes signature_data = 1; - uint64 timestamp = 2; -} - -// SignBytes defines the signed bytes used for signature verification. -message SignBytes { - option (gogoproto.goproto_getters) = false; - - // the sequence number - uint64 sequence = 1; - // the proof timestamp - uint64 timestamp = 2; - // the public key diversifier - string diversifier = 3; - // the standardised path bytes - bytes path = 4; - // the marshaled data bytes - bytes data = 5; -} - -// HeaderData returns the SignBytes data for update verification. -message HeaderData { - option (gogoproto.goproto_getters) = false; - - // header public key - google.protobuf.Any new_pub_key = 1; - // header diversifier - string new_diversifier = 2; -} diff --git a/third_party/proto/ibc/tendermint/v1/tendermint.proto b/third_party/proto/ibc/tendermint/v1/tendermint.proto deleted file mode 100644 index 505361222..000000000 --- a/third_party/proto/ibc/tendermint/v1/tendermint.proto +++ /dev/null @@ -1,101 +0,0 @@ -syntax = "proto3"; - -package ibc.lightclients.tendermint.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint;tendermint"; - -import "tendermint/types/validator.proto"; -import "tendermint/types/types.proto"; -import "cosmos/ics23/v1/proofs.proto"; -import "google/protobuf/duration.proto"; -import "google/protobuf/timestamp.proto"; -import "ibc/core/client/v1/client.proto"; -import "ibc/core/commitment/v1/commitment.proto"; -import "gogoproto/gogo.proto"; - -// ClientState from Tendermint tracks the current validator set, latest height, -// and a possible frozen height. -message ClientState { - option (gogoproto.goproto_getters) = false; - - string chain_id = 1; - Fraction trust_level = 2 [(gogoproto.nullable) = false]; - // duration of the period since the LastestTimestamp during which the - // submitted headers are valid for upgrade - google.protobuf.Duration trusting_period = 3 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; - // duration of the staking unbonding period - google.protobuf.Duration unbonding_period = 4 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; - // defines how much new (untrusted) header's Time can drift into the future. - google.protobuf.Duration max_clock_drift = 5 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; - // Block height when the client was frozen due to a misbehaviour - ibc.core.client.v1.Height frozen_height = 6 [(gogoproto.nullable) = false]; - // Latest height the client was updated to - ibc.core.client.v1.Height latest_height = 7 [(gogoproto.nullable) = false]; - - // Proof specifications used in verifying counterparty state - repeated cosmos.ics23.v1.ProofSpec proof_specs = 8; - - // Path at which next upgraded client will be committed. - // Each element corresponds to the key for a single CommitmentProof in the - // chained proof. NOTE: ClientState must stored under - // `{upgradePath}/{upgradeHeight}/clientState` ConsensusState must be stored - // under `{upgradepath}/{upgradeHeight}/consensusState` For SDK chains using - // the default upgrade module, upgrade_path should be []string{"upgrade", - // "upgradedIBCState"}` - repeated string upgrade_path = 9; - - // allow_update_after_expiry is deprecated - bool allow_update_after_expiry = 10 [deprecated = true]; - // allow_update_after_misbehaviour is deprecated - bool allow_update_after_misbehaviour = 11 [deprecated = true]; -} - -// ConsensusState defines the consensus state from Tendermint. -message ConsensusState { - option (gogoproto.goproto_getters) = false; - - // timestamp that corresponds to the block height in which the ConsensusState - // was stored. - google.protobuf.Timestamp timestamp = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - // commitment root (i.e app hash) - ibc.core.commitment.v1.MerkleRoot root = 2 [(gogoproto.nullable) = false]; - bytes next_validators_hash = 3 [(gogoproto.casttype) = "github.com/cometbft/cometbft/libs/bytes.HexBytes"]; -} - -// Misbehaviour is a wrapper over two conflicting Headers -// that implements Misbehaviour interface expected by ICS-02 -message Misbehaviour { - option (gogoproto.goproto_getters) = false; - - // ClientID is deprecated - string client_id = 1 [deprecated = true]; - Header header_1 = 2 [(gogoproto.customname) = "Header1"]; - Header header_2 = 3 [(gogoproto.customname) = "Header2"]; -} - -// Header defines the Tendermint client consensus Header. -// It encapsulates all the information necessary to update from a trusted -// Tendermint ConsensusState. The inclusion of TrustedHeight and -// TrustedValidators allows this update to process correctly, so long as the -// ConsensusState for the TrustedHeight exists, this removes race conditions -// among relayers The SignedHeader and ValidatorSet are the new untrusted update -// fields for the client. The TrustedHeight is the height of a stored -// ConsensusState on the client that will be used to verify the new untrusted -// header. The Trusted ConsensusState must be within the unbonding period of -// current time in order to correctly verify, and the TrustedValidators must -// hash to TrustedConsensusState.NextValidatorsHash since that is the last -// trusted validator set at the TrustedHeight. -message Header { - .tendermint.types.SignedHeader signed_header = 1 [(gogoproto.embed) = true]; - - .tendermint.types.ValidatorSet validator_set = 2; - ibc.core.client.v1.Height trusted_height = 3 [(gogoproto.nullable) = false]; - .tendermint.types.ValidatorSet trusted_validators = 4; -} - -// Fraction defines the protobuf message type for tmmath.Fraction that only -// supports positive values. -message Fraction { - uint64 numerator = 1; - uint64 denominator = 2; -} diff --git a/third_party/proto/ibc/transfer/v1/authz.proto b/third_party/proto/ibc/transfer/v1/authz.proto deleted file mode 100644 index e7561b070..000000000 --- a/third_party/proto/ibc/transfer/v1/authz.proto +++ /dev/null @@ -1,34 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.transfer.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"; - -import "cosmos_proto/cosmos.proto"; -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; - -// Allocation defines the spend limit for a particular port and channel -message Allocation { - // the port on which the packet will be sent - string source_port = 1; - // the channel by which the packet will be sent - string source_channel = 2; - // spend limitation on the channel - repeated cosmos.base.v1beta1.Coin spend_limit = 3 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; - // allow list of receivers, an empty allow list permits any receiver address - repeated string allow_list = 4; - // allow list of packet data keys, an empty list prohibits all packet data keys; - // a list only with "*" permits any packet data key - repeated string allowed_packet_data = 5; -} - -// TransferAuthorization allows the grantee to spend up to spend_limit coins from -// the granter's account for ibc transfer on a specific channel -message TransferAuthorization { - option (cosmos_proto.implements_interface) = "cosmos.authz.v1beta1.Authorization"; - - // port and channel amounts - repeated Allocation allocations = 1 [(gogoproto.nullable) = false]; -} diff --git a/third_party/proto/ibc/transfer/v1/genesis.proto b/third_party/proto/ibc/transfer/v1/genesis.proto deleted file mode 100644 index f7d707f6c..000000000 --- a/third_party/proto/ibc/transfer/v1/genesis.proto +++ /dev/null @@ -1,20 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.transfer.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"; - -import "ibc/applications/transfer/v1/transfer.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "gogoproto/gogo.proto"; - -// GenesisState defines the ibc-transfer genesis state -message GenesisState { - string port_id = 1; - repeated DenomTrace denom_traces = 2 [(gogoproto.castrepeated) = "Traces", (gogoproto.nullable) = false]; - Params params = 3 [(gogoproto.nullable) = false]; - // total_escrowed contains the total amount of tokens escrowed - // by the transfer module - repeated cosmos.base.v1beta1.Coin total_escrowed = 4 - [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false]; -} diff --git a/third_party/proto/ibc/transfer/v1/query.proto b/third_party/proto/ibc/transfer/v1/query.proto deleted file mode 100644 index 788296718..000000000 --- a/third_party/proto/ibc/transfer/v1/query.proto +++ /dev/null @@ -1,121 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.transfer.v1; - -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "cosmos/base/query/v1beta1/pagination.proto"; -import "ibc/applications/transfer/v1/transfer.proto"; -import "google/api/annotations.proto"; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"; - -// Query provides defines the gRPC querier service. -service Query { - // DenomTraces queries all denomination traces. - rpc DenomTraces(QueryDenomTracesRequest) returns (QueryDenomTracesResponse) { - option (google.api.http).get = "/ibc/apps/transfer/v1/denom_traces"; - } - - // DenomTrace queries a denomination trace information. - rpc DenomTrace(QueryDenomTraceRequest) returns (QueryDenomTraceResponse) { - option (google.api.http).get = "/ibc/apps/transfer/v1/denom_traces/{hash=**}"; - } - - // Params queries all parameters of the ibc-transfer module. - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/ibc/apps/transfer/v1/params"; - } - - // DenomHash queries a denomination hash information. - rpc DenomHash(QueryDenomHashRequest) returns (QueryDenomHashResponse) { - option (google.api.http).get = "/ibc/apps/transfer/v1/denom_hashes/{trace=**}"; - } - - // EscrowAddress returns the escrow address for a particular port and channel id. - rpc EscrowAddress(QueryEscrowAddressRequest) returns (QueryEscrowAddressResponse) { - option (google.api.http).get = "/ibc/apps/transfer/v1/channels/{channel_id}/ports/{port_id}/escrow_address"; - } - - // TotalEscrowForDenom returns the total amount of tokens in escrow based on the denom. - rpc TotalEscrowForDenom(QueryTotalEscrowForDenomRequest) returns (QueryTotalEscrowForDenomResponse) { - option (google.api.http).get = "/ibc/apps/transfer/v1/denoms/{denom=**}/total_escrow"; - } -} - -// QueryDenomTraceRequest is the request type for the Query/DenomTrace RPC -// method -message QueryDenomTraceRequest { - // hash (in hex format) or denom (full denom with ibc prefix) of the denomination trace information. - string hash = 1; -} - -// QueryDenomTraceResponse is the response type for the Query/DenomTrace RPC -// method. -message QueryDenomTraceResponse { - // denom_trace returns the requested denomination trace information. - DenomTrace denom_trace = 1; -} - -// QueryConnectionsRequest is the request type for the Query/DenomTraces RPC -// method -message QueryDenomTracesRequest { - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 1; -} - -// QueryConnectionsResponse is the response type for the Query/DenomTraces RPC -// method. -message QueryDenomTracesResponse { - // denom_traces returns all denominations trace information. - repeated DenomTrace denom_traces = 1 [(gogoproto.castrepeated) = "Traces", (gogoproto.nullable) = false]; - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryParamsRequest is the request type for the Query/Params RPC method. -message QueryParamsRequest {} - -// QueryParamsResponse is the response type for the Query/Params RPC method. -message QueryParamsResponse { - // params defines the parameters of the module. - Params params = 1; -} - -// QueryDenomHashRequest is the request type for the Query/DenomHash RPC -// method -message QueryDenomHashRequest { - // The denomination trace ([port_id]/[channel_id])+/[denom] - string trace = 1; -} - -// QueryDenomHashResponse is the response type for the Query/DenomHash RPC -// method. -message QueryDenomHashResponse { - // hash (in hex format) of the denomination trace information. - string hash = 1; -} - -// QueryEscrowAddressRequest is the request type for the EscrowAddress RPC method. -message QueryEscrowAddressRequest { - // unique port identifier - string port_id = 1; - // unique channel identifier - string channel_id = 2; -} - -// QueryEscrowAddressResponse is the response type of the EscrowAddress RPC method. -message QueryEscrowAddressResponse { - // the escrow account address - string escrow_address = 1; -} - -// QueryTotalEscrowForDenomRequest is the request type for TotalEscrowForDenom RPC method. -message QueryTotalEscrowForDenomRequest { - string denom = 1; -} - -// QueryTotalEscrowForDenomResponse is the response type for TotalEscrowForDenom RPC method. -message QueryTotalEscrowForDenomResponse { - cosmos.base.v1beta1.Coin amount = 1 [(gogoproto.nullable) = false]; -} diff --git a/third_party/proto/ibc/transfer/v1/transfer.proto b/third_party/proto/ibc/transfer/v1/transfer.proto deleted file mode 100644 index 7f7723762..000000000 --- a/third_party/proto/ibc/transfer/v1/transfer.proto +++ /dev/null @@ -1,28 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.transfer.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"; - -// DenomTrace contains the base denomination for ICS20 fungible tokens and the -// source tracing information path. -message DenomTrace { - // path defines the chain of port/channel identifiers used for tracing the - // source of the fungible token. - string path = 1; - // base denomination of the relayed fungible token. - string base_denom = 2; -} - -// Params defines the set of IBC transfer parameters. -// NOTE: To prevent a single token from being transferred, set the -// TransfersEnabled parameter to true and then set the bank module's SendEnabled -// parameter for the denomination to false. -message Params { - // send_enabled enables or disables all cross-chain token transfers from this - // chain. - bool send_enabled = 1; - // receive_enabled enables or disables all cross-chain token transfers to this - // chain. - bool receive_enabled = 2; -} diff --git a/third_party/proto/ibc/transfer/v1/tx.proto b/third_party/proto/ibc/transfer/v1/tx.proto deleted file mode 100644 index 42c70d3be..000000000 --- a/third_party/proto/ibc/transfer/v1/tx.proto +++ /dev/null @@ -1,79 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.transfer.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"; - -import "amino/amino.proto"; -import "gogoproto/gogo.proto"; -import "cosmos/msg/v1/msg.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "ibc/core/client/v1/client.proto"; -import "ibc/applications/transfer/v1/transfer.proto"; - -// Msg defines the ibc/transfer Msg service. -service Msg { - option (cosmos.msg.v1.service) = true; - - // Transfer defines a rpc handler method for MsgTransfer. - rpc Transfer(MsgTransfer) returns (MsgTransferResponse); - - // UpdateParams defines a rpc handler for MsgUpdateParams. - rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); -} - -// MsgTransfer defines a msg to transfer fungible tokens (i.e Coins) between -// ICS20 enabled chains. See ICS Spec here: -// https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structures -message MsgTransfer { - option (amino.name) = "cosmos-sdk/MsgTransfer"; - option (cosmos.msg.v1.signer) = "sender"; - - option (gogoproto.goproto_getters) = false; - - // the port on which the packet will be sent - string source_port = 1; - // the channel by which the packet will be sent - string source_channel = 2; - // the tokens to be transferred - cosmos.base.v1beta1.Coin token = 3 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; - // the sender address - string sender = 4; - // the recipient address on the destination chain - string receiver = 5; - // Timeout height relative to the current block height. - // The timeout is disabled when set to 0. - ibc.core.client.v1.Height timeout_height = 6 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; - // Timeout timestamp in absolute nanoseconds since unix epoch. - // The timeout is disabled when set to 0. - uint64 timeout_timestamp = 7; - // optional memo - string memo = 8; -} - -// MsgTransferResponse defines the Msg/Transfer response type. -message MsgTransferResponse { - option (gogoproto.goproto_getters) = false; - - // sequence number of the transfer packet sent - uint64 sequence = 1; -} - -// MsgUpdateParams is the Msg/UpdateParams request type. -message MsgUpdateParams { - option (cosmos.msg.v1.signer) = "signer"; - - option (gogoproto.goproto_getters) = false; - - // signer address - string signer = 1; - - // params defines the transfer parameters to update. - // - // NOTE: All parameters must be supplied. - Params params = 2 [(gogoproto.nullable) = false]; -} - -// MsgUpdateParamsResponse defines the response structure for executing a -// MsgUpdateParams message. -message MsgUpdateParamsResponse {} \ No newline at end of file diff --git a/third_party/proto/ibc/transfer/v2/packet.proto b/third_party/proto/ibc/transfer/v2/packet.proto deleted file mode 100644 index bff35bdd6..000000000 --- a/third_party/proto/ibc/transfer/v2/packet.proto +++ /dev/null @@ -1,21 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.transfer.v2; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"; - -// FungibleTokenPacketData defines a struct for the packet payload -// See FungibleTokenPacketData spec: -// https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structures -message FungibleTokenPacketData { - // the token denomination to be transferred - string denom = 1; - // the token amount to be transferred - string amount = 2; - // the sender address - string sender = 3; - // the recipient address on the destination chain - string receiver = 4; - // optional memo - string memo = 5; -} diff --git a/third_party/proto/ibc/types/v1/genesis.proto b/third_party/proto/ibc/types/v1/genesis.proto deleted file mode 100644 index 4b34f6889..000000000 --- a/third_party/proto/ibc/types/v1/genesis.proto +++ /dev/null @@ -1,20 +0,0 @@ -syntax = "proto3"; - -package ibc.core.types.v1; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/core/types"; - -import "gogoproto/gogo.proto"; -import "ibc/core/client/v1/genesis.proto"; -import "ibc/core/connection/v1/genesis.proto"; -import "ibc/core/channel/v1/genesis.proto"; - -// GenesisState defines the ibc module's genesis state. -message GenesisState { - // ICS002 - Clients genesis state - ibc.core.client.v1.GenesisState client_genesis = 1 [(gogoproto.nullable) = false]; - // ICS003 - Connections genesis state - ibc.core.connection.v1.GenesisState connection_genesis = 2 [(gogoproto.nullable) = false]; - // ICS004 - Channel genesis state - ibc.core.channel.v1.GenesisState channel_genesis = 3 [(gogoproto.nullable) = false]; -} diff --git a/third_party/proto/ibc/wasm/v1/genesis.proto b/third_party/proto/ibc/wasm/v1/genesis.proto deleted file mode 100644 index 637ba1677..000000000 --- a/third_party/proto/ibc/wasm/v1/genesis.proto +++ /dev/null @@ -1,20 +0,0 @@ - -syntax = "proto3"; -package ibc.lightclients.wasm.v1; - -import "gogoproto/gogo.proto"; - -option go_package = "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"; - -// GenesisState defines 08-wasm's keeper genesis state -message GenesisState { - // uploaded light client wasm contracts - repeated Contract contracts = 1 [(gogoproto.nullable) = false]; -} - -// Contract stores contract code -message Contract { - option (gogoproto.goproto_getters) = false; - // contract byte code - bytes code_bytes = 1; -} \ No newline at end of file diff --git a/third_party/proto/ibc/wasm/v1/query.proto b/third_party/proto/ibc/wasm/v1/query.proto deleted file mode 100644 index bbbed29dd..000000000 --- a/third_party/proto/ibc/wasm/v1/query.proto +++ /dev/null @@ -1,46 +0,0 @@ -syntax = "proto3"; -package ibc.lightclients.wasm.v1; - -import "google/api/annotations.proto"; -import "cosmos/base/query/v1beta1/pagination.proto"; - -option go_package = "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"; - -// Query service for wasm module -service Query { - // Get all Wasm checksums - rpc Checksums(QueryChecksumsRequest) returns (QueryChecksumsResponse) { - option (google.api.http).get = "/ibc/lightclients/wasm/v1/checksums"; - } - - // Get Wasm code for given checksum - rpc Code(QueryCodeRequest) returns (QueryCodeResponse) { - option (google.api.http).get = "/ibc/lightclients/wasm/v1/checksums/{checksum}/code"; - } -} - -// QueryChecksumsRequest is the request type for the Query/Checksums RPC method. -message QueryChecksumsRequest { - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 1; -} - -// QueryChecksumsResponse is the response type for the Query/Checksums RPC method. -message QueryChecksumsResponse { - // checksums is a list of the hex encoded checksums of all wasm codes stored. - repeated string checksums = 1; - - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryCodeRequest is the request type for the Query/Code RPC method. -message QueryCodeRequest { - // checksum is a hex encoded string of the code stored. - string checksum = 1; -} - -// QueryCodeResponse is the response type for the Query/Code RPC method. -message QueryCodeResponse { - bytes data = 1; -} diff --git a/third_party/proto/ibc/wasm/v1/tx.proto b/third_party/proto/ibc/wasm/v1/tx.proto deleted file mode 100644 index d2fc46591..000000000 --- a/third_party/proto/ibc/wasm/v1/tx.proto +++ /dev/null @@ -1,66 +0,0 @@ -syntax = "proto3"; -package ibc.lightclients.wasm.v1; - -option go_package = "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"; - -import "cosmos/msg/v1/msg.proto"; - -// Msg defines the ibc/08-wasm Msg service. -service Msg { - option (cosmos.msg.v1.service) = true; - - // StoreCode defines a rpc handler method for MsgStoreCode. - rpc StoreCode(MsgStoreCode) returns (MsgStoreCodeResponse); - - // RemoveChecksum defines a rpc handler method for MsgRemoveChecksum. - rpc RemoveChecksum(MsgRemoveChecksum) returns (MsgRemoveChecksumResponse); - - // MigrateContract defines a rpc handler method for MsgMigrateContract. - rpc MigrateContract(MsgMigrateContract) returns (MsgMigrateContractResponse); -} - -// MsgStoreCode defines the request type for the StoreCode rpc. -message MsgStoreCode { - option (cosmos.msg.v1.signer) = "signer"; - - // signer address - string signer = 1; - // wasm byte code of light client contract. It can be raw or gzip compressed - bytes wasm_byte_code = 2; -} - -// MsgStoreCodeResponse defines the response type for the StoreCode rpc -message MsgStoreCodeResponse { - // checksum is the sha256 hash of the stored code - bytes checksum = 1; -} - -// MsgRemoveChecksum defines the request type for the MsgRemoveChecksum rpc. -message MsgRemoveChecksum { - option (cosmos.msg.v1.signer) = "signer"; - - // signer address - string signer = 1; - // checksum is the sha256 hash to be removed from the store - bytes checksum = 2; -} - -// MsgStoreChecksumResponse defines the response type for the StoreCode rpc -message MsgRemoveChecksumResponse {} - -// MsgMigrateContract defines the request type for the MigrateContract rpc. -message MsgMigrateContract { - option (cosmos.msg.v1.signer) = "signer"; - - // signer address - string signer = 1; - // the client id of the contract - string client_id = 2; - // checksum is the sha256 hash of the new wasm byte code for the contract - bytes checksum = 3; - // the json encoded message to be passed to the contract on migration - bytes msg = 4; -} - -// MsgMigrateContractResponse defines the response type for the MigrateContract rpc -message MsgMigrateContractResponse {} diff --git a/third_party/proto/ibc/wasm/v1/wasm.proto b/third_party/proto/ibc/wasm/v1/wasm.proto deleted file mode 100644 index b6a45e3d8..000000000 --- a/third_party/proto/ibc/wasm/v1/wasm.proto +++ /dev/null @@ -1,43 +0,0 @@ - -syntax = "proto3"; -package ibc.lightclients.wasm.v1; - -import "gogoproto/gogo.proto"; -import "ibc/core/client/v1/client.proto"; - -option go_package = "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"; - -// Wasm light client's Client state -message ClientState { - option (gogoproto.goproto_getters) = false; - // bytes encoding the client state of the underlying light client - // implemented as a Wasm contract. - bytes data = 1; - bytes checksum = 2; - ibc.core.client.v1.Height latest_height = 3 [(gogoproto.nullable) = false]; -} - -// Wasm light client's ConsensusState -message ConsensusState { - option (gogoproto.goproto_getters) = false; - // bytes encoding the consensus state of the underlying light client - // implemented as a Wasm contract. - bytes data = 1; -} - -// Wasm light client message (either header(s) or misbehaviour) -message ClientMessage { - option (gogoproto.goproto_getters) = false; - - bytes data = 1; -} - -// Checksums defines a list of all checksums that are stored -// -// Deprecated: This message is deprecated in favor of storing the checksums -// using a Collections.KeySet. -message Checksums { - option deprecated = true; - - repeated bytes checksums = 1; -} \ No newline at end of file From 45eae55635cadf8ba81226aafc0d0c42b113153f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 08:16:43 +0000 Subject: [PATCH 15/15] Bump github.com/cosmos/ibc-go/v8 from 8.4.0 to 8.5.0 Bumps [github.com/cosmos/ibc-go/v8](https://github.com/cosmos/ibc-go) from 8.4.0 to 8.5.0. - [Release notes](https://github.com/cosmos/ibc-go/releases) - [Changelog](https://github.com/cosmos/ibc-go/blob/v8.5.0/CHANGELOG.md) - [Commits](https://github.com/cosmos/ibc-go/compare/v8.4.0...v8.5.0) --- updated-dependencies: - dependency-name: github.com/cosmos/ibc-go/v8 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 20 ++++++++++---------- go.sum | 40 ++++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/go.mod b/go.mod index f6e7b7368..837db6d47 100644 --- a/go.mod +++ b/go.mod @@ -20,11 +20,11 @@ require ( github.com/cosmos/cosmos-db v1.0.2 github.com/cosmos/cosmos-proto v1.0.0-beta.5 github.com/cosmos/cosmos-sdk v0.50.9 - github.com/cosmos/gogoproto v1.6.0 + github.com/cosmos/gogoproto v1.7.0 github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v8 v8.0.2 github.com/cosmos/ibc-go/modules/capability v1.0.1 - github.com/cosmos/ibc-go/v8 v8.4.0 - github.com/cosmos/ics23/go v0.10.0 + github.com/cosmos/ibc-go/v8 v8.5.0 + github.com/cosmos/ics23/go v0.11.0 github.com/cosmos/interchain-security/v5 v5.1.1 github.com/gogo/protobuf v1.3.3 github.com/golang/mock v1.6.0 @@ -53,11 +53,11 @@ require ( ) require ( - cloud.google.com/go v0.114.0 // indirect - cloud.google.com/go/auth v0.5.1 // indirect + cloud.google.com/go v0.115.0 // indirect + cloud.google.com/go/auth v0.6.0 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect cloud.google.com/go/compute/metadata v0.3.0 // indirect - cloud.google.com/go/iam v1.1.8 // indirect + cloud.google.com/go/iam v1.1.9 // indirect cloud.google.com/go/storage v1.41.0 // indirect cosmossdk.io/api v0.7.5 // indirect cosmossdk.io/collections v0.4.0 // indirect @@ -124,7 +124,7 @@ require ( github.com/google/s2a-go v0.1.7 // indirect github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect - github.com/googleapis/gax-go/v2 v2.12.4 // indirect + github.com/googleapis/gax-go/v2 v2.12.5 // indirect github.com/gorilla/handlers v1.5.2 // indirect github.com/gorilla/websocket v1.5.3 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect @@ -201,12 +201,12 @@ require ( golang.org/x/net v0.28.0 // indirect golang.org/x/oauth2 v0.22.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect golang.org/x/term v0.23.0 // indirect golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.5.0 // indirect - google.golang.org/api v0.180.0 // indirect - google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda // indirect + google.golang.org/api v0.186.0 // indirect + google.golang.org/genproto v0.0.0-20240701130421-f6361c86f094 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 389be92c2..4e52f6f9f 100644 --- a/go.sum +++ b/go.sum @@ -30,8 +30,8 @@ cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w9 cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= -cloud.google.com/go v0.114.0 h1:OIPFAdfrFDFO2ve2U7r/H5SwSbBzEdrBdE7xkgwc+kY= -cloud.google.com/go v0.114.0/go.mod h1:ZV9La5YYxctro1HTPug5lXH/GefROyW8PPD4T8n9J8E= +cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= +cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= @@ -46,8 +46,8 @@ cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjby cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= -cloud.google.com/go/auth v0.5.1 h1:0QNO7VThG54LUzKiQxv8C6x1YX7lUrzlAa1nVLF8CIw= -cloud.google.com/go/auth v0.5.1/go.mod h1:vbZT8GjzDf3AVqCcQmqeeM32U9HBFc32vVVAbwDsa6s= +cloud.google.com/go/auth v0.6.0 h1:5x+d6b5zdezZ7gmLWD1m/xNjnaQ2YDhmIz/HH3doy1g= +cloud.google.com/go/auth v0.6.0/go.mod h1:b4acV+jLQDyjwm4OXHYjNvRi4jvGBzHWJRtJcy+2P4g= cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4= cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q= cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= @@ -111,8 +111,8 @@ cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y97 cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= -cloud.google.com/go/iam v1.1.8 h1:r7umDwhj+BQyz0ScZMp4QrGXjSTI3ZINnpgU2nlB/K0= -cloud.google.com/go/iam v1.1.8/go.mod h1:GvE6lyMmfxXauzNq8NbgJbeVQNspG+tcdL/W8QO1+zE= +cloud.google.com/go/iam v1.1.9 h1:oSkYLVtVme29uGYrOcKcvJRht7cHJpYD09GM9JaR0TE= +cloud.google.com/go/iam v1.1.9/go.mod h1:Nt1eDWNYH9nGQg3d/mY7U1hvfGmsaG9o/kLGoLoLXjQ= cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= @@ -367,18 +367,18 @@ github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4x github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= -github.com/cosmos/gogoproto v1.6.0 h1:Xm0F/96O5Ox4g6xGgjA41rWaaPjYtOdTi59uBcV2qEE= -github.com/cosmos/gogoproto v1.6.0/go.mod h1:Y+g956rcUf2vr4uwtCcK/1Xx9BWVluCtcI9vsh0GHmk= +github.com/cosmos/gogoproto v1.7.0 h1:79USr0oyXAbxg3rspGh/m4SWNyoz/GLaAh0QlCe2fro= +github.com/cosmos/gogoproto v1.7.0/go.mod h1:yWChEv5IUEYURQasfyBW5ffkMHR/90hiHgbNgrtp4j0= github.com/cosmos/iavl v1.2.0 h1:kVxTmjTh4k0Dh1VNL046v6BXqKziqMDzxo93oh3kOfM= github.com/cosmos/iavl v1.2.0/go.mod h1:HidWWLVAtODJqFD6Hbne2Y0q3SdxByJepHUOeoH4LiI= github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v8 v8.0.2 h1:dyLNlDElY6+5zW/BT/dO/3Ad9FpQblfh+9dQpYQodbA= github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v8 v8.0.2/go.mod h1:82hPO/tRawbuFad2gPwChvpZ0JEIoNi91LwVneAYCeM= github.com/cosmos/ibc-go/modules/capability v1.0.1 h1:ibwhrpJ3SftEEZRxCRkH0fQZ9svjthrX2+oXdZvzgGI= github.com/cosmos/ibc-go/modules/capability v1.0.1/go.mod h1:rquyOV262nGJplkumH+/LeYs04P3eV8oB7ZM4Ygqk4E= -github.com/cosmos/ibc-go/v8 v8.4.0 h1:K2PfX0AZ+1XKZytHGEMuSjQXG/MZshPb83RSTQt2+cE= -github.com/cosmos/ibc-go/v8 v8.4.0/go.mod h1:zh6x1osR0hNvEcFrC/lhGD08sMfQmr9wHVvZ/mRWMCs= -github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= -github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= +github.com/cosmos/ibc-go/v8 v8.5.0 h1:OjaSXz480JT8ZuMrASxGgS7XzloZ2NuuJPwZB/fKDgE= +github.com/cosmos/ibc-go/v8 v8.5.0/go.mod h1:P5hkAvq0Qbg0h18uLxDVA9q1kOJ0l36htMsskiNwXbo= +github.com/cosmos/ics23/go v0.11.0 h1:jk5skjT0TqX5e5QJbEnwXIS2yI2vnmLOgpQPeM5RtnU= +github.com/cosmos/ics23/go v0.11.0/go.mod h1:A8OjxPE67hHST4Icw94hOxxFEJMBG031xIGF/JHNIY0= github.com/cosmos/interchain-security/v5 v5.0.0-20240802125602-fa1e09444aae h1:/EWV9qryltapge0v4ctvl2jV3Nne5nsbd+GYblj/jWA= github.com/cosmos/interchain-security/v5 v5.0.0-20240802125602-fa1e09444aae/go.mod h1:P3TM8JmE9Q20Jfch3jnFcQ4IXJp5twueRnUudi6XEGI= github.com/cosmos/keyring v1.2.0 h1:8C1lBP9xhImmIabyXW4c3vFjjLiBdGCmfLUfeZlV1Yo= @@ -633,8 +633,8 @@ github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99 github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= -github.com/googleapis/gax-go/v2 v2.12.4 h1:9gWcmF85Wvq4ryPFvGFaOgPIs1AQX0d0bcbGw4Z96qg= -github.com/googleapis/gax-go/v2 v2.12.4/go.mod h1:KYEYLorsnIGDi/rPC8b5TdlB9kbKoFubselGIoBMCwI= +github.com/googleapis/gax-go/v2 v2.12.5 h1:8gw9KZK8TiVKB6q3zHY3SBzLnrGp6HQjyfYBYGmXdxA= +github.com/googleapis/gax-go/v2 v2.12.5/go.mod h1:BUDKcWo+RaKq5SC9vVYL0wLADa3VcfswbOMMRmB9H3E= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -1363,8 +1363,8 @@ golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1508,8 +1508,8 @@ google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= -google.golang.org/api v0.180.0 h1:M2D87Yo0rGBPWpo1orwfCLehUUL6E7/TYe5gvMQWDh4= -google.golang.org/api v0.180.0/go.mod h1:51AiyoEg1MJPSZ9zvklA8VnRILPXxn1iVen9v25XHAE= +google.golang.org/api v0.186.0 h1:n2OPp+PPXX0Axh4GuSsL5QL8xQCTb2oDwyzPnQvqUug= +google.golang.org/api v0.186.0/go.mod h1:hvRbBmgoje49RV3xqVXrmP6w93n6ehGgIVPYrGtBFFc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1625,8 +1625,8 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda h1:wu/KJm9KJwpfHWhkkZGohVC6KRrc1oJNr4jwtQMOQXw= -google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda/go.mod h1:g2LLCvCeCSir/JJSWosk19BR4NVxGqHUC6rxIRsd7Aw= +google.golang.org/genproto v0.0.0-20240701130421-f6361c86f094 h1:6whtk83KtD3FkGrVb2hFXuQ+ZMbCNdakARIn/aHMmG8= +google.golang.org/genproto v0.0.0-20240701130421-f6361c86f094/go.mod h1:Zs4wYw8z1zr6RNF4cwYb31mvN/EGaKAdQjNCF3DW6K4= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs=