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