Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
121 changes: 121 additions & 0 deletions app/apptesting/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package apptesting

import (
"encoding/json"
"fmt"
"path/filepath"
"testing"
"time"
Expand Down Expand Up @@ -308,3 +309,123 @@ func CreateRandomAccounts(numAccts int) []AddressWithKeys {

return testAddrsWithKeys
}

// Convert bech32 into sdk.Address and returns it. Panic otherwise.
func MustAcc(s string) sdk.AccAddress {
a, err := sdk.AccAddressFromBech32(s)
if err != nil {
panic(err)
}
return a
}

// Convert bech32 into sdk.ValAddress and return it. Panic otherwise.
func MustVal(s string) sdk.ValAddress {
v, err := sdk.ValAddressFromBech32(s)
if err != nil {
panic(err)
}
return v
}

// Ensure a validator exists, and return it. Panic otherwise.
func MustExistValidator(app *app.App, ctx sdk.Context, valAddr sdk.ValAddress) stakingtypes.Validator {
v, err := app.AppKeepers.StakingKeeper.GetValidator(ctx, valAddr)
if err != nil {
panic(err)
}
return v
}

// Create a minimal validator if it does not exist yet.
func MakeValidator(app *app.App, ctx sdk.Context, valAddr sdk.ValAddress) (stakingtypes.Validator, error) {
val, err := app.AppKeepers.StakingKeeper.GetValidator(ctx, valAddr)
if err == nil {
return val, fmt.Errorf("validator already exists: %s", valAddr.String())
}
// Create a dummy validator with small power
val = stakingtypes.Validator{
OperatorAddress: valAddr.String(),
Status: stakingtypes.Bonded,
Tokens: math.NewInt(1),
DelegatorShares: math.LegacyOneDec(),
Commission: stakingtypes.NewCommission(math.LegacyZeroDec(), math.LegacyZeroDec(), math.LegacyZeroDec()),
}
err = app.AppKeepers.StakingKeeper.SetValidator(ctx, val)
if err != nil {
return stakingtypes.Validator{}, err
}
err = app.AppKeepers.DistrKeeper.Hooks().AfterValidatorCreated(ctx, valAddr)
if err != nil {
return stakingtypes.Validator{}, err
}
return val, err
}

// Create a minimal validator if it does not exist yet. Panic otherwise.
func MustMakeValidator(app *app.App, ctx sdk.Context, valAddr sdk.ValAddress) stakingtypes.Validator {
val, err := MakeValidator(app, ctx, valAddr)
if err != nil {
panic(err)
}
return val
}

// Mint and send coin to target account. Panic on error.
func MustFundAccount(app *app.App, ctx sdk.Context, addr sdk.AccAddress, denom string, amount int64) {
amt := math.NewInt(amount)
err := app.AppKeepers.BankKeeper.MintCoins(ctx, minttypes.ModuleName, sdk.NewCoins(sdk.NewCoin(denom, amt)))
if err != nil {
panic(err)
}
err = app.AppKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, addr, sdk.NewCoins(sdk.NewCoin(denom, amt)))
if err != nil {
panic(err)
}
}

// Create a delegation. Panic otherwise.
func MustCreateDelegation(app *app.App, ctx sdk.Context, delegator sdk.AccAddress, valAddr sdk.ValAddress, amount int64) {
val := MustExistValidator(app, ctx, valAddr)
bondDenom, err := app.AppKeepers.StakingKeeper.BondDenom(ctx)
if err != nil {
panic(err)
}
balPreDel := app.AppKeepers.BankKeeper.GetBalance(ctx, delegator, bondDenom).Amount.Int64()
_, err = app.AppKeepers.StakingKeeper.Delegate(ctx, delegator, math.NewInt(amount), stakingtypes.Unbonded, val, true)
if err != nil {
panic(err)
}
balPostDel := app.AppKeepers.BankKeeper.GetBalance(ctx, delegator, bondDenom).Amount.Int64()
if balPostDel != (balPreDel - amount) {
panic(fmt.Errorf("delegator balance un-affected by delegation to validator: del:%s - val:%s", delegator.String(), valAddr.String()))
}
}

// Create an unbonding delegation.
func CreateUnbondingDelegation(app *app.App, ctx sdk.Context, delegator sdk.AccAddress, valAddr sdk.ValAddress, amount int64) (time.Time, math.Int, error) {
shares := math.LegacyNewDec(amount)
return app.AppKeepers.StakingKeeper.Undelegate(ctx, delegator, valAddr, shares)
}

// Create a redelegation.
func CreateRedelegation(app *app.App, ctx sdk.Context, delegator sdk.AccAddress, valAddrSrc sdk.ValAddress, valAddrDst sdk.ValAddress, amount int64) (completionTime time.Time, err error) {
shares := math.LegacyNewDecFromInt(math.NewInt(amount))
return app.AppKeepers.StakingKeeper.BeginRedelegation(ctx, delegator, valAddrSrc, valAddrDst, shares)
}

// Create an unbonding delegation. Panic otherwise.
func MustCreateUnbondingDelegation(app *app.App, ctx sdk.Context, delegator sdk.AccAddress, valAddr sdk.ValAddress, amount int64) {
_, _, err := CreateUnbondingDelegation(app, ctx, delegator, valAddr, amount)
if err != nil {
panic(err)
}
}

// Create a redelegation. Panic otherwise.
func MustCreateRedelegation(app *app.App, ctx sdk.Context, delegator sdk.AccAddress, valAddrSrc sdk.ValAddress, valAddrDst sdk.ValAddress, amount int64) {
_, err := CreateRedelegation(app, ctx, delegator, valAddrSrc, valAddrDst, amount)
if err != nil {
panic(err)
}
}
113 changes: 113 additions & 0 deletions app/upgrades/v5.1/accounts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package v5_1

import (
"time"

"cosmossdk.io/math"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/firmachain/firmachain/app/keepers"
)

// Completes all re-delegations and returns the amount of tokens which were re-delegated.
func CompleteAllRedelegations(ctx sdk.Context, now time.Time, keepers *keepers.AppKeepers, accAddr sdk.AccAddress) (math.Int, error) {
redelegatedAmt := math.ZeroInt()

redelegations, err := keepers.StakingKeeper.GetRedelegations(ctx, accAddr, 65535)
if err != nil {
return math.ZeroInt(), err
}
for _, activeRedelegation := range redelegations {
redelegationSrc, _ := sdk.ValAddressFromBech32(activeRedelegation.ValidatorSrcAddress)
redelegationDst, _ := sdk.ValAddressFromBech32(activeRedelegation.ValidatorDstAddress)

// set all entry completionTime to now so we can complete re-delegation
for i := range activeRedelegation.Entries {
activeRedelegation.Entries[i].CompletionTime = now
}

keepers.StakingKeeper.SetRedelegation(ctx, activeRedelegation)
redelegatedCoins, err := keepers.StakingKeeper.CompleteRedelegation(ctx, accAddr, redelegationSrc, redelegationDst)
if err != nil {
return math.ZeroInt(), err
}
for i := range redelegatedCoins {
redelegatedAmt = redelegatedAmt.Add(redelegatedCoins[i].Amount)
}

}

return redelegatedAmt, nil
}

// Returns the amount of tokens which were unbonded (not rewards)
func UnbondAllAndFinish(ctx sdk.Context, now time.Time, keepers *keepers.AppKeepers, accAddr sdk.AccAddress) (math.Int, error) {
unbondedAmt := math.ZeroInt()

// First clear current unbonding delegations, in order to ensure to have space for the new ones.
unbondedAmt0, err := CompleteAllUnbondingDelegations(ctx, now, keepers, accAddr)
if err != nil {
return math.ZeroInt(), err
}
unbondedAmt = unbondedAmt.Add(unbondedAmt0)

// Unbond all delegations from the account
delegations, err := keepers.StakingKeeper.GetAllDelegatorDelegations(ctx, accAddr)
if err != nil {
return math.ZeroInt(), err
}
for _, delegation := range delegations {

validatorValAddr, err := sdk.ValAddressFromBech32(delegation.GetValidatorAddr())
if err != nil {
return math.ZeroInt(), err
}

if _, err := keepers.StakingKeeper.GetValidator(ctx, validatorValAddr); err != nil {
return math.ZeroInt(), err
}

_, _, err = keepers.StakingKeeper.Undelegate(ctx, accAddr, validatorValAddr, delegation.GetShares())
if err != nil {
return math.ZeroInt(), err
}
}

// Take all unbonding and complete them.
unbondedAmt1, err := CompleteAllUnbondingDelegations(ctx, now, keepers, accAddr)
if err != nil {
return math.ZeroInt(), err
}
unbondedAmt = unbondedAmt.Add(unbondedAmt1)

return unbondedAmt, nil
}

// Completes all unbonding delegations and returns the (final) amount of tokens which are returned from the unbond.
func CompleteAllUnbondingDelegations(ctx sdk.Context, now time.Time, keepers *keepers.AppKeepers, accAddr sdk.AccAddress) (math.Int, error) {
unbondedAmt := math.ZeroInt()

// Take all unbonding and complete them.
unbondingDelegations, err := keepers.StakingKeeper.GetAllUnbondingDelegations(ctx, accAddr)
if err != nil {
return math.ZeroInt(), err
}
for _, unbondingDelegation := range unbondingDelegations {
validatorStringAddr := unbondingDelegation.ValidatorAddress
validatorValAddr, _ := sdk.ValAddressFromBech32(validatorStringAddr)

// Complete unbonding delegation
for i := range unbondingDelegation.Entries {
unbondingDelegation.Entries[i].CompletionTime = now
unbondedAmt = unbondedAmt.Add(unbondingDelegation.Entries[i].Balance)
}

keepers.StakingKeeper.SetUnbondingDelegation(ctx, unbondingDelegation)
_, err := keepers.StakingKeeper.CompleteUnbonding(ctx, accAddr, validatorValAddr)
if err != nil {
return math.ZeroInt(), err
}
}

return unbondedAmt, nil
}
Loading