Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CNS-268: Implement Plans module #300

Merged
merged 58 commits into from
Mar 2, 2023
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
e82dab3
CNS-268: created packageManager module
oren-lava Jan 31, 2023
ff2bafb
CNS-268: created package protobuf
oren-lava Jan 31, 2023
e0d1bd6
CNS-268: created generic fixation manager
oren-lava Feb 1, 2023
5e0cf6a
CNS-268: changed package and paramFixation proto
oren-lava Feb 1, 2023
07244c3
CNS-268: created packagemanager module and implemented package storag…
oren-lava Feb 5, 2023
e247096
CNS-268: fix lint issues
oren-lava Feb 5, 2023
12d5c7d
CNS-268: added package deletion on epoch start
oren-lava Feb 5, 2023
1485238
CNS-268: renamed the module to packages (orig name: packagemanager)
oren-lava Feb 5, 2023
6147447
CNS-268: added func to update subs, changed package deletoion criterion
oren-lava Feb 5, 2023
69929f5
CNS-268: added vote proposal support
oren-lava Feb 6, 2023
43da929
CNS-268: added type and description to package proto
oren-lava Feb 6, 2023
594458d
CNS-268: fixed part of a package's validation
oren-lava Feb 6, 2023
e3a4ecf
CNS-268: removed unnecessary proposal funcs
oren-lava Feb 7, 2023
cf4f3ba
CNS-268: finished vote proposal
oren-lava Feb 7, 2023
1de80f8
CNS-268: fixed vote proposal
oren-lava Feb 7, 2023
ab9a6e2
CNS-268: implemented show-all-packages query
oren-lava Feb 7, 2023
09447cb
CNS-268: bug fixes
oren-lava Feb 8, 2023
a0bea14
CNS-268: added show-package-info query
oren-lava Feb 8, 2023
0cab70b
CNS-268: bug fixes
oren-lava Feb 9, 2023
4f9046c
CNS-268: implemented unit tests
oren-lava Feb 9, 2023
7c136fe
CNS-268: changed the way entryFixation works, updated packages module…
oren-lava Feb 12, 2023
b96eb1d
CNS-268: fixed bugs, added unit test, added example of package propos…
oren-lava Feb 13, 2023
54b6d26
Merge branch 'main' into CNS-268-implement-package-module
oren-lava Feb 13, 2023
fb2479f
Merge branch 'main' into CNS-268-implement-package-module
oren-lava Feb 13, 2023
088429a
CNS-268: fix epochstorage API signatures and lint issues
oren-lava Feb 13, 2023
1f58e34
CNS-268: fixed PR issues
oren-lava Feb 14, 2023
1099953
CNS-268: moves specs to their original folder
oren-lava Feb 14, 2023
971033d
common now knows how to use the store
Feb 15, 2023
7806274
CNS-268: upgrade plan + fix new design. still left TODOs
oren-lava Feb 15, 2023
2748480
CNS-268: fixation entry now also manages unique indices, bug fixes an…
oren-lava Feb 16, 2023
03bda1c
CNS-268: cleaned the code
oren-lava Feb 16, 2023
fc572ad
CNS-268: changed fixation entry API names
oren-lava Feb 16, 2023
f533f1e
CNS-268: fix PR issues
oren-lava Feb 16, 2023
c202b83
CNS-268: added unit test of bad package proposal
oren-lava Feb 19, 2023
4579375
CNS-268: removed subs field from package since entry fixation will ha…
oren-lava Feb 20, 2023
18a5876
Merge branch 'CNS-291-fixation-library-implementation' into CNS-268-i…
oren-lava Feb 26, 2023
f35ca3a
Merge branch 'CNS-291-fixation-library-implementation' into CNS-268-i…
oren-lava Feb 26, 2023
ab2bf4a
CNS-268: fixed packages module impl and tests after fixation merge
oren-lava Feb 26, 2023
2e981fe
Merge branch 'CNS-291-fixation-library-implementation' into CNS-268-i…
oren-lava Feb 27, 2023
dbd3e47
CNS-268: fix test according to fixation changes
oren-lava Feb 27, 2023
eddbc96
Merge branch 'CNS-291-fixation-library-implementation' into CNS-268-i…
oren-lava Feb 27, 2023
d5861b2
Merge branch 'CNS-291-fixation-library-implementation' into CNS-268-i…
oren-lava Feb 27, 2023
a60174d
CNS-268: additional fix according to fixation update
oren-lava Feb 27, 2023
1ed807c
CNS-268: changed packages module name to plan
oren-lava Feb 27, 2023
cb7bdad
Merge branch 'main' into CNS-268-implement-package-module
Feb 27, 2023
3f97864
CNS-268: fix PR issues
oren-lava Feb 27, 2023
5e113b0
CNS-268: fix github action unit tests path
oren-lava Feb 27, 2023
1544158
CNS-268: undo upgrade script change
oren-lava Feb 27, 2023
f4cd085
Merge branch 'main' into CNS-268-implement-package-module
oren-lava Feb 27, 2023
6a856c9
CNS-291: changed key prefix to work with bytes
oren-lava Mar 2, 2023
c908123
Merge branch 'CNS-291-fixation-library-implementation' into CNS-268-i…
oren-lava Mar 2, 2023
dbdfab5
CNS-268: fix PR issues
oren-lava Mar 2, 2023
e38f4c3
CNS-291: changed entry fixation get funcs return values and append's …
oren-lava Mar 2, 2023
0c0445b
Merge branch 'CNS-291-fixation-library-implementation' into CNS-268-i…
oren-lava Mar 2, 2023
452a37f
CNS-268: updated plans funcs according to fixation update
oren-lava Mar 2, 2023
82f9d8e
CNS-291: undo append args change
oren-lava Mar 2, 2023
f934276
Merge branch 'CNS-291-fixation-library-implementation' into CNS-268-i…
oren-lava Mar 2, 2023
3e67ec4
CNS-268: revert append args change
oren-lava Mar 2, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ import (
epochstoragemodule "github.com/lavanet/lava/x/epochstorage"
epochstoragemodulekeeper "github.com/lavanet/lava/x/epochstorage/keeper"
epochstoragemoduletypes "github.com/lavanet/lava/x/epochstorage/types"
"github.com/lavanet/lava/x/packages"
packagesmoduleclient "github.com/lavanet/lava/x/packages/client"
packagesmodulekeeper "github.com/lavanet/lava/x/packages/keeper"
packagesmoduletypes "github.com/lavanet/lava/x/packages/types"
pairingmodule "github.com/lavanet/lava/x/pairing"
pairingmodulekeeper "github.com/lavanet/lava/x/pairing/keeper"
pairingmoduletypes "github.com/lavanet/lava/x/pairing/types"
Expand Down Expand Up @@ -134,6 +138,7 @@ func getGovProposalHandlers() []govclient.ProposalHandler {
ibcclientclient.UpdateClientProposalHandler,
ibcclientclient.UpgradeProposalHandler,
specmoduleclient.SpecAddProposalHandler,
packagesmoduleclient.PackagesAddProposalHandler,
// this line is used by starport scaffolding # stargate/app/govProposalHandler
)

Expand Down Expand Up @@ -169,6 +174,7 @@ var (
epochstoragemodule.AppModuleBasic{},
pairingmodule.AppModuleBasic{},
conflictmodule.AppModuleBasic{},
packages.AppModuleBasic{},
// this line is used by starport scaffolding # stargate/app/moduleBasic
)

Expand Down Expand Up @@ -265,6 +271,7 @@ func New(
epochstoragemoduletypes.StoreKey,
pairingmoduletypes.StoreKey,
conflictmoduletypes.StoreKey,
packagesmoduletypes.StoreKey,
// this line is used by starport scaffolding # stargate/app/storeKey
)
tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey)
Expand Down Expand Up @@ -349,6 +356,16 @@ func New(
)
specModule := spec.NewAppModule(appCodec, app.SpecKeeper, app.AccountKeeper, app.BankKeeper)

// Initialize PackagesKeeper prior to govRouter (order is critical)
app.PackagesKeeper = *packagesmodulekeeper.NewKeeper(
appCodec,
keys[packagesmoduletypes.StoreKey],
keys[packagesmoduletypes.MemStoreKey],
app.GetSubspace(packagesmoduletypes.ModuleName),
&app.EpochstorageKeeper,
)
packagesModule := packages.NewAppModule(appCodec, app.PackagesKeeper, app.AccountKeeper, app.BankKeeper)

// register the proposal types
govRouter := govtypes.NewRouter()
govRouter.AddRoute(govtypes.RouterKey, govtypes.ProposalHandler).
Expand All @@ -357,6 +374,8 @@ func New(
AddRoute(specmoduletypes.ProposalsRouterKey, spec.NewSpecProposalsHandler(app.SpecKeeper)).
// copied the code from param and changed the handler to enable functionality
AddRoute(paramproposal.RouterKey, spec.NewParamChangeProposalHandler(app.ParamsKeeper)).
// user defined
AddRoute(packagesmoduletypes.ProposalsRouterKey, packages.NewPackagesProposalsHandler(app.PackagesKeeper)).

//
// default
Expand Down Expand Up @@ -467,6 +486,7 @@ func New(
epochstorageModule,
pairingModule,
conflictModule,
packagesModule,
// this line is used by starport scaffolding # stargate/app/appModule
)

Expand All @@ -492,6 +512,7 @@ func New(
epochstoragemoduletypes.ModuleName,
conflictmoduletypes.ModuleName, // conflict needs to change state before pairing changes stakes
pairingmoduletypes.ModuleName,
packagesmoduletypes.ModuleName,
vestingtypes.ModuleName,
upgradetypes.ModuleName,
feegrant.ModuleName,
Expand All @@ -515,6 +536,7 @@ func New(
epochstoragemoduletypes.ModuleName,
conflictmoduletypes.ModuleName,
pairingmoduletypes.ModuleName,
packagesmoduletypes.ModuleName,
vestingtypes.ModuleName,
upgradetypes.ModuleName,
feegrant.ModuleName,
Expand Down Expand Up @@ -542,6 +564,7 @@ func New(
specmoduletypes.ModuleName,
epochstoragemoduletypes.ModuleName, // epochStyorage end block must come before pairing for proper epoch handling
pairingmoduletypes.ModuleName,
packagesmoduletypes.ModuleName,
vestingtypes.ModuleName,
upgradetypes.ModuleName,
feegrant.ModuleName,
Expand Down Expand Up @@ -577,6 +600,7 @@ func New(
epochstorageModule,
pairingModule,
conflictModule,
packagesModule,
// this line is used by starport scaffolding # stargate/app/appModule
)
app.sm.RegisterStoreDecoders()
Expand Down Expand Up @@ -795,6 +819,7 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino
paramsKeeper.Subspace(epochstoragemoduletypes.ModuleName)
paramsKeeper.Subspace(pairingmoduletypes.ModuleName)
paramsKeeper.Subspace(conflictmoduletypes.ModuleName)
paramsKeeper.Subspace(packagesmoduletypes.ModuleName)
// this line is used by starport scaffolding # stargate/app/paramSubspace

return paramsKeeper
Expand Down
2 changes: 2 additions & 0 deletions app/keepers/lavaKeepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper"
conflictmodulekeeper "github.com/lavanet/lava/x/conflict/keeper"
epochstoragemodulekeeper "github.com/lavanet/lava/x/epochstorage/keeper"
packagesmodulekeeper "github.com/lavanet/lava/x/packages/keeper"
pairingmodulekeeper "github.com/lavanet/lava/x/pairing/keeper"
specmodulekeeper "github.com/lavanet/lava/x/spec/keeper"
// this line is used by starport scaffolding # stargate/app/moduleImport
Expand Down Expand Up @@ -50,4 +51,5 @@ type LavaKeepers struct {
EpochstorageKeeper epochstoragemodulekeeper.Keeper
PairingKeeper pairingmodulekeeper.Keeper
ConflictKeeper conflictmodulekeeper.Keeper
PackagesKeeper packagesmodulekeeper.Keeper
}
213 changes: 213 additions & 0 deletions common/entryFixation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
package common

import (
"strconv"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/lavanet/lava/common/types"
"github.com/lavanet/lava/utils"
)

type (
GetterFunc func(ctx sdk.Context, index string) (*types.Entry, bool)
setterFunc func(ctx sdk.Context, index string, entry *types.Entry) error
removerFunc func(ctx sdk.Context, index string)
)

// Function to add an entry to the KVStore and update the older versions entries' indices that are saved in the KVStore
func AddFixatedEntryToStorage(ctx sdk.Context, entryToSet *types.Entry, index string, getEntry GetterFunc, setEntry setterFunc, removeEntry removerFunc) (bool, error) {
// check that the function pointers are not nil
if setEntry == nil || getEntry == nil || removeEntry == nil {
return false, utils.LavaError(ctx, ctx.Logger(), "set_fixated_entry", nil, "setterFunc and/or GetterFunc input is nil")
}

isFirstVersion := false
if !checkEntryProposedInThisEpoch(ctx, entryToSet, index, getEntry) {
// update the older versions entries indices
isFirstVersionTemp, err := UpdateEntryIndices(ctx, index, getEntry, setEntry, removeEntry)
if err != nil {
return isFirstVersion, utils.LavaError(ctx, ctx.Logger(), "update_entry_indices", map[string]string{"entryToSetIndex": index}, "could not update entries indices (due to entry addition)")
}
isFirstVersion = isFirstVersionTemp
}

// set the new entry as the latest version (by using the index without number suffix)
err := setEntry(ctx, index, entryToSet)
if err != nil {
return isFirstVersion, utils.LavaError(ctx, ctx.Logger(), "set_entry", map[string]string{"entryToSetIndex": index}, "could not set entry with index")
}

return isFirstVersion, nil
}

func checkEntryProposedInThisEpoch(ctx sdk.Context, newEntryToPropose *types.Entry, newEntryIndex string, getEntry GetterFunc) bool {
oldEntry, found := getEntry(ctx, newEntryIndex)
if found {
if newEntryToPropose.GetEpoch() == oldEntry.GetEpoch() {
return true
}
}
return false
}

// Function to update the indices of older versions of some entry due to new entry version (number suffix is increased by 1)
func UpdateEntryIndices(ctx sdk.Context, index string, getEntry GetterFunc, setEntry setterFunc, removeEntry removerFunc) (bool, error) {
// get the index list of version entries saved in the KVStore
entryList, indexList := GetAllEntriesFromStorageByIndex(ctx, index, getEntry)

// get the number of versions saved in the KVStore
entryVersionsAmount := len(entryList)

// check if the added package is the first version (no older versions available)
isFirstVersion := false
if entryVersionsAmount == 0 {
isFirstVersion = true
}

// update the older version entries' indices (the number suffix is increased by 1). Note that we start from the oldest version back, and handle the latest version package separately (see below)
for i := 0; i < entryVersionsAmount; i++ {
oren-lava marked this conversation as resolved.
Show resolved Hide resolved
// get the older version entry and its index (the suffix number of the index will be entryVersionsAmount-i-1 since the first entry (the latest version) is without suffix)
olderVersionEntry := entryList[entryVersionsAmount-i-1]
olderVersionEntryIndex := indexList[entryVersionsAmount-i-1]

// remove the older version entry from the storage
err := RemoveEntryFromStorage(ctx, olderVersionEntryIndex, removeEntry)
oren-lava marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return isFirstVersion, utils.LavaError(ctx, ctx.Logger(), "remove_entry_from_storage", map[string]string{"entryIndexToRemove": olderVersionEntryIndex, "isFirstVersion": strconv.FormatBool(isFirstVersion)}, "could not remove entry with index")
}

// construct an updated index for the older version entry (increase the number suffix by 1)
olderVersionEntryUpdatedIndex := index + "_" + strconv.FormatUint(uint64(entryVersionsAmount-i-1), 10)
oren-lava marked this conversation as resolved.
Show resolved Hide resolved

// set the older version entry with the updated index
err = setEntry(ctx, olderVersionEntryUpdatedIndex, olderVersionEntry)
if err != nil {
return isFirstVersion, utils.LavaError(ctx, ctx.Logger(), "set_entry", map[string]string{"entryToSetIndex": olderVersionEntryUpdatedIndex, "isFirstVersion": strconv.FormatBool(isFirstVersion)}, "could not set entry with index")
}
}

return isFirstVersion, nil
}

// Function to create a fixated entry from epoch and marshaled data
func CreateNewFixatedEntry(ctx sdk.Context, epoch uint64, marshaledData []byte) (*types.Entry, error) {
// check that marshaledData is not nil
if marshaledData == nil {
return nil, utils.LavaError(ctx, ctx.Logger(), "create_new_fixated_entry", nil, "marshaled data is nil. Can't create fixated entry")
}

// create new entry
newEntry := types.Entry{Epoch: epoch, MarshaledData: marshaledData}

return &newEntry, nil
}

// Function to get the marshaled data from an entry by epoch
func GetMarshaledDataFromFixatedEntryByEpoch(ctx sdk.Context, epoch uint64, index string, getEntry GetterFunc) ([]byte, error) {
// check that getEntry is not nil
if getEntry == nil {
oren-lava marked this conversation as resolved.
Show resolved Hide resolved
return nil, utils.LavaError(ctx, ctx.Logger(), "get_marshaled_data_from_fixated_entry_by_epoch", nil, "GetterFunc input is nil")
}

// use the getter function to get the entry by the index
entry, found := GetEntryFromStorage(ctx, index, epoch, getEntry)
if !found {
return nil, utils.LavaError(ctx, ctx.Logger(), "search_for_entry_in_storage", map[string]string{"entryIndex": index, "requestedEpoch": strconv.FormatUint(epoch, 10)}, "entry with index and requested epoch not found")
}

// get marshaled data from the entry and make sure it's not nil
marshaledData := entry.GetMarshaledData()
if marshaledData == nil {
return nil, utils.LavaError(ctx, ctx.Logger(), "get_marshaled_data_from_fixated_entry_by_epoch", map[string]string{"entryIndex": index, "entryEpoch": strconv.FormatUint(entry.GetEpoch(), 10), "epochRequested": strconv.FormatUint(epoch, 10)}, "the marshaled data of the requested entry is nil")
}

return marshaledData, nil
}

// Function to search for an entry in the storage (latest version's index is index, older versions' index is index_0, index_1, ...)
func GetEntryFromStorage(ctx sdk.Context, index string, epoch uint64, getEntry GetterFunc) (*types.Entry, bool) {
// try getting the entry with the original index. return only if the requested epoch is larger than the entry's epoch
entry, found := getEntry(ctx, index)
if found {
if epoch >= entry.GetEpoch() {
return entry, true
}
} else {
// couldn't find the entry
return nil, false
}

// couldn't find the entry for requested epoch (epoch too small) -> may be an older version. older version indices are "index_0" (or other numbers)
versionSuffixCounter := 0
for {
// construct the older version index
versionIndex := index + "_" + strconv.FormatInt(int64(versionSuffixCounter), 10)

// get the older version entry
entry, found := getEntry(ctx, versionIndex)
if found {
if epoch > entry.GetEpoch() {
// entry old version found and the requested epoch is larger than the entry's epoch -> found the right entry
return entry, true
} else {
// entry old version found and the requested epoch is smaller than the entry's epoch -> not the right entry version, update suffix to check older versions
versionSuffixCounter += 1
}
} else {
// entry wasn't found, break
break
}
}

return nil, false
}

// Function that gets an index for storage and returns all the entries and their corresponding indices (i.e., the latest version entry and all of its older versions)
func GetAllEntriesFromStorageByIndex(ctx sdk.Context, index string, getEntry GetterFunc) ([]*types.Entry, []string) {
entryList := []*types.Entry{}
indexList := []string{}

// try getting the entry with the original index
entry, found := getEntry(ctx, index)
if found {
entryList = append(entryList, entry)
indexList = append(indexList, index)
} else {
// couldn't find the entry
return nil, nil
}

// get the older versions of this entry
versionSuffixCounter := 0
for {
// construct the older version index
versionIndex := index + "_" + strconv.FormatInt(int64(versionSuffixCounter), 10)
oren-lava marked this conversation as resolved.
Show resolved Hide resolved

// get the older version entry
oldVersionEntry, found := getEntry(ctx, versionIndex)
if found {
// entry old version found -> append to entry list and increase suffix counter to look for older versions
entryList = append(entryList, oldVersionEntry)
indexList = append(indexList, versionIndex)
oren-lava marked this conversation as resolved.
Show resolved Hide resolved
versionSuffixCounter += 1
} else {
// entry old version wasn't found -> break
break
}
}

return entryList, indexList
}

// Function to remove an entry from the KVStore
func RemoveEntryFromStorage(ctx sdk.Context, index string, removeEntry removerFunc) error {
// check that the removerFunc function pointer is not nil
if removeEntry == nil {
return utils.LavaError(ctx, ctx.Logger(), "remove_entry_from_storage", nil, "removerFunc input is nil")
}

// remove the entry from the KVStore
removeEntry(ctx, index)

return nil
}
Loading