From c57779d4f559bdb8b5998a606638ec47ba39471c Mon Sep 17 00:00:00 2001 From: Srinivas Baride Date: Sun, 18 Jul 2021 01:07:57 +0530 Subject: [PATCH] Refactored plan tests --- x/plan/genesis.go | 30 ++- x/plan/keeper/alias.go | 6 +- x/plan/keeper/keeper.go | 5 - x/plan/simulation/decoder.go | 52 ++-- x/plan/simulation/genesis.go | 24 +- x/plan/simulation/operation.go | 284 ---------------------- x/plan/simulation/operations.go | 410 ++++++++++++++++++++++++++++++++ x/plan/simulation/rand.go | 117 ++++++--- x/plan/types/genesis.go | 21 +- x/plan/types/keys.go | 7 + x/plan/types/plan.go | 38 +-- 11 files changed, 588 insertions(+), 406 deletions(-) delete mode 100644 x/plan/simulation/operation.go create mode 100644 x/plan/simulation/operations.go diff --git a/x/plan/genesis.go b/x/plan/genesis.go index 55e0585d..2d8c7510 100644 --- a/x/plan/genesis.go +++ b/x/plan/genesis.go @@ -10,14 +10,17 @@ import ( func InitGenesis(ctx sdk.Context, k keeper.Keeper, state types.GenesisState) { for _, item := range state { - k.SetPlan(ctx, item.Plan) + var ( + provider = item.Plan.GetProvider() + ) + k.SetPlan(ctx, item.Plan) if item.Plan.Status.Equal(hubtypes.StatusActive) { k.SetActivePlan(ctx, item.Plan.Id) - k.SetActivePlanForProvider(ctx, item.Plan.GetProvider(), item.Plan.Id) + k.SetActivePlanForProvider(ctx, provider, item.Plan.Id) } else { k.SetInactivePlan(ctx, item.Plan.Id) - k.SetInactivePlanForProvider(ctx, item.Plan.GetProvider(), item.Plan.Id) + k.SetInactivePlanForProvider(ctx, provider, item.Plan.Id) } for _, node := range item.Nodes { @@ -27,20 +30,33 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, state types.GenesisState) { } k.SetNodeForPlan(ctx, item.Plan.Id, address) + k.IncreaseCountForNodeByProvider(ctx, provider, address) + } + } + + var ( + count uint64 = 0 + ) + + for _, item := range state { + if item.Plan.Id > count { + count = item.Plan.Id } } - k.SetCount(ctx, uint64(len(state))) + k.SetCount(ctx, count) } func ExportGenesis(ctx sdk.Context, k keeper.Keeper) types.GenesisState { - plans := k.GetPlans(ctx, 0, 0) + var ( + plans = k.GetPlans(ctx, 0, 0) + items = make(types.GenesisPlans, 0, len(plans)) + ) - items := make(types.GenesisPlans, 0, len(plans)) for _, plan := range plans { item := types.GenesisPlan{ Plan: plan, - Nodes: nil, + Nodes: []string{}, } nodes := k.GetNodesForPlan(ctx, plan.Id, 0, 0) diff --git a/x/plan/keeper/alias.go b/x/plan/keeper/alias.go index 38407533..896e2798 100644 --- a/x/plan/keeper/alias.go +++ b/x/plan/keeper/alias.go @@ -2,15 +2,11 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + hubtypes "github.com/sentinel-official/hub/types" nodetypes "github.com/sentinel-official/hub/x/node/types" ) -func (k *Keeper) GetAccount(ctx sdk.Context, address sdk.AccAddress) authtypes.AccountI { - return k.account.GetAccount(ctx, address) -} - func (k *Keeper) HasProvider(ctx sdk.Context, address hubtypes.ProvAddress) bool { return k.provider.HasProvider(ctx, address) } diff --git a/x/plan/keeper/keeper.go b/x/plan/keeper/keeper.go index 00b33f8b..1dda64ba 100644 --- a/x/plan/keeper/keeper.go +++ b/x/plan/keeper/keeper.go @@ -17,7 +17,6 @@ type Keeper struct { key sdk.StoreKey provider expected.ProviderKeeper node expected.NodeKeeper - account expected.AccountKeeper } func NewKeeper(cdc codec.BinaryMarshaler, key sdk.StoreKey) Keeper { @@ -27,10 +26,6 @@ func NewKeeper(cdc codec.BinaryMarshaler, key sdk.StoreKey) Keeper { } } -func (k *Keeper) WithAccountKeeper(keeper expected.AccountKeeper) { - k.account = keeper -} - func (k *Keeper) WithProviderKeeper(keeper expected.ProviderKeeper) { k.provider = keeper } diff --git a/x/plan/simulation/decoder.go b/x/plan/simulation/decoder.go index eeac3ea6..fe9fb611 100644 --- a/x/plan/simulation/decoder.go +++ b/x/plan/simulation/decoder.go @@ -6,46 +6,64 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/types/kv" - protobuf "github.com/gogo/protobuf/types" + protobuftypes "github.com/gogo/protobuf/types" + "github.com/sentinel-official/hub/x/plan/types" ) -func NewDecoderStore(cdc codec.Marshaler) func(kvA, kvB kv.Pair) string { - decoderFn := func(kvA, kvB kv.Pair) string { +func NewStoreDecoder(cdc codec.Marshaler) func(kvA, kvB kv.Pair) string { + return func(kvA, kvB kv.Pair) string { switch { case bytes.Equal(kvA.Key[:1], types.CountKey): - var countA, countB protobuf.UInt64Value + var countA, countB protobuftypes.UInt64Value cdc.MustUnmarshalBinaryBare(kvA.Value, &countA) cdc.MustUnmarshalBinaryBare(kvB.Value, &countB) - return fmt.Sprintf("%s\n%s", &countA, &countB) + return fmt.Sprintf("%v\n%v", &countA, &countB) case bytes.Equal(kvA.Key[:1], types.PlanKeyPrefix): var planA, planB types.Plan cdc.MustUnmarshalBinaryBare(kvA.Value, &planA) cdc.MustUnmarshalBinaryBare(kvB.Value, &planB) - return fmt.Sprintf("%s\n%s", &planA, &planB) + return fmt.Sprintf("%v\n%v", &planA, &planB) case bytes.Equal(kvA.Key[:1], types.ActivePlanKeyPrefix): - var acivePlanA, activePlanB protobuf.BoolValue - cdc.MustUnmarshalBinaryBare(kvA.Value, &acivePlanA) + var activePlanA, activePlanB protobuftypes.BoolValue + cdc.MustUnmarshalBinaryBare(kvA.Value, &activePlanA) cdc.MustUnmarshalBinaryBare(kvB.Value, &activePlanB) - return fmt.Sprintf("%s\n%s", &acivePlanA, &activePlanB) + return fmt.Sprintf("%v\n%v", &activePlanA, &activePlanB) case bytes.Equal(kvA.Key[:1], types.InactivePlanKeyPrefix): - var inacivePlanA, inactivePlanB protobuf.BoolValue - cdc.MustUnmarshalBinaryBare(kvA.Value, &inacivePlanA) + var inactivePlanA, inactivePlanB protobuftypes.BoolValue + cdc.MustUnmarshalBinaryBare(kvA.Value, &inactivePlanA) cdc.MustUnmarshalBinaryBare(kvB.Value, &inactivePlanB) - return fmt.Sprintf("%s\n%s", &inacivePlanA, &inactivePlanB) + return fmt.Sprintf("%v\n%v", &inactivePlanA, &inactivePlanB) + case bytes.Equal(kvA.Key[:1], types.ActivePlanForProviderKeyPrefix): + var activePlanForProviderA, activePlanForProviderB protobuftypes.BoolValue + cdc.MustUnmarshalBinaryBare(kvA.Value, &activePlanForProviderA) + cdc.MustUnmarshalBinaryBare(kvB.Value, &activePlanForProviderB) + + return fmt.Sprintf("%v\n%v", &activePlanForProviderA, &activePlanForProviderB) + case bytes.Equal(kvA.Key[:1], types.InactivePlanForProviderKeyPrefix): + var inactivePlanForProviderA, inactivePlanForProviderB protobuftypes.BoolValue + cdc.MustUnmarshalBinaryBare(kvA.Value, &inactivePlanForProviderA) + cdc.MustUnmarshalBinaryBare(kvB.Value, &inactivePlanForProviderB) + + return fmt.Sprintf("%v\n%v", &inactivePlanForProviderA, &inactivePlanForProviderB) + case bytes.Equal(kvA.Key[:1], types.NodeForPlanKeyPrefix): + var nodeForPlanA, nodeForPlanB protobuftypes.BoolValue + cdc.MustUnmarshalBinaryBare(kvA.Value, &nodeForPlanA) + cdc.MustUnmarshalBinaryBare(kvB.Value, &nodeForPlanB) + + return fmt.Sprintf("%v\n%v", &nodeForPlanA, &nodeForPlanB) case bytes.Equal(kvA.Key[:1], types.CountForNodeByProviderKeyPrefix): - var countForNodeByProviderA, countForNodeByProviderB protobuf.UInt64Value + var countForNodeByProviderA, countForNodeByProviderB protobuftypes.UInt64Value cdc.MustUnmarshalBinaryBare(kvA.Value, &countForNodeByProviderA) cdc.MustUnmarshalBinaryBare(kvB.Value, &countForNodeByProviderB) - return fmt.Sprintf("%s\n%s", &countForNodeByProviderA, &countForNodeByProviderB) + + return fmt.Sprintf("%v\n%v", &countForNodeByProviderA, &countForNodeByProviderB) } - panic(fmt.Sprintf("invalid plan key prefix: %X", kvA.Key[:1])) + panic(fmt.Sprintf("invalid key prefix %X", kvA.Key[:1])) } - - return decoderFn } diff --git a/x/plan/simulation/genesis.go b/x/plan/simulation/genesis.go index 52d6fad6..075135a7 100644 --- a/x/plan/simulation/genesis.go +++ b/x/plan/simulation/genesis.go @@ -2,26 +2,12 @@ package simulation import ( "github.com/cosmos/cosmos-sdk/types/module" - "github.com/sentinel-official/hub/x/plan/types" -) -const ( - dayDurationInSeconds = 86400 - weekDurationInSeconds = dayDurationInSeconds * 7 - monthDurationInSeconds = dayDurationInSeconds * 30 - gigabytes = 1024 << 20 - terabytes = gigabytes * 1024 + "github.com/sentinel-official/hub/x/plan/types" ) -func RandomizedGenState(simState *module.SimulationState) types.GenesisState { - var plans types.GenesisPlans - - for _, plan := range getRandomPlans(simState.Rand) { - plans = append(plans, types.GenesisPlan{ - Plan: plan, - Nodes: getRandomNodes(simState.Rand), - }) - } - - return types.NewGenesisState(plans) +func RandomizedGenesisState(state *module.SimulationState) types.GenesisState { + return types.NewGenesisState( + RandomGenesisPlans(state.Rand), + ) } diff --git a/x/plan/simulation/operation.go b/x/plan/simulation/operation.go deleted file mode 100644 index 6d00eadb..00000000 --- a/x/plan/simulation/operation.go +++ /dev/null @@ -1,284 +0,0 @@ -package simulation - -import ( - "math/rand" - "time" - - "github.com/cosmos/cosmos-sdk/baseapp" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/simapp/helpers" - "github.com/cosmos/cosmos-sdk/simapp/params" - sdk "github.com/cosmos/cosmos-sdk/types" - sdksimulation "github.com/cosmos/cosmos-sdk/types/simulation" - "github.com/cosmos/cosmos-sdk/x/simulation" - hubtypes "github.com/sentinel-official/hub/types" - "github.com/sentinel-official/hub/x/plan/keeper" - types "github.com/sentinel-official/hub/x/plan/types" -) - -const ( - OpWeightMsgAddRequest = "op_weight_msg_add_request" - OpWeightMsgSetStatusRequest = "op_weight_msg_set_status_request" - OpWeightMsgAddNodeRequest = "op_weight_msg_add_node_request" - OpWeightMsgRemoveNodeRequest = "op_weight_msg_remove_node_request" -) - -func WeightedOperations(ap sdksimulation.AppParams, cdc codec.JSONMarshaler, k keeper.Keeper) simulation.WeightedOperations { - var ( - weightMsgAddRequest int - weightMsgSetStatus int - weightMsgAddNodeRequest int - weightMsgRemoveNodeRequest int - ) - - randAddRequest := func(_ *rand.Rand) { - weightMsgAddRequest = 100 - } - - randSetStatusRequest := func(_ *rand.Rand) { - weightMsgSetStatus = 100 - } - - randAddNodeRequest := func(_ *rand.Rand) { - weightMsgAddNodeRequest = 100 - } - - randRemoveNodeRequest := func(_ *rand.Rand) { - weightMsgRemoveNodeRequest = 100 - } - - ap.GetOrGenerate(cdc, OpWeightMsgAddRequest, &weightMsgAddRequest, nil, randAddRequest) - ap.GetOrGenerate(cdc, OpWeightMsgSetStatusRequest, &weightMsgSetStatus, nil, randSetStatusRequest) - ap.GetOrGenerate(cdc, OpWeightMsgAddNodeRequest, &weightMsgAddNodeRequest, nil, randAddNodeRequest) - ap.GetOrGenerate(cdc, OpWeightMsgRemoveNodeRequest, &weightMsgRemoveNodeRequest, nil, randRemoveNodeRequest) - - addOperation := simulation.NewWeightedOperation(weightMsgAddRequest, SimulateMsgAddRequest(k, cdc)) - setStatusOperation := simulation.NewWeightedOperation(weightMsgSetStatus, SimulateMsgSetStatusRequest(k, cdc)) - addNodeOperation := simulation.NewWeightedOperation(weightMsgAddNodeRequest, SimulateMsgAddNodeRequest(k, cdc)) - removeNodeOperation := simulation.NewWeightedOperation(weightMsgRemoveNodeRequest, SimulateMsgRemoveNodeRequest(k, cdc)) - - return simulation.WeightedOperations{ - addOperation, - setStatusOperation, - addNodeOperation, - removeNodeOperation, - } -} - -func SimulateMsgAddRequest(k keeper.Keeper, cdc codec.JSONMarshaler) sdksimulation.Operation { - return func( - r *rand.Rand, - app *baseapp.BaseApp, - ctx sdk.Context, - accounts []sdksimulation.Account, - chainID string, - ) (sdksimulation.OperationMsg, []sdksimulation.FutureOperation, error) { - acc, _ := sdksimulation.RandomAcc(r, accounts) - from := k.GetAccount(ctx, acc.Address) - fromProvAddress := hubtypes.ProvAddress(from.GetAddress().Bytes()) - id := r.Uint64() - - amount := sdksimulation.RandomAmount(r, sdk.NewInt(60<<13)) - - price := sdk.Coins{ - {Denom: "tsent", Amount: amount}, - } - - fees, err := sdksimulation.RandomFees(r, ctx, price) - if err != nil { - return sdksimulation.NoOpMsg(types.ModuleName, "add_request", err.Error()), nil, err - } - - _, found := k.GetPlan(ctx, id) - if found { - return sdksimulation.NoOpMsg(types.ModuleName, "add_request", "plan already exists"), nil, nil - } - - validity := time.Duration(sdksimulation.RandIntBetween(r, weekDurationInSeconds, monthDurationInSeconds)) - bytes := sdk.NewInt(int64(sdksimulation.RandIntBetween(r, gigabytes, terabytes))) - - msg := types.NewMsgAddRequest(fromProvAddress, price, validity, bytes) - txGen := params.MakeTestEncodingConfig().TxConfig - - txn, err := helpers.GenTx( - txGen, - []sdk.Msg{msg}, - fees, - helpers.DefaultGenTxGas, - chainID, - []uint64{from.GetAccountNumber()}, - []uint64{from.GetSequence()}, - ) - if err != nil { - return sdksimulation.NoOpMsg(types.ModuleName, "add_request", err.Error()), nil, err - } - - _, _, err = app.Deliver(txGen.TxEncoder(), txn) - if err != nil { - return sdksimulation.NoOpMsg(types.ModuleName, "add_request", err.Error()), nil, err - } - - return sdksimulation.NewOperationMsg(msg, true, ""), nil, nil - } -} - -func SimulateMsgSetStatusRequest(k keeper.Keeper, cdc codec.JSONMarshaler) sdksimulation.Operation { - return func( - r *rand.Rand, - app *baseapp.BaseApp, - ctx sdk.Context, - accounts []sdksimulation.Account, - chainID string, - ) (sdksimulation.OperationMsg, []sdksimulation.FutureOperation, error) { - acc, _ := sdksimulation.RandomAcc(r, accounts) - from := k.GetAccount(ctx, acc.Address) - fromProvAddress := hubtypes.ProvAddress(from.GetAddress().Bytes()) - plan := getRandomPlan(r, k.GetPlans(ctx, 0, 0)) - - amount := sdksimulation.RandomAmount(r, sdk.NewInt(60<<13)) - - price := sdk.Coins{ - {Denom: "tsent", Amount: amount}, - } - - fees, err := sdksimulation.RandomFees(r, ctx, price) - if err != nil { - return sdksimulation.NoOpMsg(types.ModuleName, "set_status_request", err.Error()), nil, err - } - - _, found := k.GetPlan(ctx, plan.Id) - if !found { - return sdksimulation.NoOpMsg(types.ModuleName, "set_status_request", "plan does not exist"), nil, nil - } - - msg := types.NewMsgSetStatusRequest(fromProvAddress, plan.Id, hubtypes.Status(r.Intn(3))) - txGen := params.MakeTestEncodingConfig().TxConfig - - txn, err := helpers.GenTx( - txGen, - []sdk.Msg{msg}, - fees, - helpers.DefaultGenTxGas, - chainID, - []uint64{from.GetAccountNumber()}, - []uint64{from.GetSequence()}, - ) - if err != nil { - return sdksimulation.NoOpMsg(types.ModuleName, "set_status_request", err.Error()), nil, err - } - - _, _, err = app.Deliver(txGen.TxEncoder(), txn) - if err != nil { - return sdksimulation.NoOpMsg(types.ModuleName, "set_status_request", err.Error()), nil, err - } - - return sdksimulation.NewOperationMsg(msg, true, ""), nil, nil - } -} - -func SimulateMsgAddNodeRequest(k keeper.Keeper, cdc codec.JSONMarshaler) sdksimulation.Operation { - return func( - r *rand.Rand, - app *baseapp.BaseApp, - ctx sdk.Context, - accounts []sdksimulation.Account, - chainID string, - ) (sdksimulation.OperationMsg, []sdksimulation.FutureOperation, error) { - acc, _ := sdksimulation.RandomAcc(r, accounts) - from := k.GetAccount(ctx, acc.Address) - nodeAddress := hubtypes.NodeAddress(from.GetAddress().Bytes()) - fromProvAddress := hubtypes.ProvAddress(from.GetAddress().Bytes()) - plan := getRandomPlan(r, k.GetPlans(ctx, 0, 0)) - amount := sdksimulation.RandomAmount(r, sdk.NewInt(60<<13)) - - price := sdk.Coins{ - {Denom: "tsent", Amount: amount}, - } - - fees, err := sdksimulation.RandomFees(r, ctx, price) - if err != nil { - return sdksimulation.NoOpMsg(types.ModuleName, "add_node_request", err.Error()), nil, err - } - - _, found := k.GetPlan(ctx, plan.Id) - if !found { - return sdksimulation.NoOpMsg(types.ModuleName, "add_node_request", "plan does not exist"), nil, nil - } - - msg := types.NewMsgAddNodeRequest(fromProvAddress, plan.Id, nodeAddress) - txGen := params.MakeTestEncodingConfig().TxConfig - - txn, err := helpers.GenTx( - txGen, - []sdk.Msg{msg}, - fees, - helpers.DefaultGenTxGas, - chainID, - []uint64{from.GetAccountNumber()}, - []uint64{from.GetSequence()}, - ) - if err != nil { - return sdksimulation.NoOpMsg(types.ModuleName, "add_node_request", err.Error()), nil, err - } - - _, _, err = app.Deliver(txGen.TxEncoder(), txn) - if err != nil { - return sdksimulation.NoOpMsg(types.ModuleName, "add_node_request", err.Error()), nil, err - } - - return sdksimulation.NewOperationMsg(msg, true, ""), nil, nil - } -} - -func SimulateMsgRemoveNodeRequest(k keeper.Keeper, cdc codec.JSONMarshaler) sdksimulation.Operation { - return func( - r *rand.Rand, - app *baseapp.BaseApp, - ctx sdk.Context, - accounts []sdksimulation.Account, - chainID string, - ) (sdksimulation.OperationMsg, []sdksimulation.FutureOperation, error) { - acc, _ := sdksimulation.RandomAcc(r, accounts) - from := k.GetAccount(ctx, acc.Address) - nodeAddress := hubtypes.NodeAddress(from.GetAddress().Bytes()) - plan := getRandomPlan(r, k.GetPlans(ctx, 0, 0)) - amount := sdksimulation.RandomAmount(r, sdk.NewInt(60<<13)) - - price := sdk.Coins{ - {Denom: "tsent", Amount: amount}, - } - - fees, err := sdksimulation.RandomFees(r, ctx, price) - if err != nil { - return sdksimulation.NoOpMsg(types.ModuleName, "remove_node_request", err.Error()), nil, err - } - - _, found := k.GetNode(ctx, nodeAddress) - if !found { - return sdksimulation.NoOpMsg(types.ModuleName, "remove_node_request", "node does not exist"), nil, nil - } - - msg := types.NewMsgRemoveNodeRequest(from.GetAddress(), plan.Id, nodeAddress) - txGen := params.MakeTestEncodingConfig().TxConfig - - txn, err := helpers.GenTx( - txGen, - []sdk.Msg{msg}, - fees, - helpers.DefaultGenTxGas, - chainID, - []uint64{from.GetAccountNumber()}, - []uint64{from.GetSequence()}, - ) - if err != nil { - return sdksimulation.NoOpMsg(types.ModuleName, "remove_node_request", err.Error()), nil, err - } - - _, _, err = app.Deliver(txGen.TxEncoder(), txn) - if err != nil { - return sdksimulation.NoOpMsg(types.ModuleName, "remove_node_request", err.Error()), nil, err - } - - return sdksimulation.NewOperationMsg(msg, true, ""), nil, nil - } -} diff --git a/x/plan/simulation/operations.go b/x/plan/simulation/operations.go new file mode 100644 index 00000000..7a7a7f91 --- /dev/null +++ b/x/plan/simulation/operations.go @@ -0,0 +1,410 @@ +package simulation + +import ( + "math/rand" + "time" + + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/simapp/helpers" + "github.com/cosmos/cosmos-sdk/simapp/params" + sdk "github.com/cosmos/cosmos-sdk/types" + simulationtypes "github.com/cosmos/cosmos-sdk/types/simulation" + "github.com/cosmos/cosmos-sdk/x/simulation" + + hubtypes "github.com/sentinel-official/hub/types" + simulationhubtypes "github.com/sentinel-official/hub/types/simulation" + "github.com/sentinel-official/hub/x/plan/expected" + "github.com/sentinel-official/hub/x/plan/keeper" + "github.com/sentinel-official/hub/x/plan/types" +) + +var ( + OperationWeightMsgAddRequest = "op_weight_" + types.TypeMsgAddRequest + OperationWeightMsgSetStatusRequest = "op_weight_" + types.TypeMsgSetStatusRequest + OperationWeightMsgAddNodeRequest = "op_weight_" + types.TypeMsgAddNodeRequest + OperationWeightMsgRemoveNodeRequest = "op_weight_" + types.TypeMsgRemoveNodeRequest +) + +func WeightedOperations( + params simulationtypes.AppParams, + cdc codec.JSONMarshaler, + ak expected.AccountKeeper, + bk expected.BankKeeper, + pk expected.ProviderKeeper, + k keeper.Keeper, +) simulation.WeightedOperations { + var ( + weightMsgAddRequest int + weightMsgSetStatusRequest int + weightMsgAddNodeRequest int + weightMsgRemoveNodeRequest int + ) + + params.GetOrGenerate( + cdc, + OperationWeightMsgAddRequest, + &weightMsgAddRequest, + nil, + func(_ *rand.Rand) { + weightMsgAddRequest = 100 + }, + ) + params.GetOrGenerate( + cdc, + OperationWeightMsgSetStatusRequest, + &weightMsgSetStatusRequest, + nil, + func(_ *rand.Rand) { + weightMsgSetStatusRequest = 100 + }, + ) + params.GetOrGenerate( + cdc, + OperationWeightMsgAddNodeRequest, + &weightMsgAddNodeRequest, + nil, + func(_ *rand.Rand) { + weightMsgAddNodeRequest = 100 + }, + ) + params.GetOrGenerate( + cdc, + OperationWeightMsgRemoveNodeRequest, + &weightMsgRemoveNodeRequest, + nil, + func(_ *rand.Rand) { + weightMsgRemoveNodeRequest = 100 + }, + ) + + return simulation.WeightedOperations{ + simulation.NewWeightedOperation( + weightMsgAddRequest, + SimulateMsgAddRequest(ak, bk, pk), + ), + simulation.NewWeightedOperation( + weightMsgSetStatusRequest, + SimulateMsgSetStatusRequest(ak, bk, pk, k), + ), + simulation.NewWeightedOperation( + weightMsgAddNodeRequest, + SimulateMsgAddNodeRequest(ak, bk, pk, k), + ), + simulation.NewWeightedOperation( + weightMsgRemoveNodeRequest, + SimulateMsgRemoveNodeRequest(ak, bk, pk, k), + ), + } +} + +func SimulateMsgAddRequest(ak expected.AccountKeeper, bk expected.BankKeeper, pk expected.ProviderKeeper) simulationtypes.Operation { + return func( + r *rand.Rand, + app *baseapp.BaseApp, + ctx sdk.Context, + accounts []simulationtypes.Account, + chainID string, + ) (simulationtypes.OperationMsg, []simulationtypes.FutureOperation, error) { + var ( + rAccount, _ = simulationtypes.RandomAcc(r, accounts) + account = ak.GetAccount(ctx, rAccount.Address) + ) + + found := pk.HasProvider(ctx, hubtypes.ProvAddress(account.GetAddress())) + if !found { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgAddRequest, "provider does not exist"), nil, nil + } + + balance := bk.SpendableCoins(ctx, account.GetAddress()) + if !balance.IsAnyNegative() { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgAddRequest, "balance cannot be negative"), nil, nil + } + + fees, err := simulationtypes.RandomFees(r, ctx, balance) + if err != nil { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgAddRequest, err.Error()), nil, err + } + + var ( + price = simulationhubtypes.RandomCoins( + r, + sdk.NewCoins( + sdk.NewInt64Coin( + sdk.DefaultBondDenom, + MaxPlanPriceAmount, + ), + ), + ) + validity = time.Duration(r.Int63n(MaxPlanValidity)) * time.Minute + bytes = sdk.NewInt(r.Int63n(MaxPlanBytes)) + ) + + var ( + txConfig = params.MakeTestEncodingConfig().TxConfig + message = types.NewMsgAddRequest( + hubtypes.ProvAddress(account.GetAddress()), + price, + validity, + bytes, + ) + ) + + txn, err := helpers.GenTx( + txConfig, + []sdk.Msg{message}, + fees, + helpers.DefaultGenTxGas, + chainID, + []uint64{account.GetAccountNumber()}, + []uint64{account.GetSequence()}, + rAccount.PrivKey, + ) + if err != nil { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgAddRequest, err.Error()), nil, err + } + + _, _, err = app.Deliver(txConfig.TxEncoder(), txn) + if err != nil { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgAddRequest, err.Error()), nil, err + } + + return simulationtypes.NewOperationMsg(message, true, ""), nil, nil + } +} + +func SimulateMsgSetStatusRequest(ak expected.AccountKeeper, bk expected.BankKeeper, pk expected.ProviderKeeper, k keeper.Keeper) simulationtypes.Operation { + return func( + r *rand.Rand, + app *baseapp.BaseApp, + ctx sdk.Context, + accounts []simulationtypes.Account, + chainID string, + ) (simulationtypes.OperationMsg, []simulationtypes.FutureOperation, error) { + var ( + rAccount, _ = simulationtypes.RandomAcc(r, accounts) + account = ak.GetAccount(ctx, rAccount.Address) + ) + + found := pk.HasProvider(ctx, hubtypes.ProvAddress(account.GetAddress())) + if !found { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgSetStatusRequest, "provider does not exist"), nil, nil + } + + plans := k.GetPlansForProvider(ctx, hubtypes.ProvAddress(account.GetAddress()), 0, 0) + if len(plans) == 0 { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgSetStatusRequest, "plans does not exist for provider"), nil, nil + } + + balance := bk.SpendableCoins(ctx, account.GetAddress()) + if !balance.IsAnyNegative() { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgSetStatusRequest, "balance cannot be negative"), nil, nil + } + + fees, err := simulationtypes.RandomFees(r, ctx, balance) + if err != nil { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgSetStatusRequest, err.Error()), nil, err + } + + var ( + id = plans[r.Intn(len(plans))].Id + status = hubtypes.StatusActive + ) + + if r.Int63n(2) == 0 { + status = hubtypes.StatusInactive + } + + var ( + txConfig = params.MakeTestEncodingConfig().TxConfig + message = types.NewMsgSetStatusRequest( + hubtypes.ProvAddress(account.GetAddress()), + id, + status, + ) + ) + + txn, err := helpers.GenTx( + txConfig, + []sdk.Msg{message}, + fees, + helpers.DefaultGenTxGas, + chainID, + []uint64{account.GetAccountNumber()}, + []uint64{account.GetSequence()}, + rAccount.PrivKey, + ) + if err != nil { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgSetStatusRequest, err.Error()), nil, err + } + + _, _, err = app.Deliver(txConfig.TxEncoder(), txn) + if err != nil { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgSetStatusRequest, err.Error()), nil, err + } + + return simulationtypes.NewOperationMsg(message, true, ""), nil, nil + } +} + +func SimulateMsgAddNodeRequest(ak expected.AccountKeeper, bk expected.BankKeeper, pk expected.ProviderKeeper, k keeper.Keeper) simulationtypes.Operation { + return func( + r *rand.Rand, + app *baseapp.BaseApp, + ctx sdk.Context, + accounts []simulationtypes.Account, + chainID string, + ) (simulationtypes.OperationMsg, []simulationtypes.FutureOperation, error) { + var ( + rProvider, _ = simulationtypes.RandomAcc(r, accounts) + provider = ak.GetAccount(ctx, rProvider.Address) + rNode, _ = simulationtypes.RandomAcc(r, accounts) + node = ak.GetAccount(ctx, rNode.Address) + ) + + found := pk.HasProvider(ctx, hubtypes.ProvAddress(provider.GetAddress())) + if !found { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgAddNodeRequest, "provider does not exist"), nil, nil + } + + _, found = k.GetNode(ctx, hubtypes.NodeAddress(node.GetAddress())) + if !found { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgAddNodeRequest, "node does not exist"), nil, nil + } + + plans := k.GetPlansForProvider(ctx, hubtypes.ProvAddress(provider.GetAddress()), 0, 0) + if len(plans) == 0 { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgAddNodeRequest, "plans does not exist for provider"), nil, nil + } + + balance := bk.SpendableCoins(ctx, provider.GetAddress()) + if !balance.IsAnyNegative() { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgAddNodeRequest, "balance cannot be negative"), nil, nil + } + + fees, err := simulationtypes.RandomFees(r, ctx, balance) + if err != nil { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgAddNodeRequest, err.Error()), nil, err + } + + var ( + id = plans[r.Intn(len(plans))].Id + ) + + found = k.HasNodeForPlan(ctx, id, hubtypes.NodeAddress(node.GetAddress())) + if found { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgAddNodeRequest, "node for plan already exists"), nil, nil + } + + var ( + txConfig = params.MakeTestEncodingConfig().TxConfig + message = types.NewMsgAddNodeRequest( + hubtypes.ProvAddress(provider.GetAddress()), + id, + hubtypes.NodeAddress(node.GetAddress()), + ) + ) + + txn, err := helpers.GenTx( + txConfig, + []sdk.Msg{message}, + fees, + helpers.DefaultGenTxGas, + chainID, + []uint64{provider.GetAccountNumber()}, + []uint64{provider.GetSequence()}, + rProvider.PrivKey, + ) + if err != nil { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgAddNodeRequest, err.Error()), nil, err + } + + _, _, err = app.Deliver(txConfig.TxEncoder(), txn) + if err != nil { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgAddNodeRequest, err.Error()), nil, err + } + + return simulationtypes.NewOperationMsg(message, true, ""), nil, nil + } +} + +func SimulateMsgRemoveNodeRequest(ak expected.AccountKeeper, bk expected.BankKeeper, pk expected.ProviderKeeper, k keeper.Keeper) simulationtypes.Operation { + return func( + r *rand.Rand, + app *baseapp.BaseApp, + ctx sdk.Context, + accounts []simulationtypes.Account, + chainID string, + ) (simulationtypes.OperationMsg, []simulationtypes.FutureOperation, error) { + var ( + rProvider, _ = simulationtypes.RandomAcc(r, accounts) + provider = ak.GetAccount(ctx, rProvider.Address) + rNode, _ = simulationtypes.RandomAcc(r, accounts) + node = ak.GetAccount(ctx, rNode.Address) + ) + + found := pk.HasProvider(ctx, hubtypes.ProvAddress(provider.GetAddress())) + if !found { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgRemoveNodeRequest, "provider does not exist"), nil, nil + } + + _, found = k.GetNode(ctx, hubtypes.NodeAddress(node.GetAddress())) + if !found { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgRemoveNodeRequest, "node does not exist"), nil, nil + } + + plans := k.GetPlansForProvider(ctx, hubtypes.ProvAddress(provider.GetAddress()), 0, 0) + if len(plans) == 0 { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgRemoveNodeRequest, "plans does not exist for provider"), nil, nil + } + + balance := bk.SpendableCoins(ctx, provider.GetAddress()) + if !balance.IsAnyNegative() { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgRemoveNodeRequest, "balance cannot be negative"), nil, nil + } + + fees, err := simulationtypes.RandomFees(r, ctx, balance) + if err != nil { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgRemoveNodeRequest, err.Error()), nil, err + } + + var ( + id = plans[r.Intn(len(plans))].Id + ) + + found = k.HasNodeForPlan(ctx, id, hubtypes.NodeAddress(node.GetAddress())) + if !found { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgRemoveNodeRequest, "node for plan does not exist"), nil, nil + } + + var ( + txConfig = params.MakeTestEncodingConfig().TxConfig + message = types.NewMsgRemoveNodeRequest( + provider.GetAddress(), + id, + hubtypes.NodeAddress(node.GetAddress()), + ) + ) + + txn, err := helpers.GenTx( + txConfig, + []sdk.Msg{message}, + fees, + helpers.DefaultGenTxGas, + chainID, + []uint64{provider.GetAccountNumber()}, + []uint64{provider.GetSequence()}, + rProvider.PrivKey, + ) + if err != nil { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgRemoveNodeRequest, err.Error()), nil, err + } + + _, _, err = app.Deliver(txConfig.TxEncoder(), txn) + if err != nil { + return simulationtypes.NoOpMsg(types.ModuleName, types.TypeMsgRemoveNodeRequest, err.Error()), nil, err + } + + return simulationtypes.NewOperationMsg(message, true, ""), nil, nil + } +} diff --git a/x/plan/simulation/rand.go b/x/plan/simulation/rand.go index 56b82f4f..c013f1e8 100644 --- a/x/plan/simulation/rand.go +++ b/x/plan/simulation/rand.go @@ -1,67 +1,106 @@ package simulation import ( + "math" "math/rand" "time" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/simulation" + hubtypes "github.com/sentinel-official/hub/types" + simulationhubtypes "github.com/sentinel-official/hub/types/simulation" "github.com/sentinel-official/hub/x/plan/types" ) -func getRandomPlan(r *rand.Rand, plans types.Plans) types.Plan { - if len(plans) == 0 { - return types.Plan{ - Provider: hubtypes.ProvAddress([]byte("provider-1")).String(), - } +const ( + MaxPlanId = 1 << 18 + MaxPlans = 1 << 10 + MaxPlanPriceAmount = 1 << 10 + MaxPlanValidity = 1 << 18 + MaxPlanBytes = math.MaxInt64 +) + +func RandomPlan(r *rand.Rand, items types.Plans) types.Plan { + if len(items) == 0 { + return types.Plan{} } - index := r.Intn(len(plans)-1) - return plans[index] + return items[r.Intn(len(items))] } -func getRandomNodes(r *rand.Rand) []string { +func RandomPlans(r *rand.Rand) types.Plans { + var ( + items = make(types.Plans, 0, r.Intn(MaxPlans)) + duplicates = make(map[uint64]bool) + ) + + for ; len(items) < cap(items); { + id := uint64(r.Int63n(MaxPlanId)) + if duplicates[id] { + continue + } - nodes := make([]string, r.Intn(28)+4) + var ( + price = simulationhubtypes.RandomCoins( + r, + sdk.NewCoins( + sdk.NewInt64Coin( + sdk.DefaultBondDenom, + MaxPlanPriceAmount, + ), + ), + ) + validity = time.Duration(r.Int63n(MaxPlanValidity)) * time.Minute + bytes = sdk.NewInt(r.Int63n(MaxPlanBytes)) + status = hubtypes.StatusActive + statusAt = time.Now() + ) - for range nodes { - bz := make([]byte, 20) - if _, err := r.Read(bz); err != nil { - panic(err) + if rand.Intn(2) == 0 { + status = hubtypes.StatusInactive } - nodeAddress := hubtypes.NodeAddress(bz) - nodes = append(nodes, nodeAddress.String()) + + duplicates[id] = true + items = append( + items, + types.Plan{ + Id: id, + Provider: "", + Price: price, + Validity: validity, + Bytes: bytes, + Status: status, + StatusAt: statusAt, + }, + ) } - return nodes + return items } -func getRandomPlans(r *rand.Rand) types.Plans { +func RandomGenesisPlan(r *rand.Rand, items types.GenesisPlans) types.GenesisPlan { + if len(items) == 0 { + return types.GenesisPlan{} + } - plans := make(types.Plans, r.Intn(28)+4) + return items[r.Intn(len(items))] +} - for range plans { - bz := make([]byte, 20) - if _, err := r.Read(bz); err != nil { - panic(err) - } +func RandomGenesisPlans(r *rand.Rand) types.GenesisPlans { + var ( + rItems = RandomPlans(r) + items = make(types.GenesisPlans, 0, len(rItems)) + ) - providerAddress := hubtypes.ProvAddress(bz) - - plans = append(plans, types.Plan{ - Id: r.Uint64(), - Provider: providerAddress.String(), - Price: sdk.NewCoins(sdk.Coin{ - Denom: simulation.RandStringOfLength(r, r.Intn(125)+3), - Amount: sdk.NewInt(r.Int63n(8 << 12)), - }), - Validity: time.Duration(simulation.RandIntBetween(r, weekDurationInSeconds, monthDurationInSeconds)), - Bytes: sdk.NewInt(int64(simulation.RandIntBetween(r, gigabytes, terabytes))), - Status: hubtypes.Status(r.Intn(3)), - StatusAt: simulation.RandTimestamp(r), - }) + for _, item := range rItems { + items = append( + items, + types.GenesisPlan{ + Plan: item, + Nodes: nil, + }, + ) } - return plans + return items } diff --git a/x/plan/types/genesis.go b/x/plan/types/genesis.go index 3a7609e5..222a2938 100644 --- a/x/plan/types/genesis.go +++ b/x/plan/types/genesis.go @@ -19,32 +19,31 @@ func DefaultGenesisState() GenesisState { } func ValidateGenesis(state GenesisState) error { - for _, item := range state { - if err := item.Plan.Validate(); err != nil { - return err - } - } - plans := make(map[uint64]bool) for _, item := range state { - id := item.Plan.Id - if plans[id] { - return fmt.Errorf("duplicate plan id %d", id) + if plans[item.Plan.Id] { + return fmt.Errorf("found duplicate plan for id %d", item.Plan.Id) } - plans[id] = true + plans[item.Plan.Id] = true } for _, item := range state { nodes := make(map[string]bool) for _, address := range item.Nodes { if nodes[address] { - return fmt.Errorf("duplicate node for plan %d", item.Plan.Id) + return fmt.Errorf("found duplicate node %s for plan %d", address, item.Plan.Id) } nodes[address] = true } } + for _, item := range state { + if err := item.Plan.Validate(); err != nil { + return err + } + } + return nil } diff --git a/x/plan/types/keys.go b/x/plan/types/keys.go index 100c91f7..97aa8fda 100644 --- a/x/plan/types/keys.go +++ b/x/plan/types/keys.go @@ -16,6 +16,13 @@ var ( StoreKey = ModuleName ) +var ( + TypeMsgAddRequest = ModuleName + ":add" + TypeMsgSetStatusRequest = ModuleName + ":set_status" + TypeMsgAddNodeRequest = ModuleName + ":add_node" + TypeMsgRemoveNodeRequest = ModuleName + ":remove_node" +) + var ( EventModuleName = EventModule{Name: ModuleName} ) diff --git a/x/plan/types/plan.go b/x/plan/types/plan.go index 2c67d2b7..d0210a3f 100644 --- a/x/plan/types/plan.go +++ b/x/plan/types/plan.go @@ -9,12 +9,12 @@ import ( hubtypes "github.com/sentinel-official/hub/types" ) -func (p *Plan) GetProvider() hubtypes.ProvAddress { - if p.Provider == "" { +func (m *Plan) GetProvider() hubtypes.ProvAddress { + if m.Provider == "" { return nil } - address, err := hubtypes.ProvAddressFromBech32(p.Provider) + address, err := hubtypes.ProvAddressFromBech32(m.Provider) if err != nil { panic(err) } @@ -22,8 +22,8 @@ func (p *Plan) GetProvider() hubtypes.ProvAddress { return address } -func (p *Plan) PriceForDenom(d string) (sdk.Coin, bool) { - for _, coin := range p.Price { +func (m *Plan) PriceForDenom(d string) (sdk.Coin, bool) { + for _, coin := range m.Price { if coin.Denom == d { return coin, true } @@ -32,40 +32,40 @@ func (p *Plan) PriceForDenom(d string) (sdk.Coin, bool) { return sdk.Coin{}, false } -func (p *Plan) Validate() error { - if p.Id == 0 { +func (m *Plan) Validate() error { + if m.Id == 0 { return fmt.Errorf("id cannot be zero") } - if p.Provider == "" { + if m.Provider == "" { return fmt.Errorf("provider cannot be empty") } - if _, err := hubtypes.ProvAddressFromBech32(p.Provider); err != nil { - return errors.Wrapf(err, "invalid provider %s", p.Provider) + if _, err := hubtypes.ProvAddressFromBech32(m.Provider); err != nil { + return errors.Wrapf(err, "invalid provider %s", m.Provider) } - if p.Price != nil { - if p.Price.Len() == 0 { + if m.Price != nil { + if m.Price.Len() == 0 { return fmt.Errorf("price cannot be empty") } - if !p.Price.IsValid() { + if !m.Price.IsValid() { return fmt.Errorf("price must be valid") } } - if p.Validity < 0 { + if m.Validity < 0 { return fmt.Errorf("validity cannot be negative") } - if p.Validity == 0 { + if m.Validity == 0 { return fmt.Errorf("validity cannot be zero") } - if p.Bytes.IsNegative() { + if m.Bytes.IsNegative() { return fmt.Errorf("bytes cannot be negative") } - if p.Bytes.IsZero() { + if m.Bytes.IsZero() { return fmt.Errorf("bytes cannot be zero") } - if !p.Status.Equal(hubtypes.StatusActive) && !p.Status.Equal(hubtypes.StatusInactive) { + if !m.Status.Equal(hubtypes.StatusActive) && !m.Status.Equal(hubtypes.StatusInactive) { return fmt.Errorf("status must be either active or inactive") } - if p.StatusAt.IsZero() { + if m.StatusAt.IsZero() { return fmt.Errorf("status_at cannot be zero") }