Skip to content

Commit

Permalink
Merge pull request #1000 from lavanet/CNS-fixmigrator
Browse files Browse the repository at this point in the history
CNS-Fix-Migrator
  • Loading branch information
Yaroms authored Nov 27, 2023
2 parents e7d5b22 + d5aeee8 commit 72c6440
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 30 deletions.
2 changes: 1 addition & 1 deletion x/dualstaking/keeper/delegate.go
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ func (k Keeper) VerifyDelegatorBalance(ctx sdk.Context, delAddr sdk.AccAddress)
for _, d := range delegations {
v, found := k.stakingKeeper.GetValidator(ctx, d.GetValidatorAddr())
if found {
sumValidatorDelegations = sumValidatorDelegations.Add(v.TokensFromShares(d.Shares).TruncateInt())
sumValidatorDelegations = sumValidatorDelegations.Add(v.TokensFromSharesRoundUp(d.Shares).TruncateInt())
}
}

Expand Down
2 changes: 1 addition & 1 deletion x/dualstaking/keeper/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ func (h Hooks) BeforeDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress,
if err != nil {
return nil
}
amount := validator.TokensFromShares(delegation.Shares).TruncateInt()
amount := validator.TokensFromSharesRoundUp(delegation.Shares).TruncateInt()
err = h.k.UnbondUniformProviders(ctx, delAddr.String(), sdk.NewCoin(epochstoragetypes.TokenDenom, amount))
if err != nil {
return utils.LavaFormatError("delegation removed hook failed", err,
Expand Down
80 changes: 59 additions & 21 deletions x/dualstaking/keeper/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,12 @@ func (m Migrator) ConvertProviderStakeToSelfDelegation(ctx sdk.Context) error {
if err != nil {
return err
}
moduleBalance := m.keeper.bankKeeper.GetBalance(ctx, m.keeper.accountKeeper.GetModuleAddress(types.ModuleName), epochstoragetypes.TokenDenom)
if moduleBalance.IsLT(entry.Stake) {
utils.LavaFormatError("insufficient balance to unstake", nil,
utils.Attribute{Key: "Unstake", Value: entry.Stake},
utils.Attribute{Key: "ModuleBalance", Value: moduleBalance},
)

err = m.keeper.bankKeeper.MintCoins(ctx, types.ModuleName, []sdk.Coin{entry.Stake})
if err != nil {
return err
}

err = m.keeper.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, addr, []sdk.Coin{entry.Stake})
if err != nil {
utils.LavaFormatError("failed to send coins from module to account", err,
Expand All @@ -63,6 +62,14 @@ func (m Migrator) ConvertProviderStakeToSelfDelegation(ctx sdk.Context) error {
}
}

moduleBalance := m.keeper.bankKeeper.GetBalance(ctx, m.keeper.accountKeeper.GetModuleAddress(types.ModuleName), epochstoragetypes.TokenDenom)
if !moduleBalance.IsZero() {
err := m.keeper.bankKeeper.BurnCoins(ctx, types.ModuleName, sdk.NewCoins(moduleBalance))
if err != nil {
return err
}
}

return nil
}

Expand All @@ -74,11 +81,18 @@ func (m Migrator) HandleProviderDelegators(ctx sdk.Context) error {
delegationsInds := m.keeper.delegationFS.GetAllEntryIndices(ctx)
nextEpoch := m.keeper.epochstorageKeeper.GetCurrentNextEpoch(ctx)

// move all funds from unbonded pool to bonded pool
notBondedPoolAddr := m.keeper.accountKeeper.GetModuleAddress(dualstakingtypes.NotBondedPoolName)
notBondedPoolAmount := m.keeper.bankKeeper.GetBalance(ctx, notBondedPoolAddr, epochstoragetypes.TokenDenom)
if !notBondedPoolAmount.IsZero() {
err := m.keeper.bankKeeper.SendCoinsFromModuleToModule(ctx, dualstakingtypes.NotBondedPoolName, dualstakingtypes.BondedPoolName, sdk.Coins{notBondedPoolAmount})
// burn all coins from the pools
moduleBalance := m.keeper.bankKeeper.GetBalance(ctx, m.keeper.accountKeeper.GetModuleAddress(dualstakingtypes.BondedPoolName), epochstoragetypes.TokenDenom)
if !moduleBalance.IsZero() {
err := m.keeper.bankKeeper.BurnCoins(ctx, dualstakingtypes.BondedPoolName, sdk.NewCoins(moduleBalance))
if err != nil {
return err
}
}

if !moduleBalance.IsZero() {
moduleBalance = m.keeper.bankKeeper.GetBalance(ctx, m.keeper.accountKeeper.GetModuleAddress(dualstakingtypes.NotBondedPoolName), epochstoragetypes.TokenDenom)
err := m.keeper.bankKeeper.BurnCoins(ctx, dualstakingtypes.NotBondedPoolName, sdk.NewCoins(moduleBalance))
if err != nil {
return err
}
Expand All @@ -94,10 +108,15 @@ func (m Migrator) HandleProviderDelegators(ctx sdk.Context) error {
continue
}

if d.Delegator == d.Provider {
if d.Delegator == d.Provider || d.Provider == EMPTY_PROVIDER {
continue
}
originalDelegations = append(originalDelegations, d)

providerAddr, err := sdk.AccAddressFromBech32(d.Provider)
if err != nil {
return err
}

originalAmount := d.Amount

// zero the delegation amount in the fixation store
Expand All @@ -109,10 +128,25 @@ func (m Migrator) HandleProviderDelegators(ctx sdk.Context) error {
if err != nil {
return err
}
err = m.keeper.bankKeeper.SendCoinsFromModuleToAccount(ctx, dualstakingtypes.BondedPoolName, delegatorAddr, sdk.Coins{originalAmount})

err = m.keeper.bankKeeper.MintCoins(ctx, types.ModuleName, []sdk.Coin{originalAmount})
if err != nil {
return err
}

err = m.keeper.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, delegatorAddr, sdk.Coins{originalAmount})
if err != nil {
return err
}

entry, found, index := m.keeper.epochstorageKeeper.GetStakeEntryByAddressCurrent(ctx, d.ChainID, providerAddr)
if !found {
continue
}
entry.DelegateTotal = entry.DelegateTotal.Sub(originalAmount)
m.keeper.epochstorageKeeper.ModifyStakeEntryCurrent(ctx, d.ChainID, entry, index)

originalDelegations = append(originalDelegations, d)
}

// get highest staked validator and delegate to it
Expand Down Expand Up @@ -202,23 +236,27 @@ func (m Migrator) VerifyDelegationsBalance(ctx sdk.Context) error {
return nil
}

// MigrateVersion1To2 implements store migration: Create a self delegation for all providers
// MigrateVersion1To2 implements store migration: Create a self delegation for all providers, Make providers-validators delegations balance
func (m Migrator) MigrateVersion1To2(ctx sdk.Context) error {
return m.ConvertProviderStakeToSelfDelegation(ctx)
}
// first balance all validators
err := m.HandleValidatorsDelegators(ctx)
if err != nil {
return err
}

// MigrateVersion2To3 implements store migration: Make providers-validators delegations balance
func (m Migrator) MigrateVersion2To3(ctx sdk.Context) error {
err := m.HandleProviderDelegators(ctx)
// create providers self delegations
err = m.ConvertProviderStakeToSelfDelegation(ctx)
if err != nil {
return err
}

err = m.HandleValidatorsDelegators(ctx)
// convert the rest of the delegations
err = m.HandleProviderDelegators(ctx)
if err != nil {
return err
}

// verify the balance once again to make sure
err = m.VerifyDelegationsBalance(ctx)
if err != nil {
return err
Expand Down
8 changes: 1 addition & 7 deletions x/dualstaking/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,6 @@ func (am AppModule) RegisterServices(cfg module.Configurator) {
// panic:ok: at start up, migration cannot proceed anyhow
panic(fmt.Errorf("%s: failed to register migration to v2: %w", types.ModuleName, err))
}

// register v2 -> v3 migration
if err := cfg.RegisterMigration(types.ModuleName, 2, migrator.MigrateVersion2To3); err != nil {
// panic:ok: at start up, migration cannot proceed anyhow
panic(fmt.Errorf("%s: failed to register migration to v3: %w", types.ModuleName, err))
}
}

// RegisterInvariants registers the invariants of the module. If an invariant deviates from its predicted value, the InvariantRegistry triggers appropriate logic (most often the chain will be halted)
Expand All @@ -152,7 +146,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw
}

// ConsensusVersion is a sequence number for state-breaking change of the module. It should be incremented on each consensus-breaking change introduced by the module. To avoid wrong/empty versions, the initial version should be set to 1
func (AppModule) ConsensusVersion() uint64 { return 3 }
func (AppModule) ConsensusVersion() uint64 { return 2 }

// BeginBlock contains the logic that is automatically triggered at the beginning of each block
func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {}
Expand Down
1 change: 1 addition & 0 deletions x/dualstaking/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type AccountKeeper interface {
type BankKeeper interface {
BurnCoins(ctx sdk.Context, name string, amt sdk.Coins) error
GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin
MintCoins(ctx sdk.Context, moduleName string, amounts sdk.Coins) error
SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error
SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error
SendCoinsFromModuleToModule(ctx sdk.Context, senderPool, recipientPool string, amt sdk.Coins) error
Expand Down

0 comments on commit 72c6440

Please sign in to comment.