github.com/cosmos/cosmos-sdk@v0.50.10/testutil/sims/address_helpers.go (about) 1 package sims 2 3 import ( 4 "bytes" 5 "context" 6 "encoding/hex" 7 "fmt" 8 "strconv" 9 10 errorsmod "cosmossdk.io/errors" 11 "cosmossdk.io/math" 12 13 "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" 14 cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" 15 sdk "github.com/cosmos/cosmos-sdk/types" 16 sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" 17 bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" 18 minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" 19 ) 20 21 type GenerateAccountStrategy func(int) []sdk.AccAddress 22 23 // BondDenomProvider is a subset of the staking keeper's public interface that 24 // provides the staking bond denom. It is used in arguments in this package's 25 // functions so that a mock staking keeper can be passed instead of the real one. 26 type BondDenomProvider interface { 27 BondDenom(ctx context.Context) (string, error) 28 } 29 30 // AddTestAddrsFromPubKeys adds the addresses into the SimApp providing only the public keys. 31 func AddTestAddrsFromPubKeys(bankKeeper bankkeeper.Keeper, stakingKeeper BondDenomProvider, ctx sdk.Context, pubKeys []cryptotypes.PubKey, accAmt math.Int) { 32 bondDenom, err := stakingKeeper.BondDenom(ctx) 33 if err != nil { 34 panic(err) 35 } 36 initCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, accAmt)) 37 38 for _, pk := range pubKeys { 39 initAccountWithCoins(bankKeeper, ctx, sdk.AccAddress(pk.Address()), initCoins) 40 } 41 } 42 43 // AddTestAddrs constructs and returns accNum amount of accounts with an 44 // initial balance of accAmt in random order 45 func AddTestAddrs(bankKeeper bankkeeper.Keeper, stakingKeeper BondDenomProvider, ctx sdk.Context, accNum int, accAmt math.Int) []sdk.AccAddress { 46 return addTestAddrs(bankKeeper, stakingKeeper, ctx, accNum, accAmt, CreateRandomAccounts) 47 } 48 49 // AddTestAddrsIncremental constructs and returns accNum amount of accounts with an initial balance of accAmt in random order 50 func AddTestAddrsIncremental(bankKeeper bankkeeper.Keeper, stakingKeeper BondDenomProvider, ctx sdk.Context, accNum int, accAmt math.Int) []sdk.AccAddress { 51 return addTestAddrs(bankKeeper, stakingKeeper, ctx, accNum, accAmt, CreateIncrementalAccounts) 52 } 53 54 func addTestAddrs(bankKeeper bankkeeper.Keeper, stakingKeeper BondDenomProvider, ctx sdk.Context, accNum int, accAmt math.Int, strategy GenerateAccountStrategy) []sdk.AccAddress { 55 testAddrs := strategy(accNum) 56 bondDenom, err := stakingKeeper.BondDenom(ctx) 57 if err != nil { 58 panic(err) 59 } 60 initCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, accAmt)) 61 62 for _, addr := range testAddrs { 63 initAccountWithCoins(bankKeeper, ctx, addr, initCoins) 64 } 65 66 return testAddrs 67 } 68 69 func initAccountWithCoins(bankKeeper bankkeeper.Keeper, ctx sdk.Context, addr sdk.AccAddress, coins sdk.Coins) { 70 if err := bankKeeper.MintCoins(ctx, minttypes.ModuleName, coins); err != nil { 71 panic(err) 72 } 73 74 if err := bankKeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, addr, coins); err != nil { 75 panic(err) 76 } 77 } 78 79 // CreateIncrementalAccounts is a strategy used by addTestAddrs() in order to generated addresses in ascending order. 80 func CreateIncrementalAccounts(accNum int) []sdk.AccAddress { 81 var addresses []sdk.AccAddress 82 var buffer bytes.Buffer 83 84 // start at 100 so we can make up to 999 test addresses with valid test addresses 85 for i := 100; i < (accNum + 100); i++ { 86 numString := strconv.Itoa(i) 87 buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA6") // base address string 88 89 buffer.WriteString(numString) // adding on final two digits to make addresses unique 90 res, _ := sdk.AccAddressFromHexUnsafe(buffer.String()) 91 bech := res.String() 92 addr, _ := TestAddr(buffer.String(), bech) 93 94 addresses = append(addresses, addr) 95 buffer.Reset() 96 } 97 98 return addresses 99 } 100 101 // CreateRandomAccounts is a strategy used by addTestAddrs() in order to generated addresses in random order. 102 func CreateRandomAccounts(accNum int) []sdk.AccAddress { 103 testAddrs := make([]sdk.AccAddress, accNum) 104 for i := 0; i < accNum; i++ { 105 pk := ed25519.GenPrivKey().PubKey() 106 testAddrs[i] = sdk.AccAddress(pk.Address()) 107 } 108 109 return testAddrs 110 } 111 112 func TestAddr(addr, bech string) (sdk.AccAddress, error) { 113 res, err := sdk.AccAddressFromHexUnsafe(addr) 114 if err != nil { 115 return nil, err 116 } 117 bechexpected := res.String() 118 if bech != bechexpected { 119 return nil, fmt.Errorf("bech encoding doesn't match reference") 120 } 121 122 bechres, err := sdk.AccAddressFromBech32(bech) 123 if err != nil { 124 return nil, err 125 } 126 if !bytes.Equal(bechres, res) { 127 return nil, err 128 } 129 130 return res, nil 131 } 132 133 // ConvertAddrsToValAddrs converts the provided addresses to ValAddress. 134 func ConvertAddrsToValAddrs(addrs []sdk.AccAddress) []sdk.ValAddress { 135 valAddrs := make([]sdk.ValAddress, len(addrs)) 136 137 for i, addr := range addrs { 138 valAddrs[i] = sdk.ValAddress(addr) 139 } 140 141 return valAddrs 142 } 143 144 // CreateTestPubKeys returns a total of numPubKeys public keys in ascending order. 145 func CreateTestPubKeys(numPubKeys int) []cryptotypes.PubKey { 146 var publicKeys []cryptotypes.PubKey 147 var buffer bytes.Buffer 148 149 // start at 10 to avoid changing 1 to 01, 2 to 02, etc 150 for i := 100; i < (numPubKeys + 100); i++ { 151 numString := strconv.Itoa(i) 152 buffer.WriteString("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AF") // base pubkey string 153 buffer.WriteString(numString) // adding on final two digits to make pubkeys unique 154 publicKeys = append(publicKeys, NewPubKeyFromHex(buffer.String())) 155 buffer.Reset() 156 } 157 158 return publicKeys 159 } 160 161 // NewPubKeyFromHex returns a PubKey from a hex string. 162 func NewPubKeyFromHex(pk string) (res cryptotypes.PubKey) { 163 pkBytes, err := hex.DecodeString(pk) 164 if err != nil { 165 panic(err) 166 } 167 if len(pkBytes) != ed25519.PubKeySize { 168 panic(errorsmod.Wrap(sdkerrors.ErrInvalidPubKey, "invalid pubkey size")) 169 } 170 return &ed25519.PubKey{Key: pkBytes} 171 }