diff --git a/go.mod b/go.mod index 4e5a8a3ebe4..bb7f1704c11 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ replace github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.2021 require ( cosmossdk.io/api v0.9.2 + cosmossdk.io/collections v1.2.0 cosmossdk.io/core v0.11.3 cosmossdk.io/errors v1.0.2 cosmossdk.io/log v1.5.1 @@ -41,7 +42,6 @@ require ( cloud.google.com/go/iam v1.2.2 // indirect cloud.google.com/go/monitoring v1.21.2 // indirect cloud.google.com/go/storage v1.49.0 // indirect - cosmossdk.io/collections v1.2.0 // indirect cosmossdk.io/depinject v1.2.0 // indirect cosmossdk.io/schema v1.1.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect diff --git a/modules/apps/27-gmp/ibc_module.go b/modules/apps/27-gmp/ibc_module.go new file mode 100644 index 00000000000..aa912c921f8 --- /dev/null +++ b/modules/apps/27-gmp/ibc_module.go @@ -0,0 +1,130 @@ +package gmp + +import ( + "fmt" + + errorsmod "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/keeper" + "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" + clienttypes "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" + channeltypesv2 "github.com/cosmos/ibc-go/v10/modules/core/04-channel/v2/types" + "github.com/cosmos/ibc-go/v10/modules/core/api" + ibcerrors "github.com/cosmos/ibc-go/v10/modules/core/errors" +) + +var _ api.IBCModule = (*IBCModule)(nil) + +// IBCModule implements the ICS26 interface for transfer given the transfer keeper. +type IBCModule struct { + keeper keeper.Keeper +} + +// NewIBCModule creates a new IBCModule given the keeper +func NewIBCModule(k keeper.Keeper) *IBCModule { + return &IBCModule{ + keeper: k, + } +} + +func (*IBCModule) OnSendPacket(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, payload channeltypesv2.Payload, signer sdk.AccAddress) error { + if payload.SourcePort != types.PortID || payload.DestinationPort != types.PortID { + return errorsmod.Wrapf(channeltypesv2.ErrInvalidPacket, "payload port ID is invalid: expected %s, got sourcePort: %s destPort: %s", types.PortID, payload.SourcePort, payload.DestinationPort) + } + if !clienttypes.IsValidClientID(sourceChannel) || !clienttypes.IsValidClientID(destinationChannel) { + return errorsmod.Wrapf(channeltypesv2.ErrInvalidPacket, "client IDs must be in valid format: {string}-{number}") + } + + data, err := types.UnmarshalPacketData(payload.Value, payload.Version, payload.Encoding) + if err != nil { + return err + } + + if err := data.ValidateBasic(); err != nil { + return errorsmod.Wrapf(err, "failed to validate %s packet data", types.Version) + } + + sender, err := sdk.AccAddressFromBech32(data.Sender) + if err != nil { + return err + } + + if !signer.Equals(sender) { + return errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "sender %s is different from signer %s", sender, signer) + } + + // TODO: emit event and telemetry + + return nil +} + +func (im *IBCModule) OnRecvPacket(ctx sdk.Context, sourceChannel, destinationChannel string, sequence uint64, payload channeltypesv2.Payload, relayer sdk.AccAddress) channeltypesv2.RecvPacketResult { + if payload.SourcePort != types.PortID || payload.DestinationPort != types.PortID { + return channeltypesv2.RecvPacketResult{ + Status: channeltypesv2.PacketStatus_Failure, + } + } + if payload.Version != types.Version { + return channeltypesv2.RecvPacketResult{ + Status: channeltypesv2.PacketStatus_Failure, + } + } + + packetData, ackErr := types.UnmarshalPacketData(payload.Value, payload.Version, payload.Encoding) + if ackErr != nil { + im.keeper.Logger(ctx).Error(fmt.Sprintf("%s sequence %d", ackErr.Error(), sequence)) + return channeltypesv2.RecvPacketResult{ + Status: channeltypesv2.PacketStatus_Failure, + } + } + + if ackErr := packetData.ValidateBasic(); ackErr != nil { + im.keeper.Logger(ctx).Error(fmt.Sprintf("%s sequence %d", ackErr.Error(), sequence)) + return channeltypesv2.RecvPacketResult{ + Status: channeltypesv2.PacketStatus_Failure, + } + } + + result, ackErr := im.keeper.OnRecvPacket( + ctx, + packetData, + payload.SourcePort, + sourceChannel, + payload.DestinationPort, + destinationChannel, + ) + if ackErr != nil { + im.keeper.Logger(ctx).Error(fmt.Sprintf("%s sequence %d", ackErr.Error(), sequence)) + return channeltypesv2.RecvPacketResult{ + Status: channeltypesv2.PacketStatus_Failure, + } + } + + ack := types.NewAcknowledgement(result) + ackBz, ackErr := types.MarshalAcknowledgement(&ack, types.Version, payload.Encoding) + if ackErr != nil { + im.keeper.Logger(ctx).Error(fmt.Sprintf("%s sequence %d", ackErr.Error(), sequence)) + return channeltypesv2.RecvPacketResult{ + Status: channeltypesv2.PacketStatus_Failure, + } + } + + im.keeper.Logger(ctx).Info("successfully handled ICS-27 GMP packet", "sequence", sequence) + + // TODO: implement telemetry + + return channeltypesv2.RecvPacketResult{ + Status: channeltypesv2.PacketStatus_Success, + Acknowledgement: ackBz, + } +} + +func (*IBCModule) OnTimeoutPacket(_ sdk.Context, _, _ string, _ uint64, _ channeltypesv2.Payload, _ sdk.AccAddress) error { + return nil +} + +func (*IBCModule) OnAcknowledgementPacket(_ sdk.Context, _, _ string, _ uint64, _ []byte, _ channeltypesv2.Payload, _ sdk.AccAddress) error { + return nil +} diff --git a/modules/apps/27-gmp/keeper/account.go b/modules/apps/27-gmp/keeper/account.go new file mode 100644 index 00000000000..8c807f2acca --- /dev/null +++ b/modules/apps/27-gmp/keeper/account.go @@ -0,0 +1,66 @@ +package keeper + +import ( + "context" + + "cosmossdk.io/collections" + errorsmod "cosmossdk.io/errors" + + "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" +) + +// getOrCreateICS27Account retrieves an existing ICS27 account or creates a new one if it doesn't exist. +func (k Keeper) getOrCreateICS27Account(ctx context.Context, accountID *types.AccountIdentifier) (*types.ICS27Account, error) { + existingIcs27Account, err := k.Accounts.Get(ctx, collections.Join3(accountID.ClientId, accountID.Sender, accountID.Salt)) + if err == nil { + return &existingIcs27Account, nil + } else if !errorsmod.IsOf(err, collections.ErrNotFound) { + return nil, err + } + + // Create a new account + newAddr, err := types.BuildAddressPredictable(accountID) + if err != nil { + return nil, err + } + + existingAcc := k.accountKeeper.GetAccount(ctx, newAddr) + if existingAcc != nil { + // TODO: ensure this cannot be abused (refactor after this is resolved) + ics27Account := types.NewICS27Account(existingAcc.GetAddress().String(), accountID) + if err := k.Accounts.Set(ctx, collections.Join3(accountID.ClientId, accountID.Sender, accountID.Salt), ics27Account); err != nil { + return nil, errorsmod.Wrapf(err, "failed to set account %s in store", ics27Account) + } + + return &ics27Account, nil + } + + newAcc := k.accountKeeper.NewAccountWithAddress(ctx, newAddr) + k.accountKeeper.SetAccount(ctx, newAcc) + + ics27Account := types.NewICS27Account(newAcc.GetAddress().String(), accountID) + if err := k.Accounts.Set(ctx, collections.Join3(accountID.ClientId, accountID.Sender, accountID.Salt), ics27Account); err != nil { + return nil, errorsmod.Wrapf(err, "failed to set account %s in store", ics27Account) + } + + k.Logger(ctx).Info("Created new ICS27 account", "account", ics27Account) + return &ics27Account, nil +} + +// getOrComputeICS27Adderss retrieves an existing ICS27 account address or computes it if it doesn't exist. This doesn't modify the store. +func (k Keeper) getOrComputeICS27Address(ctx context.Context, accountID *types.AccountIdentifier) (string, error) { + existingIcs27Account, err := k.Accounts.Get(ctx, collections.Join3(accountID.ClientId, accountID.Sender, accountID.Salt)) + if err == nil { + return existingIcs27Account.Address, nil + } else if !errorsmod.IsOf(err, collections.ErrNotFound) { + return "", err + } + + // Compute a new address + newAddr, err := types.BuildAddressPredictable(accountID) + if err != nil { + return "", err + } + + return newAddr.String(), nil +} diff --git a/modules/apps/27-gmp/keeper/genesis.go b/modules/apps/27-gmp/keeper/genesis.go new file mode 100644 index 00000000000..c45447f4ca3 --- /dev/null +++ b/modules/apps/27-gmp/keeper/genesis.go @@ -0,0 +1,53 @@ +package keeper + +import ( + "context" + + "cosmossdk.io/collections" + errorsmod "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" + ibcerrors "github.com/cosmos/ibc-go/v10/modules/core/errors" +) + +// InitGenesis initializes the module state from a genesis state. +func (k *Keeper) InitGenesis(ctx context.Context, data *types.GenesisState) error { + for _, account := range data.Ics27Accounts { + if _, err := sdk.AccAddressFromBech32(account.AccountAddress); err != nil { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + } + if _, err := sdk.AccAddressFromBech32(account.AccountId.Sender); err != nil { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + } + + if err := k.Accounts.Set(ctx, collections.Join3(account.AccountId.ClientId, account.AccountId.Sender, account.AccountId.Salt), types.ICS27Account{ + Address: account.AccountAddress, + AccountId: &account.AccountId, + }); err != nil { + return err + } + } + + return nil +} + +// ExportGenesis exports the module state to a genesis state. +func (k *Keeper) ExportGenesis(ctx context.Context) (*types.GenesisState, error) { + var accounts []types.RegisteredICS27Account + if err := k.Accounts.Walk(ctx, nil, func(key collections.Triple[string, string, []byte], value types.ICS27Account) (bool, error) { + accounts = append(accounts, types.RegisteredICS27Account{ + AccountAddress: value.Address, + AccountId: *value.AccountId, + }) + + return false, nil + }); err != nil { + return nil, err + } + + return &types.GenesisState{ + Ics27Accounts: accounts, + }, nil +} diff --git a/modules/apps/27-gmp/keeper/keeper.go b/modules/apps/27-gmp/keeper/keeper.go new file mode 100644 index 00000000000..78118a5a2e8 --- /dev/null +++ b/modules/apps/27-gmp/keeper/keeper.go @@ -0,0 +1,74 @@ +package keeper + +import ( + "context" + "errors" + "strings" + + "cosmossdk.io/collections" + storetypes "cosmossdk.io/core/store" + "cosmossdk.io/log" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" + "github.com/cosmos/ibc-go/v10/modules/core/exported" +) + +// Keeper defines the IBC fungible transfer keeper +type Keeper struct { + cdc codec.Codec + + msgRouter types.MessageRouter + + accountKeeper types.AccountKeeper + + // the address capable of executing a MsgUpdateParams message. Typically, this + // should be the x/gov module account. + authority string + + // state management + Schema collections.Schema + // Accounts is a map of (ClientID, Sender, Salt) to ICS27Account + Accounts collections.Map[collections.Triple[string, string, []byte], types.ICS27Account] +} + +// NewKeeper creates a new Keeper instance +func NewKeeper( + cdc codec.Codec, storeService storetypes.KVStoreService, + accountKeeper types.AccountKeeper, msgRouter types.MessageRouter, + authority string, +) Keeper { + if strings.TrimSpace(authority) == "" { + panic(errors.New("authority must be non-empty")) + } + + sb := collections.NewSchemaBuilder(storeService) + k := Keeper{ + cdc: cdc, + msgRouter: msgRouter, + accountKeeper: accountKeeper, + authority: authority, + Accounts: collections.NewMap(sb, types.AccountsKey, "accounts", collections.TripleKeyCodec(collections.StringKey, collections.StringKey, collections.BytesKey), codec.CollValue[types.ICS27Account](cdc)), + } + + schema, err := sb.Build() + if err != nil { + panic(err) + } + + k.Schema = schema + + return k +} + +// GetAuthority returns the module's authority. +func (k Keeper) GetAuthority() string { + return k.authority +} + +// Logger returns a module-specific logger. +func (Keeper) Logger(goCtx context.Context) log.Logger { + return sdk.UnwrapSDKContext(goCtx).Logger().With("module", "x/"+exported.ModuleName+"-"+types.ModuleName) +} diff --git a/modules/apps/27-gmp/keeper/msg_server.go b/modules/apps/27-gmp/keeper/msg_server.go new file mode 100644 index 00000000000..147aee0c88e --- /dev/null +++ b/modules/apps/27-gmp/keeper/msg_server.go @@ -0,0 +1,83 @@ +package keeper + +import ( + "context" + + "github.com/cosmos/gogoproto/proto" + + errorsmod "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" + channeltypesv2 "github.com/cosmos/ibc-go/v10/modules/core/04-channel/v2/types" + ibcerrors "github.com/cosmos/ibc-go/v10/modules/core/errors" +) + +var _ types.MsgServer = (*Keeper)(nil) + +// SendCall defines the handler for the MsgSendCall message. +func (k Keeper) SendCall(goCtx context.Context, msg *types.MsgSendCall) (*types.MsgSendCallResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + _, err := sdk.AccAddressFromBech32(msg.Sender) + if err != nil { + return nil, err + } + + packetData := types.NewGMPPacketData(msg.Sender, msg.Receiver, msg.Salt, msg.Payload, msg.Memo) + if err := packetData.ValidateBasic(); err != nil { + return nil, errorsmod.Wrapf(err, "failed to validate %s packet data", types.Version) + } + + sequence, err := k.sendPacket(ctx, msg.Encoding, msg.SourceClient, msg.TimeoutTimestamp, packetData) + if err != nil { + return nil, err + } + + k.Logger(ctx).Info("IBC send GMP packet", "sender", msg.Sender, "receiver", msg.Receiver) + + return &types.MsgSendCallResponse{Sequence: sequence}, nil +} + +func (k Keeper) sendPacket(ctx sdk.Context, encoding, sourceClient string, timeoutTimestamp uint64, packetData types.GMPPacketData) (uint64, error) { + if encoding == "" { + encoding = types.EncodingABI + } + + data, err := types.MarshalPacketData(&packetData, types.Version, encoding) + if err != nil { + return 0, err + } + + payload := channeltypesv2.NewPayload(types.PortID, types.PortID, types.Version, encoding, data) + msg := channeltypesv2.NewMsgSendPacket( + sourceClient, timeoutTimestamp, + packetData.Sender, payload, + ) + + handler := k.msgRouter.Handler(msg) + if handler == nil { + return 0, errorsmod.Wrapf(ibcerrors.ErrInvalidRequest, "unrecognized packet type: %T", msg) + } + res, err := handler(ctx, msg) + if err != nil { + return 0, err + } + + // NOTE: The sdk msg handler creates a new EventManager, so events must be correctly propagated back to the current context + ctx.EventManager().EmitEvents(res.GetEvents()) + + // Each individual sdk.Result has exactly one Msg response. We aggregate here. + msgResponse := res.MsgResponses[0] + if msgResponse == nil { + return 0, errorsmod.Wrapf(ibcerrors.ErrLogic, "got nil Msg response for msg %s", sdk.MsgTypeURL(msg)) + } + var sendResponse channeltypesv2.MsgSendPacketResponse + err = proto.Unmarshal(msgResponse.Value, &sendResponse) + if err != nil { + return 0, err + } + + return sendResponse.Sequence, nil +} diff --git a/modules/apps/27-gmp/keeper/query_server.go b/modules/apps/27-gmp/keeper/query_server.go new file mode 100644 index 00000000000..89cdced698d --- /dev/null +++ b/modules/apps/27-gmp/keeper/query_server.go @@ -0,0 +1,28 @@ +package keeper + +import ( + "context" + "encoding/hex" + + "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" +) + +var _ types.QueryServer = (*Keeper)(nil) + +// AccountAddress defines the handler for the Query/AccountAddress RPC method. +func (k Keeper) AccountAddress(ctx context.Context, req *types.QueryAccountAddressRequest) (*types.QueryAccountAddressResponse, error) { + salt, err := hex.DecodeString(req.Salt) + if err != nil { + return nil, err + } + + accountID := types.NewAccountIdentifier(req.ClientId, req.Sender, salt) + address, err := k.getOrComputeICS27Address(ctx, &accountID) + if err != nil { + return nil, err + } + + return &types.QueryAccountAddressResponse{ + AccountAddress: address, + }, nil +} diff --git a/modules/apps/27-gmp/keeper/relay.go b/modules/apps/27-gmp/keeper/relay.go new file mode 100644 index 00000000000..78461f8fb04 --- /dev/null +++ b/modules/apps/27-gmp/keeper/relay.go @@ -0,0 +1,152 @@ +package keeper + +import ( + "bytes" + + "github.com/cosmos/gogoproto/proto" + + errorsmod "cosmossdk.io/errors" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" + ibcerrors "github.com/cosmos/ibc-go/v10/modules/core/errors" +) + +// OnRecvPacket processes a GMP packet. +// Returns the data result of the execution if successful. +func (k Keeper) OnRecvPacket( + ctx sdk.Context, + data *types.GMPPacketData, + sourcePort, + sourceClient, + destPort, + destClient string, +) ([]byte, error) { + accountID := types.NewAccountIdentifier(destClient, data.Sender, data.Salt) + + ics27Acc, err := k.getOrCreateICS27Account(ctx, &accountID) + if err != nil { + return nil, err + } + + ics27Addr, err := sdk.AccAddressFromBech32(ics27Acc.Address) + if err != nil { + return nil, err + } + + ics27SdkAcc := k.accountKeeper.GetAccount(ctx, ics27Addr) + if ics27SdkAcc == nil { + return nil, errorsmod.Wrapf(types.ErrAccountNotFound, "account %s not found", ics27Addr) + } + + txResponse, err := k.executeTx(ctx, ics27SdkAcc, data.Payload) + if err != nil { + return nil, errorsmod.Wrapf(err, "failed to execute ICS27 account transaction") + } + + return txResponse, nil +} + +// executeTx attempts to execute the provided transaction. It begins by authenticating the transaction signer. +// If authentication succeeds, it does basic validation of the messages before attempting to deliver each message +// into state. The state changes will only be committed if all messages in the transaction succeed. Thus the +// execution of the transaction is atomic, all state changes are reverted if a single message fails. +func (k Keeper) executeTx(ctx sdk.Context, account sdk.AccountI, payload []byte) ([]byte, error) { + msgs, err := types.DeserializeCosmosTx(k.cdc, payload) + if err != nil { + return nil, errorsmod.Wrapf(err, "failed to deserialize ICS27 CosmosTx") + } + + if err := k.authenticateTx(ctx, account, msgs); err != nil { + return nil, err + } + + txMsgData := &sdk.TxMsgData{ + MsgResponses: make([]*codectypes.Any, len(msgs)), + } + + // CacheContext returns a new context with the multi-store branched into a cached storage object + // writeCache is called only if all msgs succeed, performing state transitions atomically + cacheCtx, writeCache := ctx.CacheContext() + for i, msg := range msgs { + if m, ok := msg.(sdk.HasValidateBasic); ok { + if err := m.ValidateBasic(); err != nil { + return nil, err + } + } + + protoAny, err := k.executeMsg(cacheCtx, msg) + if err != nil { + ctx.Logger().Error("failed to execute 27-gmp message", "msg", msg, "error", err) + return nil, err + } + + txMsgData.MsgResponses[i] = protoAny + } + + writeCache() + + ctx.Logger().Info("executed 27-gmp transaction", "account", account.GetAddress(), "msgs", msgs) + + txResponse, err := proto.Marshal(txMsgData) + if err != nil { + return nil, errorsmod.Wrap(err, "failed to marshal tx data") + } + + return txResponse, nil +} + +// authenticateTx checks that the transaction is signed by the expected signer. +func (k Keeper) authenticateTx(_ sdk.Context, account sdk.AccountI, msgs []sdk.Msg) error { + if len(msgs) == 0 { + return errorsmod.Wrapf(types.ErrInvalidPayload, "empty message list") + } + + accountAddr := account.GetAddress() + for _, msg := range msgs { + // obtain the message signers using the proto signer annotations + // the msgv2 return value is discarded as it is not used + signers, _, err := k.cdc.GetMsgV1Signers(msg) + if err != nil { + return errorsmod.Wrapf(err, "failed to obtain message signers for message type %s", sdk.MsgTypeURL(msg)) + } + + for _, signer := range signers { + // the interchain account address is stored as the string value of the sdk.AccAddress type + // thus we must cast the signer to a sdk.AccAddress to obtain the comparison value + // the stored interchain account address must match the signer for every message to be executed + if !bytes.Equal(signer, accountAddr.Bytes()) { + return errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "unexpected signer address: expected %s, got %s", accountAddr, sdk.AccAddress(signer)) + } + } + } + + return nil +} + +// Attempts to get the message handler from the router and if found will then execute the message. +// If the message execution is successful, the proto marshaled message response will be returned. +func (k Keeper) executeMsg(ctx sdk.Context, msg sdk.Msg) (*codectypes.Any, error) { + handler := k.msgRouter.Handler(msg) + if handler == nil { + return nil, types.ErrInvalidMsgRoute + } + + res, err := handler(ctx, msg) + if err != nil { + return nil, err + } + + // NOTE: The sdk msg handler creates a new EventManager, so events must be correctly propagated back to the current context + ctx.EventManager().EmitEvents(res.GetEvents()) + + // Each individual sdk.Result has exactly one Msg response. We aggregate here. + msgResponse := res.MsgResponses[0] + if msgResponse == nil { + return nil, errorsmod.Wrapf(ibcerrors.ErrLogic, "got nil Msg response for msg %s", sdk.MsgTypeURL(msg)) + } + + return msgResponse, nil +} diff --git a/modules/apps/27-gmp/module.go b/modules/apps/27-gmp/module.go new file mode 100644 index 00000000000..4c45f85ffbd --- /dev/null +++ b/modules/apps/27-gmp/module.go @@ -0,0 +1,149 @@ +package gmp + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/grpc-ecosystem/grpc-gateway/runtime" + + autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + "cosmossdk.io/core/appmodule" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + + "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/keeper" + "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" +) + +var ( + _ module.AppModule = (*AppModule)(nil) + _ module.AppModuleBasic = (*AppModule)(nil) + // _ module.AppModuleSimulation = (*AppModule)(nil) + _ module.HasGenesis = (*AppModule)(nil) + _ module.HasName = (*AppModule)(nil) + _ module.HasConsensusVersion = (*AppModule)(nil) + _ module.HasServices = (*AppModule)(nil) + // _ module.HasProposalMsgs = (*AppModule)(nil) + _ appmodule.AppModule = (*AppModule)(nil) +) + +// AppModule represents the AppModule for this module +type AppModule struct { + keeper keeper.Keeper +} + +// NewAppModule creates a new 27-gmp module +func NewAppModule(k keeper.Keeper) AppModule { + return AppModule{ + keeper: k, + } +} + +func NewAppModuleBasic(m AppModule) module.AppModuleBasic { + return module.CoreAppModuleBasicAdaptor(m.Name(), m) +} + +// Name implements AppModuleBasic interface +func (AppModule) Name() string { return types.ModuleName } + +// IsOnePerModuleType implements the depinject.OnePerModuleType interface. +func (AppModule) IsOnePerModuleType() {} + +// IsAppModule implements the appmodule.AppModule interface. +func (AppModule) IsAppModule() {} + +// RegisterLegacyAminoCodec implements AppModuleBasic interface +func (AppModule) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the ics27 module. +func (AppModule) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { + if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil { + panic(err) + } +} + +// RegisterInterfaces registers module concrete types into protobuf Any. +func (AppModule) RegisterInterfaces(registry codectypes.InterfaceRegistry) { + types.RegisterInterfaces(registry) +} + +// ConsensusVersion implements AppModule/ConsensusVersion defining the current version of transfer. +func (AppModule) ConsensusVersion() uint64 { return 1 } + +// DefaultGenesis returns default genesis state as raw bytes for the ibc +// transfer module. +func (AppModule) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(types.DefaultGenesisState()) +} + +// RegisterServices registers module services. +func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterMsgServer(cfg.MsgServer(), am.keeper) + types.RegisterQueryServer(cfg.QueryServer(), am.keeper) +} + +// ValidateGenesis performs genesis state validation for the ibc transfer module. +func (AppModule) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { + var gs types.GenesisState + if err := cdc.UnmarshalJSON(bz, &gs); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) + } + + return gs.Validate() +} + +// AutoCLIOptions implements the autocli.HasAutoCLIConfig interface. +func (AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { + return types.AutoCLIOptions() +} + +// InitGenesis performs genesis initialization for the ibc-transfer module. It returns +// no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) { + var genesisState types.GenesisState + cdc.MustUnmarshalJSON(data, &genesisState) + err := am.keeper.InitGenesis(ctx, &genesisState) + if err != nil { + panic(fmt.Errorf("failed to initialize %s genesis state: %w", types.ModuleName, err)) + } +} + +// ExportGenesis returns the exported genesis state as raw bytes for the ibc-transfer +// module. +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + gs, err := am.keeper.ExportGenesis(ctx) + if err != nil { + panic(fmt.Errorf("failed to export %s genesis state: %w", types.ModuleName, err)) + } + + return cdc.MustMarshalJSON(gs) +} + +/* +// AppModuleSimulation functions + +// GenerateGenesisState creates a randomized GenState of the transfer module. +func (AppModule) GenerateGenesisState(simState *module.SimulationState) { + simulation.RandomizedGenState(simState) +} + +// ProposalMsgs returns msgs used for governance proposals for simulations. +func (AppModule) ProposalMsgs(simState module.SimulationState) []simtypes.WeightedProposalMsg { + return simulation.ProposalMsgs() +} + +// RegisterStoreDecoder registers a decoder for transfer module's types +func (AppModule) RegisterStoreDecoder(sdr simtypes.StoreDecoderRegistry) { + sdr[types.StoreKey] = simulation.NewDecodeStore() +} + +// WeightedOperations returns the all the transfer module operations with their respective weights. +func (AppModule) WeightedOperations(_ module.SimulationState) []simtypes.WeightedOperation { + return nil +} +*/ diff --git a/modules/apps/27-gmp/types/account.go b/modules/apps/27-gmp/types/account.go new file mode 100644 index 00000000000..b4c96b73340 --- /dev/null +++ b/modules/apps/27-gmp/types/account.go @@ -0,0 +1,117 @@ +package types + +import ( + "strings" + + "github.com/cosmos/gogoproto/proto" + + errorsmod "cosmossdk.io/errors" + + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" + + host "github.com/cosmos/ibc-go/v10/modules/core/24-host" + ibcerrors "github.com/cosmos/ibc-go/v10/modules/core/errors" +) + +// NewAccountIdentifier creates a new AccountIdentifier with the given clientId, sender, and salt. +func NewAccountIdentifier(clientID, sender string, salt []byte) AccountIdentifier { + return AccountIdentifier{ + ClientId: clientID, + Sender: sender, + Salt: salt, + } +} + +// NewICS27Account creates a new ICS27Account with the given address and accountId. +func NewICS27Account(addr string, accountID *AccountIdentifier) ICS27Account { + return ICS27Account{ + Address: addr, + AccountId: accountID, + } +} + +// BuildAddressPredictable generates an account address for the gmp module with len = types.AccountAddrLen using the +// Cosmos SDK address.Module function. +// Internally a key is built containing: +// (len(clientId) | clientId | len(sender) | sender | len(salt) | salt). +// +// All method parameter values must be valid and not nil. +// +// This function was copied from wasmd and modified. +// +func BuildAddressPredictable(accountID *AccountIdentifier) (sdk.AccAddress, error) { + if err := host.ClientIdentifierValidator(accountID.ClientId); err != nil { + return nil, errorsmod.Wrapf(err, "invalid client ID %s", accountID.ClientId) + } + if strings.TrimSpace(accountID.Sender) == "" { + return nil, errorsmod.Wrap(ibcerrors.ErrInvalidAddress, "missing sender address") + } + + clientIDBz := uint64LengthPrefix([]byte(accountID.ClientId)) + senderBz := uint64LengthPrefix([]byte(accountID.Sender)) + saltBz := uint64LengthPrefix(accountID.Salt) + key := make([]byte, len(clientIDBz)+len(senderBz)+len(saltBz)) + copy(key[0:], clientIDBz) + copy(key[len(clientIDBz):], senderBz) + copy(key[len(clientIDBz)+len(senderBz):], saltBz) + return address.Module(accountsKey, key)[:AccountAddrLen], nil +} + +// uint64LengthPrefix prepend big endian encoded byte length +func uint64LengthPrefix(bz []byte) []byte { + return append(sdk.Uint64ToBigEndian(uint64(len(bz))), bz...) +} + +// DeserializeCosmosTx unmarshals and unpacks a slice of transaction bytes into a slice of sdk.Msg's. +// The transaction bytes are unmarshaled depending on the encoding type passed in. The sdk.Msg's are +// unpacked from Any's and returned. +func DeserializeCosmosTx(cdc codec.BinaryCodec, data []byte) ([]sdk.Msg, error) { + var cosmosTx CosmosTx + if err := cdc.Unmarshal(data, &cosmosTx); err != nil { + return nil, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "cannot unmarshal CosmosTx with protobuf: %v", err) + } + + msgs := make([]sdk.Msg, len(cosmosTx.Messages)) + + for i, protoAny := range cosmosTx.Messages { + var msg sdk.Msg + err := cdc.UnpackAny(protoAny, &msg) + if err != nil { + return nil, err + } + msgs[i] = msg + } + + return msgs, nil +} + +// SerializeCosmosTx serializes a slice of sdk.Msg's using the CosmosTx type. The sdk.Msg's are +// packed into Any's and inserted into the Messages field of a CosmosTx. The CosmosTx is marshaled +// depending on the encoding type passed in. The marshaled bytes are returned. +func SerializeCosmosTx(cdc codec.BinaryCodec, msgs []proto.Message) ([]byte, error) { + var ( + bz []byte + err error + ) + msgAnys := make([]*codectypes.Any, len(msgs)) + for i, msg := range msgs { + msgAnys[i], err = codectypes.NewAnyWithValue(msg) + if err != nil { + return nil, err + } + } + + cosmosTx := &CosmosTx{ + Messages: msgAnys, + } + + bz, err = cdc.Marshal(cosmosTx) + if err != nil { + return nil, errorsmod.Wrapf(err, "cannot marshal CosmosTx with protobuf") + } + + return bz, nil +} diff --git a/modules/apps/27-gmp/types/account.pb.go b/modules/apps/27-gmp/types/account.pb.go new file mode 100644 index 00000000000..22288175f99 --- /dev/null +++ b/modules/apps/27-gmp/types/account.pb.go @@ -0,0 +1,853 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ibc/applications/gmp/v1/account.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + types "github.com/cosmos/cosmos-sdk/codec/types" + proto "github.com/cosmos/gogoproto/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// AccountIdentifier is used to identify a ICS27 account. +type AccountIdentifier struct { + // The (local) client identifier + ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` + // The sender of the packet + Sender string `protobuf:"bytes,2,opt,name=sender,proto3" json:"sender,omitempty"` + // The salt of the packet + Salt []byte `protobuf:"bytes,3,opt,name=salt,proto3" json:"salt,omitempty"` +} + +func (m *AccountIdentifier) Reset() { *m = AccountIdentifier{} } +func (m *AccountIdentifier) String() string { return proto.CompactTextString(m) } +func (*AccountIdentifier) ProtoMessage() {} +func (*AccountIdentifier) Descriptor() ([]byte, []int) { + return fileDescriptor_5d5b886ccdedc1db, []int{0} +} +func (m *AccountIdentifier) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AccountIdentifier) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AccountIdentifier.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *AccountIdentifier) XXX_Merge(src proto.Message) { + xxx_messageInfo_AccountIdentifier.Merge(m, src) +} +func (m *AccountIdentifier) XXX_Size() int { + return m.Size() +} +func (m *AccountIdentifier) XXX_DiscardUnknown() { + xxx_messageInfo_AccountIdentifier.DiscardUnknown(m) +} + +var xxx_messageInfo_AccountIdentifier proto.InternalMessageInfo + +func (m *AccountIdentifier) GetClientId() string { + if m != nil { + return m.ClientId + } + return "" +} + +func (m *AccountIdentifier) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +func (m *AccountIdentifier) GetSalt() []byte { + if m != nil { + return m.Salt + } + return nil +} + +// An ICS27Account is defined as a BaseAccount & the account identifier +type ICS27Account struct { + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + AccountId *AccountIdentifier `protobuf:"bytes,2,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"` +} + +func (m *ICS27Account) Reset() { *m = ICS27Account{} } +func (m *ICS27Account) String() string { return proto.CompactTextString(m) } +func (*ICS27Account) ProtoMessage() {} +func (*ICS27Account) Descriptor() ([]byte, []int) { + return fileDescriptor_5d5b886ccdedc1db, []int{1} +} +func (m *ICS27Account) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ICS27Account) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ICS27Account.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ICS27Account) XXX_Merge(src proto.Message) { + xxx_messageInfo_ICS27Account.Merge(m, src) +} +func (m *ICS27Account) XXX_Size() int { + return m.Size() +} +func (m *ICS27Account) XXX_DiscardUnknown() { + xxx_messageInfo_ICS27Account.DiscardUnknown(m) +} + +var xxx_messageInfo_ICS27Account proto.InternalMessageInfo + +func (m *ICS27Account) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *ICS27Account) GetAccountId() *AccountIdentifier { + if m != nil { + return m.AccountId + } + return nil +} + +// CosmosTx contains a list of sdk.Msg's. It should be used when sending transactions to an SDK host chain. +type CosmosTx struct { + Messages []*types.Any `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages,omitempty"` +} + +func (m *CosmosTx) Reset() { *m = CosmosTx{} } +func (m *CosmosTx) String() string { return proto.CompactTextString(m) } +func (*CosmosTx) ProtoMessage() {} +func (*CosmosTx) Descriptor() ([]byte, []int) { + return fileDescriptor_5d5b886ccdedc1db, []int{2} +} +func (m *CosmosTx) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CosmosTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CosmosTx.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *CosmosTx) XXX_Merge(src proto.Message) { + xxx_messageInfo_CosmosTx.Merge(m, src) +} +func (m *CosmosTx) XXX_Size() int { + return m.Size() +} +func (m *CosmosTx) XXX_DiscardUnknown() { + xxx_messageInfo_CosmosTx.DiscardUnknown(m) +} + +var xxx_messageInfo_CosmosTx proto.InternalMessageInfo + +func (m *CosmosTx) GetMessages() []*types.Any { + if m != nil { + return m.Messages + } + return nil +} + +func init() { + proto.RegisterType((*AccountIdentifier)(nil), "ibc.applications.gmp.v1.AccountIdentifier") + proto.RegisterType((*ICS27Account)(nil), "ibc.applications.gmp.v1.ICS27Account") + proto.RegisterType((*CosmosTx)(nil), "ibc.applications.gmp.v1.CosmosTx") +} + +func init() { + proto.RegisterFile("ibc/applications/gmp/v1/account.proto", fileDescriptor_5d5b886ccdedc1db) +} + +var fileDescriptor_5d5b886ccdedc1db = []byte{ + // 370 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x51, 0x41, 0x8b, 0xda, 0x40, + 0x18, 0x35, 0xb5, 0x58, 0x1d, 0xbd, 0x74, 0x90, 0x36, 0x5a, 0x08, 0x22, 0x14, 0xa4, 0xe0, 0x8c, + 0xa6, 0x50, 0x2f, 0xbd, 0xa8, 0xa7, 0xdc, 0x4a, 0xec, 0xa9, 0x14, 0x64, 0x32, 0x19, 0x67, 0x07, + 0x92, 0x99, 0x90, 0x99, 0xc8, 0xfa, 0x23, 0x16, 0xf6, 0xc7, 0xec, 0x8f, 0xd8, 0xa3, 0xec, 0x69, + 0x8f, 0x8b, 0xfe, 0x91, 0x25, 0x99, 0xb8, 0x2c, 0x2c, 0x7b, 0xcb, 0xfb, 0xde, 0xcb, 0xf7, 0xde, + 0xbc, 0x0f, 0x7c, 0x17, 0x11, 0xc5, 0x24, 0xcb, 0x12, 0x41, 0x89, 0x11, 0x4a, 0x6a, 0xcc, 0xd3, + 0x0c, 0xef, 0xe7, 0x98, 0x50, 0xaa, 0x0a, 0x69, 0x50, 0x96, 0x2b, 0xa3, 0xe0, 0x57, 0x11, 0x51, + 0xf4, 0x5a, 0x86, 0x78, 0x9a, 0xa1, 0xfd, 0x7c, 0x38, 0xe0, 0x4a, 0xf1, 0x84, 0xe1, 0x4a, 0x16, + 0x15, 0x3b, 0x4c, 0xe4, 0xc1, 0xfe, 0x33, 0x1c, 0x50, 0xa5, 0x53, 0xa5, 0xb7, 0x15, 0xc2, 0x16, + 0x58, 0x6a, 0xfc, 0x1f, 0x7c, 0x5e, 0xda, 0xfd, 0x41, 0xcc, 0xa4, 0x11, 0x3b, 0xc1, 0x72, 0xf8, + 0x0d, 0x74, 0x68, 0x22, 0x98, 0x34, 0x5b, 0x11, 0xbb, 0xce, 0xc8, 0x99, 0x74, 0xc2, 0xb6, 0x1d, + 0x04, 0x31, 0xfc, 0x02, 0x5a, 0x9a, 0xc9, 0x98, 0xe5, 0xee, 0x87, 0x8a, 0xa9, 0x11, 0x84, 0xe0, + 0xa3, 0x26, 0x89, 0x71, 0x9b, 0x23, 0x67, 0xd2, 0x0b, 0xab, 0xef, 0xf1, 0x8d, 0x03, 0x7a, 0xc1, + 0x7a, 0xe3, 0x2f, 0x6a, 0x0f, 0xe8, 0x83, 0x4f, 0x24, 0x8e, 0x73, 0xa6, 0xb5, 0xdd, 0xbb, 0x72, + 0x1f, 0xee, 0xa6, 0xfd, 0x3a, 0xd1, 0xd2, 0x32, 0x1b, 0x93, 0x0b, 0xc9, 0xc3, 0x8b, 0x10, 0x06, + 0x00, 0xd4, 0x15, 0x94, 0x71, 0x4a, 0xd3, 0xae, 0xff, 0x03, 0xbd, 0x53, 0x03, 0x7a, 0xf3, 0x9a, + 0xb0, 0x43, 0x2e, 0xa3, 0xf1, 0x6f, 0xd0, 0x5e, 0x57, 0x5e, 0x7f, 0xaf, 0xe1, 0x0c, 0xb4, 0x53, + 0xa6, 0x35, 0xe1, 0xac, 0xcc, 0xd2, 0x9c, 0x74, 0xfd, 0x3e, 0xb2, 0x15, 0xa2, 0x4b, 0x85, 0x68, + 0x29, 0x0f, 0xe1, 0x8b, 0x6a, 0xf5, 0xe7, 0xfe, 0xe4, 0x39, 0xc7, 0x93, 0xe7, 0x3c, 0x9d, 0x3c, + 0xe7, 0xf6, 0xec, 0x35, 0x8e, 0x67, 0xaf, 0xf1, 0x78, 0xf6, 0x1a, 0xff, 0x7e, 0x71, 0x61, 0xae, + 0x8a, 0x08, 0x51, 0x95, 0xd6, 0xf5, 0x62, 0x11, 0xd1, 0x29, 0x57, 0x78, 0x3f, 0x9f, 0xe1, 0x54, + 0xc5, 0x45, 0xc2, 0x74, 0x79, 0x5c, 0x8d, 0xfd, 0xc5, 0xb4, 0xbc, 0xab, 0x39, 0x64, 0x4c, 0x47, + 0xad, 0xca, 0xe9, 0xe7, 0x73, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7c, 0x58, 0xaf, 0x6b, 0xfc, 0x01, + 0x00, 0x00, +} + +func (m *AccountIdentifier) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AccountIdentifier) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AccountIdentifier) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Salt) > 0 { + i -= len(m.Salt) + copy(dAtA[i:], m.Salt) + i = encodeVarintAccount(dAtA, i, uint64(len(m.Salt))) + i-- + dAtA[i] = 0x1a + } + if len(m.Sender) > 0 { + i -= len(m.Sender) + copy(dAtA[i:], m.Sender) + i = encodeVarintAccount(dAtA, i, uint64(len(m.Sender))) + i-- + dAtA[i] = 0x12 + } + if len(m.ClientId) > 0 { + i -= len(m.ClientId) + copy(dAtA[i:], m.ClientId) + i = encodeVarintAccount(dAtA, i, uint64(len(m.ClientId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ICS27Account) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ICS27Account) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ICS27Account) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.AccountId != nil { + { + size, err := m.AccountId.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAccount(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintAccount(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *CosmosTx) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CosmosTx) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CosmosTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Messages) > 0 { + for iNdEx := len(m.Messages) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Messages[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAccount(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintAccount(dAtA []byte, offset int, v uint64) int { + offset -= sovAccount(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *AccountIdentifier) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ClientId) + if l > 0 { + n += 1 + l + sovAccount(uint64(l)) + } + l = len(m.Sender) + if l > 0 { + n += 1 + l + sovAccount(uint64(l)) + } + l = len(m.Salt) + if l > 0 { + n += 1 + l + sovAccount(uint64(l)) + } + return n +} + +func (m *ICS27Account) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovAccount(uint64(l)) + } + if m.AccountId != nil { + l = m.AccountId.Size() + n += 1 + l + sovAccount(uint64(l)) + } + return n +} + +func (m *CosmosTx) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Messages) > 0 { + for _, e := range m.Messages { + l = e.Size() + n += 1 + l + sovAccount(uint64(l)) + } + } + return n +} + +func sovAccount(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozAccount(x uint64) (n int) { + return sovAccount(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *AccountIdentifier) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAccount + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AccountIdentifier: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AccountIdentifier: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ClientId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAccount + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAccount + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAccount + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ClientId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAccount + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAccount + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAccount + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sender = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Salt", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAccount + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAccount + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAccount + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Salt = append(m.Salt[:0], dAtA[iNdEx:postIndex]...) + if m.Salt == nil { + m.Salt = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAccount(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAccount + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ICS27Account) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAccount + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ICS27Account: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ICS27Account: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAccount + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAccount + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAccount + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AccountId", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAccount + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAccount + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAccount + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AccountId == nil { + m.AccountId = &AccountIdentifier{} + } + if err := m.AccountId.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAccount(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAccount + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CosmosTx) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAccount + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CosmosTx: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CosmosTx: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Messages", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAccount + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAccount + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAccount + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Messages = append(m.Messages, &types.Any{}) + if err := m.Messages[len(m.Messages)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAccount(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAccount + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipAccount(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowAccount + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowAccount + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowAccount + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthAccount + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupAccount + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthAccount + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthAccount = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowAccount = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupAccount = fmt.Errorf("proto: unexpected end of group") +) diff --git a/modules/apps/27-gmp/types/ack.go b/modules/apps/27-gmp/types/ack.go new file mode 100644 index 00000000000..6f67c6da196 --- /dev/null +++ b/modules/apps/27-gmp/types/ack.go @@ -0,0 +1,74 @@ +package types + +import ( + "encoding/json" + + "github.com/cosmos/gogoproto/proto" + + errorsmod "cosmossdk.io/errors" + + "github.com/cosmos/cosmos-sdk/codec/unknownproto" + + ibcerrors "github.com/cosmos/ibc-go/v10/modules/core/errors" +) + +// NewAcknowledgement creates a new Acknowledgement +func NewAcknowledgement(result []byte) Acknowledgement { + return Acknowledgement{ + Result: result, + } +} + +// ValidateBasic performs basic validation on the Acknowledgement +func (Acknowledgement) ValidateBasic() error { + return nil +} + +func MarshalAcknowledgement(data *Acknowledgement, ics27Version string, encoding string) ([]byte, error) { + if ics27Version != Version { + panic("unsupported ics27 version") + } + + switch encoding { + case EncodingJSON: + return json.Marshal(data) + case EncodingProtobuf: + return proto.Marshal(data) + case EncodingABI: + return EncodeABIAcknowledgement(data) + default: + return nil, errorsmod.Wrapf(ErrInvalidEncoding, "invalid encoding provided, must be either empty or one of [%q, %q, %q], got %s", EncodingJSON, EncodingProtobuf, EncodingABI, encoding) + } +} + +func UnmarshalAcknowledgement(bz []byte, ics27Version string, encoding string) (*Acknowledgement, error) { + if ics27Version != Version { + panic("unsupported ics27 version") + } + + var data *Acknowledgement + switch encoding { + case EncodingJSON: + if err := json.Unmarshal(bz, &data); err != nil { + return nil, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "failed to unmarshal json packet data: %s", err) + } + case EncodingProtobuf: + if err := unknownproto.RejectUnknownFieldsStrict(bz, data, unknownproto.DefaultAnyResolver{}); err != nil { + return nil, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "failed to unmarshal protobuf packet data: %s", err) + } + + if err := proto.Unmarshal(bz, data); err != nil { + return nil, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "failed to unmarshal protobuf packet data: %s", err) + } + case EncodingABI: + var err error + data, err = DecodeABIAcknowledgement(bz) + if err != nil { + return nil, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "failed to unmarshal ABI packet data: %s", err) + } + default: + return nil, errorsmod.Wrapf(ErrInvalidEncoding, "invalid encoding provided, must be either empty or one of [%q, %q, %q], got %s", EncodingJSON, EncodingProtobuf, EncodingABI, encoding) + } + + return data, nil +} diff --git a/modules/apps/27-gmp/types/autocli.go b/modules/apps/27-gmp/types/autocli.go new file mode 100644 index 00000000000..ddddf306067 --- /dev/null +++ b/modules/apps/27-gmp/types/autocli.go @@ -0,0 +1,46 @@ +package types + +import ( + autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" +) + +// AutoCLIOptions implements the autocli.HasAutoCLIConfig interface. +func AutoCLIOptions() *autocliv1.ModuleOptions { + return &autocliv1.ModuleOptions{ + Query: &autocliv1.ServiceCommandDescriptor{ + Service: _Query_serviceDesc.ServiceName, + RpcCommandOptions: []*autocliv1.RpcCommandOptions{ + { + RpcMethod: "AccountAddress", + Use: "get-address [client_id] [sender] [salt]", + Short: "Get or pre-compute the address of an ICS27 GMP account", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "client_id"}, + {ProtoField: "sender"}, + {ProtoField: "salt"}, + }, + }, + }, + }, + Tx: &autocliv1.ServiceCommandDescriptor{ + Service: _Msg_serviceDesc.ServiceName, + RpcCommandOptions: []*autocliv1.RpcCommandOptions{ + { + RpcMethod: "SendCall", + Use: "send-call [source_client] [sender] [receiver] [salt] [payload] [timeout_timestamp] [memo] [encoding]", + Short: "Send a call to an ICS27 GMP account", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "source_client"}, + {ProtoField: "sender"}, + {ProtoField: "receiver"}, + {ProtoField: "salt"}, + {ProtoField: "payload"}, + {ProtoField: "timeout_timestamp"}, + {ProtoField: "memo"}, + {ProtoField: "encoding", Optional: true}, + }, + }, + }, + }, + } +} diff --git a/modules/apps/27-gmp/types/codec.go b/modules/apps/27-gmp/types/codec.go new file mode 100644 index 00000000000..7ec8fae40ae --- /dev/null +++ b/modules/apps/27-gmp/types/codec.go @@ -0,0 +1,20 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// ModuleCdc references the global gmp module codec. Note, the codec +// should ONLY be used in certain instances of tests and for JSON encoding. +// +// The actual codec used for serialization should be provided to interchain accounts and +// defined at the application level. +var ModuleCdc = codec.NewProtoCodec(codectypes.NewInterfaceRegistry()) + +// RegisterInterfaces registers the gmp types and the concrete ICS27Account implementation +// against the associated x/auth AccountI and GenesisAccount interfaces. +func RegisterInterfaces(registry codectypes.InterfaceRegistry) { + registry.RegisterImplementations((*sdk.Msg)(nil), &MsgSendCall{}) +} diff --git a/modules/apps/27-gmp/types/errors.go b/modules/apps/27-gmp/types/errors.go new file mode 100644 index 00000000000..af78cee63de --- /dev/null +++ b/modules/apps/27-gmp/types/errors.go @@ -0,0 +1,17 @@ +package types + +import errorsmod "cosmossdk.io/errors" + +var ( + ErrInvalidCodec = errorsmod.Register(ModuleName, 1, "codec is not supported") + ErrInvalidMemo = errorsmod.Register(ModuleName, 2, "invalid memo") + ErrInvalidSalt = errorsmod.Register(ModuleName, 3, "invalid salt") + ErrInvalidPayload = errorsmod.Register(ModuleName, 4, "invalid payload") + ErrInvalidTimeoutTimestamp = errorsmod.Register(ModuleName, 5, "invalid timeout timestamp") + ErrInvalidEncoding = errorsmod.Register(ModuleName, 6, "invalid encoding") + ErrAbiDecoding = errorsmod.Register(ModuleName, 7, "abi decoding error") + ErrAbiEncoding = errorsmod.Register(ModuleName, 8, "abi encoding error") + ErrAccountAlreadyExists = errorsmod.Register(ModuleName, 9, "account already exists") + ErrAccountNotFound = errorsmod.Register(ModuleName, 10, "account not found") + ErrInvalidMsgRoute = errorsmod.Register(ModuleName, 11, "invalid msg route") +) diff --git a/modules/apps/27-gmp/types/expected_keepers.go b/modules/apps/27-gmp/types/expected_keepers.go new file mode 100644 index 00000000000..3b04f77b43c --- /dev/null +++ b/modules/apps/27-gmp/types/expected_keepers.go @@ -0,0 +1,17 @@ +package types + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// AccountKeeper defines a subset of methods implemented by the cosmos-sdk account keeper +type AccountKeeper interface { + // Return a new account with the next account number and the specified address. Does not save the new account to the store. + NewAccountWithAddress(ctx context.Context, addr sdk.AccAddress) sdk.AccountI + // Retrieve an account from the store. + GetAccount(ctx context.Context, addr sdk.AccAddress) sdk.AccountI + // Set an account in the store. + SetAccount(ctx context.Context, acc sdk.AccountI) +} diff --git a/modules/apps/27-gmp/types/genesis.go b/modules/apps/27-gmp/types/genesis.go new file mode 100644 index 00000000000..193c6cf4d01 --- /dev/null +++ b/modules/apps/27-gmp/types/genesis.go @@ -0,0 +1,38 @@ +package types + +import ( + errorsmod "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + + host "github.com/cosmos/ibc-go/v10/modules/core/24-host" + ibcerrors "github.com/cosmos/ibc-go/v10/modules/core/errors" +) + +// DefaultGenesisState returns the default GenesisState. +func DefaultGenesisState() *GenesisState { + return &GenesisState{ + Ics27Accounts: []RegisteredICS27Account{}, + } +} + +// Validate performs basic genesis state validation returning an error upon any +// failure. +func (gs GenesisState) Validate() error { + for _, account := range gs.Ics27Accounts { + if _, err := sdk.AccAddressFromBech32(account.AccountAddress); err != nil { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + } + if _, err := sdk.AccAddressFromBech32(account.AccountId.Sender); err != nil { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + } + if err := host.ClientIdentifierValidator(account.AccountId.ClientId); err != nil { + return errorsmod.Wrapf(err, "invalid source client ID %s", account.AccountId.ClientId) + } + if len(account.AccountId.Salt) > MaximumSaltLength { + return errorsmod.Wrapf(ErrInvalidSalt, "salt must not exceed %d bytes", MaximumSaltLength) + } + } + + return nil +} diff --git a/modules/apps/27-gmp/types/genesis.pb.go b/modules/apps/27-gmp/types/genesis.pb.go new file mode 100644 index 00000000000..0fd1913b2ee --- /dev/null +++ b/modules/apps/27-gmp/types/genesis.pb.go @@ -0,0 +1,566 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ibc/applications/gmp/v1/genesis.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// GenesisState defines the 27-gmp genesis state +type GenesisState struct { + // The list of registered ICS27 accounts + Ics27Accounts []RegisteredICS27Account `protobuf:"bytes,2,rep,name=ics27_accounts,json=ics27Accounts,proto3" json:"ics27_accounts"` +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} +func (*GenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_7cccbdb788964d3f, []int{0} +} +func (m *GenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GenesisState) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisState.Merge(m, src) +} +func (m *GenesisState) XXX_Size() int { + return m.Size() +} +func (m *GenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisState proto.InternalMessageInfo + +func (m *GenesisState) GetIcs27Accounts() []RegisteredICS27Account { + if m != nil { + return m.Ics27Accounts + } + return nil +} + +// RegisteredICS27Account contains an account identifier and associated interchain account address +type RegisteredICS27Account struct { + /// The address of the ics27 account + AccountAddress string `protobuf:"bytes,1,opt,name=account_address,json=accountAddress,proto3" json:"account_address,omitempty"` + /// The account identifier + AccountId AccountIdentifier `protobuf:"bytes,2,opt,name=account_id,json=accountId,proto3" json:"account_id"` +} + +func (m *RegisteredICS27Account) Reset() { *m = RegisteredICS27Account{} } +func (m *RegisteredICS27Account) String() string { return proto.CompactTextString(m) } +func (*RegisteredICS27Account) ProtoMessage() {} +func (*RegisteredICS27Account) Descriptor() ([]byte, []int) { + return fileDescriptor_7cccbdb788964d3f, []int{1} +} +func (m *RegisteredICS27Account) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RegisteredICS27Account) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RegisteredICS27Account.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RegisteredICS27Account) XXX_Merge(src proto.Message) { + xxx_messageInfo_RegisteredICS27Account.Merge(m, src) +} +func (m *RegisteredICS27Account) XXX_Size() int { + return m.Size() +} +func (m *RegisteredICS27Account) XXX_DiscardUnknown() { + xxx_messageInfo_RegisteredICS27Account.DiscardUnknown(m) +} + +var xxx_messageInfo_RegisteredICS27Account proto.InternalMessageInfo + +func (m *RegisteredICS27Account) GetAccountAddress() string { + if m != nil { + return m.AccountAddress + } + return "" +} + +func (m *RegisteredICS27Account) GetAccountId() AccountIdentifier { + if m != nil { + return m.AccountId + } + return AccountIdentifier{} +} + +func init() { + proto.RegisterType((*GenesisState)(nil), "ibc.applications.gmp.v1.GenesisState") + proto.RegisterType((*RegisteredICS27Account)(nil), "ibc.applications.gmp.v1.RegisteredICS27Account") +} + +func init() { + proto.RegisterFile("ibc/applications/gmp/v1/genesis.proto", fileDescriptor_7cccbdb788964d3f) +} + +var fileDescriptor_7cccbdb788964d3f = []byte{ + // 320 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x90, 0x41, 0x4b, 0x3a, 0x41, + 0x18, 0xc6, 0x77, 0xfc, 0xff, 0x09, 0x1c, 0xcb, 0x60, 0x89, 0x12, 0x0f, 0x9b, 0x08, 0x91, 0x04, + 0xce, 0xe4, 0x06, 0x79, 0xd6, 0x0e, 0xe1, 0xa9, 0xd0, 0x5b, 0x04, 0xb2, 0x3b, 0x3b, 0x4d, 0x2f, + 0xb8, 0x3b, 0xc3, 0xbe, 0xa3, 0xd0, 0xb7, 0x88, 0x3e, 0x95, 0x47, 0x8f, 0x9d, 0x22, 0xf4, 0x8b, + 0x84, 0xee, 0x08, 0x1d, 0xda, 0xdb, 0xcb, 0xf3, 0x3e, 0xbf, 0xf7, 0x79, 0x79, 0xe8, 0x05, 0xc4, + 0x82, 0x47, 0xc6, 0xcc, 0x40, 0x44, 0x16, 0x74, 0x86, 0x5c, 0xa5, 0x86, 0x2f, 0x7a, 0x5c, 0xc9, + 0x4c, 0x22, 0x20, 0x33, 0xb9, 0xb6, 0xda, 0x3f, 0x83, 0x58, 0xb0, 0xdf, 0x36, 0xa6, 0x52, 0xc3, + 0x16, 0xbd, 0x66, 0x29, 0x1f, 0x09, 0xa1, 0xe7, 0x99, 0x2d, 0xf8, 0xe6, 0x89, 0xd2, 0x4a, 0xef, + 0x46, 0xbe, 0x9d, 0x0a, 0xb5, 0x3d, 0xa3, 0x87, 0xf7, 0x45, 0xcc, 0xc4, 0x46, 0x56, 0xfa, 0xcf, + 0xb4, 0x0e, 0x02, 0xc3, 0xfe, 0xd4, 0xc1, 0xd8, 0xa8, 0xb4, 0xfe, 0x75, 0x6a, 0x21, 0x67, 0x25, + 0xf1, 0x6c, 0x2c, 0x15, 0xa0, 0x95, 0xb9, 0x4c, 0x46, 0x77, 0x93, 0xb0, 0x3f, 0x28, 0xb8, 0xe1, + 0xff, 0xe5, 0xd7, 0xb9, 0x37, 0x3e, 0xda, 0x1d, 0x73, 0x1a, 0xb6, 0x3f, 0x08, 0x3d, 0xfd, 0xdb, + 0xef, 0x5f, 0xd2, 0x63, 0x17, 0x39, 0x8d, 0x92, 0x24, 0x97, 0x88, 0x0d, 0xd2, 0x22, 0x9d, 0xea, + 0xb8, 0xee, 0xe4, 0x41, 0xa1, 0xfa, 0x0f, 0x94, 0xee, 0x8d, 0x90, 0x34, 0x2a, 0x2d, 0xd2, 0xa9, + 0x85, 0x57, 0xa5, 0xdf, 0xb9, 0xf3, 0xa3, 0x44, 0x66, 0x16, 0x5e, 0x40, 0xe6, 0xee, 0xb1, 0x6a, + 0xb4, 0x5f, 0x0c, 0x1f, 0x97, 0xeb, 0x80, 0xac, 0xd6, 0x01, 0xf9, 0x5e, 0x07, 0xe4, 0x7d, 0x13, + 0x78, 0xab, 0x4d, 0xe0, 0x7d, 0x6e, 0x02, 0xef, 0xe9, 0x56, 0x81, 0x7d, 0x9d, 0xc7, 0x4c, 0xe8, + 0x94, 0x0b, 0x8d, 0xa9, 0x46, 0x0e, 0xb1, 0xe8, 0x2a, 0xcd, 0x17, 0xbd, 0x6b, 0x9e, 0xea, 0x64, + 0x3e, 0x93, 0xb8, 0xad, 0x1e, 0x79, 0xd8, 0xef, 0x6e, 0x5b, 0xb7, 0x6f, 0x46, 0x62, 0x7c, 0xb0, + 0xeb, 0xf6, 0xe6, 0x27, 0x00, 0x00, 0xff, 0xff, 0xf5, 0x8a, 0x64, 0xe8, 0xda, 0x01, 0x00, 0x00, +} + +func (m *GenesisState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Ics27Accounts) > 0 { + for iNdEx := len(m.Ics27Accounts) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Ics27Accounts[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + return len(dAtA) - i, nil +} + +func (m *RegisteredICS27Account) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RegisteredICS27Account) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RegisteredICS27Account) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.AccountId.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.AccountAddress) > 0 { + i -= len(m.AccountAddress) + copy(dAtA[i:], m.AccountAddress) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.AccountAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Ics27Accounts) > 0 { + for _, e := range m.Ics27Accounts { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n +} + +func (m *RegisteredICS27Account) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.AccountAddress) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + l = m.AccountId.Size() + n += 1 + l + sovGenesis(uint64(l)) + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ics27Accounts", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Ics27Accounts = append(m.Ics27Accounts, RegisteredICS27Account{}) + if err := m.Ics27Accounts[len(m.Ics27Accounts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RegisteredICS27Account) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RegisteredICS27Account: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RegisteredICS27Account: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AccountAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AccountAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AccountId", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.AccountId.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenesis(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/modules/apps/27-gmp/types/keys.go b/modules/apps/27-gmp/types/keys.go new file mode 100644 index 00000000000..c511cad377e --- /dev/null +++ b/modules/apps/27-gmp/types/keys.go @@ -0,0 +1,32 @@ +package types + +import "cosmossdk.io/collections" + +const ( + // ModuleName defines the gmp module name + ModuleName = "gmp" + + // StoreKey is the primary storage key for the gmp module + StoreKey = ModuleName + + // PortID is the default IBC port id that the gmp module + PortID = "gmpport" + + // Version defines the current version for gmp + Version = "ics27-2" + + // RouterKey is the message route for gmp + RouterKey = ModuleName + + // QuerierRoute is the querier route for gmp + QuerierRoute = ModuleName + + // accountsKey is the key used when generating a module address for the gmp module + accountsKey = "gmp-accounts" + + // AccountAddrLen is the length of the ICS27 account address + AccountAddrLen = 32 +) + +// AccountsKey is the key used to store the accounts in the keeper +var AccountsKey = collections.NewPrefix(0) diff --git a/modules/apps/27-gmp/types/msgs.go b/modules/apps/27-gmp/types/msgs.go new file mode 100644 index 00000000000..6af21adb034 --- /dev/null +++ b/modules/apps/27-gmp/types/msgs.go @@ -0,0 +1,75 @@ +package types + +import ( + errorsmod "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + + host "github.com/cosmos/ibc-go/v10/modules/core/24-host" + ibcerrors "github.com/cosmos/ibc-go/v10/modules/core/errors" +) + +const ( + MaximumReceiverLength = 2048 // maximum length of the receiver address in bytes (value chosen arbitrarily) + MaximumMemoLength = 32768 // maximum length of the memo in bytes (value chosen arbitrarily) + MaximumSaltLength = 32 // maximum length of the salt in bytes (value chosen arbitrarily) + MaximumPayloadLength = 32768 // maximum length of the payload in bytes (value chosen arbitrarily) +) + +var ( + _ sdk.Msg = (*MsgSendCall)(nil) + _ sdk.HasValidateBasic = (*MsgSendCall)(nil) +) + +// ValidateBasic performs a basic check of the MsgSendCall fields. +// NOTE: The recipient addresses format is not validated as the format defined by +// the chain is not known to IBC. +func (msg MsgSendCall) ValidateBasic() error { + if err := msg.validateIdentifiers(); err != nil { + return err + } + + if _, err := sdk.AccAddressFromBech32(msg.Sender); err != nil { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + } + // receiver is allowed to be empty + if len(msg.Receiver) > MaximumReceiverLength { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "recipient address must not exceed %d bytes", MaximumReceiverLength) + } + if len(msg.Payload) > MaximumPayloadLength { + return errorsmod.Wrapf(ErrInvalidPayload, "payload must not exceed %d bytes", MaximumPayloadLength) + } + if len(msg.Salt) > MaximumSaltLength { + return errorsmod.Wrapf(ErrInvalidSalt, "salt must not exceed %d bytes", MaximumSaltLength) + } + if len(msg.Memo) > MaximumMemoLength { + return errorsmod.Wrapf(ErrInvalidMemo, "memo must not exceed %d bytes", MaximumMemoLength) + } + if msg.TimeoutTimestamp == 0 { + return errorsmod.Wrap(ErrInvalidTimeoutTimestamp, "timeout timestamp must be greater than 0") + } + if err := validateEncoding(msg.Encoding); err != nil { + return err + } + + return nil +} + +// validateIdentifiers checks if the IBC identifiers are valid +func (msg MsgSendCall) validateIdentifiers() error { + if err := host.ClientIdentifierValidator(msg.SourceClient); err != nil { + return errorsmod.Wrapf(err, "invalid source client ID %s", msg.SourceClient) + } + + return nil +} + +// validateEncoding checks if the encoding is valid +func validateEncoding(encoding string) error { + switch encoding { + case "", EncodingProtobuf, EncodingJSON, EncodingABI: + return nil + default: + return errorsmod.Wrapf(ErrInvalidEncoding, "unsupported encoding format %s", encoding) + } +} diff --git a/modules/apps/27-gmp/types/packet.go b/modules/apps/27-gmp/types/packet.go new file mode 100644 index 00000000000..35126cd290d --- /dev/null +++ b/modules/apps/27-gmp/types/packet.go @@ -0,0 +1,105 @@ +package types + +import ( + "encoding/json" + "strings" + + "github.com/cosmos/gogoproto/proto" + + errorsmod "cosmossdk.io/errors" + + "github.com/cosmos/cosmos-sdk/codec/unknownproto" + + ibcerrors "github.com/cosmos/ibc-go/v10/modules/core/errors" +) + +const ( + EncodingJSON = "application/json" + EncodingProtobuf = "application/x-protobuf" + EncodingABI = "application/x-solidity-abi" +) + +// NewGMPPacketData creates a new GMPPacketData instance with the provided parameters. +func NewGMPPacketData( + sender, receiver string, salt, payload []byte, memo string, +) GMPPacketData { + return GMPPacketData{ + Sender: sender, + Receiver: receiver, + Salt: salt, + Payload: payload, + Memo: memo, + } +} + +func (p GMPPacketData) ValidateBasic() error { + if strings.TrimSpace(p.Sender) == "" { + return errorsmod.Wrap(ibcerrors.ErrInvalidAddress, "missing sender address") + } + // receiver is allowed to be empty + if len(p.Receiver) > MaximumReceiverLength { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "recipient address must not exceed %d bytes", MaximumReceiverLength) + } + if len(p.Payload) > MaximumPayloadLength { + return errorsmod.Wrapf(ErrInvalidPayload, "payload must not exceed %d bytes", MaximumPayloadLength) + } + if len(p.Salt) > MaximumSaltLength { + return errorsmod.Wrapf(ErrInvalidSalt, "salt must not exceed %d bytes", MaximumSaltLength) + } + if len(p.Memo) > MaximumMemoLength { + return errorsmod.Wrapf(ErrInvalidMemo, "memo must not exceed %d bytes", MaximumMemoLength) + } + + return nil +} + +// MarshalPacketData attempts to marshal the provided GMPPacketData into bytes with the provided encoding. +func MarshalPacketData(data *GMPPacketData, ics27Version string, encoding string) ([]byte, error) { + if ics27Version != Version { + panic("unsupported ics27 version") + } + + switch encoding { + case EncodingJSON: + return json.Marshal(data) + case EncodingProtobuf: + return proto.Marshal(data) + case EncodingABI: + return EncodeABIGMPPacketData(data) + default: + return nil, errorsmod.Wrapf(ErrInvalidEncoding, "invalid encoding provided, must be either empty or one of [%q, %q, %q], got %s", EncodingJSON, EncodingProtobuf, EncodingABI, encoding) + } +} + +// UnmarshalPacketData attempts to unmarshal the provided bytes into a GMPPacketData with the provided encoding. +func UnmarshalPacketData(bz []byte, ics27Version string, encoding string) (*GMPPacketData, error) { + if ics27Version != Version { + panic("unsupported ics27 version") + } + + var data *GMPPacketData + switch encoding { + case EncodingJSON: + if err := json.Unmarshal(bz, &data); err != nil { + return nil, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "failed to unmarshal json packet data: %s", err) + } + case EncodingProtobuf: + if err := unknownproto.RejectUnknownFieldsStrict(bz, data, unknownproto.DefaultAnyResolver{}); err != nil { + return nil, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "failed to unmarshal protobuf packet data: %s", err) + } + + if err := proto.Unmarshal(bz, data); err != nil { + return nil, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "failed to unmarshal protobuf packet data: %s", err) + } + case EncodingABI: + var err error + data, err = DecodeABIGMPPacketData(bz) + if err != nil { + return nil, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "failed to unmarshal ABI packet data: %s", err) + } + default: + return nil, errorsmod.Wrapf(ErrInvalidEncoding, "invalid encoding provided, must be either empty or one of [%q, %q, %q], got %s", EncodingJSON, EncodingProtobuf, EncodingABI, encoding) + } + + return data, nil +} diff --git a/modules/apps/27-gmp/types/packet.pb.go b/modules/apps/27-gmp/types/packet.pb.go new file mode 100644 index 00000000000..c7204389840 --- /dev/null +++ b/modules/apps/27-gmp/types/packet.pb.go @@ -0,0 +1,712 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ibc/applications/gmp/v1/packet.proto + +package types + +import ( + fmt "fmt" + proto "github.com/cosmos/gogoproto/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// GMPPacketData defines a struct for the packet payload +type GMPPacketData struct { + // the sender address + Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` + // the recipient address on the destination chain + Receiver string `protobuf:"bytes,2,opt,name=receiver,proto3" json:"receiver,omitempty"` + // The salt used to generate the caller account address + Salt []byte `protobuf:"bytes,3,opt,name=salt,proto3" json:"salt,omitempty"` + // The payload of the call + Payload []byte `protobuf:"bytes,4,opt,name=payload,proto3" json:"payload,omitempty"` + // optional memo + Memo string `protobuf:"bytes,5,opt,name=memo,proto3" json:"memo,omitempty"` +} + +func (m *GMPPacketData) Reset() { *m = GMPPacketData{} } +func (m *GMPPacketData) String() string { return proto.CompactTextString(m) } +func (*GMPPacketData) ProtoMessage() {} +func (*GMPPacketData) Descriptor() ([]byte, []int) { + return fileDescriptor_2a0b0887619370c4, []int{0} +} +func (m *GMPPacketData) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GMPPacketData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GMPPacketData.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GMPPacketData) XXX_Merge(src proto.Message) { + xxx_messageInfo_GMPPacketData.Merge(m, src) +} +func (m *GMPPacketData) XXX_Size() int { + return m.Size() +} +func (m *GMPPacketData) XXX_DiscardUnknown() { + xxx_messageInfo_GMPPacketData.DiscardUnknown(m) +} + +var xxx_messageInfo_GMPPacketData proto.InternalMessageInfo + +func (m *GMPPacketData) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +func (m *GMPPacketData) GetReceiver() string { + if m != nil { + return m.Receiver + } + return "" +} + +func (m *GMPPacketData) GetSalt() []byte { + if m != nil { + return m.Salt + } + return nil +} + +func (m *GMPPacketData) GetPayload() []byte { + if m != nil { + return m.Payload + } + return nil +} + +func (m *GMPPacketData) GetMemo() string { + if m != nil { + return m.Memo + } + return "" +} + +// Acknowledgement defines a struct for the ICS27-2 acknowledgement +type Acknowledgement struct { + // The result of the call + Result []byte `protobuf:"bytes,1,opt,name=result,proto3" json:"result,omitempty"` +} + +func (m *Acknowledgement) Reset() { *m = Acknowledgement{} } +func (m *Acknowledgement) String() string { return proto.CompactTextString(m) } +func (*Acknowledgement) ProtoMessage() {} +func (*Acknowledgement) Descriptor() ([]byte, []int) { + return fileDescriptor_2a0b0887619370c4, []int{1} +} +func (m *Acknowledgement) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Acknowledgement) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Acknowledgement.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Acknowledgement) XXX_Merge(src proto.Message) { + xxx_messageInfo_Acknowledgement.Merge(m, src) +} +func (m *Acknowledgement) XXX_Size() int { + return m.Size() +} +func (m *Acknowledgement) XXX_DiscardUnknown() { + xxx_messageInfo_Acknowledgement.DiscardUnknown(m) +} + +var xxx_messageInfo_Acknowledgement proto.InternalMessageInfo + +func (m *Acknowledgement) GetResult() []byte { + if m != nil { + return m.Result + } + return nil +} + +func init() { + proto.RegisterType((*GMPPacketData)(nil), "ibc.applications.gmp.v1.GMPPacketData") + proto.RegisterType((*Acknowledgement)(nil), "ibc.applications.gmp.v1.Acknowledgement") +} + +func init() { + proto.RegisterFile("ibc/applications/gmp/v1/packet.proto", fileDescriptor_2a0b0887619370c4) +} + +var fileDescriptor_2a0b0887619370c4 = []byte{ + // 283 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x90, 0x31, 0x4b, 0x33, 0x31, + 0x1c, 0xc6, 0x9b, 0xf7, 0xad, 0x55, 0x43, 0x45, 0xc8, 0xa0, 0xc1, 0x21, 0x94, 0xe2, 0x50, 0x87, + 0x5e, 0xac, 0x82, 0xce, 0x8a, 0xe0, 0x24, 0x1c, 0x37, 0xba, 0xe5, 0x72, 0x7f, 0xce, 0xd0, 0xe4, + 0x12, 0x2e, 0xb9, 0x93, 0x7e, 0x00, 0x77, 0x3f, 0x96, 0x63, 0x47, 0x47, 0xb9, 0xfb, 0x22, 0x72, + 0xa1, 0x8a, 0xdb, 0xf3, 0x4b, 0x1e, 0xfe, 0x3c, 0xfc, 0xf0, 0xb9, 0xca, 0x25, 0x17, 0xce, 0x69, + 0x25, 0x45, 0x50, 0xb6, 0xf2, 0xbc, 0x34, 0x8e, 0xb7, 0x2b, 0xee, 0x84, 0x5c, 0x43, 0x48, 0x5c, + 0x6d, 0x83, 0x25, 0xa7, 0x2a, 0x97, 0xc9, 0xdf, 0x56, 0x52, 0x1a, 0x97, 0xb4, 0xab, 0xf9, 0x1b, + 0xc2, 0x47, 0x8f, 0x4f, 0x69, 0x1a, 0xcb, 0x0f, 0x22, 0x08, 0x72, 0x82, 0x27, 0x1e, 0xaa, 0x02, + 0x6a, 0x8a, 0x66, 0x68, 0x71, 0x98, 0xed, 0x88, 0x9c, 0xe1, 0x83, 0x1a, 0x24, 0xa8, 0x16, 0x6a, + 0xfa, 0x2f, 0xfe, 0xfc, 0x32, 0x21, 0x78, 0xec, 0x85, 0x0e, 0xf4, 0xff, 0x0c, 0x2d, 0xa6, 0x59, + 0xcc, 0x84, 0xe2, 0x7d, 0x27, 0x36, 0xda, 0x8a, 0x82, 0x8e, 0xe3, 0xf3, 0x0f, 0x0e, 0x6d, 0x03, + 0xc6, 0xd2, 0xbd, 0x78, 0x25, 0xe6, 0xf9, 0x05, 0x3e, 0xbe, 0x93, 0xeb, 0xca, 0xbe, 0x6a, 0x28, + 0x4a, 0x30, 0x50, 0x85, 0x61, 0x48, 0x0d, 0xbe, 0xd1, 0x21, 0x0e, 0x99, 0x66, 0x3b, 0xba, 0x4f, + 0x3f, 0x3a, 0x86, 0xb6, 0x1d, 0x43, 0x5f, 0x1d, 0x43, 0xef, 0x3d, 0x1b, 0x6d, 0x7b, 0x36, 0xfa, + 0xec, 0xd9, 0xe8, 0xf9, 0xa6, 0x54, 0xe1, 0xa5, 0xc9, 0x13, 0x69, 0x0d, 0x97, 0xd6, 0x1b, 0xeb, + 0xb9, 0xca, 0xe5, 0xb2, 0xb4, 0xbc, 0x5d, 0x5d, 0x72, 0x63, 0x8b, 0x46, 0x83, 0x1f, 0x64, 0x79, + 0x7e, 0x75, 0xbb, 0x1c, 0x3c, 0x85, 0x8d, 0x03, 0x9f, 0x4f, 0xa2, 0xa4, 0xeb, 0xef, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x3e, 0xa9, 0x52, 0x9d, 0x4c, 0x01, 0x00, 0x00, +} + +func (m *GMPPacketData) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GMPPacketData) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GMPPacketData) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Memo) > 0 { + i -= len(m.Memo) + copy(dAtA[i:], m.Memo) + i = encodeVarintPacket(dAtA, i, uint64(len(m.Memo))) + i-- + dAtA[i] = 0x2a + } + if len(m.Payload) > 0 { + i -= len(m.Payload) + copy(dAtA[i:], m.Payload) + i = encodeVarintPacket(dAtA, i, uint64(len(m.Payload))) + i-- + dAtA[i] = 0x22 + } + if len(m.Salt) > 0 { + i -= len(m.Salt) + copy(dAtA[i:], m.Salt) + i = encodeVarintPacket(dAtA, i, uint64(len(m.Salt))) + i-- + dAtA[i] = 0x1a + } + if len(m.Receiver) > 0 { + i -= len(m.Receiver) + copy(dAtA[i:], m.Receiver) + i = encodeVarintPacket(dAtA, i, uint64(len(m.Receiver))) + i-- + dAtA[i] = 0x12 + } + if len(m.Sender) > 0 { + i -= len(m.Sender) + copy(dAtA[i:], m.Sender) + i = encodeVarintPacket(dAtA, i, uint64(len(m.Sender))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Acknowledgement) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Acknowledgement) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Acknowledgement) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Result) > 0 { + i -= len(m.Result) + copy(dAtA[i:], m.Result) + i = encodeVarintPacket(dAtA, i, uint64(len(m.Result))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintPacket(dAtA []byte, offset int, v uint64) int { + offset -= sovPacket(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GMPPacketData) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Sender) + if l > 0 { + n += 1 + l + sovPacket(uint64(l)) + } + l = len(m.Receiver) + if l > 0 { + n += 1 + l + sovPacket(uint64(l)) + } + l = len(m.Salt) + if l > 0 { + n += 1 + l + sovPacket(uint64(l)) + } + l = len(m.Payload) + if l > 0 { + n += 1 + l + sovPacket(uint64(l)) + } + l = len(m.Memo) + if l > 0 { + n += 1 + l + sovPacket(uint64(l)) + } + return n +} + +func (m *Acknowledgement) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Result) + if l > 0 { + n += 1 + l + sovPacket(uint64(l)) + } + return n +} + +func sovPacket(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozPacket(x uint64) (n int) { + return sovPacket(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GMPPacketData) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GMPPacketData: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GMPPacketData: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPacket + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPacket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sender = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Receiver", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPacket + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPacket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Receiver = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Salt", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPacket + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthPacket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Salt = append(m.Salt[:0], dAtA[iNdEx:postIndex]...) + if m.Salt == nil { + m.Salt = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPacket + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthPacket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...) + if m.Payload == nil { + m.Payload = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Memo", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPacket + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPacket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Memo = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPacket(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPacket + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Acknowledgement) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Acknowledgement: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Acknowledgement: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPacket + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthPacket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Result = append(m.Result[:0], dAtA[iNdEx:postIndex]...) + if m.Result == nil { + m.Result = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPacket(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPacket + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipPacket(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPacket + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPacket + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPacket + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthPacket + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupPacket + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthPacket + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthPacket = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowPacket = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupPacket = fmt.Errorf("proto: unexpected end of group") +) diff --git a/modules/apps/27-gmp/types/query.pb.go b/modules/apps/27-gmp/types/query.pb.go new file mode 100644 index 00000000000..97809332d9d --- /dev/null +++ b/modules/apps/27-gmp/types/query.pb.go @@ -0,0 +1,697 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ibc/applications/gmp/v1/query.proto + +package types + +import ( + context "context" + fmt "fmt" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// QueryAccountAddressRequest is the request type for the Query/AccountAddress RPC method. +type QueryAccountAddressRequest struct { + // The (local) client identifier + ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` + // The sender of the packet + Sender string `protobuf:"bytes,2,opt,name=sender,proto3" json:"sender,omitempty"` + // The salt of the packet (in hex format) + Salt string `protobuf:"bytes,3,opt,name=salt,proto3" json:"salt,omitempty"` +} + +func (m *QueryAccountAddressRequest) Reset() { *m = QueryAccountAddressRequest{} } +func (m *QueryAccountAddressRequest) String() string { return proto.CompactTextString(m) } +func (*QueryAccountAddressRequest) ProtoMessage() {} +func (*QueryAccountAddressRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_0d55aa1ab285a918, []int{0} +} +func (m *QueryAccountAddressRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAccountAddressRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAccountAddressRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryAccountAddressRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAccountAddressRequest.Merge(m, src) +} +func (m *QueryAccountAddressRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryAccountAddressRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAccountAddressRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAccountAddressRequest proto.InternalMessageInfo + +func (m *QueryAccountAddressRequest) GetClientId() string { + if m != nil { + return m.ClientId + } + return "" +} + +func (m *QueryAccountAddressRequest) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +func (m *QueryAccountAddressRequest) GetSalt() string { + if m != nil { + return m.Salt + } + return "" +} + +// QueryAccountAddressResponse is the response type for the Query/AccountAddress RPC method. +type QueryAccountAddressResponse struct { + // The interchain account address + AccountAddress string `protobuf:"bytes,1,opt,name=account_address,json=accountAddress,proto3" json:"account_address,omitempty"` +} + +func (m *QueryAccountAddressResponse) Reset() { *m = QueryAccountAddressResponse{} } +func (m *QueryAccountAddressResponse) String() string { return proto.CompactTextString(m) } +func (*QueryAccountAddressResponse) ProtoMessage() {} +func (*QueryAccountAddressResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_0d55aa1ab285a918, []int{1} +} +func (m *QueryAccountAddressResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAccountAddressResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAccountAddressResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryAccountAddressResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAccountAddressResponse.Merge(m, src) +} +func (m *QueryAccountAddressResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryAccountAddressResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAccountAddressResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAccountAddressResponse proto.InternalMessageInfo + +func (m *QueryAccountAddressResponse) GetAccountAddress() string { + if m != nil { + return m.AccountAddress + } + return "" +} + +func init() { + proto.RegisterType((*QueryAccountAddressRequest)(nil), "ibc.applications.gmp.v1.QueryAccountAddressRequest") + proto.RegisterType((*QueryAccountAddressResponse)(nil), "ibc.applications.gmp.v1.QueryAccountAddressResponse") +} + +func init() { + proto.RegisterFile("ibc/applications/gmp/v1/query.proto", fileDescriptor_0d55aa1ab285a918) +} + +var fileDescriptor_0d55aa1ab285a918 = []byte{ + // 358 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x51, 0x41, 0x4b, 0x3a, 0x41, + 0x1c, 0x75, 0xfd, 0xff, 0x93, 0x9c, 0x83, 0xc1, 0x1c, 0x4a, 0x34, 0x96, 0xb0, 0x43, 0x21, 0xb8, + 0x93, 0x1a, 0x75, 0x0a, 0xd2, 0x43, 0xd4, 0xad, 0x3c, 0x76, 0x91, 0xd9, 0xd9, 0x61, 0x1b, 0xd8, + 0xdd, 0x19, 0xf7, 0x37, 0x2b, 0x88, 0x78, 0xe9, 0x13, 0x04, 0x7d, 0xa6, 0xa0, 0x5b, 0x42, 0x97, + 0x8e, 0xa1, 0x7d, 0x90, 0xd8, 0x9d, 0x45, 0x12, 0xf2, 0xd0, 0x6d, 0xe6, 0xf7, 0xe6, 0xbd, 0x37, + 0xbf, 0xf7, 0xd0, 0xa1, 0x70, 0x19, 0xa1, 0x4a, 0x05, 0x82, 0x51, 0x2d, 0x64, 0x04, 0xc4, 0x0f, + 0x15, 0x19, 0xb7, 0xc9, 0x28, 0xe1, 0xf1, 0xc4, 0x51, 0xb1, 0xd4, 0x12, 0xef, 0x09, 0x97, 0x39, + 0x3f, 0x1f, 0x39, 0x7e, 0xa8, 0x9c, 0x71, 0xbb, 0xb6, 0xef, 0x4b, 0xe9, 0x07, 0x9c, 0x50, 0x25, + 0x08, 0x8d, 0x22, 0xa9, 0x73, 0x38, 0xa3, 0x35, 0x38, 0xaa, 0xdd, 0xa5, 0x2a, 0x3d, 0xc6, 0x64, + 0x12, 0xe9, 0x9e, 0xe7, 0xc5, 0x1c, 0x60, 0xc0, 0x47, 0x09, 0x07, 0x8d, 0xeb, 0xa8, 0xcc, 0x02, + 0xc1, 0x23, 0x3d, 0x14, 0x5e, 0xd5, 0x3a, 0xb0, 0x8e, 0xcb, 0x83, 0x6d, 0x33, 0xb8, 0xf1, 0xf0, + 0x2e, 0x2a, 0x01, 0x8f, 0x3c, 0x1e, 0x57, 0x8b, 0x19, 0x92, 0xdf, 0x30, 0x46, 0xff, 0x81, 0x06, + 0xba, 0xfa, 0x2f, 0x9b, 0x66, 0xe7, 0xc6, 0x15, 0xaa, 0xff, 0x6a, 0x03, 0x4a, 0x46, 0xc0, 0xf1, + 0x11, 0xda, 0xa1, 0x06, 0x19, 0x52, 0x03, 0xe5, 0x6e, 0x15, 0xba, 0x46, 0xe8, 0xbc, 0x59, 0x68, + 0x2b, 0x13, 0xc2, 0x2f, 0x16, 0xaa, 0xac, 0xab, 0xe1, 0xae, 0xb3, 0x21, 0x03, 0x67, 0xf3, 0x8a, + 0xb5, 0xd3, 0xbf, 0x91, 0xcc, 0x87, 0x1b, 0xd7, 0x8f, 0xef, 0x5f, 0xcf, 0xc5, 0x3e, 0xbe, 0x24, + 0x79, 0x37, 0xab, 0x4e, 0x4c, 0x3c, 0x40, 0xa6, 0xab, 0xe0, 0x66, 0x24, 0x5f, 0x02, 0xc8, 0xd4, + 0x44, 0x34, 0x23, 0xd3, 0x34, 0x95, 0x8b, 0x66, 0x73, 0xd6, 0xbf, 0x7d, 0x5d, 0xd8, 0xd6, 0x7c, + 0x61, 0x5b, 0x9f, 0x0b, 0xdb, 0x7a, 0x5a, 0xda, 0x85, 0xf9, 0xd2, 0x2e, 0x7c, 0x2c, 0xed, 0xc2, + 0xfd, 0x99, 0x2f, 0xf4, 0x43, 0xe2, 0x3a, 0x4c, 0x86, 0x84, 0x49, 0x08, 0x25, 0xa4, 0x66, 0x2d, + 0x5f, 0x92, 0x71, 0xfb, 0x84, 0x84, 0xd2, 0x4b, 0x02, 0x0e, 0xc6, 0xbb, 0x73, 0xde, 0x4a, 0xed, + 0xf5, 0x44, 0x71, 0x70, 0x4b, 0x59, 0xb3, 0xdd, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x08, 0xbf, + 0x5a, 0x74, 0x37, 0x02, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueryClient interface { + // AccountAddress queries the interchain account address for a given client_id, sender, and salt. + // If the account is not registered, the address is computed deterministically + AccountAddress(ctx context.Context, in *QueryAccountAddressRequest, opts ...grpc.CallOption) (*QueryAccountAddressResponse, error) +} + +type queryClient struct { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) AccountAddress(ctx context.Context, in *QueryAccountAddressRequest, opts ...grpc.CallOption) (*QueryAccountAddressResponse, error) { + out := new(QueryAccountAddressResponse) + err := c.cc.Invoke(ctx, "/ibc.applications.gmp.v1.Query/AccountAddress", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +type QueryServer interface { + // AccountAddress queries the interchain account address for a given client_id, sender, and salt. + // If the account is not registered, the address is computed deterministically + AccountAddress(context.Context, *QueryAccountAddressRequest) (*QueryAccountAddressResponse, error) +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (*UnimplementedQueryServer) AccountAddress(ctx context.Context, req *QueryAccountAddressRequest) (*QueryAccountAddressResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AccountAddress not implemented") +} + +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +func _Query_AccountAddress_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAccountAddressRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).AccountAddress(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.applications.gmp.v1.Query/AccountAddress", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).AccountAddress(ctx, req.(*QueryAccountAddressRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "ibc.applications.gmp.v1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "AccountAddress", + Handler: _Query_AccountAddress_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "ibc/applications/gmp/v1/query.proto", +} + +func (m *QueryAccountAddressRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryAccountAddressRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAccountAddressRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Salt) > 0 { + i -= len(m.Salt) + copy(dAtA[i:], m.Salt) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Salt))) + i-- + dAtA[i] = 0x1a + } + if len(m.Sender) > 0 { + i -= len(m.Sender) + copy(dAtA[i:], m.Sender) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Sender))) + i-- + dAtA[i] = 0x12 + } + if len(m.ClientId) > 0 { + i -= len(m.ClientId) + copy(dAtA[i:], m.ClientId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ClientId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryAccountAddressResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryAccountAddressResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAccountAddressResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.AccountAddress) > 0 { + i -= len(m.AccountAddress) + copy(dAtA[i:], m.AccountAddress) + i = encodeVarintQuery(dAtA, i, uint64(len(m.AccountAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryAccountAddressRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ClientId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.Sender) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.Salt) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryAccountAddressResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.AccountAddress) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func sovQuery(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozQuery(x uint64) (n int) { + return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *QueryAccountAddressRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryAccountAddressRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAccountAddressRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ClientId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ClientId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sender = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Salt", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Salt = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAccountAddressResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryAccountAddressResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAccountAddressResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AccountAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AccountAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipQuery(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthQuery + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupQuery + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthQuery + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") +) diff --git a/modules/apps/27-gmp/types/query.pb.gw.go b/modules/apps/27-gmp/types/query.pb.gw.go new file mode 100644 index 00000000000..0fa9f5f2299 --- /dev/null +++ b/modules/apps/27-gmp/types/query.pb.gw.go @@ -0,0 +1,233 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: ibc/applications/gmp/v1/query.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage +var _ = metadata.Join + +func request_Query_AccountAddress_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAccountAddressRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["client_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "client_id") + } + + protoReq.ClientId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "client_id", err) + } + + val, ok = pathParams["sender"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "sender") + } + + protoReq.Sender, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "sender", err) + } + + val, ok = pathParams["salt"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "salt") + } + + protoReq.Salt, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "salt", err) + } + + msg, err := client.AccountAddress(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_AccountAddress_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAccountAddressRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["client_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "client_id") + } + + protoReq.ClientId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "client_id", err) + } + + val, ok = pathParams["sender"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "sender") + } + + protoReq.Sender, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "sender", err) + } + + val, ok = pathParams["salt"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "salt") + } + + protoReq.Salt, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "salt", err) + } + + msg, err := server.AccountAddress(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterQueryHandlerServer registers the http handlers for service Query to "mux". +// UnaryRPC :call QueryServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { + + mux.Handle("GET", pattern_Query_AccountAddress_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_AccountAddress_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_AccountAddress_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterQueryHandler(ctx, mux, conn) +} + +// RegisterQueryHandler registers the http handlers for service Query to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn)) +} + +// RegisterQueryHandlerClient registers the http handlers for service Query +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "QueryClient" to call the correct interceptors. +func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { + + mux.Handle("GET", pattern_Query_AccountAddress_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_AccountAddress_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_AccountAddress_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Query_AccountAddress_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 3, 0, 4, 1, 5, 8}, []string{"ibc", "apps", "gmp", "v1", "clients", "client_id", "accounts", "sender", "salt"}, "", runtime.AssumeColonVerbOpt(false))) +) + +var ( + forward_Query_AccountAddress_0 = runtime.ForwardResponseMessage +) diff --git a/modules/apps/27-gmp/types/router.go b/modules/apps/27-gmp/types/router.go new file mode 100644 index 00000000000..dd1cfb4d3cf --- /dev/null +++ b/modules/apps/27-gmp/types/router.go @@ -0,0 +1,12 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// MessageRouter ADR 031 request type routing +// https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-031-msg-service.md +type MessageRouter interface { + Handler(msg sdk.Msg) baseapp.MsgServiceHandler +} diff --git a/modules/apps/27-gmp/types/solidity_abi.go b/modules/apps/27-gmp/types/solidity_abi.go new file mode 100644 index 00000000000..7a78e27b6bb --- /dev/null +++ b/modules/apps/27-gmp/types/solidity_abi.go @@ -0,0 +1,168 @@ +package types + +import ( + "github.com/ethereum/go-ethereum/accounts/abi" + + errorsmod "cosmossdk.io/errors" +) + +// getICS27PacketABI returns an abi.Arguments slice describing the Solidity types of the struct. +func getICS27PacketABI() abi.Arguments { + // Create the ABI types for each field. + // The Solidity types used are: + // - string for Sender, Receiver and Memo. + // - bytes for Salt and Payload. + tupleType, err := abi.NewType("tuple", "", []abi.ArgumentMarshaling{ + { + Name: "sender", + Type: "string", + }, + { + Name: "receiver", + Type: "string", + }, + { + Name: "salt", + Type: "bytes", + }, + { + Name: "payload", + Type: "bytes", + }, + { + Name: "memo", + Type: "string", + }, + }) + if err != nil { + panic(err) + } + + // Create an ABI argument representing our struct as a single tuple argument. + arguments := abi.Arguments{ + { + Type: tupleType, + }, + } + + return arguments +} + +// getICS27AckABI returns an abi.Arguments slice describing the Solidity types of the struct. +func getICS27AckABI() abi.Arguments { + // Create the ABI types for each field. + // The Solidity types used are: + // - bytes for Result. + tupleType, err := abi.NewType("tuple", "", []abi.ArgumentMarshaling{ + { + Name: "result", + Type: "bytes", + }, + }) + if err != nil { + panic(err) + } + + // Create an ABI argument representing our struct as a single tuple argument. + arguments := abi.Arguments{ + { + Type: tupleType, + }, + } + + return arguments +} + +// DecodeABIGMPPacketData decodes a solidity ABI encoded ics27lib.GMPPacketData and converts it into an ibc-go GMPPacketData. +func DecodeABIGMPPacketData(data []byte) (*GMPPacketData, error) { + arguments := getICS27PacketABI() + + packetDataI, err := arguments.Unpack(data) + if err != nil { + return nil, errorsmod.Wrapf(ErrAbiDecoding, "failed to unpack data: %s", err) + } + + packetData, ok := packetDataI[0].(struct { + Sender string `json:"sender"` + Receiver string `json:"receiver"` + Salt []byte `json:"salt"` + Payload []byte `json:"payload"` + Memo string `json:"memo"` + }) + if !ok { + return nil, errorsmod.Wrapf(ErrAbiDecoding, "failed to parse packet data") + } + + return &GMPPacketData{ + Sender: packetData.Sender, + Receiver: packetData.Receiver, + Salt: packetData.Salt, + Payload: packetData.Payload, + Memo: packetData.Memo, + }, nil +} + +// EncodeABIGMPPacketData encodes a GMPPacketData into a solidity ABI encoded byte array. +func EncodeABIGMPPacketData(data *GMPPacketData) ([]byte, error) { + packetData := struct { + Sender string `json:"sender"` + Receiver string `json:"receiver"` + Salt []byte `json:"salt"` + Payload []byte `json:"payload"` + Memo string `json:"memo"` + }{ + data.Sender, + data.Receiver, + data.Salt, + data.Payload, + data.Memo, + } + + arguments := getICS27PacketABI() + // Pack the values in the order defined in the ABI. + encodedData, err := arguments.Pack(packetData) + if err != nil { + return nil, errorsmod.Wrapf(ErrAbiEncoding, "failed to pack data: %s", err) + } + + return encodedData, nil +} + +// DecodeABIAcknowledgement decodes a solidity ABI encoded ics27lib.Acknowledgement and converts it into an ibc-go Acknowledgement +func DecodeABIAcknowledgement(data []byte) (*Acknowledgement, error) { + arguments := getICS27AckABI() + + packetDataI, err := arguments.Unpack(data) + if err != nil { + return nil, errorsmod.Wrapf(ErrAbiDecoding, "failed to unpack data: %s", err) + } + + packetData, ok := packetDataI[0].(struct { + Result []byte `json:"result"` + }) + if !ok { + return nil, errorsmod.Wrapf(ErrAbiDecoding, "failed to parse packet data") + } + + return &Acknowledgement{ + Result: packetData.Result, + }, nil +} + +// EncodeABIAcknowledgement encodes an Acknowledgement into a solidity ABI encoded byte array +func EncodeABIAcknowledgement(data *Acknowledgement) ([]byte, error) { + ack := struct { + Result []byte `json:"result"` + }{ + Result: data.Result, + } + + arguments := getICS27AckABI() + // Pack the values in the order defined in the ABI. + encodedData, err := arguments.Pack(ack) + if err != nil { + return nil, errorsmod.Wrapf(ErrAbiEncoding, "failed to pack data: %s", err) + } + + return encodedData, nil +} diff --git a/modules/apps/27-gmp/types/tx.pb.go b/modules/apps/27-gmp/types/tx.pb.go new file mode 100644 index 00000000000..63af1d98ca5 --- /dev/null +++ b/modules/apps/27-gmp/types/tx.pb.go @@ -0,0 +1,867 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ibc/applications/gmp/v1/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/cosmos/cosmos-sdk/types/msgservice" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// MsgSendCall defines a msg to send a call to a contract/receiver on a ICS27-2 enabled chain. +type MsgSendCall struct { + // the client by which the packet will be sent + SourceClient string `protobuf:"bytes,1,opt,name=source_client,json=sourceClient,proto3" json:"source_client,omitempty"` + // the sender address + Sender string `protobuf:"bytes,2,opt,name=sender,proto3" json:"sender,omitempty"` + // the recipient address on the destination chain + Receiver string `protobuf:"bytes,3,opt,name=receiver,proto3" json:"receiver,omitempty"` + // The salt used to generate the caller account address + Salt []byte `protobuf:"bytes,4,opt,name=salt,proto3" json:"salt,omitempty"` + // The payload of the call + Payload []byte `protobuf:"bytes,5,opt,name=payload,proto3" json:"payload,omitempty"` + // Timeout timestamp in absolute nanoseconds since unix epoch. + TimeoutTimestamp uint64 `protobuf:"varint,6,opt,name=timeout_timestamp,json=timeoutTimestamp,proto3" json:"timeout_timestamp,omitempty"` + // optional memo + Memo string `protobuf:"bytes,7,opt,name=memo,proto3" json:"memo,omitempty"` + // optional encoding + Encoding string `protobuf:"bytes,8,opt,name=encoding,proto3" json:"encoding,omitempty"` +} + +func (m *MsgSendCall) Reset() { *m = MsgSendCall{} } +func (m *MsgSendCall) String() string { return proto.CompactTextString(m) } +func (*MsgSendCall) ProtoMessage() {} +func (*MsgSendCall) Descriptor() ([]byte, []int) { + return fileDescriptor_32bfd6a386d18ce5, []int{0} +} +func (m *MsgSendCall) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSendCall) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSendCall.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgSendCall) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSendCall.Merge(m, src) +} +func (m *MsgSendCall) XXX_Size() int { + return m.Size() +} +func (m *MsgSendCall) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSendCall.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSendCall proto.InternalMessageInfo + +// MsgSendCallResponse defines the Msg/SendCall response type. +type MsgSendCallResponse struct { + // sequence number of the GMP packet sent + Sequence uint64 `protobuf:"varint,1,opt,name=sequence,proto3" json:"sequence,omitempty"` +} + +func (m *MsgSendCallResponse) Reset() { *m = MsgSendCallResponse{} } +func (m *MsgSendCallResponse) String() string { return proto.CompactTextString(m) } +func (*MsgSendCallResponse) ProtoMessage() {} +func (*MsgSendCallResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_32bfd6a386d18ce5, []int{1} +} +func (m *MsgSendCallResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSendCallResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSendCallResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgSendCallResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSendCallResponse.Merge(m, src) +} +func (m *MsgSendCallResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgSendCallResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSendCallResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSendCallResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*MsgSendCall)(nil), "ibc.applications.gmp.v1.MsgSendCall") + proto.RegisterType((*MsgSendCallResponse)(nil), "ibc.applications.gmp.v1.MsgSendCallResponse") +} + +func init() { proto.RegisterFile("ibc/applications/gmp/v1/tx.proto", fileDescriptor_32bfd6a386d18ce5) } + +var fileDescriptor_32bfd6a386d18ce5 = []byte{ + // 422 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0xb1, 0x6e, 0x14, 0x31, + 0x10, 0xbd, 0x4d, 0x36, 0x97, 0xc3, 0x04, 0x01, 0x06, 0x11, 0x6b, 0x8b, 0xe5, 0x14, 0x28, 0x4e, + 0x81, 0xac, 0xb9, 0x20, 0x11, 0x29, 0x25, 0xa9, 0x23, 0xa1, 0x85, 0x8a, 0x82, 0x68, 0xd7, 0x3b, + 0x32, 0x96, 0xd6, 0x6b, 0xb3, 0xe3, 0x3d, 0x91, 0x0e, 0xa5, 0xa2, 0xe4, 0x13, 0xf8, 0x84, 0x7c, + 0x06, 0x65, 0x4a, 0x4a, 0x74, 0x57, 0xe4, 0x37, 0x90, 0x7d, 0xb7, 0xa7, 0x6b, 0x90, 0xa8, 0x3c, + 0x6f, 0xde, 0xd3, 0xf3, 0xd3, 0xcc, 0x90, 0xb1, 0x2a, 0x05, 0x2f, 0xac, 0xad, 0x95, 0x28, 0x9c, + 0x32, 0x0d, 0x72, 0xa9, 0x2d, 0x9f, 0x4d, 0xb9, 0xfb, 0x9a, 0xd9, 0xd6, 0x38, 0x43, 0xf7, 0x55, + 0x29, 0xb2, 0x4d, 0x45, 0x26, 0xb5, 0xcd, 0x66, 0xd3, 0xe4, 0xb1, 0x34, 0xd2, 0x04, 0x0d, 0xf7, + 0xd5, 0x52, 0x9e, 0xec, 0x0b, 0x83, 0xda, 0x20, 0xd7, 0x28, 0xbd, 0x8d, 0x46, 0xb9, 0x24, 0x0e, + 0xae, 0xb6, 0xc8, 0xdd, 0x73, 0x94, 0xef, 0xa1, 0xa9, 0xce, 0x8a, 0xba, 0xa6, 0xcf, 0xc8, 0x3d, + 0x34, 0x5d, 0x2b, 0xe0, 0x42, 0xd4, 0x0a, 0x1a, 0xc7, 0xa2, 0x71, 0x34, 0xb9, 0x93, 0xef, 0x2d, + 0x9b, 0x67, 0xa1, 0x47, 0x9f, 0x90, 0x21, 0x42, 0x53, 0x41, 0xcb, 0xb6, 0x02, 0xbb, 0x42, 0x34, + 0x21, 0xa3, 0x16, 0x04, 0xa8, 0x19, 0xb4, 0x6c, 0x3b, 0x30, 0x6b, 0x4c, 0x29, 0x89, 0xb1, 0xa8, + 0x1d, 0x8b, 0xc7, 0xd1, 0x64, 0x2f, 0x0f, 0x35, 0x65, 0x64, 0xd7, 0x16, 0x97, 0xb5, 0x29, 0x2a, + 0xb6, 0x13, 0xda, 0x3d, 0xa4, 0x2f, 0xc8, 0x43, 0xa7, 0x34, 0x98, 0xce, 0x5d, 0xf8, 0x17, 0x5d, + 0xa1, 0x2d, 0x1b, 0x8e, 0xa3, 0x49, 0x9c, 0x3f, 0x58, 0x11, 0x1f, 0xfa, 0xbe, 0xb7, 0xd6, 0xa0, + 0x0d, 0xdb, 0x0d, 0x5f, 0x86, 0xda, 0x47, 0x81, 0x46, 0x98, 0x4a, 0x35, 0x92, 0x8d, 0x96, 0x51, + 0x7a, 0x7c, 0x7a, 0xff, 0xfb, 0xcf, 0xa7, 0x83, 0xab, 0xdb, 0xeb, 0xc3, 0x55, 0xee, 0x83, 0x13, + 0xf2, 0x68, 0x63, 0x06, 0x39, 0xa0, 0x35, 0x0d, 0x82, 0xf7, 0x40, 0xf8, 0xd2, 0x41, 0x23, 0x20, + 0x8c, 0x21, 0xce, 0xd7, 0xf8, 0x34, 0xf6, 0x1e, 0xc7, 0x35, 0xd9, 0x3e, 0x47, 0x49, 0x3f, 0x91, + 0xd1, 0x7a, 0x80, 0xcf, 0xb3, 0x7f, 0x6c, 0x26, 0xdb, 0xf8, 0x22, 0x79, 0xf9, 0x3f, 0xaa, 0x3e, + 0x48, 0xb2, 0xf3, 0xed, 0xf6, 0xfa, 0x30, 0x7a, 0xfb, 0xee, 0xd7, 0x3c, 0x8d, 0x6e, 0xe6, 0x69, + 0xf4, 0x67, 0x9e, 0x46, 0x3f, 0x16, 0xe9, 0xe0, 0x66, 0x91, 0x0e, 0x7e, 0x2f, 0xd2, 0xc1, 0xc7, + 0x37, 0x52, 0xb9, 0xcf, 0x5d, 0x99, 0x09, 0xa3, 0xf9, 0x6a, 0xd3, 0xaa, 0x14, 0x47, 0xd2, 0xf0, + 0xd9, 0xf4, 0x15, 0xd7, 0xa6, 0xea, 0x6a, 0x40, 0x7f, 0x50, 0xc8, 0x8f, 0x4f, 0x8e, 0xfc, 0x2d, + 0xb9, 0x4b, 0x0b, 0x58, 0x0e, 0xc3, 0x11, 0xbc, 0xfe, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x54, 0x14, + 0xab, 0xb4, 0x70, 0x02, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MsgClient interface { + // SendCall defines a rpc handler method for MsgSendCall. + SendCall(ctx context.Context, in *MsgSendCall, opts ...grpc.CallOption) (*MsgSendCallResponse, error) +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) SendCall(ctx context.Context, in *MsgSendCall, opts ...grpc.CallOption) (*MsgSendCallResponse, error) { + out := new(MsgSendCallResponse) + err := c.cc.Invoke(ctx, "/ibc.applications.gmp.v1.Msg/SendCall", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { + // SendCall defines a rpc handler method for MsgSendCall. + SendCall(context.Context, *MsgSendCall) (*MsgSendCallResponse, error) +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (*UnimplementedMsgServer) SendCall(ctx context.Context, req *MsgSendCall) (*MsgSendCallResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SendCall not implemented") +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +func _Msg_SendCall_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgSendCall) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).SendCall(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.applications.gmp.v1.Msg/SendCall", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).SendCall(ctx, req.(*MsgSendCall)) + } + return interceptor(ctx, in, info, handler) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "ibc.applications.gmp.v1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "SendCall", + Handler: _Msg_SendCall_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "ibc/applications/gmp/v1/tx.proto", +} + +func (m *MsgSendCall) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgSendCall) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSendCall) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Encoding) > 0 { + i -= len(m.Encoding) + copy(dAtA[i:], m.Encoding) + i = encodeVarintTx(dAtA, i, uint64(len(m.Encoding))) + i-- + dAtA[i] = 0x42 + } + if len(m.Memo) > 0 { + i -= len(m.Memo) + copy(dAtA[i:], m.Memo) + i = encodeVarintTx(dAtA, i, uint64(len(m.Memo))) + i-- + dAtA[i] = 0x3a + } + if m.TimeoutTimestamp != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.TimeoutTimestamp)) + i-- + dAtA[i] = 0x30 + } + if len(m.Payload) > 0 { + i -= len(m.Payload) + copy(dAtA[i:], m.Payload) + i = encodeVarintTx(dAtA, i, uint64(len(m.Payload))) + i-- + dAtA[i] = 0x2a + } + if len(m.Salt) > 0 { + i -= len(m.Salt) + copy(dAtA[i:], m.Salt) + i = encodeVarintTx(dAtA, i, uint64(len(m.Salt))) + i-- + dAtA[i] = 0x22 + } + if len(m.Receiver) > 0 { + i -= len(m.Receiver) + copy(dAtA[i:], m.Receiver) + i = encodeVarintTx(dAtA, i, uint64(len(m.Receiver))) + i-- + dAtA[i] = 0x1a + } + if len(m.Sender) > 0 { + i -= len(m.Sender) + copy(dAtA[i:], m.Sender) + i = encodeVarintTx(dAtA, i, uint64(len(m.Sender))) + i-- + dAtA[i] = 0x12 + } + if len(m.SourceClient) > 0 { + i -= len(m.SourceClient) + copy(dAtA[i:], m.SourceClient) + i = encodeVarintTx(dAtA, i, uint64(len(m.SourceClient))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgSendCallResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgSendCallResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSendCallResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Sequence != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Sequence)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintTx(dAtA []byte, offset int, v uint64) int { + offset -= sovTx(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgSendCall) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.SourceClient) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Sender) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Receiver) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Salt) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Payload) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.TimeoutTimestamp != 0 { + n += 1 + sovTx(uint64(m.TimeoutTimestamp)) + } + l = len(m.Memo) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Encoding) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgSendCallResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Sequence != 0 { + n += 1 + sovTx(uint64(m.Sequence)) + } + return n +} + +func sovTx(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTx(x uint64) (n int) { + return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *MsgSendCall) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgSendCall: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSendCall: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SourceClient", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SourceClient = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sender = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Receiver", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Receiver = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Salt", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Salt = append(m.Salt[:0], dAtA[iNdEx:postIndex]...) + if m.Salt == nil { + m.Salt = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...) + if m.Payload == nil { + m.Payload = []byte{} + } + iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TimeoutTimestamp", wireType) + } + m.TimeoutTimestamp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TimeoutTimestamp |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Memo", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Memo = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Encoding", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Encoding = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgSendCallResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgSendCallResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSendCallResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Sequence", wireType) + } + m.Sequence = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Sequence |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTx(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthTx + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTx + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTx + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTx = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTx = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTx = fmt.Errorf("proto: unexpected end of group") +) diff --git a/modules/light-clients/08-wasm/testing/simapp/app.go b/modules/light-clients/08-wasm/testing/simapp/app.go index 14588114ff9..7109f81796a 100644 --- a/modules/light-clients/08-wasm/testing/simapp/app.go +++ b/modules/light-clients/08-wasm/testing/simapp/app.go @@ -111,6 +111,9 @@ import ( "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/v10/blsverifier" ibcwasmkeeper "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/v10/keeper" ibcwasmtypes "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/v10/types" + gmp "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp" + gmpkeeper "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/keeper" + gmptypes "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" ica "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts" icacontroller "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts/controller" icacontrollerkeeper "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts/controller/keeper" @@ -151,6 +154,7 @@ var ( govtypes.ModuleName: {authtypes.Burner}, ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, icatypes.ModuleName: nil, + gmptypes.ModuleName: nil, ibcmock.ModuleName: nil, } ) @@ -189,6 +193,7 @@ type SimApp struct { IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly ICAControllerKeeper icacontrollerkeeper.Keeper ICAHostKeeper icahostkeeper.Keeper + GMPKeeper gmpkeeper.Keeper EvidenceKeeper evidencekeeper.Keeper TransferKeeper ibctransferkeeper.Keeper WasmClientKeeper ibcwasmkeeper.Keeper @@ -312,7 +317,7 @@ func newSimApp( authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, crisistypes.StoreKey, minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, govtypes.StoreKey, group.StoreKey, paramstypes.StoreKey, ibcexported.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey, - evidencetypes.StoreKey, ibctransfertypes.StoreKey, icacontrollertypes.StoreKey, icahosttypes.StoreKey, + evidencetypes.StoreKey, ibctransfertypes.StoreKey, icacontrollertypes.StoreKey, icahosttypes.StoreKey, gmptypes.StoreKey, authzkeeper.StoreKey, consensusparamtypes.StoreKey, circuittypes.StoreKey, ibcwasmtypes.StoreKey, ) @@ -486,6 +491,15 @@ func newSimApp( app.GRPCQueryRouter(), authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) + // ICS-27 GMP keeper + app.GMPKeeper = gmpkeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[gmptypes.ModuleName]), + app.AccountKeeper, + app.MsgServiceRouter(), + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + // Create IBC Router ibcRouter := porttypes.NewRouter() ibcRouterV2 := ibcapi.NewRouter() @@ -557,6 +571,9 @@ func newSimApp( // register the transfer v2 module. ibcRouterV2.AddRoute(ibctransfertypes.PortID, transferv2.NewIBCModule(app.TransferKeeper)) + // Register the ICS-27 GMP module + ibcRouterV2.AddRoute(gmptypes.PortID, gmp.NewIBCModule(app.GMPKeeper)) + // Seal the IBC Routers. app.IBCKeeper.SetRouter(ibcRouter) app.IBCKeeper.SetRouterV2(ibcRouterV2) @@ -615,6 +632,7 @@ func newSimApp( ibc.NewAppModule(app.IBCKeeper), transfer.NewAppModule(app.TransferKeeper), ica.NewAppModule(&app.ICAControllerKeeper, &app.ICAHostKeeper), + gmp.NewAppModule(app.GMPKeeper), mockModule, // IBC light clients @@ -661,6 +679,7 @@ func newSimApp( genutiltypes.ModuleName, authz.ModuleName, icatypes.ModuleName, + gmptypes.ModuleName, ibcwasmtypes.ModuleName, ibcmock.ModuleName, ) @@ -673,6 +692,7 @@ func newSimApp( genutiltypes.ModuleName, feegrant.ModuleName, icatypes.ModuleName, + gmptypes.ModuleName, ibcwasmtypes.ModuleName, ibcmock.ModuleName, group.ModuleName, @@ -686,7 +706,7 @@ func newSimApp( banktypes.ModuleName, distrtypes.ModuleName, stakingtypes.ModuleName, slashingtypes.ModuleName, govtypes.ModuleName, minttypes.ModuleName, crisistypes.ModuleName, ibcexported.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName, ibctransfertypes.ModuleName, - icatypes.ModuleName, ibcmock.ModuleName, feegrant.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName, + icatypes.ModuleName, gmptypes.ModuleName, ibcmock.ModuleName, feegrant.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName, vestingtypes.ModuleName, group.ModuleName, consensusparamtypes.ModuleName, circuittypes.ModuleName, ibcwasmtypes.ModuleName, } app.ModuleManager.SetOrderInitGenesis(genesisModuleOrder...) diff --git a/proto/ibc/applications/gmp/v1/account.proto b/proto/ibc/applications/gmp/v1/account.proto new file mode 100644 index 00000000000..ce1680f3d24 --- /dev/null +++ b/proto/ibc/applications/gmp/v1/account.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; + +package ibc.applications.gmp.v1; + +option go_package = "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types"; + +import "google/protobuf/any.proto"; +import "cosmos_proto/cosmos.proto"; + +// AccountIdentifier is used to identify a ICS27 account. +message AccountIdentifier { + // The (local) client identifier + string client_id = 1; + // The sender of the packet + string sender = 2; + // The salt of the packet + bytes salt = 3; +} + +// An ICS27Account is defined as a BaseAccount & the account identifier +message ICS27Account { + string address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + AccountIdentifier account_id = 2; +} + +// 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/proto/ibc/applications/gmp/v1/genesis.proto b/proto/ibc/applications/gmp/v1/genesis.proto new file mode 100644 index 00000000000..8a0e2d04601 --- /dev/null +++ b/proto/ibc/applications/gmp/v1/genesis.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; + +package ibc.applications.gmp.v1; + +option go_package = "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types"; + +import "ibc/applications/gmp/v1/account.proto"; +import "gogoproto/gogo.proto"; + +// GenesisState defines the 27-gmp genesis state +message GenesisState { + // The list of registered ICS27 accounts + repeated RegisteredICS27Account ics27_accounts = 2 [(gogoproto.nullable) = false]; +} + +// RegisteredICS27Account contains an account identifier and associated interchain account address +message RegisteredICS27Account { + /// The address of the ics27 account + string account_address = 1; + /// The account identifier + AccountIdentifier account_id = 2 [(gogoproto.nullable) = false]; +} diff --git a/proto/ibc/applications/gmp/v1/packet.proto b/proto/ibc/applications/gmp/v1/packet.proto new file mode 100644 index 00000000000..43ede2a576f --- /dev/null +++ b/proto/ibc/applications/gmp/v1/packet.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; + +package ibc.applications.gmp.v1; + +option go_package = "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types"; + +// GMPPacketData defines a struct for the packet payload +message GMPPacketData { + // the sender address + string sender = 1; + // the recipient address on the destination chain + string receiver = 2; + // The salt used to generate the caller account address + bytes salt = 3; + // The payload of the call + bytes payload = 4; + // optional memo + string memo = 5; +} + +// Acknowledgement defines a struct for the ICS27-2 acknowledgement +message Acknowledgement { + // The result of the call + bytes result = 1; +} diff --git a/proto/ibc/applications/gmp/v1/query.proto b/proto/ibc/applications/gmp/v1/query.proto new file mode 100644 index 00000000000..3532e8ecaad --- /dev/null +++ b/proto/ibc/applications/gmp/v1/query.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; + +package ibc.applications.gmp.v1; + +import "google/api/annotations.proto"; + +option go_package = "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types"; + +// Query provides defines the gRPC querier service. +service Query { + // AccountAddress queries the interchain account address for a given client_id, sender, and salt. + // If the account is not registered, the address is computed deterministically + rpc AccountAddress(QueryAccountAddressRequest) returns (QueryAccountAddressResponse) { + option (google.api.http).get = "/ibc/apps/gmp/v1/clients/{client_id}/accounts/{sender}/{salt=**}"; + } +} + +// QueryAccountAddressRequest is the request type for the Query/AccountAddress RPC method. +message QueryAccountAddressRequest { + // The (local) client identifier + string client_id = 1; + // The sender of the packet + string sender = 2; + // The salt of the packet (in hex format) + string salt = 3; +} + +// QueryAccountAddressResponse is the response type for the Query/AccountAddress RPC method. +message QueryAccountAddressResponse { + // The interchain account address + string account_address = 1; +} diff --git a/proto/ibc/applications/gmp/v1/tx.proto b/proto/ibc/applications/gmp/v1/tx.proto new file mode 100644 index 00000000000..d3942230f51 --- /dev/null +++ b/proto/ibc/applications/gmp/v1/tx.proto @@ -0,0 +1,48 @@ +syntax = "proto3"; + +package ibc.applications.gmp.v1; + +option go_package = "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/msg/v1/msg.proto"; + +// Msg defines the ibc/gmp Msg service. +service Msg { + option (cosmos.msg.v1.service) = true; + + // SendCall defines a rpc handler method for MsgSendCall. + rpc SendCall(MsgSendCall) returns (MsgSendCallResponse); +} + +// MsgSendCall defines a msg to send a call to a contract/receiver on a ICS27-2 enabled chain. +message MsgSendCall { + option (cosmos.msg.v1.signer) = "sender"; + + option (gogoproto.goproto_getters) = false; + + // the client by which the packet will be sent + string source_client = 1; + // the sender address + string sender = 2; + // the recipient address on the destination chain + string receiver = 3; + // The salt used to generate the caller account address + bytes salt = 4; + // The payload of the call + bytes payload = 5; + // Timeout timestamp in absolute nanoseconds since unix epoch. + uint64 timeout_timestamp = 6; + // optional memo + string memo = 7; + // optional encoding + string encoding = 8; +} + +// MsgSendCallResponse defines the Msg/SendCall response type. +message MsgSendCallResponse { + option (gogoproto.goproto_getters) = false; + + // sequence number of the GMP packet sent + uint64 sequence = 1; +} diff --git a/simapp/app.go b/simapp/app.go index c7825e64815..a38a0ca0ae0 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -365,7 +365,7 @@ func NewSimApp( app.GovKeeper = *govKeeper.SetHooks( govtypes.NewMultiGovHooks( - // register the governance hooks + // register the governance hooks ), ) diff --git a/testing/simapp/app.go b/testing/simapp/app.go index ae21ddb29ac..8d91f9abcfb 100644 --- a/testing/simapp/app.go +++ b/testing/simapp/app.go @@ -83,6 +83,9 @@ import ( abci "github.com/cometbft/cometbft/abci/types" + gmp "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp" + gmpkeeper "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/keeper" + gmptypes "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" ica "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts" icacontroller "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts/controller" icacontrollerkeeper "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts/controller/keeper" @@ -124,6 +127,7 @@ var ( govtypes.ModuleName: {authtypes.Burner}, ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, icatypes.ModuleName: nil, + gmptypes.ModuleName: nil, ibcmock.ModuleName: nil, } ) @@ -158,6 +162,7 @@ type SimApp struct { IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly ICAControllerKeeper icacontrollerkeeper.Keeper ICAHostKeeper icahostkeeper.Keeper + GMPKeeper gmpkeeper.Keeper TransferKeeper ibctransferkeeper.Keeper ConsensusParamsKeeper consensusparamkeeper.Keeper @@ -252,7 +257,7 @@ func NewSimApp( authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, govtypes.StoreKey, group.StoreKey, paramstypes.StoreKey, ibcexported.StoreKey, upgradetypes.StoreKey, - ibctransfertypes.StoreKey, icacontrollertypes.StoreKey, icahosttypes.StoreKey, + ibctransfertypes.StoreKey, icacontrollertypes.StoreKey, icahosttypes.StoreKey, gmptypes.StoreKey, authzkeeper.StoreKey, consensusparamtypes.StoreKey, ) @@ -360,6 +365,15 @@ func NewSimApp( authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) + // ICS-27 GMP keeper + app.GMPKeeper = gmpkeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[gmptypes.ModuleName]), + app.AccountKeeper, + app.MsgServiceRouter(), + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + // Create IBC Router ibcRouter := porttypes.NewRouter() ibcRouterV2 := ibcapi.NewRouter() @@ -445,6 +459,9 @@ func NewSimApp( // register the transfer v2 module. ibcRouterV2.AddRoute(ibctransfertypes.PortID, transferv2.NewIBCModule(app.TransferKeeper)) + // Register the ICS-27 GMP module + ibcRouterV2.AddRoute(gmptypes.PortID, gmp.NewIBCModule(app.GMPKeeper)) + // Seal the IBC Router app.IBCKeeper.SetRouter(ibcRouter) app.IBCKeeper.SetRouterV2(ibcRouterV2) @@ -484,6 +501,7 @@ func NewSimApp( ibc.NewAppModule(app.IBCKeeper), transfer.NewAppModule(app.TransferKeeper), ica.NewAppModule(&app.ICAControllerKeeper, &app.ICAHostKeeper), + gmp.NewAppModule(app.GMPKeeper), mockModule, // IBC light clients @@ -528,6 +546,7 @@ func NewSimApp( genutiltypes.ModuleName, authz.ModuleName, icatypes.ModuleName, + gmptypes.ModuleName, ibcmock.ModuleName, ) app.ModuleManager.SetOrderEndBlockers( @@ -537,6 +556,7 @@ func NewSimApp( ibctransfertypes.ModuleName, genutiltypes.ModuleName, icatypes.ModuleName, + gmptypes.ModuleName, ibcmock.ModuleName, group.ModuleName, ) @@ -549,8 +569,8 @@ func NewSimApp( banktypes.ModuleName, distrtypes.ModuleName, stakingtypes.ModuleName, slashingtypes.ModuleName, govtypes.ModuleName, minttypes.ModuleName, ibcexported.ModuleName, genutiltypes.ModuleName, authz.ModuleName, ibctransfertypes.ModuleName, - icatypes.ModuleName, ibcmock.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName, - vestingtypes.ModuleName, group.ModuleName, consensusparamtypes.ModuleName, + icatypes.ModuleName, gmptypes.ModuleName, ibcmock.ModuleName, paramstypes.ModuleName, + upgradetypes.ModuleName, vestingtypes.ModuleName, group.ModuleName, consensusparamtypes.ModuleName, } app.ModuleManager.SetOrderInitGenesis(genesisModuleOrder...) app.ModuleManager.SetOrderExportGenesis(genesisModuleOrder...)