2019-12-03 14:33:20 +00:00
package app
import (
2022-01-08 00:39:27 +00:00
"encoding/json"
2023-04-04 00:08:45 +00:00
"fmt"
2019-12-03 14:33:20 +00:00
"math/rand"
2023-10-03 22:10:22 +00:00
"reflect"
2019-12-05 13:51:46 +00:00
"testing"
2020-08-17 15:06:59 +00:00
"time"
2019-12-05 13:51:46 +00:00
2023-04-05 23:21:59 +00:00
sdkmath "cosmossdk.io/math"
2024-08-09 05:34:37 +00:00
dasignerskeeper "github.com/0glabs/0g-chain/x/dasigners/v1/keeper"
2024-02-06 22:54:10 +00:00
tmdb "github.com/cometbft/cometbft-db"
abci "github.com/cometbft/cometbft/abci/types"
"github.com/cometbft/cometbft/libs/log"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
tmtypes "github.com/cometbft/cometbft/types"
2022-01-08 00:39:27 +00:00
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
2023-04-04 00:08:45 +00:00
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
2022-12-09 21:24:35 +00:00
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
2022-01-08 00:39:27 +00:00
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
2023-10-02 20:10:22 +00:00
storetypes "github.com/cosmos/cosmos-sdk/store/types"
2023-04-04 00:08:45 +00:00
"github.com/cosmos/cosmos-sdk/testutil/mock"
2022-01-08 00:39:27 +00:00
sdk "github.com/cosmos/cosmos-sdk/types"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
2023-04-04 00:08:45 +00:00
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
2022-01-08 00:39:27 +00:00
crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper"
distkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
2023-01-26 16:50:27 +00:00
mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
2022-01-08 00:39:27 +00:00
paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
2022-12-09 21:24:35 +00:00
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
2023-04-04 00:08:45 +00:00
evmkeeper "github.com/evmos/ethermint/x/evm/keeper"
feemarketkeeper "github.com/evmos/ethermint/x/feemarket/keeper"
2019-12-05 13:51:46 +00:00
"github.com/stretchr/testify/require"
2019-12-03 14:33:20 +00:00
2024-05-01 05:53:58 +00:00
"github.com/0glabs/0g-chain/chaincfg"
2024-05-01 03:17:24 +00:00
bep3keeper "github.com/0glabs/0g-chain/x/bep3/keeper"
committeekeeper "github.com/0glabs/0g-chain/x/committee/keeper"
evmutilkeeper "github.com/0glabs/0g-chain/x/evmutil/keeper"
issuancekeeper "github.com/0glabs/0g-chain/x/issuance/keeper"
precisebankkeeper "github.com/0glabs/0g-chain/x/precisebank/keeper"
pricefeedkeeper "github.com/0glabs/0g-chain/x/pricefeed/keeper"
2019-12-03 14:33:20 +00:00
)
2021-06-10 13:35:44 +00:00
var (
2022-06-06 16:07:31 +00:00
emptyTime time . Time
defaultInitialHeight int64 = 1
2021-06-10 13:35:44 +00:00
)
2024-08-09 05:34:37 +00:00
const TestChainId = "zgchain_8888-1"
2024-02-06 22:54:10 +00:00
2019-12-03 14:33:20 +00:00
// TestApp is a simple wrapper around an App. It exposes internal keepers for use in integration tests.
// This file also contains test helpers. Ideally they would be in separate package.
// Basic Usage:
2023-04-04 00:08:45 +00:00
//
// Create a test app with NewTestApp, then all keepers and their methods can be accessed for test setup and execution.
//
2019-12-03 14:33:20 +00:00
// Advanced Usage:
2023-04-04 00:08:45 +00:00
//
// Some tests call for an app to be initialized with some state. This can be achieved through keeper method calls (ie keeper.SetParams(...)).
// However this leads to a lot of duplicated logic similar to InitGenesis methods.
// So TestApp.InitializeFromGenesisStates() will call InitGenesis with the default genesis state.
2019-12-03 14:35:27 +00:00
// and TestApp.InitializeFromGenesisStates(authState, cdpState) will do the same but overwrite the auth and cdp sections of the default genesis state
2023-04-04 00:08:45 +00:00
// Creating the genesis states can be combersome, but helper methods can make it easier such as NewAuthGenStateFromAccounts below.
2019-12-03 14:33:20 +00:00
type TestApp struct {
App
2023-04-04 00:08:45 +00:00
GenesisAddrs [ ] sdk . AccAddress
2019-12-03 14:33:20 +00:00
}
2022-01-08 00:39:27 +00:00
// NewTestApp creates a new TestApp
//
// Note, it also sets the sdk config with the app's address prefix, coin type, etc.
2019-12-03 14:33:20 +00:00
func NewTestApp ( ) TestApp {
2024-05-01 06:08:58 +00:00
chaincfg . SetSDKConfig ( )
2020-04-23 16:35:58 +00:00
2022-01-08 00:39:27 +00:00
return NewTestAppFromSealed ( )
2019-12-03 14:33:20 +00:00
}
2022-01-08 00:39:27 +00:00
// NewTestAppFromSealed creates a TestApp without first setting sdk config.
2021-08-26 22:53:46 +00:00
func NewTestAppFromSealed ( ) TestApp {
db := tmdb . NewMemDB ( )
2022-01-08 00:39:27 +00:00
encCfg := MakeEncodingConfig ( )
2024-02-06 22:54:10 +00:00
app := NewApp (
2024-05-01 05:53:58 +00:00
log . NewNopLogger ( ) , db , chaincfg . DefaultNodeHome , nil ,
2024-02-06 22:54:10 +00:00
encCfg , DefaultOptions , baseapp . SetChainID ( TestChainId ) ,
)
2021-08-26 22:53:46 +00:00
return TestApp { App : * app }
}
2020-05-07 20:34:05 +00:00
// nolint
2024-05-10 16:30:28 +00:00
func ( tApp TestApp ) GetAccountKeeper ( ) authkeeper . AccountKeeper { return tApp . accountKeeper }
func ( tApp TestApp ) GetBankKeeper ( ) bankkeeper . Keeper { return tApp . bankKeeper }
func ( tApp TestApp ) GetMintKeeper ( ) mintkeeper . Keeper { return tApp . mintKeeper }
func ( tApp TestApp ) GetStakingKeeper ( ) * stakingkeeper . Keeper { return tApp . stakingKeeper }
func ( tApp TestApp ) GetSlashingKeeper ( ) slashingkeeper . Keeper { return tApp . slashingKeeper }
func ( tApp TestApp ) GetDistrKeeper ( ) distkeeper . Keeper { return tApp . distrKeeper }
func ( tApp TestApp ) GetGovKeeper ( ) govkeeper . Keeper { return tApp . govKeeper }
func ( tApp TestApp ) GetCrisisKeeper ( ) crisiskeeper . Keeper { return tApp . crisisKeeper }
func ( tApp TestApp ) GetParamsKeeper ( ) paramskeeper . Keeper { return tApp . paramsKeeper }
func ( tApp TestApp ) GetIssuanceKeeper ( ) issuancekeeper . Keeper { return tApp . issuanceKeeper }
func ( tApp TestApp ) GetBep3Keeper ( ) bep3keeper . Keeper { return tApp . bep3Keeper }
func ( tApp TestApp ) GetPriceFeedKeeper ( ) pricefeedkeeper . Keeper { return tApp . pricefeedKeeper }
func ( tApp TestApp ) GetCommitteeKeeper ( ) committeekeeper . Keeper { return tApp . committeeKeeper }
func ( tApp TestApp ) GetEvmutilKeeper ( ) evmutilkeeper . Keeper { return tApp . evmutilKeeper }
func ( tApp TestApp ) GetEvmKeeper ( ) * evmkeeper . Keeper { return tApp . evmKeeper }
func ( tApp TestApp ) GetFeeMarketKeeper ( ) feemarketkeeper . Keeper { return tApp . feeMarketKeeper }
2024-08-09 05:34:37 +00:00
func ( tApp TestApp ) GetDASignersKeeper ( ) dasignerskeeper . Keeper { return tApp . dasignersKeeper }
2024-05-10 16:30:28 +00:00
func ( tApp TestApp ) GetPrecisebankKeeper ( ) precisebankkeeper . Keeper { return tApp . precisebankKeeper }
2022-01-08 00:39:27 +00:00
2023-10-02 20:10:22 +00:00
func ( tApp TestApp ) GetKVStoreKey ( key string ) * storetypes . KVStoreKey {
return tApp . keys [ key ]
}
2024-06-17 17:53:41 +00:00
func ( tApp TestApp ) GetBlockedMaccAddrs ( ) map [ string ] bool {
return tApp . loadBlockedMaccAddrs ( )
}
2022-01-08 00:39:27 +00:00
// LegacyAmino returns the app's amino codec.
func ( app * App ) LegacyAmino ( ) * codec . LegacyAmino {
return app . legacyAmino
}
// AppCodec returns the app's app codec.
func ( app * App ) AppCodec ( ) codec . Codec {
return app . appCodec
}
2019-12-03 14:33:20 +00:00
2023-04-04 00:08:45 +00:00
// SetupWithGenesisValSet initializes GenesisState with a single validator and genesis accounts
// that also act as delegators.
func GenesisStateWithSingleValidator (
app * TestApp ,
genesisState GenesisState ,
) GenesisState {
privVal := mock . NewPV ( )
pubKey , err := privVal . GetPubKey ( )
if err != nil {
panic ( fmt . Errorf ( "error getting pubkey: %w" , err ) )
}
// create validator set with single validator
validator := tmtypes . NewValidator ( pubKey , 1 )
valSet := tmtypes . NewValidatorSet ( [ ] * tmtypes . Validator { validator } )
// generate genesis account
senderPrivKey := secp256k1 . GenPrivKey ( )
acc := authtypes . NewBaseAccount ( senderPrivKey . PubKey ( ) . Address ( ) . Bytes ( ) , senderPrivKey . PubKey ( ) , 0 , 0 )
app . GenesisAddrs = append ( app . GenesisAddrs , acc . GetAddress ( ) )
balances := [ ] banktypes . Balance {
{
Address : acc . GetAddress ( ) . String ( ) ,
2024-05-10 06:31:49 +00:00
Coins : sdk . NewCoins ( chaincfg . MakeCoinForGasDenom ( 100000000000000 ) ) ,
2023-04-04 00:08:45 +00:00
} ,
}
return genesisStateWithValSet ( app , genesisState , valSet , [ ] authtypes . GenesisAccount { acc } , balances ... )
}
// genesisStateWithValSet applies the provided validator set and genesis accounts
// to the provided genesis state, appending to any existing state without replacement.
func genesisStateWithValSet (
app * TestApp ,
genesisState GenesisState ,
valSet * tmtypes . ValidatorSet ,
genAccs [ ] authtypes . GenesisAccount ,
balances ... banktypes . Balance ,
) GenesisState {
// set genesis accounts
currentAuthGenesis := authtypes . GetGenesisStateFromAppState ( app . appCodec , genesisState )
currentAccs , err := authtypes . UnpackAccounts ( currentAuthGenesis . Accounts )
if err != nil {
panic ( fmt . Errorf ( "error unpacking accounts: %w" , err ) )
}
// Add the new accounts to the existing ones
authGenesis := authtypes . NewGenesisState ( currentAuthGenesis . Params , append ( currentAccs , genAccs ... ) )
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 )
if err != nil {
panic ( fmt . Errorf ( "error converting validator public key: %w" , err ) )
}
pkAny , err := codectypes . NewAnyWithValue ( pk )
if err != nil {
panic ( fmt . Errorf ( "can't pack public key into Any: %w" , 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 {
Moniker : "genesis validator" ,
} ,
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
currentStakingGenesis := stakingtypes . GetGenesisStateFromAppState ( app . appCodec , genesisState )
2024-05-10 06:31:49 +00:00
currentStakingGenesis . Params . BondDenom = chaincfg . GasDenom // TODO:
2023-04-04 00:08:45 +00:00
stakingGenesis := stakingtypes . NewGenesisState (
currentStakingGenesis . Params ,
append ( currentStakingGenesis . Validators , validators ... ) ,
append ( currentStakingGenesis . Delegations , delegations ... ) ,
)
// Add the new balances to the existing ones
currentBankGenesis := banktypes . GetGenesisStateFromAppState ( app . appCodec , genesisState )
balances = append ( currentBankGenesis . Balances , balances ... )
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
2024-05-10 06:31:49 +00:00
totalSupply = totalSupply . Add ( chaincfg . MakeCoinForGasDenom ( bondAmt ) )
2023-04-04 00:08:45 +00:00
}
// add bonded amount to bonded pool module account
balances = append ( balances , banktypes . Balance {
Address : authtypes . NewModuleAddress ( stakingtypes . BondedPoolName ) . String ( ) ,
2024-05-10 06:31:49 +00:00
Coins : sdk . Coins { chaincfg . MakeCoinForGasDenom ( bondAmt ) } ,
2023-04-04 00:08:45 +00:00
} )
bankGenesis := banktypes . NewGenesisState (
currentBankGenesis . Params ,
balances ,
totalSupply ,
currentBankGenesis . DenomMetadata ,
2024-02-06 22:54:10 +00:00
currentBankGenesis . SendEnabled ,
2023-04-04 00:08:45 +00:00
)
// set genesis state
genesisState [ authtypes . ModuleName ] = app . appCodec . MustMarshalJSON ( authGenesis )
genesisState [ banktypes . ModuleName ] = app . appCodec . MustMarshalJSON ( bankGenesis )
genesisState [ stakingtypes . ModuleName ] = app . appCodec . MustMarshalJSON ( stakingGenesis )
return genesisState
}
2022-06-06 16:07:31 +00:00
// InitializeFromGenesisStates calls InitChain on the app using the provided genesis states.
// If any module genesis states are missing, defaults are used.
2019-12-03 14:33:20 +00:00
func ( tApp TestApp ) InitializeFromGenesisStates ( genesisStates ... GenesisState ) TestApp {
2024-02-06 22:54:10 +00:00
return tApp . InitializeFromGenesisStatesWithTimeAndChainIDAndHeight ( emptyTime , TestChainId , defaultInitialHeight , true , genesisStates ... )
2019-12-03 14:33:20 +00:00
}
2022-06-06 16:07:31 +00:00
// InitializeFromGenesisStatesWithTime calls InitChain on the app using the provided genesis states and time.
// If any module genesis states are missing, defaults are used.
2020-08-17 15:06:59 +00:00
func ( tApp TestApp ) InitializeFromGenesisStatesWithTime ( genTime time . Time , genesisStates ... GenesisState ) TestApp {
2024-02-06 22:54:10 +00:00
return tApp . InitializeFromGenesisStatesWithTimeAndChainIDAndHeight ( genTime , TestChainId , defaultInitialHeight , true , genesisStates ... )
2020-08-17 15:06:59 +00:00
}
2022-06-06 16:07:31 +00:00
// InitializeFromGenesisStatesWithTimeAndChainID calls InitChain on the app using the provided genesis states, time, and chain id.
// If any module genesis states are missing, defaults are used.
2020-10-06 18:25:05 +00:00
func ( tApp TestApp ) InitializeFromGenesisStatesWithTimeAndChainID ( genTime time . Time , chainID string , genesisStates ... GenesisState ) TestApp {
2023-06-09 23:52:52 +00:00
return tApp . InitializeFromGenesisStatesWithTimeAndChainIDAndHeight ( genTime , chainID , defaultInitialHeight , true , genesisStates ... )
2022-06-06 16:07:31 +00:00
}
// InitializeFromGenesisStatesWithTimeAndChainIDAndHeight calls InitChain on the app using the provided genesis states and other parameters.
// If any module genesis states are missing, defaults are used.
2023-04-04 00:08:45 +00:00
func ( tApp TestApp ) InitializeFromGenesisStatesWithTimeAndChainIDAndHeight (
genTime time . Time ,
chainID string ,
initialHeight int64 ,
2023-06-09 23:52:52 +00:00
addValidator bool ,
2023-04-04 00:08:45 +00:00
genesisStates ... GenesisState ,
) TestApp {
2020-10-06 18:25:05 +00:00
// Create a default genesis state and overwrite with provided values
genesisState := NewDefaultGenesisState ( )
2023-04-04 00:08:45 +00:00
modifiedStates := make ( map [ string ] bool )
2020-10-06 18:25:05 +00:00
for _ , state := range genesisStates {
for k , v := range state {
genesisState [ k ] = v
2023-04-04 00:08:45 +00:00
// Ensure that the same module genesis state is not set more than once.
// Multiple GenesisStates can have the same module genesis state, but
// the same module genesis state will be overwritten.
if previouslyModified := modifiedStates [ k ] ; previouslyModified {
panic ( fmt . Sprintf ( "genesis state for module %s was set more than once, this overrides previous state" , k ) )
}
modifiedStates [ k ] = true
2020-10-06 18:25:05 +00:00
}
}
2023-04-04 00:08:45 +00:00
// Add default genesis states for at least 1 validator
2023-06-09 23:52:52 +00:00
if addValidator {
genesisState = GenesisStateWithSingleValidator (
& tApp ,
genesisState ,
)
}
2023-04-04 00:08:45 +00:00
2020-10-06 18:25:05 +00:00
// Initialize the chain
2022-01-08 00:39:27 +00:00
stateBytes , err := json . Marshal ( genesisState )
2020-10-06 18:25:05 +00:00
if err != nil {
panic ( err )
}
tApp . InitChain (
abci . RequestInitChain {
Time : genTime ,
Validators : [ ] abci . ValidatorUpdate { } ,
AppStateBytes : stateBytes ,
ChainId : chainID ,
2022-04-21 20:16:28 +00:00
// Set consensus params, which is needed by x/feemarket
2024-02-06 22:54:10 +00:00
ConsensusParams : & tmproto . ConsensusParams {
Block : & tmproto . BlockParams {
2022-04-21 20:16:28 +00:00
MaxBytes : 200000 ,
MaxGas : 20000000 ,
} ,
} ,
2022-06-06 16:07:31 +00:00
InitialHeight : initialHeight ,
2020-10-06 18:25:05 +00:00
} ,
)
tApp . Commit ( )
2022-04-21 20:16:28 +00:00
tApp . BeginBlock ( abci . RequestBeginBlock {
Header : tmproto . Header {
Height : tApp . LastBlockHeight ( ) + 1 , Time : genTime , ChainID : chainID ,
} ,
} )
2023-04-04 00:08:45 +00:00
2020-10-06 18:25:05 +00:00
return tApp
}
2023-04-04 00:08:45 +00:00
// DeleteGenesisValidator deletes the genesis validator from the staking module.
// This is useful for testing with validators, but only want to consider the
// validators added in the test. InitGenesis requires at least 1 validator, so
// it must be deleted additional validators are created.
func ( tApp TestApp ) DeleteGenesisValidator ( t * testing . T , ctx sdk . Context ) {
sk := tApp . GetStakingKeeper ( )
vals := sk . GetAllValidators ( ctx )
var genVal stakingtypes . Validator
found := false
for _ , val := range vals {
if val . GetMoniker ( ) == "genesis validator" {
genVal = val
found = true
break
}
}
require . True ( t , found , "genesis validator not found" )
delegations := sk . GetValidatorDelegations ( ctx , genVal . GetOperator ( ) )
for _ , delegation := range delegations {
_ , err := sk . Undelegate ( ctx , delegation . GetDelegatorAddr ( ) , genVal . GetOperator ( ) , delegation . Shares )
require . NoError ( t , err )
}
}
func ( tApp TestApp ) DeleteGenesisValidatorCoins ( t * testing . T , ctx sdk . Context ) {
ak := tApp . GetAccountKeeper ( )
bk := tApp . GetBankKeeper ( )
notBondedAcc := ak . GetModuleAccount ( ctx , stakingtypes . NotBondedPoolName )
// Burn genesis account balance - use staking module to burn
genAccBal := bk . GetAllBalances ( ctx , tApp . GenesisAddrs [ 0 ] )
err := bk . SendCoinsFromAccountToModule ( ctx , tApp . GenesisAddrs [ 0 ] , stakingtypes . NotBondedPoolName , genAccBal )
require . NoError ( t , err )
// Burn coins from the module account
err = bk . BurnCoins (
ctx ,
stakingtypes . NotBondedPoolName ,
bk . GetAllBalances ( ctx , notBondedAcc . GetAddress ( ) ) ,
)
require . NoError ( t , err )
}
2022-01-08 00:39:27 +00:00
// CheckBalance requires the account address has the expected amount of coins.
2019-12-05 13:51:46 +00:00
func ( tApp TestApp ) CheckBalance ( t * testing . T , ctx sdk . Context , owner sdk . AccAddress , expectedCoins sdk . Coins ) {
2022-01-08 00:39:27 +00:00
coins := tApp . GetBankKeeper ( ) . GetAllBalances ( ctx , owner )
require . Equal ( t , expectedCoins , coins )
}
2022-12-09 21:24:35 +00:00
// GetModuleAccountBalance gets the current balance of the denom for a module account
2023-04-05 23:21:59 +00:00
func ( tApp TestApp ) GetModuleAccountBalance ( ctx sdk . Context , moduleName string , denom string ) sdkmath . Int {
2022-12-09 21:24:35 +00:00
moduleAcc := tApp . accountKeeper . GetModuleAccount ( ctx , moduleName )
balance := tApp . bankKeeper . GetBalance ( ctx , moduleAcc . GetAddress ( ) , denom )
return balance . Amount
}
2022-01-08 00:39:27 +00:00
// FundAccount is a utility function that funds an account by minting and sending the coins to the address.
func ( tApp TestApp ) FundAccount ( ctx sdk . Context , addr sdk . AccAddress , amounts sdk . Coins ) error {
2023-01-26 16:50:27 +00:00
if err := tApp . bankKeeper . MintCoins ( ctx , minttypes . ModuleName , amounts ) ; err != nil {
2022-01-08 00:39:27 +00:00
return err
}
2023-01-26 16:50:27 +00:00
return tApp . bankKeeper . SendCoinsFromModuleToAccount ( ctx , minttypes . ModuleName , addr , amounts )
2022-01-08 00:39:27 +00:00
}
// NewQueryServerTestHelper creates a new QueryServiceTestHelper that wraps the provided sdk.Context.
func ( tApp TestApp ) NewQueryServerTestHelper ( ctx sdk . Context ) * baseapp . QueryServiceTestHelper {
return baseapp . NewQueryServerTestHelper ( ctx , tApp . interfaceRegistry )
}
// FundModuleAccount is a utility function that funds a module account by minting and sending the coins to the address.
func ( tApp TestApp ) FundModuleAccount ( ctx sdk . Context , recipientMod string , amounts sdk . Coins ) error {
2023-01-26 16:50:27 +00:00
if err := tApp . bankKeeper . MintCoins ( ctx , minttypes . ModuleName , amounts ) ; err != nil {
2022-01-08 00:39:27 +00:00
return err
}
2023-01-26 16:50:27 +00:00
return tApp . bankKeeper . SendCoinsFromModuleToModule ( ctx , minttypes . ModuleName , recipientMod , amounts )
2019-12-05 13:51:46 +00:00
}
2022-12-09 21:24:35 +00:00
// CreateNewUnbondedValidator creates a new validator in the staking module.
// New validators are unbonded until the end blocker is run.
2023-04-05 23:21:59 +00:00
func ( tApp TestApp ) CreateNewUnbondedValidator ( ctx sdk . Context , valAddress sdk . ValAddress , selfDelegation sdkmath . Int ) error {
2022-12-09 21:24:35 +00:00
msg , err := stakingtypes . NewMsgCreateValidator (
valAddress ,
ed25519 . GenPrivKey ( ) . PubKey ( ) ,
sdk . NewCoin ( tApp . stakingKeeper . BondDenom ( ctx ) , selfDelegation ) ,
stakingtypes . Description { } ,
stakingtypes . NewCommissionRates ( sdk . ZeroDec ( ) , sdk . ZeroDec ( ) , sdk . ZeroDec ( ) ) ,
2023-04-05 23:21:59 +00:00
sdkmath . NewInt ( 1e6 ) ,
2022-12-09 21:24:35 +00:00
)
if err != nil {
return err
}
msgServer := stakingkeeper . NewMsgServerImpl ( tApp . stakingKeeper )
_ , err = msgServer . CreateValidator ( sdk . WrapSDKContext ( ctx ) , msg )
return err
}
2023-04-04 00:08:45 +00:00
func ( tApp TestApp ) SetInflation ( ctx sdk . Context , value sdk . Dec ) {
mk := tApp . GetMintKeeper ( )
mintParams := mk . GetParams ( ctx )
mintParams . InflationMax = sdk . ZeroDec ( )
mintParams . InflationMin = sdk . ZeroDec ( )
if err := mintParams . Validate ( ) ; err != nil {
panic ( err )
}
mk . SetParams ( ctx , mintParams )
}
2024-04-23 21:44:04 +00:00
// GeneratePrivKeyAddressPairs generates (deterministically) a total of n private keys and addresses.
2022-01-08 00:39:27 +00:00
func GeneratePrivKeyAddressPairs ( n int ) ( keys [ ] cryptotypes . PrivKey , addrs [ ] sdk . AccAddress ) {
2019-12-03 14:33:20 +00:00
r := rand . New ( rand . NewSource ( 12345 ) ) // make the generation deterministic
2022-01-08 00:39:27 +00:00
keys = make ( [ ] cryptotypes . PrivKey , n )
2019-12-03 14:33:20 +00:00
addrs = make ( [ ] sdk . AccAddress , n )
for i := 0 ; i < n ; i ++ {
secret := make ( [ ] byte , 32 )
_ , err := r . Read ( secret )
if err != nil {
panic ( "Could not read randomness" )
}
2022-01-08 00:39:27 +00:00
keys [ i ] = secp256k1 . GenPrivKeyFromSecret ( secret )
2019-12-03 14:33:20 +00:00
addrs [ i ] = sdk . AccAddress ( keys [ i ] . PubKey ( ) . Address ( ) )
}
return
}
2021-06-10 13:35:44 +00:00
2022-10-19 19:26:14 +00:00
// RandomAddress non-deterministically generates a new address, discarding the private key.
func RandomAddress ( ) sdk . AccAddress {
secret := make ( [ ] byte , 32 )
_ , err := rand . Read ( secret )
if err != nil {
panic ( "Could not read randomness" )
}
key := secp256k1 . GenPrivKeyFromSecret ( secret )
return sdk . AccAddress ( key . PubKey ( ) . Address ( ) )
}
2022-01-08 00:39:27 +00:00
// NewFundedGenStateWithSameCoins creates a (auth and bank) genesis state populated with accounts from the given addresses and balance.
func NewFundedGenStateWithSameCoins ( cdc codec . JSONCodec , balance sdk . Coins , addresses [ ] sdk . AccAddress ) GenesisState {
builder := NewAuthBankGenesisBuilder ( )
for _ , address := range addresses {
builder . WithSimpleAccount ( address , balance )
2021-06-10 13:35:44 +00:00
}
2022-01-08 00:39:27 +00:00
return builder . BuildMarshalled ( cdc )
2021-06-10 13:35:44 +00:00
}
2022-01-08 00:39:27 +00:00
// NewFundedGenStateWithCoins creates a (auth and bank) genesis state populated with accounts from the given addresses and coins.
func NewFundedGenStateWithCoins ( cdc codec . JSONCodec , coins [ ] sdk . Coins , addresses [ ] sdk . AccAddress ) GenesisState {
builder := NewAuthBankGenesisBuilder ( )
for i , address := range addresses {
builder . WithSimpleAccount ( address , coins [ i ] )
2021-06-10 13:35:44 +00:00
}
2022-01-08 00:39:27 +00:00
return builder . BuildMarshalled ( cdc )
2021-06-10 13:35:44 +00:00
}
2022-01-08 00:39:27 +00:00
// NewFundedGenStateWithSameCoinsWithModuleAccount creates a (auth and bank) genesis state populated with accounts from the given addresses and balance along with an empty module account
func NewFundedGenStateWithSameCoinsWithModuleAccount ( cdc codec . JSONCodec , coins sdk . Coins , addresses [ ] sdk . AccAddress , modAcc * authtypes . ModuleAccount ) GenesisState {
builder := NewAuthBankGenesisBuilder ( )
2021-06-10 13:35:44 +00:00
2022-01-08 00:39:27 +00:00
for _ , address := range addresses {
builder . WithSimpleAccount ( address , coins )
2021-06-10 13:35:44 +00:00
}
2022-01-08 00:39:27 +00:00
builder . WithSimpleModuleAccount ( modAcc . Address , nil )
2021-06-10 13:35:44 +00:00
2022-01-08 00:39:27 +00:00
return builder . BuildMarshalled ( cdc )
2021-06-10 13:35:44 +00:00
}
2023-10-03 22:10:22 +00:00
// EventsContains returns an error if the expected event is not in the provided events
func EventsContains ( events sdk . Events , expectedEvent sdk . Event ) error {
foundMatch := false
for _ , event := range events {
if event . Type == expectedEvent . Type {
if reflect . DeepEqual ( attrsToMap ( expectedEvent . Attributes ) , attrsToMap ( event . Attributes ) ) {
foundMatch = true
}
}
}
if ! foundMatch {
return fmt . Errorf ( "event of type %s not found or did not match" , expectedEvent . Type )
}
return nil
}
func attrsToMap ( attrs [ ] abci . EventAttribute ) [ ] sdk . Attribute { // new cosmos changed the event attribute type
out := [ ] sdk . Attribute { }
for _ , attr := range attrs {
out = append ( out , sdk . NewAttribute ( string ( attr . Key ) , string ( attr . Value ) ) )
}
return out
}