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

v4 Upgrade Handler #385

Merged
merged 24 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
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
2 changes: 1 addition & 1 deletion app/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (app *JackalApp) registerTestnetUpgradeHandlers() {
func (app *JackalApp) registerMainnetUpgradeHandlers() {
app.registerUpgrade(bouncybulldog.NewUpgrade(app.mm, app.configurator, app.OracleKeeper))
app.registerUpgrade(v3.NewUpgrade(app.mm, app.configurator, app.StorageKeeper))
app.registerUpgrade(v4.NewUpgrade(app.mm, app.configurator, app.StorageKeeper, app.FileTreeKeeper))
app.registerUpgrade(v4.NewUpgrade(app.mm, app.configurator, &app.StorageKeeper, &app.FileTreeKeeper))
}

// registerUpgrade registers the given upgrade to be supported by the app
Expand Down
116 changes: 111 additions & 5 deletions app/upgrades/v4/commont_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
package v4_test

import (
gocontext "context"
"fmt"
"testing"

authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/golang/mock/gomock"
minttypes "github.com/jackalLabs/canine-chain/v3/x/jklmint/types"
oracletypes "github.com/jackalLabs/canine-chain/v3/x/oracle/types"
storagekeeper "github.com/jackalLabs/canine-chain/v3/x/storage/keeper"
storagetestutil "github.com/jackalLabs/canine-chain/v3/x/storage/testutil"
storagemoduletypes "github.com/jackalLabs/canine-chain/v3/x/storage/types"

storetypes "github.com/cosmos/cosmos-sdk/store/types"
typesparams "github.com/cosmos/cosmos-sdk/x/params/types"
canineglobaltestutil "github.com/jackalLabs/canine-chain/v3/testutil"
Expand All @@ -21,6 +30,8 @@ import (
"github.com/stretchr/testify/suite"
)

var modAccount = authtypes.NewModuleAddress(types.ModuleName)

// SetupFileTreeKeeper creates a filetreeKeeper as well as all its dependencies.
func SetupFileTreeKeeper(t *testing.T) (
*keeper.Keeper,
Expand Down Expand Up @@ -56,12 +67,68 @@ func SetupFileTreeKeeper(t *testing.T) (
return filetreeKeeper, encCfg, ctx
}

// SetupStorageKeeper creates a storageKeeper as well as all its dependencies.
func SetupStorageKeeper(t *testing.T) (
*storagekeeper.Keeper,
*storagetestutil.MockBankKeeper,
*storagetestutil.MockAccountKeeper,
moduletestutil.TestEncodingConfig,
sdk.Context,
) {
key := sdk.NewKVStoreKey(storagemoduletypes.StoreKey)
// memStoreKey := storetypes.NewMemoryStoreKey(storagemoduletypes.MemStoreKey)
tkey := sdk.NewTransientStoreKey("transient_test")
testCtx := canineglobaltestutil.DefaultContextWithDB(t, key, tkey)
ctx := testCtx.Ctx.WithBlockHeader(tmproto.Header{Time: tmtime.Now()})

encCfg := moduletestutil.MakeTestEncodingConfig()
storagemoduletypes.RegisterInterfaces(encCfg.InterfaceRegistry)
banktypes.RegisterInterfaces(encCfg.InterfaceRegistry)
authtypes.RegisterInterfaces(encCfg.InterfaceRegistry)

// Create MsgServiceRouter, but don't populate it before creating the storage keeper.
msr := baseapp.NewMsgServiceRouter()

// gomock initializations
ctrl := gomock.NewController(t)
bankKeeper := storagetestutil.NewMockBankKeeper(ctrl)
accountKeeper := storagetestutil.NewMockAccountKeeper(ctrl)
oracleKeeper := storagetestutil.NewMockOracleKeeper(ctrl)
trackMockBalances(bankKeeper)
accountKeeper.EXPECT().GetModuleAddress(storagemoduletypes.ModuleName).Return(modAccount).AnyTimes()

oracleKeeper.EXPECT().GetFeed(gomock.Any(), gomock.Any()).Return(oracletypes.Feed{
Data: `{"price":"0.24","24h_change":"0"}`,
Name: "jklprice",
Owner: "cosmos1arsaayyj5tash86mwqudmcs2fd5jt5zgp07gl8",
}, true).AnyTimes()

paramsSubspace := typesparams.NewSubspace(encCfg.Codec,
storagemoduletypes.Amino,
key,
tkey,
"StorageParams",
)

// storage keeper initializations
storageKeeper := storagekeeper.NewKeeper(encCfg.Codec, key, paramsSubspace, bankKeeper, accountKeeper, oracleKeeper)
storageKeeper.SetParams(ctx, storagemoduletypes.DefaultParams())

// Register all handlers for the MegServiceRouter.
msr.SetInterfaceRegistry(encCfg.InterfaceRegistry)
storagemoduletypes.RegisterMsgServer(msr, storagekeeper.NewMsgServerImpl(*storageKeeper))
banktypes.RegisterMsgServer(msr, nil) // Nil is fine here as long as we never execute the proposal's Msgs.

return storageKeeper, bankKeeper, accountKeeper, encCfg, ctx
}

type UpgradeTestKeeper struct {
suite.Suite

cdc codec.Codec
ctx sdk.Context
filetreeKeeper *keeper.Keeper
storageKeeper *storagekeeper.Keeper
queryClient types.QueryClient
msgSrvr types.MsgServer
}
Expand All @@ -71,26 +138,65 @@ func (suite *UpgradeTestKeeper) SetupSuite() {
}

func (suite *UpgradeTestKeeper) reset() {
filetreeKeeper, encCfg, ctx := SetupFileTreeKeeper(suite.T())
filetreeKeeper, _, _ := SetupFileTreeKeeper(suite.T())
storageKeeper, _, _, encCfg, ctx := SetupStorageKeeper(suite.T())

queryHelper := baseapp.NewQueryServerTestHelper(ctx, encCfg.InterfaceRegistry)
types.RegisterQueryServer(queryHelper, filetreeKeeper)
queryClient := types.NewQueryClient(queryHelper)

suite.ctx = ctx
suite.filetreeKeeper = filetreeKeeper
suite.storageKeeper = storageKeeper
suite.cdc = encCfg.Codec
suite.queryClient = queryClient
suite.msgSrvr = keeper.NewMsgServerImpl(*suite.filetreeKeeper)
}

func setupMsgServer(suite *UpgradeTestKeeper) (types.MsgServer, gocontext.Context) {
func setupMsgServer(suite *UpgradeTestKeeper) {
k := suite.filetreeKeeper
filetree.InitGenesis(suite.ctx, *k, *types.DefaultGenesis())
ctx := sdk.WrapSDKContext(suite.ctx)
return keeper.NewMsgServerImpl(*k), ctx
}

func TestFiletreeTestSuite(t *testing.T) {
suite.Run(t, new(UpgradeTestKeeper))
}

// trackMockBalances sets up expected calls on the Mock BankKeeper, and also
// locally tracks accounts balances (not modules balances).
func trackMockBalances(bankKeeper *storagetestutil.MockBankKeeper) {
balances := make(map[string]sdk.Coins)

// We don't track module account balances.
bankKeeper.EXPECT().MintCoins(gomock.Any(), minttypes.ModuleName, gomock.Any()).AnyTimes()
bankKeeper.EXPECT().BurnCoins(gomock.Any(), types.ModuleName, gomock.Any()).DoAndReturn(func(_ sdk.Context, moduleName string, coins sdk.Coins) error {
newBalance, negative := balances[modAccount.String()].SafeSub(coins)
if negative {
return fmt.Errorf("not enough balance")
}
balances[modAccount.String()] = newBalance
return nil
}).AnyTimes()
bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), minttypes.ModuleName, types.ModuleName, gomock.Any()).AnyTimes()

// But we do track normal account balances.
bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(_ sdk.Context, sender sdk.AccAddress, _ string, coins sdk.Coins) error {
newBalance, negative := balances[sender.String()].SafeSub(coins) // in v0.46, this method is variadic
if negative {
return fmt.Errorf("not enough balance")
}
balances[sender.String()] = newBalance
return nil
}).AnyTimes()
bankKeeper.EXPECT().SendCoinsFromModuleToAccount(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(_ sdk.Context, module string, rcpt sdk.AccAddress, coins sdk.Coins) error {
balances[rcpt.String()] = balances[rcpt.String()].Add(coins...)
return nil
}).AnyTimes()
bankKeeper.EXPECT().GetAllBalances(gomock.Any(), gomock.Any()).DoAndReturn(func(_ sdk.Context, addr sdk.AccAddress) sdk.Coins {
return balances[addr.String()]
}).AnyTimes()
bankKeeper.EXPECT().GetBalance(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(_ sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin {
amt := balances[addr.String()].AmountOf(denom)
return sdk.NewCoin(denom, amt)
}).AnyTimes()
}
31 changes: 30 additions & 1 deletion app/upgrades/v4/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"encoding/json"
"fmt"

types2 "github.com/jackalLabs/canine-chain/v3/x/storage/types"

v4 "github.com/jackalLabs/canine-chain/v3/app/upgrades/v4"
"github.com/jackalLabs/canine-chain/v3/x/filetree/types"
)
Expand Down Expand Up @@ -35,7 +37,7 @@ func (suite *UpgradeTestKeeper) TestUpgrade() {
suite.filetreeKeeper.SetFiles(suite.ctx, f)
}

v4.UpdateFileTree(suite.ctx, *suite.filetreeKeeper, fidMerkleMap)
v4.UpdateFileTree(suite.ctx, suite.filetreeKeeper, fidMerkleMap)

allFiles := suite.filetreeKeeper.GetAllFiles(suite.ctx)

Expand All @@ -48,3 +50,30 @@ func (suite *UpgradeTestKeeper) TestUpgrade() {
suite.Require().Equal([]byte(file.Address), mct.Merkles[0])
}
}

func (suite *UpgradeTestKeeper) TestStorageUpgrade() {
suite.SetupSuite()
setupMsgServer(suite)

ad := types2.LegacyActiveDeals{
Cid: "cid",
Signee: "signee",
Provider: "provider",
Startblock: "0",
Endblock: "0",
Filesize: "1024",
Proofverified: "false",
Proofsmissed: "0",
Blocktoprove: "0",
Creator: "creator",
Merkle: "941cb8791cb5441674b06de1a931cd101da54457c41e87e9a8ce56e1d39c96bc",
Fid: "fid",
}
suite.storageKeeper.SetLegacyActiveDeals(suite.ctx, ad)

v4.UpdateFiles(suite.ctx, suite.storageKeeper)

f := suite.storageKeeper.GetAllFileByMerkle(suite.ctx)

suite.Require().Equal(1, len(f))
}
61 changes: 31 additions & 30 deletions app/upgrades/v4/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ var _ upgrades.Upgrade = &Upgrade{}
type Upgrade struct {
mm *module.Manager
configurator module.Configurator
sk storagekeeper.Keeper
fk filetreemodulekeeper.Keeper
sk *storagekeeper.Keeper
fk *filetreemodulekeeper.Keeper
}

// NewUpgrade returns a new Upgrade instance
func NewUpgrade(mm *module.Manager, configurator module.Configurator, sk storagekeeper.Keeper, fk filetreemodulekeeper.Keeper) *Upgrade {
func NewUpgrade(mm *module.Manager, configurator module.Configurator, sk *storagekeeper.Keeper, fk *filetreemodulekeeper.Keeper) *Upgrade {
return &Upgrade{
mm: mm,
configurator: configurator,
Expand All @@ -55,7 +55,7 @@ type MerkleContents struct {
Merkles [][]byte `json:"merkles"`
}

func UpdateFileTree(ctx sdk.Context, fk filetreemodulekeeper.Keeper, merkleMap map[string][]byte) {
func UpdateFileTree(ctx sdk.Context, fk *filetreemodulekeeper.Keeper, merkleMap map[string][]byte) {
allFiles := fk.GetAllFiles(ctx)

for _, file := range allFiles {
Expand Down Expand Up @@ -93,7 +93,7 @@ func UpdateFileTree(ctx sdk.Context, fk filetreemodulekeeper.Keeper, merkleMap m
}
}

func UpdatePaymentInfo(ctx sdk.Context, sk storagekeeper.Keeper) {
func UpdatePaymentInfo(ctx sdk.Context, sk *storagekeeper.Keeper) {
paymentInfo := sk.GetAllStoragePaymentInfo(ctx)
for _, info := range paymentInfo {

Expand All @@ -113,34 +113,36 @@ func UpdatePaymentInfo(ctx sdk.Context, sk storagekeeper.Keeper) {
}
}

func UpdateFiles(ctx sdk.Context, u *Upgrade) map[string][]byte {
func UpdateFiles(ctx sdk.Context, sk *storagekeeper.Keeper) map[string][]byte {
fidMerkle := make(map[string][]byte)

allDeals := u.sk.GetAllLegacyActiveDeals(ctx)
allDeals := sk.GetAllLegacyActiveDeals(ctx)

ctx.Logger().Info(fmt.Sprintf("There are %d active deals being migrated", len(allDeals)))

for _, deal := range allDeals {

merkle, err := hex.DecodeString(deal.Merkle)
if err != nil {
ctx.Logger().Error(err.Error())
ctx.Logger().Error(fmt.Sprintf("cannot parse merkle string: '%s' | %s", deal.Merkle, err.Error()))
continue
}

start, err := strconv.ParseInt(deal.Startblock, 10, 64)
if err != nil {
ctx.Logger().Error(err.Error())
ctx.Logger().Error(fmt.Sprintf("cannot parse start block | %s", err.Error()))
continue
}

end, err := strconv.ParseInt(deal.Endblock, 10, 64)
if err != nil {
ctx.Logger().Error(err.Error())
ctx.Logger().Error(fmt.Sprintf("cannot parse end block | %s", err.Error()))
continue
}

size, err := strconv.ParseInt(deal.Filesize, 10, 64)
if err != nil {
ctx.Logger().Error(err.Error())
ctx.Logger().Error(fmt.Sprintf("cannot parse file size | %s", err.Error()))
continue
}

Expand All @@ -153,30 +155,29 @@ func UpdateFiles(ctx sdk.Context, u *Upgrade) map[string][]byte {

lmBytes, err := json.Marshal(lm)
if err != nil {
ctx.Logger().Error(err.Error())
ctx.Logger().Error(fmt.Sprintf("cannot marshal legacy marker | %s", err.Error()))
continue
}

var uf storagemoduletypes.UnifiedFile
uf := storagemoduletypes.UnifiedFile{
Merkle: merkle,
Owner: deal.Signee,
Start: start,
Expires: end,
FileSize: size,
ProofInterval: 1800, // TODO: Decide on default window
ProofType: 0,
Proofs: make([]string, 0),
MaxProofs: 3,
Note: string(lmBytes),
}
sk.SetFile(ctx, uf)

uf, found := u.sk.GetFile(ctx, merkle, deal.Signee, start)
_, found := sk.GetFile(ctx, merkle, deal.Signee, start)
if !found {
uf = storagemoduletypes.UnifiedFile{
Merkle: merkle,
Owner: deal.Signee,
Start: start,
Expires: end,
FileSize: size,
ProofInterval: 1800, // TODO: Decide on default window
ProofType: 0,
Proofs: make([]string, 0),
MaxProofs: 3,
Note: string(lmBytes),
}
ctx.Logger().Error("Failed to migrate file")
}

u.sk.SetFile(ctx, uf)
uf.AddProver(ctx, u.sk, deal.Provider)
uf.AddProver(ctx, sk, deal.Provider)

}

Expand All @@ -190,7 +191,7 @@ func (u *Upgrade) Handler() upgradetypes.UpgradeHandler {

fromVM[storagemoduletypes.ModuleName] = 5

fidMerkleMap := UpdateFiles(ctx, u)
fidMerkleMap := UpdateFiles(ctx, u.sk)

UpdateFileTree(ctx, u.fk, fidMerkleMap)

Expand Down
Loading
Loading