Skip to content

Commit

Permalink
cleaned up UBD unit test and incremented consensus version
Browse files Browse the repository at this point in the history
  • Loading branch information
sampocs committed Aug 8, 2023
1 parent 0063de6 commit 3d19da9
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 78 deletions.
2 changes: 1 addition & 1 deletion x/staking/keeper/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ func (m Migrator) Migrate1to2(ctx sdk.Context) error {

// Migrate2to3 migrates from version 2 to 3.
func (m Migrator) Migrate2to3(ctx sdk.Context) error {
return v3.MigrateStore(ctx, m.keeper, m.keeper.paramstore)
return v3.MigrateStore(ctx, m.keeper.storeKey, m.keeper.cdc, m.keeper, m.keeper.paramstore)
}
127 changes: 51 additions & 76 deletions x/staking/migrations/v3/migrations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ import (
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
"github.com/cosmos/cosmos-sdk/x/staking"

// "github.com/cosmos/cosmos-sdk/x/staking"
v3 "github.com/cosmos/cosmos-sdk/x/staking/migrations/v3"
legacytypes "github.com/cosmos/cosmos-sdk/x/staking/migrations/v3/types"
"github.com/cosmos/cosmos-sdk/x/staking/types"
Expand All @@ -36,6 +34,47 @@ func setLegacyDelegation(store sdk.KVStore, cdc codec.BinaryCodec, delegation le
store.Set(types.GetDelegationKey(delegatorAddress, delegation.GetValidatorAddr()), bz)
}

// Helper function to get unbonding delegation records
func getUBD(store storetypes.KVStore, cdc codec.BinaryCodec, accAddr sdk.AccAddress, valAddr sdk.ValAddress) (ubdRes types.UnbondingDelegation) {
ubdbz := store.Get(types.GetUBDKey(accAddr, valAddr))
cdc.MustUnmarshal(ubdbz, &ubdRes)
return ubdRes
}

// createOldStateUnbonding will create the ubd entries with duplicate heights
// 10 duplicate heights and 10 unique ubd with creation height
func createOldUnbondingDelegationRecords(t *testing.T, creationHeight int64, valAddr sdk.ValAddress, accAddr sdk.AccAddress, cdc codec.BinaryCodec, store storetypes.KVStore) error {
unbondBalance := sdk.NewInt(100)
completionTime := time.Now()
ubdEntries := make([]types.UnbondingDelegationEntry, 0, 10)

for i := int64(0); i < 10; i++ {
ubdEntry := types.UnbondingDelegationEntry{
CreationHeight: creationHeight,
Balance: unbondBalance,
InitialBalance: unbondBalance,
CompletionTime: completionTime,
}
ubdEntries = append(ubdEntries, ubdEntry)
// creating more entries for testing the creation_heights
ubdEntry.CreationHeight = i + 2
ubdEntry.CompletionTime = completionTime.Add(time.Minute * 10)
ubdEntries = append(ubdEntries, ubdEntry)
}

ubd := types.UnbondingDelegation{
ValidatorAddress: valAddr.String(),
DelegatorAddress: accAddr.String(),
Entries: ubdEntries,
}

// set the unbond delegation with validator and delegator
bz := types.MustMarshalUBD(cdc, ubd)
key := types.GetUBDKey(accAddr, valAddr)
store.Set(key, bz)
return nil
}

// Test setting params in the staking module
func TestMigrateParamsStore(t *testing.T) {
cdc := simapp.MakeTestEncodingConfig()
Expand Down Expand Up @@ -150,7 +189,7 @@ func TestMigrateValidators(t *testing.T) {
require.Equal(t, oldValidator.UnbondingTime, newValidator.UnbondingTime, "unbonding time")
require.Equal(t, oldValidator.UnbondingOnHoldRefCount, newValidator.UnbondingOnHoldRefCount, "unbonding on hold")
require.Equal(t, oldValidator.UnbondingIds, newValidator.UnbondingIds, "unbonding ids")
require.Equal(t, oldValidator.MinSelfDelegation.String(), newValidator.MinSelfDelegation, "min self delegation")
require.Equal(t, oldValidator.MinSelfDelegation.String(), newValidator.MinSelfDelegation.String(), "min self delegation")

oldDescription := oldValidator.Description
newDescription := newValidator.Description
Expand Down Expand Up @@ -210,39 +249,26 @@ func TestMigrateDelegations(t *testing.T) {
}
}

type mockSubspace struct {
ps types.Params
}

func newMockSubspace(ps types.Params) mockSubspace {
return mockSubspace{ps: ps}
}

func (ms mockSubspace) GetParamSet(ctx sdk.Context, ps paramtypes.ParamSet) {
*ps.(*types.Params) = ms.ps
}

func TestMigrate(t *testing.T) {
cdc := moduletestutil.MakeTestEncodingConfig(staking.AppModuleBasic{}).Codec
// Tests unbonding delegation records with the same height are removed and combined into a new record
func TestMigrateUBD(t *testing.T) {
cdc := simapp.MakeTestEncodingConfig().Marshaler

storeKey := sdk.NewKVStoreKey(v4.ModuleName)
storeKey := sdk.NewKVStoreKey(legacytypes.ModuleName)
tKey := sdk.NewTransientStoreKey("transient_test")
ctx := testutil.DefaultContext(storeKey, tKey)
store := ctx.KVStore(storeKey)
duplicateCreationHeight := int64(1)

accAddrs := sims.CreateIncrementalAccounts(1)
accAddrs := v3.CreateIncrementalAccounts(1)
accAddr := accAddrs[0]

valAddrs := sims.ConvertAddrsToValAddrs(accAddrs)
valAddrs := v3.ConvertAddrsToValAddrs(accAddrs)
valAddr := valAddrs[0]

// creating 10 ubdEntries with same height and 10 ubdEntries with different creation height
err := createOldStateUnbonding(t, duplicateCreationHeight, valAddr, accAddr, cdc, store)
err := createOldUnbondingDelegationRecords(t, duplicateCreationHeight, valAddr, accAddr, cdc, store)
require.NoError(t, err)

legacySubspace := newMockSubspace(types.DefaultParams())

testCases := []struct {
name string
doMigration bool
Expand All @@ -260,16 +286,11 @@ func TestMigrate(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
if tc.doMigration {
require.NoError(t, v4.MigrateStore(ctx, storeKey, cdc, legacySubspace))
require.NoError(t, v3.MigrateUBDEntries(ctx, store, cdc))
}

ubd := getUBD(t, accAddr, valAddr, store, cdc)
ubd := getUBD(store, cdc, accAddr, valAddr)
if tc.doMigration {
var res types.Params
bz := store.Get(v4.ParamsKey)
require.NoError(t, cdc.Unmarshal(bz, &res))
require.Equal(t, legacySubspace.ps, res)

// checking the updated balance for duplicateCreationHeight
for _, ubdEntry := range ubd.Entries {
if ubdEntry.CreationHeight == duplicateCreationHeight {
Expand All @@ -285,49 +306,3 @@ func TestMigrate(t *testing.T) {
})
}
}

// createOldStateUnbonding will create the ubd entries with duplicate heights
// 10 duplicate heights and 10 unique ubd with creation height
func createOldStateUnbonding(t *testing.T, creationHeight int64, valAddr sdk.ValAddress, accAddr sdk.AccAddress, cdc codec.BinaryCodec, store storetypes.KVStore) error {
unbondBalance := sdk.NewInt(100)
completionTime := time.Now()
ubdEntries := make([]types.UnbondingDelegationEntry, 0, 10)

for i := int64(0); i < 10; i++ {
ubdEntry := types.UnbondingDelegationEntry{
CreationHeight: creationHeight,
Balance: unbondBalance,
InitialBalance: unbondBalance,
CompletionTime: completionTime,
}
ubdEntries = append(ubdEntries, ubdEntry)
// creating more entries for testing the creation_heights
ubdEntry.CreationHeight = i + 2
ubdEntry.CompletionTime = completionTime.Add(time.Minute * 10)
ubdEntries = append(ubdEntries, ubdEntry)
}

ubd := types.UnbondingDelegation{
ValidatorAddress: valAddr.String(),
DelegatorAddress: accAddr.String(),
Entries: ubdEntries,
}

// set the unbond delegation with validator and delegator
bz := types.MustMarshalUBD(cdc, ubd)
key := getUBDKey(accAddr, valAddr)
store.Set(key, bz)
return nil
}

func getUBD(t *testing.T, accAddr sdk.AccAddress, valAddr sdk.ValAddress, store storetypes.KVStore, cdc codec.BinaryCodec) types.UnbondingDelegation {
// get the unbonding delegations
var ubdRes types.UnbondingDelegation
ubdbz := store.Get(getUBDKey(accAddr, valAddr))
require.NoError(t, cdc.Unmarshal(ubdbz, &ubdRes))
return ubdRes
}

func getUBDKey(accAddr sdk.AccAddress, valAddr sdk.ValAddress) []byte {
return types.GetUBDKey(accAddr, valAddr)
}
83 changes: 83 additions & 0 deletions x/staking/migrations/v3/test_helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// This file contains utility testing functions from SDK 47 that are required for the UBD migration unit test
package v3

import (
"bytes"
"encoding/hex"
"fmt"
"strconv"

sdk "github.com/cosmos/cosmos-sdk/types"
)

// CreateIncrementalAccounts is a strategy used by addTestAddrs() in order to generated addresses in ascending order.
func CreateIncrementalAccounts(accNum int) []sdk.AccAddress {
var addresses []sdk.AccAddress
var buffer bytes.Buffer

// start at 100 so we can make up to 999 test addresses with valid test addresses
for i := 100; i < (accNum + 100); i++ {
numString := strconv.Itoa(i)
buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA6") // base address string

buffer.WriteString(numString) // adding on final two digits to make addresses unique
res, _ := AccAddressFromHexUnsafe(buffer.String())
bech := res.String()
addr, _ := CheckHexConversion(buffer.String(), bech)

addresses = append(addresses, addr)
buffer.Reset()
}

return addresses
}

func CheckHexConversion(addr string, bech string) (sdk.AccAddress, error) {
res, err := AccAddressFromHexUnsafe(addr)
if err != nil {
return nil, err
}
bechexpected := res.String()
if bech != bechexpected {
return nil, fmt.Errorf("bech encoding doesn't match reference")
}

bechres, err := sdk.AccAddressFromBech32(bech)
if err != nil {
return nil, err
}
if !bytes.Equal(bechres, res) {
return nil, err
}

return res, nil
}

// ConvertAddrsToValAddrs converts the provided addresses to ValAddress.
func ConvertAddrsToValAddrs(addrs []sdk.AccAddress) []sdk.ValAddress {
valAddrs := make([]sdk.ValAddress, len(addrs))

for i, addr := range addrs {
valAddrs[i] = sdk.ValAddress(addr)
}

return valAddrs
}

// AccAddressFromHexUnsafe creates an AccAddress from a HEX-encoded string.
//
// Note, this function is considered unsafe as it may produce an AccAddress from
// otherwise invalid input, such as a transaction hash. Please use
// AccAddressFromBech32.
func AccAddressFromHexUnsafe(address string) (addr sdk.AccAddress, err error) {
bz, err := addressBytesFromHexString(address)
return sdk.AccAddress(bz), err
}

func addressBytesFromHexString(address string) ([]byte, error) {
if len(address) == 0 {
return nil, fmt.Errorf("empty hex address")
}

return hex.DecodeString(address)
}
2 changes: 1 addition & 1 deletion x/staking/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw
}

// ConsensusVersion implements AppModule/ConsensusVersion.
func (AppModule) ConsensusVersion() uint64 { return 2 }
func (AppModule) ConsensusVersion() uint64 { return 3 }

// BeginBlock returns the begin blocker for the staking module.
func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) {
Expand Down

0 comments on commit 3d19da9

Please sign in to comment.