diff --git a/app/app.go b/app/app.go index c824bb31..7a78e8bb 100644 --- a/app/app.go +++ b/app/app.go @@ -87,6 +87,9 @@ import ( upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + onion "github.com/Team-Kujira/core/x/onion" + onionkeeper "github.com/Team-Kujira/core/x/onion/keeper" + oniontypes "github.com/Team-Kujira/core/x/onion/types" ibcwasm "github.com/cosmos/ibc-go/modules/light-clients/08-wasm" ibcwasmkeeper "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/keeper" ibcwasmtypes "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types" @@ -226,6 +229,7 @@ var ( oracle.AppModuleBasic{}, alliancemodule.AppModuleBasic{}, cwica.AppModuleBasic{}, + onion.AppModuleBasic{}, ) // module account permissions @@ -295,6 +299,7 @@ type App struct { ConsensusParamsKeeper consensusparamkeeper.Keeper ParamsKeeper paramskeeper.Keeper IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly + OnionKeeper *onionkeeper.Keeper IBCFeeKeeper ibcfeekeeper.Keeper ICAControllerKeeper icacontrollerkeeper.Keeper ICAHostKeeper icahostkeeper.Keeper @@ -383,6 +388,7 @@ func New( batchtypes.StoreKey, AllianceStoreKey, cwicatypes.StoreKey, + oniontypes.StoreKey, ) tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey) @@ -546,6 +552,14 @@ func New( scopedIBCKeeper, ) + app.OnionKeeper = onionkeeper.NewKeeper( + keys[oniontypes.StoreKey], + app.GetSubspace(oniontypes.ModuleName), + app.MsgServiceRouter(), + app.AccountKeeper, + txConfig.SignModeHandler(), + ) + // IBC Fee Module keeper app.IBCFeeKeeper = ibcfeekeeper.NewKeeper( @@ -762,6 +776,7 @@ func New( transferStack = transfer.NewIBCModule(app.TransferKeeper) transferStack = ibcfee.NewIBCMiddleware(transferStack, app.IBCFeeKeeper) transferStack = cwica.NewIBCMiddleware(transferStack, app.CwICAKeeper, app.IBCKeeper.ChannelKeeper) + transferStack = onion.NewIBCModule(transferStack, app.OnionKeeper, encodingConfig.TxConfig) // Create Interchain Accounts Stack // SendPacket, since it is originating from the application to core IBC: @@ -965,6 +980,8 @@ func New( ), ibcwasm.NewAppModule(app.WasmClientKeeper), + + onion.NewAppModule(*app.OnionKeeper), ) // During begin block slashing happens after distr.BeginBlocker so that @@ -1002,6 +1019,7 @@ func New( alliancemoduletypes.ModuleName, cwicatypes.ModuleName, ibcwasmtypes.ModuleName, + oniontypes.ModuleName, ) app.ModuleManager.SetOrderEndBlockers( @@ -1035,6 +1053,7 @@ func New( alliancemoduletypes.ModuleName, cwicatypes.ModuleName, ibcwasmtypes.ModuleName, + oniontypes.ModuleName, ) // NOTE: The genutils module must occur after staking so that pools are @@ -1075,6 +1094,7 @@ func New( alliancemoduletypes.ModuleName, wasmtypes.ModuleName, cwicatypes.ModuleName, + oniontypes.ModuleName, ) app.ModuleManager.RegisterInvariants(app.CrisisKeeper) @@ -1328,6 +1348,7 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino paramsKeeper.Subspace(oracletypes.ModuleName) paramsKeeper.Subspace(batchtypes.ModuleName) paramsKeeper.Subspace(alliancemoduletypes.ModuleName) + paramsKeeper.Subspace(oniontypes.ModuleName) return paramsKeeper } diff --git a/go.mod b/go.mod index 48cea682..012a004a 100644 --- a/go.mod +++ b/go.mod @@ -27,10 +27,12 @@ require ( github.com/prometheus/client_golang v1.16.0 github.com/spf13/cast v1.6.0 github.com/spf13/cobra v1.8.0 + github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 github.com/terra-money/alliance v0.3.5 google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 google.golang.org/grpc v1.62.1 + google.golang.org/protobuf v1.33.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -156,7 +158,6 @@ require ( github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.18.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect @@ -187,7 +188,6 @@ require ( google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect - google.golang.org/protobuf v1.33.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect nhooyr.io/websocket v1.8.6 // indirect diff --git a/proto/kujira/onion/genesis.proto b/proto/kujira/onion/genesis.proto new file mode 100644 index 00000000..b6734487 --- /dev/null +++ b/proto/kujira/onion/genesis.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; +package kujira.onion; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "kujira/onion/params.proto"; + +option go_package = "github.com/Team-Kujira/core/x/onion/types"; + +message GenesisState { + Params params = 1 [ (gogoproto.nullable) = false ]; + repeated OnionSequence sequences = 2 [ (gogoproto.nullable) = false ]; +} + +message OnionSequence { + string address = 1; + uint64 sequence = 2; +} \ No newline at end of file diff --git a/proto/kujira/onion/params.proto b/proto/kujira/onion/params.proto new file mode 100644 index 00000000..9faa6c9b --- /dev/null +++ b/proto/kujira/onion/params.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; +package kujira.onion; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "google/protobuf/duration.proto"; + +option go_package = "github.com/Team-Kujira/core/x/onion/types"; + +message Params { +} diff --git a/proto/kujira/onion/query.proto b/proto/kujira/onion/query.proto new file mode 100644 index 00000000..a4f3afb8 --- /dev/null +++ b/proto/kujira/onion/query.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; +package kujira.onion; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "kujira/onion/genesis.proto"; + +option go_package = "github.com/Team-Kujira/core/x/onion/types"; + +// Query defines the gRPC querier service. +service Query { + rpc Sequence(QuerySequenceRequest) returns (QuerySequenceResponse) { + option (google.api.http).get = "/kujira/onion/sequence/{address}"; + } +} + +message QuerySequenceRequest { string address = 1; } +message QuerySequenceResponse { + OnionSequence seq = 1 [ (gogoproto.nullable) = false ]; +} diff --git a/proto/kujira/onion/tx.proto b/proto/kujira/onion/tx.proto new file mode 100644 index 00000000..145d3b7f --- /dev/null +++ b/proto/kujira/onion/tx.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; +package kujira.onion; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/Team-Kujira/core/x/onion/types"; + +// Msg defines the Msg service. +service Msg { +} diff --git a/x/onion/client/cli/query.go b/x/onion/client/cli/query.go new file mode 100644 index 00000000..93352f72 --- /dev/null +++ b/x/onion/client/cli/query.go @@ -0,0 +1,68 @@ +package cli + +import ( + "context" + "fmt" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/spf13/cobra" + + "github.com/Team-Kujira/core/x/onion/types" +) + +func indexRunCmd(cmd *cobra.Command, _ []string) error { + usageTemplate := `Usage:{{if .HasAvailableSubCommands}} + {{.CommandPath}} [command]{{end}} + +{{if .HasAvailableSubCommands}}Available Commands:{{range .Commands}}{{if .IsAvailableCommand}} + {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}} + +Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}} +` + cmd.SetUsageTemplate(usageTemplate) + return cmd.Help() +} + +// GetQueryCmd returns the cli query commands for this module. +func GetQueryCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: indexRunCmd, + } + + cmd.AddCommand( + GetCmdQuerySequence(), + ) + return cmd +} + +// GetCmdQuerySequence implements the query sequence command. +func GetCmdQuerySequence() *cobra.Command { + cmd := &cobra.Command{ + Use: "sequence [address]", + Args: cobra.ExactArgs(1), + Short: "Query the onion sequence of an address", + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + res, err := queryClient.Sequence(context.Background(), &types.QuerySequenceRequest{ + Address: args[0], + }) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} diff --git a/x/onion/client/cli/tx.go b/x/onion/client/cli/tx.go new file mode 100644 index 00000000..a4dfc31c --- /dev/null +++ b/x/onion/client/cli/tx.go @@ -0,0 +1,138 @@ +package cli + +import ( + "context" + "encoding/base64" + "errors" + "fmt" + "os" + + "github.com/spf13/cobra" + "github.com/spf13/pflag" + + "github.com/Team-Kujira/core/x/onion/types" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + sdktx "github.com/cosmos/cosmos-sdk/client/tx" + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" +) + +// NewTxCmd returns a root CLI command handler for all x/bank transaction commands. +func NewTxCmd() *cobra.Command { + txCmd := &cobra.Command{ + Use: types.ModuleName, + Short: "Onion transaction subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + txCmd.AddCommand( + NewSendTxCmd(), + ) + + return txCmd +} + +// NewSendTxCmd returns a CLI command handler for creating a MsgSend transaction. +func NewSendTxCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "send [from_key_or_address] [to_address] [amount]", + Short: "Send funds from one account to another.", + Long: `Send funds from one account to another. +Note, the '--from' flag is ignored as it is implied from [from_key_or_address]. +When using '--dry-run' a key name cannot be used, only a bech32 address. +`, + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) error { + err := cmd.Flags().Set(flags.FlagFrom, args[0]) + if err != nil { + return err + } + + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + toAddr, err := sdk.AccAddressFromBech32(args[1]) + if err != nil { + return err + } + + coins, err := sdk.ParseCoinsNormalized(args[2]) + if err != nil { + return err + } + + msg := banktypes.NewMsgSend(clientCtx.GetFromAddress(), toAddr, coins) + + return WriteBase64Tx(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} + +func WriteBase64Tx(clientCtx client.Context, flagSet *pflag.FlagSet, msgs ...sdk.Msg) error { + txf, err := sdktx.NewFactoryCLI(clientCtx, flagSet) + if err != nil { + return err + } + + txf, err = txf.Prepare(clientCtx) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + newSeq := uint64(0) + res, err := queryClient.Sequence(context.Background(), &types.QuerySequenceRequest{ + Address: clientCtx.GetFromAddress().String(), + }) + if err == nil { + newSeq = res.Seq.Sequence + } + txf = txf.WithSequence(newSeq) + txf = txf.WithAccountNumber(types.AccountNumber) + + if txf.SimulateAndExecute() || clientCtx.Simulate { + if clientCtx.Offline { + return errors.New("cannot estimate gas in offline mode") + } + + _, adjusted, err := sdktx.CalculateGas(clientCtx, txf, msgs...) + if err != nil { + return err + } + + txf = txf.WithGas(adjusted) + _, _ = fmt.Fprintf(os.Stderr, "%s\n", sdktx.GasEstimateResponse{GasEstimate: txf.Gas()}) + } + + if clientCtx.Simulate { + return nil + } + + tx, err := txf.BuildUnsignedTx(msgs...) + if err != nil { + return err + } + + err = sdktx.Sign(txf, clientCtx.GetFromName(), tx, true) + if err != nil { + return err + } + + txBytes, err := clientCtx.TxConfig.TxEncoder()(tx.GetTx()) + if err != nil { + return err + } + + txBase64Encoding := base64.StdEncoding.EncodeToString(txBytes) + fmt.Println(txBase64Encoding) + return nil +} diff --git a/x/onion/ibc_module.go b/x/onion/ibc_module.go new file mode 100644 index 00000000..ccee40c7 --- /dev/null +++ b/x/onion/ibc_module.go @@ -0,0 +1,141 @@ +package onion + +import ( + // external libraries + + sdk "github.com/cosmos/cosmos-sdk/types" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + + // ibc-go + "github.com/Team-Kujira/core/x/onion/keeper" + "github.com/cosmos/cosmos-sdk/client" + transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" +) + +var _ porttypes.IBCModule = IBCModule{} + +type IBCModule struct { + App porttypes.IBCModule + Keeper *keeper.Keeper + txEncodingConfig client.TxEncodingConfig +} + +func NewIBCModule( + app porttypes.IBCModule, + Keeper *keeper.Keeper, + txEncodingConfig client.TxEncodingConfig, +) IBCModule { + return IBCModule{ + App: app, + Keeper: Keeper, + txEncodingConfig: txEncodingConfig, + } +} + +// OnChanOpenInit implements the IBCModule interface +func (im IBCModule) OnChanOpenInit( + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID string, + channelID string, + channelCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, + version string, +) (string, error) { + return im.App.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, channelCap, counterparty, version) +} + +// OnChanOpenTry implements the IBCModule interface +func (im IBCModule) OnChanOpenTry( + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID, + channelID string, + channelCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, + counterpartyVersion string, +) (string, error) { + return im.App.OnChanOpenTry(ctx, order, connectionHops, portID, channelID, channelCap, counterparty, counterpartyVersion) +} + +// OnChanOpenAck implements the IBCModule interface +func (im IBCModule) OnChanOpenAck( + ctx sdk.Context, + portID, + channelID string, + counterpartyChannelID string, + counterpartyVersion string, +) error { + return im.App.OnChanOpenAck(ctx, portID, channelID, counterpartyChannelID, counterpartyVersion) +} + +// OnChanOpenConfirm implements the IBCModule interface +func (im IBCModule) OnChanOpenConfirm( + ctx sdk.Context, + portID, + channelID string, +) error { + return im.App.OnChanOpenConfirm(ctx, portID, channelID) +} + +// OnChanCloseInit implements the IBCModule interface +func (im IBCModule) OnChanCloseInit( + ctx sdk.Context, + portID, + channelID string, +) error { + return im.App.OnChanCloseInit(ctx, portID, channelID) +} + +// OnChanCloseConfirm implements the IBCModule interface +func (im IBCModule) OnChanCloseConfirm( + ctx sdk.Context, + portID, + channelID string, +) error { + return im.App.OnChanCloseConfirm(ctx, portID, channelID) +} + +// OnRecvPacket implements the IBCModule interface +func (im IBCModule) OnRecvPacket( + ctx sdk.Context, + packet channeltypes.Packet, + relayer sdk.AccAddress, +) ibcexported.Acknowledgement { + ack := im.App.OnRecvPacket(ctx, packet, relayer) + + var data transfertypes.FungibleTokenPacketData + if err := transfertypes.ModuleCdc.UnmarshalJSON(packet.GetData(), &data); err != nil { + return ack + } + + if data.Memo != "" { + im.Keeper.HandleTransferHook(ctx, data.Memo, im.txEncodingConfig) + } + + return ack +} + +// OnAcknowledgementPacket implements the IBCModule interface +func (im IBCModule) OnAcknowledgementPacket( + ctx sdk.Context, + packet channeltypes.Packet, + acknowledgement []byte, + relayer sdk.AccAddress, +) error { + return im.App.OnAcknowledgementPacket(ctx, packet, acknowledgement, relayer) +} + +// OnTimeoutPacket implements the IBCModule interface +func (im IBCModule) OnTimeoutPacket( + ctx sdk.Context, + packet channeltypes.Packet, + relayer sdk.AccAddress, +) error { + return im.App.OnTimeoutPacket(ctx, packet, relayer) +} diff --git a/x/onion/keeper/ante.go b/x/onion/keeper/ante.go new file mode 100644 index 00000000..27bdadd7 --- /dev/null +++ b/x/onion/keeper/ante.go @@ -0,0 +1,191 @@ +package keeper + +import ( + "bytes" + "fmt" + + errorsmod "cosmossdk.io/errors" + "github.com/Team-Kujira/core/x/onion/types" + kmultisig "github.com/cosmos/cosmos-sdk/crypto/keys/multisig" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + txsigning "github.com/cosmos/cosmos-sdk/types/tx/signing" + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +func GetSignerAcc(ctx sdk.Context, ak types.AccountKeeper, addr sdk.AccAddress) (authtypes.AccountI, error) { + if acc := ak.GetAccount(ctx, addr); acc != nil { + return acc, nil + } + + return nil, errorsmod.Wrapf(sdkerrors.ErrUnknownAddress, "account %s does not exist", addr) +} + +// CountSubKeys counts the total number of keys for a multi-sig public key. +func CountSubKeys(pub cryptotypes.PubKey) int { + v, ok := pub.(*kmultisig.LegacyAminoPubKey) + if !ok { + return 1 + } + + numKeys := 0 + for _, subkey := range v.GetPubKeys() { + numKeys += CountSubKeys(subkey) + } + + return numKeys +} + +func OnlyLegacyAminoSigners(sigData txsigning.SignatureData) bool { + switch v := sigData.(type) { + case *txsigning.SingleSignatureData: + return v.SignMode == txsigning.SignMode_SIGN_MODE_LEGACY_AMINO_JSON + case *txsigning.MultiSignatureData: + for _, s := range v.Signatures { + if !OnlyLegacyAminoSigners(s) { + return false + } + } + return true + default: + return false + } +} + +func (k Keeper) ExecuteAnte(ctx sdk.Context, tx sdk.Tx) error { + // ValidateBasicDecorator + if err := tx.ValidateBasic(); err != nil { + return err + } + + // SetPubKeyDecorator + sigTx, ok := tx.(authsigning.SigVerifiableTx) + if !ok { + return errorsmod.Wrap(sdkerrors.ErrTxDecode, "invalid tx type") + } + + pubkeys, err := sigTx.GetPubKeys() + if err != nil { + return err + } + signers := sigTx.GetSigners() + + for i, pk := range pubkeys { + if pk == nil { + continue + } + if !bytes.Equal(pk.Address(), signers[i]) { + return errorsmod.Wrapf(sdkerrors.ErrInvalidPubKey, + "pubKey does not match signer address %s with signer index: %d", signers[i], i) + } + + acc, err := GetSignerAcc(ctx, k.accountKeeper, signers[i]) + if err != nil { + acc = k.accountKeeper.NewAccountWithAddress(ctx, signers[i]) + k.accountKeeper.SetAccount(ctx, acc) + } + if acc.GetPubKey() != nil { + continue + } + err = acc.SetPubKey(pk) + if err != nil { + return errorsmod.Wrap(sdkerrors.ErrInvalidPubKey, err.Error()) + } + k.accountKeeper.SetAccount(ctx, acc) + } + + // ValidateSigCountDecorator + params := k.accountKeeper.GetParams(ctx) + pubKeys, err := sigTx.GetPubKeys() + if err != nil { + return err + } + + sigCount := 0 + for _, pk := range pubKeys { + sigCount += CountSubKeys(pk) + if uint64(sigCount) > params.TxSigLimit { + return errorsmod.Wrapf(sdkerrors.ErrTooManySignatures, + "signatures: %d, limit: %d", sigCount, params.TxSigLimit) + } + } + + // SigVerificationDecorator + sigs, err := sigTx.GetSignaturesV2() + if err != nil { + return err + } + + signerAddrs := sigTx.GetSigners() + + if len(sigs) != len(signerAddrs) { + return errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "invalid number of signer; expected: %d, got %d", len(signerAddrs), len(sigs)) + } + + for i, sig := range sigs { + acc, err := GetSignerAcc(ctx, k.accountKeeper, signerAddrs[i]) + if err != nil { + return err + } + + pubKey := acc.GetPubKey() + if pubKey == nil { + return errorsmod.Wrap(sdkerrors.ErrInvalidPubKey, "pubkey on account is not set") + } + + onionSeq := uint64(0) + seq, err := k.GetSequence(ctx, acc.GetAddress().String()) + if err == nil { + onionSeq = seq.Sequence + } + + if sig.Sequence != onionSeq { + return errorsmod.Wrapf( + sdkerrors.ErrWrongSequence, + "onion sequence mismatch, expected %d, got %d", onionSeq, sig.Sequence, + ) + } + + chainID := ctx.ChainID() + accNum := types.AccountNumber + signerData := authsigning.SignerData{ + Address: acc.GetAddress().String(), + ChainID: chainID, + AccountNumber: accNum, + Sequence: onionSeq, + PubKey: pubKey, + } + + err = authsigning.VerifySignature(pubKey, signerData, sig.Data, k.signModeHandler, tx) + if err != nil { + var errMsg string + if OnlyLegacyAminoSigners(sig.Data) { + errMsg = fmt.Sprintf("signature verification failed; please verify account number (%d), sequence (%d) and chain-id (%s)", accNum, acc.GetSequence(), chainID) + } else { + errMsg = fmt.Sprintf("signature verification failed; please verify account number (%d) and chain-id (%s)", accNum, chainID) + } + return errorsmod.Wrap(sdkerrors.ErrUnauthorized, errMsg) + } + } + + // IncrementSequenceDecorator + for _, addr := range sigTx.GetSigners() { + seq, err := k.GetSequence(ctx, addr.String()) + if err != nil { + seq = types.OnionSequence{ + Address: addr.String(), + Sequence: 0, + } + } + + seq.Sequence++ + err = k.SetSequence(ctx, seq) + if err != nil { + return err + } + } + + return nil +} diff --git a/x/onion/keeper/ante_test.go b/x/onion/keeper/ante_test.go new file mode 100644 index 00000000..adcc5968 --- /dev/null +++ b/x/onion/keeper/ante_test.go @@ -0,0 +1,88 @@ +package keeper_test + +import ( + "github.com/Team-Kujira/core/x/onion/types" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" +) + +func (s *KeeperTestSuite) TestExecuteAnte() { + privKey1 := secp256k1.GenPrivKeyFromSecret([]byte("test1")) + pubKey1 := privKey1.PubKey() + privKey2 := secp256k1.GenPrivKeyFromSecret([]byte("test2")) + pubKey2 := privKey2.PubKey() + + addr1 := sdk.AccAddress(pubKey1.Address()) + addr2 := sdk.AccAddress(pubKey2.Address()) + + msgSend1 := &banktypes.MsgSend{ + FromAddress: addr1.String(), + ToAddress: addr2.String(), + Amount: sdk.Coins{sdk.NewInt64Coin("test", 100)}, + } + msgSend2 := &banktypes.MsgSend{ + FromAddress: addr1.String(), + ToAddress: addr2.String(), + Amount: sdk.Coins{sdk.NewInt64Coin("test", 200)}, + } + + specs := map[string]struct { + msgs []sdk.Msg + accNum uint64 + nonce uint64 + expErr bool + }{ + "empty message tx ante": { + msgs: []sdk.Msg{}, + accNum: types.AccountNumber, + nonce: 0, + expErr: true, + }, + "single message tx ante": { + msgs: []sdk.Msg{msgSend1}, + accNum: types.AccountNumber, + nonce: 0, + expErr: false, + }, + "multiple messages tx ante": { + msgs: []sdk.Msg{msgSend1, msgSend2}, + accNum: types.AccountNumber, + nonce: 0, + expErr: false, + }, + "invalid nonce check": { + msgs: []sdk.Msg{msgSend1}, + accNum: types.AccountNumber, + nonce: 1, + expErr: true, + }, + "invalid account number check": { + msgs: []sdk.Msg{msgSend1}, + accNum: 1, + nonce: 0, + expErr: true, + }, + } + for msg, spec := range specs { + spec := spec + s.Run(msg, func() { + s.SetupTest() + s.Ctx = s.Ctx.WithChainID("test") + tx := newTx(s.T(), s.App.TxConfig(), addr1, s.Ctx.ChainID(), spec.accNum, spec.msgs, spec.nonce, privKey1) + err := s.App.OnionKeeper.ExecuteAnte(s.Ctx, tx) + if spec.expErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + // check account set in account module + acc1 := s.App.AccountKeeper.GetAccount(s.Ctx, addr1) + s.Require().NotNil(acc1) + // check sequence increase + seq, err := s.App.OnionKeeper.GetSequence(s.Ctx, addr1.String()) + s.Require().NoError(err) + s.Require().Equal(seq.Sequence, uint64(1)) + } + }) + } +} diff --git a/x/onion/keeper/execute.go b/x/onion/keeper/execute.go new file mode 100644 index 00000000..125424ca --- /dev/null +++ b/x/onion/keeper/execute.go @@ -0,0 +1,31 @@ +package keeper + +import ( + "fmt" + + errorsmod "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/group/errors" +) + +func (k Keeper) ExecuteTxMsgs(ctx sdk.Context, tx sdk.Tx) ([]sdk.Result, error) { + msgs := tx.GetMsgs() + results := make([]sdk.Result, len(msgs)) + for i, msg := range msgs { + handler := k.router.Handler(msg) + if handler == nil { + return nil, errorsmod.Wrapf(errors.ErrInvalid, "no message handler found for %q", sdk.MsgTypeURL(msg)) + } + r, err := handler(ctx, msg) + if err != nil { + return nil, errorsmod.Wrapf(err, "message %s at position %d", sdk.MsgTypeURL(msg), i) + } + // Handler should always return non-nil sdk.Result. + if r == nil { + return nil, fmt.Errorf("got nil sdk.Result for message %q at position %d", msg, i) + } + + results[i] = *r + } + return results, nil +} diff --git a/x/onion/keeper/execute_test.go b/x/onion/keeper/execute_test.go new file mode 100644 index 00000000..c7192799 --- /dev/null +++ b/x/onion/keeper/execute_test.go @@ -0,0 +1,144 @@ +package keeper_test + +import ( + "testing" + + "github.com/Team-Kujira/core/x/onion/types" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" + signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" + "github.com/cosmos/cosmos-sdk/x/auth/signing" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + "github.com/stretchr/testify/require" +) + +func (s *KeeperTestSuite) TestExecuteTxMsgs() { + privKey1 := secp256k1.GenPrivKeyFromSecret([]byte("test1")) + pubKey1 := privKey1.PubKey() + privKey2 := secp256k1.GenPrivKeyFromSecret([]byte("test2")) + pubKey2 := privKey2.PubKey() + + addr1 := sdk.AccAddress(pubKey1.Address()) + addr2 := sdk.AccAddress(pubKey2.Address()) + + msgSend1 := &banktypes.MsgSend{ + FromAddress: addr1.String(), + ToAddress: addr2.String(), + Amount: sdk.Coins{sdk.NewInt64Coin("test", 100)}, + } + msgSend2 := &banktypes.MsgSend{ + FromAddress: addr1.String(), + ToAddress: addr2.String(), + Amount: sdk.Coins{sdk.NewInt64Coin("test", 200)}, + } + msgSend3 := &banktypes.MsgSend{ + FromAddress: addr1.String(), + ToAddress: addr2.String(), + Amount: sdk.Coins{sdk.NewInt64Coin("test", 1000)}, + } + + specs := map[string]struct { + msgs []sdk.Msg + expErr bool + expSenderBalance sdk.Coins + expReceiverBalance sdk.Coins + }{ + "empty messages execution": { + msgs: []sdk.Msg{}, + expErr: false, + expSenderBalance: sdk.Coins{sdk.NewInt64Coin("test", 500)}, + expReceiverBalance: sdk.Coins{}, + }, + "successful execution of a single message": { + msgs: []sdk.Msg{msgSend1}, + expErr: false, + expSenderBalance: sdk.Coins{sdk.NewInt64Coin("test", 400)}, + expReceiverBalance: sdk.Coins{sdk.NewInt64Coin("test", 100)}, + }, + "successful execution of multiple messages": { + msgs: []sdk.Msg{msgSend1, msgSend2}, + expErr: false, + expSenderBalance: sdk.Coins{sdk.NewInt64Coin("test", 200)}, + expReceiverBalance: sdk.Coins{sdk.NewInt64Coin("test", 300)}, + }, + "one execution failure in multiple messages": { + msgs: []sdk.Msg{msgSend1, msgSend3}, + expErr: true, + expSenderBalance: sdk.Coins{}, + expReceiverBalance: sdk.Coins{}, + }, + } + for msg, spec := range specs { + spec := spec + s.Run(msg, func() { + s.SetupTest() + coins := sdk.Coins{sdk.NewInt64Coin("test", 500)} + err := s.App.BankKeeper.MintCoins(s.Ctx, minttypes.ModuleName, coins) + s.Require().NoError(err) + err = s.App.BankKeeper.SendCoinsFromModuleToAccount(s.Ctx, minttypes.ModuleName, addr1, coins) + s.Require().NoError(err) + + tx := newTx(s.T(), s.App.TxConfig(), addr1, s.Ctx.ChainID(), types.AccountNumber, spec.msgs, 0, privKey1) + results, err := s.App.OnionKeeper.ExecuteTxMsgs(s.Ctx, tx) + if spec.expErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + s.Require().Len(results, len(spec.msgs)) + senderBalance := s.App.BankKeeper.GetAllBalances(s.Ctx, addr1) + s.Require().Equal(senderBalance.String(), spec.expSenderBalance.String()) + receiverBalance := s.App.BankKeeper.GetAllBalances(s.Ctx, addr2) + s.Require().Equal(receiverBalance.String(), spec.expReceiverBalance.String()) + } + }) + } +} + +func newTx(t *testing.T, cfg client.TxConfig, addr sdk.AccAddress, chainId string, accountNumber uint64, msgs []sdk.Msg, nonce uint64, privKey *secp256k1.PrivKey) signing.Tx { + builder := cfg.NewTxBuilder() + builder.SetMsgs(msgs...) + if len(msgs) > 0 { + pubKey := privKey.PubKey() + signModeHandler := cfg.SignModeHandler() + err := builder.SetSignatures( + signingtypes.SignatureV2{ + PubKey: pubKey, + Sequence: nonce, + Data: &signingtypes.SingleSignatureData{ + SignMode: signModeHandler.DefaultMode(), + Signature: []byte{}, + }, + }, + ) + require.NoError(t, err) + + signerData := signing.SignerData{ + Address: addr.String(), + ChainID: chainId, + AccountNumber: accountNumber, + Sequence: nonce, + PubKey: pubKey, + } + tx := builder.GetTx() + signBytes, err := signModeHandler.GetSignBytes(signModeHandler.DefaultMode(), signerData, tx) + require.NoError(t, err) + sigBz, err := privKey.Sign(signBytes) + require.NoError(t, err) + + err = builder.SetSignatures( + signingtypes.SignatureV2{ + PubKey: pubKey, + Sequence: nonce, + Data: &signingtypes.SingleSignatureData{ + SignMode: signModeHandler.DefaultMode(), + Signature: sigBz, + }, + }, + ) + require.NoError(t, err) + } + + return builder.GetTx() +} diff --git a/x/onion/keeper/hook.go b/x/onion/keeper/hook.go new file mode 100644 index 00000000..dc2e80c3 --- /dev/null +++ b/x/onion/keeper/hook.go @@ -0,0 +1,31 @@ +package keeper + +import ( + "encoding/base64" + + "github.com/cosmos/cosmos-sdk/client" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (k Keeper) HandleTransferHook(ctx sdk.Context, memo string, txEncodingConfig client.TxEncodingConfig) { + newRawTx, err := base64.StdEncoding.DecodeString(memo) + if err != nil { + return + } + + tx, err := txEncodingConfig.TxDecoder()(newRawTx) + if err != nil { + return + } + + cacheCtx, write := ctx.CacheContext() + err = k.ExecuteAnte(cacheCtx, tx) + if err != nil { + return + } + + _, err = k.ExecuteTxMsgs(cacheCtx, tx) + if err == nil { + write() + } +} diff --git a/x/onion/keeper/hook_test.go b/x/onion/keeper/hook_test.go new file mode 100644 index 00000000..4e4080f6 --- /dev/null +++ b/x/onion/keeper/hook_test.go @@ -0,0 +1,105 @@ +package keeper_test + +import ( + "encoding/base64" + + "github.com/Team-Kujira/core/x/onion/types" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" +) + +func (s *KeeperTestSuite) TestOnReceivePacketHook() { + privKey1 := secp256k1.GenPrivKeyFromSecret([]byte("test1")) + pubKey1 := privKey1.PubKey() + privKey2 := secp256k1.GenPrivKeyFromSecret([]byte("test2")) + pubKey2 := privKey2.PubKey() + + addr1 := sdk.AccAddress(pubKey1.Address()) + addr2 := sdk.AccAddress(pubKey2.Address()) + + msgSend1 := &banktypes.MsgSend{ + FromAddress: addr1.String(), + ToAddress: addr2.String(), + Amount: sdk.Coins{sdk.NewInt64Coin("test", 100)}, + } + msgSend2 := &banktypes.MsgSend{ + FromAddress: addr1.String(), + ToAddress: addr2.String(), + Amount: sdk.Coins{sdk.NewInt64Coin("test", 200)}, + } + msgSend3 := &banktypes.MsgSend{ + FromAddress: addr1.String(), + ToAddress: addr2.String(), + Amount: sdk.Coins{sdk.NewInt64Coin("test", 1000)}, + } + + specs := map[string]struct { + msgs []sdk.Msg + expErr bool + expSenderBalance sdk.Coins + expReceiverBalance sdk.Coins + }{ + "successful execution of a single message": { + msgs: []sdk.Msg{msgSend1}, + expErr: false, + expSenderBalance: sdk.Coins{sdk.NewInt64Coin("test", 400)}, + expReceiverBalance: sdk.Coins{sdk.NewInt64Coin("test", 100)}, + }, + "successful execution of multiple messages": { + msgs: []sdk.Msg{msgSend1, msgSend2}, + expErr: false, + expSenderBalance: sdk.Coins{sdk.NewInt64Coin("test", 200)}, + expReceiverBalance: sdk.Coins{sdk.NewInt64Coin("test", 300)}, + }, + "empty messages execution": { + msgs: []sdk.Msg{}, + expErr: true, + expSenderBalance: sdk.Coins{sdk.NewInt64Coin("test", 500)}, + expReceiverBalance: sdk.Coins{}, + }, + "one execution failure in multiple messages": { + msgs: []sdk.Msg{msgSend1, msgSend3}, + expErr: true, + expSenderBalance: sdk.Coins{}, + expReceiverBalance: sdk.Coins{}, + }, + } + for msg, spec := range specs { + spec := spec + s.Run(msg, func() { + s.SetupTest() + coins := sdk.Coins{sdk.NewInt64Coin("test", 500)} + err := s.App.BankKeeper.MintCoins(s.Ctx, minttypes.ModuleName, coins) + s.Require().NoError(err) + err = s.App.BankKeeper.SendCoinsFromModuleToAccount(s.Ctx, minttypes.ModuleName, addr1, coins) + s.Require().NoError(err) + + tx := newTx(s.T(), s.App.TxConfig(), addr1, s.Ctx.ChainID(), types.AccountNumber, spec.msgs, 0, privKey1) + txBytes, err := s.App.TxConfig().TxEncoder()(tx) + s.Require().NoError(err) + + memo := base64.StdEncoding.EncodeToString(txBytes) + + s.App.OnionKeeper.HandleTransferHook(s.Ctx, memo, s.App.TxConfig()) + if spec.expErr { + // Check sequence change + seq, err := s.App.OnionKeeper.GetSequence(s.Ctx, addr1.String()) + s.Require().NoError(err) + s.Require().Equal(seq.Sequence, uint64(0)) + } else { + // Check sequence change + seq, err := s.App.OnionKeeper.GetSequence(s.Ctx, addr1.String()) + s.Require().NoError(err) + s.Require().Equal(seq.Sequence, uint64(1)) + + // Check balance + senderBalance := s.App.BankKeeper.GetAllBalances(s.Ctx, addr1) + s.Require().Equal(senderBalance.String(), spec.expSenderBalance.String()) + receiverBalance := s.App.BankKeeper.GetAllBalances(s.Ctx, addr2) + s.Require().Equal(receiverBalance.String(), spec.expReceiverBalance.String()) + } + }) + } +} diff --git a/x/onion/keeper/keeper.go b/x/onion/keeper/keeper.go new file mode 100644 index 00000000..18577113 --- /dev/null +++ b/x/onion/keeper/keeper.go @@ -0,0 +1,77 @@ +package keeper + +import ( + "fmt" + + "github.com/Team-Kujira/core/x/onion/types" + "github.com/cometbft/cometbft/libs/log" + "github.com/cosmos/cosmos-sdk/baseapp" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" +) + +type ( + Keeper struct { + storeKey storetypes.StoreKey + paramSpace paramtypes.Subspace + + accountKeeper types.AccountKeeper + + router *baseapp.MsgServiceRouter + signModeHandler authsigning.SignModeHandler + } +) + +// NewKeeper returns a new instance of the x/ibchooks keeper +func NewKeeper( + storeKey storetypes.StoreKey, + paramSpace paramtypes.Subspace, + router *baseapp.MsgServiceRouter, + accountKeeper types.AccountKeeper, + signModeHandler authsigning.SignModeHandler, +) *Keeper { + if !paramSpace.HasKeyTable() { + paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable()) + } + return &Keeper{ + storeKey: storeKey, + paramSpace: paramSpace, + router: router, + accountKeeper: accountKeeper, + signModeHandler: signModeHandler, + } +} + +// Logger returns a logger for the x/tokenfactory module +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) +} + +// GetParams returns the total set of the module's parameters. +func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { + k.paramSpace.GetParamSet(ctx, ¶ms) + return params +} + +// SetParams sets the module's parameters with the provided parameters. +func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { + k.paramSpace.SetParamSet(ctx, ¶ms) +} + +func (k Keeper) InitGenesis(ctx sdk.Context, genState types.GenesisState) { + k.SetParams(ctx, genState.Params) + for _, seq := range genState.Sequences { + if err := k.SetSequence(ctx, seq); err != nil { + panic(err) + } + } +} + +func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { + return &types.GenesisState{ + Params: k.GetParams(ctx), + Sequences: k.GetAllSequences(ctx), + } +} diff --git a/x/onion/keeper/keeper_test.go b/x/onion/keeper/keeper_test.go new file mode 100644 index 00000000..6825d4d2 --- /dev/null +++ b/x/onion/keeper/keeper_test.go @@ -0,0 +1,28 @@ +package keeper_test + +import ( + "testing" + + app "github.com/Team-Kujira/core/app" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/suite" +) + +type KeeperTestSuite struct { + suite.Suite + + App *app.App + Ctx sdk.Context +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} + +func (suite *KeeperTestSuite) SetupTest() { + app := app.Setup(suite.T(), false) + + suite.Ctx = app.BaseApp.NewContext(false, tmproto.Header{}) + suite.App = app +} diff --git a/x/onion/keeper/msg_server.go b/x/onion/keeper/msg_server.go new file mode 100644 index 00000000..2749b4f2 --- /dev/null +++ b/x/onion/keeper/msg_server.go @@ -0,0 +1,17 @@ +package keeper + +import ( + "github.com/Team-Kujira/core/x/onion/types" +) + +type msgServer struct { + Keeper +} + +// NewMsgServerImpl returns an implementation of the MsgServer interface +// for the provided Keeper. +func NewMsgServerImpl(keeper Keeper) types.MsgServer { + return &msgServer{Keeper: keeper} +} + +var _ types.MsgServer = msgServer{} diff --git a/x/onion/keeper/query.go b/x/onion/keeper/query.go new file mode 100644 index 00000000..373afe8a --- /dev/null +++ b/x/onion/keeper/query.go @@ -0,0 +1,20 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/Team-Kujira/core/x/onion/types" +) + +var _ types.QueryServer = Keeper{} + +func (k Keeper) Sequence(c context.Context, req *types.QuerySequenceRequest) (*types.QuerySequenceResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + seq, err := k.GetSequence(ctx, req.Address) + if err != nil { + return nil, err + } + return &types.QuerySequenceResponse{Seq: seq}, nil +} diff --git a/x/onion/keeper/sequence.go b/x/onion/keeper/sequence.go new file mode 100644 index 00000000..a5efde6a --- /dev/null +++ b/x/onion/keeper/sequence.go @@ -0,0 +1,59 @@ +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/gogoproto/proto" + + "github.com/Team-Kujira/core/x/onion/types" +) + +// GetAuthorityMetadata returns the authority metadata for a specific denom +func (k Keeper) GetSequence(ctx sdk.Context, address string) (types.OnionSequence, error) { + store := ctx.KVStore(k.storeKey) + prefixStore := prefix.NewStore(store, []byte(types.OnionSequencePrefix)) + bz := prefixStore.Get([]byte(address)) + if bz == nil { + return types.OnionSequence{ + Address: address, + Sequence: 0, + }, nil + } + sequence := types.OnionSequence{} + err := proto.Unmarshal(bz, &sequence) + if err != nil { + return types.OnionSequence{}, err + } + return sequence, nil +} + +// SetAuthorityMetadata stores authority metadata for a specific denom +func (k Keeper) SetSequence(ctx sdk.Context, sequence types.OnionSequence) error { + store := ctx.KVStore(k.storeKey) + prefixStore := prefix.NewStore(store, []byte(types.OnionSequencePrefix)) + + bz, err := proto.Marshal(&sequence) + if err != nil { + return err + } + + prefixStore.Set([]byte(sequence.Address), bz) + return nil +} + +func (k Keeper) GetAllSequences(ctx sdk.Context) []types.OnionSequence { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + defer iterator.Close() + + sequences := []types.OnionSequence{} + for ; iterator.Valid(); iterator.Next() { + sequence := types.OnionSequence{} + err := proto.Unmarshal(iterator.Value(), &sequence) + if err != nil { + panic(err) + } + sequences = append(sequences, sequence) + } + return sequences +} diff --git a/x/onion/keeper/sequence_test.go b/x/onion/keeper/sequence_test.go new file mode 100644 index 00000000..83023a97 --- /dev/null +++ b/x/onion/keeper/sequence_test.go @@ -0,0 +1,40 @@ +package keeper_test + +import ( + "github.com/Team-Kujira/core/x/onion/types" + "github.com/cometbft/cometbft/crypto/ed25519" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (suite *KeeperTestSuite) TestSequence() { + suite.SetupTest() + + // Set accounts + addr1 := sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address()) + addr2 := sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address()) + addr3 := sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address()) + err := suite.App.OnionKeeper.SetSequence(suite.Ctx, types.OnionSequence{ + Address: addr1.String(), + Sequence: 1, + }) + suite.Require().NoError(err) + err = suite.App.OnionKeeper.SetSequence(suite.Ctx, types.OnionSequence{ + Address: addr2.String(), + Sequence: 2, + }) + suite.Require().NoError(err) + + // Check queries + sequence, err := suite.App.OnionKeeper.GetSequence(suite.Ctx, addr1.String()) + suite.Require().NoError(err) + suite.Require().Equal(sequence.Address, addr1.String()) + suite.Require().Equal(sequence.Sequence, uint64(1)) + sequence, err = suite.App.OnionKeeper.GetSequence(suite.Ctx, addr2.String()) + suite.Require().NoError(err) + suite.Require().Equal(sequence.Address, addr2.String()) + suite.Require().Equal(sequence.Sequence, uint64(2)) + sequence, err = suite.App.OnionKeeper.GetSequence(suite.Ctx, addr3.String()) + suite.Require().NoError(err) + suite.Require().Equal(sequence.Address, addr3.String()) + suite.Require().Equal(sequence.Sequence, uint64(0)) +} diff --git a/x/onion/module.go b/x/onion/module.go new file mode 100644 index 00000000..4529a244 --- /dev/null +++ b/x/onion/module.go @@ -0,0 +1,142 @@ +package onion + +import ( + "encoding/json" + "fmt" + + "github.com/Team-Kujira/core/x/onion/keeper" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/types/module" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + + "github.com/Team-Kujira/core/x/onion/client/cli" + "github.com/Team-Kujira/core/x/onion/types" + + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + + abci "github.com/cometbft/cometbft/abci/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} +) + +// AppModuleBasic defines the basic application module used by the ibc-hooks module. +type AppModuleBasic struct{} + +var _ module.AppModuleBasic = AppModuleBasic{} + +// Name returns the ibc-hooks module's name. +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +// RegisterLegacyAminoCodec registers the ibc-hooks module's types on the given LegacyAmino codec. +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + types.RegisterCodec(cdc) +} + +// RegisterInterfaces registers the module's interface types +func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) { + types.RegisterInterfaces(reg) +} + +// DefaultGenesis returns default genesis state as raw bytes for the +// module. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(types.DefaultGenesis()) +} + +// ValidateGenesis performs genesis state validation for the ibc-hooks module. +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error { + var genState types.GenesisState + if err := cdc.UnmarshalJSON(bz, &genState); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) + } + return genState.Validate() +} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the ibc-hooks module. +func (AppModuleBasic) RegisterGRPCGatewayRoutes(_ client.Context, _ *runtime.ServeMux) {} + +// GetTxCmd returns no root tx command for the ibc-hooks module. +func (AppModuleBasic) GetTxCmd() *cobra.Command { + return cli.NewTxCmd() +} + +// GetQueryCmd returns the root query command for the ibc-hooks module. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return cli.GetQueryCmd() +} + +// ___________________________________________________________________________ + +// AppModule implements an application module for the ibc-hooks module. +type AppModule struct { + AppModuleBasic + + keeper keeper.Keeper +} + +// NewAppModule creates a new AppModule object. +func NewAppModule(keeper keeper.Keeper) AppModule { + return AppModule{ + AppModuleBasic: AppModuleBasic{}, + keeper: keeper, + } +} + +// Name returns the ibc-hooks module's name. +func (AppModule) Name() string { + return types.ModuleName +} + +// RegisterInvariants registers the ibc-hooks module invariants. +func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} + +// QuerierRoute returns the module's querier route name. +func (AppModule) QuerierRoute() string { + return "" +} + +// RegisterServices registers a gRPC query service to respond to the +// module-specific gRPC queries. +func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) + types.RegisterQueryServer(cfg.QueryServer(), am.keeper) +} + +// InitGenesis performs genesis initialization for the ibc-hooks module. It returns +// no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { + var genState types.GenesisState + // Initialize global index to index in genesis state + cdc.MustUnmarshalJSON(data, &genState) + + am.keeper.InitGenesis(ctx, genState) + + return []abci.ValidatorUpdate{} +} + +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + genState := am.keeper.ExportGenesis(ctx) + return cdc.MustMarshalJSON(genState) +} + +// BeginBlock returns the begin blocker for the ibc-hooks module. +func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) { +} + +// EndBlock returns the end blocker for the ibc-hooks module. It returns no validator +// updates. +func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} + +// ConsensusVersion implements AppModule/ConsensusVersion. +func (AppModule) ConsensusVersion() uint64 { return 1 } diff --git a/x/onion/types/codec.go b/x/onion/types/codec.go new file mode 100644 index 00000000..d639f465 --- /dev/null +++ b/x/onion/types/codec.go @@ -0,0 +1,36 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + authzcodec "github.com/cosmos/cosmos-sdk/x/authz/codec" + + // this line is used by starport scaffolding # 1 + "github.com/cosmos/cosmos-sdk/types/msgservice" +) + +func RegisterCodec(_ *codec.LegacyAmino) { +} + +func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { + registry.RegisterImplementations( + (*sdk.Msg)(nil), + ) + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) +} + +var ( + amino = codec.NewLegacyAmino() + ModuleCdc = codec.NewProtoCodec(cdctypes.NewInterfaceRegistry()) +) + +func init() { + RegisterCodec(amino) + // Register all Amino interfaces and concrete types on the authz Amino codec so that this can later be + // used to properly serialize MsgGrant and MsgExec instances + sdk.RegisterLegacyAminoCodec(amino) + RegisterCodec(authzcodec.Amino) + + amino.Seal() +} diff --git a/x/onion/types/errors.go b/x/onion/types/errors.go new file mode 100644 index 00000000..ab1254f4 --- /dev/null +++ b/x/onion/types/errors.go @@ -0,0 +1 @@ +package types diff --git a/x/onion/types/expected_keepers.go b/x/onion/types/expected_keepers.go new file mode 100644 index 00000000..71d8f43b --- /dev/null +++ b/x/onion/types/expected_keepers.go @@ -0,0 +1,14 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +type AccountKeeper interface { + GetParams(ctx sdk.Context) (params authtypes.Params) + GetAccount(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI + SetAccount(ctx sdk.Context, acc authtypes.AccountI) + GetModuleAddress(moduleName string) sdk.AccAddress + NewAccountWithAddress(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI +} diff --git a/x/onion/types/genesis.go b/x/onion/types/genesis.go new file mode 100644 index 00000000..980e39e2 --- /dev/null +++ b/x/onion/types/genesis.go @@ -0,0 +1,17 @@ +package types + +// DefaultGenesis returns the default GenesisState for the concentrated-liquidity module. +func DefaultGenesis() *GenesisState { + return &GenesisState{ + Params: DefaultParams(), + Sequences: []OnionSequence{}, + } +} + +// Validate performs basic genesis state validation returning an error upon any failure. +func (gs GenesisState) Validate() error { + if err := gs.Params.Validate(); err != nil { + return err + } + return nil +} diff --git a/x/onion/types/genesis.pb.go b/x/onion/types/genesis.pb.go new file mode 100644 index 00000000..f85d2aaa --- /dev/null +++ b/x/onion/types/genesis.pb.go @@ -0,0 +1,593 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: kujira/onion/genesis.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + _ "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 + +type GenesisState struct { + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + Sequences []OnionSequence `protobuf:"bytes,2,rep,name=sequences,proto3" json:"sequences"` +} + +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_e5d80ee52a36c767, []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) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +func (m *GenesisState) GetSequences() []OnionSequence { + if m != nil { + return m.Sequences + } + return nil +} + +type OnionSequence struct { + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + Sequence uint64 `protobuf:"varint,2,opt,name=sequence,proto3" json:"sequence,omitempty"` +} + +func (m *OnionSequence) Reset() { *m = OnionSequence{} } +func (m *OnionSequence) String() string { return proto.CompactTextString(m) } +func (*OnionSequence) ProtoMessage() {} +func (*OnionSequence) Descriptor() ([]byte, []int) { + return fileDescriptor_e5d80ee52a36c767, []int{1} +} +func (m *OnionSequence) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *OnionSequence) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_OnionSequence.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 *OnionSequence) XXX_Merge(src proto.Message) { + xxx_messageInfo_OnionSequence.Merge(m, src) +} +func (m *OnionSequence) XXX_Size() int { + return m.Size() +} +func (m *OnionSequence) XXX_DiscardUnknown() { + xxx_messageInfo_OnionSequence.DiscardUnknown(m) +} + +var xxx_messageInfo_OnionSequence proto.InternalMessageInfo + +func (m *OnionSequence) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *OnionSequence) GetSequence() uint64 { + if m != nil { + return m.Sequence + } + return 0 +} + +func init() { + proto.RegisterType((*GenesisState)(nil), "kujira.onion.GenesisState") + proto.RegisterType((*OnionSequence)(nil), "kujira.onion.OnionSequence") +} + +func init() { proto.RegisterFile("kujira/onion/genesis.proto", fileDescriptor_e5d80ee52a36c767) } + +var fileDescriptor_e5d80ee52a36c767 = []byte{ + // 276 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xca, 0x2e, 0xcd, 0xca, + 0x2c, 0x4a, 0xd4, 0xcf, 0xcf, 0xcb, 0xcc, 0xcf, 0xd3, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, + 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x81, 0xc8, 0xe9, 0x81, 0xe5, 0xa4, 0x44, 0xd2, + 0xf3, 0xd3, 0xf3, 0xc1, 0x12, 0xfa, 0x20, 0x16, 0x44, 0x8d, 0x94, 0x64, 0x72, 0x7e, 0x71, 0x6e, + 0x7e, 0x71, 0x3c, 0x44, 0x02, 0xc2, 0x81, 0x49, 0xa1, 0x18, 0x5d, 0x90, 0x58, 0x94, 0x98, 0x0b, + 0x95, 0x52, 0x6a, 0x66, 0xe4, 0xe2, 0x71, 0x87, 0xd8, 0x15, 0x5c, 0x92, 0x58, 0x92, 0x2a, 0x64, + 0xc4, 0xc5, 0x06, 0x51, 0x20, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x6d, 0x24, 0xa2, 0x87, 0x6c, 0xb7, + 0x5e, 0x00, 0x58, 0xce, 0x89, 0xe5, 0xc4, 0x3d, 0x79, 0x86, 0x20, 0xa8, 0x4a, 0x21, 0x7b, 0x2e, + 0xce, 0xe2, 0xd4, 0xc2, 0xd2, 0xd4, 0xbc, 0xe4, 0xd4, 0x62, 0x09, 0x26, 0x05, 0x66, 0x0d, 0x6e, + 0x23, 0x69, 0x54, 0x6d, 0xfe, 0x20, 0x32, 0x18, 0xaa, 0x06, 0xaa, 0x1b, 0xa1, 0x47, 0xc9, 0x95, + 0x8b, 0x17, 0x45, 0x85, 0x90, 0x04, 0x17, 0x7b, 0x62, 0x4a, 0x4a, 0x51, 0x6a, 0x31, 0xc4, 0x19, + 0x9c, 0x41, 0x30, 0xae, 0x90, 0x14, 0x17, 0x07, 0x4c, 0x9f, 0x04, 0x93, 0x02, 0xa3, 0x06, 0x4b, + 0x10, 0x9c, 0xef, 0xe4, 0x7c, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, + 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0x9a, + 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0x21, 0xa9, 0x89, 0xb9, 0xba, + 0xde, 0x90, 0x10, 0x49, 0xce, 0x2f, 0x4a, 0xd5, 0xaf, 0x80, 0x06, 0x4c, 0x49, 0x65, 0x41, 0x6a, + 0x71, 0x12, 0x1b, 0x38, 0x60, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xbf, 0xac, 0xe9, 0x22, + 0x90, 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.Sequences) > 0 { + for iNdEx := len(m.Sequences) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Sequences[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *OnionSequence) 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 *OnionSequence) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OnionSequence) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Sequence != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.Sequence)) + i-- + dAtA[i] = 0x10 + } + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Address))) + 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 + l = m.Params.Size() + n += 1 + l + sovGenesis(uint64(l)) + if len(m.Sequences) > 0 { + for _, e := range m.Sequences { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n +} + +func (m *OnionSequence) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + if m.Sequence != 0 { + n += 1 + sovGenesis(uint64(m.Sequence)) + } + 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 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", 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.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sequences", 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.Sequences = append(m.Sequences, OnionSequence{}) + if err := m.Sequences[len(m.Sequences)-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 *OnionSequence) 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: OnionSequence: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: OnionSequence: 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 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.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + 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 ErrIntOverflowGenesis + } + 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 := 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/x/onion/types/keys.go b/x/onion/types/keys.go new file mode 100644 index 00000000..acb3c70d --- /dev/null +++ b/x/onion/types/keys.go @@ -0,0 +1,11 @@ +package types + +const ( + ModuleName = "onion" + RouterKey = ModuleName + StoreKey = ModuleName + + OnionSequencePrefix = "onion-sequence" +) + +const AccountNumber = ^uint64(0) diff --git a/x/onion/types/msgs.go b/x/onion/types/msgs.go new file mode 100644 index 00000000..ab1254f4 --- /dev/null +++ b/x/onion/types/msgs.go @@ -0,0 +1 @@ +package types diff --git a/x/onion/types/params.go b/x/onion/types/params.go new file mode 100644 index 00000000..a7db94df --- /dev/null +++ b/x/onion/types/params.go @@ -0,0 +1,33 @@ +package types + +import ( + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" +) + +// Parameter store keys. +var ( + _ paramtypes.ParamSet = &Params{} +) + +func ParamKeyTable() paramtypes.KeyTable { + return paramtypes.NewKeyTable() +} + +func NewParams() Params { + return Params{} +} + +// DefaultParams returns default concentrated-liquidity module parameters. +func DefaultParams() Params { + return Params{} +} + +// ParamSetPairs implements params.ParamSet. +func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { + return paramtypes.ParamSetPairs{} +} + +// Validate params. +func (p Params) Validate() error { + return nil +} diff --git a/x/onion/types/params.pb.go b/x/onion/types/params.pb.go new file mode 100644 index 00000000..5dd3232d --- /dev/null +++ b/x/onion/types/params.pb.go @@ -0,0 +1,268 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: kujira/onion/params.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + _ "google.golang.org/protobuf/types/known/durationpb" + 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 + +type Params struct { +} + +func (m *Params) Reset() { *m = Params{} } +func (m *Params) String() string { return proto.CompactTextString(m) } +func (*Params) ProtoMessage() {} +func (*Params) Descriptor() ([]byte, []int) { + return fileDescriptor_c9158e41ac96e8e0, []int{0} +} +func (m *Params) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Params.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 *Params) XXX_Merge(src proto.Message) { + xxx_messageInfo_Params.Merge(m, src) +} +func (m *Params) XXX_Size() int { + return m.Size() +} +func (m *Params) XXX_DiscardUnknown() { + xxx_messageInfo_Params.DiscardUnknown(m) +} + +var xxx_messageInfo_Params proto.InternalMessageInfo + +func init() { + proto.RegisterType((*Params)(nil), "kujira.onion.Params") +} + +func init() { proto.RegisterFile("kujira/onion/params.proto", fileDescriptor_c9158e41ac96e8e0) } + +var fileDescriptor_c9158e41ac96e8e0 = []byte{ + // 183 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xcc, 0x2e, 0xcd, 0xca, + 0x2c, 0x4a, 0xd4, 0xcf, 0xcf, 0xcb, 0xcc, 0xcf, 0xd3, 0x2f, 0x48, 0x2c, 0x4a, 0xcc, 0x2d, 0xd6, + 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x81, 0x48, 0xe9, 0x81, 0xa5, 0xa4, 0x44, 0xd2, 0xf3, + 0xd3, 0xf3, 0xc1, 0x12, 0xfa, 0x20, 0x16, 0x44, 0x8d, 0x94, 0x64, 0x72, 0x7e, 0x71, 0x6e, 0x7e, + 0x71, 0x3c, 0x44, 0x02, 0xc2, 0x81, 0x4a, 0xc9, 0xa5, 0xe7, 0xe7, 0xa7, 0xe7, 0xa4, 0xea, 0x83, + 0x79, 0x49, 0xa5, 0x69, 0xfa, 0x29, 0xa5, 0x45, 0x89, 0x25, 0x99, 0xf9, 0x79, 0x10, 0x79, 0x25, + 0x0e, 0x2e, 0xb6, 0x00, 0xb0, 0x75, 0x4e, 0xce, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, + 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, + 0xc7, 0x10, 0xa5, 0x99, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x1f, 0x92, + 0x9a, 0x98, 0xab, 0xeb, 0x0d, 0x71, 0x6d, 0x72, 0x7e, 0x51, 0xaa, 0x7e, 0x05, 0xd4, 0xd1, 0x25, + 0x95, 0x05, 0xa9, 0xc5, 0x49, 0x6c, 0x60, 0x53, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x42, + 0xa0, 0x06, 0x6b, 0xd1, 0x00, 0x00, 0x00, +} + +func (m *Params) 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 *Params) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintParams(dAtA []byte, offset int, v uint64) int { + offset -= sovParams(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Params) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovParams(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozParams(x uint64) (n int) { + return sovParams(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Params) 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 ErrIntOverflowParams + } + 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: Params: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipParams(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthParams + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipParams(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, ErrIntOverflowParams + } + 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, ErrIntOverflowParams + } + 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, ErrIntOverflowParams + } + 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, ErrInvalidLengthParams + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupParams + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthParams + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthParams = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowParams = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupParams = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/onion/types/query.pb.go b/x/onion/types/query.pb.go new file mode 100644 index 00000000..0d9756e9 --- /dev/null +++ b/x/onion/types/query.pb.go @@ -0,0 +1,582 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: kujira/onion/query.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/cosmos/gogoproto/gogoproto" + 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 + +type QuerySequenceRequest struct { + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` +} + +func (m *QuerySequenceRequest) Reset() { *m = QuerySequenceRequest{} } +func (m *QuerySequenceRequest) String() string { return proto.CompactTextString(m) } +func (*QuerySequenceRequest) ProtoMessage() {} +func (*QuerySequenceRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d450ac6fbe173c50, []int{0} +} +func (m *QuerySequenceRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySequenceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySequenceRequest.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 *QuerySequenceRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySequenceRequest.Merge(m, src) +} +func (m *QuerySequenceRequest) XXX_Size() int { + return m.Size() +} +func (m *QuerySequenceRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySequenceRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySequenceRequest proto.InternalMessageInfo + +func (m *QuerySequenceRequest) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +type QuerySequenceResponse struct { + Seq OnionSequence `protobuf:"bytes,1,opt,name=seq,proto3" json:"seq"` +} + +func (m *QuerySequenceResponse) Reset() { *m = QuerySequenceResponse{} } +func (m *QuerySequenceResponse) String() string { return proto.CompactTextString(m) } +func (*QuerySequenceResponse) ProtoMessage() {} +func (*QuerySequenceResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d450ac6fbe173c50, []int{1} +} +func (m *QuerySequenceResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySequenceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySequenceResponse.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 *QuerySequenceResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySequenceResponse.Merge(m, src) +} +func (m *QuerySequenceResponse) XXX_Size() int { + return m.Size() +} +func (m *QuerySequenceResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySequenceResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySequenceResponse proto.InternalMessageInfo + +func (m *QuerySequenceResponse) GetSeq() OnionSequence { + if m != nil { + return m.Seq + } + return OnionSequence{} +} + +func init() { + proto.RegisterType((*QuerySequenceRequest)(nil), "kujira.onion.QuerySequenceRequest") + proto.RegisterType((*QuerySequenceResponse)(nil), "kujira.onion.QuerySequenceResponse") +} + +func init() { proto.RegisterFile("kujira/onion/query.proto", fileDescriptor_d450ac6fbe173c50) } + +var fileDescriptor_d450ac6fbe173c50 = []byte{ + // 304 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x90, 0xcb, 0x4a, 0x03, 0x31, + 0x18, 0x85, 0x27, 0xde, 0x8d, 0xae, 0x42, 0x85, 0x32, 0x4a, 0x2c, 0xe3, 0xa6, 0x2e, 0x9c, 0x48, + 0xfb, 0x06, 0x75, 0xa9, 0x20, 0x56, 0x57, 0xee, 0xd2, 0xf6, 0x27, 0x46, 0x6d, 0xfe, 0xe9, 0x24, + 0x03, 0x16, 0xe9, 0xc6, 0x85, 0x6b, 0xc1, 0x97, 0xea, 0xb2, 0xe0, 0xc6, 0x95, 0x48, 0xeb, 0x83, + 0xc8, 0xdc, 0xc0, 0x11, 0x71, 0x93, 0x0b, 0xe7, 0x3b, 0x27, 0x27, 0x3f, 0xad, 0xdf, 0x25, 0xb7, + 0x3a, 0x96, 0x02, 0x8d, 0x46, 0x23, 0x46, 0x09, 0xc4, 0xe3, 0x30, 0x8a, 0xd1, 0x21, 0xdb, 0xce, + 0x95, 0x30, 0x53, 0xfc, 0x9a, 0x42, 0x85, 0x99, 0x20, 0xd2, 0x53, 0xce, 0xf8, 0x7b, 0x0a, 0x51, + 0xdd, 0x83, 0x90, 0x91, 0x16, 0xd2, 0x18, 0x74, 0xd2, 0x69, 0x34, 0xb6, 0x50, 0xfd, 0x4a, 0xb6, + 0x02, 0x03, 0x56, 0x17, 0x5a, 0x70, 0x4c, 0x6b, 0x17, 0xe9, 0x63, 0x97, 0x30, 0x4a, 0xc0, 0xf4, + 0xa1, 0x9b, 0xee, 0xd6, 0xb1, 0x3a, 0x5d, 0x97, 0x83, 0x41, 0x0c, 0xd6, 0xd6, 0x49, 0x83, 0x34, + 0x37, 0xbb, 0xe5, 0x35, 0x38, 0xa3, 0x3b, 0xbf, 0x1c, 0x36, 0x42, 0x63, 0x81, 0xb5, 0xe9, 0xb2, + 0x85, 0x51, 0x86, 0x6f, 0xb5, 0x76, 0xc3, 0x9f, 0xb5, 0xc3, 0xf3, 0x74, 0x2d, 0x1d, 0x9d, 0x95, + 0xe9, 0xc7, 0xbe, 0xd7, 0x4d, 0xe9, 0xd6, 0x33, 0xa1, 0xab, 0x59, 0x1c, 0x9b, 0xd0, 0x8d, 0x12, + 0x60, 0x41, 0xd5, 0xfd, 0x57, 0x43, 0xff, 0xe0, 0x5f, 0x26, 0xef, 0x14, 0x34, 0x9f, 0xde, 0xbe, + 0x5e, 0x97, 0x02, 0xd6, 0x10, 0x95, 0x19, 0xd8, 0x82, 0x13, 0x8f, 0xc5, 0xaf, 0x26, 0x9d, 0x93, + 0xe9, 0x9c, 0x93, 0xd9, 0x9c, 0x93, 0xcf, 0x39, 0x27, 0x2f, 0x0b, 0xee, 0xcd, 0x16, 0xdc, 0x7b, + 0x5f, 0x70, 0xef, 0xfa, 0x50, 0x69, 0x77, 0x93, 0xf4, 0xc2, 0x3e, 0x0e, 0xc5, 0x15, 0xc8, 0xe1, + 0xd1, 0x69, 0x1e, 0xd5, 0xc7, 0x18, 0xc4, 0x43, 0x91, 0xe8, 0xc6, 0x11, 0xd8, 0xde, 0x5a, 0x36, + 0xd4, 0xf6, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x5f, 0x6b, 0x98, 0x59, 0xce, 0x01, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueryClient interface { + Sequence(ctx context.Context, in *QuerySequenceRequest, opts ...grpc.CallOption) (*QuerySequenceResponse, error) +} + +type queryClient struct { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) Sequence(ctx context.Context, in *QuerySequenceRequest, opts ...grpc.CallOption) (*QuerySequenceResponse, error) { + out := new(QuerySequenceResponse) + err := c.cc.Invoke(ctx, "/kujira.onion.Query/Sequence", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +type QueryServer interface { + Sequence(context.Context, *QuerySequenceRequest) (*QuerySequenceResponse, error) +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (*UnimplementedQueryServer) Sequence(ctx context.Context, req *QuerySequenceRequest) (*QuerySequenceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Sequence not implemented") +} + +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +func _Query_Sequence_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QuerySequenceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Sequence(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/kujira.onion.Query/Sequence", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Sequence(ctx, req.(*QuerySequenceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "kujira.onion.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Sequence", + Handler: _Query_Sequence_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "kujira/onion/query.proto", +} + +func (m *QuerySequenceRequest) 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 *QuerySequenceRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QuerySequenceRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QuerySequenceResponse) 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 *QuerySequenceResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QuerySequenceResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Seq.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + 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 *QuerySequenceRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QuerySequenceResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Seq.Size() + 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 *QuerySequenceRequest) 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: QuerySequenceRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySequenceRequest: 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 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.Address = 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 *QuerySequenceResponse) 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: QuerySequenceResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySequenceResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Seq", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Seq.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + 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/x/onion/types/query.pb.gw.go b/x/onion/types/query.pb.gw.go new file mode 100644 index 00000000..e02cfdb3 --- /dev/null +++ b/x/onion/types/query.pb.gw.go @@ -0,0 +1,184 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: kujira/onion/query.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage + +func request_Query_Sequence_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySequenceRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") + } + + protoReq.Address, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) + } + + msg, err := client.Sequence(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Sequence_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySequenceRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") + } + + protoReq.Address, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) + } + + msg, err := server.Sequence(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterQueryHandlerServer registers the http handlers for service Query to "mux". +// UnaryRPC :call QueryServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { + + mux.Handle("GET", pattern_Query_Sequence_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_Sequence_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Sequence_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_Sequence_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_Sequence_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_Sequence_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Query_Sequence_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"kujira", "onion", "sequence", "address"}, "", runtime.AssumeColonVerbOpt(true))) +) + +var ( + forward_Query_Sequence_0 = runtime.ForwardResponseMessage +) diff --git a/x/onion/types/tx.pb.go b/x/onion/types/tx.pb.go new file mode 100644 index 00000000..cdd9e7a3 --- /dev/null +++ b/x/onion/types/tx.pb.go @@ -0,0 +1,82 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: kujira/onion/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + grpc "google.golang.org/grpc" + math "math" +) + +// 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 + +func init() { proto.RegisterFile("kujira/onion/tx.proto", fileDescriptor_788539ffbe617633) } + +var fileDescriptor_788539ffbe617633 = []byte{ + // 139 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xcd, 0x2e, 0xcd, 0xca, + 0x2c, 0x4a, 0xd4, 0xcf, 0xcf, 0xcb, 0xcc, 0xcf, 0xd3, 0x2f, 0xa9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, + 0xc9, 0x17, 0xe2, 0x81, 0x08, 0xeb, 0x81, 0x85, 0xa5, 0x44, 0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0x12, + 0xfa, 0x20, 0x16, 0x44, 0x8d, 0x11, 0x2b, 0x17, 0xb3, 0x6f, 0x71, 0xba, 0x93, 0xf3, 0x89, 0x47, + 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c, 0xc3, 0x85, + 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0x69, 0xa6, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, + 0x25, 0xe7, 0xe7, 0xea, 0x87, 0xa4, 0x26, 0xe6, 0xea, 0x7a, 0x43, 0xec, 0x4a, 0xce, 0x2f, 0x4a, + 0xd5, 0xaf, 0x80, 0x59, 0x59, 0x59, 0x90, 0x5a, 0x9c, 0xc4, 0x06, 0x36, 0xd2, 0x18, 0x10, 0x00, + 0x00, 0xff, 0xff, 0x22, 0x53, 0x0d, 0xef, 0x8f, 0x00, 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 { +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "kujira.onion.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{}, + Metadata: "kujira/onion/tx.proto", +} diff --git a/x/onion/types/types.go b/x/onion/types/types.go new file mode 100644 index 00000000..ab1254f4 --- /dev/null +++ b/x/onion/types/types.go @@ -0,0 +1 @@ +package types