From d1a12098eef390df4c8dcbae71ad6e8828ead4f0 Mon Sep 17 00:00:00 2001 From: ZuluSpl0it Date: Mon, 11 May 2026 23:11:29 -0500 Subject: [PATCH 1/5] feat: add cron module --- app/cron_integration_test.go | 149 +++ app/keepers/keepers.go | 14 + app/modules.go | 8 + proto/terra/cron/v1/genesis.proto | 13 + proto/terra/cron/v1/params.proto | 12 + proto/terra/cron/v1/query.proto | 47 + proto/terra/cron/v1/schedule.proto | 28 + proto/terra/cron/v1/tx.proto | 52 + scripts/README.md | 36 + scripts/cron-auth-gate-test.sh | 107 ++ scripts/cron-test.sh | 116 +++ x/cron/client/cli/query.go | 106 ++ x/cron/client/cli/query_test.go | 14 + x/cron/client/cli/tx.go | 144 +++ x/cron/client/cli/tx_test.go | 14 + x/cron/genesis.go | 26 + x/cron/keeper/grpc_query.go | 56 ++ x/cron/keeper/keeper.go | 210 ++++ x/cron/keeper/keeper_test.go | 74 ++ x/cron/keeper/msg_server.go | 70 ++ x/cron/keeper/msg_server_test.go | 41 + x/cron/keeper/params.go | 27 + x/cron/keeper/test_utils_test.go | 104 ++ x/cron/module.go | 122 +++ x/cron/spec/01_concepts.md | 41 + x/cron/spec/02_state.md | 66 ++ x/cron/spec/03_block_lifecycle.md | 42 + x/cron/spec/04_messages.md | 67 ++ x/cron/spec/05_events.md | 25 + x/cron/spec/06_params.md | 22 + x/cron/spec/README.md | 33 + x/cron/types/codec.go | 39 + x/cron/types/errors.go | 14 + x/cron/types/expected_keepers.go | 16 + x/cron/types/genesis.go | 69 ++ x/cron/types/genesis.pb.go | 385 ++++++++ x/cron/types/genesis_test.go | 14 + x/cron/types/keys.go | 30 + x/cron/types/params.go | 59 ++ x/cron/types/params.pb.go | 304 ++++++ x/cron/types/query.pb.go | 1379 ++++++++++++++++++++++++++ x/cron/types/query.pb.gw.go | 337 +++++++ x/cron/types/schedule.pb.go | 899 +++++++++++++++++ x/cron/types/tx.go | 107 ++ x/cron/types/tx.pb.go | 1485 ++++++++++++++++++++++++++++ 45 files changed, 7023 insertions(+) create mode 100644 app/cron_integration_test.go create mode 100644 proto/terra/cron/v1/genesis.proto create mode 100644 proto/terra/cron/v1/params.proto create mode 100644 proto/terra/cron/v1/query.proto create mode 100644 proto/terra/cron/v1/schedule.proto create mode 100644 proto/terra/cron/v1/tx.proto create mode 100644 scripts/cron-auth-gate-test.sh create mode 100644 scripts/cron-test.sh create mode 100644 x/cron/client/cli/query.go create mode 100644 x/cron/client/cli/query_test.go create mode 100644 x/cron/client/cli/tx.go create mode 100644 x/cron/client/cli/tx_test.go create mode 100644 x/cron/genesis.go create mode 100644 x/cron/keeper/grpc_query.go create mode 100644 x/cron/keeper/keeper.go create mode 100644 x/cron/keeper/keeper_test.go create mode 100644 x/cron/keeper/msg_server.go create mode 100644 x/cron/keeper/msg_server_test.go create mode 100644 x/cron/keeper/params.go create mode 100644 x/cron/keeper/test_utils_test.go create mode 100644 x/cron/module.go create mode 100644 x/cron/spec/01_concepts.md create mode 100644 x/cron/spec/02_state.md create mode 100644 x/cron/spec/03_block_lifecycle.md create mode 100644 x/cron/spec/04_messages.md create mode 100644 x/cron/spec/05_events.md create mode 100644 x/cron/spec/06_params.md create mode 100644 x/cron/spec/README.md create mode 100644 x/cron/types/codec.go create mode 100644 x/cron/types/errors.go create mode 100644 x/cron/types/expected_keepers.go create mode 100644 x/cron/types/genesis.go create mode 100644 x/cron/types/genesis.pb.go create mode 100644 x/cron/types/genesis_test.go create mode 100644 x/cron/types/keys.go create mode 100644 x/cron/types/params.go create mode 100644 x/cron/types/params.pb.go create mode 100644 x/cron/types/query.pb.go create mode 100644 x/cron/types/query.pb.gw.go create mode 100644 x/cron/types/schedule.pb.go create mode 100644 x/cron/types/tx.go create mode 100644 x/cron/types/tx.pb.go diff --git a/app/cron_integration_test.go b/app/cron_integration_test.go new file mode 100644 index 000000000..a40d3da1a --- /dev/null +++ b/app/cron_integration_test.go @@ -0,0 +1,149 @@ +package app_test + +import ( + "context" + "testing" + "time" + + sdkmath "cosmossdk.io/math" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + "github.com/classic-terra/core/v4/app" + appparams "github.com/classic-terra/core/v4/app/params" + helpers "github.com/classic-terra/core/v4/app/testing" + coretypes "github.com/classic-terra/core/v4/types" + "github.com/classic-terra/core/v4/x/cron/types" + dyncommtypes "github.com/classic-terra/core/v4/x/dyncomm/types" + markettypes "github.com/classic-terra/core/v4/x/market/types" + oracletypes "github.com/classic-terra/core/v4/x/oracle/types" + taxtypes "github.com/classic-terra/core/v4/x/tax/types" + treasurytypes "github.com/classic-terra/core/v4/x/treasury/types" + abci "github.com/cometbft/cometbft/abci/types" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/stretchr/testify/require" +) + +type appCronWasmMsgServer struct { + calls []*wasmtypes.MsgExecuteContract +} + +func (s *appCronWasmMsgServer) ExecuteContract(_ context.Context, msg *wasmtypes.MsgExecuteContract) (*wasmtypes.MsgExecuteContractResponse, error) { + s.calls = append(s.calls, msg) + return &wasmtypes.MsgExecuteContractResponse{}, nil +} + +func initCronAppState(t *testing.T, terraApp *app.TerraApp, ctx sdk.Context) { + t.Helper() + + terraApp.ConsensusParamsKeeper.ParamsStore.Set(ctx, *helpers.DefaultConsensusParams) + terraApp.MintKeeper.Params.Set(ctx, minttypes.DefaultParams()) + terraApp.MintKeeper.Minter.Set(ctx, minttypes.DefaultInitialMinter()) + + taxParams := taxtypes.DefaultParams() + taxParams.GasPrices = sdk.NewDecCoins(sdk.NewDecCoin(coretypes.MicroSDRDenom, sdkmath.ZeroInt())) + require.NoError(t, terraApp.TaxKeeper.SetParams(ctx, taxParams)) + + bankParams := banktypes.DefaultParams() + bankParams.DefaultSendEnabled = true + require.NoError(t, terraApp.BankKeeper.SetParams(ctx, bankParams)) + terraApp.BankKeeper.SetSendEnabled(ctx, "uluna", true) + + stakingParams := stakingtypes.DefaultParams() + stakingParams.BondDenom = appparams.BondDenom + require.NoError(t, terraApp.StakingKeeper.SetParams(ctx, stakingParams)) + terraApp.DistrKeeper.Params.Set(ctx, distrtypes.DefaultParams()) + terraApp.DistrKeeper.FeePool.Set(ctx, distrtypes.InitialFeePool()) + terraApp.WasmKeeper.SetParams(ctx, wasmtypes.DefaultParams()) + terraApp.MarketKeeper.SetParams(ctx, markettypes.DefaultParams()) + terraApp.OracleKeeper.SetParams(ctx, oracletypes.DefaultParams()) + terraApp.TreasuryKeeper.SetParams(ctx, treasurytypes.DefaultParams()) + terraApp.DyncommKeeper.SetParams(ctx, dyncommtypes.DefaultParams()) +} + +type appBlockModule interface { + BeginBlock(context.Context) ([]abci.ValidatorUpdate, error) + EndBlock(context.Context) ([]abci.ValidatorUpdate, error) +} + +func TestCronModuleWiredIntoApp(t *testing.T) { + terraApp := helpers.SetupApp(t, "cron-test") + + require.Contains(t, terraApp.Modules(), types.ModuleName) + require.NotNil(t, terraApp.CronKeeper.WasmMsgServer) + require.True(t, terraApp.ModuleAccountAddrs()[authtypes.NewModuleAddress(types.ModuleName).String()]) +} + +func TestCronExecutesInBeginBlock(t *testing.T) { + terraApp := helpers.SetupApp(t, "cron-test") + fakeServer := &appCronWasmMsgServer{} + terraApp.CronKeeper.WasmMsgServer = fakeServer + + ctx := terraApp.NewUncachedContext(false, tmproto.Header{ChainID: "cron-test"}) + ctx = ctx.WithBlockHeight(9).WithBlockTime(time.Now().UTC()) + initCronAppState(t, terraApp, ctx) + + require.NoError(t, terraApp.CronKeeper.SetParams(ctx, types.NewParams(1))) + require.NoError(t, terraApp.CronKeeper.AddSchedule( + ctx, + "begin-job", + 1, + []types.MsgExecuteContract{{Contract: "terra1contract", Msg: `{"ping":{}}`}}, + 9, + types.ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER, + )) + + execCtx := terraApp.NewUncachedContext(false, tmproto.Header{ChainID: "cron-test"}) + execCtx = execCtx.WithBlockHeight(10).WithBlockTime(time.Now().UTC()) + require.Equal(t, int64(10), execCtx.BlockHeight()) + + // Use the app-registered cron module instance so the test exercises the module + // exactly as Terra wires it into the app. + cronModule := terraApp.Modules()[types.ModuleName].(appBlockModule) + _, err := cronModule.BeginBlock(sdk.WrapSDKContext(execCtx)) + require.NoError(t, err) + require.Len(t, fakeServer.calls, 1) + + schedule, found := terraApp.CronKeeper.GetSchedule(execCtx, "begin-job") + require.True(t, found) + require.Equal(t, uint64(10), schedule.LastExecuteHeight) +} + +func TestCronExecutesInEndBlock(t *testing.T) { + terraApp := helpers.SetupApp(t, "cron-test") + fakeServer := &appCronWasmMsgServer{} + terraApp.CronKeeper.WasmMsgServer = fakeServer + + ctx := terraApp.NewUncachedContext(false, tmproto.Header{ChainID: "cron-test"}) + ctx = ctx.WithBlockHeight(10).WithBlockTime(time.Now().UTC()) + initCronAppState(t, terraApp, ctx) + + require.NoError(t, terraApp.CronKeeper.SetParams(ctx, types.NewParams(1))) + require.NoError(t, terraApp.CronKeeper.AddSchedule( + ctx, + "end-job", + 1, + []types.MsgExecuteContract{{Contract: "terra1contract", Msg: `{"pong":{}}`}}, + 10, + types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER, + )) + + execCtx := terraApp.NewUncachedContext(false, tmproto.Header{ChainID: "cron-test"}) + execCtx = execCtx.WithBlockHeight(11).WithBlockTime(time.Now().UTC()) + require.Equal(t, int64(11), execCtx.BlockHeight()) + + // Use the app-registered cron module instance so the test exercises the module + // exactly as Terra wires it into the app. + cronModule := terraApp.Modules()[types.ModuleName].(appBlockModule) + _, err := cronModule.EndBlock(sdk.WrapSDKContext(execCtx)) + require.NoError(t, err) + require.Len(t, fakeServer.calls, 1) + + schedule, found := terraApp.CronKeeper.GetSchedule(execCtx, "end-job") + require.True(t, found) + require.Equal(t, uint64(11), schedule.LastExecuteHeight) +} diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 84280bcf6..da96aa712 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -18,6 +18,8 @@ import ( customstaking "github.com/classic-terra/core/v4/custom/staking" customwasmkeeper "github.com/classic-terra/core/v4/custom/wasm/keeper" terrawasm "github.com/classic-terra/core/v4/wasmbinding" + cronkeeper "github.com/classic-terra/core/v4/x/cron/keeper" + crontypes "github.com/classic-terra/core/v4/x/cron/types" dyncommkeeper "github.com/classic-terra/core/v4/x/dyncomm/keeper" dyncommtypes "github.com/classic-terra/core/v4/x/dyncomm/types" marketkeeper "github.com/classic-terra/core/v4/x/market/keeper" @@ -101,6 +103,7 @@ type AppKeepers struct { TreasuryKeeper treasurykeeper.Keeper TaxExemptionKeeper taxexemptionkeeper.Keeper WasmKeeper wasmkeeper.Keeper + CronKeeper cronkeeper.Keeper DyncommKeeper dyncommkeeper.Keeper IBCHooksKeeper *ibchookskeeper.Keeper ConsensusParamsKeeper consensusparamkeeper.Keeper @@ -147,6 +150,7 @@ func NewAppKeepers( treasurytypes.StoreKey: storetypes.NewKVStoreKey(treasurytypes.StoreKey), taxexemptiontypes.StoreKey: storetypes.NewKVStoreKey(taxexemptiontypes.StoreKey), wasmtypes.StoreKey: storetypes.NewKVStoreKey(wasmtypes.StoreKey), + crontypes.StoreKey: storetypes.NewKVStoreKey(crontypes.StoreKey), dyncommtypes.StoreKey: storetypes.NewKVStoreKey(dyncommtypes.StoreKey), taxtypes.StoreKey: storetypes.NewKVStoreKey(taxtypes.StoreKey), } @@ -343,6 +347,13 @@ func NewAppKeepers( authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) + appKeepers.CronKeeper = cronkeeper.NewKeeper( + appCodec, + appKeepers.keys[crontypes.StoreKey], + appKeepers.AccountKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + hooksKeeper := ibchookskeeper.NewKeeper( appKeepers.keys[ibchookstypes.StoreKey], ) @@ -435,6 +446,8 @@ func NewAppKeepers( wasmOpts..., // Options ) + appKeepers.CronKeeper.WasmMsgServer = wasmkeeper.NewMsgServerImpl(&appKeepers.WasmKeeper) + // AFTER wasm set contractKeeper for ics20 wasm hook appKeepers.Ics20WasmHooks.ContractKeeper = &appKeepers.WasmKeeper @@ -535,6 +548,7 @@ func initParamsKeeper( paramsKeeper.Subspace(taxexemptiontypes.ModuleName) paramsKeeper.Subspace(treasurytypes.ModuleName) paramsKeeper.Subspace(wasmtypes.ModuleName) + paramsKeeper.Subspace(crontypes.ModuleName).WithKeyTable(crontypes.ParamKeyTable()) paramsKeeper.Subspace(dyncommtypes.ModuleName) paramsKeeper.Subspace(taxtypes.ModuleName) diff --git a/app/modules.go b/app/modules.go index ed4556b56..c08330231 100644 --- a/app/modules.go +++ b/app/modules.go @@ -25,6 +25,8 @@ import ( customstaking "github.com/classic-terra/core/v4/custom/staking" customupgrade "github.com/classic-terra/core/v4/custom/upgrade" customwasm "github.com/classic-terra/core/v4/custom/wasm" + "github.com/classic-terra/core/v4/x/cron" + crontypes "github.com/classic-terra/core/v4/x/cron/types" "github.com/classic-terra/core/v4/x/dyncomm" dyncommtypes "github.com/classic-terra/core/v4/x/dyncomm/types" "github.com/classic-terra/core/v4/x/market" @@ -111,6 +113,7 @@ var ( treasury.AppModuleBasic{}, taxexemption.AppModuleBasic{}, customwasm.AppModuleBasic{}, + cron.AppModuleBasic{}, dyncomm.AppModuleBasic{}, ibchooks.AppModuleBasic{}, consensus.AppModuleBasic{}, @@ -131,6 +134,7 @@ var ( ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, icatypes.ModuleName: nil, wasmtypes.ModuleName: {authtypes.Burner}, + crontypes.ModuleName: nil, } // module accounts that are allowed to receive tokens allowedReceivingModAcc = map[string]bool{ @@ -169,6 +173,7 @@ func appModules( treasury.NewAppModule(appCodec, app.TreasuryKeeper), taxexemption.NewAppModule(appCodec, app.TaxExemptionKeeper), customwasm.NewAppModule(appCodec, &app.WasmKeeper, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.MsgServiceRouter(), app.GetSubspace(wasmtypes.ModuleName), app.GetKey(wasmtypes.StoreKey)), + cron.NewAppModule(appCodec, &app.CronKeeper), dyncomm.NewAppModule(appCodec, app.DyncommKeeper, app.StakingKeeper), ibchooks.NewAppModule(app.AccountKeeper), consensus.NewAppModule(appCodec, app.ConsensusParamsKeeper), @@ -232,6 +237,7 @@ func orderBeginBlockers() []string { taxexemptiontypes.ModuleName, markettypes.ModuleName, wasmtypes.ModuleName, + crontypes.ModuleName, dyncommtypes.ModuleName, taxtypes.ModuleName, // consensus module @@ -266,6 +272,7 @@ func orderEndBlockers() []string { taxexemptiontypes.ModuleName, markettypes.ModuleName, wasmtypes.ModuleName, + crontypes.ModuleName, dyncommtypes.ModuleName, taxtypes.ModuleName, // consensus module @@ -300,6 +307,7 @@ func orderInitGenesis() []string { treasurytypes.ModuleName, taxexemptiontypes.ModuleName, wasmtypes.ModuleName, + crontypes.ModuleName, dyncommtypes.ModuleName, taxtypes.ModuleName, // consensus module diff --git a/proto/terra/cron/v1/genesis.proto b/proto/terra/cron/v1/genesis.proto new file mode 100644 index 000000000..d694486d3 --- /dev/null +++ b/proto/terra/cron/v1/genesis.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; +package terra.cron.v1; + +import "gogoproto/gogo.proto"; +import "terra/cron/v1/params.proto"; +import "terra/cron/v1/schedule.proto"; + +option go_package = "github.com/classic-terra/core/v4/x/cron/types"; + +message GenesisState { + Params params = 1 [(gogoproto.nullable) = false]; + repeated Schedule schedule_list = 2 [(gogoproto.nullable) = false]; +} diff --git a/proto/terra/cron/v1/params.proto b/proto/terra/cron/v1/params.proto new file mode 100644 index 000000000..d87b85661 --- /dev/null +++ b/proto/terra/cron/v1/params.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; +package terra.cron.v1; + +import "amino/amino.proto"; +import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; + +option go_package = "github.com/classic-terra/core/v4/x/cron/types"; + +message Params { + uint64 limit = 1; +} diff --git a/proto/terra/cron/v1/query.proto b/proto/terra/cron/v1/query.proto new file mode 100644 index 000000000..4a7f4c611 --- /dev/null +++ b/proto/terra/cron/v1/query.proto @@ -0,0 +1,47 @@ +syntax = "proto3"; +package terra.cron.v1; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "google/api/annotations.proto"; +import "gogoproto/gogo.proto"; +import "terra/cron/v1/params.proto"; +import "terra/cron/v1/schedule.proto"; + +option go_package = "github.com/classic-terra/core/v4/x/cron/types"; + +service Query { + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/terra/cron/v1/params"; + } + + rpc Schedule(QueryScheduleRequest) returns (QueryScheduleResponse) { + option (google.api.http).get = "/terra/cron/v1/schedules/{name}"; + } + + rpc Schedules(QuerySchedulesRequest) returns (QuerySchedulesResponse) { + option (google.api.http).get = "/terra/cron/v1/schedules"; + } +} + +message QueryParamsRequest {} + +message QueryParamsResponse { + Params params = 1 [(gogoproto.nullable) = false]; +} + +message QueryScheduleRequest { + string name = 1; +} + +message QueryScheduleResponse { + Schedule schedule = 1 [(gogoproto.nullable) = false]; +} + +message QuerySchedulesRequest { + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +message QuerySchedulesResponse { + repeated Schedule schedules = 1 [(gogoproto.nullable) = false]; + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} diff --git a/proto/terra/cron/v1/schedule.proto b/proto/terra/cron/v1/schedule.proto new file mode 100644 index 000000000..c373272b1 --- /dev/null +++ b/proto/terra/cron/v1/schedule.proto @@ -0,0 +1,28 @@ +syntax = "proto3"; +package terra.cron.v1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/classic-terra/core/v4/x/cron/types"; + +enum ExecutionStage { + EXECUTION_STAGE_END_BLOCKER = 0; + EXECUTION_STAGE_BEGIN_BLOCKER = 1; +} + +message Schedule { + string name = 1; + uint64 period = 2; + repeated MsgExecuteContract msgs = 3 [(gogoproto.nullable) = false]; + uint64 last_execute_height = 4; + ExecutionStage execution_stage = 5; +} + +message MsgExecuteContract { + string contract = 1; + string msg = 2; +} + +message ScheduleCount { + int32 count = 1; +} diff --git a/proto/terra/cron/v1/tx.proto b/proto/terra/cron/v1/tx.proto new file mode 100644 index 000000000..3258bdae5 --- /dev/null +++ b/proto/terra/cron/v1/tx.proto @@ -0,0 +1,52 @@ +syntax = "proto3"; +package terra.cron.v1; + +import "amino/amino.proto"; +import "cosmos/msg/v1/msg.proto"; +import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; +import "terra/cron/v1/params.proto"; +import "terra/cron/v1/schedule.proto"; + +option go_package = "github.com/classic-terra/core/v4/x/cron/types"; + +service Msg { + option (cosmos.msg.v1.service) = true; + + rpc AddSchedule(MsgAddSchedule) returns (MsgAddScheduleResponse); + rpc RemoveSchedule(MsgRemoveSchedule) returns (MsgRemoveScheduleResponse); + rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); +} + +message MsgAddSchedule { + option (amino.name) = "cron/MsgAddSchedule"; + option (cosmos.msg.v1.signer) = "authority"; + + string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + string name = 2; + uint64 period = 3; + repeated MsgExecuteContract msgs = 4 [(gogoproto.nullable) = false]; + ExecutionStage execution_stage = 5; +} + +message MsgAddScheduleResponse {} + +message MsgRemoveSchedule { + option (amino.name) = "cron/MsgRemoveSchedule"; + option (cosmos.msg.v1.signer) = "authority"; + + string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + string name = 2; +} + +message MsgRemoveScheduleResponse {} + +message MsgUpdateParams { + option (amino.name) = "cron/MsgUpdateParams"; + option (cosmos.msg.v1.signer) = "authority"; + + string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + Params params = 2 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; +} + +message MsgUpdateParamsResponse {} diff --git a/scripts/README.md b/scripts/README.md index 1d039360d..f8c02ed48 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -64,6 +64,42 @@ OLD_VERSION=v3.6.0-rc.0 SOFTWARE_UPGRADE_NAME=v14 bash scripts/upgrade-test.sh --- +### `cron-test.sh` + +Starts the same single-validator local testnet flow as `run-node.sh`, but seeds a cron schedule in genesis so the cron query CLI can be exercised against a live node. + +**Usage:** `bash scripts/cron-test.sh [binary] [denom]` + +**Example:** +```bash +bash scripts/cron-test.sh _build/new/terrad uluna +``` + +**Notes:** +- This is a query-focused smoke test. +- Cron write messages stay authority-gated, so the script validates `terrad q cron ...` against seeded chain state instead of trying to broadcast a direct write tx. +- The script seeds two schedules so `cron schedule` and `cron schedules` return different payloads. +- It skips `validate-genesis`; the SDK gentx validation path can panic in this local smoke setup without affecting the query flow. + +--- + +### `cron-auth-gate-test.sh` + +Starts the same single-validator local testnet flow as `run-node.sh`, then proves that a non-authority sender cannot broadcast `tx cron add-schedule`. + +**Usage:** `bash scripts/cron-auth-gate-test.sh [binary] [denom]` + +**Example:** +```bash +bash scripts/cron-auth-gate-test.sh _build/new/terrad uluna +``` + +**Notes:** +- This is a negative smoke test for the cron auth gate. +- It expects the tx to fail with an `invalid authority` error. + +--- + ### `upgrade-test-multi.sh` Tests a **chain of sequential upgrades**, simulating the full upgrade history from an old version to the current codebase through intermediate releases. diff --git a/scripts/cron-auth-gate-test.sh b/scripts/cron-auth-gate-test.sh new file mode 100644 index 000000000..169d3a1ab --- /dev/null +++ b/scripts/cron-auth-gate-test.sh @@ -0,0 +1,107 @@ +#!/bin/bash + +set -euo pipefail + +ROOT=$(pwd) +HOME_DIR=mytestnet +DENOM=${2:-uluna} +BINARY=${1:-_build/new/terrad} +KEYRING="test" +CHAIN_ID="localterra" +KEY="test0" +KEY1="test1" +KEY2="test2" +SED_BINARY=sed + +if [[ "$OSTYPE" == "darwin"* ]]; then + if ! command -v gsed &> /dev/null + then + echo "gsed could not be found. Please install it with 'brew install gnu-sed'" + exit 1 + else + SED_BINARY=gsed + fi +fi + +mkdir -p _build/gocache +export GOMODCACHE=$ROOT/_build/gocache + +if ! command -v "$BINARY" &> /dev/null && [[ ! -x "$BINARY" ]] +then + GOBIN="$ROOT/_build/new" go install -mod=readonly ./... + BINARY="$ROOT/_build/new/terrad" +fi + +rm -rf "$HOME_DIR" +pkill terrad || true + +"$BINARY" init --chain-id "$CHAIN_ID" moniker --home "$HOME_DIR" + +"$BINARY" keys add "$KEY" --keyring-backend "$KEYRING" --home "$HOME_DIR" +"$BINARY" keys add "$KEY1" --keyring-backend "$KEYRING" --home "$HOME_DIR" +"$BINARY" keys add "$KEY2" --keyring-backend "$KEYRING" --home "$HOME_DIR" + +"$BINARY" add-genesis-account "$KEY" "1000000000000${DENOM}" --keyring-backend "$KEYRING" --home "$HOME_DIR" +"$BINARY" add-genesis-account "$KEY1" "1000000000000${DENOM}" --keyring-backend "$KEYRING" --home "$HOME_DIR" +"$BINARY" add-genesis-account "$KEY2" "1000000000000${DENOM}" --keyring-backend "$KEYRING" --home "$HOME_DIR" + +update_test_genesis() { + cat "$HOME_DIR/config/genesis.json" | jq "$1" > "$HOME_DIR/config/tmp_genesis.json" && mv "$HOME_DIR/config/tmp_genesis.json" "$HOME_DIR/config/genesis.json" +} + +update_test_genesis '.app_state["mint"]["params"]["mint_denom"]="'$DENOM'"' +update_test_genesis '.app_state["gov"]["deposit_params"]["min_deposit"]=[{"denom":"'$DENOM'","amount":"1000000"}]' +update_test_genesis '.app_state["gov"]["params"]["min_deposit"]=[{"denom":"'$DENOM'","amount":"1000000"}]' +update_test_genesis '.app_state["gov"]["params"]["voting_period"]="30s"' +update_test_genesis '.app_state["gov"]["voting_params"]["voting_period"]="30s"' +if cat "$HOME_DIR/config/genesis.json" | jq -e '.app_state["gov"]["params"]["expedited_voting_period"]' > /dev/null 2>&1; then + update_test_genesis '.app_state["gov"]["params"]["expedited_voting_period"]="4s"' +fi +update_test_genesis '.app_state["crisis"]["constant_fee"]={"denom":"'$DENOM'","amount":"1000"}' +update_test_genesis '.app_state["staking"]["params"]["bond_denom"]="'$DENOM'"' + +"$SED_BINARY" -i '0,/enable = false/s//enable = true/' "$HOME_DIR/config/app.toml" +"$SED_BINARY" -i 's/swagger = false/swagger = true/' "$HOME_DIR/config/app.toml" +"$SED_BINARY" -i -e 's/enabled-unsafe-cors = false/enabled-unsafe-cors = true/g' "$HOME_DIR/config/app.toml" +"$SED_BINARY" -i -e 's/max-txs = 5000/max-txs = 3/g' "$HOME_DIR/config/app.toml" +"$SED_BINARY" -i -e 's/timeout_commit = "5s"/timeout_commit = "500ms"/g' "$HOME_DIR/config/config.toml" + +"$BINARY" gentx "$KEY" "900000000000${DENOM}" --commission-rate=0.01 --commission-max-rate=0.02 --keyring-backend "$KEYRING" --chain-id "$CHAIN_ID" --home "$HOME_DIR" +"$BINARY" collect-gentxs --home "$HOME_DIR" + +LOGFILE="$HOME_DIR/log-screen.txt" +"$BINARY" start --home "$HOME_DIR" --log_level debug >"$LOGFILE" 2>&1 & +CRON_NODE_PID=$! + +cleanup() { + if kill -0 "$CRON_NODE_PID" 2>/dev/null; then + kill "$CRON_NODE_PID" || true + wait "$CRON_NODE_PID" || true + fi +} +trap cleanup EXIT + +sleep 20 + +echo "QUERY GOV AUTHORITY" +GOV_AUTHORITY=$("$BINARY" q auth module-account gov --home "$HOME_DIR" --output json | jq -r '.account.value.address // .account.base_account.address // .account.address') +echo "$GOV_AUTHORITY" + +echo "EXPECT CRON WRITE TO FAIL FOR NON-AUTHORITY SENDER" +set +e +OUT=$("$BINARY" tx cron add-schedule bad-cron 999999 end-blocker terra1contract '{"ping":{}}' --from "$KEY" --keyring-backend "$KEYRING" --chain-id "$CHAIN_ID" --home "$HOME_DIR" --fees "20000${DENOM}" --gas auto --gas-adjustment 1.5 --broadcast-mode block -y --output json 2>&1) +CODE=$? +set -e + +echo "$OUT" +if [ "$CODE" -eq 0 ]; then + echo "expected cron add-schedule to fail for non-authority sender" >&2 + exit 1 +fi + +if echo "$OUT" | jq -e '.raw_log | test("invalid authority")' >/dev/null 2>&1 || echo "$OUT" | grep -q "invalid authority"; then + echo "auth gate check passed" +else + echo "expected invalid authority error in tx output" >&2 + exit 1 +fi diff --git a/scripts/cron-test.sh b/scripts/cron-test.sh new file mode 100644 index 000000000..397cdfe77 --- /dev/null +++ b/scripts/cron-test.sh @@ -0,0 +1,116 @@ +#!/bin/bash + +set -euo pipefail + +ROOT=$(pwd) +HOME_DIR=mytestnet +DENOM=${2:-uluna} +BINARY=${1:-_build/new/terrad} +KEYRING="test" +CHAIN_ID="localterra" +KEY="test0" +KEY1="test1" +KEY2="test2" +SED_BINARY=sed + +if [[ "$OSTYPE" == "darwin"* ]]; then + if ! command -v gsed &> /dev/null + then + echo "gsed could not be found. Please install it with 'brew install gnu-sed'" + exit 1 + else + SED_BINARY=gsed + fi +fi + +# underscore so that go tool will not take gocache into account +mkdir -p _build/gocache +export GOMODCACHE=$ROOT/_build/gocache + +# install new binary if it is not already available +if ! command -v "$BINARY" &> /dev/null && [[ ! -x "$BINARY" ]] +then + GOBIN="$ROOT/_build/new" go install -mod=readonly ./... + BINARY="$ROOT/_build/new/terrad" +fi + +rm -rf "$HOME_DIR" +pkill terrad || true + +"$BINARY" init --chain-id "$CHAIN_ID" moniker --home "$HOME_DIR" + +"$BINARY" keys add "$KEY" --keyring-backend "$KEYRING" --home "$HOME_DIR" +"$BINARY" keys add "$KEY1" --keyring-backend "$KEYRING" --home "$HOME_DIR" +"$BINARY" keys add "$KEY2" --keyring-backend "$KEYRING" --home "$HOME_DIR" + +# Allocate genesis accounts (cosmos formatted addresses) +"$BINARY" add-genesis-account "$KEY" "1000000000000${DENOM}" --keyring-backend "$KEYRING" --home "$HOME_DIR" +"$BINARY" add-genesis-account "$KEY1" "1000000000000${DENOM}" --keyring-backend "$KEYRING" --home "$HOME_DIR" +"$BINARY" add-genesis-account "$KEY2" "1000000000000${DENOM}" --keyring-backend "$KEYRING" --home "$HOME_DIR" + +update_test_genesis() { + cat "$HOME_DIR/config/genesis.json" | jq "$1" > "$HOME_DIR/config/tmp_genesis.json" && mv "$HOME_DIR/config/tmp_genesis.json" "$HOME_DIR/config/genesis.json" +} + +update_test_genesis '.app_state["mint"]["params"]["mint_denom"]="'$DENOM'"' +update_test_genesis '.app_state["gov"]["deposit_params"]["min_deposit"]=[{"denom":"'$DENOM'","amount":"1000000"}]' +update_test_genesis '.app_state["gov"]["params"]["min_deposit"]=[{"denom":"'$DENOM'","amount":"1000000"}]' +update_test_genesis '.app_state["gov"]["params"]["voting_period"]="30s"' +update_test_genesis '.app_state["gov"]["voting_params"]["voting_period"]="30s"' +if cat "$HOME_DIR/config/genesis.json" | jq -e '.app_state["gov"]["params"]["expedited_voting_period"]' > /dev/null 2>&1; then + update_test_genesis '.app_state["gov"]["params"]["expedited_voting_period"]="4s"' +fi +update_test_genesis '.app_state["crisis"]["constant_fee"]={"denom":"'$DENOM'","amount":"1000"}' +update_test_genesis '.app_state["staking"]["params"]["bond_denom"]="'$DENOM'"' +update_test_genesis '.app_state["cron"]={ + "params":{"limit":"1"}, + "schedule_list":[ + { + "name":"cron-smoke", + "period":"999999", + "msgs":[{"contract":"terra1contract","msg":"{\"ping\":{}}"}], + "last_execute_height":"0", + "execution_stage":"EXECUTION_STAGE_END_BLOCKER" + }, + { + "name":"cron-smoke-begin", + "period":"999998", + "msgs":[{"contract":"terra1contract","msg":"{\"pong\":{}}"}], + "last_execute_height":"0", + "execution_stage":"EXECUTION_STAGE_BEGIN_BLOCKER" + } + ] +}' + +# enable rest server and swagger +"$SED_BINARY" -i '0,/enable = false/s//enable = true/' "$HOME_DIR/config/app.toml" +"$SED_BINARY" -i 's/swagger = false/swagger = true/' "$HOME_DIR/config/app.toml" +"$SED_BINARY" -i -e 's/enabled-unsafe-cors = false/enabled-unsafe-cors = true/g' "$HOME_DIR/config/app.toml" +"$SED_BINARY" -i -e 's/max-txs = 5000/max-txs = 3/g' "$HOME_DIR/config/app.toml" +"$SED_BINARY" -i -e 's/timeout_commit = "5s"/timeout_commit = "500ms"/g' "$HOME_DIR/config/config.toml" + +"$BINARY" gentx "$KEY" "900000000000${DENOM}" --commission-rate=0.01 --commission-max-rate=0.02 --keyring-backend "$KEYRING" --chain-id "$CHAIN_ID" --home "$HOME_DIR" +"$BINARY" collect-gentxs --home "$HOME_DIR" + +LOGFILE="$HOME_DIR/log-screen.txt" +"$BINARY" start --home "$HOME_DIR" --log_level debug >"$LOGFILE" 2>&1 & +CRON_NODE_PID=$! + +cleanup() { + if kill -0 "$CRON_NODE_PID" 2>/dev/null; then + kill "$CRON_NODE_PID" || true + wait "$CRON_NODE_PID" || true + fi +} +trap cleanup EXIT + +sleep 20 + +echo "QUERY CRON PARAMS" +"$BINARY" q cron params --home "$HOME_DIR" --chain-id "$CHAIN_ID" -o json | jq ".params" + +echo "QUERY CRON SCHEDULE" +"$BINARY" q cron schedule cron-smoke-begin --home "$HOME_DIR" --chain-id "$CHAIN_ID" -o json | jq ".schedule" + +echo "QUERY CRON SCHEDULES" +"$BINARY" q cron schedules --home "$HOME_DIR" --chain-id "$CHAIN_ID" --limit 10 -o json | jq ".schedules" diff --git a/x/cron/client/cli/query.go b/x/cron/client/cli/query.go new file mode 100644 index 000000000..8c3696318 --- /dev/null +++ b/x/cron/client/cli/query.go @@ -0,0 +1,106 @@ +package cli + +import ( + "context" + + "github.com/classic-terra/core/v4/x/cron/types" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/spf13/cobra" +) + +func GetQueryCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: types.ModuleName, + Short: "Querying commands for the cron module", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + cmd.AddCommand( + GetCmdQueryParams(), + GetCmdQuerySchedule(), + GetCmdQuerySchedules(), + ) + + return cmd +} + +func GetCmdQueryParams() *cobra.Command { + cmd := &cobra.Command{ + Use: "params", + Args: cobra.NoArgs, + Short: "Query cron params", + RunE: func(cmd *cobra.Command, _ []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + res, err := types.NewQueryClient(clientCtx).Params(context.Background(), &types.QueryParamsRequest{}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +func GetCmdQuerySchedule() *cobra.Command { + cmd := &cobra.Command{ + Use: "schedule [name]", + Args: cobra.ExactArgs(1), + Short: "Query a cron schedule by name", + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + res, err := types.NewQueryClient(clientCtx).Schedule(context.Background(), &types.QueryScheduleRequest{Name: args[0]}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +func GetCmdQuerySchedules() *cobra.Command { + cmd := &cobra.Command{ + Use: "schedules", + Args: cobra.NoArgs, + Short: "Query all cron schedules", + RunE: func(cmd *cobra.Command, _ []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + pageReq, err := client.ReadPageRequest(cmd.Flags()) + if err != nil { + return err + } + + res, err := types.NewQueryClient(clientCtx).Schedules(context.Background(), &types.QuerySchedulesRequest{Pagination: pageReq}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + flags.AddPaginationFlagsToCmd(cmd, "cron schedules") + return cmd +} diff --git a/x/cron/client/cli/query_test.go b/x/cron/client/cli/query_test.go new file mode 100644 index 000000000..1a2c7f5ff --- /dev/null +++ b/x/cron/client/cli/query_test.go @@ -0,0 +1,14 @@ +package cli + +import ( + "testing" + + "github.com/classic-terra/core/v4/x/cron/types" + "github.com/stretchr/testify/require" +) + +func TestGetQueryCmd(t *testing.T) { + cmd := GetQueryCmd() + require.Equal(t, types.ModuleName, cmd.Use) + require.Len(t, cmd.Commands(), 3) +} diff --git a/x/cron/client/cli/tx.go b/x/cron/client/cli/tx.go new file mode 100644 index 000000000..99de97886 --- /dev/null +++ b/x/cron/client/cli/tx.go @@ -0,0 +1,144 @@ +package cli + +import ( + "fmt" + "strconv" + "strings" + + "github.com/classic-terra/core/v4/x/cron/types" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/spf13/cobra" +) + +func GetTxCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf("%s transactions subcommands", types.ModuleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + cmd.AddCommand( + GetCmdAddSchedule(), + GetCmdRemoveSchedule(), + GetCmdUpdateParams(), + ) + + return cmd +} + +func GetCmdAddSchedule() *cobra.Command { + cmd := &cobra.Command{ + Use: "add-schedule [name] [period] [execution-stage] [contract] [msg-json]", + Args: cobra.ExactArgs(5), + Short: "Create a cron schedule", + Long: strings.TrimSpace(` +Create a cron schedule that executes one Wasm contract message periodically. + +$ terrad tx cron add-schedule my-job 10 end-blocker terra1contract... '{"ping":{}}' +`), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + period, err := strconv.ParseUint(args[1], 10, 64) + if err != nil { + return err + } + + stage, err := parseExecutionStage(args[2]) + if err != nil { + return err + } + + msgs := []types.MsgExecuteContract{ + { + Contract: args[3], + Msg: args[4], + }, + } + + msg := &types.MsgAddSchedule{ + Authority: clientCtx.GetFromAddress().String(), + Name: args[0], + Period: period, + Msgs: msgs, + ExecutionStage: stage, + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + return cmd +} + +func GetCmdRemoveSchedule() *cobra.Command { + cmd := &cobra.Command{ + Use: "remove-schedule [name]", + Args: cobra.ExactArgs(1), + Short: "Remove a cron schedule", + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + msg := &types.MsgRemoveSchedule{ + Authority: clientCtx.GetFromAddress().String(), + Name: args[0], + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + return cmd +} + +func GetCmdUpdateParams() *cobra.Command { + cmd := &cobra.Command{ + Use: "update-params [limit]", + Args: cobra.ExactArgs(1), + Short: "Update cron params", + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + limit, err := strconv.ParseUint(args[0], 10, 64) + if err != nil { + return err + } + + msg := &types.MsgUpdateParams{ + Authority: clientCtx.GetFromAddress().String(), + Params: types.NewParams(limit), + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + return cmd +} + +func parseExecutionStage(v string) (types.ExecutionStage, error) { + switch strings.ToLower(v) { + case "begin", "begin-blocker", "begin_blocker": + return types.ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER, nil + case "end", "end-blocker", "end_blocker": + return types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER, nil + default: + return 0, fmt.Errorf("invalid execution stage %q", v) + } +} diff --git a/x/cron/client/cli/tx_test.go b/x/cron/client/cli/tx_test.go new file mode 100644 index 000000000..6a7d143b5 --- /dev/null +++ b/x/cron/client/cli/tx_test.go @@ -0,0 +1,14 @@ +package cli + +import ( + "testing" + + "github.com/classic-terra/core/v4/x/cron/types" + "github.com/stretchr/testify/require" +) + +func TestGetTxCmd(t *testing.T) { + cmd := GetTxCmd() + require.Equal(t, types.ModuleName, cmd.Use) + require.Len(t, cmd.Commands(), 3) +} diff --git a/x/cron/genesis.go b/x/cron/genesis.go new file mode 100644 index 000000000..5e455ef1e --- /dev/null +++ b/x/cron/genesis.go @@ -0,0 +1,26 @@ +package cron + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/classic-terra/core/v4/x/cron/keeper" + "github.com/classic-terra/core/v4/x/cron/types" +) + +func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) { + for _, schedule := range genState.ScheduleList { + if err := k.AddSchedule(ctx, schedule.Name, schedule.Period, schedule.Msgs, schedule.LastExecuteHeight, schedule.ExecutionStage); err != nil { + panic(err) + } + } + if err := k.SetParams(ctx, genState.Params); err != nil { + panic(err) + } +} + +func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { + genesis := types.DefaultGenesisState() + genesis.Params = k.GetParams(ctx) + genesis.ScheduleList = k.GetAllSchedules(ctx) + return genesis +} diff --git a/x/cron/keeper/grpc_query.go b/x/cron/keeper/grpc_query.go new file mode 100644 index 000000000..be19fae16 --- /dev/null +++ b/x/cron/keeper/grpc_query.go @@ -0,0 +1,56 @@ +package keeper + +import ( + "context" + + "cosmossdk.io/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/query" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "github.com/classic-terra/core/v4/x/cron/types" +) + +func (k Keeper) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + return &types.QueryParamsResponse{Params: k.GetParams(sdk.UnwrapSDKContext(c))}, nil +} + +func (k Keeper) Schedule(c context.Context, req *types.QueryScheduleRequest) (*types.QueryScheduleResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + schedule, found := k.GetSchedule(sdk.UnwrapSDKContext(c), req.Name) + if !found { + return nil, status.Error(codes.NotFound, "schedule not found") + } + + return &types.QueryScheduleResponse{Schedule: *schedule}, nil +} + +func (k Keeper) Schedules(c context.Context, req *types.QuerySchedulesRequest) (*types.QuerySchedulesResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(c) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.ScheduleKey) + var schedules []types.Schedule + + pageRes, err := query.Paginate(store, req.Pagination, func(_, value []byte) error { + var schedule types.Schedule + k.cdc.MustUnmarshal(value, &schedule) + schedules = append(schedules, schedule) + return nil + }) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + return &types.QuerySchedulesResponse{Schedules: schedules, Pagination: pageRes}, nil +} diff --git a/x/cron/keeper/keeper.go b/x/cron/keeper/keeper.go new file mode 100644 index 000000000..dbf8309ba --- /dev/null +++ b/x/cron/keeper/keeper.go @@ -0,0 +1,210 @@ +package keeper + +import ( + "fmt" + + "cosmossdk.io/store/prefix" + storetypes "cosmossdk.io/store/types" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/classic-terra/core/v4/x/cron/types" +) + +type Keeper struct { + cdc codec.BinaryCodec + storeKey storetypes.StoreKey + accountKeeper types.AccountKeeper + WasmMsgServer types.WasmMsgServer + authority string +} + +// NewKeeper creates a new cron Keeper instance. +func NewKeeper( + cdc codec.BinaryCodec, + storeKey storetypes.StoreKey, + accountKeeper types.AccountKeeper, + authority string, +) Keeper { + return Keeper{ + cdc: cdc, + storeKey: storeKey, + accountKeeper: accountKeeper, + authority: authority, + } +} + +// GetAuthority returns the module authority address. +func (k Keeper) GetAuthority() string { + return k.authority +} + +// ExecuteReadySchedules executes all schedules eligible for the given stage. +func (k Keeper) ExecuteReadySchedules(ctx sdk.Context, executionStage types.ExecutionStage) { + schedules := k.getSchedulesReadyForExecution(ctx, executionStage) + for _, schedule := range schedules { + _ = k.executeSchedule(ctx, schedule) + } +} + +// AddSchedule validates and stores a new schedule. +func (k Keeper) AddSchedule( + ctx sdk.Context, + name string, + period uint64, + msgs []types.MsgExecuteContract, + lastExecuteHeight uint64, + executionStage types.ExecutionStage, +) error { + schedule := types.Schedule{ + Name: name, + Period: period, + Msgs: msgs, + LastExecuteHeight: lastExecuteHeight, + ExecutionStage: executionStage, + } + if err := types.ValidateSchedule(schedule); err != nil { + return err + } + if k.scheduleExists(ctx, name) { + return fmt.Errorf("%w: %s", types.ErrDuplicateSchedule, name) + } + + k.storeSchedule(ctx, schedule) + k.changeTotalCount(ctx, 1) + return nil +} + +// RemoveSchedule deletes a schedule if it exists. +func (k Keeper) RemoveSchedule(ctx sdk.Context, name string) { + if !k.scheduleExists(ctx, name) { + return + } + + k.changeTotalCount(ctx, -1) + k.removeSchedule(ctx, name) +} + +// GetSchedule returns the schedule with the given name, if it exists. +func (k Keeper) GetSchedule(ctx sdk.Context, name string) (*types.Schedule, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.ScheduleKey) + bz := store.Get(types.GetScheduleKey(name)) + if bz == nil { + return nil, false + } + + var schedule types.Schedule + k.cdc.MustUnmarshal(bz, &schedule) + return &schedule, true +} + +// GetAllSchedules returns all stored schedules. +func (k Keeper) GetAllSchedules(ctx sdk.Context) []types.Schedule { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.ScheduleKey) + res := make([]types.Schedule, 0) + + iterator := storetypes.KVStorePrefixIterator(store, []byte{}) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var schedule types.Schedule + k.cdc.MustUnmarshal(iterator.Value(), &schedule) + res = append(res, schedule) + } + return res +} + +// GetScheduleCount returns the total number of stored schedules. +func (k Keeper) GetScheduleCount(ctx sdk.Context) int32 { + return k.getScheduleCount(ctx) +} + +func (k Keeper) getSchedulesReadyForExecution(ctx sdk.Context, executionStage types.ExecutionStage) []types.Schedule { + params := k.GetParams(ctx) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.ScheduleKey) + res := make([]types.Schedule, 0) + count := uint64(0) + + iterator := storetypes.KVStorePrefixIterator(store, []byte{}) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var schedule types.Schedule + k.cdc.MustUnmarshal(iterator.Value(), &schedule) + if k.intervalPassed(ctx, schedule) && schedule.ExecutionStage == executionStage { + res = append(res, schedule) + count++ + if count >= params.Limit { + return res + } + } + } + + return res +} + +func (k Keeper) executeSchedule(ctx sdk.Context, schedule types.Schedule) error { + schedule.LastExecuteHeight = uint64(ctx.BlockHeight()) + k.storeSchedule(ctx, schedule) + + cacheCtx, writeFn := ctx.CacheContext() + for _, msg := range schedule.Msgs { + executeMsg := wasmtypes.MsgExecuteContract{ + Sender: k.accountKeeper.GetModuleAddress(types.ModuleName).String(), + Contract: msg.Contract, + Msg: []byte(msg.Msg), + Funds: sdk.NewCoins(), + } + + if _, err := k.WasmMsgServer.ExecuteContract(cacheCtx, &executeMsg); err != nil { + ctx.Logger().Info("cron execute failed", + "schedule_name", schedule.Name, + "contract", msg.Contract, + "error", err, + ) + return err + } + } + + writeFn() + return nil +} + +func (k Keeper) storeSchedule(ctx sdk.Context, schedule types.Schedule) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.ScheduleKey) + store.Set(types.GetScheduleKey(schedule.Name), k.cdc.MustMarshal(&schedule)) +} + +func (k Keeper) removeSchedule(ctx sdk.Context, name string) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.ScheduleKey) + store.Delete(types.GetScheduleKey(name)) +} + +func (k Keeper) scheduleExists(ctx sdk.Context, name string) bool { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.ScheduleKey) + return store.Has(types.GetScheduleKey(name)) +} + +func (k Keeper) intervalPassed(ctx sdk.Context, schedule types.Schedule) bool { + return uint64(ctx.BlockHeight()) >= (schedule.LastExecuteHeight + schedule.Period) +} + +func (k Keeper) changeTotalCount(ctx sdk.Context, incrementAmount int32) { + store := ctx.KVStore(k.storeKey) + count := k.getScheduleCount(ctx) + newCount := types.ScheduleCount{Count: count + incrementAmount} + store.Set(types.ScheduleCountKey, k.cdc.MustMarshal(&newCount)) +} + +func (k Keeper) getScheduleCount(ctx sdk.Context) int32 { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.ScheduleCountKey) + if bz == nil { + return 0 + } + + var count types.ScheduleCount + k.cdc.MustUnmarshal(bz, &count) + return count.Count +} diff --git a/x/cron/keeper/keeper_test.go b/x/cron/keeper/keeper_test.go new file mode 100644 index 000000000..5d167ddda --- /dev/null +++ b/x/cron/keeper/keeper_test.go @@ -0,0 +1,74 @@ +package keeper + +import ( + "testing" + + "github.com/classic-terra/core/v4/x/cron/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/query" + "github.com/stretchr/testify/require" +) + +func TestKeeperScheduleCRUD(t *testing.T) { + input := createTestInput(t) + ctx := input.Ctx.WithBlockHeight(10) + + err := input.Keeper.AddSchedule(ctx, "job", 3, []types.MsgExecuteContract{{Contract: "terra1contract", Msg: `{"ping":{}}`}}, 1, types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER) + require.NoError(t, err) + + schedule, found := input.Keeper.GetSchedule(ctx, "job") + require.True(t, found) + require.Equal(t, "job", schedule.Name) + require.Equal(t, uint64(3), schedule.Period) + require.Equal(t, int32(1), input.Keeper.GetScheduleCount(ctx)) + + input.Keeper.RemoveSchedule(ctx, "job") + require.Equal(t, int32(0), input.Keeper.GetScheduleCount(ctx)) + _, found = input.Keeper.GetSchedule(ctx, "job") + require.False(t, found) +} + +func TestKeeperExecuteReadySchedules(t *testing.T) { + input := createTestInput(t) + ctx := input.Ctx.WithBlockHeight(5) + + require.NoError(t, input.Keeper.SetParams(ctx, types.NewParams(1))) + require.NoError(t, input.Keeper.AddSchedule(ctx, "job-a", 1, []types.MsgExecuteContract{{Contract: "terra1contract", Msg: `{"ping":{}}`}}, 0, types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER)) + require.NoError(t, input.Keeper.AddSchedule(ctx, "job-b", 1, []types.MsgExecuteContract{{Contract: "terra1contract", Msg: `{"pong":{}}`}}, 0, types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER)) + require.NoError(t, input.Keeper.AddSchedule(ctx, "job-c", 1, []types.MsgExecuteContract{{Contract: "terra1contract", Msg: `{"skip":{}}`}}, 0, types.ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER)) + + input.Keeper.ExecuteReadySchedules(ctx, types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER) + + require.Len(t, input.MsgServer.calls, 1) + schedule, found := input.Keeper.GetSchedule(ctx, "job-a") + require.True(t, found) + require.Equal(t, uint64(5), schedule.LastExecuteHeight) +} + +func TestKeeperSchedulesPagination(t *testing.T) { + input := createTestInput(t) + + ctx := input.Ctx.WithBlockHeight(5) + require.NoError(t, input.Keeper.AddSchedule(ctx, "job-a", 1, []types.MsgExecuteContract{{Contract: "terra1contract", Msg: `{"ping":{}}`}}, 0, types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER)) + require.NoError(t, input.Keeper.AddSchedule(ctx, "job-b", 1, []types.MsgExecuteContract{{Contract: "terra1contract", Msg: `{"pong":{}}`}}, 0, types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER)) + require.NoError(t, input.Keeper.AddSchedule(ctx, "job-c", 1, []types.MsgExecuteContract{{Contract: "terra1contract", Msg: `{"skip":{}}`}}, 0, types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER)) + + res, err := input.Keeper.Schedules(sdk.WrapSDKContext(ctx), &types.QuerySchedulesRequest{ + Pagination: &query.PageRequest{Limit: 2}, + }) + require.NoError(t, err) + require.Len(t, res.Schedules, 2) + require.NotNil(t, res.Pagination) + require.NotEmpty(t, res.Pagination.NextKey) +} + +func TestKeeperScheduleQuery(t *testing.T) { + input := createTestInput(t) + ctx := input.Ctx.WithBlockHeight(5) + + require.NoError(t, input.Keeper.AddSchedule(ctx, "job-a", 1, []types.MsgExecuteContract{{Contract: "terra1contract", Msg: `{"ping":{}}`}}, 0, types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER)) + + res, err := input.Keeper.Schedule(sdk.WrapSDKContext(ctx), &types.QueryScheduleRequest{Name: "job-a"}) + require.NoError(t, err) + require.Equal(t, "job-a", res.Schedule.Name) +} diff --git a/x/cron/keeper/msg_server.go b/x/cron/keeper/msg_server.go new file mode 100644 index 000000000..0234172e4 --- /dev/null +++ b/x/cron/keeper/msg_server.go @@ -0,0 +1,70 @@ +package keeper + +import ( + "context" + + "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + "github.com/classic-terra/core/v4/x/cron/types" +) + +type msgServer struct { + keeper Keeper +} + +func NewMsgServerImpl(keeper Keeper) types.MsgServer { + return &msgServer{keeper: keeper} +} + +var _ types.MsgServer = msgServer{} + +func (k msgServer) AddSchedule(goCtx context.Context, req *types.MsgAddSchedule) (*types.MsgAddScheduleResponse, error) { + if err := req.Validate(); err != nil { + return nil, errors.Wrap(err, "failed to validate MsgAddSchedule") + } + + if authority := k.keeper.GetAuthority(); authority != req.Authority { + return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid authority; expected %s, got %s", authority, req.Authority) + } + + ctx := sdk.UnwrapSDKContext(goCtx) + if err := k.keeper.AddSchedule(ctx, req.Name, req.Period, req.Msgs, uint64(ctx.BlockHeight()), req.ExecutionStage); err != nil { + return nil, errors.Wrap(err, "failed to add schedule") + } + + return &types.MsgAddScheduleResponse{}, nil +} + +func (k msgServer) RemoveSchedule(goCtx context.Context, req *types.MsgRemoveSchedule) (*types.MsgRemoveScheduleResponse, error) { + if err := req.Validate(); err != nil { + return nil, errors.Wrap(err, "failed to validate MsgRemoveSchedule") + } + + if authority := k.keeper.GetAuthority(); authority != req.Authority { + return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid authority; expected %s, got %s", authority, req.Authority) + } + + ctx := sdk.UnwrapSDKContext(goCtx) + k.keeper.RemoveSchedule(ctx, req.Name) + + return &types.MsgRemoveScheduleResponse{}, nil +} + +func (k msgServer) UpdateParams(goCtx context.Context, req *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) { + if err := req.Validate(); err != nil { + return nil, errors.Wrap(err, "failed to validate MsgUpdateParams") + } + + if authority := k.keeper.GetAuthority(); authority != req.Authority { + return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid authority; expected %s, got %s", authority, req.Authority) + } + + ctx := sdk.UnwrapSDKContext(goCtx) + if err := k.keeper.SetParams(ctx, req.Params); err != nil { + return nil, err + } + + return &types.MsgUpdateParamsResponse{}, nil +} diff --git a/x/cron/keeper/msg_server_test.go b/x/cron/keeper/msg_server_test.go new file mode 100644 index 000000000..9f4d2159a --- /dev/null +++ b/x/cron/keeper/msg_server_test.go @@ -0,0 +1,41 @@ +package keeper + +import ( + "testing" + + "github.com/classic-terra/core/v4/x/cron/types" + "github.com/stretchr/testify/require" +) + +func TestMsgServerAddScheduleAuthority(t *testing.T) { + input := createTestInput(t) + server := NewMsgServerImpl(input.Keeper) + + _, err := server.AddSchedule(input.Ctx, &types.MsgAddSchedule{ + Authority: input.Keeper.GetAuthority(), + Name: "job", + Period: 2, + Msgs: []types.MsgExecuteContract{{Contract: "terra1contract", Msg: `{"ping":{}}`}}, + }) + require.NoError(t, err) + + _, err = server.AddSchedule(input.Ctx, &types.MsgAddSchedule{ + Authority: "bad", + Name: "job2", + Period: 2, + Msgs: []types.MsgExecuteContract{{Contract: "terra1contract", Msg: `{"ping":{}}`}}, + }) + require.Error(t, err) +} + +func TestMsgServerUpdateParams(t *testing.T) { + input := createTestInput(t) + server := NewMsgServerImpl(input.Keeper) + + _, err := server.UpdateParams(input.Ctx, &types.MsgUpdateParams{ + Authority: input.Keeper.GetAuthority(), + Params: types.NewParams(7), + }) + require.NoError(t, err) + require.Equal(t, uint64(7), input.Keeper.GetParams(input.Ctx).Limit) +} diff --git a/x/cron/keeper/params.go b/x/cron/keeper/params.go new file mode 100644 index 000000000..a13b05fb7 --- /dev/null +++ b/x/cron/keeper/params.go @@ -0,0 +1,27 @@ +package keeper + +import sdk "github.com/cosmos/cosmos-sdk/types" + +import "github.com/classic-terra/core/v4/x/cron/types" + +func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.ParamsKey) + if bz == nil { + return params + } + + k.cdc.MustUnmarshal(bz, ¶ms) + return params +} + +func (k Keeper) SetParams(ctx sdk.Context, params types.Params) error { + store := ctx.KVStore(k.storeKey) + bz, err := k.cdc.Marshal(¶ms) + if err != nil { + return err + } + + store.Set(types.ParamsKey, bz) + return nil +} diff --git a/x/cron/keeper/test_utils_test.go b/x/cron/keeper/test_utils_test.go new file mode 100644 index 000000000..2a3205ffa --- /dev/null +++ b/x/cron/keeper/test_utils_test.go @@ -0,0 +1,104 @@ +package keeper + +import ( + "context" + "testing" + "time" + + sdklog "cosmossdk.io/log" + store "cosmossdk.io/store" + storemetrics "cosmossdk.io/store/metrics" + storetypes "cosmossdk.io/store/types" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + coretypes "github.com/classic-terra/core/v4/types" + chronotypes "github.com/classic-terra/core/v4/x/cron/types" + "github.com/cometbft/cometbft/crypto/secp256k1" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + dbm "github.com/cosmos/cosmos-db" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + "github.com/stretchr/testify/require" +) + +type fakeAccountKeeper struct { + moduleAddr sdk.AccAddress +} + +func (f fakeAccountKeeper) GetModuleAddress(_ string) sdk.AccAddress { + return f.moduleAddr +} + +type fakeWasmMsgServer struct { + calls []*chronotypes.MsgExecuteContract + err error +} + +func (f *fakeWasmMsgServer) ExecuteContract(_ context.Context, msg *wasmtypes.MsgExecuteContract) (*wasmtypes.MsgExecuteContractResponse, error) { + f.calls = append(f.calls, &chronotypes.MsgExecuteContract{ + Contract: msg.Contract, + Msg: string(msg.Msg), + }) + if f.err != nil { + return nil, f.err + } + return &wasmtypes.MsgExecuteContractResponse{}, nil +} + +type testEncodingConfig struct { + Codec codec.Codec + Amino *codec.LegacyAmino +} + +func makeTestEncodingConfig(t *testing.T) testEncodingConfig { + t.Helper() + amino := codec.NewLegacyAmino() + registry := codectypes.NewInterfaceRegistry() + cdc := codec.NewProtoCodec(registry) + + chronotypes.RegisterLegacyAminoCodec(amino) + chronotypes.RegisterInterfaces(registry) + + return testEncodingConfig{Codec: cdc, Amino: amino} +} + +type testInput struct { + Ctx sdk.Context + Keeper Keeper + AccountKey sdk.AccAddress + StoreKey storetypes.StoreKey + MsgServer *fakeWasmMsgServer +} + +func createTestInput(t *testing.T) testInput { + t.Helper() + sdk.GetConfig().SetBech32PrefixForAccount(coretypes.Bech32PrefixAccAddr, coretypes.Bech32PrefixAccPub) + sdk.GetConfig().SetBech32PrefixForValidator(coretypes.Bech32PrefixValAddr, coretypes.Bech32PrefixValPub) + sdk.GetConfig().SetBech32PrefixForConsensusNode(coretypes.Bech32PrefixConsAddr, coretypes.Bech32PrefixConsPub) + + keyCron := storetypes.NewKVStoreKey(chronotypes.StoreKey) + db := dbm.NewMemDB() + ms := store.NewCommitMultiStore(db, sdklog.NewNopLogger(), storemetrics.NewNoOpMetrics()) + ctx := sdk.NewContext(ms, tmproto.Header{Time: time.Now().UTC()}, false, sdklog.NewNopLogger()) + + enc := makeTestEncodingConfig(t) + moduleAddr := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) + fakeKeeper := fakeAccountKeeper{moduleAddr: moduleAddr} + msgServer := &fakeWasmMsgServer{} + + ms.MountStoreWithDB(keyCron, storetypes.StoreTypeIAVL, db) + require.NoError(t, ms.LoadLatestVersion()) + + k := NewKeeper(enc.Codec, keyCron, fakeKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String()) + k.WasmMsgServer = msgServer + + return testInput{ + Ctx: ctx, + Keeper: k, + AccountKey: moduleAddr, + StoreKey: keyCron, + MsgServer: msgServer, + } +} diff --git a/x/cron/module.go b/x/cron/module.go new file mode 100644 index 000000000..4c2e0e550 --- /dev/null +++ b/x/cron/module.go @@ -0,0 +1,122 @@ +package cron + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/classic-terra/core/v4/x/cron/client/cli" + "github.com/classic-terra/core/v4/x/cron/keeper" + "github.com/classic-terra/core/v4/x/cron/types" + abci "github.com/cometbft/cometbft/abci/types" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} +) + +type AppModuleBasic struct { + cdc codec.Codec +} + +type AppModule struct { + AppModuleBasic + keeper *keeper.Keeper +} + +// NewAppModule creates a new AppModule object. +func NewAppModule(cdc codec.Codec, k *keeper.Keeper) AppModule { + return AppModule{AppModuleBasic: AppModuleBasic{cdc: cdc}, keeper: k} +} + +// Name returns the cron module's name. +func (AppModuleBasic) Name() string { return types.ModuleName } + +// RegisterLegacyAminoCodec registers the cron module's types on the legacy Amino codec. +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + types.RegisterLegacyAminoCodec(cdc) +} + +// RegisterInterfaces registers the cron module's interface types. +func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) { + types.RegisterInterfaces(registry) +} + +// DefaultGenesis returns the default genesis state for the cron module. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(types.DefaultGenesisState()) +} + +// ValidateGenesis performs genesis state validation for the cron module. +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error { + var data types.GenesisState + if err := cdc.UnmarshalJSON(bz, &data); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) + } + return types.ValidateGenesis(&data) +} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the cron module. +func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { + _ = types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) +} + +// GetTxCmd returns the root tx command for the cron module. +func (AppModuleBasic) GetTxCmd() *cobra.Command { + return cli.GetTxCmd() +} + +// GetQueryCmd returns the root query command for the cron module. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return cli.GetQueryCmd() +} + +func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} + +// QuerierRoute returns the cron module's query route. +func (AppModule) QuerierRoute() string { return types.RouterKey } + +// RegisterServices registers the cron module's gRPC services. +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 cron module. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { + var genesisState types.GenesisState + cdc.MustUnmarshalJSON(data, &genesisState) + InitGenesis(ctx, *am.keeper, genesisState) + return nil +} + +// ExportGenesis returns the exported genesis state for the cron module. +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(ExportGenesis(ctx, *am.keeper)) +} + +// ConsensusVersion implements AppModule/ConsensusVersion. +func (AppModule) ConsensusVersion() uint64 { return 1 } + +func (AppModule) IsAppModule() {} +func (AppModule) IsOnePerModuleType() {} + +// BeginBlock executes ready begin-block schedules. +func (am AppModule) BeginBlock(ctx context.Context) ([]abci.ValidatorUpdate, error) { + am.keeper.ExecuteReadySchedules(sdk.UnwrapSDKContext(ctx), types.ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER) + return []abci.ValidatorUpdate{}, nil +} + +// EndBlock executes ready end-block schedules. +func (am AppModule) EndBlock(ctx context.Context) ([]abci.ValidatorUpdate, error) { + am.keeper.ExecuteReadySchedules(sdk.UnwrapSDKContext(ctx), types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER) + return []abci.ValidatorUpdate{}, nil +} diff --git a/x/cron/spec/01_concepts.md b/x/cron/spec/01_concepts.md new file mode 100644 index 000000000..82006987a --- /dev/null +++ b/x/cron/spec/01_concepts.md @@ -0,0 +1,41 @@ + + +# Concepts + +## Scheduled Execution + +A cron schedule is a named record that says: + +- which Wasm contract messages to execute +- how often to execute them, measured in block intervals +- whether execution happens in `BeginBlock` or `EndBlock` +- the last block height at which the schedule executed + +At each supported block stage, the module scans stored schedules, selects the ones whose interval has elapsed, and executes up to the configured per-stage limit. + +## Authority Model + +Cron state is admin-controlled. The module exposes `MsgAddSchedule`, `MsgRemoveSchedule`, and `MsgUpdateParams`, but each message is gated by the module `authority` address configured when the keeper is constructed. + +In Terra Classic app wiring, this authority is the standard governance authority address. A normal user account cannot directly create or modify schedules unless it is the configured authority. + +## Execution Stages + +The module supports two execution stages: + +- `EXECUTION_STAGE_BEGIN_BLOCKER` +- `EXECUTION_STAGE_END_BLOCKER` + +The stage is part of the stored schedule and is checked before execution. The app wires cron into both `BeginBlock` and `EndBlock`, so the same module can host schedules that run at either lifecycle point. + +## Failure Semantics + +Cron executes each due schedule in a cached context. + +- Before execution starts, the module updates `last_execute_height` on the stored schedule. +- It then executes each nested contract message using the cron module account as the sender. +- If any nested message fails, the cached writes are discarded, so no partial Wasm effects are committed for that schedule. + +The failure is logged, but the schedule remains advanced to the current height because the schedule record itself is updated before the cached execution block. This means failed schedules are not retried again in the same block. diff --git a/x/cron/spec/02_state.md b/x/cron/spec/02_state.md new file mode 100644 index 000000000..28c6ee32c --- /dev/null +++ b/x/cron/spec/02_state.md @@ -0,0 +1,66 @@ + + +# State + +## Schedule + +`Schedule` is the primary cron state object. + +- `Schedule`: `0x01 -> proto(Schedule)` + +```go +type Schedule struct { + Name string + Period uint64 + Msgs []MsgExecuteContract + LastExecuteHeight uint64 + ExecutionStage ExecutionStage +} +``` + +Field meanings: + +- `Name`: unique schedule identifier +- `Period`: execution interval in blocks +- `Msgs`: ordered list of Wasm execute payloads +- `LastExecuteHeight`: last successful scheduling checkpoint used for interval calculation +- `ExecutionStage`: whether the schedule runs in `BeginBlock` or `EndBlock` + +`Msgs` contains only contract address plus raw JSON message payload: + +```go +type MsgExecuteContract struct { + Contract string + Msg string +} +``` + +## ScheduleCount + +The module stores a denormalized count of schedules. + +- `ScheduleCount`: `0x02 -> proto(ScheduleCount)` + +```go +type ScheduleCount struct { + Count int32 +} +``` + +This count is incremented on add and decremented on remove. + +## Params + +Cron parameters are stored under a dedicated params key. + +- `Params`: `0x03 -> proto(Params)` + +```go +type Params struct { + Limit uint64 +} +``` + +`Limit` bounds how many schedules may execute during one pass of `BeginBlock` or `EndBlock`. diff --git a/x/cron/spec/03_block_lifecycle.md b/x/cron/spec/03_block_lifecycle.md new file mode 100644 index 000000000..6d18886da --- /dev/null +++ b/x/cron/spec/03_block_lifecycle.md @@ -0,0 +1,42 @@ + + +# Block Lifecycle + +## BeginBlock + +During `BeginBlock`, the app calls: + +```go +am.keeper.ExecuteReadySchedules(ctx, EXECUTION_STAGE_BEGIN_BLOCKER) +``` + +The keeper: + +1. loads current params +2. iterates all stored schedules +3. selects schedules whose interval has elapsed and whose `execution_stage` is `BEGIN_BLOCKER` +4. stops once `params.limit` schedules have been selected +5. executes each selected schedule in order + +## EndBlock + +During `EndBlock`, the app calls: + +```go +am.keeper.ExecuteReadySchedules(ctx, EXECUTION_STAGE_END_BLOCKER) +``` + +The same selection and execution flow is used, but only schedules tagged for `END_BLOCKER` are considered. + +## Nested Contract Dispatch + +Each scheduled item is dispatched as a Wasm `MsgExecuteContract` with: + +- `sender = cron module account` +- `contract = schedule message contract` +- `msg = schedule message JSON payload` +- `funds = []` + +Cron does not mint, move, or attach native coins itself. Any downstream token movement comes from the executed contract logic. diff --git a/x/cron/spec/04_messages.md b/x/cron/spec/04_messages.md new file mode 100644 index 000000000..d69009dd7 --- /dev/null +++ b/x/cron/spec/04_messages.md @@ -0,0 +1,67 @@ + + +# Messages + +## MsgAddSchedule + +Adds a new named schedule. + +```go +type MsgAddSchedule struct { + Authority string + Name string + Period uint64 + Msgs []MsgExecuteContract + ExecutionStage ExecutionStage +} +``` + +Validation rules: + +- `authority` must be a valid Bech32 account address +- `name` must be non-empty +- `period` must be greater than zero +- `msgs` must be non-empty +- `execution_stage` must be a defined enum value +- each nested contract message must have non-empty `contract` and `msg` +- each nested `msg` string must be valid JSON + +The handler also enforces that `authority` equals the keeper authority configured by the app. + +## MsgRemoveSchedule + +Removes a schedule by name. + +```go +type MsgRemoveSchedule struct { + Authority string + Name string +} +``` + +Validation rules: + +- `authority` must be a valid Bech32 account address +- `name` must be non-empty + +The handler is authority-gated. Removing a missing schedule is a no-op at keeper level. + +## MsgUpdateParams + +Updates cron module parameters. + +```go +type MsgUpdateParams struct { + Authority string + Params Params +} +``` + +Validation rules: + +- `authority` must be a valid Bech32 account address +- `params.limit` must be greater than zero + +The handler is authority-gated. diff --git a/x/cron/spec/05_events.md b/x/cron/spec/05_events.md new file mode 100644 index 000000000..c4345cd28 --- /dev/null +++ b/x/cron/spec/05_events.md @@ -0,0 +1,25 @@ + + +# Events + +## Cron Module Events + +The cron module does not define custom cron-specific event types in its keeper or message server code. + +Successful authority messages still emit the standard SDK `message` event metadata produced by the message execution stack. + +Execution failures are logged with: + +- `schedule_name` +- `contract` +- `error` + +but these log lines are not ABCI events. + +## Nested Wasm Events + +When a scheduled contract call succeeds, any events emitted by the nested Wasm execution are surfaced through the normal Wasm execution pipeline. + +Cron itself does not rewrite or add additional execution events around those nested calls. diff --git a/x/cron/spec/06_params.md b/x/cron/spec/06_params.md new file mode 100644 index 000000000..af83b6bf2 --- /dev/null +++ b/x/cron/spec/06_params.md @@ -0,0 +1,22 @@ + + +# Parameters + +The cron module contains the following parameters: + +| Key | Type | Example | +|-------|--------|---------| +| limit | uint64 | `5` | + +## limit + +`limit` is the maximum number of schedules the module will execute in a single stage pass. + +The limit is applied independently to: + +- one `BeginBlock` execution pass +- one `EndBlock` execution pass + +This parameter bounds block-time work even if more schedules are due. diff --git a/x/cron/spec/README.md b/x/cron/spec/README.md new file mode 100644 index 000000000..d92c46a86 --- /dev/null +++ b/x/cron/spec/README.md @@ -0,0 +1,33 @@ +## Abstract + +The `x/cron` module provides a governance-controlled scheduler for recurring CosmWasm contract execution. It stores named schedules, evaluates them at block boundaries, and dispatches due contract calls from the cron module account through Terra's existing Wasm message server. + +This implementation is intentionally narrow: + +- only module-authority messages may create, remove, or update cron state +- scheduled payloads are Wasm `ExecuteContract` messages with no funds +- execution can occur at either `BeginBlock` or `EndBlock` +- execution throughput per stage is bounded by a module parameter + +## Contents + +1. **[Concepts](01_concepts.md)** + - [Scheduled Execution](01_concepts.md#scheduled-execution) + - [Authority Model](01_concepts.md#authority-model) + - [Execution Stages](01_concepts.md#execution-stages) + - [Failure Semantics](01_concepts.md#failure-semantics) +2. **[State](02_state.md)** + - [Schedule](02_state.md#schedule) + - [ScheduleCount](02_state.md#schedulecount) + - [Params](02_state.md#params) +3. **[Block Lifecycle](03_block_lifecycle.md)** + - [BeginBlock](03_block_lifecycle.md#beginblock) + - [EndBlock](03_block_lifecycle.md#endblock) +4. **[Messages](04_messages.md)** + - [MsgAddSchedule](04_messages.md#msgaddschedule) + - [MsgRemoveSchedule](04_messages.md#msgremoveschedule) + - [MsgUpdateParams](04_messages.md#msgupdateparams) +5. **[Events](05_events.md)** + - [Cron Module Events](05_events.md#cron-module-events) + - [Nested Wasm Events](05_events.md#nested-wasm-events) +6. **[Parameters](06_params.md)** diff --git a/x/cron/types/codec.go b/x/cron/types/codec.go new file mode 100644 index 000000000..cd0781465 --- /dev/null +++ b/x/cron/types/codec.go @@ -0,0 +1,39 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/legacy" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/msgservice" +) + +func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + legacy.RegisterAminoMsg(cdc, &MsgAddSchedule{}, "cron/MsgAddSchedule") + legacy.RegisterAminoMsg(cdc, &MsgRemoveSchedule{}, "cron/MsgRemoveSchedule") + legacy.RegisterAminoMsg(cdc, &MsgUpdateParams{}, "cron/MsgUpdateParams") +} + +func RegisterInterfaces(registry codectypes.InterfaceRegistry) { + registry.RegisterImplementations( + (*sdk.Msg)(nil), + &MsgAddSchedule{}, + &MsgRemoveSchedule{}, + &MsgUpdateParams{}, + ) + + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) +} + +var ( + amino = codec.NewLegacyAmino() + ModuleCdc = codec.NewAminoCodec(amino) +) + +func init() { + RegisterLegacyAminoCodec(amino) + cryptocodec.RegisterCrypto(amino) + sdk.RegisterLegacyAminoCodec(amino) + amino.Seal() +} diff --git a/x/cron/types/errors.go b/x/cron/types/errors.go new file mode 100644 index 000000000..fbd61bbdb --- /dev/null +++ b/x/cron/types/errors.go @@ -0,0 +1,14 @@ +package types + +import errorsmod "cosmossdk.io/errors" + +var ( + ErrInvalidScheduleName = errorsmod.Register(ModuleName, 1, "schedule name is invalid") + ErrInvalidSchedulePeriod = errorsmod.Register(ModuleName, 2, "schedule period is invalid") + ErrInvalidScheduleStage = errorsmod.Register(ModuleName, 3, "schedule execution stage is invalid") + ErrDuplicateSchedule = errorsmod.Register(ModuleName, 4, "schedule already exists") + ErrScheduleNotFound = errorsmod.Register(ModuleName, 5, "schedule not found") + ErrInvalidAuthority = errorsmod.Register(ModuleName, 6, "authority is invalid") + ErrInvalidMsg = errorsmod.Register(ModuleName, 7, "contract execute message is invalid") + ErrInvalidLimit = errorsmod.Register(ModuleName, 8, "limit cannot be zero") +) diff --git a/x/cron/types/expected_keepers.go b/x/cron/types/expected_keepers.go new file mode 100644 index 000000000..dba848c89 --- /dev/null +++ b/x/cron/types/expected_keepers.go @@ -0,0 +1,16 @@ +package types + +import ( + "context" + + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type AccountKeeper interface { + GetModuleAddress(moduleName string) sdk.AccAddress +} + +type WasmMsgServer interface { + ExecuteContract(context.Context, *wasmtypes.MsgExecuteContract) (*wasmtypes.MsgExecuteContractResponse, error) +} diff --git a/x/cron/types/genesis.go b/x/cron/types/genesis.go new file mode 100644 index 000000000..e7757b842 --- /dev/null +++ b/x/cron/types/genesis.go @@ -0,0 +1,69 @@ +package types + +import "fmt" + +func DefaultGenesisState() *GenesisState { + return &GenesisState{Params: DefaultParams()} +} + +func ValidateGenesis(gs *GenesisState) error { + return gs.Validate() +} + +func (gs GenesisState) Validate() error { + if err := gs.Params.Validate(); err != nil { + return err + } + + seen := make(map[string]struct{}, len(gs.ScheduleList)) + for _, schedule := range gs.ScheduleList { + if err := validateSchedule(schedule); err != nil { + return err + } + if _, exists := seen[schedule.Name]; exists { + return fmt.Errorf("%w: %s", ErrDuplicateSchedule, schedule.Name) + } + seen[schedule.Name] = struct{}{} + } + + return nil +} + +func ValidateSchedule(schedule Schedule) error { + return validateSchedule(schedule) +} + +func validateSchedule(schedule Schedule) error { + if schedule.Name == "" { + return ErrInvalidScheduleName + } + if schedule.Period == 0 { + return ErrInvalidSchedulePeriod + } + if len(schedule.Msgs) == 0 { + return ErrInvalidMsg + } + for _, msg := range schedule.Msgs { + if err := validateMsgExecuteContract(msg); err != nil { + return err + } + } + if _, ok := ExecutionStage_name[int32(schedule.ExecutionStage)]; !ok { + return ErrInvalidScheduleStage + } + return nil +} + +func ValidateMsgExecuteContract(msg MsgExecuteContract) error { + return validateMsgExecuteContract(msg) +} + +func validateMsgExecuteContract(msg MsgExecuteContract) error { + if msg.Contract == "" { + return ErrInvalidMsg + } + if msg.Msg == "" { + return ErrInvalidMsg + } + return nil +} diff --git a/x/cron/types/genesis.pb.go b/x/cron/types/genesis.pb.go new file mode 100644 index 000000000..39e80aa70 --- /dev/null +++ b/x/cron/types/genesis.pb.go @@ -0,0 +1,385 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: terra/cron/v1/genesis.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type GenesisState struct { + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + ScheduleList []Schedule `protobuf:"bytes,2,rep,name=schedule_list,json=scheduleList,proto3" json:"schedule_list"` +} + +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_df1fe9b25afd41d8, []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) GetScheduleList() []Schedule { + if m != nil { + return m.ScheduleList + } + return nil +} + +func init() { + proto.RegisterType((*GenesisState)(nil), "terra.cron.v1.GenesisState") +} + +func init() { proto.RegisterFile("terra/cron/v1/genesis.proto", fileDescriptor_df1fe9b25afd41d8) } + +var fileDescriptor_df1fe9b25afd41d8 = []byte{ + // 249 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x2e, 0x49, 0x2d, 0x2a, + 0x4a, 0xd4, 0x4f, 0x2e, 0xca, 0xcf, 0xd3, 0x2f, 0x33, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, + 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x05, 0x4b, 0xea, 0x81, 0x24, 0xf5, 0xca, + 0x0c, 0xa5, 0x44, 0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0x32, 0xfa, 0x20, 0x16, 0x44, 0x91, 0x94, 0x14, + 0xaa, 0x09, 0x05, 0x89, 0x45, 0x89, 0xb9, 0x50, 0x03, 0xa4, 0x64, 0x50, 0xe5, 0x8a, 0x93, 0x33, + 0x52, 0x53, 0x4a, 0x73, 0x52, 0x21, 0xb2, 0x4a, 0xed, 0x8c, 0x5c, 0x3c, 0xee, 0x10, 0x0b, 0x83, + 0x4b, 0x12, 0x4b, 0x52, 0x85, 0x8c, 0xb9, 0xd8, 0x20, 0xda, 0x25, 0x18, 0x15, 0x18, 0x35, 0xb8, + 0x8d, 0x44, 0xf5, 0x50, 0x1c, 0xa0, 0x17, 0x00, 0x96, 0x74, 0x62, 0x39, 0x71, 0x4f, 0x9e, 0x21, + 0x08, 0xaa, 0x54, 0xc8, 0x89, 0x8b, 0x17, 0x66, 0x6e, 0x7c, 0x4e, 0x66, 0x71, 0x89, 0x04, 0x93, + 0x02, 0xb3, 0x06, 0xb7, 0x91, 0x38, 0x9a, 0xde, 0x60, 0xa8, 0x1a, 0xa8, 0x6e, 0x1e, 0x98, 0x1e, + 0x9f, 0xcc, 0xe2, 0x12, 0x27, 0xf7, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, + 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, + 0xd2, 0x4d, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x49, 0x2c, + 0x2e, 0xce, 0x4c, 0xd6, 0x85, 0x7a, 0x2a, 0xbf, 0x28, 0x55, 0xbf, 0xcc, 0x44, 0xbf, 0x02, 0xe2, + 0xbd, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, 0xb0, 0xcf, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, + 0xff, 0xdd, 0x75, 0x64, 0x55, 0x57, 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.ScheduleList) > 0 { + for iNdEx := len(m.ScheduleList) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ScheduleList[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 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.ScheduleList) > 0 { + for _, e := range m.ScheduleList { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 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 ScheduleList", 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.ScheduleList = append(m.ScheduleList, Schedule{}) + if err := m.ScheduleList[len(m.ScheduleList)-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 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/cron/types/genesis_test.go b/x/cron/types/genesis_test.go new file mode 100644 index 000000000..a2fae9835 --- /dev/null +++ b/x/cron/types/genesis_test.go @@ -0,0 +1,14 @@ +package types + +import "testing" + +import "github.com/stretchr/testify/require" + +func TestGenesisValidate(t *testing.T) { + require.NoError(t, DefaultGenesisState().Validate()) + + err := GenesisState{ + Params: Params{Limit: 0}, + }.Validate() + require.Error(t, err) +} diff --git a/x/cron/types/keys.go b/x/cron/types/keys.go new file mode 100644 index 000000000..0d6af16de --- /dev/null +++ b/x/cron/types/keys.go @@ -0,0 +1,30 @@ +package types + +const ( + // ModuleName defines the module name. + ModuleName = "cron" + // StoreKey defines the primary module store key. + StoreKey = ModuleName + // RouterKey defines the module message route. + RouterKey = ModuleName + + // MemStoreKey defines the in-memory store key. + MemStoreKey = "mem_cron" +) + +const ( + prefixScheduleKey = iota + 1 + prefixScheduleCountKey + prefixParamsKey +) + +var ( + ScheduleKey = []byte{prefixScheduleKey} + ScheduleCountKey = []byte{prefixScheduleCountKey} + ParamsKey = []byte{prefixParamsKey} +) + +// GetScheduleKey returns the store key for a schedule name. +func GetScheduleKey(name string) []byte { + return []byte(name) +} diff --git a/x/cron/types/params.go b/x/cron/types/params.go new file mode 100644 index 000000000..a1ce4532c --- /dev/null +++ b/x/cron/types/params.go @@ -0,0 +1,59 @@ +package types + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" +) + +var _ paramtypes.ParamSet = (*Params)(nil) + +var ( + DefaultLimit = uint64(5) +) + +// ParamKeyTable returns the cron module parameter key table. +func ParamKeyTable() paramtypes.KeyTable { + return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) +} + +// NewParams creates a new Params instance. +func NewParams(limit uint64) Params { + return Params{Limit: limit} +} + +// DefaultParams returns the default cron module parameters. +func DefaultParams() Params { + return NewParams(DefaultLimit) +} + +// ParamSetPairs returns the cron module parameter set pairs. +func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { + return paramtypes.ParamSetPairs{ + paramtypes.NewParamSetPair([]byte("Limit"), &p.Limit, validateLimit), + } +} + +// Validate validates the cron module parameters. +func (p Params) Validate() error { + return validateLimit(p.Limit) +} + +func validateLimit(i interface{}) error { + l, ok := i.(uint64) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + if l == 0 { + return ErrInvalidLimit + } + return nil +} + +func validateAuthority(authority string) error { + if _, err := sdk.AccAddressFromBech32(authority); err != nil { + return ErrInvalidAuthority + } + return nil +} diff --git a/x/cron/types/params.pb.go b/x/cron/types/params.pb.go new file mode 100644 index 000000000..c54fd93f0 --- /dev/null +++ b/x/cron/types/params.pb.go @@ -0,0 +1,304 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: terra/cron/v1/params.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + _ "github.com/cosmos/cosmos-sdk/types/tx/amino" + _ "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 Params struct { + Limit uint64 `protobuf:"varint,1,opt,name=limit,proto3" json:"limit,omitempty"` +} + +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_c5cf0b5e5aec2d7b, []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 (m *Params) GetLimit() uint64 { + if m != nil { + return m.Limit + } + return 0 +} + +func init() { + proto.RegisterType((*Params)(nil), "terra.cron.v1.Params") +} + +func init() { proto.RegisterFile("terra/cron/v1/params.proto", fileDescriptor_c5cf0b5e5aec2d7b) } + +var fileDescriptor_c5cf0b5e5aec2d7b = []byte{ + // 195 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x2a, 0x49, 0x2d, 0x2a, + 0x4a, 0xd4, 0x4f, 0x2e, 0xca, 0xcf, 0xd3, 0x2f, 0x33, 0xd4, 0x2f, 0x48, 0x2c, 0x4a, 0xcc, 0x2d, + 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x05, 0xcb, 0xe9, 0x81, 0xe4, 0xf4, 0xca, 0x0c, + 0xa5, 0x04, 0x13, 0x73, 0x33, 0xf3, 0xf2, 0xf5, 0xc1, 0x24, 0x44, 0x85, 0x94, 0x64, 0x72, 0x7e, + 0x71, 0x6e, 0x7e, 0x71, 0x3c, 0x98, 0xa7, 0x0f, 0xe1, 0x40, 0xa5, 0x44, 0xd2, 0xf3, 0xd3, 0xf3, + 0x21, 0xe2, 0x20, 0x16, 0x44, 0x54, 0x49, 0x8e, 0x8b, 0x2d, 0x00, 0x6c, 0x85, 0x90, 0x08, 0x17, + 0x6b, 0x4e, 0x66, 0x6e, 0x66, 0x89, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x4b, 0x10, 0x84, 0xe3, 0xe4, + 0x7e, 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, 0xba, 0xe9, 0x99, 0x25, 0x19, + 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0xc9, 0x39, 0x89, 0xc5, 0xc5, 0x99, 0xc9, 0xba, 0x50, + 0xb7, 0xe7, 0x17, 0xa5, 0xea, 0x97, 0x99, 0xe8, 0x57, 0x40, 0x7c, 0x51, 0x52, 0x59, 0x90, 0x5a, + 0x9c, 0xc4, 0x06, 0xb6, 0xcf, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xce, 0x49, 0x77, 0x1f, 0xe0, + 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 + if m.Limit != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.Limit)) + i-- + dAtA[i] = 0x8 + } + 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 + if m.Limit != 0 { + n += 1 + sovParams(uint64(m.Limit)) + } + 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 { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) + } + m.Limit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Limit |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + 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/cron/types/query.pb.go b/x/cron/types/query.pb.go new file mode 100644 index 000000000..6f80ed0c8 --- /dev/null +++ b/x/cron/types/query.pb.go @@ -0,0 +1,1379 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: terra/cron/v1/query.proto + +package types + +import ( + context "context" + fmt "fmt" + query "github.com/cosmos/cosmos-sdk/types/query" + _ "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 QueryParamsRequest struct { +} + +func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } +func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryParamsRequest) ProtoMessage() {} +func (*QueryParamsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_5b0805d57f892efa, []int{0} +} +func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsRequest.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 *QueryParamsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsRequest.Merge(m, src) +} +func (m *QueryParamsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsRequest proto.InternalMessageInfo + +type QueryParamsResponse struct { + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` +} + +func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } +func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryParamsResponse) ProtoMessage() {} +func (*QueryParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_5b0805d57f892efa, []int{1} +} +func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsResponse.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 *QueryParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsResponse.Merge(m, src) +} +func (m *QueryParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsResponse proto.InternalMessageInfo + +func (m *QueryParamsResponse) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +type QueryScheduleRequest struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (m *QueryScheduleRequest) Reset() { *m = QueryScheduleRequest{} } +func (m *QueryScheduleRequest) String() string { return proto.CompactTextString(m) } +func (*QueryScheduleRequest) ProtoMessage() {} +func (*QueryScheduleRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_5b0805d57f892efa, []int{2} +} +func (m *QueryScheduleRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryScheduleRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryScheduleRequest.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 *QueryScheduleRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryScheduleRequest.Merge(m, src) +} +func (m *QueryScheduleRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryScheduleRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryScheduleRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryScheduleRequest proto.InternalMessageInfo + +func (m *QueryScheduleRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +type QueryScheduleResponse struct { + Schedule Schedule `protobuf:"bytes,1,opt,name=schedule,proto3" json:"schedule"` +} + +func (m *QueryScheduleResponse) Reset() { *m = QueryScheduleResponse{} } +func (m *QueryScheduleResponse) String() string { return proto.CompactTextString(m) } +func (*QueryScheduleResponse) ProtoMessage() {} +func (*QueryScheduleResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_5b0805d57f892efa, []int{3} +} +func (m *QueryScheduleResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryScheduleResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryScheduleResponse.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 *QueryScheduleResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryScheduleResponse.Merge(m, src) +} +func (m *QueryScheduleResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryScheduleResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryScheduleResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryScheduleResponse proto.InternalMessageInfo + +func (m *QueryScheduleResponse) GetSchedule() Schedule { + if m != nil { + return m.Schedule + } + return Schedule{} +} + +type QuerySchedulesRequest struct { + Pagination *query.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QuerySchedulesRequest) Reset() { *m = QuerySchedulesRequest{} } +func (m *QuerySchedulesRequest) String() string { return proto.CompactTextString(m) } +func (*QuerySchedulesRequest) ProtoMessage() {} +func (*QuerySchedulesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_5b0805d57f892efa, []int{4} +} +func (m *QuerySchedulesRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySchedulesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySchedulesRequest.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 *QuerySchedulesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySchedulesRequest.Merge(m, src) +} +func (m *QuerySchedulesRequest) XXX_Size() int { + return m.Size() +} +func (m *QuerySchedulesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySchedulesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySchedulesRequest proto.InternalMessageInfo + +func (m *QuerySchedulesRequest) GetPagination() *query.PageRequest { + if m != nil { + return m.Pagination + } + return nil +} + +type QuerySchedulesResponse struct { + Schedules []Schedule `protobuf:"bytes,1,rep,name=schedules,proto3" json:"schedules"` + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QuerySchedulesResponse) Reset() { *m = QuerySchedulesResponse{} } +func (m *QuerySchedulesResponse) String() string { return proto.CompactTextString(m) } +func (*QuerySchedulesResponse) ProtoMessage() {} +func (*QuerySchedulesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_5b0805d57f892efa, []int{5} +} +func (m *QuerySchedulesResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySchedulesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySchedulesResponse.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 *QuerySchedulesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySchedulesResponse.Merge(m, src) +} +func (m *QuerySchedulesResponse) XXX_Size() int { + return m.Size() +} +func (m *QuerySchedulesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySchedulesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySchedulesResponse proto.InternalMessageInfo + +func (m *QuerySchedulesResponse) GetSchedules() []Schedule { + if m != nil { + return m.Schedules + } + return nil +} + +func (m *QuerySchedulesResponse) GetPagination() *query.PageResponse { + if m != nil { + return m.Pagination + } + return nil +} + +func init() { + proto.RegisterType((*QueryParamsRequest)(nil), "terra.cron.v1.QueryParamsRequest") + proto.RegisterType((*QueryParamsResponse)(nil), "terra.cron.v1.QueryParamsResponse") + proto.RegisterType((*QueryScheduleRequest)(nil), "terra.cron.v1.QueryScheduleRequest") + proto.RegisterType((*QueryScheduleResponse)(nil), "terra.cron.v1.QueryScheduleResponse") + proto.RegisterType((*QuerySchedulesRequest)(nil), "terra.cron.v1.QuerySchedulesRequest") + proto.RegisterType((*QuerySchedulesResponse)(nil), "terra.cron.v1.QuerySchedulesResponse") +} + +func init() { proto.RegisterFile("terra/cron/v1/query.proto", fileDescriptor_5b0805d57f892efa) } + +var fileDescriptor_5b0805d57f892efa = []byte{ + // 505 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x93, 0xbf, 0x6e, 0x13, 0x41, + 0x10, 0xc6, 0x7d, 0x26, 0x58, 0xf1, 0x20, 0x9a, 0x21, 0xc6, 0xe6, 0x14, 0x2e, 0xc9, 0x09, 0x62, + 0x84, 0xe4, 0x5d, 0x39, 0xa1, 0x41, 0x74, 0x29, 0xb0, 0x44, 0x15, 0x8c, 0x68, 0x68, 0xd0, 0xfa, + 0x58, 0x5d, 0x4e, 0xb2, 0x6f, 0x2f, 0xb7, 0x6b, 0x8b, 0x80, 0x68, 0x10, 0x0f, 0x80, 0x44, 0xcf, + 0xf3, 0xa4, 0x8c, 0x44, 0x43, 0x85, 0x90, 0xcd, 0x53, 0x50, 0xa1, 0xdb, 0x3f, 0x89, 0xcf, 0x36, + 0x71, 0xb7, 0xda, 0xf9, 0xe6, 0xfb, 0x7e, 0x7b, 0x33, 0x07, 0xf7, 0x14, 0xcf, 0x73, 0x46, 0xa3, + 0x5c, 0xa4, 0x74, 0xd2, 0xa5, 0xa7, 0x63, 0x9e, 0x9f, 0x91, 0x2c, 0x17, 0x4a, 0xe0, 0x6d, 0x5d, + 0x22, 0x45, 0x89, 0x4c, 0xba, 0xfe, 0xe3, 0x48, 0xc8, 0x91, 0x90, 0x74, 0xc0, 0x24, 0x37, 0x3a, + 0x3a, 0xe9, 0x0e, 0xb8, 0x62, 0x5d, 0x9a, 0xb1, 0x38, 0x49, 0x99, 0x4a, 0x44, 0x6a, 0x5a, 0xfd, + 0xed, 0x58, 0x88, 0x78, 0xc8, 0x29, 0xcb, 0x12, 0xca, 0xd2, 0x54, 0x28, 0x5d, 0x94, 0xb6, 0xba, + 0x15, 0x8b, 0x58, 0xe8, 0x23, 0x2d, 0x4e, 0xf6, 0xd6, 0x2f, 0x93, 0x64, 0x2c, 0x67, 0x23, 0xd7, + 0xb1, 0x5d, 0xae, 0xc9, 0xe8, 0x84, 0xbf, 0x1b, 0x0f, 0xb9, 0xa9, 0x86, 0x5b, 0x80, 0x2f, 0x0b, + 0x9e, 0x63, 0xdd, 0xd2, 0xe7, 0xa7, 0x63, 0x2e, 0x55, 0xf8, 0x02, 0xee, 0x94, 0x6e, 0x65, 0x26, + 0x52, 0xc9, 0xf1, 0x10, 0x6a, 0xc6, 0xba, 0xe5, 0xed, 0x7a, 0x8f, 0x6e, 0x1d, 0x34, 0x48, 0xe9, + 0x99, 0xc4, 0xc8, 0x8f, 0x36, 0xce, 0x7f, 0xed, 0x54, 0xfa, 0x56, 0x1a, 0x76, 0xa0, 0xa9, 0xbd, + 0x7a, 0x5c, 0xbd, 0xb2, 0xd9, 0x36, 0x06, 0x11, 0x36, 0x52, 0x36, 0xe2, 0xda, 0xad, 0xde, 0xd7, + 0xe7, 0xf0, 0x35, 0xb4, 0x96, 0xe5, 0x36, 0xff, 0x29, 0x6c, 0x3a, 0x7c, 0x4b, 0xd0, 0x5c, 0x20, + 0x70, 0x2d, 0x96, 0xe1, 0x52, 0x1e, 0xbe, 0x85, 0x86, 0xb6, 0x75, 0x02, 0xf7, 0x54, 0x7c, 0x0e, + 0x70, 0x35, 0x02, 0xeb, 0xba, 0x4f, 0xcc, 0xbc, 0x48, 0x31, 0x2f, 0x62, 0xe6, 0x6a, 0xe7, 0x45, + 0x8e, 0x59, 0xec, 0xf8, 0xfb, 0x73, 0x9d, 0xe1, 0x77, 0x0f, 0xee, 0x2e, 0x26, 0x58, 0xec, 0x67, + 0x50, 0x77, 0x1c, 0xc5, 0x97, 0xbb, 0xb1, 0x9e, 0xfb, 0x4a, 0x8f, 0xbd, 0x12, 0x5f, 0x55, 0xf3, + 0xb5, 0xd7, 0xf2, 0x99, 0xe4, 0x79, 0xc0, 0x83, 0xbf, 0x55, 0xb8, 0xa9, 0x01, 0x31, 0x85, 0x9a, + 0x99, 0x14, 0xee, 0x2d, 0x60, 0x2c, 0xaf, 0x82, 0x1f, 0x5e, 0x27, 0x31, 0x31, 0xe1, 0xfd, 0xcf, + 0x3f, 0xfe, 0x7c, 0xab, 0x36, 0xb1, 0x41, 0x57, 0xed, 0x21, 0x7e, 0xf1, 0x60, 0xd3, 0x3d, 0x10, + 0xf7, 0x57, 0xf9, 0x2d, 0xef, 0x86, 0xdf, 0x5e, 0xab, 0xb3, 0xe1, 0x6d, 0x1d, 0xbe, 0x87, 0x3b, + 0x74, 0xf5, 0xa2, 0x4b, 0xfa, 0xb1, 0x58, 0xac, 0x4f, 0xf8, 0x01, 0xea, 0x97, 0xb3, 0xc1, 0x07, + 0xab, 0xec, 0x17, 0x97, 0xc3, 0x7f, 0xb8, 0x46, 0x65, 0x11, 0x76, 0x35, 0x82, 0x8f, 0xad, 0xff, + 0x21, 0x1c, 0xf5, 0xce, 0xa7, 0x81, 0x77, 0x31, 0x0d, 0xbc, 0xdf, 0xd3, 0xc0, 0xfb, 0x3a, 0x0b, + 0x2a, 0x17, 0xb3, 0xa0, 0xf2, 0x73, 0x16, 0x54, 0xde, 0x74, 0xe2, 0x44, 0x9d, 0x8c, 0x07, 0x24, + 0x12, 0x23, 0x1a, 0x0d, 0x99, 0x94, 0x49, 0xd4, 0xb1, 0x2e, 0x22, 0xe7, 0x74, 0xf2, 0x84, 0xbe, + 0x37, 0x7e, 0xea, 0x2c, 0xe3, 0x72, 0x50, 0xd3, 0xbf, 0xed, 0xe1, 0xbf, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xb4, 0x29, 0xa2, 0x08, 0x7c, 0x04, 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 { + Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) + Schedule(ctx context.Context, in *QueryScheduleRequest, opts ...grpc.CallOption) (*QueryScheduleResponse, error) + Schedules(ctx context.Context, in *QuerySchedulesRequest, opts ...grpc.CallOption) (*QuerySchedulesResponse, error) +} + +type queryClient struct { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { + out := new(QueryParamsResponse) + err := c.cc.Invoke(ctx, "/terra.cron.v1.Query/Params", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) Schedule(ctx context.Context, in *QueryScheduleRequest, opts ...grpc.CallOption) (*QueryScheduleResponse, error) { + out := new(QueryScheduleResponse) + err := c.cc.Invoke(ctx, "/terra.cron.v1.Query/Schedule", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) Schedules(ctx context.Context, in *QuerySchedulesRequest, opts ...grpc.CallOption) (*QuerySchedulesResponse, error) { + out := new(QuerySchedulesResponse) + err := c.cc.Invoke(ctx, "/terra.cron.v1.Query/Schedules", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +type QueryServer interface { + Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + Schedule(context.Context, *QueryScheduleRequest) (*QueryScheduleResponse, error) + Schedules(context.Context, *QuerySchedulesRequest) (*QuerySchedulesResponse, error) +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") +} +func (*UnimplementedQueryServer) Schedule(ctx context.Context, req *QueryScheduleRequest) (*QueryScheduleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Schedule not implemented") +} +func (*UnimplementedQueryServer) Schedules(ctx context.Context, req *QuerySchedulesRequest) (*QuerySchedulesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Schedules not implemented") +} + +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryParamsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Params(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/terra.cron.v1.Query/Params", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_Schedule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryScheduleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Schedule(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/terra.cron.v1.Query/Schedule", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Schedule(ctx, req.(*QueryScheduleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_Schedules_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QuerySchedulesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Schedules(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/terra.cron.v1.Query/Schedules", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Schedules(ctx, req.(*QuerySchedulesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "terra.cron.v1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Params", + Handler: _Query_Params_Handler, + }, + { + MethodName: "Schedule", + Handler: _Query_Schedule_Handler, + }, + { + MethodName: "Schedules", + Handler: _Query_Schedules_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "terra/cron/v1/query.proto", +} + +func (m *QueryParamsRequest) 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 *QueryParamsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryParamsResponse) 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 *QueryParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.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 (m *QueryScheduleRequest) 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 *QueryScheduleRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryScheduleRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryScheduleResponse) 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 *QueryScheduleResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryScheduleResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Schedule.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 (m *QuerySchedulesRequest) 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 *QuerySchedulesRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QuerySchedulesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.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 (m *QuerySchedulesResponse) 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 *QuerySchedulesResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QuerySchedulesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Schedules) > 0 { + for iNdEx := len(m.Schedules) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Schedules[iNdEx].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 *QueryParamsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryScheduleRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryScheduleResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Schedule.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QuerySchedulesRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QuerySchedulesResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Schedules) > 0 { + for _, e := range m.Schedules { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.Pagination != nil { + l = m.Pagination.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 *QueryParamsRequest) 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: QueryParamsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + 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 *QueryParamsResponse) 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: QueryParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsResponse: 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 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.Params.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 (m *QueryScheduleRequest) 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: QueryScheduleRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryScheduleRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", 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.Name = 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 *QueryScheduleResponse) 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: QueryScheduleResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryScheduleResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Schedule", 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.Schedule.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 (m *QuerySchedulesRequest) 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: QuerySchedulesRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySchedulesRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", 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 m.Pagination == nil { + m.Pagination = &query.PageRequest{} + } + if err := m.Pagination.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 (m *QuerySchedulesResponse) 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: QuerySchedulesResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySchedulesResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Schedules", 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 + } + m.Schedules = append(m.Schedules, Schedule{}) + if err := m.Schedules[len(m.Schedules)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", 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 m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.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/cron/types/query.pb.gw.go b/x/cron/types/query.pb.gw.go new file mode 100644 index 000000000..3816dc516 --- /dev/null +++ b/x/cron/types/query.pb.gw.go @@ -0,0 +1,337 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: terra/cron/v1/query.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage +var _ = metadata.Join + +func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := client.Params(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := server.Params(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_Schedule_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryScheduleRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := client.Schedule(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Schedule_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryScheduleRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := server.Schedule(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Query_Schedules_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Query_Schedules_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySchedulesRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Schedules_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.Schedules(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Schedules_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySchedulesRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Schedules_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.Schedules(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterQueryHandlerServer registers the http handlers for service Query to "mux". +// UnaryRPC :call QueryServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { + + mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_Params_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_Schedule_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_Schedule_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Schedule_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_Schedules_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_Schedules_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Schedules_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_Params_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_Params_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_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_Schedule_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_Schedule_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_Schedule_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_Schedules_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_Schedules_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_Schedules_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"terra", "cron", "v1", "params"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_Schedule_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"terra", "cron", "v1", "schedules", "name"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_Schedules_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"terra", "cron", "v1", "schedules"}, "", runtime.AssumeColonVerbOpt(false))) +) + +var ( + forward_Query_Params_0 = runtime.ForwardResponseMessage + + forward_Query_Schedule_0 = runtime.ForwardResponseMessage + + forward_Query_Schedules_0 = runtime.ForwardResponseMessage +) diff --git a/x/cron/types/schedule.pb.go b/x/cron/types/schedule.pb.go new file mode 100644 index 000000000..543ab6915 --- /dev/null +++ b/x/cron/types/schedule.pb.go @@ -0,0 +1,899 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: terra/cron/v1/schedule.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type ExecutionStage int32 + +const ( + ExecutionStage_EXECUTION_STAGE_END_BLOCKER ExecutionStage = 0 + ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER ExecutionStage = 1 +) + +var ExecutionStage_name = map[int32]string{ + 0: "EXECUTION_STAGE_END_BLOCKER", + 1: "EXECUTION_STAGE_BEGIN_BLOCKER", +} + +var ExecutionStage_value = map[string]int32{ + "EXECUTION_STAGE_END_BLOCKER": 0, + "EXECUTION_STAGE_BEGIN_BLOCKER": 1, +} + +func (x ExecutionStage) String() string { + return proto.EnumName(ExecutionStage_name, int32(x)) +} + +func (ExecutionStage) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_27c1282684f054b4, []int{0} +} + +type Schedule struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Period uint64 `protobuf:"varint,2,opt,name=period,proto3" json:"period,omitempty"` + Msgs []MsgExecuteContract `protobuf:"bytes,3,rep,name=msgs,proto3" json:"msgs"` + LastExecuteHeight uint64 `protobuf:"varint,4,opt,name=last_execute_height,json=lastExecuteHeight,proto3" json:"last_execute_height,omitempty"` + ExecutionStage ExecutionStage `protobuf:"varint,5,opt,name=execution_stage,json=executionStage,proto3,enum=terra.cron.v1.ExecutionStage" json:"execution_stage,omitempty"` +} + +func (m *Schedule) Reset() { *m = Schedule{} } +func (m *Schedule) String() string { return proto.CompactTextString(m) } +func (*Schedule) ProtoMessage() {} +func (*Schedule) Descriptor() ([]byte, []int) { + return fileDescriptor_27c1282684f054b4, []int{0} +} +func (m *Schedule) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Schedule) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Schedule.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 *Schedule) XXX_Merge(src proto.Message) { + xxx_messageInfo_Schedule.Merge(m, src) +} +func (m *Schedule) XXX_Size() int { + return m.Size() +} +func (m *Schedule) XXX_DiscardUnknown() { + xxx_messageInfo_Schedule.DiscardUnknown(m) +} + +var xxx_messageInfo_Schedule proto.InternalMessageInfo + +func (m *Schedule) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Schedule) GetPeriod() uint64 { + if m != nil { + return m.Period + } + return 0 +} + +func (m *Schedule) GetMsgs() []MsgExecuteContract { + if m != nil { + return m.Msgs + } + return nil +} + +func (m *Schedule) GetLastExecuteHeight() uint64 { + if m != nil { + return m.LastExecuteHeight + } + return 0 +} + +func (m *Schedule) GetExecutionStage() ExecutionStage { + if m != nil { + return m.ExecutionStage + } + return ExecutionStage_EXECUTION_STAGE_END_BLOCKER +} + +type MsgExecuteContract struct { + Contract string `protobuf:"bytes,1,opt,name=contract,proto3" json:"contract,omitempty"` + Msg string `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"` +} + +func (m *MsgExecuteContract) Reset() { *m = MsgExecuteContract{} } +func (m *MsgExecuteContract) String() string { return proto.CompactTextString(m) } +func (*MsgExecuteContract) ProtoMessage() {} +func (*MsgExecuteContract) Descriptor() ([]byte, []int) { + return fileDescriptor_27c1282684f054b4, []int{1} +} +func (m *MsgExecuteContract) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgExecuteContract) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgExecuteContract.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 *MsgExecuteContract) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgExecuteContract.Merge(m, src) +} +func (m *MsgExecuteContract) XXX_Size() int { + return m.Size() +} +func (m *MsgExecuteContract) XXX_DiscardUnknown() { + xxx_messageInfo_MsgExecuteContract.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgExecuteContract proto.InternalMessageInfo + +func (m *MsgExecuteContract) GetContract() string { + if m != nil { + return m.Contract + } + return "" +} + +func (m *MsgExecuteContract) GetMsg() string { + if m != nil { + return m.Msg + } + return "" +} + +type ScheduleCount struct { + Count int32 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"` +} + +func (m *ScheduleCount) Reset() { *m = ScheduleCount{} } +func (m *ScheduleCount) String() string { return proto.CompactTextString(m) } +func (*ScheduleCount) ProtoMessage() {} +func (*ScheduleCount) Descriptor() ([]byte, []int) { + return fileDescriptor_27c1282684f054b4, []int{2} +} +func (m *ScheduleCount) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ScheduleCount) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ScheduleCount.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 *ScheduleCount) XXX_Merge(src proto.Message) { + xxx_messageInfo_ScheduleCount.Merge(m, src) +} +func (m *ScheduleCount) XXX_Size() int { + return m.Size() +} +func (m *ScheduleCount) XXX_DiscardUnknown() { + xxx_messageInfo_ScheduleCount.DiscardUnknown(m) +} + +var xxx_messageInfo_ScheduleCount proto.InternalMessageInfo + +func (m *ScheduleCount) GetCount() int32 { + if m != nil { + return m.Count + } + return 0 +} + +func init() { + proto.RegisterEnum("terra.cron.v1.ExecutionStage", ExecutionStage_name, ExecutionStage_value) + proto.RegisterType((*Schedule)(nil), "terra.cron.v1.Schedule") + proto.RegisterType((*MsgExecuteContract)(nil), "terra.cron.v1.MsgExecuteContract") + proto.RegisterType((*ScheduleCount)(nil), "terra.cron.v1.ScheduleCount") +} + +func init() { proto.RegisterFile("terra/cron/v1/schedule.proto", fileDescriptor_27c1282684f054b4) } + +var fileDescriptor_27c1282684f054b4 = []byte{ + // 403 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x92, 0x41, 0x8b, 0xd3, 0x40, + 0x1c, 0xc5, 0x33, 0x36, 0x5d, 0x76, 0x47, 0xb6, 0xae, 0xe3, 0x22, 0x61, 0x75, 0xb3, 0xd9, 0x82, + 0x10, 0x84, 0x26, 0xb4, 0x7a, 0xf3, 0x64, 0xe2, 0x58, 0x8b, 0xda, 0x42, 0x5a, 0x41, 0xbc, 0x84, + 0x74, 0x3a, 0x4c, 0x02, 0x4d, 0xa6, 0x64, 0x26, 0xa5, 0x7e, 0x0b, 0x3f, 0x56, 0x8f, 0x3d, 0x7a, + 0x12, 0x69, 0x8f, 0x7e, 0x09, 0xc9, 0x24, 0x2d, 0xb4, 0x7b, 0x7b, 0x8f, 0xf7, 0x7b, 0xfc, 0xe7, + 0x9f, 0xfc, 0xe1, 0x4b, 0x49, 0xf3, 0x3c, 0x72, 0x49, 0xce, 0x33, 0x77, 0xd9, 0x75, 0x05, 0x89, + 0xe9, 0xac, 0x98, 0x53, 0x67, 0x91, 0x73, 0xc9, 0xd1, 0xa5, 0x4a, 0x9d, 0x32, 0x75, 0x96, 0xdd, + 0x9b, 0x6b, 0xc6, 0x19, 0x57, 0x89, 0x5b, 0xaa, 0x0a, 0x6a, 0xff, 0x03, 0xf0, 0x7c, 0x5c, 0xf7, + 0x10, 0x82, 0x7a, 0x16, 0xa5, 0xd4, 0x00, 0x16, 0xb0, 0x2f, 0x02, 0xa5, 0xd1, 0x73, 0x78, 0xb6, + 0xa0, 0x79, 0xc2, 0x67, 0xc6, 0x23, 0x0b, 0xd8, 0x7a, 0x50, 0x3b, 0xf4, 0x0e, 0xea, 0xa9, 0x60, + 0xc2, 0x68, 0x58, 0x0d, 0xfb, 0x71, 0xef, 0xde, 0x39, 0x1a, 0xe6, 0x7c, 0x15, 0x0c, 0xaf, 0x28, + 0x29, 0x24, 0xf5, 0x79, 0x26, 0xf3, 0x88, 0x48, 0x4f, 0x5f, 0xff, 0xb9, 0xd3, 0x02, 0x55, 0x42, + 0x0e, 0x7c, 0x36, 0x8f, 0x84, 0x0c, 0x69, 0xc5, 0x84, 0x31, 0x4d, 0x58, 0x2c, 0x0d, 0x5d, 0x4d, + 0x78, 0x5a, 0x46, 0x75, 0xfb, 0x93, 0x0a, 0xd0, 0x47, 0xf8, 0xa4, 0x42, 0x13, 0x9e, 0x85, 0x42, + 0x46, 0x8c, 0x1a, 0x4d, 0x0b, 0xd8, 0xad, 0xde, 0xed, 0xc9, 0x5c, 0xbc, 0xa7, 0xc6, 0x25, 0x14, + 0xb4, 0xe8, 0x91, 0x6f, 0x7b, 0x10, 0x3d, 0x7c, 0x19, 0xba, 0x81, 0xe7, 0xa4, 0xd6, 0xf5, 0xea, + 0x07, 0x8f, 0xae, 0x60, 0x23, 0x15, 0x4c, 0xed, 0x7e, 0x11, 0x94, 0xb2, 0xfd, 0x0a, 0x5e, 0xee, + 0x3f, 0x98, 0xcf, 0x8b, 0x4c, 0xa2, 0x6b, 0xd8, 0x24, 0xa5, 0x50, 0xdd, 0x66, 0x50, 0x99, 0xd7, + 0x13, 0xd8, 0x3a, 0x7e, 0x0c, 0xba, 0x83, 0x2f, 0xf0, 0x77, 0xec, 0x7f, 0x9b, 0x0c, 0x46, 0xc3, + 0x70, 0x3c, 0x79, 0xdf, 0xc7, 0x21, 0x1e, 0x7e, 0x08, 0xbd, 0x2f, 0x23, 0xff, 0x33, 0x0e, 0xae, + 0x34, 0x74, 0x0f, 0x6f, 0x4f, 0x01, 0x0f, 0xf7, 0x07, 0xc3, 0x03, 0x02, 0xbc, 0xfe, 0x7a, 0x6b, + 0x82, 0xcd, 0xd6, 0x04, 0x7f, 0xb7, 0x26, 0xf8, 0xb5, 0x33, 0xb5, 0xcd, 0xce, 0xd4, 0x7e, 0xef, + 0x4c, 0xed, 0x47, 0x87, 0x25, 0x32, 0x2e, 0xa6, 0x0e, 0xe1, 0xa9, 0x4b, 0xe6, 0x91, 0x10, 0x09, + 0xe9, 0xd4, 0xe7, 0xc1, 0x73, 0xea, 0x2e, 0xdf, 0xba, 0xab, 0xea, 0x50, 0xe4, 0xcf, 0x05, 0x15, + 0xd3, 0x33, 0xf5, 0xfb, 0xdf, 0xfc, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x4c, 0x9a, 0xf1, 0xed, 0x43, + 0x02, 0x00, 0x00, +} + +func (m *Schedule) 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 *Schedule) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Schedule) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ExecutionStage != 0 { + i = encodeVarintSchedule(dAtA, i, uint64(m.ExecutionStage)) + i-- + dAtA[i] = 0x28 + } + if m.LastExecuteHeight != 0 { + i = encodeVarintSchedule(dAtA, i, uint64(m.LastExecuteHeight)) + i-- + dAtA[i] = 0x20 + } + if len(m.Msgs) > 0 { + for iNdEx := len(m.Msgs) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Msgs[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSchedule(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if m.Period != 0 { + i = encodeVarintSchedule(dAtA, i, uint64(m.Period)) + i-- + dAtA[i] = 0x10 + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintSchedule(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgExecuteContract) 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 *MsgExecuteContract) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgExecuteContract) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Msg) > 0 { + i -= len(m.Msg) + copy(dAtA[i:], m.Msg) + i = encodeVarintSchedule(dAtA, i, uint64(len(m.Msg))) + i-- + dAtA[i] = 0x12 + } + if len(m.Contract) > 0 { + i -= len(m.Contract) + copy(dAtA[i:], m.Contract) + i = encodeVarintSchedule(dAtA, i, uint64(len(m.Contract))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ScheduleCount) 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 *ScheduleCount) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ScheduleCount) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Count != 0 { + i = encodeVarintSchedule(dAtA, i, uint64(m.Count)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintSchedule(dAtA []byte, offset int, v uint64) int { + offset -= sovSchedule(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Schedule) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovSchedule(uint64(l)) + } + if m.Period != 0 { + n += 1 + sovSchedule(uint64(m.Period)) + } + if len(m.Msgs) > 0 { + for _, e := range m.Msgs { + l = e.Size() + n += 1 + l + sovSchedule(uint64(l)) + } + } + if m.LastExecuteHeight != 0 { + n += 1 + sovSchedule(uint64(m.LastExecuteHeight)) + } + if m.ExecutionStage != 0 { + n += 1 + sovSchedule(uint64(m.ExecutionStage)) + } + return n +} + +func (m *MsgExecuteContract) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Contract) + if l > 0 { + n += 1 + l + sovSchedule(uint64(l)) + } + l = len(m.Msg) + if l > 0 { + n += 1 + l + sovSchedule(uint64(l)) + } + return n +} + +func (m *ScheduleCount) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Count != 0 { + n += 1 + sovSchedule(uint64(m.Count)) + } + return n +} + +func sovSchedule(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozSchedule(x uint64) (n int) { + return sovSchedule(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Schedule) 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 ErrIntOverflowSchedule + } + 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: Schedule: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Schedule: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSchedule + } + 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 ErrInvalidLengthSchedule + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSchedule + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Period", wireType) + } + m.Period = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSchedule + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Period |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Msgs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSchedule + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSchedule + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSchedule + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Msgs = append(m.Msgs, MsgExecuteContract{}) + if err := m.Msgs[len(m.Msgs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LastExecuteHeight", wireType) + } + m.LastExecuteHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSchedule + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.LastExecuteHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ExecutionStage", wireType) + } + m.ExecutionStage = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSchedule + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ExecutionStage |= ExecutionStage(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipSchedule(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSchedule + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgExecuteContract) 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 ErrIntOverflowSchedule + } + 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: MsgExecuteContract: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgExecuteContract: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Contract", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSchedule + } + 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 ErrInvalidLengthSchedule + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSchedule + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Contract = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Msg", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSchedule + } + 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 ErrInvalidLengthSchedule + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSchedule + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Msg = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSchedule(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSchedule + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ScheduleCount) 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 ErrIntOverflowSchedule + } + 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: ScheduleCount: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ScheduleCount: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Count", wireType) + } + m.Count = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSchedule + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Count |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipSchedule(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSchedule + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipSchedule(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, ErrIntOverflowSchedule + } + 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, ErrIntOverflowSchedule + } + 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, ErrIntOverflowSchedule + } + 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, ErrInvalidLengthSchedule + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupSchedule + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthSchedule + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthSchedule = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowSchedule = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupSchedule = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/cron/types/tx.go b/x/cron/types/tx.go new file mode 100644 index 000000000..5e40276f5 --- /dev/null +++ b/x/cron/types/tx.go @@ -0,0 +1,107 @@ +package types + +import ( + "encoding/json" + + "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +var _ sdk.Msg = &MsgAddSchedule{} + +func (msg *MsgAddSchedule) Route() string { return RouterKey } + +func (msg *MsgAddSchedule) Type() string { return "add-schedule" } + +func (msg *MsgAddSchedule) GetSigners() []sdk.AccAddress { + authority, err := sdk.AccAddressFromBech32(msg.Authority) + if err != nil { + panic(err.Error()) + } + return []sdk.AccAddress{authority} +} + +func (msg *MsgAddSchedule) GetSignBytes() []byte { + return ModuleCdc.MustMarshalJSON(msg) +} + +func (msg *MsgAddSchedule) Validate() error { + if err := validateAuthority(msg.Authority); err != nil { + return err + } + if msg.Name == "" { + return errors.Wrap(sdkerrors.ErrInvalidRequest, "name is invalid") + } + if msg.Period == 0 { + return errors.Wrap(sdkerrors.ErrInvalidRequest, "period is invalid") + } + if len(msg.Msgs) == 0 { + return errors.Wrap(sdkerrors.ErrInvalidRequest, "msgs should not be empty") + } + if _, ok := ExecutionStage_name[int32(msg.ExecutionStage)]; !ok { + return errors.Wrap(sdkerrors.ErrInvalidRequest, "execution stage is invalid") + } + for _, execMsg := range msg.Msgs { + if err := validateMsgExecuteContract(execMsg); err != nil { + return errors.Wrap(err, "invalid execute contract msg") + } + if !json.Valid([]byte(execMsg.Msg)) { + return errors.Wrap(sdkerrors.ErrInvalidRequest, "msg is not valid json") + } + } + return nil +} + +var _ sdk.Msg = &MsgRemoveSchedule{} + +func (msg *MsgRemoveSchedule) Route() string { return RouterKey } + +func (msg *MsgRemoveSchedule) Type() string { return "remove-schedule" } + +func (msg *MsgRemoveSchedule) GetSigners() []sdk.AccAddress { + authority, err := sdk.AccAddressFromBech32(msg.Authority) + if err != nil { + panic(err.Error()) + } + return []sdk.AccAddress{authority} +} + +func (msg *MsgRemoveSchedule) GetSignBytes() []byte { + return ModuleCdc.MustMarshalJSON(msg) +} + +func (msg *MsgRemoveSchedule) Validate() error { + if err := validateAuthority(msg.Authority); err != nil { + return err + } + if msg.Name == "" { + return errors.Wrap(sdkerrors.ErrInvalidRequest, "name is invalid") + } + return nil +} + +var _ sdk.Msg = &MsgUpdateParams{} + +func (msg *MsgUpdateParams) Route() string { return RouterKey } + +func (msg *MsgUpdateParams) Type() string { return "update-params" } + +func (msg *MsgUpdateParams) GetSigners() []sdk.AccAddress { + authority, err := sdk.AccAddressFromBech32(msg.Authority) + if err != nil { + panic(err.Error()) + } + return []sdk.AccAddress{authority} +} + +func (msg *MsgUpdateParams) GetSignBytes() []byte { + return ModuleCdc.MustMarshalJSON(msg) +} + +func (msg *MsgUpdateParams) Validate() error { + if err := validateAuthority(msg.Authority); err != nil { + return err + } + return msg.Params.Validate() +} diff --git a/x/cron/types/tx.pb.go b/x/cron/types/tx.pb.go new file mode 100644 index 000000000..4fa570856 --- /dev/null +++ b/x/cron/types/tx.pb.go @@ -0,0 +1,1485 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: terra/cron/v1/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + _ "github.com/cosmos/cosmos-sdk/types/msgservice" + _ "github.com/cosmos/cosmos-sdk/types/tx/amino" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type MsgAddSchedule struct { + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Period uint64 `protobuf:"varint,3,opt,name=period,proto3" json:"period,omitempty"` + Msgs []MsgExecuteContract `protobuf:"bytes,4,rep,name=msgs,proto3" json:"msgs"` + ExecutionStage ExecutionStage `protobuf:"varint,5,opt,name=execution_stage,json=executionStage,proto3,enum=terra.cron.v1.ExecutionStage" json:"execution_stage,omitempty"` +} + +func (m *MsgAddSchedule) Reset() { *m = MsgAddSchedule{} } +func (m *MsgAddSchedule) String() string { return proto.CompactTextString(m) } +func (*MsgAddSchedule) ProtoMessage() {} +func (*MsgAddSchedule) Descriptor() ([]byte, []int) { + return fileDescriptor_889293b94ebd8bf7, []int{0} +} +func (m *MsgAddSchedule) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgAddSchedule) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgAddSchedule.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 *MsgAddSchedule) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgAddSchedule.Merge(m, src) +} +func (m *MsgAddSchedule) XXX_Size() int { + return m.Size() +} +func (m *MsgAddSchedule) XXX_DiscardUnknown() { + xxx_messageInfo_MsgAddSchedule.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgAddSchedule proto.InternalMessageInfo + +func (m *MsgAddSchedule) GetAuthority() string { + if m != nil { + return m.Authority + } + return "" +} + +func (m *MsgAddSchedule) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *MsgAddSchedule) GetPeriod() uint64 { + if m != nil { + return m.Period + } + return 0 +} + +func (m *MsgAddSchedule) GetMsgs() []MsgExecuteContract { + if m != nil { + return m.Msgs + } + return nil +} + +func (m *MsgAddSchedule) GetExecutionStage() ExecutionStage { + if m != nil { + return m.ExecutionStage + } + return ExecutionStage_EXECUTION_STAGE_END_BLOCKER +} + +type MsgAddScheduleResponse struct { +} + +func (m *MsgAddScheduleResponse) Reset() { *m = MsgAddScheduleResponse{} } +func (m *MsgAddScheduleResponse) String() string { return proto.CompactTextString(m) } +func (*MsgAddScheduleResponse) ProtoMessage() {} +func (*MsgAddScheduleResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_889293b94ebd8bf7, []int{1} +} +func (m *MsgAddScheduleResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgAddScheduleResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgAddScheduleResponse.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 *MsgAddScheduleResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgAddScheduleResponse.Merge(m, src) +} +func (m *MsgAddScheduleResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgAddScheduleResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgAddScheduleResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgAddScheduleResponse proto.InternalMessageInfo + +type MsgRemoveSchedule struct { + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` +} + +func (m *MsgRemoveSchedule) Reset() { *m = MsgRemoveSchedule{} } +func (m *MsgRemoveSchedule) String() string { return proto.CompactTextString(m) } +func (*MsgRemoveSchedule) ProtoMessage() {} +func (*MsgRemoveSchedule) Descriptor() ([]byte, []int) { + return fileDescriptor_889293b94ebd8bf7, []int{2} +} +func (m *MsgRemoveSchedule) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgRemoveSchedule) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgRemoveSchedule.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 *MsgRemoveSchedule) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgRemoveSchedule.Merge(m, src) +} +func (m *MsgRemoveSchedule) XXX_Size() int { + return m.Size() +} +func (m *MsgRemoveSchedule) XXX_DiscardUnknown() { + xxx_messageInfo_MsgRemoveSchedule.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgRemoveSchedule proto.InternalMessageInfo + +func (m *MsgRemoveSchedule) GetAuthority() string { + if m != nil { + return m.Authority + } + return "" +} + +func (m *MsgRemoveSchedule) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +type MsgRemoveScheduleResponse struct { +} + +func (m *MsgRemoveScheduleResponse) Reset() { *m = MsgRemoveScheduleResponse{} } +func (m *MsgRemoveScheduleResponse) String() string { return proto.CompactTextString(m) } +func (*MsgRemoveScheduleResponse) ProtoMessage() {} +func (*MsgRemoveScheduleResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_889293b94ebd8bf7, []int{3} +} +func (m *MsgRemoveScheduleResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgRemoveScheduleResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgRemoveScheduleResponse.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 *MsgRemoveScheduleResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgRemoveScheduleResponse.Merge(m, src) +} +func (m *MsgRemoveScheduleResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgRemoveScheduleResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgRemoveScheduleResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgRemoveScheduleResponse proto.InternalMessageInfo + +type MsgUpdateParams struct { + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` + Params Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params"` +} + +func (m *MsgUpdateParams) Reset() { *m = MsgUpdateParams{} } +func (m *MsgUpdateParams) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateParams) ProtoMessage() {} +func (*MsgUpdateParams) Descriptor() ([]byte, []int) { + return fileDescriptor_889293b94ebd8bf7, []int{4} +} +func (m *MsgUpdateParams) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateParams.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 *MsgUpdateParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateParams.Merge(m, src) +} +func (m *MsgUpdateParams) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateParams) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateParams.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateParams proto.InternalMessageInfo + +func (m *MsgUpdateParams) GetAuthority() string { + if m != nil { + return m.Authority + } + return "" +} + +func (m *MsgUpdateParams) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +type MsgUpdateParamsResponse struct { +} + +func (m *MsgUpdateParamsResponse) Reset() { *m = MsgUpdateParamsResponse{} } +func (m *MsgUpdateParamsResponse) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateParamsResponse) ProtoMessage() {} +func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_889293b94ebd8bf7, []int{5} +} +func (m *MsgUpdateParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateParamsResponse.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 *MsgUpdateParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateParamsResponse.Merge(m, src) +} +func (m *MsgUpdateParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateParamsResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*MsgAddSchedule)(nil), "terra.cron.v1.MsgAddSchedule") + proto.RegisterType((*MsgAddScheduleResponse)(nil), "terra.cron.v1.MsgAddScheduleResponse") + proto.RegisterType((*MsgRemoveSchedule)(nil), "terra.cron.v1.MsgRemoveSchedule") + proto.RegisterType((*MsgRemoveScheduleResponse)(nil), "terra.cron.v1.MsgRemoveScheduleResponse") + proto.RegisterType((*MsgUpdateParams)(nil), "terra.cron.v1.MsgUpdateParams") + proto.RegisterType((*MsgUpdateParamsResponse)(nil), "terra.cron.v1.MsgUpdateParamsResponse") +} + +func init() { proto.RegisterFile("terra/cron/v1/tx.proto", fileDescriptor_889293b94ebd8bf7) } + +var fileDescriptor_889293b94ebd8bf7 = []byte{ + // 566 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0x41, 0x8b, 0xd3, 0x40, + 0x14, 0x6e, 0xb6, 0xdd, 0x42, 0xa7, 0xda, 0x65, 0x63, 0xed, 0xa6, 0xd1, 0x8d, 0xb5, 0xe0, 0x5a, + 0x0b, 0x4d, 0xd8, 0x2a, 0x22, 0xf5, 0xb4, 0x95, 0xd5, 0x53, 0x41, 0x52, 0xf4, 0x20, 0xc2, 0x92, + 0x4d, 0x86, 0x69, 0x60, 0x93, 0x09, 0xf3, 0xa6, 0xa5, 0x7b, 0x13, 0x8f, 0x7b, 0xf2, 0xe6, 0xd9, + 0x9b, 0x07, 0x0f, 0x3d, 0xf8, 0x23, 0xf6, 0xb8, 0x78, 0xf2, 0x24, 0xd2, 0x1e, 0xfa, 0x37, 0x24, + 0x93, 0x64, 0xb7, 0x69, 0x60, 0x05, 0xc1, 0x4b, 0x98, 0xf7, 0x7d, 0xdf, 0x7b, 0xf9, 0xde, 0x9b, + 0xc7, 0xa0, 0x1a, 0xc7, 0x8c, 0x59, 0x86, 0xcd, 0xa8, 0x6f, 0x4c, 0xf6, 0x0d, 0x3e, 0xd5, 0x03, + 0x46, 0x39, 0x95, 0x6f, 0x0a, 0x5c, 0x0f, 0x71, 0x7d, 0xb2, 0xaf, 0x6e, 0x5b, 0x9e, 0xeb, 0x53, + 0x43, 0x7c, 0x23, 0x85, 0xba, 0x63, 0x53, 0xf0, 0x28, 0x18, 0x1e, 0x90, 0x30, 0xd3, 0x03, 0x12, + 0x13, 0xf5, 0x88, 0x38, 0x12, 0x91, 0x11, 0x05, 0x31, 0x55, 0x25, 0x94, 0xd0, 0x08, 0x0f, 0x4f, + 0x31, 0xaa, 0xa6, 0x3d, 0x04, 0x16, 0xb3, 0xbc, 0x24, 0xe3, 0x6e, 0x9a, 0x03, 0x7b, 0x84, 0x9d, + 0xf1, 0x09, 0x8e, 0xd8, 0xe6, 0x97, 0x0d, 0x54, 0x19, 0x00, 0x39, 0x70, 0x9c, 0x61, 0x4c, 0xc8, + 0x4f, 0x51, 0xc9, 0x1a, 0xf3, 0x11, 0x65, 0x2e, 0x3f, 0x55, 0xa4, 0x86, 0xd4, 0x2a, 0xf5, 0x95, + 0x1f, 0xdf, 0x3b, 0xd5, 0xd8, 0xc7, 0x81, 0xe3, 0x30, 0x0c, 0x30, 0xe4, 0xcc, 0xf5, 0x89, 0x79, + 0x25, 0x95, 0x65, 0x54, 0xf0, 0x2d, 0x0f, 0x2b, 0x1b, 0x61, 0x8a, 0x29, 0xce, 0x72, 0x0d, 0x15, + 0x03, 0xcc, 0x5c, 0xea, 0x28, 0xf9, 0x86, 0xd4, 0x2a, 0x98, 0x71, 0x24, 0x3f, 0x47, 0x05, 0x0f, + 0x08, 0x28, 0x85, 0x46, 0xbe, 0x55, 0xee, 0xde, 0xd7, 0x53, 0xb3, 0xd2, 0x07, 0x40, 0x0e, 0xa7, + 0xd8, 0x1e, 0x73, 0xfc, 0x82, 0xfa, 0x9c, 0x59, 0x36, 0xef, 0x17, 0xce, 0x7f, 0xdd, 0xcb, 0x99, + 0x22, 0x49, 0x7e, 0x89, 0xb6, 0xb0, 0xa0, 0x5d, 0xea, 0x1f, 0x01, 0xb7, 0x08, 0x56, 0x36, 0x1b, + 0x52, 0xab, 0xd2, 0xdd, 0x5d, 0xab, 0x73, 0x98, 0xa8, 0x86, 0xa1, 0xc8, 0xac, 0xe0, 0x54, 0xdc, + 0xdb, 0xfb, 0xb8, 0x9c, 0xb5, 0xaf, 0x1a, 0x38, 0x5b, 0xce, 0xda, 0xb7, 0xc4, 0x98, 0xd2, 0x03, + 0x69, 0x2a, 0xa8, 0x96, 0x46, 0x4c, 0x0c, 0x01, 0xf5, 0x01, 0x37, 0xcf, 0x24, 0xb4, 0x3d, 0x00, + 0x62, 0x62, 0x8f, 0x4e, 0xf0, 0xff, 0x18, 0x60, 0xef, 0x51, 0xd6, 0x63, 0x2d, 0xf1, 0x98, 0xfe, + 0x6d, 0xf3, 0x0e, 0xaa, 0x67, 0xc0, 0x4b, 0xa7, 0xdf, 0x24, 0xb4, 0x35, 0x00, 0xf2, 0x26, 0x70, + 0x2c, 0x8e, 0x5f, 0x8b, 0xfd, 0xf8, 0x67, 0x9f, 0xcf, 0x50, 0x31, 0xda, 0x30, 0xe1, 0xb4, 0xdc, + 0xbd, 0xbd, 0x36, 0xf6, 0xa8, 0x7c, 0xbf, 0x14, 0x5e, 0xd9, 0xd7, 0xe5, 0xac, 0x2d, 0x99, 0xb1, + 0xbe, 0xf7, 0x30, 0xdb, 0x4d, 0x35, 0xe9, 0x66, 0xd5, 0x5a, 0xb3, 0x8e, 0x76, 0xd6, 0xa0, 0xa4, + 0x93, 0xee, 0xe7, 0x0d, 0x94, 0x1f, 0x00, 0x91, 0x87, 0xa8, 0xbc, 0xba, 0xb5, 0xbb, 0xd9, 0x1d, + 0x5a, 0xa1, 0xd5, 0x07, 0xd7, 0xd2, 0x49, 0x71, 0xf9, 0x3d, 0xaa, 0xac, 0x5d, 0x66, 0x23, 0x9b, + 0x98, 0x56, 0xa8, 0xad, 0xbf, 0x29, 0x2e, 0xab, 0xbf, 0x45, 0x37, 0x52, 0x17, 0xa0, 0x65, 0x33, + 0x57, 0x79, 0x75, 0xef, 0x7a, 0x3e, 0xa9, 0xab, 0x6e, 0x7e, 0x08, 0xa7, 0xdc, 0x7f, 0x75, 0x3e, + 0xd7, 0xa4, 0x8b, 0xb9, 0x26, 0xfd, 0x9e, 0x6b, 0xd2, 0xa7, 0x85, 0x96, 0xbb, 0x58, 0x68, 0xb9, + 0x9f, 0x0b, 0x2d, 0xf7, 0xae, 0x43, 0x5c, 0x3e, 0x1a, 0x1f, 0xeb, 0x36, 0xf5, 0x0c, 0xfb, 0xc4, + 0x02, 0x70, 0xed, 0x4e, 0xfc, 0x2c, 0x50, 0x86, 0x8d, 0xc9, 0x13, 0x63, 0x1a, 0x3d, 0x10, 0xfc, + 0x34, 0xc0, 0x70, 0x5c, 0x14, 0x6f, 0xc3, 0xe3, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x17, 0x95, + 0x11, 0xdf, 0xdb, 0x04, 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 { + AddSchedule(ctx context.Context, in *MsgAddSchedule, opts ...grpc.CallOption) (*MsgAddScheduleResponse, error) + RemoveSchedule(ctx context.Context, in *MsgRemoveSchedule, opts ...grpc.CallOption) (*MsgRemoveScheduleResponse, error) + UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) AddSchedule(ctx context.Context, in *MsgAddSchedule, opts ...grpc.CallOption) (*MsgAddScheduleResponse, error) { + out := new(MsgAddScheduleResponse) + err := c.cc.Invoke(ctx, "/terra.cron.v1.Msg/AddSchedule", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) RemoveSchedule(ctx context.Context, in *MsgRemoveSchedule, opts ...grpc.CallOption) (*MsgRemoveScheduleResponse, error) { + out := new(MsgRemoveScheduleResponse) + err := c.cc.Invoke(ctx, "/terra.cron.v1.Msg/RemoveSchedule", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) { + out := new(MsgUpdateParamsResponse) + err := c.cc.Invoke(ctx, "/terra.cron.v1.Msg/UpdateParams", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { + AddSchedule(context.Context, *MsgAddSchedule) (*MsgAddScheduleResponse, error) + RemoveSchedule(context.Context, *MsgRemoveSchedule) (*MsgRemoveScheduleResponse, error) + UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (*UnimplementedMsgServer) AddSchedule(ctx context.Context, req *MsgAddSchedule) (*MsgAddScheduleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AddSchedule not implemented") +} +func (*UnimplementedMsgServer) RemoveSchedule(ctx context.Context, req *MsgRemoveSchedule) (*MsgRemoveScheduleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RemoveSchedule not implemented") +} +func (*UnimplementedMsgServer) UpdateParams(ctx context.Context, req *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented") +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +func _Msg_AddSchedule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgAddSchedule) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).AddSchedule(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/terra.cron.v1.Msg/AddSchedule", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).AddSchedule(ctx, req.(*MsgAddSchedule)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_RemoveSchedule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgRemoveSchedule) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).RemoveSchedule(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/terra.cron.v1.Msg/RemoveSchedule", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).RemoveSchedule(ctx, req.(*MsgRemoveSchedule)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdateParams) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UpdateParams(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/terra.cron.v1.Msg/UpdateParams", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UpdateParams(ctx, req.(*MsgUpdateParams)) + } + return interceptor(ctx, in, info, handler) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "terra.cron.v1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "AddSchedule", + Handler: _Msg_AddSchedule_Handler, + }, + { + MethodName: "RemoveSchedule", + Handler: _Msg_RemoveSchedule_Handler, + }, + { + MethodName: "UpdateParams", + Handler: _Msg_UpdateParams_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "terra/cron/v1/tx.proto", +} + +func (m *MsgAddSchedule) 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 *MsgAddSchedule) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgAddSchedule) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ExecutionStage != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.ExecutionStage)) + i-- + dAtA[i] = 0x28 + } + if len(m.Msgs) > 0 { + for iNdEx := len(m.Msgs) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Msgs[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if m.Period != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Period)) + i-- + dAtA[i] = 0x18 + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintTx(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x12 + } + if len(m.Authority) > 0 { + i -= len(m.Authority) + copy(dAtA[i:], m.Authority) + i = encodeVarintTx(dAtA, i, uint64(len(m.Authority))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgAddScheduleResponse) 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 *MsgAddScheduleResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgAddScheduleResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgRemoveSchedule) 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 *MsgRemoveSchedule) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgRemoveSchedule) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintTx(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x12 + } + if len(m.Authority) > 0 { + i -= len(m.Authority) + copy(dAtA[i:], m.Authority) + i = encodeVarintTx(dAtA, i, uint64(len(m.Authority))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgRemoveScheduleResponse) 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 *MsgRemoveScheduleResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgRemoveScheduleResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgUpdateParams) 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 *MsgUpdateParams) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.Authority) > 0 { + i -= len(m.Authority) + copy(dAtA[i:], m.Authority) + i = encodeVarintTx(dAtA, i, uint64(len(m.Authority))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgUpdateParamsResponse) 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 *MsgUpdateParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintTx(dAtA []byte, offset int, v uint64) int { + offset -= sovTx(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgAddSchedule) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Authority) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Name) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.Period != 0 { + n += 1 + sovTx(uint64(m.Period)) + } + if len(m.Msgs) > 0 { + for _, e := range m.Msgs { + l = e.Size() + n += 1 + l + sovTx(uint64(l)) + } + } + if m.ExecutionStage != 0 { + n += 1 + sovTx(uint64(m.ExecutionStage)) + } + return n +} + +func (m *MsgAddScheduleResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgRemoveSchedule) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Authority) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Name) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgRemoveScheduleResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgUpdateParams) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Authority) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.Params.Size() + n += 1 + l + sovTx(uint64(l)) + return n +} + +func (m *MsgUpdateParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovTx(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTx(x uint64) (n int) { + return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *MsgAddSchedule) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgAddSchedule: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgAddSchedule: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Period", wireType) + } + m.Period = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Period |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Msgs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Msgs = append(m.Msgs, MsgExecuteContract{}) + if err := m.Msgs[len(m.Msgs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ExecutionStage", wireType) + } + m.ExecutionStage = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ExecutionStage |= ExecutionStage(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgAddScheduleResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgAddScheduleResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgAddScheduleResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgRemoveSchedule) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgRemoveSchedule: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgRemoveSchedule: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgRemoveScheduleResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgRemoveScheduleResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgRemoveScheduleResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateParams) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgUpdateParams: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateParams: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + 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 ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateParamsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgUpdateParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTx(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthTx + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTx + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTx + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTx = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTx = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTx = fmt.Errorf("proto: unexpected end of group") +) From 66e67577f609c3c80be03674255fdd500306f9b2 Mon Sep 17 00:00:00 2001 From: ZuluSpl0it Date: Wed, 13 May 2026 09:49:01 -0500 Subject: [PATCH 2/5] feat: update cron module behavior --- .gitignore | 3 +- app/keepers/keepers.go | 1 - proto/terra/cron/v1/params.proto | 1 + proto/terra/cron/v1/schedule.proto | 2 + x/cron/keeper/keeper.go | 46 ++++++++- x/cron/keeper/keeper_test.go | 126 ++++++++++++++++++++++++ x/cron/keeper/params.go | 7 ++ x/cron/keeper/test_utils_test.go | 22 ++++- x/cron/spec/01_concepts.md | 13 ++- x/cron/spec/02_state.md | 11 ++- x/cron/spec/03_block_lifecycle.md | 15 ++- x/cron/spec/04_messages.md | 1 + x/cron/spec/05_events.md | 4 +- x/cron/spec/06_params.md | 13 ++- x/cron/types/params.go | 28 +++++- x/cron/types/params.pb.go | 57 +++++++++-- x/cron/types/query.pb.go | 66 ++++++------- x/cron/types/schedule.pb.go | 152 +++++++++++++++++++++++------ 18 files changed, 468 insertions(+), 100 deletions(-) diff --git a/.gitignore b/.gitignore index a7b619726..5d5c378ae 100644 --- a/.gitignore +++ b/.gitignore @@ -56,6 +56,7 @@ dependency-graph.png # AI-assisted tools .claude/ CLAUDE.md +my_doc/ # CI cache (populated during Docker builds) -.cache/ \ No newline at end of file +.cache/ diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index da96aa712..cfeeffc6b 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -548,7 +548,6 @@ func initParamsKeeper( paramsKeeper.Subspace(taxexemptiontypes.ModuleName) paramsKeeper.Subspace(treasurytypes.ModuleName) paramsKeeper.Subspace(wasmtypes.ModuleName) - paramsKeeper.Subspace(crontypes.ModuleName).WithKeyTable(crontypes.ParamKeyTable()) paramsKeeper.Subspace(dyncommtypes.ModuleName) paramsKeeper.Subspace(taxtypes.ModuleName) diff --git a/proto/terra/cron/v1/params.proto b/proto/terra/cron/v1/params.proto index d87b85661..3b26e1495 100644 --- a/proto/terra/cron/v1/params.proto +++ b/proto/terra/cron/v1/params.proto @@ -9,4 +9,5 @@ option go_package = "github.com/classic-terra/core/v4/x/cron/types"; message Params { uint64 limit = 1; + uint64 max_execution_gas = 2; } diff --git a/proto/terra/cron/v1/schedule.proto b/proto/terra/cron/v1/schedule.proto index c373272b1..2c7553a69 100644 --- a/proto/terra/cron/v1/schedule.proto +++ b/proto/terra/cron/v1/schedule.proto @@ -16,6 +16,8 @@ message Schedule { repeated MsgExecuteContract msgs = 3 [(gogoproto.nullable) = false]; uint64 last_execute_height = 4; ExecutionStage execution_stage = 5; + uint64 last_run_height = 6; + string last_execution_error = 7; } message MsgExecuteContract { diff --git a/x/cron/keeper/keeper.go b/x/cron/keeper/keeper.go index dbf8309ba..9b0f5a128 100644 --- a/x/cron/keeper/keeper.go +++ b/x/cron/keeper/keeper.go @@ -144,12 +144,41 @@ func (k Keeper) getSchedulesReadyForExecution(ctx sdk.Context, executionStage ty return res } -func (k Keeper) executeSchedule(ctx sdk.Context, schedule types.Schedule) error { - schedule.LastExecuteHeight = uint64(ctx.BlockHeight()) +func (k Keeper) executeSchedule(ctx sdk.Context, schedule types.Schedule) (err error) { + params := k.GetParams(ctx) + schedule.LastRunHeight = uint64(ctx.BlockHeight()) k.storeSchedule(ctx, schedule) cacheCtx, writeFn := ctx.CacheContext() + limitedCtx := cacheCtx.WithGasMeter(storetypes.NewGasMeter(params.MaxExecutionGas)) + currentContract := "" + lastExecutionErr := func(contract string, err error) string { + if contract == "" { + return err.Error() + } + return fmt.Sprintf("%s: %v", contract, err) + } + + defer func() { + if r := recover(); r != nil { + if oog, ok := r.(storetypes.ErrorOutOfGas); ok { + err = fmt.Errorf("cron execute out of gas: %s", oog.Descriptor) + schedule.LastExecutionError = lastExecutionErr(currentContract, err) + k.storeSchedule(ctx, schedule) + ctx.Logger().Info("cron execute out of gas", + "schedule_name", schedule.Name, + "contract", currentContract, + "max_execution_gas", params.MaxExecutionGas, + "error", err, + ) + return + } + panic(r) + } + }() + for _, msg := range schedule.Msgs { + currentContract = msg.Contract executeMsg := wasmtypes.MsgExecuteContract{ Sender: k.accountKeeper.GetModuleAddress(types.ModuleName).String(), Contract: msg.Contract, @@ -157,7 +186,9 @@ func (k Keeper) executeSchedule(ctx sdk.Context, schedule types.Schedule) error Funds: sdk.NewCoins(), } - if _, err := k.WasmMsgServer.ExecuteContract(cacheCtx, &executeMsg); err != nil { + if _, err := k.WasmMsgServer.ExecuteContract(sdk.WrapSDKContext(limitedCtx), &executeMsg); err != nil { + schedule.LastExecutionError = lastExecutionErr(msg.Contract, err) + k.storeSchedule(ctx, schedule) ctx.Logger().Info("cron execute failed", "schedule_name", schedule.Name, "contract", msg.Contract, @@ -168,6 +199,9 @@ func (k Keeper) executeSchedule(ctx sdk.Context, schedule types.Schedule) error } writeFn() + schedule.LastExecuteHeight = uint64(ctx.BlockHeight()) + schedule.LastExecutionError = "" + k.storeSchedule(ctx, schedule) return nil } @@ -187,7 +221,11 @@ func (k Keeper) scheduleExists(ctx sdk.Context, name string) bool { } func (k Keeper) intervalPassed(ctx sdk.Context, schedule types.Schedule) bool { - return uint64(ctx.BlockHeight()) >= (schedule.LastExecuteHeight + schedule.Period) + lastRunHeight := schedule.LastRunHeight + if lastRunHeight == 0 { + lastRunHeight = schedule.LastExecuteHeight + } + return uint64(ctx.BlockHeight()) >= (lastRunHeight + schedule.Period) } func (k Keeper) changeTotalCount(ctx sdk.Context, incrementAmount int32) { diff --git a/x/cron/keeper/keeper_test.go b/x/cron/keeper/keeper_test.go index 5d167ddda..d9f824297 100644 --- a/x/cron/keeper/keeper_test.go +++ b/x/cron/keeper/keeper_test.go @@ -42,9 +42,127 @@ func TestKeeperExecuteReadySchedules(t *testing.T) { require.Len(t, input.MsgServer.calls, 1) schedule, found := input.Keeper.GetSchedule(ctx, "job-a") require.True(t, found) + require.Equal(t, uint64(5), schedule.LastRunHeight) require.Equal(t, uint64(5), schedule.LastExecuteHeight) } +func TestKeeperExecuteReadySchedules_ExecutionGasLimit(t *testing.T) { + input := createTestInput(t) + ctx := input.Ctx.WithBlockHeight(5) + input.MsgServer.gasToConsume = 11 + + require.NoError(t, input.Keeper.SetParams(ctx, types.Params{Limit: 1, MaxExecutionGas: 10})) + require.NoError(t, input.Keeper.AddSchedule(ctx, "job", 1, []types.MsgExecuteContract{{Contract: "terra1contract", Msg: `{"ping":{}}`}}, 0, types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER)) + + require.NotPanics(t, func() { + input.Keeper.ExecuteReadySchedules(ctx, types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER) + }) + + require.Len(t, input.MsgServer.calls, 1) + require.Equal(t, uint64(10), input.MsgServer.observedGasLimit) +} + +func TestKeeperExecuteReadySchedules_FailedScheduleDoesNotBlockOthers(t *testing.T) { + input := createTestInput(t) + ctx := input.Ctx.WithBlockHeight(8) + input.MsgServer.errByContract = map[string]error{ + "terra1fail": errFailedContract(), + } + + require.NoError(t, input.Keeper.SetParams(ctx, types.NewParams(2))) + require.NoError(t, input.Keeper.AddSchedule(ctx, "job-a", 1, []types.MsgExecuteContract{ + {Contract: "terra1fail", Msg: `{"fail":{}}`}, + {Contract: "terra1ok", Msg: `{"ok":{}}`}, + }, 0, types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER)) + require.NoError(t, input.Keeper.AddSchedule(ctx, "job-b", 1, []types.MsgExecuteContract{ + {Contract: "terra1later", Msg: `{"later":{}}`}, + }, 0, types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER)) + + input.Keeper.ExecuteReadySchedules(ctx, types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER) + + require.Equal(t, []string{"terra1fail", "terra1later"}, calledContracts(input.MsgServer.calls)) + schedule, found := input.Keeper.GetSchedule(ctx, "job-a") + require.True(t, found) + require.Equal(t, uint64(8), schedule.LastRunHeight) + require.Equal(t, uint64(0), schedule.LastExecuteHeight) + require.Contains(t, schedule.LastExecutionError, "terra1fail") + require.Contains(t, schedule.LastExecutionError, "contract execution failed") + + schedule, found = input.Keeper.GetSchedule(ctx, "job-b") + require.True(t, found) + require.Equal(t, uint64(8), schedule.LastRunHeight) + require.Equal(t, uint64(8), schedule.LastExecuteHeight) +} + +func TestKeeperExecuteReadySchedules_FailureOnlyUpdatesRunHeight(t *testing.T) { + input := createTestInput(t) + ctx := input.Ctx.WithBlockHeight(8) + input.MsgServer.errByContract = map[string]error{ + "terra1fail": errFailedContract(), + } + + require.NoError(t, input.Keeper.SetParams(ctx, types.NewParams(1))) + require.NoError(t, input.Keeper.AddSchedule(ctx, "job", 1, []types.MsgExecuteContract{ + {Contract: "terra1fail", Msg: `{"fail":{}}`}, + }, 3, types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER)) + + input.Keeper.ExecuteReadySchedules(ctx, types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER) + + schedule, found := input.Keeper.GetSchedule(ctx, "job") + require.True(t, found) + require.Equal(t, uint64(8), schedule.LastRunHeight) + require.Equal(t, uint64(3), schedule.LastExecuteHeight) + require.Contains(t, schedule.LastExecutionError, "terra1fail") +} + +func TestKeeperExecuteReadySchedules_SuccessClearsLastExecutionError(t *testing.T) { + input := createTestInput(t) + ctx := input.Ctx.WithBlockHeight(8) + input.MsgServer.errByContract = map[string]error{ + "terra1contract": errFailedContract(), + } + + require.NoError(t, input.Keeper.SetParams(ctx, types.NewParams(1))) + require.NoError(t, input.Keeper.AddSchedule(ctx, "job", 1, []types.MsgExecuteContract{ + {Contract: "terra1contract", Msg: `{"ping":{}}`}, + }, 0, types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER)) + + input.Keeper.ExecuteReadySchedules(ctx, types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER) + schedule, found := input.Keeper.GetSchedule(ctx, "job") + require.True(t, found) + require.NotEmpty(t, schedule.LastExecutionError) + + input.MsgServer.errByContract = nil + input.Keeper.ExecuteReadySchedules(ctx.WithBlockHeight(9), types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER) + + schedule, found = input.Keeper.GetSchedule(ctx, "job") + require.True(t, found) + require.Empty(t, schedule.LastExecutionError) + require.Equal(t, uint64(9), schedule.LastExecuteHeight) +} + +func TestKeeperExecuteReadySchedules_FailedAttemptWaitsForPeriodBeforeRetry(t *testing.T) { + input := createTestInput(t) + ctx := input.Ctx.WithBlockHeight(10) + input.MsgServer.errByContract = map[string]error{ + "terra1fail": errFailedContract(), + } + + require.NoError(t, input.Keeper.SetParams(ctx, types.NewParams(1))) + require.NoError(t, input.Keeper.AddSchedule(ctx, "job", 5, []types.MsgExecuteContract{ + {Contract: "terra1fail", Msg: `{"fail":{}}`}, + }, 0, types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER)) + + input.Keeper.ExecuteReadySchedules(ctx, types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER) + require.Len(t, input.MsgServer.calls, 1) + + input.Keeper.ExecuteReadySchedules(ctx.WithBlockHeight(11), types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER) + require.Len(t, input.MsgServer.calls, 1) + + input.Keeper.ExecuteReadySchedules(ctx.WithBlockHeight(15), types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER) + require.Len(t, input.MsgServer.calls, 2) +} + func TestKeeperSchedulesPagination(t *testing.T) { input := createTestInput(t) @@ -72,3 +190,11 @@ func TestKeeperScheduleQuery(t *testing.T) { require.NoError(t, err) require.Equal(t, "job-a", res.Schedule.Name) } + +func calledContracts(calls []*types.MsgExecuteContract) []string { + contracts := make([]string, 0, len(calls)) + for _, call := range calls { + contracts = append(contracts, call.Contract) + } + return contracts +} diff --git a/x/cron/keeper/params.go b/x/cron/keeper/params.go index a13b05fb7..f5cad24bf 100644 --- a/x/cron/keeper/params.go +++ b/x/cron/keeper/params.go @@ -12,10 +12,17 @@ func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { } k.cdc.MustUnmarshal(bz, ¶ms) + if params.MaxExecutionGas == 0 { + params.MaxExecutionGas = types.DefaultMaxExecutionGas + } return params } func (k Keeper) SetParams(ctx sdk.Context, params types.Params) error { + if err := params.Validate(); err != nil { + return err + } + store := ctx.KVStore(k.storeKey) bz, err := k.cdc.Marshal(¶ms) if err != nil { diff --git a/x/cron/keeper/test_utils_test.go b/x/cron/keeper/test_utils_test.go index 2a3205ffa..d6e7a5ecb 100644 --- a/x/cron/keeper/test_utils_test.go +++ b/x/cron/keeper/test_utils_test.go @@ -2,6 +2,7 @@ package keeper import ( "context" + "errors" "testing" "time" @@ -32,21 +33,36 @@ func (f fakeAccountKeeper) GetModuleAddress(_ string) sdk.AccAddress { } type fakeWasmMsgServer struct { - calls []*chronotypes.MsgExecuteContract - err error + calls []*chronotypes.MsgExecuteContract + err error + errByContract map[string]error + gasToConsume uint64 + observedGasLimit uint64 } -func (f *fakeWasmMsgServer) ExecuteContract(_ context.Context, msg *wasmtypes.MsgExecuteContract) (*wasmtypes.MsgExecuteContractResponse, error) { +func (f *fakeWasmMsgServer) ExecuteContract(ctx context.Context, msg *wasmtypes.MsgExecuteContract) (*wasmtypes.MsgExecuteContractResponse, error) { f.calls = append(f.calls, &chronotypes.MsgExecuteContract{ Contract: msg.Contract, Msg: string(msg.Msg), }) + if f.gasToConsume > 0 { + sdkCtx := sdk.UnwrapSDKContext(ctx) + f.observedGasLimit = sdkCtx.GasMeter().Limit() + sdkCtx.GasMeter().ConsumeGas(f.gasToConsume, "fake wasm execution") + } if f.err != nil { return nil, f.err } + if err := f.errByContract[msg.Contract]; err != nil { + return nil, err + } return &wasmtypes.MsgExecuteContractResponse{}, nil } +func errFailedContract() error { + return errors.New("contract execution failed") +} + type testEncodingConfig struct { Codec codec.Codec Amino *codec.LegacyAmino diff --git a/x/cron/spec/01_concepts.md b/x/cron/spec/01_concepts.md index 82006987a..a2d353439 100644 --- a/x/cron/spec/01_concepts.md +++ b/x/cron/spec/01_concepts.md @@ -11,7 +11,8 @@ A cron schedule is a named record that says: - which Wasm contract messages to execute - how often to execute them, measured in block intervals - whether execution happens in `BeginBlock` or `EndBlock` -- the last block height at which the schedule executed +- the last block height at which the schedule was attempted +- the last block height at which the schedule fully succeeded At each supported block stage, the module scans stored schedules, selects the ones whose interval has elapsed, and executes up to the configured per-stage limit. @@ -32,10 +33,12 @@ The stage is part of the stored schedule and is checked before execution. The ap ## Failure Semantics -Cron executes each due schedule in a cached context. +Cron treats one schedule as one atomic job. A schedule may contain multiple Wasm contract messages, but those messages are expected to be related steps of the same job. -- Before execution starts, the module updates `last_execute_height` on the stored schedule. +- Before execution starts, the module updates `last_run_height` on the stored schedule. - It then executes each nested contract message using the cron module account as the sender. -- If any nested message fails, the cached writes are discarded, so no partial Wasm effects are committed for that schedule. +- All nested messages run in one cached context with a schedule-level gas limit. +- If every nested message succeeds, the cached writes are committed, `last_execute_height` is updated, and `last_execution_error` is cleared. +- If any nested message fails or the schedule runs out of gas, the cached writes are discarded, `last_execute_height` is not updated, and `last_execution_error` is stored on the schedule. -The failure is logged, but the schedule remains advanced to the current height because the schedule record itself is updated before the cached execution block. This means failed schedules are not retried again in the same block. +Failed schedules do not prevent other ready schedules from running. Retry pacing is based on `last_run_height`, so a failed schedule waits for its period before being attempted again. diff --git a/x/cron/spec/02_state.md b/x/cron/spec/02_state.md index 28c6ee32c..b5c6051dd 100644 --- a/x/cron/spec/02_state.md +++ b/x/cron/spec/02_state.md @@ -17,6 +17,8 @@ type Schedule struct { Msgs []MsgExecuteContract LastExecuteHeight uint64 ExecutionStage ExecutionStage + LastRunHeight uint64 + LastExecutionError string } ``` @@ -25,8 +27,10 @@ Field meanings: - `Name`: unique schedule identifier - `Period`: execution interval in blocks - `Msgs`: ordered list of Wasm execute payloads -- `LastExecuteHeight`: last successful scheduling checkpoint used for interval calculation +- `LastExecuteHeight`: last block height where every message in the schedule succeeded - `ExecutionStage`: whether the schedule runs in `BeginBlock` or `EndBlock` +- `LastRunHeight`: last block height where the scheduler attempted this schedule +- `LastExecutionError`: most recent execution error, including the failing contract, cleared after a full successful run `Msgs` contains only contract address plus raw JSON message payload: @@ -59,8 +63,11 @@ Cron parameters are stored under a dedicated params key. ```go type Params struct { - Limit uint64 + Limit uint64 + MaxExecutionGas uint64 } ``` `Limit` bounds how many schedules may execute during one pass of `BeginBlock` or `EndBlock`. + +`MaxExecutionGas` bounds gas consumed by one atomic schedule execution. diff --git a/x/cron/spec/03_block_lifecycle.md b/x/cron/spec/03_block_lifecycle.md index 6d18886da..54e3d362d 100644 --- a/x/cron/spec/03_block_lifecycle.md +++ b/x/cron/spec/03_block_lifecycle.md @@ -20,6 +20,8 @@ The keeper: 4. stops once `params.limit` schedules have been selected 5. executes each selected schedule in order +A schedule is due when the current block height is at least `schedule.last_run_height + schedule.period`. For older state where `last_run_height` is unset, the keeper falls back to `last_execute_height`. + ## EndBlock During `EndBlock`, the app calls: @@ -32,7 +34,7 @@ The same selection and execution flow is used, but only schedules tagged for `EN ## Nested Contract Dispatch -Each scheduled item is dispatched as a Wasm `MsgExecuteContract` with: +Each nested schedule message is dispatched as a Wasm `MsgExecuteContract` with: - `sender = cron module account` - `contract = schedule message contract` @@ -40,3 +42,14 @@ Each scheduled item is dispatched as a Wasm `MsgExecuteContract` with: - `funds = []` Cron does not mint, move, or attach native coins itself. Any downstream token movement comes from the executed contract logic. + +## Atomic Schedule Execution + +Each selected schedule is executed as one atomic job: + +1. `last_run_height` is updated before the contract calls are attempted. +2. all nested contract calls run in a cached context with a schedule-level gas meter +3. if all contract calls succeed, cached writes are committed, `last_execute_height` is updated, and `last_execution_error` is cleared +4. if any contract call fails or the gas meter is exhausted, cached writes are discarded and `last_execution_error` is persisted + +A failed schedule does not stop later ready schedules from executing in the same stage pass. diff --git a/x/cron/spec/04_messages.md b/x/cron/spec/04_messages.md index d69009dd7..981798028 100644 --- a/x/cron/spec/04_messages.md +++ b/x/cron/spec/04_messages.md @@ -63,5 +63,6 @@ Validation rules: - `authority` must be a valid Bech32 account address - `params.limit` must be greater than zero +- `params.max_execution_gas` must be greater than zero The handler is authority-gated. diff --git a/x/cron/spec/05_events.md b/x/cron/spec/05_events.md index c4345cd28..7d173d142 100644 --- a/x/cron/spec/05_events.md +++ b/x/cron/spec/05_events.md @@ -18,8 +18,10 @@ Execution failures are logged with: but these log lines are not ABCI events. +Execution failures are also persisted on the schedule as `last_execution_error`. This field includes the failing contract and is cleared after the schedule later completes successfully. + ## Nested Wasm Events -When a scheduled contract call succeeds, any events emitted by the nested Wasm execution are surfaced through the normal Wasm execution pipeline. +When an atomic schedule succeeds, any events emitted by the nested Wasm executions are surfaced through the normal Wasm execution pipeline. Cron itself does not rewrite or add additional execution events around those nested calls. diff --git a/x/cron/spec/06_params.md b/x/cron/spec/06_params.md index af83b6bf2..4a829f590 100644 --- a/x/cron/spec/06_params.md +++ b/x/cron/spec/06_params.md @@ -6,9 +6,10 @@ order: 6 The cron module contains the following parameters: -| Key | Type | Example | -|-------|--------|---------| -| limit | uint64 | `5` | +| Key | Type | Example | +|-------------------|--------|-----------| +| limit | uint64 | `5` | +| max_execution_gas | uint64 | `5000000` | ## limit @@ -20,3 +21,9 @@ The limit is applied independently to: - one `EndBlock` execution pass This parameter bounds block-time work even if more schedules are due. + +## max_execution_gas + +`max_execution_gas` is the maximum gas one atomic schedule execution may consume. + +The gas limit applies to the full schedule, including all nested contract messages. If the schedule exceeds this limit, the cached writes are discarded, the schedule records a queryable execution error, and later ready schedules may still run. diff --git a/x/cron/types/params.go b/x/cron/types/params.go index a1ce4532c..713dcdf22 100644 --- a/x/cron/types/params.go +++ b/x/cron/types/params.go @@ -10,7 +10,8 @@ import ( var _ paramtypes.ParamSet = (*Params)(nil) var ( - DefaultLimit = uint64(5) + DefaultLimit = uint64(5) + DefaultMaxExecutionGas = uint64(5_000_000) ) // ParamKeyTable returns the cron module parameter key table. @@ -19,8 +20,12 @@ func ParamKeyTable() paramtypes.KeyTable { } // NewParams creates a new Params instance. -func NewParams(limit uint64) Params { - return Params{Limit: limit} +func NewParams(limit uint64, maxExecutionGas ...uint64) Params { + gasLimit := DefaultMaxExecutionGas + if len(maxExecutionGas) > 0 { + gasLimit = maxExecutionGas[0] + } + return Params{Limit: limit, MaxExecutionGas: gasLimit} } // DefaultParams returns the default cron module parameters. @@ -32,12 +37,16 @@ func DefaultParams() Params { func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { return paramtypes.ParamSetPairs{ paramtypes.NewParamSetPair([]byte("Limit"), &p.Limit, validateLimit), + paramtypes.NewParamSetPair([]byte("MaxExecutionGas"), &p.MaxExecutionGas, validateMaxExecutionGas), } } // Validate validates the cron module parameters. func (p Params) Validate() error { - return validateLimit(p.Limit) + if err := validateLimit(p.Limit); err != nil { + return err + } + return validateMaxExecutionGas(p.MaxExecutionGas) } func validateLimit(i interface{}) error { @@ -51,6 +60,17 @@ func validateLimit(i interface{}) error { return nil } +func validateMaxExecutionGas(i interface{}) error { + g, ok := i.(uint64) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + if g == 0 { + return fmt.Errorf("max execution gas must be positive") + } + return nil +} + func validateAuthority(authority string) error { if _, err := sdk.AccAddressFromBech32(authority); err != nil { return ErrInvalidAuthority diff --git a/x/cron/types/params.pb.go b/x/cron/types/params.pb.go index c54fd93f0..30f6af83a 100644 --- a/x/cron/types/params.pb.go +++ b/x/cron/types/params.pb.go @@ -26,7 +26,8 @@ var _ = math.Inf const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type Params struct { - Limit uint64 `protobuf:"varint,1,opt,name=limit,proto3" json:"limit,omitempty"` + Limit uint64 `protobuf:"varint,1,opt,name=limit,proto3" json:"limit,omitempty"` + MaxExecutionGas uint64 `protobuf:"varint,2,opt,name=max_execution_gas,json=maxExecutionGas,proto3" json:"max_execution_gas,omitempty"` } func (m *Params) Reset() { *m = Params{} } @@ -69,6 +70,13 @@ func (m *Params) GetLimit() uint64 { return 0 } +func (m *Params) GetMaxExecutionGas() uint64 { + if m != nil { + return m.MaxExecutionGas + } + return 0 +} + func init() { proto.RegisterType((*Params)(nil), "terra.cron.v1.Params") } @@ -76,20 +84,22 @@ func init() { func init() { proto.RegisterFile("terra/cron/v1/params.proto", fileDescriptor_c5cf0b5e5aec2d7b) } var fileDescriptor_c5cf0b5e5aec2d7b = []byte{ - // 195 bytes of a gzipped FileDescriptorProto + // 230 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x2a, 0x49, 0x2d, 0x2a, 0x4a, 0xd4, 0x4f, 0x2e, 0xca, 0xcf, 0xd3, 0x2f, 0x33, 0xd4, 0x2f, 0x48, 0x2c, 0x4a, 0xcc, 0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x05, 0xcb, 0xe9, 0x81, 0xe4, 0xf4, 0xca, 0x0c, 0xa5, 0x04, 0x13, 0x73, 0x33, 0xf3, 0xf2, 0xf5, 0xc1, 0x24, 0x44, 0x85, 0x94, 0x64, 0x72, 0x7e, 0x71, 0x6e, 0x7e, 0x71, 0x3c, 0x98, 0xa7, 0x0f, 0xe1, 0x40, 0xa5, 0x44, 0xd2, 0xf3, 0xd3, 0xf3, - 0x21, 0xe2, 0x20, 0x16, 0x44, 0x54, 0x49, 0x8e, 0x8b, 0x2d, 0x00, 0x6c, 0x85, 0x90, 0x08, 0x17, - 0x6b, 0x4e, 0x66, 0x6e, 0x66, 0x89, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x4b, 0x10, 0x84, 0xe3, 0xe4, - 0x7e, 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, 0xba, 0xe9, 0x99, 0x25, 0x19, - 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0xc9, 0x39, 0x89, 0xc5, 0xc5, 0x99, 0xc9, 0xba, 0x50, - 0xb7, 0xe7, 0x17, 0xa5, 0xea, 0x97, 0x99, 0xe8, 0x57, 0x40, 0x7c, 0x51, 0x52, 0x59, 0x90, 0x5a, - 0x9c, 0xc4, 0x06, 0xb6, 0xcf, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xce, 0x49, 0x77, 0x1f, 0xe0, - 0x00, 0x00, 0x00, + 0x21, 0xe2, 0x20, 0x16, 0x44, 0x54, 0xc9, 0x8b, 0x8b, 0x2d, 0x00, 0x6c, 0x85, 0x90, 0x08, 0x17, + 0x6b, 0x4e, 0x66, 0x6e, 0x66, 0x89, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x4b, 0x10, 0x84, 0x23, 0xa4, + 0xc5, 0x25, 0x98, 0x9b, 0x58, 0x11, 0x9f, 0x5a, 0x91, 0x9a, 0x5c, 0x5a, 0x92, 0x99, 0x9f, 0x17, + 0x9f, 0x9e, 0x58, 0x2c, 0xc1, 0x04, 0x56, 0xc1, 0x9f, 0x9b, 0x58, 0xe1, 0x0a, 0x13, 0x77, 0x4f, + 0x2c, 0x76, 0x72, 0x3f, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, + 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x28, 0xdd, 0xf4, + 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0xfd, 0xe4, 0x9c, 0xc4, 0xe2, 0xe2, 0xcc, + 0x64, 0x5d, 0xa8, 0x3f, 0xf3, 0x8b, 0x52, 0xf5, 0xcb, 0x4c, 0xf4, 0x2b, 0x20, 0x3e, 0x2e, 0xa9, + 0x2c, 0x48, 0x2d, 0x4e, 0x62, 0x03, 0xbb, 0xcd, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xf0, 0xdb, + 0x8a, 0x68, 0x0c, 0x01, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -112,6 +122,11 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.MaxExecutionGas != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.MaxExecutionGas)) + i-- + dAtA[i] = 0x10 + } if m.Limit != 0 { i = encodeVarintParams(dAtA, i, uint64(m.Limit)) i-- @@ -140,6 +155,9 @@ func (m *Params) Size() (n int) { if m.Limit != 0 { n += 1 + sovParams(uint64(m.Limit)) } + if m.MaxExecutionGas != 0 { + n += 1 + sovParams(uint64(m.MaxExecutionGas)) + } return n } @@ -197,6 +215,25 @@ func (m *Params) Unmarshal(dAtA []byte) error { break } } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxExecutionGas", wireType) + } + m.MaxExecutionGas = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxExecutionGas |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipParams(dAtA[iNdEx:]) diff --git a/x/cron/types/query.pb.go b/x/cron/types/query.pb.go index 6f80ed0c8..ae3d24b1f 100644 --- a/x/cron/types/query.pb.go +++ b/x/cron/types/query.pb.go @@ -306,39 +306,39 @@ func init() { func init() { proto.RegisterFile("terra/cron/v1/query.proto", fileDescriptor_5b0805d57f892efa) } var fileDescriptor_5b0805d57f892efa = []byte{ - // 505 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x93, 0xbf, 0x6e, 0x13, 0x41, - 0x10, 0xc6, 0x7d, 0x26, 0x58, 0xf1, 0x20, 0x9a, 0x21, 0xc6, 0xe6, 0x14, 0x2e, 0xc9, 0x09, 0x62, - 0x84, 0xe4, 0x5d, 0x39, 0xa1, 0x41, 0x74, 0x29, 0xb0, 0x44, 0x15, 0x8c, 0x68, 0x68, 0xd0, 0xfa, - 0x58, 0x5d, 0x4e, 0xb2, 0x6f, 0x2f, 0xb7, 0x6b, 0x8b, 0x80, 0x68, 0x10, 0x0f, 0x80, 0x44, 0xcf, - 0xf3, 0xa4, 0x8c, 0x44, 0x43, 0x85, 0x90, 0xcd, 0x53, 0x50, 0xa1, 0xdb, 0x3f, 0x89, 0xcf, 0x36, - 0x71, 0xb7, 0xda, 0xf9, 0xe6, 0xfb, 0x7e, 0x7b, 0x33, 0x07, 0xf7, 0x14, 0xcf, 0x73, 0x46, 0xa3, - 0x5c, 0xa4, 0x74, 0xd2, 0xa5, 0xa7, 0x63, 0x9e, 0x9f, 0x91, 0x2c, 0x17, 0x4a, 0xe0, 0x6d, 0x5d, - 0x22, 0x45, 0x89, 0x4c, 0xba, 0xfe, 0xe3, 0x48, 0xc8, 0x91, 0x90, 0x74, 0xc0, 0x24, 0x37, 0x3a, - 0x3a, 0xe9, 0x0e, 0xb8, 0x62, 0x5d, 0x9a, 0xb1, 0x38, 0x49, 0x99, 0x4a, 0x44, 0x6a, 0x5a, 0xfd, - 0xed, 0x58, 0x88, 0x78, 0xc8, 0x29, 0xcb, 0x12, 0xca, 0xd2, 0x54, 0x28, 0x5d, 0x94, 0xb6, 0xba, - 0x15, 0x8b, 0x58, 0xe8, 0x23, 0x2d, 0x4e, 0xf6, 0xd6, 0x2f, 0x93, 0x64, 0x2c, 0x67, 0x23, 0xd7, - 0xb1, 0x5d, 0xae, 0xc9, 0xe8, 0x84, 0xbf, 0x1b, 0x0f, 0xb9, 0xa9, 0x86, 0x5b, 0x80, 0x2f, 0x0b, - 0x9e, 0x63, 0xdd, 0xd2, 0xe7, 0xa7, 0x63, 0x2e, 0x55, 0xf8, 0x02, 0xee, 0x94, 0x6e, 0x65, 0x26, - 0x52, 0xc9, 0xf1, 0x10, 0x6a, 0xc6, 0xba, 0xe5, 0xed, 0x7a, 0x8f, 0x6e, 0x1d, 0x34, 0x48, 0xe9, - 0x99, 0xc4, 0xc8, 0x8f, 0x36, 0xce, 0x7f, 0xed, 0x54, 0xfa, 0x56, 0x1a, 0x76, 0xa0, 0xa9, 0xbd, - 0x7a, 0x5c, 0xbd, 0xb2, 0xd9, 0x36, 0x06, 0x11, 0x36, 0x52, 0x36, 0xe2, 0xda, 0xad, 0xde, 0xd7, - 0xe7, 0xf0, 0x35, 0xb4, 0x96, 0xe5, 0x36, 0xff, 0x29, 0x6c, 0x3a, 0x7c, 0x4b, 0xd0, 0x5c, 0x20, - 0x70, 0x2d, 0x96, 0xe1, 0x52, 0x1e, 0xbe, 0x85, 0x86, 0xb6, 0x75, 0x02, 0xf7, 0x54, 0x7c, 0x0e, - 0x70, 0x35, 0x02, 0xeb, 0xba, 0x4f, 0xcc, 0xbc, 0x48, 0x31, 0x2f, 0x62, 0xe6, 0x6a, 0xe7, 0x45, - 0x8e, 0x59, 0xec, 0xf8, 0xfb, 0x73, 0x9d, 0xe1, 0x77, 0x0f, 0xee, 0x2e, 0x26, 0x58, 0xec, 0x67, - 0x50, 0x77, 0x1c, 0xc5, 0x97, 0xbb, 0xb1, 0x9e, 0xfb, 0x4a, 0x8f, 0xbd, 0x12, 0x5f, 0x55, 0xf3, - 0xb5, 0xd7, 0xf2, 0x99, 0xe4, 0x79, 0xc0, 0x83, 0xbf, 0x55, 0xb8, 0xa9, 0x01, 0x31, 0x85, 0x9a, - 0x99, 0x14, 0xee, 0x2d, 0x60, 0x2c, 0xaf, 0x82, 0x1f, 0x5e, 0x27, 0x31, 0x31, 0xe1, 0xfd, 0xcf, - 0x3f, 0xfe, 0x7c, 0xab, 0x36, 0xb1, 0x41, 0x57, 0xed, 0x21, 0x7e, 0xf1, 0x60, 0xd3, 0x3d, 0x10, - 0xf7, 0x57, 0xf9, 0x2d, 0xef, 0x86, 0xdf, 0x5e, 0xab, 0xb3, 0xe1, 0x6d, 0x1d, 0xbe, 0x87, 0x3b, - 0x74, 0xf5, 0xa2, 0x4b, 0xfa, 0xb1, 0x58, 0xac, 0x4f, 0xf8, 0x01, 0xea, 0x97, 0xb3, 0xc1, 0x07, - 0xab, 0xec, 0x17, 0x97, 0xc3, 0x7f, 0xb8, 0x46, 0x65, 0x11, 0x76, 0x35, 0x82, 0x8f, 0xad, 0xff, - 0x21, 0x1c, 0xf5, 0xce, 0xa7, 0x81, 0x77, 0x31, 0x0d, 0xbc, 0xdf, 0xd3, 0xc0, 0xfb, 0x3a, 0x0b, - 0x2a, 0x17, 0xb3, 0xa0, 0xf2, 0x73, 0x16, 0x54, 0xde, 0x74, 0xe2, 0x44, 0x9d, 0x8c, 0x07, 0x24, - 0x12, 0x23, 0x1a, 0x0d, 0x99, 0x94, 0x49, 0xd4, 0xb1, 0x2e, 0x22, 0xe7, 0x74, 0xf2, 0x84, 0xbe, - 0x37, 0x7e, 0xea, 0x2c, 0xe3, 0x72, 0x50, 0xd3, 0xbf, 0xed, 0xe1, 0xbf, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xb4, 0x29, 0xa2, 0x08, 0x7c, 0x04, 0x00, 0x00, + // 497 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x93, 0xcf, 0x6e, 0xd3, 0x40, + 0x10, 0xc6, 0xe3, 0x50, 0xa2, 0x66, 0x10, 0x97, 0x21, 0xa1, 0xc5, 0x2a, 0x6e, 0x6b, 0xfe, 0x14, + 0x55, 0xea, 0xae, 0xd2, 0x72, 0x41, 0xdc, 0x7a, 0xa0, 0x12, 0xa7, 0x62, 0x6e, 0x5c, 0xd0, 0xc6, + 0xac, 0x5c, 0x4b, 0xc9, 0xae, 0xeb, 0xdd, 0x44, 0x14, 0x04, 0x07, 0x9e, 0x00, 0x89, 0x3b, 0xcf, + 0xd3, 0x63, 0x25, 0x2e, 0x9c, 0x10, 0x4a, 0x78, 0x03, 0x5e, 0x00, 0x79, 0x77, 0x9d, 0xd6, 0x26, + 0x4d, 0x6e, 0x2b, 0xcf, 0x37, 0xdf, 0xf7, 0xdb, 0x9d, 0x31, 0xdc, 0xd3, 0x3c, 0xcf, 0x19, 0x8d, + 0x73, 0x29, 0xe8, 0xb8, 0x47, 0x4f, 0x47, 0x3c, 0x3f, 0x23, 0x59, 0x2e, 0xb5, 0xc4, 0xdb, 0xa6, + 0x44, 0x8a, 0x12, 0x19, 0xf7, 0xfc, 0xdd, 0x58, 0xaa, 0xa1, 0x54, 0xb4, 0xcf, 0x14, 0xb7, 0x3a, + 0x3a, 0xee, 0xf5, 0xb9, 0x66, 0x3d, 0x9a, 0xb1, 0x24, 0x15, 0x4c, 0xa7, 0x52, 0xd8, 0x56, 0x7f, + 0x23, 0x91, 0x32, 0x19, 0x70, 0xca, 0xb2, 0x94, 0x32, 0x21, 0xa4, 0x36, 0x45, 0xe5, 0xaa, 0x9d, + 0x44, 0x26, 0xd2, 0x1c, 0x69, 0x71, 0x72, 0x5f, 0xfd, 0x2a, 0x49, 0xc6, 0x72, 0x36, 0x2c, 0x3b, + 0x36, 0xaa, 0x35, 0x15, 0x9f, 0xf0, 0x77, 0xa3, 0x01, 0xb7, 0xd5, 0xb0, 0x03, 0xf8, 0xaa, 0xe0, + 0x39, 0x36, 0x2d, 0x11, 0x3f, 0x1d, 0x71, 0xa5, 0xc3, 0x97, 0x70, 0xa7, 0xf2, 0x55, 0x65, 0x52, + 0x28, 0x8e, 0x07, 0xd0, 0xb2, 0xd6, 0xeb, 0xde, 0x96, 0xf7, 0xe4, 0xd6, 0x7e, 0x97, 0x54, 0xae, + 0x49, 0xac, 0xfc, 0x70, 0xe5, 0xfc, 0xd7, 0x66, 0x23, 0x72, 0xd2, 0x70, 0x17, 0x3a, 0xc6, 0xeb, + 0xb5, 0x0b, 0x76, 0x19, 0x88, 0xb0, 0x22, 0xd8, 0x90, 0x1b, 0xab, 0x76, 0x64, 0xce, 0x61, 0x04, + 0xdd, 0x9a, 0xd6, 0x25, 0x3f, 0x83, 0xd5, 0x12, 0xdc, 0x65, 0xaf, 0xd5, 0xb2, 0xcb, 0x16, 0x97, + 0x3e, 0x93, 0x87, 0x6f, 0x6b, 0x9e, 0xe5, 0x25, 0xf1, 0x05, 0xc0, 0xe5, 0xe3, 0x3b, 0xd7, 0xc7, + 0xc4, 0x4e, 0x8a, 0x14, 0x93, 0x22, 0x76, 0xa2, 0x6e, 0x52, 0xe4, 0x98, 0x25, 0x25, 0x7c, 0x74, + 0xa5, 0x33, 0xfc, 0xee, 0xc1, 0xdd, 0x7a, 0x82, 0xc3, 0x7e, 0x0e, 0xed, 0x92, 0xa3, 0x78, 0xb3, + 0x1b, 0xcb, 0xb9, 0x2f, 0xf5, 0x78, 0x54, 0xe1, 0x6b, 0x1a, 0xbe, 0x9d, 0xa5, 0x7c, 0x36, 0xf9, + 0x2a, 0xe0, 0xfe, 0xdf, 0x26, 0xdc, 0x34, 0x80, 0x28, 0xa0, 0x65, 0x67, 0x84, 0xdb, 0x35, 0x8c, + 0xff, 0x97, 0xc0, 0x0f, 0x17, 0x49, 0x6c, 0x4c, 0x78, 0xff, 0xcb, 0x8f, 0x3f, 0xdf, 0x9a, 0x6b, + 0xd8, 0xa5, 0xf3, 0x36, 0x10, 0x3f, 0xc3, 0x6a, 0x79, 0x3f, 0x7c, 0x30, 0xcf, 0xae, 0xb6, 0x14, + 0xfe, 0xc3, 0xc5, 0x22, 0x97, 0xba, 0x63, 0x52, 0xb7, 0x71, 0x93, 0xce, 0xdf, 0x6d, 0x45, 0x3f, + 0x16, 0xeb, 0xf4, 0x09, 0x3f, 0x40, 0x7b, 0x36, 0x14, 0x5c, 0xe8, 0x3d, 0xbb, 0xf5, 0xa3, 0x25, + 0x2a, 0x87, 0xb0, 0x65, 0x10, 0x7c, 0x5c, 0xbf, 0x0e, 0xe1, 0xf0, 0xe8, 0x7c, 0x12, 0x78, 0x17, + 0x93, 0xc0, 0xfb, 0x3d, 0x09, 0xbc, 0xaf, 0xd3, 0xa0, 0x71, 0x31, 0x0d, 0x1a, 0x3f, 0xa7, 0x41, + 0xe3, 0xcd, 0x5e, 0x92, 0xea, 0x93, 0x51, 0x9f, 0xc4, 0x72, 0x48, 0xe3, 0x01, 0x53, 0x2a, 0x8d, + 0xf7, 0x9c, 0x8b, 0xcc, 0x39, 0x1d, 0x3f, 0xa5, 0xef, 0xad, 0x9f, 0x3e, 0xcb, 0xb8, 0xea, 0xb7, + 0xcc, 0x9f, 0x7a, 0xf0, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x5a, 0xcf, 0xae, 0x5f, 0x6f, 0x04, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/cron/types/schedule.pb.go b/x/cron/types/schedule.pb.go index 543ab6915..133363eb4 100644 --- a/x/cron/types/schedule.pb.go +++ b/x/cron/types/schedule.pb.go @@ -49,11 +49,13 @@ func (ExecutionStage) EnumDescriptor() ([]byte, []int) { } type Schedule struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Period uint64 `protobuf:"varint,2,opt,name=period,proto3" json:"period,omitempty"` - Msgs []MsgExecuteContract `protobuf:"bytes,3,rep,name=msgs,proto3" json:"msgs"` - LastExecuteHeight uint64 `protobuf:"varint,4,opt,name=last_execute_height,json=lastExecuteHeight,proto3" json:"last_execute_height,omitempty"` - ExecutionStage ExecutionStage `protobuf:"varint,5,opt,name=execution_stage,json=executionStage,proto3,enum=terra.cron.v1.ExecutionStage" json:"execution_stage,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Period uint64 `protobuf:"varint,2,opt,name=period,proto3" json:"period,omitempty"` + Msgs []MsgExecuteContract `protobuf:"bytes,3,rep,name=msgs,proto3" json:"msgs"` + LastExecuteHeight uint64 `protobuf:"varint,4,opt,name=last_execute_height,json=lastExecuteHeight,proto3" json:"last_execute_height,omitempty"` + ExecutionStage ExecutionStage `protobuf:"varint,5,opt,name=execution_stage,json=executionStage,proto3,enum=terra.cron.v1.ExecutionStage" json:"execution_stage,omitempty"` + LastRunHeight uint64 `protobuf:"varint,6,opt,name=last_run_height,json=lastRunHeight,proto3" json:"last_run_height,omitempty"` + LastExecutionError string `protobuf:"bytes,7,opt,name=last_execution_error,json=lastExecutionError,proto3" json:"last_execution_error,omitempty"` } func (m *Schedule) Reset() { *m = Schedule{} } @@ -124,6 +126,20 @@ func (m *Schedule) GetExecutionStage() ExecutionStage { return ExecutionStage_EXECUTION_STAGE_END_BLOCKER } +func (m *Schedule) GetLastRunHeight() uint64 { + if m != nil { + return m.LastRunHeight + } + return 0 +} + +func (m *Schedule) GetLastExecutionError() string { + if m != nil { + return m.LastExecutionError + } + return "" +} + type MsgExecuteContract struct { Contract string `protobuf:"bytes,1,opt,name=contract,proto3" json:"contract,omitempty"` Msg string `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"` @@ -230,33 +246,35 @@ func init() { func init() { proto.RegisterFile("terra/cron/v1/schedule.proto", fileDescriptor_27c1282684f054b4) } var fileDescriptor_27c1282684f054b4 = []byte{ - // 403 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x92, 0x41, 0x8b, 0xd3, 0x40, - 0x1c, 0xc5, 0x33, 0x36, 0x5d, 0x76, 0x47, 0xb6, 0xae, 0xe3, 0x22, 0x61, 0x75, 0xb3, 0xd9, 0x82, - 0x10, 0x84, 0x26, 0xb4, 0x7a, 0xf3, 0x64, 0xe2, 0x58, 0x8b, 0xda, 0x42, 0x5a, 0x41, 0xbc, 0x84, - 0x74, 0x3a, 0x4c, 0x02, 0x4d, 0xa6, 0x64, 0x26, 0xa5, 0x7e, 0x0b, 0x3f, 0x56, 0x8f, 0x3d, 0x7a, - 0x12, 0x69, 0x8f, 0x7e, 0x09, 0xc9, 0x24, 0x2d, 0xb4, 0x7b, 0x7b, 0x8f, 0xf7, 0x7b, 0xfc, 0xe7, - 0x9f, 0xfc, 0xe1, 0x4b, 0x49, 0xf3, 0x3c, 0x72, 0x49, 0xce, 0x33, 0x77, 0xd9, 0x75, 0x05, 0x89, - 0xe9, 0xac, 0x98, 0x53, 0x67, 0x91, 0x73, 0xc9, 0xd1, 0xa5, 0x4a, 0x9d, 0x32, 0x75, 0x96, 0xdd, - 0x9b, 0x6b, 0xc6, 0x19, 0x57, 0x89, 0x5b, 0xaa, 0x0a, 0x6a, 0xff, 0x03, 0xf0, 0x7c, 0x5c, 0xf7, - 0x10, 0x82, 0x7a, 0x16, 0xa5, 0xd4, 0x00, 0x16, 0xb0, 0x2f, 0x02, 0xa5, 0xd1, 0x73, 0x78, 0xb6, - 0xa0, 0x79, 0xc2, 0x67, 0xc6, 0x23, 0x0b, 0xd8, 0x7a, 0x50, 0x3b, 0xf4, 0x0e, 0xea, 0xa9, 0x60, - 0xc2, 0x68, 0x58, 0x0d, 0xfb, 0x71, 0xef, 0xde, 0x39, 0x1a, 0xe6, 0x7c, 0x15, 0x0c, 0xaf, 0x28, - 0x29, 0x24, 0xf5, 0x79, 0x26, 0xf3, 0x88, 0x48, 0x4f, 0x5f, 0xff, 0xb9, 0xd3, 0x02, 0x55, 0x42, - 0x0e, 0x7c, 0x36, 0x8f, 0x84, 0x0c, 0x69, 0xc5, 0x84, 0x31, 0x4d, 0x58, 0x2c, 0x0d, 0x5d, 0x4d, - 0x78, 0x5a, 0x46, 0x75, 0xfb, 0x93, 0x0a, 0xd0, 0x47, 0xf8, 0xa4, 0x42, 0x13, 0x9e, 0x85, 0x42, - 0x46, 0x8c, 0x1a, 0x4d, 0x0b, 0xd8, 0xad, 0xde, 0xed, 0xc9, 0x5c, 0xbc, 0xa7, 0xc6, 0x25, 0x14, - 0xb4, 0xe8, 0x91, 0x6f, 0x7b, 0x10, 0x3d, 0x7c, 0x19, 0xba, 0x81, 0xe7, 0xa4, 0xd6, 0xf5, 0xea, - 0x07, 0x8f, 0xae, 0x60, 0x23, 0x15, 0x4c, 0xed, 0x7e, 0x11, 0x94, 0xb2, 0xfd, 0x0a, 0x5e, 0xee, - 0x3f, 0x98, 0xcf, 0x8b, 0x4c, 0xa2, 0x6b, 0xd8, 0x24, 0xa5, 0x50, 0xdd, 0x66, 0x50, 0x99, 0xd7, - 0x13, 0xd8, 0x3a, 0x7e, 0x0c, 0xba, 0x83, 0x2f, 0xf0, 0x77, 0xec, 0x7f, 0x9b, 0x0c, 0x46, 0xc3, - 0x70, 0x3c, 0x79, 0xdf, 0xc7, 0x21, 0x1e, 0x7e, 0x08, 0xbd, 0x2f, 0x23, 0xff, 0x33, 0x0e, 0xae, - 0x34, 0x74, 0x0f, 0x6f, 0x4f, 0x01, 0x0f, 0xf7, 0x07, 0xc3, 0x03, 0x02, 0xbc, 0xfe, 0x7a, 0x6b, - 0x82, 0xcd, 0xd6, 0x04, 0x7f, 0xb7, 0x26, 0xf8, 0xb5, 0x33, 0xb5, 0xcd, 0xce, 0xd4, 0x7e, 0xef, - 0x4c, 0xed, 0x47, 0x87, 0x25, 0x32, 0x2e, 0xa6, 0x0e, 0xe1, 0xa9, 0x4b, 0xe6, 0x91, 0x10, 0x09, - 0xe9, 0xd4, 0xe7, 0xc1, 0x73, 0xea, 0x2e, 0xdf, 0xba, 0xab, 0xea, 0x50, 0xe4, 0xcf, 0x05, 0x15, - 0xd3, 0x33, 0xf5, 0xfb, 0xdf, 0xfc, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x4c, 0x9a, 0xf1, 0xed, 0x43, - 0x02, 0x00, 0x00, + // 445 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x92, 0x41, 0x6f, 0xd3, 0x30, + 0x14, 0xc7, 0x93, 0x35, 0x2d, 0xdb, 0x43, 0xed, 0x86, 0xa9, 0x50, 0x34, 0x58, 0xd6, 0x55, 0x02, + 0x55, 0x48, 0x4b, 0xd8, 0xe0, 0xc6, 0x89, 0x14, 0x53, 0x26, 0xa0, 0x93, 0xd2, 0x22, 0x21, 0x2e, + 0x51, 0xe6, 0x59, 0x6e, 0xa4, 0xd6, 0xae, 0x6c, 0xa7, 0x1a, 0xdf, 0x82, 0x2f, 0x85, 0xb4, 0xe3, + 0x8e, 0x9c, 0x10, 0x6a, 0xbf, 0x08, 0xb2, 0x93, 0x0e, 0x3a, 0x6e, 0xff, 0x97, 0xff, 0xff, 0xe9, + 0xe7, 0xf7, 0xf2, 0xe0, 0x89, 0xa6, 0x52, 0x66, 0x11, 0x91, 0x82, 0x47, 0x8b, 0x93, 0x48, 0x91, + 0x09, 0xbd, 0x2c, 0xa6, 0x34, 0x9c, 0x4b, 0xa1, 0x05, 0x6a, 0x5a, 0x37, 0x34, 0x6e, 0xb8, 0x38, + 0xd9, 0x6f, 0x33, 0xc1, 0x84, 0x75, 0x22, 0xa3, 0xca, 0x50, 0xf7, 0xc7, 0x16, 0x6c, 0x8f, 0xaa, + 0x3e, 0x84, 0xc0, 0xe3, 0xd9, 0x8c, 0xfa, 0x6e, 0xc7, 0xed, 0xed, 0x24, 0x56, 0xa3, 0x47, 0xd0, + 0x98, 0x53, 0x99, 0x8b, 0x4b, 0x7f, 0xab, 0xe3, 0xf6, 0xbc, 0xa4, 0xaa, 0xd0, 0x6b, 0xf0, 0x66, + 0x8a, 0x29, 0xbf, 0xd6, 0xa9, 0xf5, 0xee, 0x9f, 0x1e, 0x85, 0x1b, 0xb0, 0xf0, 0x93, 0x62, 0xf8, + 0x8a, 0x92, 0x42, 0xd3, 0xbe, 0xe0, 0x5a, 0x66, 0x44, 0xc7, 0xde, 0xf5, 0xaf, 0x43, 0x27, 0xb1, + 0x4d, 0x28, 0x84, 0x87, 0xd3, 0x4c, 0xe9, 0x94, 0x96, 0x99, 0x74, 0x42, 0x73, 0x36, 0xd1, 0xbe, + 0x67, 0x09, 0x0f, 0x8c, 0x55, 0x75, 0xbf, 0xb7, 0x06, 0x7a, 0x07, 0xbb, 0x65, 0x34, 0x17, 0x3c, + 0x55, 0x3a, 0x63, 0xd4, 0xaf, 0x77, 0xdc, 0x5e, 0xeb, 0xf4, 0xe0, 0x0e, 0x17, 0xaf, 0x53, 0x23, + 0x13, 0x4a, 0x5a, 0x74, 0xa3, 0x46, 0xcf, 0x60, 0xd7, 0x72, 0x65, 0xc1, 0xd7, 0xcc, 0x86, 0x65, + 0x36, 0xcd, 0xe7, 0xa4, 0xe0, 0x15, 0xef, 0x05, 0xb4, 0xff, 0x79, 0x9f, 0x81, 0x52, 0x29, 0x85, + 0xf4, 0xef, 0xd9, 0xc5, 0xa0, 0xbf, 0x0f, 0xcc, 0x05, 0xc7, 0xc6, 0xe9, 0xc6, 0x80, 0xfe, 0x9f, + 0x19, 0xed, 0xc3, 0x36, 0xa9, 0x74, 0xb5, 0xd4, 0xdb, 0x1a, 0xed, 0x41, 0x6d, 0xa6, 0x98, 0xdd, + 0xea, 0x4e, 0x62, 0x64, 0xf7, 0x29, 0x34, 0xd7, 0xbf, 0xa2, 0x2f, 0x0a, 0xae, 0x51, 0x1b, 0xea, + 0xc4, 0x08, 0xdb, 0x5b, 0x4f, 0xca, 0xe2, 0xf9, 0x18, 0x5a, 0x9b, 0x63, 0xa2, 0x43, 0x78, 0x8c, + 0xbf, 0xe0, 0xfe, 0xe7, 0xf1, 0xd9, 0xf9, 0x30, 0x1d, 0x8d, 0xdf, 0x0c, 0x70, 0x8a, 0x87, 0x6f, + 0xd3, 0xf8, 0xe3, 0x79, 0xff, 0x03, 0x4e, 0xf6, 0x1c, 0x74, 0x04, 0x07, 0x77, 0x03, 0x31, 0x1e, + 0x9c, 0x0d, 0x6f, 0x23, 0x6e, 0x3c, 0xb8, 0x5e, 0x06, 0xee, 0xcd, 0x32, 0x70, 0x7f, 0x2f, 0x03, + 0xf7, 0xfb, 0x2a, 0x70, 0x6e, 0x56, 0x81, 0xf3, 0x73, 0x15, 0x38, 0x5f, 0x8f, 0x59, 0xae, 0x27, + 0xc5, 0x45, 0x48, 0xc4, 0x2c, 0x22, 0xd3, 0x4c, 0xa9, 0x9c, 0x1c, 0x57, 0x87, 0x27, 0x24, 0x8d, + 0x16, 0xaf, 0xa2, 0xab, 0xf2, 0x04, 0xf5, 0xb7, 0x39, 0x55, 0x17, 0x0d, 0x7b, 0x58, 0x2f, 0xff, + 0x04, 0x00, 0x00, 0xff, 0xff, 0x3c, 0x44, 0x6c, 0xb4, 0x9d, 0x02, 0x00, 0x00, } func (m *Schedule) Marshal() (dAtA []byte, err error) { @@ -279,6 +297,18 @@ func (m *Schedule) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.LastExecutionError) > 0 { + i -= len(m.LastExecutionError) + copy(dAtA[i:], m.LastExecutionError) + i = encodeVarintSchedule(dAtA, i, uint64(len(m.LastExecutionError))) + i-- + dAtA[i] = 0x3a + } + if m.LastRunHeight != 0 { + i = encodeVarintSchedule(dAtA, i, uint64(m.LastRunHeight)) + i-- + dAtA[i] = 0x30 + } if m.ExecutionStage != 0 { i = encodeVarintSchedule(dAtA, i, uint64(m.ExecutionStage)) i-- @@ -419,6 +449,13 @@ func (m *Schedule) Size() (n int) { if m.ExecutionStage != 0 { n += 1 + sovSchedule(uint64(m.ExecutionStage)) } + if m.LastRunHeight != 0 { + n += 1 + sovSchedule(uint64(m.LastRunHeight)) + } + l = len(m.LastExecutionError) + if l > 0 { + n += 1 + l + sovSchedule(uint64(l)) + } return n } @@ -609,6 +646,57 @@ func (m *Schedule) Unmarshal(dAtA []byte) error { break } } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LastRunHeight", wireType) + } + m.LastRunHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSchedule + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.LastRunHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LastExecutionError", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSchedule + } + 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 ErrInvalidLengthSchedule + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSchedule + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.LastExecutionError = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipSchedule(dAtA[iNdEx:]) From b6558a17e55a0ec77572d8fbb3bc58a6b7ea269d Mon Sep 17 00:00:00 2001 From: ZuluSpl0it Date: Wed, 13 May 2026 11:01:38 -0500 Subject: [PATCH 3/5] fix: capture cron execution panics --- x/cron/keeper/keeper.go | 9 ++++++++- x/cron/keeper/keeper_test.go | 20 ++++++++++++++++++++ x/cron/keeper/test_utils_test.go | 4 ++++ x/cron/spec/01_concepts.md | 2 +- x/cron/spec/03_block_lifecycle.md | 2 +- x/cron/spec/05_events.md | 2 +- 6 files changed, 35 insertions(+), 4 deletions(-) diff --git a/x/cron/keeper/keeper.go b/x/cron/keeper/keeper.go index 9b0f5a128..710e3e769 100644 --- a/x/cron/keeper/keeper.go +++ b/x/cron/keeper/keeper.go @@ -173,7 +173,14 @@ func (k Keeper) executeSchedule(ctx sdk.Context, schedule types.Schedule) (err e ) return } - panic(r) + err = fmt.Errorf("cron execute panic: %v", r) + schedule.LastExecutionError = lastExecutionErr(currentContract, err) + k.storeSchedule(ctx, schedule) + ctx.Logger().Info("cron execute panic", + "schedule_name", schedule.Name, + "contract", currentContract, + "error", err, + ) } }() diff --git a/x/cron/keeper/keeper_test.go b/x/cron/keeper/keeper_test.go index d9f824297..6d4704e31 100644 --- a/x/cron/keeper/keeper_test.go +++ b/x/cron/keeper/keeper_test.go @@ -62,6 +62,26 @@ func TestKeeperExecuteReadySchedules_ExecutionGasLimit(t *testing.T) { require.Equal(t, uint64(10), input.MsgServer.observedGasLimit) } +func TestKeeperExecuteReadySchedules_ExecutionPanicIsRecorded(t *testing.T) { + input := createTestInput(t) + ctx := input.Ctx.WithBlockHeight(5) + input.MsgServer.panicValue = "wasm panic" + + require.NoError(t, input.Keeper.SetParams(ctx, types.NewParams(1))) + require.NoError(t, input.Keeper.AddSchedule(ctx, "job", 1, []types.MsgExecuteContract{{Contract: "terra1contract", Msg: `{"panic":{}}`}}, 2, types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER)) + + require.NotPanics(t, func() { + input.Keeper.ExecuteReadySchedules(ctx, types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER) + }) + + schedule, found := input.Keeper.GetSchedule(ctx, "job") + require.True(t, found) + require.Equal(t, uint64(5), schedule.LastRunHeight) + require.Equal(t, uint64(2), schedule.LastExecuteHeight) + require.Contains(t, schedule.LastExecutionError, "terra1contract") + require.Contains(t, schedule.LastExecutionError, "wasm panic") +} + func TestKeeperExecuteReadySchedules_FailedScheduleDoesNotBlockOthers(t *testing.T) { input := createTestInput(t) ctx := input.Ctx.WithBlockHeight(8) diff --git a/x/cron/keeper/test_utils_test.go b/x/cron/keeper/test_utils_test.go index d6e7a5ecb..d284e7107 100644 --- a/x/cron/keeper/test_utils_test.go +++ b/x/cron/keeper/test_utils_test.go @@ -38,6 +38,7 @@ type fakeWasmMsgServer struct { errByContract map[string]error gasToConsume uint64 observedGasLimit uint64 + panicValue interface{} } func (f *fakeWasmMsgServer) ExecuteContract(ctx context.Context, msg *wasmtypes.MsgExecuteContract) (*wasmtypes.MsgExecuteContractResponse, error) { @@ -56,6 +57,9 @@ func (f *fakeWasmMsgServer) ExecuteContract(ctx context.Context, msg *wasmtypes. if err := f.errByContract[msg.Contract]; err != nil { return nil, err } + if f.panicValue != nil { + panic(f.panicValue) + } return &wasmtypes.MsgExecuteContractResponse{}, nil } diff --git a/x/cron/spec/01_concepts.md b/x/cron/spec/01_concepts.md index a2d353439..e9bb92c61 100644 --- a/x/cron/spec/01_concepts.md +++ b/x/cron/spec/01_concepts.md @@ -39,6 +39,6 @@ Cron treats one schedule as one atomic job. A schedule may contain multiple Wasm - It then executes each nested contract message using the cron module account as the sender. - All nested messages run in one cached context with a schedule-level gas limit. - If every nested message succeeds, the cached writes are committed, `last_execute_height` is updated, and `last_execution_error` is cleared. -- If any nested message fails or the schedule runs out of gas, the cached writes are discarded, `last_execute_height` is not updated, and `last_execution_error` is stored on the schedule. +- If any nested message fails, panics, or the schedule runs out of gas, the cached writes are discarded, `last_execute_height` is not updated, and `last_execution_error` is stored on the schedule. Failed schedules do not prevent other ready schedules from running. Retry pacing is based on `last_run_height`, so a failed schedule waits for its period before being attempted again. diff --git a/x/cron/spec/03_block_lifecycle.md b/x/cron/spec/03_block_lifecycle.md index 54e3d362d..87bcadc8b 100644 --- a/x/cron/spec/03_block_lifecycle.md +++ b/x/cron/spec/03_block_lifecycle.md @@ -50,6 +50,6 @@ Each selected schedule is executed as one atomic job: 1. `last_run_height` is updated before the contract calls are attempted. 2. all nested contract calls run in a cached context with a schedule-level gas meter 3. if all contract calls succeed, cached writes are committed, `last_execute_height` is updated, and `last_execution_error` is cleared -4. if any contract call fails or the gas meter is exhausted, cached writes are discarded and `last_execution_error` is persisted +4. if any contract call fails, panics, or the gas meter is exhausted, cached writes are discarded and `last_execution_error` is persisted A failed schedule does not stop later ready schedules from executing in the same stage pass. diff --git a/x/cron/spec/05_events.md b/x/cron/spec/05_events.md index 7d173d142..17f95aac0 100644 --- a/x/cron/spec/05_events.md +++ b/x/cron/spec/05_events.md @@ -18,7 +18,7 @@ Execution failures are logged with: but these log lines are not ABCI events. -Execution failures are also persisted on the schedule as `last_execution_error`. This field includes the failing contract and is cleared after the schedule later completes successfully. +Execution failures, panics, and out-of-gas errors are also persisted on the schedule as `last_execution_error`. This field includes the failing contract when available and is cleared after the schedule later completes successfully. ## Nested Wasm Events From 3106aa53110dc7a7bae4b5ba552a3591c76f1a6b Mon Sep 17 00:00:00 2001 From: ZuluSpl0it Date: Wed, 13 May 2026 12:03:31 -0500 Subject: [PATCH 4/5] fix: format cron imports --- custom/bank/simulation/operations.go | 6 +- custom/staking/query_server.go | 9 +- tests/e2e/api_regression_test.go | 178 ++++++++++++++------------- tests/e2e/configurer/base.go | 3 +- tests/e2e/configurer/factory.go | 6 +- tests/e2e/e2e_test.go | 54 ++++---- types/util/blocks.go | 2 +- x/cron/genesis.go | 3 +- x/cron/keeper/grpc_query.go | 3 +- x/cron/keeper/keeper.go | 12 +- x/cron/keeper/msg_server.go | 3 +- x/cron/keeper/params.go | 7 +- x/cron/types/genesis_test.go | 6 +- x/dyncomm/ante/ante_test.go | 3 +- x/dyncomm/client/cli/query.go | 3 +- x/market/client/cli/query.go | 6 +- x/market/keeper/keeper_test.go | 6 +- x/market/simulation/operations.go | 3 +- x/market/simulation/params.go | 9 +- x/market/types/codec.go | 3 +- x/oracle/abci.go | 4 +- x/oracle/abci_test.go | 3 +- x/oracle/keeper/ballot.go | 3 +- x/oracle/keeper/keeper.go | 3 +- x/oracle/keeper/reward_test.go | 6 +- x/oracle/keeper/slash.go | 3 +- x/oracle/simulation/operations.go | 9 +- x/oracle/simulation/params.go | 18 ++- x/oracle/types/codec.go | 3 +- x/oracle/types/test_utils.go | 12 +- x/taxexemption/keeper/test_utils.go | 3 +- x/treasury/abci.go | 3 +- x/treasury/simulation/params.go | 21 ++-- 33 files changed, 234 insertions(+), 182 deletions(-) diff --git a/custom/bank/simulation/operations.go b/custom/bank/simulation/operations.go index 41b4204a4..a26b32eaf 100644 --- a/custom/bank/simulation/operations.go +++ b/custom/bank/simulation/operations.go @@ -31,13 +31,15 @@ func WeightedOperations( appParams simtypes.AppParams, cdc codec.JSONCodec, ak banktypes.AccountKeeper, bk keeper.Keeper, ) simulation.WeightedOperations { var weightMsgSend, weightMsgMultiSend int - appParams.GetOrGenerate(OpWeightMsgSend, &weightMsgSend, nil, + appParams.GetOrGenerate( + OpWeightMsgSend, &weightMsgSend, nil, func(*rand.Rand) { weightMsgSend = banksim.DefaultWeightMsgSend }, ) - appParams.GetOrGenerate(OpWeightMsgMultiSend, &weightMsgMultiSend, nil, + appParams.GetOrGenerate( + OpWeightMsgMultiSend, &weightMsgMultiSend, nil, func(*rand.Rand) { weightMsgMultiSend = banksim.DefaultWeightMsgMultiSend }, diff --git a/custom/staking/query_server.go b/custom/staking/query_server.go index e37adcf43..08f373e22 100644 --- a/custom/staking/query_server.go +++ b/custom/staking/query_server.go @@ -63,7 +63,8 @@ func (q *LegacyQueryServer) ensureLegacyParams(ctx context.Context) context.Cont // Only set legacy params for pre-upgrade heights legacyMode := legacyupgrade.GetLegacyHandling(sdkCtx.ChainID(), sdkCtx.BlockHeight()) - sdkCtx.Logger().Debug("Setting legacy params for pre-upgrade height queries", + sdkCtx.Logger().Debug( + "Setting legacy params for pre-upgrade height queries", "block_height", sdkCtx.BlockHeight(), "legacy_mode", legacyMode, "chain_id", sdkCtx.ChainID(), @@ -88,7 +89,8 @@ func (q *LegacyQueryServer) ensureLegacyParams(ctx context.Context) context.Cont }) // Return updated context - sdkCtx.Logger().Debug("Legacy params set for pre-upgrade height queries", + sdkCtx.Logger().Debug( + "Legacy params set for pre-upgrade height queries", "block_height", sdkCtx.BlockHeight(), "chain_id", sdkCtx.ChainID(), "params", params, @@ -110,7 +112,8 @@ func (q *LegacyQueryServer) ensureLegacyParams(ctx context.Context) context.Cont q.keeper.SetParams(sdkCtx, params) // Return updated context - sdkCtx.Logger().Debug("Legacy params set for pre-upgrade height queries", + sdkCtx.Logger().Debug( + "Legacy params set for pre-upgrade height queries", "block_height", sdkCtx.BlockHeight(), "chain_id", sdkCtx.ChainID(), "params", params, diff --git a/tests/e2e/api_regression_test.go b/tests/e2e/api_regression_test.go index 3187b50a0..dac119b64 100644 --- a/tests/e2e/api_regression_test.go +++ b/tests/e2e/api_regression_test.go @@ -251,43 +251,44 @@ func (s *IntegrationTestSuite) TestAPIRegression() { // Execute test with retries var taxResp TaxComputeResponse - s.Eventually(func() bool { - // Resolve REST API host:port from container mapping - hostPort, err := node.GetHostPort("1317/tcp") - if err != nil { - s.Suite.T().Logf("Failed to get REST port: %v", err) - return false - } - // Make API request - reqBody, err := json.Marshal(req) - if err != nil { - s.Suite.T().Logf("Failed to marshal request: %v", err) - return false - } + s.Eventually( + func() bool { + // Resolve REST API host:port from container mapping + hostPort, err := node.GetHostPort("1317/tcp") + if err != nil { + s.Suite.T().Logf("Failed to get REST port: %v", err) + return false + } + // Make API request + reqBody, err := json.Marshal(req) + if err != nil { + s.Suite.T().Logf("Failed to marshal request: %v", err) + return false + } - // Create API client - apiClient := util.NewAPIClient(fmt.Sprintf("http://%s", hostPort)) + // Create API client + apiClient := util.NewAPIClient(fmt.Sprintf("http://%s", hostPort)) - resp, err := apiClient.PostJSON("/terra/tx/v1beta1/compute_tax", reqBody) - if err != nil { - s.Suite.T().Logf("API request failed: %v", err) - return false - } + resp, err := apiClient.PostJSON("/terra/tx/v1beta1/compute_tax", reqBody) + if err != nil { + s.Suite.T().Logf("API request failed: %v", err) + return false + } - // Parse response - err = util.UnmarshalResponse(resp, &taxResp) - if err != nil { - s.Suite.T().Logf("Failed to unmarshal response: %v", err) - return false - } + // Parse response + err = util.UnmarshalResponse(resp, &taxResp) + if err != nil { + s.Suite.T().Logf("Failed to unmarshal response: %v", err) + return false + } - // Verify endpoint responds without error (this tests against regression from PR #561) - // Tax amount might be zero if addresses are exempted or due to other factors - // The main goal is ensuring the endpoint doesn't panic or return errors - s.Suite.T().Logf("Tax computation endpoint responded successfully with %d tax entries", len(taxResp.TaxAmount)) + // Verify endpoint responds without error (this tests against regression from PR #561) + // Tax amount might be zero if addresses are exempted or due to other factors + // The main goal is ensuring the endpoint doesn't panic or return errors + s.Suite.T().Logf("Tax computation endpoint responded successfully with %d tax entries", len(taxResp.TaxAmount)) - return true - }, + return true + }, 30*time.Second, // timeout 1*time.Second, // interval ) @@ -376,25 +377,26 @@ func (s *IntegrationTestSuite) TestAPIRegression() { // First, query the list of all signing infos to get a valid terravalcons address signingInfosPath := "/cosmos/slashing/v1beta1/signing_infos" var signingInfosResp SigningInfosResponse - s.Eventually(func() bool { - resp, err := apiClient.GetWithHeaders(signingInfosPath, emptyHeaders) - if err != nil { - s.Suite.T().Logf("Failed to query signing infos: %v", err) - return false - } - if resp.StatusCode != 200 { - s.Suite.T().Logf("Unexpected status code for signing infos: %d", resp.StatusCode) - return false - } + s.Eventually( + func() bool { + resp, err := apiClient.GetWithHeaders(signingInfosPath, emptyHeaders) + if err != nil { + s.Suite.T().Logf("Failed to query signing infos: %v", err) + return false + } + if resp.StatusCode != 200 { + s.Suite.T().Logf("Unexpected status code for signing infos: %d", resp.StatusCode) + return false + } - err = util.UnmarshalResponse(resp, &signingInfosResp) - if err != nil { - s.Suite.T().Logf("Failed to unmarshal signing infos response: %v", err) - return false - } + err = util.UnmarshalResponse(resp, &signingInfosResp) + if err != nil { + s.Suite.T().Logf("Failed to unmarshal signing infos response: %v", err) + return false + } - return len(signingInfosResp.Info) > 0 - }, + return len(signingInfosResp.Info) > 0 + }, 30*time.Second, 1*time.Second, ) @@ -462,28 +464,29 @@ func (s *IntegrationTestSuite) TestAPIRegression() { // Query transactions by sender address using events filter var txsResp TxsEventResponse - s.Eventually(func() bool { - // URL encode the query - the sender is txTestSender - txQueryPath := fmt.Sprintf("/cosmos/tx/v1beta1/txs?query=message.sender='%s'", txTestSender) - resp, err := apiClient.GetWithHeaders(txQueryPath, emptyHeaders) - if err != nil { - s.Suite.T().Logf("Failed to query txs: %v", err) - return false - } - if resp.StatusCode != 200 { - s.Suite.T().Logf("Unexpected status code for txs query: %d", resp.StatusCode) - return false - } + s.Eventually( + func() bool { + // URL encode the query - the sender is txTestSender + txQueryPath := fmt.Sprintf("/cosmos/tx/v1beta1/txs?query=message.sender='%s'", txTestSender) + resp, err := apiClient.GetWithHeaders(txQueryPath, emptyHeaders) + if err != nil { + s.Suite.T().Logf("Failed to query txs: %v", err) + return false + } + if resp.StatusCode != 200 { + s.Suite.T().Logf("Unexpected status code for txs query: %d", resp.StatusCode) + return false + } - err = util.UnmarshalResponse(resp, &txsResp) - if err != nil { - s.Suite.T().Logf("Failed to unmarshal txs response: %v", err) - return false - } + err = util.UnmarshalResponse(resp, &txsResp) + if err != nil { + s.Suite.T().Logf("Failed to unmarshal txs response: %v", err) + return false + } - // Should have at least one transaction from our BankSend - return len(txsResp.TxResponses) > 0 - }, + // Should have at least one transaction from our BankSend + return len(txsResp.TxResponses) > 0 + }, 30*time.Second, 1*time.Second, ) @@ -539,26 +542,27 @@ func (s *IntegrationTestSuite) TestAPIRegression() { // Query transactions by sender to get any wasm-related txs if available // This validates the middleware handles various tx types including potential wasm txs var txsResp TxsEventResponse - s.Eventually(func() bool { - txQueryPath := fmt.Sprintf("/cosmos/tx/v1beta1/txs?query=message.sender='%s'", wasmSender) - resp, err := apiClient.GetWithHeaders(txQueryPath, emptyHeaders) - if err != nil { - s.Suite.T().Logf("Failed to query txs: %v", err) - return false - } - if resp.StatusCode != 200 { - s.Suite.T().Logf("Unexpected status code: %d", resp.StatusCode) - return false - } + s.Eventually( + func() bool { + txQueryPath := fmt.Sprintf("/cosmos/tx/v1beta1/txs?query=message.sender='%s'", wasmSender) + resp, err := apiClient.GetWithHeaders(txQueryPath, emptyHeaders) + if err != nil { + s.Suite.T().Logf("Failed to query txs: %v", err) + return false + } + if resp.StatusCode != 200 { + s.Suite.T().Logf("Unexpected status code: %d", resp.StatusCode) + return false + } - err = util.UnmarshalResponse(resp, &txsResp) - if err != nil { - s.Suite.T().Logf("Failed to unmarshal response: %v", err) - return false - } + err = util.UnmarshalResponse(resp, &txsResp) + if err != nil { + s.Suite.T().Logf("Failed to unmarshal response: %v", err) + return false + } - return true - }, + return true + }, 30*time.Second, 1*time.Second, ) diff --git a/tests/e2e/configurer/base.go b/tests/e2e/configurer/base.go index 4d1c4043f..0e9339f68 100644 --- a/tests/e2e/configurer/base.go +++ b/tests/e2e/configurer/base.go @@ -121,7 +121,8 @@ func (bc *baseConfigurer) runIBCRelayer(chainConfigA *chain.Config, chainConfigB relayerNodeB.Name, filepath.Join("/root/hermes", "mnemonicB.json"), hermesContainerName, - hermesCfgPath) + hermesCfgPath, + ) /* keep commented for debugging in case of failure ctx, cancel := context.WithCancel(context.Background()) bc.t.Cleanup(cancel) // stop streaming when test finishes diff --git a/tests/e2e/configurer/factory.go b/tests/e2e/configurer/factory.go index f33bd2ca5..de1caece9 100644 --- a/tests/e2e/configurer/factory.go +++ b/tests/e2e/configurer/factory.go @@ -135,7 +135,8 @@ func New(t *testing.T, isIBCEnabled, isDebugLogEnabled bool) (Configurer, error) } if isIBCEnabled { // configure two chains from current Git branch - return NewCurrentBranchConfigurer(t, + return NewCurrentBranchConfigurer( + t, []*chain.Config{ chain.New(t, containerManager, initialization.ChainAID, validatorConfigsChainA), chain.New(t, containerManager, initialization.ChainBID, validatorConfigsChainB), @@ -147,7 +148,8 @@ func New(t *testing.T, isIBCEnabled, isDebugLogEnabled bool) (Configurer, error) } // configure one chain from current Git branch - return NewCurrentBranchConfigurer(t, + return NewCurrentBranchConfigurer( + t, []*chain.Config{ chain.New(t, containerManager, initialization.ChainAID, validatorConfigsChainA), }, diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 7b9a03c8c..d66b6d23f 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -27,7 +27,8 @@ func (s *IntegrationTestSuite) TestIBCWasmHooks() { nodeA.InstantiateWasmContract( strconv.Itoa(chainA.LatestCodeID), `{"count": "0"}`, "", - initialization.ValidatorWalletName) + initialization.ValidatorWalletName, + ) contracts, err := nodeA.QueryContractsFromID(chainA.LatestCodeID) s.NoError(err) @@ -57,30 +58,31 @@ func (s *IntegrationTestSuite) TestIBCWasmHooks() { response, err = nodeA.QueryWasmSmart(contractAddr, `{"get_total_funds": {}}`) s.Require().NoError(err) - s.Eventually(func() bool { - response, err = nodeA.QueryWasmSmart(contractAddr, `{"get_total_funds": {}}`) - if err != nil { - return false - } + s.Eventually( + func() bool { + response, err = nodeA.QueryWasmSmart(contractAddr, `{"get_total_funds": {}}`) + if err != nil { + return false + } - totalFunds := response.([]interface{})[0] - amount, err := strconv.ParseInt(totalFunds.(map[string]interface{})["amount"].(string), 10, 64) - if err != nil { - return false - } - denom := totalFunds.(map[string]interface{})["denom"].(string) + totalFunds := response.([]interface{})[0] + amount, err := strconv.ParseInt(totalFunds.(map[string]interface{})["amount"].(string), 10, 64) + if err != nil { + return false + } + denom := totalFunds.(map[string]interface{})["denom"].(string) - response, err = nodeA.QueryWasmSmart(contractAddr, `{"get_count": {}}`) - if err != nil { - return false - } - count, err := strconv.ParseInt(response.(string), 10, 64) - if err != nil { - return false - } - // check if denom is uluna token ibc - return sdkmath.NewInt(amount).Equal(transferAmount) && denom == initialization.TerraIBCDenom && count == 1 - }, + response, err = nodeA.QueryWasmSmart(contractAddr, `{"get_count": {}}`) + if err != nil { + return false + } + count, err := strconv.ParseInt(response.(string), 10, 64) + if err != nil { + return false + } + // check if denom is uluna token ibc + return sdkmath.NewInt(amount).Equal(transferAmount) && denom == initialization.TerraIBCDenom && count == 1 + }, 30*time.Second, 10*time.Millisecond, ) @@ -230,7 +232,8 @@ func (s *IntegrationTestSuite) TestFeeTaxWasm() { node.InstantiateWasmContract( strconv.Itoa(chain.LatestCodeID), `{"count": "0"}`, transferCoin.String(), - "test") + "test", + ) contracts, err := node.QueryContractsFromID(chain.LatestCodeID) s.Require().NoError(err) @@ -248,7 +251,8 @@ func (s *IntegrationTestSuite) TestFeeTaxWasm() { strconv.Itoa(chain.LatestCodeID), `{"count": "0"}`, "salt", transferCoin.String(), - fmt.Sprintf("%duluna", stabilityFee), "300000", "test") + fmt.Sprintf("%duluna", stabilityFee), "300000", "test", + ) contracts, err = node.QueryContractsFromID(chain.LatestCodeID) s.Require().NoError(err) diff --git a/types/util/blocks.go b/types/util/blocks.go index ae957d5e7..be783c4ee 100644 --- a/types/util/blocks.go +++ b/types/util/blocks.go @@ -15,5 +15,5 @@ const ( // IsPeriodLastBlock returns true if we are at the last block of the period func IsPeriodLastBlock(ctx sdk.Context, blocksPerPeriod uint64) bool { - return ((uint64)(ctx.BlockHeight())+1)%blocksPerPeriod == 0 + return (uint64(ctx.BlockHeight())+1)%blocksPerPeriod == 0 } diff --git a/x/cron/genesis.go b/x/cron/genesis.go index 5e455ef1e..9bb2b1451 100644 --- a/x/cron/genesis.go +++ b/x/cron/genesis.go @@ -1,10 +1,9 @@ package cron import ( - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/classic-terra/core/v4/x/cron/keeper" "github.com/classic-terra/core/v4/x/cron/types" + sdk "github.com/cosmos/cosmos-sdk/types" ) func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) { diff --git a/x/cron/keeper/grpc_query.go b/x/cron/keeper/grpc_query.go index be19fae16..f0cd9ccdb 100644 --- a/x/cron/keeper/grpc_query.go +++ b/x/cron/keeper/grpc_query.go @@ -4,12 +4,11 @@ import ( "context" "cosmossdk.io/store/prefix" + "github.com/classic-terra/core/v4/x/cron/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - - "github.com/classic-terra/core/v4/x/cron/types" ) func (k Keeper) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { diff --git a/x/cron/keeper/keeper.go b/x/cron/keeper/keeper.go index 710e3e769..5a1cde3df 100644 --- a/x/cron/keeper/keeper.go +++ b/x/cron/keeper/keeper.go @@ -6,10 +6,9 @@ import ( "cosmossdk.io/store/prefix" storetypes "cosmossdk.io/store/types" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + "github.com/classic-terra/core/v4/x/cron/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/classic-terra/core/v4/x/cron/types" ) type Keeper struct { @@ -165,7 +164,8 @@ func (k Keeper) executeSchedule(ctx sdk.Context, schedule types.Schedule) (err e err = fmt.Errorf("cron execute out of gas: %s", oog.Descriptor) schedule.LastExecutionError = lastExecutionErr(currentContract, err) k.storeSchedule(ctx, schedule) - ctx.Logger().Info("cron execute out of gas", + ctx.Logger().Info( + "cron execute out of gas", "schedule_name", schedule.Name, "contract", currentContract, "max_execution_gas", params.MaxExecutionGas, @@ -176,7 +176,8 @@ func (k Keeper) executeSchedule(ctx sdk.Context, schedule types.Schedule) (err e err = fmt.Errorf("cron execute panic: %v", r) schedule.LastExecutionError = lastExecutionErr(currentContract, err) k.storeSchedule(ctx, schedule) - ctx.Logger().Info("cron execute panic", + ctx.Logger().Info( + "cron execute panic", "schedule_name", schedule.Name, "contract", currentContract, "error", err, @@ -196,7 +197,8 @@ func (k Keeper) executeSchedule(ctx sdk.Context, schedule types.Schedule) (err e if _, err := k.WasmMsgServer.ExecuteContract(sdk.WrapSDKContext(limitedCtx), &executeMsg); err != nil { schedule.LastExecutionError = lastExecutionErr(msg.Contract, err) k.storeSchedule(ctx, schedule) - ctx.Logger().Info("cron execute failed", + ctx.Logger().Info( + "cron execute failed", "schedule_name", schedule.Name, "contract", msg.Contract, "error", err, diff --git a/x/cron/keeper/msg_server.go b/x/cron/keeper/msg_server.go index 0234172e4..6c9d854b3 100644 --- a/x/cron/keeper/msg_server.go +++ b/x/cron/keeper/msg_server.go @@ -4,10 +4,9 @@ import ( "context" "cosmossdk.io/errors" + "github.com/classic-terra/core/v4/x/cron/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - - "github.com/classic-terra/core/v4/x/cron/types" ) type msgServer struct { diff --git a/x/cron/keeper/params.go b/x/cron/keeper/params.go index f5cad24bf..aaa61e7d1 100644 --- a/x/cron/keeper/params.go +++ b/x/cron/keeper/params.go @@ -1,8 +1,9 @@ package keeper -import sdk "github.com/cosmos/cosmos-sdk/types" - -import "github.com/classic-terra/core/v4/x/cron/types" +import ( + "github.com/classic-terra/core/v4/x/cron/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { store := ctx.KVStore(k.storeKey) diff --git a/x/cron/types/genesis_test.go b/x/cron/types/genesis_test.go index a2fae9835..9f7011787 100644 --- a/x/cron/types/genesis_test.go +++ b/x/cron/types/genesis_test.go @@ -1,8 +1,10 @@ package types -import "testing" +import ( + "testing" -import "github.com/stretchr/testify/require" + "github.com/stretchr/testify/require" +) func TestGenesisValidate(t *testing.T) { require.NoError(t, DefaultGenesisState().Validate()) diff --git a/x/dyncomm/ante/ante_test.go b/x/dyncomm/ante/ante_test.go index 394e650df..9b3127a48 100644 --- a/x/dyncomm/ante/ante_test.go +++ b/x/dyncomm/ante/ante_test.go @@ -89,7 +89,8 @@ func (suite *AnteTestSuite) CreateTestTx(privs []cryptotypes.PrivKey, accNums [] } sigV2, err := tx.SignWithPrivKey( context.Background(), signing.SignMode(suite.clientCtx.TxConfig.SignModeHandler().DefaultMode()), signerData, - suite.txBuilder, priv, suite.clientCtx.TxConfig, accSeqs[i]) + suite.txBuilder, priv, suite.clientCtx.TxConfig, accSeqs[i], + ) if err != nil { return nil, err } diff --git a/x/dyncomm/client/cli/query.go b/x/dyncomm/client/cli/query.go index 55cb4e18f..7fe3053b0 100644 --- a/x/dyncomm/client/cli/query.go +++ b/x/dyncomm/client/cli/query.go @@ -47,7 +47,8 @@ func GetCmdQueryRate() *cobra.Command { return err } - res, err := queryClient.Rate(context.Background(), + res, err := queryClient.Rate( + context.Background(), &types.QueryRateRequest{ValidatorAddr: addr.String()}, ) if err != nil { diff --git a/x/market/client/cli/query.go b/x/market/client/cli/query.go index 08e0f6371..f4dbb42dc 100644 --- a/x/market/client/cli/query.go +++ b/x/market/client/cli/query.go @@ -57,7 +57,8 @@ $ terrad query swap 5000000uluna usdr askDenom := args[1] - res, err := queryClient.Swap(context.Background(), + res, err := queryClient.Swap( + context.Background(), &types.QuerySwapRequest{OfferCoin: offerCoinStr, AskDenom: askDenom}, ) if err != nil { @@ -90,7 +91,8 @@ $ terrad query market terra-pool-delta } queryClient := types.NewQueryClient(clientCtx) - res, err := queryClient.TerraPoolDelta(context.Background(), + res, err := queryClient.TerraPoolDelta( + context.Background(), &types.QueryTerraPoolDeltaRequest{}, ) if err != nil { diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index d8d2332bb..d9d1479c5 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -32,13 +32,13 @@ func TestReplenishPools(t *testing.T) { require.True(t, terraPoolDelta.IsZero()) // Positive delta - diff := basePool.QuoInt64((int64)(core.BlocksPerDay)) + diff := basePool.QuoInt64(int64(core.BlocksPerDay)) input.MarketKeeper.SetTerraPoolDelta(input.Ctx, diff) input.MarketKeeper.ReplenishPools(input.Ctx) terraPoolDelta = input.MarketKeeper.GetTerraPoolDelta(input.Ctx) - replenishAmt := diff.QuoInt64((int64)(input.MarketKeeper.PoolRecoveryPeriod(input.Ctx))) + replenishAmt := diff.QuoInt64(int64(input.MarketKeeper.PoolRecoveryPeriod(input.Ctx))) expectedDelta := diff.Sub(replenishAmt) require.Equal(t, expectedDelta, terraPoolDelta) @@ -49,7 +49,7 @@ func TestReplenishPools(t *testing.T) { input.MarketKeeper.ReplenishPools(input.Ctx) terraPoolDelta = input.MarketKeeper.GetTerraPoolDelta(input.Ctx) - replenishAmt = diff.QuoInt64((int64)(input.MarketKeeper.PoolRecoveryPeriod(input.Ctx))) + replenishAmt = diff.QuoInt64(int64(input.MarketKeeper.PoolRecoveryPeriod(input.Ctx))) expectedDelta = diff.Sub(replenishAmt) require.Equal(t, expectedDelta, terraPoolDelta) } diff --git a/x/market/simulation/operations.go b/x/market/simulation/operations.go index 3c6c75797..efc4808e0 100644 --- a/x/market/simulation/operations.go +++ b/x/market/simulation/operations.go @@ -35,7 +35,8 @@ func WeightedOperations( ok types.OracleKeeper, ) simulation.WeightedOperations { var weightMsgSwap int - appParams.GetOrGenerate(OpWeightMsgSwap, &weightMsgSwap, nil, + appParams.GetOrGenerate( + OpWeightMsgSwap, &weightMsgSwap, nil, func(*rand.Rand) { weightMsgSwap = banksim.DefaultWeightMsgSend }, diff --git a/x/market/simulation/params.go b/x/market/simulation/params.go index 99d2b4711..28e441ff2 100644 --- a/x/market/simulation/params.go +++ b/x/market/simulation/params.go @@ -15,17 +15,20 @@ import ( // on the simulation func ParamChanges(*rand.Rand) []simtypes.LegacyParamChange { return []simtypes.LegacyParamChange{ - simulation.NewSimLegacyParamChange(types.ModuleName, string(types.KeyBasePool), + simulation.NewSimLegacyParamChange( + types.ModuleName, string(types.KeyBasePool), func(r *rand.Rand) string { return fmt.Sprintf("\"%s\"", GenBasePool(r)) }, ), - simulation.NewSimLegacyParamChange(types.ModuleName, string(types.KeyPoolRecoveryPeriod), + simulation.NewSimLegacyParamChange( + types.ModuleName, string(types.KeyPoolRecoveryPeriod), func(r *rand.Rand) string { return fmt.Sprintf("\"%d\"", GenPoolRecoveryPeriod(r)) }, ), - simulation.NewSimLegacyParamChange(types.ModuleName, string(types.KeyMinStabilitySpread), + simulation.NewSimLegacyParamChange( + types.ModuleName, string(types.KeyMinStabilitySpread), func(r *rand.Rand) string { return fmt.Sprintf("\"%s\"", GenMinSpread(r)) }, diff --git a/x/market/types/codec.go b/x/market/types/codec.go index 8eb95f8cd..319e50160 100644 --- a/x/market/types/codec.go +++ b/x/market/types/codec.go @@ -18,7 +18,8 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { // RegisterInterfaces registers the x/market interfaces types with the interface registry func RegisterInterfaces(registry codectypes.InterfaceRegistry) { - registry.RegisterImplementations((*sdk.Msg)(nil), + registry.RegisterImplementations( + (*sdk.Msg)(nil), &MsgSwap{}, &MsgSwapSend{}, ) diff --git a/x/oracle/abci.go b/x/oracle/abci.go index f31605db3..ed39c1fc2 100644 --- a/x/oracle/abci.go +++ b/x/oracle/abci.go @@ -114,8 +114,8 @@ func EndBlocker(ctx sdk.Context, k keeper.Keeper) { // Distribute rewards to ballot winners k.RewardBallotWinners( ctx, - (int64)(params.VotePeriod), - (int64)(params.RewardDistributionWindow), + int64(params.VotePeriod), + int64(params.RewardDistributionWindow), voteTargets, validatorClaimMap, ) diff --git a/x/oracle/abci_test.go b/x/oracle/abci_test.go index 406e433fa..c7013d482 100644 --- a/x/oracle/abci_test.go +++ b/x/oracle/abci_test.go @@ -149,7 +149,8 @@ func TestOracleTally(t *testing.T) { } vote := types.NewVoteForTally( - decExchangeRate, core.MicroSDRDenom, valAddrs[i], power) + decExchangeRate, core.MicroSDRDenom, valAddrs[i], power, + ) ballot = append(ballot, vote) // change power of every three validator diff --git a/x/oracle/keeper/ballot.go b/x/oracle/keeper/ballot.go index aef12cf17..c89d7c557 100644 --- a/x/oracle/keeper/ballot.go +++ b/x/oracle/keeper/ballot.go @@ -29,7 +29,8 @@ func (k Keeper) OrganizeBallotByDenom(ctx sdk.Context, validatorClaimMap map[str tmpPower = 0 } - votes[tuple.Denom] = append(votes[tuple.Denom], + votes[tuple.Denom] = append( + votes[tuple.Denom], types.NewVoteForTally( tuple.ExchangeRate, tuple.Denom, diff --git a/x/oracle/keeper/keeper.go b/x/oracle/keeper/keeper.go index 6ebb4c96c..9c9846bab 100644 --- a/x/oracle/keeper/keeper.go +++ b/x/oracle/keeper/keeper.go @@ -100,7 +100,8 @@ func (k Keeper) SetLunaExchangeRate(ctx sdk.Context, denom string, exchangeRate func (k Keeper) SetLunaExchangeRateWithEvent(ctx sdk.Context, denom string, exchangeRate math.LegacyDec) { k.SetLunaExchangeRate(ctx, denom, exchangeRate) ctx.EventManager().EmitEvent( - sdk.NewEvent(types.EventTypeExchangeRateUpdate, + sdk.NewEvent( + types.EventTypeExchangeRateUpdate, sdk.NewAttribute(types.AttributeKeyDenom, denom), sdk.NewAttribute(types.AttributeKeyExchangeRate, exchangeRate.String()), ), diff --git a/x/oracle/keeper/reward_test.go b/x/oracle/keeper/reward_test.go index 06c5df80e..cbf9c09fd 100644 --- a/x/oracle/keeper/reward_test.go +++ b/x/oracle/keeper/reward_test.go @@ -65,10 +65,10 @@ func TestRewardBallotWinners(t *testing.T) { return false }) - votePeriodsPerWindow := sdkmath.LegacyNewDec((int64)(input.OracleKeeper.RewardDistributionWindow(input.Ctx))). - QuoInt64((int64)(input.OracleKeeper.VotePeriod(input.Ctx))). + votePeriodsPerWindow := sdkmath.LegacyNewDec(int64(input.OracleKeeper.RewardDistributionWindow(input.Ctx))). + QuoInt64(int64(input.OracleKeeper.VotePeriod(input.Ctx))). TruncateInt64() - input.OracleKeeper.RewardBallotWinners(ctx, (int64)(input.OracleKeeper.VotePeriod(input.Ctx)), (int64)(input.OracleKeeper.RewardDistributionWindow(input.Ctx)), voteTargets, claims) + input.OracleKeeper.RewardBallotWinners(ctx, int64(input.OracleKeeper.VotePeriod(input.Ctx)), int64(input.OracleKeeper.RewardDistributionWindow(input.Ctx)), voteTargets, claims) outstandingRewardsDec, err := input.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, addr) require.NoError(t, err) outstandingRewards, _ := outstandingRewardsDec.TruncateDecimal() diff --git a/x/oracle/keeper/slash.go b/x/oracle/keeper/slash.go index 140ffebdc..4e6c307d4 100644 --- a/x/oracle/keeper/slash.go +++ b/x/oracle/keeper/slash.go @@ -23,7 +23,8 @@ func (k Keeper) SlashAndResetMissCounters(ctx sdk.Context) { k.IterateMissCounters(ctx, func(operator sdk.ValAddress, missCounter uint64) bool { // Calculate valid vote rate; (SlashWindow - MissCounter)/SlashWindow validVoteRate := math.LegacyNewDecFromInt( - math.NewInt(int64(votePeriodsPerWindow - missCounter))). + math.NewInt(int64(votePeriodsPerWindow - missCounter)), + ). QuoInt64(int64(votePeriodsPerWindow)) // Penalize the validator whose the valid vote rate is smaller than min threshold diff --git a/x/oracle/simulation/operations.go b/x/oracle/simulation/operations.go index 1d311053e..e31681713 100644 --- a/x/oracle/simulation/operations.go +++ b/x/oracle/simulation/operations.go @@ -50,19 +50,22 @@ func WeightedOperations( weightMsgAggregateExchangeRateVote int weightMsgDelegateFeedConsent int ) - appParams.GetOrGenerate(OpWeightMsgAggregateExchangeRatePrevote, &weightMsgAggregateExchangeRatePrevote, nil, + appParams.GetOrGenerate( + OpWeightMsgAggregateExchangeRatePrevote, &weightMsgAggregateExchangeRatePrevote, nil, func(*rand.Rand) { weightMsgAggregateExchangeRatePrevote = banksim.DefaultWeightMsgSend * 2 }, ) - appParams.GetOrGenerate(OpWeightMsgAggregateExchangeRateVote, &weightMsgAggregateExchangeRateVote, nil, + appParams.GetOrGenerate( + OpWeightMsgAggregateExchangeRateVote, &weightMsgAggregateExchangeRateVote, nil, func(*rand.Rand) { weightMsgAggregateExchangeRateVote = banksim.DefaultWeightMsgSend * 2 }, ) - appParams.GetOrGenerate(OpWeightMsgDelegateFeedConsent, &weightMsgDelegateFeedConsent, nil, + appParams.GetOrGenerate( + OpWeightMsgDelegateFeedConsent, &weightMsgDelegateFeedConsent, nil, func(*rand.Rand) { weightMsgDelegateFeedConsent = distrsim.DefaultWeightMsgSetWithdrawAddress }, diff --git a/x/oracle/simulation/params.go b/x/oracle/simulation/params.go index 12f2ba82c..a6caa041f 100644 --- a/x/oracle/simulation/params.go +++ b/x/oracle/simulation/params.go @@ -15,32 +15,38 @@ import ( // on the simulation func ParamChanges(*rand.Rand) []simtypes.LegacyParamChange { return []simtypes.LegacyParamChange{ - simulation.NewSimLegacyParamChange(types.ModuleName, string(types.KeyVotePeriod), + simulation.NewSimLegacyParamChange( + types.ModuleName, string(types.KeyVotePeriod), func(r *rand.Rand) string { return fmt.Sprintf("\"%d\"", GenVotePeriod(r)) }, ), - simulation.NewSimLegacyParamChange(types.ModuleName, string(types.KeyVoteThreshold), + simulation.NewSimLegacyParamChange( + types.ModuleName, string(types.KeyVoteThreshold), func(r *rand.Rand) string { return fmt.Sprintf("\"%s\"", GenVoteThreshold(r)) }, ), - simulation.NewSimLegacyParamChange(types.ModuleName, string(types.KeyRewardBand), + simulation.NewSimLegacyParamChange( + types.ModuleName, string(types.KeyRewardBand), func(r *rand.Rand) string { return fmt.Sprintf("\"%s\"", GenRewardBand(r)) }, ), - simulation.NewSimLegacyParamChange(types.ModuleName, string(types.KeyRewardDistributionWindow), + simulation.NewSimLegacyParamChange( + types.ModuleName, string(types.KeyRewardDistributionWindow), func(r *rand.Rand) string { return fmt.Sprintf("\"%d\"", GenRewardDistributionWindow(r)) }, ), - simulation.NewSimLegacyParamChange(types.ModuleName, string(types.KeySlashFraction), + simulation.NewSimLegacyParamChange( + types.ModuleName, string(types.KeySlashFraction), func(r *rand.Rand) string { return fmt.Sprintf("\"%s\"", GenSlashFraction(r)) }, ), - simulation.NewSimLegacyParamChange(types.ModuleName, string(types.KeySlashWindow), + simulation.NewSimLegacyParamChange( + types.ModuleName, string(types.KeySlashWindow), func(r *rand.Rand) string { return fmt.Sprintf("\"%d\"", GenSlashWindow(r)) }, diff --git a/x/oracle/types/codec.go b/x/oracle/types/codec.go index a87322215..d52fa2f0d 100644 --- a/x/oracle/types/codec.go +++ b/x/oracle/types/codec.go @@ -19,7 +19,8 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { // RegisterInterfaces registers the x/oracle interfaces types with the interface registry func RegisterInterfaces(registry codectypes.InterfaceRegistry) { - registry.RegisterImplementations((*sdk.Msg)(nil), + registry.RegisterImplementations( + (*sdk.Msg)(nil), &MsgDelegateFeedConsent{}, &MsgAggregateExchangeRatePrevote{}, &MsgAggregateExchangeRateVote{}, diff --git a/x/oracle/types/test_utils.go b/x/oracle/types/test_utils.go index 03a21c00e..24d8b0200 100644 --- a/x/oracle/types/test_utils.go +++ b/x/oracle/types/test_utils.go @@ -132,12 +132,14 @@ func (v MockValidator) GetTokens() math.Int { func (v MockValidator) GetBondedTokens() math.Int { return sdk.TokensFromConsensusPower(v.power, sdk.DefaultPowerReduction) } -func (v MockValidator) GetConsensusPower(_ math.Int) int64 { return v.power } -func (v *MockValidator) SetConsensusPower(power int64) { v.power = power } -func (v MockValidator) GetCommission() math.LegacyDec { return math.LegacyZeroDec() } -func (v MockValidator) GetMinSelfDelegation() math.Int { return math.OneInt() } -func (v MockValidator) GetDelegatorShares() math.LegacyDec { return math.LegacyNewDec(v.power) } +func (v MockValidator) GetConsensusPower(_ math.Int) int64 { return v.power } +func (v *MockValidator) SetConsensusPower(power int64) { v.power = power } +func (v MockValidator) GetCommission() math.LegacyDec { return math.LegacyZeroDec() } +func (v MockValidator) GetMinSelfDelegation() math.Int { return math.OneInt() } +func (v MockValidator) GetDelegatorShares() math.LegacyDec { return math.LegacyNewDec(v.power) } + func (v MockValidator) TokensFromShares(math.LegacyDec) math.LegacyDec { return math.LegacyZeroDec() } + func (v MockValidator) TokensFromSharesTruncated(math.LegacyDec) math.LegacyDec { return math.LegacyZeroDec() } diff --git a/x/taxexemption/keeper/test_utils.go b/x/taxexemption/keeper/test_utils.go index 2808e06ee..354b44706 100644 --- a/x/taxexemption/keeper/test_utils.go +++ b/x/taxexemption/keeper/test_utils.go @@ -136,7 +136,8 @@ func CreateTestInput(t *testing.T) TestInput { authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) - taxexemptionKeeper := NewKeeper(appCodec, + taxexemptionKeeper := NewKeeper( + appCodec, keyTaxExemption, paramsKeeper.Subspace(types.ModuleName), accountKeeper, string(accountKeeper.GetModuleAddress(govtypes.ModuleName)), diff --git a/x/treasury/abci.go b/x/treasury/abci.go index 0534e26cf..4d758899a 100644 --- a/x/treasury/abci.go +++ b/x/treasury/abci.go @@ -43,7 +43,8 @@ func EndBlocker(ctx sdk.Context, k keeper.Keeper) { taxCap := k.UpdateTaxCap(ctx) ctx.EventManager().EmitEvent( - sdk.NewEvent(types.EventTypePolicyUpdate, + sdk.NewEvent( + types.EventTypePolicyUpdate, sdk.NewAttribute(types.AttributeKeyTaxRate, taxRate.String()), sdk.NewAttribute(types.AttributeKeyRewardWeight, rewardWeight.String()), sdk.NewAttribute(types.AttributeKeyTaxCap, taxCap.String()), diff --git a/x/treasury/simulation/params.go b/x/treasury/simulation/params.go index 84e644a4a..d85310ea9 100644 --- a/x/treasury/simulation/params.go +++ b/x/treasury/simulation/params.go @@ -16,39 +16,46 @@ import ( // on the simulation func ParamChanges(*rand.Rand) []simtypes.LegacyParamChange { return []simtypes.LegacyParamChange{ - simulation.NewSimLegacyParamChange(types.ModuleName, string(types.KeyTaxPolicy), + simulation.NewSimLegacyParamChange( + types.ModuleName, string(types.KeyTaxPolicy), func(r *rand.Rand) string { bz, _ := json.Marshal(GenTaxPolicy(r)) return string(bz) }, ), - simulation.NewSimLegacyParamChange(types.ModuleName, string(types.KeyRewardPolicy), + simulation.NewSimLegacyParamChange( + types.ModuleName, string(types.KeyRewardPolicy), func(r *rand.Rand) string { bz, _ := json.Marshal(GenRewardPolicy(r)) return string(bz) }, ), - simulation.NewSimLegacyParamChange(types.ModuleName, string(types.KeySeigniorageBurdenTarget), + simulation.NewSimLegacyParamChange( + types.ModuleName, string(types.KeySeigniorageBurdenTarget), func(r *rand.Rand) string { return fmt.Sprintf("\"%s\"", GenSeigniorageBurdenTarget(r)) }, ), - simulation.NewSimLegacyParamChange(types.ModuleName, string(types.KeyMiningIncrement), + simulation.NewSimLegacyParamChange( + types.ModuleName, string(types.KeyMiningIncrement), func(r *rand.Rand) string { return fmt.Sprintf("\"%s\"", GenMiningIncrement(r)) }, ), - simulation.NewSimLegacyParamChange(types.ModuleName, string(types.KeyWindowShort), + simulation.NewSimLegacyParamChange( + types.ModuleName, string(types.KeyWindowShort), func(r *rand.Rand) string { return fmt.Sprintf("\"%d\"", GenWindowShort(r)) }, ), - simulation.NewSimLegacyParamChange(types.ModuleName, string(types.KeyWindowLong), + simulation.NewSimLegacyParamChange( + types.ModuleName, string(types.KeyWindowLong), func(r *rand.Rand) string { return fmt.Sprintf("\"%d\"", GenWindowLong(r)) }, ), - simulation.NewSimLegacyParamChange(types.ModuleName, string(types.KeyWindowProbation), + simulation.NewSimLegacyParamChange( + types.ModuleName, string(types.KeyWindowProbation), func(r *rand.Rand) string { return fmt.Sprintf("\"%d\"", GenWindowProbation(r)) }, From ad9c334efe2f8fbe25bfa3e5a8f9d5a1f07771b1 Mon Sep 17 00:00:00 2001 From: ZuluSpl0it Date: Wed, 13 May 2026 13:47:00 -0500 Subject: [PATCH 5/5] fix: register app simulation flags --- app/sim_flags_test.go | 13 +++++++++++++ scripts/cron-auth-gate-test.sh | 4 ++++ scripts/cron-test.sh | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 app/sim_flags_test.go diff --git a/app/sim_flags_test.go b/app/sim_flags_test.go new file mode 100644 index 000000000..ed36e164f --- /dev/null +++ b/app/sim_flags_test.go @@ -0,0 +1,13 @@ +package app_test + +import ( + "flag" + + simcli "github.com/cosmos/cosmos-sdk/x/simulation/client/cli" +) + +func init() { + if flag.Lookup("Enabled") == nil { + simcli.GetSimulatorFlags() + } +} diff --git a/scripts/cron-auth-gate-test.sh b/scripts/cron-auth-gate-test.sh index 169d3a1ab..0de4ef832 100644 --- a/scripts/cron-auth-gate-test.sh +++ b/scripts/cron-auth-gate-test.sh @@ -59,6 +59,10 @@ if cat "$HOME_DIR/config/genesis.json" | jq -e '.app_state["gov"]["params"]["exp fi update_test_genesis '.app_state["crisis"]["constant_fee"]={"denom":"'$DENOM'","amount":"1000"}' update_test_genesis '.app_state["staking"]["params"]["bond_denom"]="'$DENOM'"' +update_test_genesis '.app_state["cron"]={ + "params":{"limit":"1","max_execution_gas":"5000000"}, + "schedule_list":[] +}' "$SED_BINARY" -i '0,/enable = false/s//enable = true/' "$HOME_DIR/config/app.toml" "$SED_BINARY" -i 's/swagger = false/swagger = true/' "$HOME_DIR/config/app.toml" diff --git a/scripts/cron-test.sh b/scripts/cron-test.sh index 397cdfe77..c7139eee2 100644 --- a/scripts/cron-test.sh +++ b/scripts/cron-test.sh @@ -63,7 +63,7 @@ fi update_test_genesis '.app_state["crisis"]["constant_fee"]={"denom":"'$DENOM'","amount":"1000"}' update_test_genesis '.app_state["staking"]["params"]["bond_denom"]="'$DENOM'"' update_test_genesis '.app_state["cron"]={ - "params":{"limit":"1"}, + "params":{"limit":"1","max_execution_gas":"5000000"}, "schedule_list":[ { "name":"cron-smoke",