diff --git a/.github/workflows/consensus_tests.yml b/.github/workflows/consensus_tests.yml index dbec87668b..408c79e4a9 100644 --- a/.github/workflows/consensus_tests.yml +++ b/.github/workflows/consensus_tests.yml @@ -69,5 +69,8 @@ jobs: - name: lava plans unit Tests run: go test ./x/plans/ ./x/plans/keeper ./x/plans/types -v + - name: lava projects unit Tests + run: go test ./x/projects/... -v + - name: lava subscription unit Tests run: go test ./x/subscription/... -v diff --git a/app/app.go b/app/app.go index 6008058321..0b699085ab 100644 --- a/app/app.go +++ b/app/app.go @@ -103,6 +103,9 @@ import ( plansmoduleclient "github.com/lavanet/lava/x/plans/client" plansmodulekeeper "github.com/lavanet/lava/x/plans/keeper" plansmoduletypes "github.com/lavanet/lava/x/plans/types" + projectsmodule "github.com/lavanet/lava/x/projects" + projectsmodulekeeper "github.com/lavanet/lava/x/projects/keeper" + projectsmoduletypes "github.com/lavanet/lava/x/projects/types" specmodule "github.com/lavanet/lava/x/spec" specmoduleclient "github.com/lavanet/lava/x/spec/client" specmodulekeeper "github.com/lavanet/lava/x/spec/keeper" @@ -190,6 +193,7 @@ var ( subscriptionmodule.AppModuleBasic{}, pairingmodule.AppModuleBasic{}, conflictmodule.AppModuleBasic{}, + projectsmodule.AppModuleBasic{}, plansmodule.AppModuleBasic{}, // this line is used by starport scaffolding # stargate/app/moduleBasic ) @@ -289,6 +293,7 @@ func New( subscriptionmoduletypes.StoreKey, pairingmoduletypes.StoreKey, conflictmoduletypes.StoreKey, + projectsmoduletypes.StoreKey, plansmoduletypes.StoreKey, // this line is used by starport scaffolding # stargate/app/storeKey ) @@ -373,7 +378,7 @@ func New( ) specModule := specmodule.NewAppModule(appCodec, app.SpecKeeper, app.AccountKeeper, app.BankKeeper) - // Initialize PackagesKeeper prior to govRouter (order is critical) + // Initialize PlansKeeper prior to govRouter (order is critical) app.PlansKeeper = *plansmodulekeeper.NewKeeper( appCodec, keys[plansmoduletypes.StoreKey], @@ -445,6 +450,14 @@ func New( ) pairingModule := pairingmodule.NewAppModule(appCodec, app.PairingKeeper, app.AccountKeeper, app.BankKeeper) + app.ProjectsKeeper = *projectsmodulekeeper.NewKeeper( + appCodec, + keys[projectsmoduletypes.StoreKey], + keys[projectsmoduletypes.MemStoreKey], + app.GetSubspace(projectsmoduletypes.ModuleName), + ) + projectsModule := projectsmodule.NewAppModule(appCodec, app.ProjectsKeeper) + app.SubscriptionKeeper = *subscriptionmodulekeeper.NewKeeper( appCodec, keys[subscriptionmoduletypes.StoreKey], @@ -454,6 +467,7 @@ func New( app.BankKeeper, app.AccountKeeper, &app.EpochstorageKeeper, + app.ProjectsKeeper, app.PlansKeeper, ) subscriptionModule := subscriptionmodule.NewAppModule(appCodec, app.SubscriptionKeeper, app.AccountKeeper, app.BankKeeper) @@ -516,6 +530,7 @@ func New( subscriptionModule, pairingModule, conflictModule, + projectsModule, plansModule, // this line is used by starport scaffolding # stargate/app/appModule ) @@ -543,6 +558,7 @@ func New( subscriptionmoduletypes.ModuleName, conflictmoduletypes.ModuleName, // conflict needs to change state before pairing changes stakes pairingmoduletypes.ModuleName, + projectsmoduletypes.ModuleName, plansmoduletypes.ModuleName, vestingtypes.ModuleName, upgradetypes.ModuleName, @@ -568,6 +584,7 @@ func New( subscriptionmoduletypes.ModuleName, conflictmoduletypes.ModuleName, pairingmoduletypes.ModuleName, + projectsmoduletypes.ModuleName, plansmoduletypes.ModuleName, vestingtypes.ModuleName, upgradetypes.ModuleName, @@ -597,6 +614,7 @@ func New( epochstoragemoduletypes.ModuleName, // epochStyorage end block must come before pairing for proper epoch handling subscriptionmoduletypes.ModuleName, pairingmoduletypes.ModuleName, + projectsmoduletypes.ModuleName, plansmoduletypes.ModuleName, vestingtypes.ModuleName, upgradetypes.ModuleName, @@ -634,6 +652,7 @@ func New( subscriptionModule, pairingModule, conflictModule, + projectsModule, plansModule, // this line is used by starport scaffolding # stargate/app/appModule ) @@ -854,6 +873,7 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino paramsKeeper.Subspace(subscriptionmoduletypes.ModuleName) paramsKeeper.Subspace(pairingmoduletypes.ModuleName) paramsKeeper.Subspace(conflictmoduletypes.ModuleName) + paramsKeeper.Subspace(projectsmoduletypes.ModuleName) paramsKeeper.Subspace(plansmoduletypes.ModuleName) // this line is used by starport scaffolding # stargate/app/paramSubspace diff --git a/app/keepers/lavaKeepers.go b/app/keepers/lavaKeepers.go index 2f6175b50e..007bb35452 100644 --- a/app/keepers/lavaKeepers.go +++ b/app/keepers/lavaKeepers.go @@ -20,6 +20,7 @@ import ( epochstoragemodulekeeper "github.com/lavanet/lava/x/epochstorage/keeper" pairingmodulekeeper "github.com/lavanet/lava/x/pairing/keeper" plansmodulekeeper "github.com/lavanet/lava/x/plans/keeper" + projectsmodulekeeper "github.com/lavanet/lava/x/projects/keeper" specmodulekeeper "github.com/lavanet/lava/x/spec/keeper" subscriptionmodulekeeper "github.com/lavanet/lava/x/subscription/keeper" // this line is used by starport scaffolding # stargate/app/moduleImport @@ -53,5 +54,6 @@ type LavaKeepers struct { EpochstorageKeeper epochstoragemodulekeeper.Keeper PairingKeeper pairingmodulekeeper.Keeper ConflictKeeper conflictmodulekeeper.Keeper + ProjectsKeeper projectsmodulekeeper.Keeper PlansKeeper plansmodulekeeper.Keeper } diff --git a/testutil/keeper/keepers_init.go b/testutil/keeper/keepers_init.go index 38a129fddd..5fe66192e8 100644 --- a/testutil/keeper/keepers_init.go +++ b/testutil/keeper/keepers_init.go @@ -49,10 +49,10 @@ type Keepers struct { Epochstorage epochstoragekeeper.Keeper Spec speckeeper.Keeper Plans planskeeper.Keeper + Projects projectskeeper.Keeper Subscription subscriptionkeeper.Keeper Pairing pairingkeeper.Keeper Conflict conflictkeeper.Keeper - Projects projectskeeper.Keeper BankKeeper mockBankKeeper AccountKeeper mockAccountKeeper ParamsKeeper paramskeeper.Keeper @@ -107,6 +107,11 @@ func InitAllKeepers(t testing.TB) (*Servers, *Keepers, context.Context) { stateStore.MountStoreWithDB(plansStoreKey, sdk.StoreTypeIAVL, db) stateStore.MountStoreWithDB(plansMemStoreKey, sdk.StoreTypeMemory, nil) + projectsStoreKey := sdk.NewKVStoreKey(projectstypes.StoreKey) + projectsMemStoreKey := storetypes.NewMemoryStoreKey(projectstypes.MemStoreKey) + stateStore.MountStoreWithDB(projectsStoreKey, sdk.StoreTypeIAVL, db) + stateStore.MountStoreWithDB(projectsMemStoreKey, sdk.StoreTypeMemory, nil) + subscriptionStoreKey := sdk.NewKVStoreKey(subscriptiontypes.StoreKey) subscriptionMemStoreKey := storetypes.NewMemoryStoreKey(subscriptiontypes.MemStoreKey) stateStore.MountStoreWithDB(subscriptionStoreKey, sdk.StoreTypeIAVL, db) @@ -127,16 +132,10 @@ func InitAllKeepers(t testing.TB) (*Servers, *Keepers, context.Context) { stateStore.MountStoreWithDB(conflictStoreKey, sdk.StoreTypeIAVL, db) stateStore.MountStoreWithDB(conflictMemStoreKey, sdk.StoreTypeMemory, nil) - projectsStoreKey := sdk.NewKVStoreKey(projectstypes.StoreKey) - projectsMemStoreKey := storetypes.NewMemoryStoreKey(projectstypes.MemStoreKey) - stateStore.MountStoreWithDB(projectsStoreKey, sdk.StoreTypeIAVL, db) - stateStore.MountStoreWithDB(projectsMemStoreKey, sdk.StoreTypeMemory, nil) - require.NoError(t, stateStore.LoadLatestVersion()) paramsKeeper := paramskeeper.NewKeeper(cdc, pairingtypes.Amino, paramsStoreKey, tkey) paramsKeeper.Subspace(spectypes.ModuleName) - paramsKeeper.Subspace(subscriptiontypes.ModuleName) paramsKeeper.Subspace(epochstoragetypes.ModuleName) paramsKeeper.Subspace(pairingtypes.ModuleName) // paramsKeeper.Subspace(conflicttypes.ModuleName) //TODO... @@ -167,7 +166,8 @@ func InitAllKeepers(t testing.TB) (*Servers, *Keepers, context.Context) { ks.Projects = *projectskeeper.NewKeeper(cdc, projectsStoreKey, projectsMemStoreKey, projectsparamsSubspace) ks.Epochstorage = *epochstoragekeeper.NewKeeper(cdc, epochStoreKey, epochMemStoreKey, epochparamsSubspace, &ks.BankKeeper, &ks.AccountKeeper, ks.Spec) ks.Plans = *planskeeper.NewKeeper(cdc, plansStoreKey, plansMemStoreKey, plansparamsSubspace) - ks.Subscription = *subscriptionkeeper.NewKeeper(cdc, subscriptionStoreKey, subscriptionMemStoreKey, subscriptionparamsSubspace, &ks.BankKeeper, &ks.AccountKeeper, &ks.Epochstorage, ks.Plans) + ks.Projects = *projectskeeper.NewKeeper(cdc, projectsStoreKey, projectsMemStoreKey, projectsparamsSubspace) + ks.Subscription = *subscriptionkeeper.NewKeeper(cdc, subscriptionStoreKey, subscriptionMemStoreKey, subscriptionparamsSubspace, &ks.BankKeeper, &ks.AccountKeeper, &ks.Epochstorage, ks.Projects, ks.Plans) ks.Pairing = *pairingkeeper.NewKeeper(cdc, pairingStoreKey, pairingMemStoreKey, pairingparamsSubspace, &ks.BankKeeper, &ks.AccountKeeper, ks.Spec, &ks.Epochstorage) ks.ParamsKeeper = paramsKeeper ks.Conflict = *conflictkeeper.NewKeeper(cdc, conflictStoreKey, conflictMemStoreKey, conflictparamsSubspace, &ks.BankKeeper, &ks.AccountKeeper, ks.Pairing, ks.Epochstorage, ks.Spec) diff --git a/testutil/keeper/subscription.go b/testutil/keeper/subscription.go index ab758b1d61..43eca0b36d 100644 --- a/testutil/keeper/subscription.go +++ b/testutil/keeper/subscription.go @@ -11,6 +11,7 @@ import ( typesparams "github.com/cosmos/cosmos-sdk/x/params/types" epochstoragekeeper "github.com/lavanet/lava/x/epochstorage/keeper" planskeeper "github.com/lavanet/lava/x/plans/keeper" + projectskeeper "github.com/lavanet/lava/x/projects/keeper" "github.com/lavanet/lava/x/subscription/keeper" "github.com/lavanet/lava/x/subscription/types" "github.com/stretchr/testify/require" @@ -46,6 +47,13 @@ func SubscriptionKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) { "EpochStorageParams", ) + paramsSubspaceProjects := typesparams.NewSubspace(cdc, + types.Amino, + storeKey, + memStoreKey, + "ProjectsParams", + ) + paramsSubspacePlans := typesparams.NewSubspace(cdc, types.Amino, storeKey, @@ -61,6 +69,7 @@ func SubscriptionKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) { nil, nil, epochstoragekeeper.NewKeeper(cdc, nil, nil, paramsSubspaceEpochstorage, nil, nil, nil), + projectskeeper.NewKeeper(cdc, nil, nil, paramsSubspaceProjects), planskeeper.NewKeeper(cdc, nil, nil, paramsSubspacePlans), ) diff --git a/x/projects/module.go b/x/projects/module.go index 32c1795adc..c60912c9b5 100644 --- a/x/projects/module.go +++ b/x/projects/module.go @@ -99,22 +99,16 @@ func (AppModuleBasic) GetQueryCmd() *cobra.Command { type AppModule struct { AppModuleBasic - keeper keeper.Keeper - accountKeeper types.AccountKeeper - bankKeeper types.BankKeeper + keeper keeper.Keeper } func NewAppModule( cdc codec.Codec, keeper keeper.Keeper, - accountKeeper types.AccountKeeper, - bankKeeper types.BankKeeper, ) AppModule { return AppModule{ AppModuleBasic: NewAppModuleBasic(cdc), keeper: keeper, - accountKeeper: accountKeeper, - bankKeeper: bankKeeper, } } diff --git a/x/projects/module_simulation.go b/x/projects/module_simulation.go index e10728772e..7e01a560cc 100644 --- a/x/projects/module_simulation.go +++ b/x/projects/module_simulation.go @@ -73,7 +73,7 @@ func (am AppModule) WeightedOperations(simState module.SimulationState) []simtyp ) operations = append(operations, simulation.NewWeightedOperation( weightMsgAddProjectKeys, - projectssimulation.SimulateMsgAddProjectKeys(am.accountKeeper, am.bankKeeper, am.keeper), + projectssimulation.SimulateMsgAddProjectKeys(am.keeper), )) var weightMsgSetProjectPolicy int @@ -84,7 +84,7 @@ func (am AppModule) WeightedOperations(simState module.SimulationState) []simtyp ) operations = append(operations, simulation.NewWeightedOperation( weightMsgSetProjectPolicy, - projectssimulation.SimulateMsgSetProjectPolicy(am.accountKeeper, am.bankKeeper, am.keeper), + projectssimulation.SimulateMsgSetProjectPolicy(am.keeper), )) // this line is used by starport scaffolding # simapp/module/operation diff --git a/x/projects/simulation/add_project_keys.go b/x/projects/simulation/add_project_keys.go index 1c92c819e4..565432229c 100644 --- a/x/projects/simulation/add_project_keys.go +++ b/x/projects/simulation/add_project_keys.go @@ -11,8 +11,6 @@ import ( ) func SimulateMsgAddProjectKeys( - ak types.AccountKeeper, - bk types.BankKeeper, k keeper.Keeper, ) simtypes.Operation { return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, diff --git a/x/projects/simulation/set_project_policy.go b/x/projects/simulation/set_project_policy.go index ee30c81700..0875908bea 100644 --- a/x/projects/simulation/set_project_policy.go +++ b/x/projects/simulation/set_project_policy.go @@ -11,8 +11,6 @@ import ( ) func SimulateMsgSetProjectPolicy( - ak types.AccountKeeper, - bk types.BankKeeper, k keeper.Keeper, ) simtypes.Operation { return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, diff --git a/x/subscription/keeper/keeper.go b/x/subscription/keeper/keeper.go index b405ba6a6c..69b0cfb143 100644 --- a/x/subscription/keeper/keeper.go +++ b/x/subscription/keeper/keeper.go @@ -21,6 +21,7 @@ type ( bankKeeper types.BankKeeper accountKeeper types.AccountKeeper epochstorageKeeper types.EpochstorageKeeper + projectsKeeper types.ProjectsKeeper plansKeeper types.PlansKeeper } ) @@ -34,6 +35,7 @@ func NewKeeper( bankKeeper types.BankKeeper, accountKeeper types.AccountKeeper, epochstorageKeeper types.EpochstorageKeeper, + projectsKeeper types.ProjectsKeeper, plansKeeper types.PlansKeeper, ) *Keeper { // set KeyTable if it has not already been set @@ -50,6 +52,7 @@ func NewKeeper( bankKeeper: bankKeeper, accountKeeper: accountKeeper, epochstorageKeeper: epochstorageKeeper, + projectsKeeper: projectsKeeper, plansKeeper: plansKeeper, } } diff --git a/x/subscription/keeper/subscription.go b/x/subscription/keeper/subscription.go index e1a578e2aa..fac387aca2 100644 --- a/x/subscription/keeper/subscription.go +++ b/x/subscription/keeper/subscription.go @@ -183,6 +183,24 @@ func (k Keeper) CreateSubscription( } }() + err = k.projectsKeeper.CreateDefaultProject(ctx, consumer) + if err != nil { + details := map[string]string{ + "err": err.Error(), + } + err = utils.LavaError(ctx, logger, "subscribe", details, "failed to create default project") + return err + } + + // delete default Project in case of error + defer func() { + if err != nil { + // TODO: delete all projects of the subscription + // k.projectsKeeper.DeleteAllProject(ctx, consumer) + _ = err + } + }() + price := plan.GetPrice() expiry := time.Now().UTC() diff --git a/x/subscription/keeper/subscription_test.go b/x/subscription/keeper/subscription_test.go index 0ea82b9f9b..48ce5b8e67 100644 --- a/x/subscription/keeper/subscription_test.go +++ b/x/subscription/keeper/subscription_test.go @@ -9,7 +9,6 @@ import ( "github.com/lavanet/lava/testutil/common" keepertest "github.com/lavanet/lava/testutil/keeper" "github.com/lavanet/lava/testutil/nullify" - epochstoragetypes "github.com/lavanet/lava/x/epochstorage/types" "github.com/lavanet/lava/x/subscription/keeper" "github.com/lavanet/lava/x/subscription/types" "github.com/stretchr/testify/require" @@ -75,7 +74,6 @@ func TestCreateSubscription(t *testing. T) { ctx := sdk.UnwrapSDKContext(_ctx) keeper := keepers.Subscription - bankKeeper := keepers.BankKeeper plansKeeper := keepers.Plans plan := common.CreateMockPlan() @@ -101,20 +99,15 @@ func TestCreateSubscription(t *testing. T) { for i := range creators { if creators[i].address == "FILL" { - _, addr := sigs.GenerateFloatingKey() - creators[i].address = addr.String() - coins := sdk.NewCoins(sdk.NewCoin( - epochstoragetypes.TokenDenom, - sdk.NewInt(creators[i].amount), - )) - bankKeeper.SetBalance(ctx, addr, coins) + account := common.CreateNewAccount(_ctx, *keepers, creators[i].amount) + creators[i].address = account.Addr.String() } } consumers := make([]string, 4) for i := range consumers { - _, addr := sigs.GenerateFloatingKey() - consumers[i] = addr.String() + account := common.CreateNewAccount(_ctx, *keepers, 1) + consumers[i] = account.Addr.String() } consumers[3] = "invalid consumer" @@ -198,3 +191,24 @@ func TestCreateSubscription(t *testing. T) { } } } + +func TestSubscriptionDefaultProject(t *testing. T) { + _, keepers, _ctx := keepertest.InitAllKeepers(t) + ctx := sdk.UnwrapSDKContext(_ctx) + + keeper := keepers.Subscription + keepers.Plans.AddPlan(ctx, common.CreateMockPlan()) + + account := common.CreateNewAccount(_ctx, *keepers, 10000) + creator := account.Addr.String() + + err := keeper.CreateSubscription(ctx, creator, creator, "mockPlan", true) + require.Nil(t, err) + + block := uint64(ctx.BlockHeight()) + + // a newly created subscription is expected to have one default project, + // with the subscription address as its developer key + _, err = keepers.Projects.GetProjectIDForDeveloper(ctx, creator, block) + require.Nil(t, err) +} diff --git a/x/subscription/types/expected_keepers.go b/x/subscription/types/expected_keepers.go index e957e86c82..d78fc8f66f 100644 --- a/x/subscription/types/expected_keepers.go +++ b/x/subscription/types/expected_keepers.go @@ -24,6 +24,12 @@ type EpochstorageKeeper interface { // Methods imported from epochstorage should be defined here } +type ProjectsKeeper interface { + CreateDefaultProject(ctx sdk.Context, consumer string) error + DeleteProject(ctx sdk.Context, index string) error + // Methods imported from projectskeeper should be defined here +} + type PlansKeeper interface { GetPlan(ctx sdk.Context, index string) (planstypes.Plan, bool) PutPlan(ctx sdk.Context, index string, block uint64) bool