mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-11-04 13:27:27 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			323 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			323 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package simulation
 | 
						|
 | 
						|
// import (
 | 
						|
// 	"fmt"
 | 
						|
// 	"math/rand"
 | 
						|
 | 
						|
// 	"github.com/cosmos/cosmos-sdk/baseapp"
 | 
						|
// 	"github.com/cosmos/cosmos-sdk/codec"
 | 
						|
// 	"github.com/cosmos/cosmos-sdk/simapp/helpers"
 | 
						|
// 	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
						|
// 	"github.com/cosmos/cosmos-sdk/x/simulation"
 | 
						|
// 	simappparams "github.com/0glabs/0g-chain/app/params"
 | 
						|
 | 
						|
// 	"github.com/0glabs/0g-chain/x/issuance/keeper"
 | 
						|
// 	"github.com/0glabs/0g-chain/x/issuance/types"
 | 
						|
// )
 | 
						|
 | 
						|
// // Simulation operation weights constants
 | 
						|
// const (
 | 
						|
// 	OpWeightMsgIssue  = "op_weight_msg_issue"
 | 
						|
// 	OpWeightMsgRedeem = "op_weight_msg_redeem"
 | 
						|
// 	OpWeightMsgBlock  = "op_weight_msg_block"
 | 
						|
// 	OpWeightMsgPause  = "op_weight_msg_pause"
 | 
						|
// )
 | 
						|
 | 
						|
// // WeightedOperations returns all the operations from the module with their respective weights
 | 
						|
// func WeightedOperations(
 | 
						|
// 	appParams simulation.AppParams, cdc *codec.Codec, ak types.AccountKeeper, k keeper.Keeper,
 | 
						|
// ) simulation.WeightedOperations {
 | 
						|
// 	var (
 | 
						|
// 		weightMsgIssue  int
 | 
						|
// 		weightMsgReedem int
 | 
						|
// 		weightMsgBlock  int
 | 
						|
// 		weightMsgPause  int
 | 
						|
// 	)
 | 
						|
 | 
						|
// 	appParams.GetOrGenerate(cdc, OpWeightMsgIssue, &weightMsgIssue, nil,
 | 
						|
// 		func(_ *rand.Rand) {
 | 
						|
// 			weightMsgIssue = simappparams.DefaultWeightMsgIssue
 | 
						|
// 		},
 | 
						|
// 	)
 | 
						|
 | 
						|
// 	appParams.GetOrGenerate(cdc, OpWeightMsgRedeem, &weightMsgReedem, nil,
 | 
						|
// 		func(_ *rand.Rand) {
 | 
						|
// 			weightMsgReedem = simappparams.DefaultWeightMsgRedeem
 | 
						|
// 		},
 | 
						|
// 	)
 | 
						|
 | 
						|
// 	appParams.GetOrGenerate(cdc, OpWeightMsgBlock, &weightMsgBlock, nil,
 | 
						|
// 		func(_ *rand.Rand) {
 | 
						|
// 			weightMsgBlock = simappparams.DefaultWeightMsgBlock
 | 
						|
// 		},
 | 
						|
// 	)
 | 
						|
 | 
						|
// 	appParams.GetOrGenerate(cdc, OpWeightMsgPause, &weightMsgPause, nil,
 | 
						|
// 		func(_ *rand.Rand) {
 | 
						|
// 			weightMsgPause = simappparams.DefaultWeightMsgPause
 | 
						|
// 		},
 | 
						|
// 	)
 | 
						|
 | 
						|
// 	return simulation.WeightedOperations{
 | 
						|
// 		simulation.NewWeightedOperation(
 | 
						|
// 			weightMsgIssue,
 | 
						|
// 			SimulateMsgIssueTokens(ak, k),
 | 
						|
// 		),
 | 
						|
// 		simulation.NewWeightedOperation(
 | 
						|
// 			weightMsgReedem,
 | 
						|
// 			SimulateMsgRedeemTokens(ak, k),
 | 
						|
// 		),
 | 
						|
// 		simulation.NewWeightedOperation(
 | 
						|
// 			weightMsgBlock,
 | 
						|
// 			SimulateMsgBlockAddress(ak, k),
 | 
						|
// 		),
 | 
						|
// 		simulation.NewWeightedOperation(
 | 
						|
// 			weightMsgPause,
 | 
						|
// 			SimulateMsgPause(ak, k),
 | 
						|
// 		),
 | 
						|
// 	}
 | 
						|
// }
 | 
						|
 | 
						|
// // SimulateMsgIssueTokens generates a MsgIssueTokens with random values
 | 
						|
// func SimulateMsgIssueTokens(ak types.AccountKeeper, k keeper.Keeper) simulation.Operation {
 | 
						|
// 	return func(
 | 
						|
// 		r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, chainID string,
 | 
						|
// 	) (simulation.OperationMsg, []simulation.FutureOperation, error) {
 | 
						|
// 		// shuffle the assets and get a random one
 | 
						|
// 		assets := k.GetParams(ctx).Assets
 | 
						|
// 		r.Shuffle(len(assets), func(i, j int) {
 | 
						|
// 			assets[i], assets[j] = assets[j], assets[i]
 | 
						|
// 		})
 | 
						|
// 		asset := assets[0]
 | 
						|
 | 
						|
// 		if asset.Paused {
 | 
						|
// 			return simulation.NoOpMsg(types.ModuleName), nil, nil
 | 
						|
// 		}
 | 
						|
 | 
						|
// 		// make sure owner account exists
 | 
						|
// 		ownerSimAcc, found := simulation.FindAccount(accs, asset.Owner)
 | 
						|
// 		if !found {
 | 
						|
// 			return simulation.NoOpMsg(types.ModuleName), nil, fmt.Errorf("asset owner not found: %s", asset)
 | 
						|
// 		}
 | 
						|
 | 
						|
// 		// issue new tokens to the owner 50% of the time so we have funds to redeem
 | 
						|
// 		ownerAcc := ak.GetAccount(ctx, asset.Owner)
 | 
						|
// 		recipient := ownerAcc
 | 
						|
// 		if r.Intn(2) == 0 {
 | 
						|
// 			simAccount, _ := simulation.RandomAcc(r, accs)
 | 
						|
// 			recipient = ak.GetAccount(ctx, simAccount.Address)
 | 
						|
// 		}
 | 
						|
// 		if recipient == nil {
 | 
						|
// 			return simulation.NoOpMsg(types.ModuleName), nil, nil
 | 
						|
// 		}
 | 
						|
// 		for _, blockedAddr := range asset.BlockedAddresses {
 | 
						|
// 			if recipient.GetAddress().Equals(blockedAddr) {
 | 
						|
// 				return simulation.NoOpMsg(types.ModuleName), nil, nil
 | 
						|
// 			}
 | 
						|
// 		}
 | 
						|
// 		randomAmount := simulation.RandIntBetween(r, 10000000, 1000000000000)
 | 
						|
// 		if asset.RateLimit.Active {
 | 
						|
// 			supply, found := k.GetAssetSupply(ctx, asset.Denom)
 | 
						|
// 			if !found {
 | 
						|
// 				return simulation.NoOpMsg(types.ModuleName), nil, fmt.Errorf("issuance - no asset supply for %s", asset.Denom)
 | 
						|
// 			}
 | 
						|
// 			if asset.RateLimit.Limit.LT(supply.CurrentSupply.Amount.Add(sdkmath.NewInt(int64(randomAmount)))) {
 | 
						|
// 				maxAmount := asset.RateLimit.Limit.Sub(supply.CurrentSupply.Amount)
 | 
						|
// 				if maxAmount.IsPositive() && maxAmount.GT(sdk.OneInt()) {
 | 
						|
// 					randomAmount = simulation.RandIntBetween(r, 1, int(maxAmount.Int64()))
 | 
						|
// 				} else if maxAmount.Equal(sdk.OneInt()) {
 | 
						|
// 					randomAmount = 1
 | 
						|
// 				} else {
 | 
						|
// 					return simulation.NoOpMsg(types.ModuleName), nil, nil
 | 
						|
// 				}
 | 
						|
// 			}
 | 
						|
 | 
						|
// 		}
 | 
						|
// 		msg := types.NewMsgIssueTokens(asset.Owner, sdk.NewCoin(asset.Denom, sdkmath.NewInt(int64(randomAmount))), recipient.GetAddress())
 | 
						|
// 		spendableCoins := ownerAcc.SpendableCoins(ctx.BlockTime())
 | 
						|
// 		fees, err := simulation.RandomFees(r, ctx, spendableCoins)
 | 
						|
// 		if err != nil {
 | 
						|
// 			return simulation.NoOpMsg(types.ModuleName), nil, err
 | 
						|
// 		}
 | 
						|
// 		tx := helpers.GenTx(
 | 
						|
// 			[]sdk.Msg{msg},
 | 
						|
// 			fees,
 | 
						|
// 			helpers.DefaultGenTxGas,
 | 
						|
// 			chainID,
 | 
						|
// 			[]uint64{ownerAcc.GetAccountNumber()},
 | 
						|
// 			[]uint64{ownerAcc.GetSequence()},
 | 
						|
// 			ownerSimAcc.PrivKey,
 | 
						|
// 		)
 | 
						|
 | 
						|
// 		_, _, err = app.Deliver(tx)
 | 
						|
// 		if err != nil {
 | 
						|
// 			fmt.Printf("error on issue %s\n%s\n", msg, asset)
 | 
						|
// 			return simulation.NoOpMsg(types.ModuleName), nil, err
 | 
						|
// 		}
 | 
						|
// 		return simulation.NewOperationMsg(msg, true, ""), nil, nil
 | 
						|
// 	}
 | 
						|
// }
 | 
						|
 | 
						|
// // SimulateMsgRedeemTokens generates a MsgRedeemTokens with random values
 | 
						|
// func SimulateMsgRedeemTokens(ak types.AccountKeeper, k keeper.Keeper) simulation.Operation {
 | 
						|
// 	return func(
 | 
						|
// 		r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, chainID string,
 | 
						|
// 	) (simulation.OperationMsg, []simulation.FutureOperation, error) {
 | 
						|
// 		// shuffle the assets and get a random one
 | 
						|
// 		assets := k.GetParams(ctx).Assets
 | 
						|
// 		r.Shuffle(len(assets), func(i, j int) {
 | 
						|
// 			assets[i], assets[j] = assets[j], assets[i]
 | 
						|
// 		})
 | 
						|
// 		asset := assets[0]
 | 
						|
// 		if asset.Paused {
 | 
						|
// 			return simulation.NoOpMsg(types.ModuleName), nil, nil
 | 
						|
// 		}
 | 
						|
 | 
						|
// 		// make sure owner account exists
 | 
						|
// 		ownerSimAcc, found := simulation.FindAccount(accs, asset.Owner)
 | 
						|
// 		if !found {
 | 
						|
// 			return simulation.NoOpMsg(types.ModuleName), nil, fmt.Errorf("asset owner not found: %s", asset)
 | 
						|
// 		}
 | 
						|
 | 
						|
// 		ownerAcc := ak.GetAccount(ctx, asset.Owner)
 | 
						|
 | 
						|
// 		spendableCoinAmount := ownerAcc.SpendableCoins(ctx.BlockTime()).AmountOf(asset.Denom)
 | 
						|
// 		if spendableCoinAmount.IsZero() {
 | 
						|
// 			return simulation.NoOpMsg(types.ModuleName), nil, nil
 | 
						|
// 		}
 | 
						|
// 		var redeemAmount sdkmath.Int
 | 
						|
// 		if spendableCoinAmount.Equal(sdk.OneInt()) {
 | 
						|
// 			redeemAmount = sdk.OneInt()
 | 
						|
// 		} else {
 | 
						|
// 			redeemAmount = sdkmath.NewInt(int64(simulation.RandIntBetween(r, 1, int(spendableCoinAmount.Int64()))))
 | 
						|
// 		}
 | 
						|
 | 
						|
// 		msg := types.NewMsgRedeemTokens(asset.Owner, sdk.NewCoin(asset.Denom, redeemAmount))
 | 
						|
// 		spendableCoins := ownerAcc.SpendableCoins(ctx.BlockTime()).Sub(sdk.NewCoins(sdk.NewCoin(asset.Denom, redeemAmount)))
 | 
						|
// 		fees, err := simulation.RandomFees(r, ctx, spendableCoins)
 | 
						|
// 		if err != nil {
 | 
						|
// 			fmt.Printf("%s\n", msg)
 | 
						|
// 			return simulation.NoOpMsg(types.ModuleName), nil, err
 | 
						|
// 		}
 | 
						|
// 		tx := helpers.GenTx(
 | 
						|
// 			[]sdk.Msg{msg},
 | 
						|
// 			fees,
 | 
						|
// 			helpers.DefaultGenTxGas,
 | 
						|
// 			chainID,
 | 
						|
// 			[]uint64{ownerAcc.GetAccountNumber()},
 | 
						|
// 			[]uint64{ownerAcc.GetSequence()},
 | 
						|
// 			ownerSimAcc.PrivKey,
 | 
						|
// 		)
 | 
						|
 | 
						|
// 		_, _, err = app.Deliver(tx)
 | 
						|
// 		if err != nil {
 | 
						|
// 			fmt.Printf("error on redeem %s\n%s\n", msg, asset)
 | 
						|
// 			return simulation.NoOpMsg(types.ModuleName), nil, err
 | 
						|
// 		}
 | 
						|
// 		return simulation.NewOperationMsg(msg, true, ""), nil, nil
 | 
						|
// 	}
 | 
						|
// }
 | 
						|
 | 
						|
// // SimulateMsgBlockAddress generates a MsgBlockAddress with random values
 | 
						|
// func SimulateMsgBlockAddress(ak types.AccountKeeper, k keeper.Keeper) simulation.Operation {
 | 
						|
// 	return func(
 | 
						|
// 		r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, chainID string,
 | 
						|
// 	) (simulation.OperationMsg, []simulation.FutureOperation, error) {
 | 
						|
// 		// shuffle the assets and get a random one
 | 
						|
// 		assets := k.GetParams(ctx).Assets
 | 
						|
// 		r.Shuffle(len(assets), func(i, j int) {
 | 
						|
// 			assets[i], assets[j] = assets[j], assets[i]
 | 
						|
// 		})
 | 
						|
// 		asset := assets[0]
 | 
						|
 | 
						|
// 		// make sure owner account exists
 | 
						|
// 		ownerSimAcc, found := simulation.FindAccount(accs, asset.Owner)
 | 
						|
// 		if !found {
 | 
						|
// 			return simulation.NoOpMsg(types.ModuleName), nil, fmt.Errorf("asset owner not found: %s", asset)
 | 
						|
// 		}
 | 
						|
// 		ownerAcc := ak.GetAccount(ctx, asset.Owner)
 | 
						|
 | 
						|
// 		// find an account to block
 | 
						|
// 		simAccount, _ := simulation.RandomAcc(r, accs)
 | 
						|
// 		blockedAccount := ak.GetAccount(ctx, simAccount.Address)
 | 
						|
// 		if blockedAccount.GetAddress().Equals(asset.Owner) {
 | 
						|
// 			return simulation.NoOpMsg(types.ModuleName), nil, nil
 | 
						|
// 		}
 | 
						|
// 		for _, blockedAddr := range asset.BlockedAddresses {
 | 
						|
// 			if blockedAccount.GetAddress().Equals(blockedAddr) {
 | 
						|
// 				return simulation.NoOpMsg(types.ModuleName), nil, nil
 | 
						|
// 			}
 | 
						|
// 		}
 | 
						|
 | 
						|
// 		msg := types.NewMsgBlockAddress(asset.Owner, asset.Denom, blockedAccount.GetAddress())
 | 
						|
// 		spendableCoins := ownerAcc.SpendableCoins(ctx.BlockTime())
 | 
						|
// 		fees, err := simulation.RandomFees(r, ctx, spendableCoins)
 | 
						|
// 		if err != nil {
 | 
						|
// 			return simulation.NoOpMsg(types.ModuleName), nil, err
 | 
						|
// 		}
 | 
						|
// 		tx := helpers.GenTx(
 | 
						|
// 			[]sdk.Msg{msg},
 | 
						|
// 			fees,
 | 
						|
// 			helpers.DefaultGenTxGas*2,
 | 
						|
// 			chainID,
 | 
						|
// 			[]uint64{ownerAcc.GetAccountNumber()},
 | 
						|
// 			[]uint64{ownerAcc.GetSequence()},
 | 
						|
// 			ownerSimAcc.PrivKey,
 | 
						|
// 		)
 | 
						|
 | 
						|
// 		_, _, err = app.Deliver(tx)
 | 
						|
// 		if err != nil {
 | 
						|
// 			fmt.Printf("error on block %s\n%s\n", msg, asset)
 | 
						|
// 			return simulation.NoOpMsg(types.ModuleName), nil, err
 | 
						|
// 		}
 | 
						|
// 		return simulation.NewOperationMsg(msg, true, ""), nil, nil
 | 
						|
// 	}
 | 
						|
// }
 | 
						|
 | 
						|
// // SimulateMsgPause generates a MsgChangePauseStatus with random values
 | 
						|
// func SimulateMsgPause(ak types.AccountKeeper, k keeper.Keeper) simulation.Operation {
 | 
						|
// 	return func(
 | 
						|
// 		r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, chainID string,
 | 
						|
// 	) (simulation.OperationMsg, []simulation.FutureOperation, error) {
 | 
						|
// 		// shuffle the assets and get a random one
 | 
						|
// 		assets := k.GetParams(ctx).Assets
 | 
						|
// 		r.Shuffle(len(assets), func(i, j int) {
 | 
						|
// 			assets[i], assets[j] = assets[j], assets[i]
 | 
						|
// 		})
 | 
						|
// 		asset := assets[0]
 | 
						|
 | 
						|
// 		// make sure owner account exists
 | 
						|
// 		ownerSimAcc, found := simulation.FindAccount(accs, asset.Owner)
 | 
						|
// 		if !found {
 | 
						|
// 			return simulation.NoOpMsg(types.ModuleName), nil, fmt.Errorf("asset owner not found: %s", asset)
 | 
						|
// 		}
 | 
						|
// 		ownerAcc := ak.GetAccount(ctx, asset.Owner)
 | 
						|
 | 
						|
// 		// set status to paused/un-paused
 | 
						|
// 		status := r.Intn(2) == 0
 | 
						|
 | 
						|
// 		msg := types.NewMsgSetPauseStatus(asset.Owner, asset.Denom, status)
 | 
						|
// 		spendableCoins := ownerAcc.SpendableCoins(ctx.BlockTime())
 | 
						|
// 		fees, err := simulation.RandomFees(r, ctx, spendableCoins)
 | 
						|
// 		if err != nil {
 | 
						|
// 			return simulation.NoOpMsg(types.ModuleName), nil, err
 | 
						|
// 		}
 | 
						|
// 		tx := helpers.GenTx(
 | 
						|
// 			[]sdk.Msg{msg},
 | 
						|
// 			fees,
 | 
						|
// 			helpers.DefaultGenTxGas*2,
 | 
						|
// 			chainID,
 | 
						|
// 			[]uint64{ownerAcc.GetAccountNumber()},
 | 
						|
// 			[]uint64{ownerAcc.GetSequence()},
 | 
						|
// 			ownerSimAcc.PrivKey,
 | 
						|
// 		)
 | 
						|
 | 
						|
// 		_, _, err = app.Deliver(tx)
 | 
						|
// 		if err != nil {
 | 
						|
// 			fmt.Printf("error on pause %s\n%s\n", msg, asset)
 | 
						|
// 			return simulation.NoOpMsg(types.ModuleName), nil, err
 | 
						|
// 		}
 | 
						|
// 		return simulation.NewOperationMsg(msg, true, ""), nil, nil
 | 
						|
// 	}
 | 
						|
// }
 |