diff --git a/x/crosschain/keeper/msg_server_update_rate_limiter_flags.go b/x/crosschain/keeper/msg_server_update_rate_limiter_flags.go index 12fbdda9c8..8da83c2c81 100644 --- a/x/crosschain/keeper/msg_server_update_rate_limiter_flags.go +++ b/x/crosschain/keeper/msg_server_update_rate_limiter_flags.go @@ -2,7 +2,6 @@ package keeper import ( "context" - "fmt" errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/x/crosschain/simulation/operation_abort_stuck_cctx.go b/x/crosschain/simulation/operation_abort_stuck_cctx.go index 65232bcf8d..79e1930996 100644 --- a/x/crosschain/simulation/operation_abort_stuck_cctx.go +++ b/x/crosschain/simulation/operation_abort_stuck_cctx.go @@ -42,26 +42,10 @@ func SimulateMsgAbortStuckCCTX(k keeper.Keeper) simtypes.Operation { authAccount := k.GetAuthKeeper().GetAccount(ctx, policyAccount.Address) spendable := k.GetBankKeeper().SpendableCoins(ctx, authAccount.GetAddress()) - //_, creator, err := GetRandomAccountAndObserver(r, ctx, k, accounts) - //if err != nil { - // return simtypes.OperationMsg{}, nil, nil - //} - //index := ethcrypto.Keccak256Hash([]byte(fmt.Sprintf("%d", r.Int63()))).Hex() - // tss, found := k.GetObserverKeeper().GetTSS(ctx) if !found { return simtypes.OperationMsg{}, nil, fmt.Errorf("tss not found") } - // - //cctx := sample.CCTXfromRand(r, creator, index, to, from, tss.TssPubkey) - //cctx.CctxStatus = &types.Status{ - // Status: types.CctxStatus_Aborted, - // StatusMessage: "testing SimulateMsgAbortStuckCCTX", - // ErrorMessage: "SimulateMsgAbortStuckCCTX", - // LastUpdateTimestamp: r.Int63(), - // IsAbortRefunded: false, - // CreatedTimestamp: r.Int63(), - //} pendingNonces, found := k.GetObserverKeeper().GetPendingNonces(ctx, tss.TssPubkey, chainID) if !found { @@ -81,27 +65,6 @@ func SimulateMsgAbortStuckCCTX(k keeper.Keeper) simtypes.Operation { "no pending nonces found", ), nil, nil } - //fmt.Println("Pending nonces:", pendingNonces.NonceLow, pendingNonces.NonceHigh) - //for i := pendingNonces.NonceLow; i < pendingNonces.NonceHigh; i++ { - // fmt.Println("Checking nonce:", i) - // nonceToCctx, found := k.GetObserverKeeper().GetNonceToCctx(ctx, tss.TssPubkey, chainID, int64(i)) - // if !found { - // fmt.Println("NonceToCctx not found:", chainID, i) - // continue - // } - // - // cctx, found := k.GetCrossChainTx(ctx, nonceToCctx.CctxIndex) - // if !found { - // fmt.Println("CCTX not found:", chainID, i) - // continue - // } - // fmt.Println("CCTX found:", cctx.Index, cctx.CctxStatus.Status, cctx.GetCurrentOutboundParam().TssNonce) - // //if cctx.CctxStatus.Status == types.CctxStatus_Aborted { - // // fmt.Println("CCTX already aborted:", cctx.Index) - // // continue - // //} - //} - // Pick a random pending nonce nonce := 0 switch { diff --git a/x/crosschain/simulation/operation_refund_aborted_cctx.go b/x/crosschain/simulation/operation_refund_aborted_cctx.go index 463aaf8c17..5c286c12a4 100644 --- a/x/crosschain/simulation/operation_refund_aborted_cctx.go +++ b/x/crosschain/simulation/operation_refund_aborted_cctx.go @@ -13,6 +13,7 @@ import ( "github.com/zeta-chain/node/x/crosschain/types" ) +// SimulateMsgRefundAbortedCCTX generates a MsgRefundAbortedCCTX with random values func SimulateMsgRefundAbortedCCTX(k keeper.Keeper, ) simtypes.Operation { return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accounts []simtypes.Account, _ string, diff --git a/x/crosschain/simulation/operation_update_erc20_pause_status.go b/x/crosschain/simulation/operation_update_erc20_pause_status.go new file mode 100644 index 0000000000..fe6e55b80c --- /dev/null +++ b/x/crosschain/simulation/operation_update_erc20_pause_status.go @@ -0,0 +1,115 @@ +package simulation + +import ( + "math/rand" + + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + "github.com/cosmos/cosmos-sdk/x/simulation" + "github.com/zeta-chain/node/pkg/chains" + "github.com/zeta-chain/node/x/crosschain/keeper" + "github.com/zeta-chain/node/x/crosschain/types" +) + +// SimulateUpdateERC20CustodyPauseStatus generates a MsgUpdateERC20CustodyPauseStatus with random values and delivers it +func SimulateUpdateERC20CustodyPauseStatus(k keeper.Keeper) simtypes.Operation { + return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accounts []simtypes.Account, _ string, + ) (OperationMsg simtypes.OperationMsg, futureOps []simtypes.FutureOperation, err error) { + policyAccount, err := GetPolicyAccount(ctx, k.GetAuthorityKeeper(), accounts) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgWhitelistERC20, err.Error()), nil, nil + } + + authAccount := k.GetAuthKeeper().GetAccount(ctx, policyAccount.Address) + spendable := k.GetBankKeeper().SpendableCoins(ctx, authAccount.GetAddress()) + + supportedChains := k.GetObserverKeeper().GetSupportedChains(ctx) + if len(supportedChains) == 0 { + return simtypes.NoOpMsg( + types.ModuleName, + types.TypeUpdateERC20CustodyPauseStatus, + "no supported chains found", + ), nil, nil + } + + filteredChains := chains.FilterChains(supportedChains, chains.FilterExternalChains) + + //pick a random chain + randomChain := supportedChains[r.Intn(len(filteredChains))] + + _, found := k.GetObserverKeeper().GetChainNonces(ctx, randomChain.ChainId) + if !found { + return simtypes.NoOpMsg( + types.ModuleName, + types.TypeUpdateERC20CustodyPauseStatus, + "no chain nonces found", + ), nil, nil + } + + _, found = k.GetObserverKeeper().GetTSS(ctx) + if !found { + return simtypes.NoOpMsg( + types.ModuleName, + types.TypeUpdateERC20CustodyPauseStatus, + "no TSS found", + ), nil, nil + } + + _, found = k.GetObserverKeeper().GetChainParamsByChainID(ctx, randomChain.ChainId) + if !found { + return simtypes.NoOpMsg( + types.ModuleName, + types.TypeUpdateERC20CustodyPauseStatus, + "no chain params found", + ), nil, nil + } + medianGasPrice, priorityFee, found := k.GetMedianGasValues(ctx, randomChain.ChainId) + if !found { + return simtypes.NoOpMsg( + types.ModuleName, + types.TypeUpdateERC20CustodyPauseStatus, + "no median gas values found", + ), nil, nil + } + medianGasPrice = medianGasPrice.MulUint64(types.ERC20CustodyPausingGasMultiplierEVM) + priorityFee = priorityFee.MulUint64(types.ERC20CustodyPausingGasMultiplierEVM) + + if priorityFee.GT(medianGasPrice) { + return simtypes.NoOpMsg( + types.ModuleName, + types.TypeUpdateERC20CustodyPauseStatus, + "priorityFee is greater than median gasPrice", + ), nil, nil + } + + msg := types.MsgUpdateERC20CustodyPauseStatus{ + Creator: policyAccount.Address.String(), + ChainId: randomChain.ChainId, + Pause: r.Intn(2) == 0, + } + + err = msg.ValidateBasic() + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to validate MsgRemoveOutboundTracker msg"), nil, err + } + + txCtx := simulation.OperationInput{ + R: r, + App: app, + TxGen: moduletestutil.MakeTestEncodingConfig().TxConfig, + Cdc: nil, + Msg: &msg, + MsgType: msg.Type(), + Context: ctx, + SimAccount: policyAccount, + AccountKeeper: k.GetAuthKeeper(), + Bankkeeper: k.GetBankKeeper(), + ModuleName: types.ModuleName, + CoinsSpentInMsg: spendable, + } + + return simulation.GenAndDeliverTxWithRandFees(txCtx) + } +} diff --git a/x/crosschain/simulation/operation_vote_outbound.go b/x/crosschain/simulation/operation_vote_outbound.go index a1062fa073..43e156ad62 100644 --- a/x/crosschain/simulation/operation_vote_outbound.go +++ b/x/crosschain/simulation/operation_vote_outbound.go @@ -55,6 +55,8 @@ func operationSimulateVoteOutbound( } } +// SimulateVoteOutbound generates a MsgVoteOutbound with random values +// This is the only operation which saves a cctx directly to the store. func SimulateVoteOutbound(k keeper.Keeper) simtypes.Operation { defaultVote := chains.ReceiveStatus_success diff --git a/x/crosschain/simulation/operation_whitelist_erc20.go b/x/crosschain/simulation/operation_whitelist_erc20.go index 7776ee79cb..ea0cbe53ac 100644 --- a/x/crosschain/simulation/operation_whitelist_erc20.go +++ b/x/crosschain/simulation/operation_whitelist_erc20.go @@ -14,6 +14,7 @@ import ( "github.com/zeta-chain/node/x/crosschain/types" ) +// SimulateMsgAddInboundTracker generates a MsgAddInboundTracker with random values and delivers it func SimulateMsgWhitelistERC20(k keeper.Keeper) simtypes.Operation { return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accounts []simtypes.Account, _ string, ) (OperationMsg simtypes.OperationMsg, futureOps []simtypes.FutureOperation, err error) { @@ -47,14 +48,16 @@ func SimulateMsgWhitelistERC20(k keeper.Keeper) simtypes.Operation { return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgWhitelistERC20, "unsupported chain"), nil, nil } + gasLimit := r.Int63n(1000000000) + 1 + nameLength := r.Intn(97) + 3 msg := types.MsgWhitelistERC20{ Creator: policyAccount.Address.String(), ChainId: randomChain.ChainId, Erc20Address: tokenAddress, - GasLimit: 100000, + GasLimit: gasLimit, Decimals: 18, - Name: "Test", - Symbol: "TST", + Name: sample.StringRandom(r, nameLength), + Symbol: sample.StringRandom(r, 3), } err = msg.ValidateBasic() diff --git a/x/crosschain/simulation/operations.go b/x/crosschain/simulation/operations.go index ae0a4c2217..aa5a53ed6b 100644 --- a/x/crosschain/simulation/operations.go +++ b/x/crosschain/simulation/operations.go @@ -22,49 +22,52 @@ import ( // TODO Add more details to comment based on what the number represents in terms of percentage of operations in a block // https://github.com/zeta-chain/node/issues/3100 const ( - DefaultWeightAddOutboundTracker = 100 - DefaultWeightAddInboundTracker = 20 - DefaultWeightRemoveOutboundTracker = 10 - DefaultWeightVoteGasPrice = 100 - DefaultWeightVoteOutbound = 100 - DefaultWeightVoteInbound = 100 - DefaultWeightWhitelistERC20 = 10 - DefaultWeightMigrateTssFunds = 1 - DefaultWeightUpdateTssAddress = 1 - DefaultWeightAbortStuckCCTX = 10 - DefaultWeightUpdateRateLimiterFlags = 10 - DefaultWeightRefundAbortedCCTX = 10 - - OpWeightMsgAddOutboundTracker = "op_weight_msg_add_outbound_tracker" // #nosec G101 not a hardcoded credential - OpWeightAddInboundTracker = "op_weight_msg_add_inbound_tracker" // #nosec G101 not a hardcoded credential - OpWeightRemoveOutboundTracker = "op_weight_msg_remove_outbound_tracker" // #nosec G101 not a hardcoded credential - OpWeightVoteGasPrice = "op_weight_msg_vote_gas_price" // #nosec G101 not a hardcoded credential - OpWeightVoteOutbound = "op_weight_msg_vote_outbound" // #nosec G101 not a hardcoded credential - OpWeightVoteInbound = "op_weight_msg_vote_inbound" // #nosec G101 not a hardcoded credential - OpWeightWhitelistERC20 = "op_weight_msg_whitelist_erc20" // #nosec G101 not a hardcoded credential - OpWeightMigrateTssFunds = "op_weight_msg_migrate_tss_funds" // #nosec G101 not a hardcoded credential - OpWeightUpdateTssAddress = "op_weight_msg_update_tss_address" // #nosec G101 not a hardcoded credential - OpWeightAbortStuckCCTX = "op_weight_msg_abort_stuck_cctx" // #nosec G101 not a hardcoded credential - OpWeightUpdateRateLimiterFlags = "op_weight_msg_update_rate_limiter_flags" // #nosec G101 not a hardcoded credential - OpWeightRefundAbortedCCTX = "op_weight_msg_refund_aborted_cctx" // #nosec G101 not a hardcoded credential + DefaultWeightAddOutboundTracker = 100 + DefaultWeightAddInboundTracker = 20 + DefaultWeightRemoveOutboundTracker = 10 + DefaultWeightVoteGasPrice = 100 + DefaultWeightVoteOutbound = 100 + DefaultWeightVoteInbound = 100 + DefaultWeightWhitelistERC20 = 10 + DefaultWeightMigrateTssFunds = 1 + DefaultWeightUpdateTssAddress = 1 + DefaultWeightAbortStuckCCTX = 10 + DefaultWeightUpdateRateLimiterFlags = 10 + DefaultWeightRefundAbortedCCTX = 10 + DefaultWeightUpdateERC20CustodyPauseStatus = 10 + + OpWeightMsgAddOutboundTracker = "op_weight_msg_add_outbound_tracker" // #nosec G101 not a hardcoded credential + OpWeightAddInboundTracker = "op_weight_msg_add_inbound_tracker" // #nosec G101 not a hardcoded credential + OpWeightRemoveOutboundTracker = "op_weight_msg_remove_outbound_tracker" // #nosec G101 not a hardcoded credential + OpWeightVoteGasPrice = "op_weight_msg_vote_gas_price" // #nosec G101 not a hardcoded credential + OpWeightVoteOutbound = "op_weight_msg_vote_outbound" // #nosec G101 not a hardcoded credential + OpWeightVoteInbound = "op_weight_msg_vote_inbound" // #nosec G101 not a hardcoded credential + OpWeightWhitelistERC20 = "op_weight_msg_whitelist_erc20" // #nosec G101 not a hardcoded credential + OpWeightMigrateTssFunds = "op_weight_msg_migrate_tss_funds" // #nosec G101 not a hardcoded credential + OpWeightUpdateTssAddress = "op_weight_msg_update_tss_address" // #nosec G101 not a hardcoded credential + OpWeightAbortStuckCCTX = "op_weight_msg_abort_stuck_cctx" // #nosec G101 not a hardcoded credential + OpWeightUpdateRateLimiterFlags = "op_weight_msg_update_rate_limiter_flags" // #nosec G101 not a hardcoded credential + OpWeightRefundAbortedCCTX = "op_weight_msg_refund_aborted_cctx" // #nosec G101 not a hardcoded credential + OppWeightUpdateERC20CustodyPauseStatus = "op_weight_msg_update_erc20_custody_pause_status" // #nosec G101 not a hardcoded credential ) func WeightedOperations( appParams simtypes.AppParams, cdc codec.JSONCodec, k keeper.Keeper) simulation.WeightedOperations { var ( - weightAddOutboundTracker int - weightAddInboundTracker int - weightRemoveOutboundTracker int - weightVoteGasPrice int - weightVoteOutbound int - weightVoteInbound int - weightWhitelistERC20 int - weightMigrateTssFunds int - weightUpdateTssAddress int - weightAbortStuckCCTX int - weightUpdateRateLimiterFlags int - weightRefundAbortedCCTX int + weightAddOutboundTracker int + weightAddInboundTracker int + weightRemoveOutboundTracker int + weightVoteGasPrice int + weightVoteOutbound int + weightVoteInbound int + weightWhitelistERC20 int + weightMigrateTssFunds int + weightUpdateTssAddress int + weightAbortStuckCCTX int + weightUpdateRateLimiterFlags int + weightRefundAbortedCCTX int + weightUpdateERC20CustodyPauseStatus int ) appParams.GetOrGenerate(cdc, OpWeightMsgAddOutboundTracker, &weightAddOutboundTracker, nil, @@ -139,6 +142,12 @@ func WeightedOperations( }, ) + appParams.GetOrGenerate(cdc, OppWeightUpdateERC20CustodyPauseStatus, &weightUpdateERC20CustodyPauseStatus, nil, + func(_ *rand.Rand) { + weightUpdateERC20CustodyPauseStatus = DefaultWeightUpdateERC20CustodyPauseStatus + }, + ) + return simulation.WeightedOperations{ simulation.NewWeightedOperation( weightVoteGasPrice, @@ -180,6 +189,10 @@ func WeightedOperations( weightUpdateRateLimiterFlags, SimulateMsgUpdateRateLimiterFlags(k), ), + simulation.NewWeightedOperation( + weightUpdateERC20CustodyPauseStatus, + SimulateUpdateERC20CustodyPauseStatus(k), + ), } }