mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-11-04 10:37:26 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			141 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			141 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package simulation
 | 
						|
 | 
						|
// import (
 | 
						|
// 	"fmt"
 | 
						|
// 	"math/rand"
 | 
						|
// 	"time"
 | 
						|
 | 
						|
// 	"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/auth"
 | 
						|
// 	"github.com/cosmos/cosmos-sdk/x/simulation"
 | 
						|
 | 
						|
// 	appparams "github.com/0glabs/0g-chain/app/params"
 | 
						|
// 	"github.com/0glabs/0g-chain/x/pricefeed/keeper"
 | 
						|
// 	"github.com/0glabs/0g-chain/x/pricefeed/types"
 | 
						|
// )
 | 
						|
 | 
						|
// // Simulation operation weights constants
 | 
						|
// const (
 | 
						|
// 	OpWeightMsgUpdatePrices = "op_weight_msg_update_prices"
 | 
						|
 | 
						|
// 	// Block time params are un-exported constants in cosmos-sdk/x/simulation.
 | 
						|
// 	// Copy them here in lieu of importing them.
 | 
						|
// 	minTimePerBlock time.Duration = (10000 / 2) * time.Second
 | 
						|
// 	maxTimePerBlock time.Duration = 10000 * time.Second
 | 
						|
 | 
						|
// 	// Calculate the average block time
 | 
						|
// 	AverageBlockTime time.Duration = (maxTimePerBlock - minTimePerBlock) / 2
 | 
						|
// )
 | 
						|
 | 
						|
// // WeightedOperations returns all the operations from the module with their respective weights
 | 
						|
// func WeightedOperations(
 | 
						|
// 	appParams simulation.AppParams, cdc *codec.Codec, ak auth.AccountKeeper, k keeper.Keeper,
 | 
						|
// ) simulation.WeightedOperations {
 | 
						|
// 	var weightMsgUpdatePrices int
 | 
						|
// 	// var numBlocks int
 | 
						|
 | 
						|
// 	appParams.GetOrGenerate(cdc, OpWeightMsgUpdatePrices, &weightMsgUpdatePrices, nil,
 | 
						|
// 		func(_ *rand.Rand) {
 | 
						|
// 			weightMsgUpdatePrices = appparams.DefaultWeightMsgUpdatePrices
 | 
						|
// 		},
 | 
						|
// 	)
 | 
						|
 | 
						|
// 	return simulation.WeightedOperations{
 | 
						|
// 		simulation.NewWeightedOperation(
 | 
						|
// 			weightMsgUpdatePrices,
 | 
						|
// 			SimulateMsgUpdatePrices(ak, k, 10000),
 | 
						|
// 		),
 | 
						|
// 	}
 | 
						|
// }
 | 
						|
 | 
						|
// // SimulateMsgUpdatePrices updates the prices of various assets by randomly varying them based on current price
 | 
						|
// func SimulateMsgUpdatePrices(ak auth.AccountKeeper, keeper keeper.Keeper, blocks int) simulation.Operation {
 | 
						|
// 	// runs one at the start of each simulation
 | 
						|
// 	startingPrices := map[string]sdk.Dec{
 | 
						|
// 		"btc:usd": sdk.MustNewDecFromStr("7000"),
 | 
						|
// 		"bnb:usd": sdk.MustNewDecFromStr("15"),
 | 
						|
// 		"xrp:usd": sdk.MustNewDecFromStr("0.25"),
 | 
						|
// 	}
 | 
						|
 | 
						|
// 	// creates the new price generator from starting prices - resets for each sim
 | 
						|
// 	priceGenerator := NewPriceGenerator(startingPrices)
 | 
						|
 | 
						|
// 	return func(
 | 
						|
// 		r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, chainID string,
 | 
						|
// 	) (simulation.OperationMsg, []simulation.FutureOperation, error) {
 | 
						|
// 		// walk prices to current block height, noop if already called for current height
 | 
						|
// 		priceGenerator.Step(r, ctx.BlockHeight())
 | 
						|
 | 
						|
// 		randomMarket := pickRandomAsset(ctx, keeper, r)
 | 
						|
// 		marketID := randommarket.MarketId
 | 
						|
// 		address := getRandomOracle(r, randomMarket)
 | 
						|
 | 
						|
// 		oracle, found := simulation.FindAccount(accs, address)
 | 
						|
// 		if !found {
 | 
						|
// 			return simulation.NoOpMsg(types.ModuleName), nil, nil
 | 
						|
// 		}
 | 
						|
 | 
						|
// 		oracleAcc := ak.GetAccount(ctx, oracle.Address)
 | 
						|
// 		if oracleAcc == nil {
 | 
						|
// 			return simulation.NoOpMsg(types.ModuleName), nil, nil
 | 
						|
// 		}
 | 
						|
 | 
						|
// 		// get price for marketID and current block height set in Step
 | 
						|
// 		price := priceGenerator.GetCurrentPrice(marketID)
 | 
						|
 | 
						|
// 		// get the expiry time based off the current time
 | 
						|
// 		expiry := getExpiryTime(ctx)
 | 
						|
 | 
						|
// 		// now create the msg to post price
 | 
						|
// 		msg := types.NewMsgPostPrice(oracle.Address, marketID, price, expiry)
 | 
						|
 | 
						|
// 		spendable := oracleAcc.SpendableCoins(ctx.BlockTime())
 | 
						|
// 		fees, err := simulation.RandomFees(r, ctx, spendable)
 | 
						|
// 		if err != nil {
 | 
						|
// 			return simulation.NoOpMsg(types.ModuleName), nil, err
 | 
						|
// 		}
 | 
						|
 | 
						|
// 		tx := helpers.GenTx(
 | 
						|
// 			[]sdk.Msg{msg},
 | 
						|
// 			fees,
 | 
						|
// 			helpers.DefaultGenTxGas,
 | 
						|
// 			chainID,
 | 
						|
// 			[]uint64{oracleAcc.GetAccountNumber()},
 | 
						|
// 			[]uint64{oracleAcc.GetSequence()},
 | 
						|
// 			oracle.PrivKey,
 | 
						|
// 		)
 | 
						|
 | 
						|
// 		_, result, err := app.Deliver(tx)
 | 
						|
// 		if err != nil {
 | 
						|
// 			// to aid debugging, add the stack trace to the comment field of the returned opMsg
 | 
						|
// 			return simulation.NewOperationMsg(msg, false, fmt.Sprintf("%+v", err)), nil, err
 | 
						|
// 		}
 | 
						|
// 		return simulation.NewOperationMsg(msg, true, result.Log), nil, nil
 | 
						|
// 	}
 | 
						|
// }
 | 
						|
 | 
						|
// // getRandomOracle picks a random oracle from the list of oracles
 | 
						|
// func getRandomOracle(r *rand.Rand, market types.Market) sdk.AccAddress {
 | 
						|
// 	randomIndex := simulation.RandIntBetween(r, 0, len(market.Oracles))
 | 
						|
// 	return market.Oracles[randomIndex]
 | 
						|
// }
 | 
						|
 | 
						|
// // pickRandomAsset picks a random asset out of the assets with equal probability
 | 
						|
// // it returns the Market which includes the base asset as one of its fields
 | 
						|
// func pickRandomAsset(ctx sdk.Context, keeper keeper.Keeper, r *rand.Rand) (market types.Market) {
 | 
						|
// 	// get the params
 | 
						|
// 	params := keeper.GetParams(ctx)
 | 
						|
// 	// now pick a random asset
 | 
						|
// 	randomIndex := simulation.RandIntBetween(r, 0, len(params.Markets))
 | 
						|
// 	return params.Markets[randomIndex]
 | 
						|
// }
 | 
						|
 | 
						|
// // getExpiryTime gets a price expiry time by taking the current time and adding a delta to it
 | 
						|
// func getExpiryTime(ctx sdk.Context) (t time.Time) {
 | 
						|
// 	// need to use the blocktime from the context as the context generates random start time when running simulations
 | 
						|
// 	return ctx.BlockTime().Add(AverageBlockTime * 5000) // if blocks were 6 seconds, the expiry would be 8 hrs
 | 
						|
// }
 |