github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/simulation/account.go (about)

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