github.com/cosmos/cosmos-sdk@v0.50.10/types/simulation/account.go (about) 1 package simulation 2 3 import ( 4 "fmt" 5 "math/rand" 6 7 "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" 8 "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" 9 cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" 10 sdk "github.com/cosmos/cosmos-sdk/types" 11 ) 12 13 // Account contains a privkey, pubkey, address tuple 14 // eventually more useful data can be placed in here. 15 // (e.g. number of coins) 16 type Account struct { 17 PrivKey cryptotypes.PrivKey 18 PubKey cryptotypes.PubKey 19 Address sdk.AccAddress 20 ConsKey cryptotypes.PrivKey 21 } 22 23 // Equals returns true if two accounts are equal 24 func (acc Account) Equals(acc2 Account) bool { 25 return acc.Address.Equals(acc2.Address) 26 } 27 28 // RandomAcc picks and returns a random account and its index from an array. 29 func RandomAcc(r *rand.Rand, accs []Account) (Account, int) { 30 idx := r.Intn(len(accs)) 31 return accs[idx], idx 32 } 33 34 // RandomAccounts generates n random accounts 35 func RandomAccounts(r *rand.Rand, n int) []Account { 36 accs := make([]Account, n) 37 38 for i := 0; i < n; i++ { 39 // don't need that much entropy for simulation 40 privkeySeed := make([]byte, 15) 41 r.Read(privkeySeed) 42 43 accs[i].PrivKey = secp256k1.GenPrivKeyFromSecret(privkeySeed) 44 accs[i].PubKey = accs[i].PrivKey.PubKey() 45 accs[i].Address = sdk.AccAddress(accs[i].PubKey.Address()) 46 47 accs[i].ConsKey = ed25519.GenPrivKeyFromSecret(privkeySeed) 48 } 49 50 return accs 51 } 52 53 // FindAccount iterates over all the simulation accounts to find the one that matches 54 // the given address 55 func FindAccount(accs []Account, address sdk.Address) (Account, bool) { 56 for _, acc := range accs { 57 if acc.Address.Equals(address) { 58 return acc, true 59 } 60 } 61 62 return Account{}, false 63 } 64 65 // RandomFees returns a random fee by selecting a random coin denomination and 66 // amount from the account's available balance. If the user doesn't have enough 67 // funds for paying fees, it returns empty coins. 68 func RandomFees(r *rand.Rand, ctx sdk.Context, spendableCoins sdk.Coins) (sdk.Coins, error) { 69 if spendableCoins.Empty() { 70 return nil, nil 71 } 72 73 perm := r.Perm(len(spendableCoins)) 74 var randCoin sdk.Coin 75 for _, index := range perm { 76 randCoin = spendableCoins[index] 77 if !randCoin.Amount.IsZero() { 78 break 79 } 80 } 81 82 if randCoin.Amount.IsZero() { 83 return nil, fmt.Errorf("no coins found for random fees") 84 } 85 86 amt, err := RandPositiveInt(r, randCoin.Amount) 87 if err != nil { 88 return nil, err 89 } 90 91 // Create a random fee and verify the fees are within the account's spendable 92 // balance. 93 fees := sdk.NewCoins(sdk.NewCoin(randCoin.Denom, amt)) 94 95 return fees, nil 96 }