From 5c3d8f19a0c47dbd8644257536279f55cbe8b40f Mon Sep 17 00:00:00 2001 From: Aleksandr Pismenskiy Date: Sun, 25 Aug 2024 15:41:01 +0300 Subject: [PATCH] make execution_stage field an array of stages --- proto/neutron/cron/query.proto | 6 + proto/neutron/cron/schedule.proto | 16 +- proto/neutron/cron/tx.proto | 9 +- proto/neutron/cron/v1/schedule.proto | 5 +- wasmbinding/bindings/msg.go | 8 +- wasmbinding/message_plugin.go | 11 +- x/cron/genesis.go | 2 +- x/cron/keeper/grpc_query_schedule_test.go | 3 +- x/cron/keeper/keeper.go | 36 ++-- x/cron/keeper/keeper_test.go | 73 +++++--- x/cron/keeper/msg_server.go | 2 +- x/cron/keeper/msg_server_test.go | 44 ++++- x/cron/migrations/v2/store.go | 2 +- x/cron/migrations/v2/store_test.go | 2 +- x/cron/module.go | 4 +- x/cron/types/query.pb.go | 6 + x/cron/types/schedule.pb.go | 186 +++++++++++++------- x/cron/types/tx.go | 4 + x/cron/types/tx.pb.go | 198 +++++++++++++++------- x/cron/types/v1/schedule.pb.go | 5 +- 20 files changed, 427 insertions(+), 195 deletions(-) diff --git a/proto/neutron/cron/query.proto b/proto/neutron/cron/query.proto index 401e9ce9d..415d7300f 100644 --- a/proto/neutron/cron/query.proto +++ b/proto/neutron/cron/query.proto @@ -30,25 +30,31 @@ service Query { // this line is used by starport scaffolding # 2 } +// QueryParamsRequest is the request type for the Query/Params RPC method. message QueryParamsRequest {} +// QueryParamsResponse is the response type for the Query/Params RPC method. message QueryParamsResponse { // params holds all the parameters of this module. Params params = 1 [(gogoproto.nullable) = false]; } +// QueryGetScheduleRequest is the request type for the Query/Schedule RPC method. message QueryGetScheduleRequest { string name = 1; } +// QueryGetScheduleResponse is the response type for the Query/Params RPC method. message QueryGetScheduleResponse { Schedule schedule = 1 [(gogoproto.nullable) = false]; } +// QuerySchedulesRequest is the request type for the Query/Schedules RPC method. message QuerySchedulesRequest { cosmos.base.query.v1beta1.PageRequest pagination = 1; } +// QuerySchedulesResponse is the response type for the Query/Params RPC method. message QuerySchedulesResponse { repeated Schedule schedules = 1 [(gogoproto.nullable) = false]; cosmos.base.query.v1beta1.PageResponse pagination = 2; diff --git a/proto/neutron/cron/schedule.proto b/proto/neutron/cron/schedule.proto index 88baf0b8a..920d0fc38 100644 --- a/proto/neutron/cron/schedule.proto +++ b/proto/neutron/cron/schedule.proto @@ -7,24 +7,27 @@ option go_package = "github.com/neutron-org/neutron/v4/x/cron/types"; // ExecutionStage defines when messages will be executed in the block enum ExecutionStage { - BEGIN_BLOCKER = 0; - END_BLOCKER = 1; - BOTH_BLOCKERS = 2; + // Execution at the end of the block + EXECUTION_STAGE_END_BLOCKER = 0; + // Execution at the beginning of the block + EXECUTION_STAGE_BEGIN_BLOCKER = 1; } +// Schedule defines the schedule for execution message Schedule { // Name of schedule string name = 1; // Period in blocks uint64 period = 2; - // Msgs that will be executed every period amount of time + // Msgs that will be executed every certain number of blocks, specified in the `period` field repeated MsgExecuteContract msgs = 3 [(gogoproto.nullable) = false]; // Last execution's block height uint64 last_execute_height = 4; - // Execution stage when messages will be executed - ExecutionStage execution_stage = 5; + // Execution stages when messages will be executed + repeated ExecutionStage execution_stages = 5 [(gogoproto.nullable) = false]; } +// MsgExecuteContract defines the contract and the message to pass message MsgExecuteContract { // Contract is the address of the smart contract string contract = 1; @@ -32,6 +35,7 @@ message MsgExecuteContract { string msg = 2; } +// ScheduleCount defines the number of current schedules message ScheduleCount { // Count is the number of current schedules int32 count = 1; diff --git a/proto/neutron/cron/tx.proto b/proto/neutron/cron/tx.proto index fde954369..9db1d58dc 100644 --- a/proto/neutron/cron/tx.proto +++ b/proto/neutron/cron/tx.proto @@ -32,11 +32,14 @@ message MsgAddSchedule { // Authority is the address of the governance account. string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; - + // Name of the schedule string name = 2; + // Period in blocks uint64 period = 3; + // Msgs that will be executed every certain number of blocks, specified in the `period` field repeated MsgExecuteContract msgs = 4 [(gogoproto.nullable) = false]; - ExecutionStage execution_stage = 5; + // Execution stages when messages will be executed + repeated ExecutionStage execution_stages = 5 [(gogoproto.nullable) = false]; } // MsgAddScheduleResponse defines the response structure for executing a @@ -50,7 +53,7 @@ message MsgRemoveSchedule { // Authority is the address of the governance account. string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; - + // Name of the schedule string name = 2; } diff --git a/proto/neutron/cron/v1/schedule.proto b/proto/neutron/cron/v1/schedule.proto index b1f824918..ec7494745 100644 --- a/proto/neutron/cron/v1/schedule.proto +++ b/proto/neutron/cron/v1/schedule.proto @@ -5,17 +5,19 @@ import "gogoproto/gogo.proto"; option go_package = "github.com/neutron-org/neutron/v4/x/cron/types/v1"; +// Schedule defines the schedule for execution message Schedule { // Name of schedule string name = 1; // Period in blocks uint64 period = 2; - // Msgs that will be executed every period amount of time + // Msgs that will be executed every certain number of blocks, specified in the `period` field repeated MsgExecuteContract msgs = 3 [(gogoproto.nullable) = false]; // Last execution's block height uint64 last_execute_height = 4; } +// MsgExecuteContract defines the contract and the message to pass message MsgExecuteContract { // Contract is the address of the smart contract string contract = 1; @@ -23,6 +25,7 @@ message MsgExecuteContract { string msg = 2; } +// ScheduleCount defines the number of current schedules message ScheduleCount { // Count is the number of current schedules int32 count = 1; diff --git a/wasmbinding/bindings/msg.go b/wasmbinding/bindings/msg.go index c1697401d..4f245ce0d 100644 --- a/wasmbinding/bindings/msg.go +++ b/wasmbinding/bindings/msg.go @@ -195,10 +195,10 @@ type ForceTransfer struct { // AddSchedule adds new schedule to the cron module type AddSchedule struct { - Name string `json:"name"` - Period uint64 `json:"period"` - Msgs []MsgExecuteContract `json:"msgs"` - ExecutionStage string `json:"execution_stage"` + Name string `json:"name"` + Period uint64 `json:"period"` + Msgs []MsgExecuteContract `json:"msgs"` + ExecutionStages []string `json:"execution_stages"` } // AddScheduleResponse holds response AddSchedule diff --git a/wasmbinding/message_plugin.go b/wasmbinding/message_plugin.go index 73c9282c9..799e48612 100644 --- a/wasmbinding/message_plugin.go +++ b/wasmbinding/message_plugin.go @@ -985,15 +985,12 @@ func (m *CustomMessenger) addSchedule(ctx sdk.Context, contractAddr sdk.AccAddre }) } - var executionStage crontypes.ExecutionStage - - if v, ok := crontypes.ExecutionStage_value[addSchedule.ExecutionStage]; !ok { - executionStage = crontypes.ExecutionStage_END_BLOCKER - } else { - executionStage = crontypes.ExecutionStage(v) + executionStages := make([]crontypes.ExecutionStage, 0, len(addSchedule.ExecutionStages)) + for _, executionStage := range addSchedule.ExecutionStages { + executionStages = append(executionStages, crontypes.ExecutionStage(crontypes.ExecutionStage_value[executionStage])) } - err := m.CronKeeper.AddSchedule(ctx, addSchedule.Name, addSchedule.Period, msgs, executionStage) + err := m.CronKeeper.AddSchedule(ctx, addSchedule.Name, addSchedule.Period, msgs, executionStages) if err != nil { ctx.Logger().Error("failed to addSchedule", "from_address", contractAddr.String(), diff --git a/x/cron/genesis.go b/x/cron/genesis.go index 525840e26..404c5dbd3 100644 --- a/x/cron/genesis.go +++ b/x/cron/genesis.go @@ -11,7 +11,7 @@ import ( func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) { // Set all the schedules for _, elem := range genState.ScheduleList { - err := k.AddSchedule(ctx, elem.Name, elem.Period, elem.Msgs, elem.ExecutionStage) + err := k.AddSchedule(ctx, elem.Name, elem.Period, elem.Msgs, elem.ExecutionStages) if err != nil { panic(err) } diff --git a/x/cron/keeper/grpc_query_schedule_test.go b/x/cron/keeper/grpc_query_schedule_test.go index 8f971f63d..78afe1517 100644 --- a/x/cron/keeper/grpc_query_schedule_test.go +++ b/x/cron/keeper/grpc_query_schedule_test.go @@ -133,8 +133,9 @@ func createNSchedule(t *testing.T, ctx sdk.Context, k *cronkeeper.Keeper, n int3 item.Period = 1000 item.Msgs = nil item.LastExecuteHeight = uint64(ctx.BlockHeight()) + item.ExecutionStages = []types.ExecutionStage{types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER} - err := k.AddSchedule(ctx, item.Name, item.Period, item.Msgs, item.ExecutionStage) + err := k.AddSchedule(ctx, item.Name, item.Period, item.Msgs, item.ExecutionStages) require.NoError(t, err) res[idx] = item diff --git a/x/cron/keeper/keeper.go b/x/cron/keeper/keeper.go index 0a9e8c0ce..460e5fc00 100644 --- a/x/cron/keeper/keeper.go +++ b/x/cron/keeper/keeper.go @@ -27,6 +27,8 @@ var ( MetricLabelSuccess = "success" MetricLabelScheduleName = "schedule_name" + + schedulesExecutionStages map[string]map[types.ExecutionStage]struct{} ) type ( @@ -47,6 +49,8 @@ func NewKeeper( accountKeeper types.AccountKeeper, authority string, ) *Keeper { + schedulesExecutionStages = make(map[string]map[types.ExecutionStage]struct{}) + return &Keeper{ cdc: cdc, storeKey: storeKey, @@ -66,42 +70,50 @@ func (k *Keeper) Logger(ctx sdk.Context) log.Logger { // ExecuteReadySchedules gets all schedules that are due for execution (with limit that is equal to Params.Limit) // and executes messages in each one -// NOTE that errors in contract calls rollback all already executed messages func (k *Keeper) ExecuteReadySchedules(ctx sdk.Context, executionStage types.ExecutionStage) { telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), LabelExecuteReadySchedules) schedules := k.getSchedulesReadyForExecution(ctx) for _, schedule := range schedules { - if isExecutableAtTheStage(schedule, executionStage) { + if _, ok := schedulesExecutionStages[schedule.Name][executionStage]; ok { err := k.executeSchedule(ctx, schedule) recordExecutedSchedule(err, schedule) } } } -// AddSchedule adds new schedule to execution for every block `period`. +// AddSchedule adds a new schedule to be executed every certain number of blocks, specified in the `period`. // First schedule execution is supposed to be on `now + period` block. func (k *Keeper) AddSchedule( ctx sdk.Context, name string, period uint64, msgs []types.MsgExecuteContract, - executionStage types.ExecutionStage, + executionStages []types.ExecutionStage, ) error { if k.scheduleExists(ctx, name) { return fmt.Errorf("schedule already exists with name=%v", name) } + schedulesExecutionStages[name] = make(map[types.ExecutionStage]struct{}) + execStages := make([]types.ExecutionStage, 0) + for _, executionStage := range executionStages { + if _, ok := types.ExecutionStage_name[int32(executionStage)]; !ok { + executionStage = types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER + } + + if _, ok := schedulesExecutionStages[name][executionStage]; !ok { + schedulesExecutionStages[name][executionStage] = struct{}{} + execStages = append(execStages, executionStage) + } + } + schedule := types.Schedule{ Name: name, Period: period, Msgs: msgs, LastExecuteHeight: uint64(ctx.BlockHeight()), // let's execute newly added schedule on `now + period` block - ExecutionStage: executionStage, - } - - if _, ok := types.ExecutionStage_name[int32(executionStage)]; !ok { - schedule.ExecutionStage = types.ExecutionStage_END_BLOCKER + ExecutionStages: execStages, } k.storeSchedule(ctx, schedule) @@ -116,6 +128,8 @@ func (k *Keeper) RemoveSchedule(ctx sdk.Context, name string) { return } + delete(schedulesExecutionStages, name) + k.changeTotalCount(ctx, -1) k.removeSchedule(ctx, name) } @@ -183,10 +197,6 @@ func (k *Keeper) getSchedulesReadyForExecution(ctx sdk.Context) []types.Schedule return res } -func isExecutableAtTheStage(schedule types.Schedule, executionStage types.ExecutionStage) bool { - return schedule.ExecutionStage == executionStage || schedule.ExecutionStage == types.ExecutionStage_BOTH_BLOCKERS -} - // executeSchedule executes all msgs in a given schedule and changes LastExecuteHeight // if at least one msg execution fails, rollback all messages func (k *Keeper) executeSchedule(ctx sdk.Context, schedule types.Schedule) error { diff --git a/x/cron/keeper/keeper_test.go b/x/cron/keeper/keeper_test.go index 3042e839b..4d3cd2956 100644 --- a/x/cron/keeper/keeper_test.go +++ b/x/cron/keeper/keeper_test.go @@ -52,7 +52,9 @@ func TestKeeperExecuteReadySchedules(t *testing.T) { }, }, LastExecuteHeight: 4, - ExecutionStage: types.ExecutionStage_BEGIN_BLOCKER, + ExecutionStages: []types.ExecutionStage{ + types.ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER, + }, }, { Name: "2_ready1", @@ -64,7 +66,9 @@ func TestKeeperExecuteReadySchedules(t *testing.T) { }, }, LastExecuteHeight: 0, - ExecutionStage: types.ExecutionStage_BEGIN_BLOCKER, + ExecutionStages: []types.ExecutionStage{ + types.ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER, + }, }, { Name: "3_ready2", @@ -76,14 +80,19 @@ func TestKeeperExecuteReadySchedules(t *testing.T) { }, }, LastExecuteHeight: 0, - ExecutionStage: types.ExecutionStage_BEGIN_BLOCKER, + ExecutionStages: []types.ExecutionStage{ + types.ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER, + }, }, { Name: "4_unready2", Period: 10, Msgs: []types.MsgExecuteContract{}, LastExecuteHeight: 4, - ExecutionStage: types.ExecutionStage_BOTH_BLOCKERS, + ExecutionStages: []types.ExecutionStage{ + types.ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER, + types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER, + }, }, { Name: "5_ready3", @@ -95,7 +104,10 @@ func TestKeeperExecuteReadySchedules(t *testing.T) { }, }, LastExecuteHeight: 0, - ExecutionStage: types.ExecutionStage_BOTH_BLOCKERS, + ExecutionStages: []types.ExecutionStage{ + types.ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER, + types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER, + }, }, { Name: "6_ready4", @@ -107,7 +119,9 @@ func TestKeeperExecuteReadySchedules(t *testing.T) { }, }, LastExecuteHeight: 0, - ExecutionStage: types.ExecutionStage_END_BLOCKER, + ExecutionStages: []types.ExecutionStage{ + types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER, + }, }, { Name: "7_ready5", @@ -119,13 +133,16 @@ func TestKeeperExecuteReadySchedules(t *testing.T) { }, }, LastExecuteHeight: 0, - ExecutionStage: types.ExecutionStage_BOTH_BLOCKERS, + ExecutionStages: []types.ExecutionStage{ + types.ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER, + types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER, + }, }, } for _, item := range schedules { ctx = ctx.WithBlockHeight(int64(item.LastExecuteHeight)) - err := k.AddSchedule(ctx, item.Name, item.Period, item.Msgs, item.ExecutionStage) + err := k.AddSchedule(ctx, item.Name, item.Period, item.Msgs, item.ExecutionStages) require.NoError(t, err) } @@ -148,7 +165,7 @@ func TestKeeperExecuteReadySchedules(t *testing.T) { Funds: sdk.NewCoins(), }).Return(&wasmtypes.MsgExecuteContractResponse{}, nil) - k.ExecuteReadySchedules(ctx, types.ExecutionStage_BEGIN_BLOCKER) + k.ExecuteReadySchedules(ctx, types.ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER) unready1, _ := k.GetSchedule(ctx, "1_unready1") ready1, _ := k.GetSchedule(ctx, "2_ready1") @@ -181,7 +198,7 @@ func TestKeeperExecuteReadySchedules(t *testing.T) { Funds: sdk.NewCoins(), }).Return(&wasmtypes.MsgExecuteContractResponse{}, nil) - k.ExecuteReadySchedules(ctx, types.ExecutionStage_END_BLOCKER) + k.ExecuteReadySchedules(ctx, types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER) unready1, _ = k.GetSchedule(ctx, "1_unready1") ready1, _ = k.GetSchedule(ctx, "2_ready1") @@ -206,7 +223,7 @@ func TestKeeperExecuteReadySchedules(t *testing.T) { Funds: sdk.NewCoins(), }).Return(&wasmtypes.MsgExecuteContractResponse{}, nil) - k.ExecuteReadySchedules(ctx, types.ExecutionStage_BEGIN_BLOCKER) + k.ExecuteReadySchedules(ctx, types.ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER) ready5, _ := k.GetSchedule(ctx, "7_ready5") @@ -221,7 +238,7 @@ func TestKeeperExecuteReadySchedules(t *testing.T) { Funds: sdk.NewCoins(), }).Return(&wasmtypes.MsgExecuteContractResponse{}, nil) - k.ExecuteReadySchedules(ctx, types.ExecutionStage_END_BLOCKER) + k.ExecuteReadySchedules(ctx, types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER) ready5, _ = k.GetSchedule(ctx, "7_ready5") @@ -250,7 +267,7 @@ func TestAddSchedule(t *testing.T) { Contract: "c", Msg: "m", }, - }, 0) + }, []types.ExecutionStage{types.ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER}) require.NoError(t, err) err = k.AddSchedule(ctx, "b", 7, []types.MsgExecuteContract{ @@ -258,7 +275,7 @@ func TestAddSchedule(t *testing.T) { Contract: "c", Msg: "m", }, - }, 1) + }, []types.ExecutionStage{types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER}) require.NoError(t, err) err = k.AddSchedule(ctx, "c", 7, []types.MsgExecuteContract{ @@ -266,7 +283,10 @@ func TestAddSchedule(t *testing.T) { Contract: "c", Msg: "m", }, - }, 2) + }, []types.ExecutionStage{ + types.ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER, + types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER, + }) require.NoError(t, err) err = k.AddSchedule(ctx, "d", 7, []types.MsgExecuteContract{ @@ -274,11 +294,13 @@ func TestAddSchedule(t *testing.T) { Contract: "c", Msg: "m", }, - }, 7) + }, []types.ExecutionStage{7}) require.NoError(t, err) // second time with same name returns error - err = k.AddSchedule(ctx, "a", 5, []types.MsgExecuteContract{}, 1) + err = k.AddSchedule(ctx, "a", 5, []types.MsgExecuteContract{}, []types.ExecutionStage{ + types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER, + }) require.Error(t, err) scheduleA, found := k.GetSchedule(ctx, "a") @@ -291,10 +313,13 @@ func TestAddSchedule(t *testing.T) { schedules := k.GetAllSchedules(ctx) require.Len(t, schedules, 4) - require.Equal(t, schedules[0].ExecutionStage, types.ExecutionStage_BEGIN_BLOCKER) - require.Equal(t, schedules[1].ExecutionStage, types.ExecutionStage_END_BLOCKER) - require.Equal(t, schedules[2].ExecutionStage, types.ExecutionStage_BOTH_BLOCKERS) - require.Equal(t, schedules[3].ExecutionStage, types.ExecutionStage_END_BLOCKER) + require.Equal(t, schedules[0].ExecutionStages, []types.ExecutionStage{types.ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER}) + require.Equal(t, schedules[1].ExecutionStages, []types.ExecutionStage{types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER}) + require.Equal(t, schedules[2].ExecutionStages, []types.ExecutionStage{ + types.ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER, + types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER, + }) + require.Equal(t, schedules[3].ExecutionStages, []types.ExecutionStage{types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER}) // remove schedule works k.RemoveSchedule(ctx, "a") @@ -321,10 +346,12 @@ func TestGetAllSchedules(t *testing.T) { Period: 5, Msgs: nil, LastExecuteHeight: uint64(ctx.BlockHeight()), - ExecutionStage: types.ExecutionStage_END_BLOCKER, + ExecutionStages: []types.ExecutionStage{ + types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER, + }, } expectedSchedules = append(expectedSchedules, s) - err := k.AddSchedule(ctx, s.Name, s.Period, s.Msgs, s.ExecutionStage) + err := k.AddSchedule(ctx, s.Name, s.Period, s.Msgs, s.ExecutionStages) require.NoError(t, err) } diff --git a/x/cron/keeper/msg_server.go b/x/cron/keeper/msg_server.go index 03f84220f..8751cd800 100644 --- a/x/cron/keeper/msg_server.go +++ b/x/cron/keeper/msg_server.go @@ -34,7 +34,7 @@ func (k msgServer) AddSchedule(goCtx context.Context, req *types.MsgAddSchedule) } ctx := sdk.UnwrapSDKContext(goCtx) - if err := k.Keeper.AddSchedule(ctx, req.Name, req.Period, req.Msgs, req.ExecutionStage); err != nil { + if err := k.Keeper.AddSchedule(ctx, req.Name, req.Period, req.Msgs, req.ExecutionStages); err != nil { return nil, err } diff --git a/x/cron/keeper/msg_server_test.go b/x/cron/keeper/msg_server_test.go index c1d4b6e79..a523def37 100644 --- a/x/cron/keeper/msg_server_test.go +++ b/x/cron/keeper/msg_server_test.go @@ -32,7 +32,9 @@ func TestMsgAddScheduleValidate(t *testing.T) { Msg: "msg", }, }, - ExecutionStage: types.ExecutionStage_BEGIN_BLOCKER, + ExecutionStages: []types.ExecutionStage{ + types.ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER, + }, }, "authority is invalid", }, @@ -48,7 +50,9 @@ func TestMsgAddScheduleValidate(t *testing.T) { Msg: "msg", }, }, - ExecutionStage: types.ExecutionStage_BEGIN_BLOCKER, + ExecutionStages: []types.ExecutionStage{ + types.ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER, + }, }, "authority is invalid", }, @@ -64,7 +68,9 @@ func TestMsgAddScheduleValidate(t *testing.T) { Msg: "msg", }, }, - ExecutionStage: types.ExecutionStage_BEGIN_BLOCKER, + ExecutionStages: []types.ExecutionStage{ + types.ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER, + }, }, "name is invalid", }, @@ -80,21 +86,41 @@ func TestMsgAddScheduleValidate(t *testing.T) { Msg: "msg", }, }, - ExecutionStage: types.ExecutionStage_BEGIN_BLOCKER, + ExecutionStages: []types.ExecutionStage{ + types.ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER, + }, }, "period is invalid", }, { "empty msgs", types.MsgAddSchedule{ - Authority: testutil.TestOwnerAddress, - Name: "name", - Period: 3, - Msgs: []types.MsgExecuteContract{}, - ExecutionStage: types.ExecutionStage_BEGIN_BLOCKER, + Authority: testutil.TestOwnerAddress, + Name: "name", + Period: 3, + Msgs: []types.MsgExecuteContract{}, + ExecutionStages: []types.ExecutionStage{ + types.ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER, + }, }, "msgs should not be empty", }, + { + "empty execution stages", + types.MsgAddSchedule{ + Authority: testutil.TestOwnerAddress, + Name: "name", + Period: 3, + Msgs: []types.MsgExecuteContract{ + { + Contract: "contract", + Msg: "msg", + }, + }, + ExecutionStages: []types.ExecutionStage{}, + }, + "execution stages should not be empty", + }, } for _, tt := range tests { diff --git a/x/cron/migrations/v2/store.go b/x/cron/migrations/v2/store.go index 0f519a64d..c22e73fdb 100644 --- a/x/cron/migrations/v2/store.go +++ b/x/cron/migrations/v2/store.go @@ -32,7 +32,7 @@ func migrateSchedules(ctx sdk.Context, cdc codec.BinaryCodec, storeKey storetype var schedule types.Schedule cdc.MustUnmarshal(iterator.Value(), &schedule) // Set execution in EndBlocker - schedule.ExecutionStage = types.ExecutionStage_END_BLOCKER + schedule.ExecutionStages = []types.ExecutionStage{types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER} schedulesToUpdate = append(schedulesToUpdate, migrationUpdate{ key: iterator.Key(), diff --git a/x/cron/migrations/v2/store_test.go b/x/cron/migrations/v2/store_test.go index 9757f508a..f065837af 100644 --- a/x/cron/migrations/v2/store_test.go +++ b/x/cron/migrations/v2/store_test.go @@ -49,5 +49,5 @@ func (suite *V2CronMigrationTestSuite) TestScheduleUpgrade() { // Check Schedule has correct ExecutionStage newSchedule, _ := app.CronKeeper.GetSchedule(ctx, schedule.Name) - suite.Equal(newSchedule.ExecutionStage, types.ExecutionStage_END_BLOCKER) + suite.Equal(newSchedule.ExecutionStages, []types.ExecutionStage{types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER}) } diff --git a/x/cron/module.go b/x/cron/module.go index b865fa43a..3471b0379 100644 --- a/x/cron/module.go +++ b/x/cron/module.go @@ -156,11 +156,11 @@ func (AppModule) ConsensusVersion() uint64 { return types.ConsensusVersion } // BeginBlock contains the logic that is automatically triggered at the beginning of each block func (am AppModule) BeginBlock(ctx sdk.Context) { - am.keeper.ExecuteReadySchedules(ctx, types.ExecutionStage_BEGIN_BLOCKER) + am.keeper.ExecuteReadySchedules(ctx, types.ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER) } // EndBlock contains the logic that is automatically triggered at the end of each block func (am AppModule) EndBlock(ctx context.Context) ([]abci.ValidatorUpdate, error) { - am.keeper.ExecuteReadySchedules(sdk.UnwrapSDKContext(ctx), types.ExecutionStage_END_BLOCKER) + am.keeper.ExecuteReadySchedules(sdk.UnwrapSDKContext(ctx), types.ExecutionStage_EXECUTION_STAGE_END_BLOCKER) return []abci.ValidatorUpdate{}, nil } diff --git a/x/cron/types/query.pb.go b/x/cron/types/query.pb.go index c34c6c3f9..6ba041f07 100644 --- a/x/cron/types/query.pb.go +++ b/x/cron/types/query.pb.go @@ -30,6 +30,7 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +// QueryParamsRequest is the request type for the Query/Params RPC method. type QueryParamsRequest struct { } @@ -66,6 +67,7 @@ func (m *QueryParamsRequest) XXX_DiscardUnknown() { var xxx_messageInfo_QueryParamsRequest proto.InternalMessageInfo +// QueryParamsResponse is the response type for the Query/Params RPC method. type QueryParamsResponse struct { // params holds all the parameters of this module. Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` @@ -111,6 +113,7 @@ func (m *QueryParamsResponse) GetParams() Params { return Params{} } +// QueryGetScheduleRequest is the request type for the Query/Schedule RPC method. type QueryGetScheduleRequest struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } @@ -155,6 +158,7 @@ func (m *QueryGetScheduleRequest) GetName() string { return "" } +// QueryGetScheduleResponse is the response type for the Query/Params RPC method. type QueryGetScheduleResponse struct { Schedule Schedule `protobuf:"bytes,1,opt,name=schedule,proto3" json:"schedule"` } @@ -199,6 +203,7 @@ func (m *QueryGetScheduleResponse) GetSchedule() Schedule { return Schedule{} } +// QuerySchedulesRequest is the request type for the Query/Schedules RPC method. type QuerySchedulesRequest struct { Pagination *query.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -243,6 +248,7 @@ func (m *QuerySchedulesRequest) GetPagination() *query.PageRequest { return nil } +// QuerySchedulesResponse is the response type for the Query/Params RPC method. 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"` diff --git a/x/cron/types/schedule.pb.go b/x/cron/types/schedule.pb.go index d948efa4f..5599c1e91 100644 --- a/x/cron/types/schedule.pb.go +++ b/x/cron/types/schedule.pb.go @@ -27,21 +27,20 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type ExecutionStage int32 const ( - ExecutionStage_BEGIN_BLOCKER ExecutionStage = 0 - ExecutionStage_END_BLOCKER ExecutionStage = 1 - ExecutionStage_BOTH_BLOCKERS ExecutionStage = 2 + // Execution at the end of the block + ExecutionStage_EXECUTION_STAGE_END_BLOCKER ExecutionStage = 0 + // Execution at the beginning of the block + ExecutionStage_EXECUTION_STAGE_BEGIN_BLOCKER ExecutionStage = 1 ) var ExecutionStage_name = map[int32]string{ - 0: "BEGIN_BLOCKER", - 1: "END_BLOCKER", - 2: "BOTH_BLOCKERS", + 0: "EXECUTION_STAGE_END_BLOCKER", + 1: "EXECUTION_STAGE_BEGIN_BLOCKER", } var ExecutionStage_value = map[string]int32{ - "BEGIN_BLOCKER": 0, - "END_BLOCKER": 1, - "BOTH_BLOCKERS": 2, + "EXECUTION_STAGE_END_BLOCKER": 0, + "EXECUTION_STAGE_BEGIN_BLOCKER": 1, } func (x ExecutionStage) String() string { @@ -52,17 +51,18 @@ func (ExecutionStage) EnumDescriptor() ([]byte, []int) { return fileDescriptor_49ace1b59de613ef, []int{0} } +// Schedule defines the schedule for execution type Schedule struct { // Name of schedule Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // Period in blocks Period uint64 `protobuf:"varint,2,opt,name=period,proto3" json:"period,omitempty"` - // Msgs that will be executed every period amount of time + // Msgs that will be executed every certain number of blocks, specified in the `period` field Msgs []MsgExecuteContract `protobuf:"bytes,3,rep,name=msgs,proto3" json:"msgs"` // Last execution's block height LastExecuteHeight uint64 `protobuf:"varint,4,opt,name=last_execute_height,json=lastExecuteHeight,proto3" json:"last_execute_height,omitempty"` - // Execution stage when messages will be executed - ExecutionStage ExecutionStage `protobuf:"varint,5,opt,name=execution_stage,json=executionStage,proto3,enum=neutron.cron.ExecutionStage" json:"execution_stage,omitempty"` + // Execution stages when messages will be executed + ExecutionStages []ExecutionStage `protobuf:"varint,5,rep,packed,name=execution_stages,json=executionStages,proto3,enum=neutron.cron.ExecutionStage" json:"execution_stages,omitempty"` } func (m *Schedule) Reset() { *m = Schedule{} } @@ -126,13 +126,14 @@ func (m *Schedule) GetLastExecuteHeight() uint64 { return 0 } -func (m *Schedule) GetExecutionStage() ExecutionStage { +func (m *Schedule) GetExecutionStages() []ExecutionStage { if m != nil { - return m.ExecutionStage + return m.ExecutionStages } - return ExecutionStage_BEGIN_BLOCKER + return nil } +// MsgExecuteContract defines the contract and the message to pass type MsgExecuteContract struct { // Contract is the address of the smart contract Contract string `protobuf:"bytes,1,opt,name=contract,proto3" json:"contract,omitempty"` @@ -187,6 +188,7 @@ func (m *MsgExecuteContract) GetMsg() string { return "" } +// ScheduleCount defines the number of current schedules type ScheduleCount struct { // Count is the number of current schedules Count int32 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"` @@ -242,31 +244,32 @@ func init() { func init() { proto.RegisterFile("neutron/cron/schedule.proto", fileDescriptor_49ace1b59de613ef) } var fileDescriptor_49ace1b59de613ef = []byte{ - // 383 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x52, 0x4f, 0x6b, 0xe2, 0x40, - 0x1c, 0xcd, 0x68, 0x14, 0x1d, 0xd7, 0x7f, 0xb3, 0xb2, 0x04, 0x77, 0xc9, 0x06, 0x61, 0x21, 0x2c, - 0x6c, 0x02, 0xee, 0x9e, 0xf6, 0x18, 0x37, 0xe8, 0xd2, 0x56, 0x21, 0xf6, 0xd4, 0x4b, 0x88, 0x71, - 0x98, 0x04, 0x4c, 0x46, 0x32, 0x93, 0x62, 0xbf, 0x45, 0x3f, 0x96, 0x47, 0x8f, 0x3d, 0x95, 0xa2, - 0xa7, 0x7e, 0x8b, 0x92, 0x49, 0x22, 0x95, 0x5e, 0xc2, 0x7b, 0xbf, 0xf7, 0x1e, 0xbf, 0x3f, 0x19, - 0xf8, 0x35, 0xc6, 0x29, 0x4f, 0x68, 0x6c, 0xfa, 0xd9, 0x87, 0xf9, 0x01, 0x5e, 0xa7, 0x1b, 0x6c, - 0x6c, 0x13, 0xca, 0x29, 0xfa, 0x54, 0x88, 0x46, 0x26, 0x0e, 0x07, 0x84, 0x12, 0x2a, 0x04, 0x33, - 0x43, 0xb9, 0x67, 0xf4, 0x0a, 0x60, 0x63, 0x59, 0xc4, 0x10, 0x82, 0x72, 0xec, 0x45, 0x58, 0x01, - 0x1a, 0xd0, 0x9b, 0x8e, 0xc0, 0xe8, 0x0b, 0xac, 0x6f, 0x71, 0x12, 0xd2, 0xb5, 0x52, 0xd1, 0x80, - 0x2e, 0x3b, 0x05, 0x43, 0x7f, 0xa1, 0x1c, 0x31, 0xc2, 0x94, 0xaa, 0x56, 0xd5, 0x5b, 0x63, 0xcd, - 0x78, 0xdf, 0xcb, 0xb8, 0x61, 0xc4, 0xde, 0x61, 0x3f, 0xe5, 0x78, 0x42, 0x63, 0x9e, 0x78, 0x3e, - 0xb7, 0xe4, 0xfd, 0xf3, 0x77, 0xc9, 0x11, 0x19, 0x64, 0xc0, 0xcf, 0x1b, 0x8f, 0x71, 0x17, 0xe7, - 0x1e, 0x37, 0xc0, 0x21, 0x09, 0xb8, 0x22, 0x8b, 0x06, 0xfd, 0x4c, 0x2a, 0xd2, 0x33, 0x21, 0x20, - 0x1b, 0x76, 0x73, 0x6b, 0x48, 0x63, 0x97, 0x71, 0x8f, 0x60, 0xa5, 0xa6, 0x01, 0xbd, 0x33, 0xfe, - 0x76, 0xd9, 0xd6, 0x2e, 0x4d, 0xcb, 0xcc, 0xe3, 0x74, 0xf0, 0x05, 0x1f, 0x59, 0x10, 0x7d, 0x1c, - 0x0c, 0x0d, 0x61, 0xc3, 0x2f, 0x70, 0xb1, 0xf8, 0x99, 0xa3, 0x1e, 0xac, 0x46, 0x8c, 0x88, 0xcd, - 0x9b, 0x4e, 0x06, 0x47, 0x3f, 0x60, 0xbb, 0x3c, 0xd7, 0x84, 0xa6, 0x31, 0x47, 0x03, 0x58, 0xf3, - 0x33, 0x20, 0xb2, 0x35, 0x27, 0x27, 0x3f, 0xa7, 0xb0, 0x73, 0x39, 0x0c, 0xea, 0xc3, 0xb6, 0x65, - 0x4f, 0xff, 0xcf, 0x5d, 0xeb, 0x7a, 0x31, 0xb9, 0xb2, 0x9d, 0x9e, 0x84, 0xba, 0xb0, 0x65, 0xcf, - 0xff, 0x9d, 0x0b, 0x40, 0x78, 0x16, 0xb7, 0xb3, 0xb2, 0xb2, 0xec, 0x55, 0xac, 0xd9, 0xfe, 0xa8, - 0x82, 0xc3, 0x51, 0x05, 0x2f, 0x47, 0x15, 0x3c, 0x9e, 0x54, 0xe9, 0x70, 0x52, 0xa5, 0xa7, 0x93, - 0x2a, 0xdd, 0x19, 0x24, 0xe4, 0x41, 0xba, 0x32, 0x7c, 0x1a, 0x99, 0xc5, 0x15, 0x7e, 0xd1, 0x84, - 0x94, 0xd8, 0xbc, 0xff, 0x63, 0xee, 0xf2, 0x67, 0xc1, 0x1f, 0xb6, 0x98, 0xad, 0xea, 0xe2, 0x87, - 0xff, 0x7e, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xed, 0x05, 0x84, 0xca, 0x33, 0x02, 0x00, 0x00, + // 396 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x52, 0x41, 0x8b, 0xd3, 0x40, + 0x18, 0xcd, 0x98, 0x74, 0xd9, 0x1d, 0x75, 0xad, 0xe3, 0x22, 0x61, 0xab, 0x69, 0x2c, 0x08, 0x41, + 0x30, 0x81, 0xea, 0xc9, 0x9b, 0x89, 0x43, 0x5b, 0xb4, 0x2d, 0xa4, 0x15, 0xc4, 0x4b, 0x48, 0xd3, + 0x61, 0x12, 0x68, 0x32, 0x25, 0x33, 0x91, 0xfa, 0x2f, 0xfc, 0x59, 0x3d, 0xf6, 0xe8, 0x49, 0xa4, + 0xfd, 0x05, 0xfe, 0x03, 0xc9, 0x64, 0x5a, 0xac, 0x7b, 0x19, 0xde, 0x37, 0xef, 0x3d, 0xde, 0xc7, + 0xe3, 0x83, 0x9d, 0x82, 0x54, 0xa2, 0x64, 0x85, 0x97, 0xd4, 0x0f, 0x4f, 0x52, 0xb2, 0xac, 0x56, + 0xc4, 0x5d, 0x97, 0x4c, 0x30, 0xf4, 0x40, 0x91, 0x6e, 0x4d, 0xde, 0xde, 0x50, 0x46, 0x99, 0x24, + 0xbc, 0x1a, 0x35, 0x9a, 0xde, 0x1f, 0x00, 0x2f, 0x67, 0xca, 0x86, 0x10, 0x34, 0x8a, 0x38, 0x27, + 0x26, 0xb0, 0x81, 0x73, 0x15, 0x4a, 0x8c, 0x9e, 0xc2, 0x8b, 0x35, 0x29, 0x33, 0xb6, 0x34, 0xef, + 0xd9, 0xc0, 0x31, 0x42, 0x35, 0xa1, 0x77, 0xd0, 0xc8, 0x39, 0xe5, 0xa6, 0x6e, 0xeb, 0xce, 0xfd, + 0xbe, 0xed, 0xfe, 0x9b, 0xe5, 0x8e, 0x39, 0xc5, 0x1b, 0x92, 0x54, 0x82, 0x04, 0xac, 0x10, 0x65, + 0x9c, 0x08, 0xdf, 0xd8, 0xfe, 0xea, 0x6a, 0xa1, 0xf4, 0x20, 0x17, 0x3e, 0x59, 0xc5, 0x5c, 0x44, + 0xa4, 0xd1, 0x44, 0x29, 0xc9, 0x68, 0x2a, 0x4c, 0x43, 0x06, 0x3c, 0xae, 0x29, 0xe5, 0x1e, 0x4a, + 0x02, 0x8d, 0x61, 0xbb, 0x91, 0x66, 0xac, 0x88, 0xb8, 0x88, 0x29, 0xe1, 0x66, 0xcb, 0xd6, 0x9d, + 0xeb, 0xfe, 0xb3, 0xf3, 0x5c, 0x7c, 0x54, 0xcd, 0x6a, 0x91, 0xca, 0x7c, 0x44, 0xce, 0x7e, 0x79, + 0xcf, 0x87, 0xe8, 0xee, 0x82, 0xe8, 0x16, 0x5e, 0x26, 0x0a, 0xab, 0x02, 0x4e, 0x33, 0x6a, 0x43, + 0x3d, 0xe7, 0x54, 0x36, 0x70, 0x15, 0xd6, 0xb0, 0xf7, 0x12, 0x3e, 0x3c, 0xd6, 0x16, 0xb0, 0xaa, + 0x10, 0xe8, 0x06, 0xb6, 0x92, 0x1a, 0x48, 0x6f, 0x2b, 0x6c, 0x86, 0x57, 0x73, 0x78, 0x7d, 0xbe, + 0x13, 0xea, 0xc2, 0x0e, 0xfe, 0x82, 0x83, 0xcf, 0xf3, 0xd1, 0x74, 0x12, 0xcd, 0xe6, 0xef, 0x07, + 0x38, 0xc2, 0x93, 0x0f, 0x91, 0xff, 0x69, 0x1a, 0x7c, 0xc4, 0x61, 0x5b, 0x43, 0x2f, 0xe0, 0xf3, + 0xff, 0x05, 0x3e, 0x1e, 0x8c, 0x26, 0x27, 0x09, 0xf0, 0x87, 0xdb, 0xbd, 0x05, 0x76, 0x7b, 0x0b, + 0xfc, 0xde, 0x5b, 0xe0, 0xc7, 0xc1, 0xd2, 0x76, 0x07, 0x4b, 0xfb, 0x79, 0xb0, 0xb4, 0xaf, 0x2e, + 0xcd, 0x44, 0x5a, 0x2d, 0xdc, 0x84, 0xe5, 0x9e, 0x6a, 0xe6, 0x35, 0x2b, 0xe9, 0x11, 0x7b, 0xdf, + 0xde, 0x7a, 0x9b, 0xe6, 0x56, 0xc4, 0xf7, 0x35, 0xe1, 0x8b, 0x0b, 0x79, 0x05, 0x6f, 0xfe, 0x06, + 0x00, 0x00, 0xff, 0xff, 0xf1, 0x0a, 0x42, 0x3f, 0x48, 0x02, 0x00, 0x00, } func (m *Schedule) Marshal() (dAtA []byte, err error) { @@ -289,10 +292,23 @@ func (m *Schedule) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.ExecutionStage != 0 { - i = encodeVarintSchedule(dAtA, i, uint64(m.ExecutionStage)) + if len(m.ExecutionStages) > 0 { + dAtA2 := make([]byte, len(m.ExecutionStages)*10) + var j1 int + for _, num := range m.ExecutionStages { + for num >= 1<<7 { + dAtA2[j1] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j1++ + } + dAtA2[j1] = uint8(num) + j1++ + } + i -= j1 + copy(dAtA[i:], dAtA2[:j1]) + i = encodeVarintSchedule(dAtA, i, uint64(j1)) i-- - dAtA[i] = 0x28 + dAtA[i] = 0x2a } if m.LastExecuteHeight != 0 { i = encodeVarintSchedule(dAtA, i, uint64(m.LastExecuteHeight)) @@ -426,8 +442,12 @@ func (m *Schedule) Size() (n int) { if m.LastExecuteHeight != 0 { n += 1 + sovSchedule(uint64(m.LastExecuteHeight)) } - if m.ExecutionStage != 0 { - n += 1 + sovSchedule(uint64(m.ExecutionStage)) + if len(m.ExecutionStages) > 0 { + l = 0 + for _, e := range m.ExecutionStages { + l += sovSchedule(uint64(e)) + } + n += 1 + sovSchedule(uint64(l)) + l } return n } @@ -601,23 +621,73 @@ func (m *Schedule) Unmarshal(dAtA []byte) error { } } 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 wireType == 0 { + var v ExecutionStage + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSchedule + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= ExecutionStage(b&0x7F) << shift + if b < 0x80 { + break + } } - if iNdEx >= l { + m.ExecutionStages = append(m.ExecutionStages, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSchedule + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthSchedule + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthSchedule + } + if postIndex > l { return io.ErrUnexpectedEOF } - b := dAtA[iNdEx] - iNdEx++ - m.ExecutionStage |= ExecutionStage(b&0x7F) << shift - if b < 0x80 { - break + var elementCount int + if elementCount != 0 && len(m.ExecutionStages) == 0 { + m.ExecutionStages = make([]ExecutionStage, 0, elementCount) + } + for iNdEx < postIndex { + var v ExecutionStage + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSchedule + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= ExecutionStage(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.ExecutionStages = append(m.ExecutionStages, v) } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field ExecutionStages", wireType) } default: iNdEx = preIndex diff --git a/x/cron/types/tx.go b/x/cron/types/tx.go index 1bca78a71..c439f37d5 100644 --- a/x/cron/types/tx.go +++ b/x/cron/types/tx.go @@ -45,6 +45,10 @@ func (msg *MsgAddSchedule) Validate() error { return errors.Wrap(sdkerrors.ErrInvalidRequest, "msgs should not be empty") } + if len(msg.ExecutionStages) == 0 { + return errors.Wrap(sdkerrors.ErrInvalidRequest, "execution stages should not be empty") + } + return nil } diff --git a/x/cron/types/tx.pb.go b/x/cron/types/tx.pb.go index 16905d24b..8588b6028 100644 --- a/x/cron/types/tx.pb.go +++ b/x/cron/types/tx.pb.go @@ -34,11 +34,15 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // MsgAddSchedule is the MsgAddSchedule request type. type MsgAddSchedule struct { // Authority is the address of the governance account. - 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=neutron.cron.ExecutionStage" json:"execution_stage,omitempty"` + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` + // Name of the schedule + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // Period in blocks + Period uint64 `protobuf:"varint,3,opt,name=period,proto3" json:"period,omitempty"` + // Msgs that will be executed every certain number of blocks, specified in the `period` field + Msgs []MsgExecuteContract `protobuf:"bytes,4,rep,name=msgs,proto3" json:"msgs"` + // Execution stages when messages will be executed + ExecutionStages []ExecutionStage `protobuf:"varint,5,rep,packed,name=execution_stages,json=executionStages,proto3,enum=neutron.cron.ExecutionStage" json:"execution_stages,omitempty"` } func (m *MsgAddSchedule) Reset() { *m = MsgAddSchedule{} } @@ -102,11 +106,11 @@ func (m *MsgAddSchedule) GetMsgs() []MsgExecuteContract { return nil } -func (m *MsgAddSchedule) GetExecutionStage() ExecutionStage { +func (m *MsgAddSchedule) GetExecutionStages() []ExecutionStage { if m != nil { - return m.ExecutionStage + return m.ExecutionStages } - return ExecutionStage_BEGIN_BLOCKER + return nil } // MsgAddScheduleResponse defines the response structure for executing a @@ -151,7 +155,8 @@ var xxx_messageInfo_MsgAddScheduleResponse proto.InternalMessageInfo type MsgRemoveSchedule struct { // Authority is the address of the governance account. Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // Name of the schedule + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` } func (m *MsgRemoveSchedule) Reset() { *m = MsgRemoveSchedule{} } @@ -350,42 +355,42 @@ func init() { func init() { proto.RegisterFile("neutron/cron/tx.proto", fileDescriptor_c9e0a673aba8d6fd) } var fileDescriptor_c9e0a673aba8d6fd = []byte{ - // 554 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0xbf, 0x6b, 0xdb, 0x40, - 0x14, 0xf6, 0xd9, 0x8e, 0xc1, 0xe7, 0xe0, 0x10, 0xd5, 0x75, 0x64, 0x25, 0x55, 0x8c, 0x68, 0x1b, - 0xd7, 0x10, 0x89, 0xba, 0xa5, 0x05, 0x6f, 0x71, 0x31, 0x74, 0x11, 0xb4, 0x72, 0xbb, 0x64, 0x09, - 0x8a, 0x74, 0x9c, 0x05, 0x95, 0x4e, 0xe8, 0x4e, 0xc6, 0xd9, 0x4a, 0xc7, 0x4c, 0xed, 0x5f, 0xd0, - 0xb5, 0xd0, 0xc5, 0x43, 0xff, 0x88, 0x8c, 0xa1, 0x53, 0xa7, 0x52, 0xec, 0xc1, 0xff, 0x46, 0xd1, - 0xaf, 0x44, 0x17, 0x41, 0x0a, 0x85, 0x2c, 0xa7, 0x7b, 0xef, 0xfb, 0xde, 0xd3, 0x77, 0xdf, 0x3d, - 0x0e, 0xde, 0xf7, 0x50, 0xc8, 0x02, 0xe2, 0x69, 0x56, 0xb4, 0xb0, 0xb9, 0xea, 0x07, 0x84, 0x11, - 0x61, 0x33, 0x4d, 0xab, 0x51, 0x5a, 0xda, 0x36, 0x5d, 0xc7, 0x23, 0x5a, 0xbc, 0x26, 0x04, 0x69, - 0xc7, 0x22, 0xd4, 0x25, 0x54, 0x73, 0x29, 0xd6, 0x66, 0x4f, 0xa3, 0x4f, 0x0a, 0x74, 0x12, 0xe0, - 0x24, 0x8e, 0xb4, 0x24, 0x48, 0xa1, 0x16, 0x26, 0x98, 0x24, 0xf9, 0x68, 0x97, 0x15, 0x70, 0x0a, - 0x7c, 0x33, 0x30, 0xdd, 0xac, 0x60, 0x97, 0x83, 0xa8, 0x35, 0x45, 0x76, 0xf8, 0x01, 0x25, 0xa0, - 0xf2, 0xb5, 0x0c, 0x9b, 0x3a, 0xc5, 0x47, 0xb6, 0x3d, 0x49, 0x01, 0xe1, 0x05, 0xac, 0x9b, 0x21, - 0x9b, 0x92, 0xc0, 0x61, 0x67, 0x22, 0xe8, 0x82, 0x5e, 0x7d, 0x24, 0xfe, 0xfc, 0x71, 0xd8, 0x4a, - 0x55, 0x1c, 0xd9, 0x76, 0x80, 0x28, 0x9d, 0xb0, 0xc0, 0xf1, 0xb0, 0x71, 0x4d, 0x15, 0x04, 0x58, - 0xf5, 0x4c, 0x17, 0x89, 0xe5, 0xa8, 0xc4, 0x88, 0xf7, 0x42, 0x1b, 0xd6, 0x7c, 0x14, 0x38, 0xc4, - 0x16, 0x2b, 0x5d, 0xd0, 0xab, 0x1a, 0x69, 0x24, 0x0c, 0x61, 0xd5, 0xa5, 0x98, 0x8a, 0xd5, 0x6e, - 0xa5, 0xd7, 0x18, 0x74, 0xd5, 0xbc, 0x51, 0xaa, 0x4e, 0xf1, 0x78, 0x8e, 0xac, 0x90, 0xa1, 0x57, - 0xc4, 0x63, 0x81, 0x69, 0xb1, 0x51, 0xf5, 0xe2, 0xf7, 0x7e, 0xc9, 0x88, 0x6b, 0x84, 0x31, 0xdc, - 0x42, 0x31, 0xec, 0x10, 0xef, 0x84, 0x32, 0x13, 0x23, 0x71, 0xa3, 0x0b, 0x7a, 0xcd, 0xc1, 0x1e, - 0xdf, 0x66, 0x9c, 0x91, 0x26, 0x11, 0xc7, 0x68, 0x22, 0x2e, 0x1e, 0x3e, 0xfe, 0xb4, 0x5e, 0xf4, - 0xaf, 0xe5, 0x9f, 0xaf, 0x17, 0xfd, 0x7b, 0xb1, 0x43, 0xbc, 0x1d, 0x8a, 0x08, 0xdb, 0x7c, 0xc6, - 0x40, 0xd4, 0x27, 0x1e, 0x45, 0xca, 0x39, 0x80, 0xdb, 0x3a, 0xc5, 0x06, 0x72, 0xc9, 0x0c, 0xdd, - 0x85, 0x7d, 0xc3, 0x27, 0x45, 0x8d, 0xed, 0x4c, 0x23, 0xff, 0x5b, 0x65, 0x17, 0x76, 0x0a, 0xc9, - 0x2b, 0xa5, 0xdf, 0x01, 0xdc, 0xd2, 0x29, 0x7e, 0xef, 0xdb, 0x26, 0x43, 0x6f, 0xe2, 0xe1, 0xf8, - 0x6f, 0x9d, 0x2f, 0x61, 0x2d, 0x19, 0xaf, 0x58, 0x69, 0x63, 0xd0, 0xe2, 0x5d, 0x4f, 0xba, 0x8f, - 0xea, 0xd1, 0x85, 0x7d, 0x5b, 0x2f, 0xfa, 0xc0, 0x48, 0xe9, 0xc3, 0x83, 0xe2, 0x61, 0x5a, 0xd9, - 0x61, 0xf2, 0xca, 0x94, 0x0e, 0xdc, 0xb9, 0x91, 0xca, 0x0e, 0x32, 0xf8, 0x52, 0x86, 0x15, 0x9d, - 0x62, 0xe1, 0x2d, 0x6c, 0xe4, 0x47, 0x76, 0xaf, 0x30, 0x40, 0x39, 0x54, 0x7a, 0x78, 0x1b, 0x9a, - 0xb5, 0x16, 0x8e, 0x61, 0xf3, 0xc6, 0x4d, 0xee, 0x17, 0xea, 0x78, 0x82, 0x74, 0xf0, 0x0f, 0xc2, - 0x55, 0xef, 0x77, 0x70, 0x93, 0xf3, 0xfe, 0x41, 0xa1, 0x30, 0x0f, 0x4b, 0x8f, 0x6e, 0x85, 0xb3, - 0xae, 0xd2, 0xc6, 0xc7, 0xc8, 0xdf, 0xd1, 0xeb, 0x8b, 0xa5, 0x0c, 0x2e, 0x97, 0x32, 0xf8, 0xb3, - 0x94, 0xc1, 0xe7, 0x95, 0x5c, 0xba, 0x5c, 0xc9, 0xa5, 0x5f, 0x2b, 0xb9, 0x74, 0xac, 0x62, 0x87, - 0x4d, 0xc3, 0x53, 0xd5, 0x22, 0xae, 0x96, 0x76, 0x3c, 0x24, 0x01, 0xce, 0xf6, 0xda, 0xec, 0xb9, - 0x36, 0x4f, 0x9f, 0xac, 0x33, 0x1f, 0xd1, 0xd3, 0x5a, 0xfc, 0x26, 0x3c, 0xfb, 0x1b, 0x00, 0x00, - 0xff, 0xff, 0xf7, 0xca, 0x79, 0x29, 0xcf, 0x04, 0x00, 0x00, + // 556 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0xc1, 0x6b, 0xd3, 0x50, + 0x1c, 0x6e, 0xd6, 0xae, 0xd0, 0xd7, 0xd1, 0xb9, 0x58, 0xbb, 0x34, 0x9b, 0x59, 0x08, 0xea, 0x6a, + 0x61, 0x09, 0x56, 0x51, 0xe8, 0x6d, 0x95, 0x81, 0x97, 0x80, 0xa6, 0x7a, 0xd9, 0x65, 0x64, 0xc9, + 0xe3, 0x35, 0x60, 0xf2, 0x42, 0xde, 0x4b, 0xe9, 0x6e, 0xe2, 0x71, 0x27, 0xfd, 0x2b, 0x14, 0xbc, + 0xf4, 0xe0, 0x1f, 0xb1, 0xe3, 0xf0, 0xe4, 0x49, 0xa4, 0x3d, 0xf4, 0xdf, 0x90, 0x24, 0x2f, 0x5b, + 0xde, 0x02, 0x13, 0x04, 0x2f, 0xe9, 0x7b, 0xbf, 0xef, 0xfb, 0x7d, 0xfd, 0x7e, 0x5f, 0x7e, 0x04, + 0xdc, 0x0b, 0x60, 0x4c, 0x23, 0x1c, 0x18, 0x4e, 0xf2, 0xa0, 0x33, 0x3d, 0x8c, 0x30, 0xc5, 0xe2, + 0x06, 0x2b, 0xeb, 0x49, 0x59, 0xde, 0xb2, 0x7d, 0x2f, 0xc0, 0x46, 0xfa, 0xcc, 0x08, 0xf2, 0xb6, + 0x83, 0x89, 0x8f, 0x89, 0xe1, 0x13, 0x64, 0x4c, 0x9f, 0x24, 0x3f, 0x0c, 0xe8, 0x66, 0xc0, 0x49, + 0x7a, 0x33, 0xb2, 0x0b, 0x83, 0xda, 0x08, 0x23, 0x9c, 0xd5, 0x93, 0x53, 0xde, 0xc0, 0x39, 0x08, + 0xed, 0xc8, 0xf6, 0xf3, 0x86, 0x1d, 0x0e, 0x22, 0xce, 0x04, 0xba, 0xf1, 0x7b, 0x98, 0x81, 0xda, + 0x97, 0x35, 0xd0, 0x32, 0x09, 0x3a, 0x74, 0xdd, 0x31, 0x03, 0xc4, 0xe7, 0xa0, 0x61, 0xc7, 0x74, + 0x82, 0x23, 0x8f, 0x9e, 0x49, 0x82, 0x2a, 0xf4, 0x1a, 0x23, 0xe9, 0xc7, 0xf7, 0x83, 0x36, 0x73, + 0x71, 0xe8, 0xba, 0x11, 0x24, 0x64, 0x4c, 0x23, 0x2f, 0x40, 0xd6, 0x35, 0x55, 0x14, 0x41, 0x2d, + 0xb0, 0x7d, 0x28, 0xad, 0x25, 0x2d, 0x56, 0x7a, 0x16, 0x3b, 0xa0, 0x1e, 0xc2, 0xc8, 0xc3, 0xae, + 0x54, 0x55, 0x85, 0x5e, 0xcd, 0x62, 0x37, 0x71, 0x08, 0x6a, 0x3e, 0x41, 0x44, 0xaa, 0xa9, 0xd5, + 0x5e, 0x73, 0xa0, 0xea, 0xc5, 0xa0, 0x74, 0x93, 0xa0, 0xa3, 0x19, 0x74, 0x62, 0x0a, 0x5f, 0xe2, + 0x80, 0x46, 0xb6, 0x43, 0x47, 0xb5, 0x8b, 0x5f, 0x7b, 0x15, 0x2b, 0xed, 0x11, 0x4d, 0x70, 0x07, + 0xa6, 0xb0, 0x87, 0x83, 0x13, 0x42, 0x6d, 0x04, 0x89, 0xb4, 0xae, 0x56, 0x7b, 0xad, 0xc1, 0x2e, + 0xaf, 0x73, 0x94, 0xb3, 0xc6, 0x09, 0x89, 0x69, 0x6c, 0x42, 0xae, 0x4a, 0x86, 0x8f, 0x3e, 0xae, + 0xe6, 0xfd, 0xeb, 0x31, 0xce, 0x57, 0xf3, 0xfe, 0xdd, 0x34, 0x29, 0x3e, 0x16, 0x4d, 0x02, 0x1d, + 0xbe, 0x62, 0x41, 0x12, 0xe2, 0x80, 0x40, 0xed, 0x5c, 0x00, 0x5b, 0x26, 0x41, 0x16, 0xf4, 0xf1, + 0x14, 0xfe, 0x8f, 0x18, 0x87, 0x8f, 0xcb, 0x1e, 0x3b, 0xb9, 0x47, 0xfe, 0x6f, 0xb5, 0x1d, 0xd0, + 0x2d, 0x15, 0xaf, 0x9c, 0x7e, 0x13, 0xc0, 0xa6, 0x49, 0xd0, 0xbb, 0xd0, 0xb5, 0x29, 0x7c, 0x9d, + 0x2e, 0xc9, 0x3f, 0xfb, 0x7c, 0x01, 0xea, 0xd9, 0x9a, 0xa5, 0x4e, 0x9b, 0x83, 0x36, 0x1f, 0x7e, + 0xa6, 0x3e, 0x6a, 0x24, 0xa1, 0x7f, 0x5d, 0xcd, 0xfb, 0x82, 0xc5, 0xe8, 0xc3, 0xfd, 0xf2, 0x30, + 0xed, 0x7c, 0x98, 0xa2, 0x33, 0xad, 0x0b, 0xb6, 0x6f, 0x94, 0xf2, 0x41, 0x06, 0x9f, 0xd7, 0x40, + 0xd5, 0x24, 0x48, 0x7c, 0x03, 0x9a, 0xc5, 0xd5, 0xdd, 0x2d, 0x2d, 0x52, 0x01, 0x95, 0x1f, 0xdc, + 0x86, 0xe6, 0xd2, 0xe2, 0x31, 0x68, 0xdd, 0x78, 0x93, 0x7b, 0xa5, 0x3e, 0x9e, 0x20, 0xef, 0xff, + 0x85, 0x70, 0xa5, 0xfd, 0x16, 0x6c, 0x70, 0xd9, 0xdf, 0x2f, 0x35, 0x16, 0x61, 0xf9, 0xe1, 0xad, + 0x70, 0xae, 0x2a, 0xaf, 0x7f, 0x48, 0xf2, 0x1d, 0xbd, 0xba, 0x58, 0x28, 0xc2, 0xe5, 0x42, 0x11, + 0x7e, 0x2f, 0x14, 0xe1, 0xd3, 0x52, 0xa9, 0x5c, 0x2e, 0x95, 0xca, 0xcf, 0xa5, 0x52, 0x39, 0xd6, + 0x91, 0x47, 0x27, 0xf1, 0xa9, 0xee, 0x60, 0xdf, 0x60, 0x8a, 0x07, 0x38, 0x42, 0xf9, 0xd9, 0x98, + 0x3e, 0x33, 0x66, 0xec, 0xd3, 0x75, 0x16, 0x42, 0x72, 0x5a, 0x4f, 0xbf, 0x0d, 0x4f, 0xff, 0x04, + 0x00, 0x00, 0xff, 0xff, 0xb7, 0x18, 0xba, 0xe9, 0xd7, 0x04, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -566,10 +571,23 @@ func (m *MsgAddSchedule) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.ExecutionStage != 0 { - i = encodeVarintTx(dAtA, i, uint64(m.ExecutionStage)) + if len(m.ExecutionStages) > 0 { + dAtA2 := make([]byte, len(m.ExecutionStages)*10) + var j1 int + for _, num := range m.ExecutionStages { + for num >= 1<<7 { + dAtA2[j1] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j1++ + } + dAtA2[j1] = uint8(num) + j1++ + } + i -= j1 + copy(dAtA[i:], dAtA2[:j1]) + i = encodeVarintTx(dAtA, i, uint64(j1)) i-- - dAtA[i] = 0x28 + dAtA[i] = 0x2a } if len(m.Msgs) > 0 { for iNdEx := len(m.Msgs) - 1; iNdEx >= 0; iNdEx-- { @@ -787,8 +805,12 @@ func (m *MsgAddSchedule) Size() (n int) { n += 1 + l + sovTx(uint64(l)) } } - if m.ExecutionStage != 0 { - n += 1 + sovTx(uint64(m.ExecutionStage)) + if len(m.ExecutionStages) > 0 { + l = 0 + for _, e := range m.ExecutionStages { + l += sovTx(uint64(e)) + } + n += 1 + sovTx(uint64(l)) + l } return n } @@ -1005,23 +1027,73 @@ func (m *MsgAddSchedule) Unmarshal(dAtA []byte) error { } 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 wireType == 0 { + var v ExecutionStage + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= ExecutionStage(b&0x7F) << shift + if b < 0x80 { + break + } } - if iNdEx >= l { + m.ExecutionStages = append(m.ExecutionStages, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { return io.ErrUnexpectedEOF } - b := dAtA[iNdEx] - iNdEx++ - m.ExecutionStage |= ExecutionStage(b&0x7F) << shift - if b < 0x80 { - break + var elementCount int + if elementCount != 0 && len(m.ExecutionStages) == 0 { + m.ExecutionStages = make([]ExecutionStage, 0, elementCount) + } + for iNdEx < postIndex { + var v ExecutionStage + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= ExecutionStage(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.ExecutionStages = append(m.ExecutionStages, v) } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field ExecutionStages", wireType) } default: iNdEx = preIndex diff --git a/x/cron/types/v1/schedule.pb.go b/x/cron/types/v1/schedule.pb.go index b2fe7d90c..814f91cbb 100644 --- a/x/cron/types/v1/schedule.pb.go +++ b/x/cron/types/v1/schedule.pb.go @@ -23,12 +23,13 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +// Schedule defines the schedule for execution type Schedule struct { // Name of schedule Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // Period in blocks Period uint64 `protobuf:"varint,2,opt,name=period,proto3" json:"period,omitempty"` - // Msgs that will be executed every period amount of time + // Msgs that will be executed every certain number of blocks, specified in the `period` field Msgs []MsgExecuteContract `protobuf:"bytes,3,rep,name=msgs,proto3" json:"msgs"` // Last execution's block height LastExecuteHeight uint64 `protobuf:"varint,4,opt,name=last_execute_height,json=lastExecuteHeight,proto3" json:"last_execute_height,omitempty"` @@ -95,6 +96,7 @@ func (m *Schedule) GetLastExecuteHeight() uint64 { return 0 } +// MsgExecuteContract defines the contract and the message to pass type MsgExecuteContract struct { // Contract is the address of the smart contract Contract string `protobuf:"bytes,1,opt,name=contract,proto3" json:"contract,omitempty"` @@ -149,6 +151,7 @@ func (m *MsgExecuteContract) GetMsg() string { return "" } +// ScheduleCount defines the number of current schedules type ScheduleCount struct { // Count is the number of current schedules Count int32 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"`