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

feat: decouple x/nft from simapp #12233

Merged
merged 15 commits into from
Jun 14, 2022
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Features

* (x/nft) [#12038](https://github.com/cosmos/cosmos-sdk/issues/12038) Migrate `x/nft` to App Wiring.
julienrbrt marked this conversation as resolved.
Show resolved Hide resolved
* (cli) [#12028](https://github.com/cosmos/cosmos-sdk/pull/12028) Add the `tendermint key-migrate` to perform Tendermint v0.35 DB key migration.

### Improvements
Expand All @@ -48,6 +49,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

### API Breaking Changes

* (testutil) [#12233](https://github.com/cosmos/cosmos-sdk/pull/12233) Move `simapp.TestAddr` to `simtestutil.TestAddr` (`testutil/sims`)
* (x/staking) [#12102](https://github.com/cosmos/cosmos-sdk/pull/12102) Staking keeper now is passed by reference instead of copy. Keeper's SetHooks no longer returns keeper. It updates the keeper in place instead.
* (linting) [#12141](https://github.com/cosmos/cosmos-sdk/pull/12141) Fix usability related linting for database. This means removing the infix Prefix from `prefix.NewPrefixWriter` and such so that it is `prefix.NewWriter` and making `db.DBConnection` and such into `db.Connection`

Expand Down
140 changes: 9 additions & 131 deletions simapp/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ import (
"context"
"encoding/hex"
"encoding/json"
"fmt"
"strconv"
"testing"
"time"

"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
Expand All @@ -21,8 +19,6 @@ import (
"cosmossdk.io/math"
bam "github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
Expand All @@ -38,7 +34,6 @@ import (
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)

// SetupOptions defines arguments that are passed into `Simapp` constructor.
Expand Down Expand Up @@ -83,7 +78,8 @@ func NewSimappWithCustomOptions(t *testing.T, isCheckTx bool, options SetupOptio

app := NewSimApp(options.Logger, options.DB, nil, true, options.SkipUpgradeHeights, options.HomePath, options.InvCheckPeriod, options.EncConfig, options.AppOpts)
genesisState := NewDefaultGenesisState(app.appCodec)
genesisState = genesisStateWithValSet(t, app, genesisState, valSet, []authtypes.GenesisAccount{acc}, balance)
genesisState, err = simtestutil.GenesisStateWithValSet(app.AppCodec(), genesisState, valSet, []authtypes.GenesisAccount{acc}, balance)
require.NoError(t, err)

if !isCheckTx {
// init chain must be called to stop deliverState from being nil
Expand Down Expand Up @@ -128,70 +124,6 @@ func Setup(t *testing.T, isCheckTx bool) *SimApp {
return app
}

func genesisStateWithValSet(t *testing.T,
app *SimApp, genesisState GenesisState,
valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount,
balances ...banktypes.Balance,
) GenesisState {
// set genesis accounts
authGenesis := authtypes.NewGenesisState(authtypes.DefaultParams(), genAccs)
genesisState[authtypes.ModuleName] = app.AppCodec().MustMarshalJSON(authGenesis)

validators := make([]stakingtypes.Validator, 0, len(valSet.Validators))
delegations := make([]stakingtypes.Delegation, 0, len(valSet.Validators))

bondAmt := sdk.DefaultPowerReduction

for _, val := range valSet.Validators {
pk, err := cryptocodec.FromTmPubKeyInterface(val.PubKey)
require.NoError(t, err)
pkAny, err := codectypes.NewAnyWithValue(pk)
require.NoError(t, err)
validator := stakingtypes.Validator{
OperatorAddress: sdk.ValAddress(val.Address).String(),
ConsensusPubkey: pkAny,
Jailed: false,
Status: stakingtypes.Bonded,
Tokens: bondAmt,
DelegatorShares: sdk.OneDec(),
Description: stakingtypes.Description{},
UnbondingHeight: int64(0),
UnbondingTime: time.Unix(0, 0).UTC(),
Commission: stakingtypes.NewCommission(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()),
MinSelfDelegation: sdk.ZeroInt(),
}
validators = append(validators, validator)
delegations = append(delegations, stakingtypes.NewDelegation(genAccs[0].GetAddress(), val.Address.Bytes(), sdk.OneDec()))

}
// set validators and delegations
stakingGenesis := stakingtypes.NewGenesisState(stakingtypes.DefaultParams(), validators, delegations)
genesisState[stakingtypes.ModuleName] = app.AppCodec().MustMarshalJSON(stakingGenesis)

totalSupply := sdk.NewCoins()
for _, b := range balances {
// add genesis acc tokens to total supply
totalSupply = totalSupply.Add(b.Coins...)
}

for range delegations {
// add delegated tokens to total supply
totalSupply = totalSupply.Add(sdk.NewCoin(sdk.DefaultBondDenom, bondAmt))
}

// add bonded amount to bonded pool module account
balances = append(balances, banktypes.Balance{
Address: authtypes.NewModuleAddress(stakingtypes.BondedPoolName).String(),
Coins: sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, bondAmt)},
})

// update total supply
bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, totalSupply, []banktypes.Metadata{}, []banktypes.SendEnabled{})
genesisState[banktypes.ModuleName] = app.AppCodec().MustMarshalJSON(bankGenesis)

return genesisState
}

// SetupWithGenesisValSet initializes a new SimApp with a validator set and genesis accounts
// that also act as delegators. For simplicity, each validator is bonded with a delegation
// of one consensus engine unit in the default token of the simapp from first genesis
Expand All @@ -200,7 +132,8 @@ func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs
t.Helper()

app, genesisState := setup(true, 5)
genesisState = genesisStateWithValSet(t, app, genesisState, valSet, genAccs, balances...)
genesisState, err := simtestutil.GenesisStateWithValSet(app.AppCodec(), genesisState, valSet, genAccs, balances...)
require.NoError(t, err)

stateBytes, err := json.MarshalIndent(genesisState, "", " ")
require.NoError(t, err)
Expand Down Expand Up @@ -266,46 +199,12 @@ func GenesisStateWithSingleValidator(t *testing.T, app *SimApp) GenesisState {
}

genesisState := NewDefaultGenesisState(app.appCodec)
genesisState = genesisStateWithValSet(t, app, genesisState, valSet, []authtypes.GenesisAccount{acc}, balances...)
genesisState, err = simtestutil.GenesisStateWithValSet(app.AppCodec(), genesisState, valSet, []authtypes.GenesisAccount{acc}, balances...)
require.NoError(t, err)

return genesisState
}

type GenerateAccountStrategy func(int) []sdk.AccAddress

// createRandomAccounts is a strategy used by addTestAddrs() in order to generated addresses in random order.
func createRandomAccounts(accNum int) []sdk.AccAddress {
testAddrs := make([]sdk.AccAddress, accNum)
for i := 0; i < accNum; i++ {
pk := ed25519.GenPrivKey().PubKey()
testAddrs[i] = sdk.AccAddress(pk.Address())
}

return testAddrs
}

// 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, _ := sdk.AccAddressFromHexUnsafe(buffer.String())
bech := res.String()
addr, _ := TestAddr(buffer.String(), bech)

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

return addresses
}

// AddTestAddrsFromPubKeys adds the addresses into the SimApp providing only the public keys.
func AddTestAddrsFromPubKeys(app *SimApp, ctx sdk.Context, pubKeys []cryptotypes.PubKey, accAmt math.Int) {
initCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), accAmt))
Expand All @@ -318,16 +217,16 @@ func AddTestAddrsFromPubKeys(app *SimApp, ctx sdk.Context, pubKeys []cryptotypes
// AddTestAddrs constructs and returns accNum amount of accounts with an
// initial balance of accAmt in random order
func AddTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt math.Int) []sdk.AccAddress {
return addTestAddrs(app, ctx, accNum, accAmt, createRandomAccounts)
return addTestAddrs(app, ctx, accNum, accAmt, simtestutil.CreateRandomAccounts)
}

// AddTestAddrsIncremental constructs and returns accNum amount of accounts with an
// initial balance of accAmt in random order
func AddTestAddrsIncremental(app *SimApp, ctx sdk.Context, accNum int, accAmt math.Int) []sdk.AccAddress {
return addTestAddrs(app, ctx, accNum, accAmt, createIncrementalAccounts)
return addTestAddrs(app, ctx, accNum, accAmt, simtestutil.CreateIncrementalAccounts)
}

func addTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt math.Int, strategy GenerateAccountStrategy) []sdk.AccAddress {
func addTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt math.Int, strategy simtestutil.GenerateAccountStrategy) []sdk.AccAddress {
testAddrs := strategy(accNum)

initCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), accAmt))
Expand Down Expand Up @@ -362,27 +261,6 @@ func ConvertAddrsToValAddrs(addrs []sdk.AccAddress) []sdk.ValAddress {
return valAddrs
}

func TestAddr(addr string, bech string) (sdk.AccAddress, error) {
res, err := sdk.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
}

// CheckBalance checks the balance of an account.
func CheckBalance(t *testing.T, app *SimApp, addr sdk.AccAddress, balances sdk.Coins) {
ctxCheck := app.BaseApp.NewContext(true, tmproto.Header{})
Expand Down
19 changes: 17 additions & 2 deletions testutil/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,16 +132,31 @@ func DefaultConfig() Config {

func DefaultConfigWithAppConfig(appConfig depinject.Config) (Config, error) {
cfg := DefaultConfig()
var appBuilder *runtime.AppBuilder
var msgServiceRouter *baseapp.MsgServiceRouter

var (
appBuilder *runtime.AppBuilder
msgServiceRouter *baseapp.MsgServiceRouter
txConfig client.TxConfig
legacyAmino *codec.LegacyAmino
codec codec.Codec
interfaceRegistry codectypes.InterfaceRegistry
)

if err := depinject.Inject(appConfig,
&appBuilder,
&msgServiceRouter,
&txConfig,
&codec,
&legacyAmino,
&interfaceRegistry,
); err != nil {
return Config{}, err
}

cfg.Codec = codec
cfg.TxConfig = txConfig
cfg.LegacyAmino = legacyAmino
cfg.InterfaceRegistry = interfaceRegistry
cfg.GenesisState = appBuilder.DefaultGenesis()
cfg.AppConstructor = func(val Validator) servertypes.Application {
app := appBuilder.Build(
Expand Down
96 changes: 96 additions & 0 deletions testutil/sims/address_helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package sims

import (
"bytes"
"fmt"
"strconv"

"cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
sdk "github.com/cosmos/cosmos-sdk/types"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
)

type GenerateAccountStrategy func(int) []sdk.AccAddress

// AddTestAddrsIncremental constructs and returns accNum amount of accounts with an initial balance of accAmt in random order
func AddTestAddrsIncremental(bankKeeper bankkeeper.Keeper, stakingKeeper *stakingkeeper.Keeper, ctx sdk.Context, accNum int, accAmt math.Int) []sdk.AccAddress {
return addTestAddrs(bankKeeper, stakingKeeper, ctx, accNum, accAmt, CreateIncrementalAccounts)
}

func addTestAddrs(bankKeeper bankkeeper.Keeper, stakingKeeper *stakingkeeper.Keeper, ctx sdk.Context, accNum int, accAmt math.Int, strategy GenerateAccountStrategy) []sdk.AccAddress {
testAddrs := strategy(accNum)
initCoins := sdk.NewCoins(sdk.NewCoin(stakingKeeper.BondDenom(ctx), accAmt))

for _, addr := range testAddrs {
initAccountWithCoins(bankKeeper, ctx, addr, initCoins)
}

return testAddrs
}

func initAccountWithCoins(bankKeeper bankkeeper.Keeper, ctx sdk.Context, addr sdk.AccAddress, coins sdk.Coins) {
if err := bankKeeper.MintCoins(ctx, minttypes.ModuleName, coins); err != nil {
panic(err)
}

if err := bankKeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, addr, coins); err != nil {
panic(err)
}
}

// 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, _ := sdk.AccAddressFromHexUnsafe(buffer.String())
bech := res.String()
addr, _ := TestAddr(buffer.String(), bech)

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

return addresses
}

// CreateRandomAccounts is a strategy used by addTestAddrs() in order to generated addresses in random order.
func CreateRandomAccounts(accNum int) []sdk.AccAddress {
testAddrs := make([]sdk.AccAddress, accNum)
for i := 0; i < accNum; i++ {
pk := ed25519.GenPrivKey().PubKey()
testAddrs[i] = sdk.AccAddress(pk.Address())
}

return testAddrs
}

func TestAddr(addr string, bech string) (sdk.AccAddress, error) {
res, err := sdk.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
}
Loading