From 85005b5bc260f1544480bb165b43ef032613122d Mon Sep 17 00:00:00 2001 From: Dzmitry Hil Date: Thu, 7 Nov 2024 15:57:36 +0300 Subject: [PATCH] Decrease the gas required for the module's integration tests to pass. * Update funding balances * Move heavy integration tests to stress tests --- .../modules/assetft_extension_test.go | 44 ++-- integration-tests/modules/assetft_test.go | 116 +++++---- integration-tests/modules/bank_test.go | 195 --------------- .../modules/distribution_test.go | 207 ---------------- integration-tests/modules/group_test.go | 2 +- integration-tests/modules/wasm_test.go | 139 +++++------ integration-tests/stress/bank_test.go | 212 +++++++++++++++++ .../{modules => stress}/crisis_test.go | 2 +- integration-tests/stress/distribution_test.go | 224 ++++++++++++++++++ .../gas_estimation_test.go | 16 +- 10 files changed, 606 insertions(+), 551 deletions(-) create mode 100644 integration-tests/stress/bank_test.go rename integration-tests/{modules => stress}/crisis_test.go (98%) create mode 100644 integration-tests/stress/distribution_test.go rename integration-tests/{modules => stress}/gas_estimation_test.go (93%) diff --git a/integration-tests/modules/assetft_extension_test.go b/integration-tests/modules/assetft_extension_test.go index 948e5b3c7..bfb0e2c8a 100644 --- a/integration-tests/modules/assetft_extension_test.go +++ b/integration-tests/modules/assetft_extension_test.go @@ -811,9 +811,9 @@ func TestAssetFTExtensionMint(t *testing.T) { Amount: sdkmath.NewInt(1 * 500_000), // add 500k for each message with extenstion transfer }) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(admin, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, admin, integration.BalancesOptions{ + Amount: sdkmath.NewInt(1_000_000), + }) codeID, err := chain.Wasm.DeployWASMContract( ctx, chain.TxFactoryAuto(), issuer, testcontracts.AssetExtensionWasm, @@ -1006,11 +1006,12 @@ func TestAssetFTExtensionSendingToSmartContractIsDenied(t *testing.T) { ctx, chain := integrationtests.NewCoreumTestingContext(t) issuer := chain.GenAccount() - requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(issuer, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + + chain.FundAccountWithOptions(ctx, t, issuer, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(1_000_000)), + }) clientCtx := chain.ClientContext @@ -1046,7 +1047,6 @@ func TestAssetFTExtensionSendingToSmartContractIsDenied(t *testing.T) { chain.TxFactoryAuto(), issueMsg, ) - requireT.NoError(err) denom := assetfttypes.BuildDenom(issueMsg.Subunit, issuer) @@ -1115,9 +1115,10 @@ func TestAssetFTExtensionAttachingToSmartContractCallIsDenied(t *testing.T) { issuer := chain.GenAccount() requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(issuer, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, issuer, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(1_000_000)), + }) codeID, err := chain.Wasm.DeployWASMContract( ctx, chain.TxFactoryAuto(), issuer, testcontracts.AssetExtensionWasm, @@ -1195,9 +1196,10 @@ func TestAssetFTExtensionIssuingSmartContractIsAllowedToSendAndReceive(t *testin recipient := chain.GenAccount() requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(admin, chain.NewCoin(sdkmath.NewInt(50000000000))), - ) + chain.FundAccountWithOptions(ctx, t, admin, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount.MulRaw(2). + Add(sdkmath.NewInt(1_000_000)), + }) chain.FundAccountWithOptions(ctx, t, recipient, integration.BalancesOptions{ Amount: sdkmath.NewInt(500_000), }) @@ -1308,9 +1310,10 @@ func TestAssetFTExtensionAttachingToSmartContractInstantiationIsDenied(t *testin issuer := chain.GenAccount() requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(issuer, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, issuer, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(1_000_000)), + }) codeID, err := chain.Wasm.DeployWASMContract( ctx, chain.TxFactory().WithSimulateAndExecute(true), issuer, testcontracts.AssetExtensionWasm, @@ -1384,9 +1387,10 @@ func TestAssetFTExtensionMintingAndSendingOnBehalfOfIssuingSmartContractIsPossib recipient := chain.GenAccount() requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(admin, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, admin, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(1_000_000)), + }) codeID, err := chain.Wasm.DeployWASMContract( ctx, chain.TxFactoryAuto(), admin, testcontracts.AssetExtensionWasm, diff --git a/integration-tests/modules/assetft_test.go b/integration-tests/modules/assetft_test.go index f83a5a04f..77cac0e3c 100644 --- a/integration-tests/modules/assetft_test.go +++ b/integration-tests/modules/assetft_test.go @@ -1146,9 +1146,10 @@ func TestAssetFTMint(t *testing.T) { }, }) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(admin, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, admin, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(1_000_000)), + }) // Issue an unmintable fungible token issueMsg := &assetfttypes.MsgIssue{ @@ -1813,9 +1814,10 @@ func TestAssetFTFeesAreChargedWhenSmartContractExecutesAuthZTransfer(t *testing. granter := chain.GenAccount() receiver := chain.GenAccount() - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(issuer, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, issuer, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(1_000_000)), + }) chain.FundAccountWithOptions(ctx, t, granter, integration.BalancesOptions{ Messages: []sdk.Msg{ &authztypes.MsgGrant{}, @@ -1991,9 +1993,10 @@ func TestAssetFTFeesAreNotChargedWhenTokensAreTransferredFromSmartContractUsingA grantee := chain.GenAccount() receiver := chain.GenAccount() - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(issuer, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, issuer, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(1_000_000)), + }) // Issue a fungible token issueMsg := &assetfttypes.MsgIssue{ @@ -2705,9 +2708,10 @@ func TestAssetFTClawbackSmartContract(t *testing.T) { issuer := chain.GenAccount() requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(issuer, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, issuer, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(1_000_000)), + }) clientCtx := chain.ClientContext @@ -3795,9 +3799,10 @@ func TestAssetFTSendingToNonWhitelistedSmartContractIsDenied(t *testing.T) { issuer := chain.GenAccount() requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(issuer, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, issuer, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(1_000_000)), + }) clientCtx := chain.ClientContext @@ -3869,9 +3874,10 @@ func TestAssetFTAttachingToNonWhitelistedSmartContractCallIsDenied(t *testing.T) issuer := chain.GenAccount() requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(issuer, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, issuer, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(1_000_000)), + }) txf := chain.TxFactoryAuto() @@ -3935,9 +3941,10 @@ func TestAssetFTAttachingToNonWhitelistedSmartContractInstantiationIsDenied(t *t issuer := chain.GenAccount() requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(issuer, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, issuer, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(1_000_000)), + }) txf := chain.TxFactoryAuto() @@ -5455,11 +5462,16 @@ func TestAssetFTSendCommissionAndBurnRateWithSmartContract(t *testing.T) { issuer := chain.GenAccount() admin := chain.GenAccount() + chain.FundAccountWithOptions(ctx, t, issuer, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(1_000_000)), + }) + chain.FundAccountWithOptions(ctx, t, admin, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(1_000_000)), + }) + requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(issuer, chain.NewCoin(sdkmath.NewInt(5000000000))), - integration.NewFundedAccount(admin, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) clientCtx := chain.ClientContext txf := chain.TxFactoryAuto() @@ -5673,7 +5685,10 @@ func TestAssetFTSendCommissionAndBurnRateWithSmartContractInstantiation(t *testi recipient := chain.GenAccount() requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, integration.NewFundedAccount(issuer, chain.NewCoin(sdkmath.NewInt(5000000000)))) + chain.FundAccountWithOptions(ctx, t, issuer, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(1_000_000)), + }) clientCtx := chain.ClientContext txf := chain.TxFactoryAuto() @@ -5735,9 +5750,10 @@ func TestAssetFTSendingToSmartContractIsDenied(t *testing.T) { issuer := chain.GenAccount() requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(issuer, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, issuer, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(1_000_000)), + }) clientCtx := chain.ClientContext @@ -5831,9 +5847,10 @@ func TestAssetFTAttachingToSmartContractCallIsDenied(t *testing.T) { issuer := chain.GenAccount() requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(issuer, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, issuer, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(1_000_000)), + }) txf := chain.TxFactoryAuto() @@ -5897,9 +5914,10 @@ func TestAssetFTAttachingToSmartContractInstantiationIsDenied(t *testing.T) { issuer := chain.GenAccount() requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(issuer, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, issuer, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(1_000_000)), + }) txf := chain.TxFactoryAuto() @@ -5960,9 +5978,10 @@ func TestAssetFTIssuingSmartContractIsAllowedToSendAndReceive(t *testing.T) { recipient := chain.GenAccount() requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(admin, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, admin, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(1_000_000)), + }) chain.FundAccountWithOptions(ctx, t, recipient, integration.BalancesOptions{ Messages: []sdk.Msg{ &banktypes.MsgSend{}, @@ -6060,9 +6079,10 @@ func TestAssetFTMintingAndSendingOnBehalfOfIssuingSmartContractIsPossibleEvenIfS recipient := chain.GenAccount() requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(admin, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, admin, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(1_000_000)), + }) // instantiate new contract initialPayload, err := json.Marshal(struct{}{}) @@ -6208,9 +6228,10 @@ func TestAssetFTSendingTokensFromRegularAccountBySmartContractUsingAuthZIsDenied }, Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount, }) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(admin, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, admin, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(1_000_000)), + }) // issue token issueMsg := &assetfttypes.MsgIssue{ @@ -6574,9 +6595,10 @@ func TestAssetFTTransferAdminMint(t *testing.T) { }, }) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(wasmAdmin, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, wasmAdmin, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(1_000_000)), + }) // Issue an unmintable fungible token issueMsg := &assetfttypes.MsgIssue{ diff --git a/integration-tests/modules/bank_test.go b/integration-tests/modules/bank_test.go index f7b78a4cd..b1848c9ba 100644 --- a/integration-tests/modules/bank_test.go +++ b/integration-tests/modules/bank_test.go @@ -3,14 +3,11 @@ package modules import ( - "context" "fmt" "strings" "testing" - "time" sdkmath "cosmossdk.io/math" - "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" sdk "github.com/cosmos/cosmos-sdk/types" cosmoserrors "github.com/cosmos/cosmos-sdk/types/errors" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" @@ -27,179 +24,6 @@ import ( var maxMemo = strings.Repeat("-", 256) // cosmos sdk is configured to accept maximum memo of 256 characters by default -// TestBankMultiSendBatchOutputs tests MultiSend message with maximum amount of addresses. -func TestBankMultiSendBatchOutputs(t *testing.T) { - t.Parallel() - - ctx, chain := integrationtests.NewCoreumTestingContext(t) - - issuer := chain.GenAccount() - requireT := require.New(t) - - issueMsg := &assetfttypes.MsgIssue{ - Issuer: issuer.String(), - Symbol: "TOK1", - Subunit: "tok1", - Precision: 1, - Description: "TOK1 Description", - InitialAmount: sdkmath.NewInt(100_000_000_000_000_000), - Features: []assetfttypes.Feature{ - assetfttypes.Feature_freezing, // enable the feature to make the computation more complicated - }, - } - - numAccountsToFund := 20 // 1700 was the max accepted - iterationsToFund := 2 - - inputItem := banktypes.Input{ - Address: issuer.String(), - Coins: sdk.NewCoins(), - } - denom := assetfttypes.BuildDenom(issueMsg.Subunit, issuer) - outputItems := make([]banktypes.Output, 0, numAccountsToFund) - fundedAccounts := make([]sdk.AccAddress, 0, numAccountsToFund) - coinToFund := sdk.NewCoin(denom, sdkmath.NewInt(10_000_000_000)) - - for i := 0; i < numAccountsToFund; i++ { - inputItem.Coins = inputItem.Coins.Add(coinToFund) - recipient := sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address()) - fundedAccounts = append(fundedAccounts, recipient) - outputItems = append(outputItems, banktypes.Output{ - Address: recipient.String(), - Coins: sdk.NewCoins(coinToFund), - }) - } - // prepare MultiSend messages - multiSendMsgs := make([]sdk.Msg, 0, iterationsToFund) - for i := 0; i < iterationsToFund; i++ { - multiSendMsgs = append(multiSendMsgs, &banktypes.MsgMultiSend{ - Inputs: []banktypes.Input{ - inputItem, - }, - Outputs: outputItems, - }) - } - - chain.FundAccountWithOptions(ctx, t, issuer, integration.BalancesOptions{ - Messages: append([]sdk.Msg{issueMsg}, multiSendMsgs...), - NondeterministicMessagesGas: 50_000_000, // to cover extra bytes because of the message size - Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount, - }) - - // issue fungible tokens - _, err := client.BroadcastTx( - ctx, - chain.ClientContext.WithFromAddress(issuer), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(issueMsg)), - issueMsg, - ) - requireT.NoError(err) - - // send coins in loop - start := time.Now() - for _, msg := range multiSendMsgs { - res, err := client.BroadcastTx( - ctx, - chain.ClientContext.WithFromAddress(issuer), - // we estimate here since the th size is grater then allowed for the deterministic fee - chain.TxFactoryAuto(), - msg, - ) - requireT.NoError(err) - t.Logf("Successfully sent batch MultiSend tx, hash: %s, gasUse:%d", res.TxHash, res.GasUsed) - } - t.Logf("It takes %s to fund %d accounts with MultiSend", time.Since(start), numAccountsToFund*iterationsToFund) - - assertBatchAccounts( - ctx, - chain, - sdk.NewCoins(sdk.NewCoin(coinToFund.Denom, coinToFund.Amount.MulRaw(int64(iterationsToFund)))), - fundedAccounts, - denom, - requireT, - ) -} - -// TestBankSendBatchMsgs tests BankSend message with maximum amount of accounts. -func TestBankSendBatchMsgs(t *testing.T) { - t.Parallel() - - ctx, chain := integrationtests.NewCoreumTestingContext(t) - - issuer := chain.GenAccount() - requireT := require.New(t) - - issueMsg := &assetfttypes.MsgIssue{ - Issuer: issuer.String(), - Symbol: "TOK1", - Subunit: "tok1", - Precision: 1, - Description: "TOK1 Description", - InitialAmount: sdkmath.NewInt(100_000_000_000_000_000), - Features: []assetfttypes.Feature{ - assetfttypes.Feature_freezing, // enable the feature to make the computation more complicated - }, - } - - numAccountsToFund := 20 // 600 was the max accepted - iterationsToFund := 3 - - denom := assetfttypes.BuildDenom(issueMsg.Subunit, issuer) - bankSendSendMsgs := make([]sdk.Msg, 0, numAccountsToFund) - coinToFund := sdk.NewCoin(denom, sdkmath.NewInt(10_000_000_000)) - fundedAccounts := make([]sdk.AccAddress, 0, numAccountsToFund) - for i := 0; i < numAccountsToFund; i++ { - recipient := sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address()) - fundedAccounts = append(fundedAccounts, recipient) - bankSendSendMsgs = append(bankSendSendMsgs, &banktypes.MsgSend{ - FromAddress: issuer.String(), - ToAddress: recipient.String(), - Amount: sdk.NewCoins(coinToFund), - }) - } - - fundMsgs := make([]sdk.Msg, 0) - fundMsgs = append(fundMsgs, issueMsg) - for i := 0; i < iterationsToFund; i++ { - fundMsgs = append(fundMsgs, bankSendSendMsgs...) - } - chain.FundAccountWithOptions(ctx, t, issuer, integration.BalancesOptions{ - Messages: fundMsgs, - Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount, - }) - - // issue fungible tokens - _, err := client.BroadcastTx( - ctx, - chain.ClientContext.WithFromAddress(issuer), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(issueMsg)), - issueMsg, - ) - requireT.NoError(err) - - // send coins in loop - start := time.Now() - for i := 0; i < iterationsToFund; i++ { - res, err := client.BroadcastTx( - ctx, - chain.ClientContext.WithFromAddress(issuer), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(bankSendSendMsgs...)), - bankSendSendMsgs...) - requireT.NoError(err) - t.Logf("Successfully sent batch BankSend tx, hash: %s, gasUsed:%d", res.TxHash, res.GasUsed) - } - t.Logf("It takes %s to fund %d accounts with BankSend", time.Since(start), numAccountsToFund*iterationsToFund) - - assertBatchAccounts( - ctx, - chain, - sdk.NewCoins(sdk.NewCoin(coinToFund.Denom, coinToFund.Amount.MulRaw(int64(iterationsToFund)))), - fundedAccounts, - denom, - requireT, - ) -} - // TestBankSendDeterministicGas checks that transfer takes the deterministic amount of gas. func TestBankSendDeterministicGas(t *testing.T) { t.Parallel() @@ -840,22 +664,3 @@ func TestBankCoreSend(t *testing.T) { require.Error(t, err) require.ErrorContains(t, err, "insufficient funds") } - -func assertBatchAccounts( - ctx context.Context, - chain integration.CoreumChain, - expectedCoins sdk.Coins, - fundedAccounts []sdk.AccAddress, - denom string, - requireT *require.Assertions, -) { - bankClient := banktypes.NewQueryClient(chain.ClientContext) - for _, acc := range fundedAccounts { - res, err := bankClient.Balance(ctx, &banktypes.QueryBalanceRequest{ - Address: acc.String(), - Denom: denom, - }) - requireT.NoError(err) - requireT.Equal(expectedCoins.String(), res.Balance.String()) - } -} diff --git a/integration-tests/modules/distribution_test.go b/integration-tests/modules/distribution_test.go index 7620c0420..2bcc5e736 100644 --- a/integration-tests/modules/distribution_test.go +++ b/integration-tests/modules/distribution_test.go @@ -13,13 +13,11 @@ import ( distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" integrationtests "github.com/CoreumFoundation/coreum/v5/integration-tests" "github.com/CoreumFoundation/coreum/v5/pkg/client" "github.com/CoreumFoundation/coreum/v5/testutil/integration" - customparamstypes "github.com/CoreumFoundation/coreum/v5/x/customparams/types" ) // TestDistributionSpendCommunityPoolProposal checks that FundCommunityPool and SpendCommunityPoolProposal @@ -128,211 +126,6 @@ func TestDistributionSpendCommunityPoolProposal(t *testing.T) { requireT.Equal(sdk.NewCoins(poolCoin), communityPoolRecipientBalancesRes.Balances) } -// TestDistributionWithdrawRewardWithDeterministicGas checks that withdraw reward works correctly and -// gas is deterministic. -func TestDistributionWithdrawRewardWithDeterministicGas(t *testing.T) { - t.Parallel() - - ctx, chain := integrationtests.NewCoreumTestingContext(t) - - delegator := chain.GenAccount() - delegatorRewardRecipient := chain.GenAccount() - - bankClient := banktypes.NewQueryClient(chain.ClientContext) - customParamsClient := customparamstypes.NewQueryClient(chain.ClientContext) - - requireT := require.New(t) - // the amount of the delegation should be big enough to get at least some reward for the few blocks - amountToDelegate := sdkmath.NewInt(1_000_000_000) - chain.FundAccountWithOptions(ctx, t, delegator, integration.BalancesOptions{ - Messages: []sdk.Msg{ - &stakingtypes.MsgDelegate{}, - &distributiontypes.MsgDepositValidatorRewardsPool{}, - &distributiontypes.MsgWithdrawDelegatorReward{}, - &distributiontypes.MsgSetWithdrawAddress{}, - &distributiontypes.MsgWithdrawDelegatorReward{}, - }, - Amount: amountToDelegate.Add(sdkmath.NewInt(1_000)), - }) - - delegatedCoin := chain.NewCoin(amountToDelegate) - - // *** Create new validator to use it in the test and capture all required balances. *** - customStakingParams, err := customParamsClient.StakingParams(ctx, &customparamstypes.QueryStakingParamsRequest{}) - require.NoError(t, err) - // we multiply not to conflict with the tests which increases the min amount - validatorStakingAmount := customStakingParams.Params.MinSelfDelegation.Mul(sdkmath.NewInt(2)) - validatorStakerAddress, validatorAddress, deactivateValidator, err := chain.CreateValidator( - ctx, t, validatorStakingAmount, validatorStakingAmount, - ) - require.NoError(t, err) - defer deactivateValidator() - - // delegate coins - delegateMsg := &stakingtypes.MsgDelegate{ - DelegatorAddress: delegator.String(), - ValidatorAddress: validatorAddress.String(), - Amount: delegatedCoin, - } - - clientCtx := chain.ClientContext - - t.Log("Delegating some coins to validator to withdraw later") - _, err = client.BroadcastTx( - ctx, - clientCtx.WithFromAddress(delegator), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(delegateMsg)), - delegateMsg, - ) - requireT.NoError(err) - - // deposit in validator rewards pool - t.Log("Deposit some more amount in the validator rewards pool") - // withdraw the normal reward - depositValidatorRewardsPoolMsg := &distributiontypes.MsgDepositValidatorRewardsPool{ - Depositor: delegator.String(), - ValidatorAddress: validatorAddress.String(), - Amount: sdk.NewCoins(chain.NewCoin(sdkmath.NewInt(1000))), - } - txResult, err := client.BroadcastTx( - ctx, - clientCtx.WithFromAddress(delegator), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(depositValidatorRewardsPoolMsg)), - depositValidatorRewardsPoolMsg, - ) - requireT.NoError(err) - // validate the deterministic gas - requireT.Equal(chain.GasLimitByMsgs(depositValidatorRewardsPoolMsg), uint64(txResult.GasUsed)) - - // capture the normal staker balance - delegatorBalanceRes, err := bankClient.Balance(ctx, &banktypes.QueryBalanceRequest{ - Address: delegator.String(), - Denom: delegatedCoin.Denom, - }) - requireT.NoError(err) - delegatorBalanceBeforeWithdrawal := delegatorBalanceRes.Balance - - // capture validator staker balance - validatorStakerBalanceRes, err := bankClient.Balance(ctx, &banktypes.QueryBalanceRequest{ - Address: validatorStakerAddress.String(), - Denom: delegatedCoin.Denom, - }) - requireT.NoError(err) - validatorStakerBalanceBeforeWithdrawal := validatorStakerBalanceRes.Balance - - // await next 5 blocks - requireT.NoError(client.AwaitNextBlocks(ctx, clientCtx, 5)) - - // *** Withdraw and check the delegator reward. *** - - // normal delegator - t.Log("Withdrawing the delegator reward") - // withdraw the normal reward - withdrawRewardMsg := &distributiontypes.MsgWithdrawDelegatorReward{ - DelegatorAddress: delegator.String(), - ValidatorAddress: validatorAddress.String(), - } - txResult, err = client.BroadcastTx( - ctx, - clientCtx.WithFromAddress(delegator), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(withdrawRewardMsg)), - withdrawRewardMsg, - ) - requireT.NoError(err) - // validate the deterministic gas - requireT.Equal(chain.GasLimitByMsgs(withdrawRewardMsg), uint64(txResult.GasUsed)) - - delegatorBalanceRes, err = bankClient.Balance(ctx, &banktypes.QueryBalanceRequest{ - Address: delegator.String(), - Denom: delegatedCoin.Denom, - }) - requireT.NoError(err) - delegatorBalanceAfterWithdrawal := delegatorBalanceRes.Balance - - feeSpentOnWithdrawReward := chain.ComputeNeededBalanceFromOptions(integration.BalancesOptions{ - Messages: []sdk.Msg{withdrawRewardMsg}, - }) - - delegatorReward := delegatorBalanceAfterWithdrawal.Amount. - Sub(delegatorBalanceBeforeWithdrawal.Amount.Sub(feeSpentOnWithdrawReward)) - requireT.True(delegatorReward.IsPositive()) - t.Logf("Withdrawing of the delegator reward is done, amount:%s", delegatorReward.String()) - - // *** Change the reward owner and withdraw the delegator reward. *** - - // Change the reward owner and withdraw the reward - t.Log("Changing the reward recipient and windowing the reward") - // change withdraw address - setWithdrawAddressMsg := &distributiontypes.MsgSetWithdrawAddress{ - DelegatorAddress: delegator.String(), - WithdrawAddress: delegatorRewardRecipient.String(), - } - txResult, err = client.BroadcastTx( - ctx, - clientCtx.WithFromAddress(delegator), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(setWithdrawAddressMsg)), - setWithdrawAddressMsg, - ) - requireT.NoError(err) - // validate the deterministic gas - requireT.Equal(chain.GasLimitByMsgs(setWithdrawAddressMsg), uint64(txResult.GasUsed)) - // withdraw the reward second time - txResult, err = client.BroadcastTx( - ctx, - clientCtx.WithFromAddress(delegator), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(withdrawRewardMsg)), - withdrawRewardMsg, - ) - requireT.NoError(err) - // validate the deterministic gas - requireT.Equal(chain.GasLimitByMsgs(withdrawRewardMsg), uint64(txResult.GasUsed)) - delegatorRewardRecipientBalanceRes, err := bankClient.Balance(ctx, &banktypes.QueryBalanceRequest{ - Address: delegatorRewardRecipient.String(), - Denom: delegatedCoin.Denom, - }) - requireT.NoError(err) - requireT.True(delegatorRewardRecipientBalanceRes.Balance.IsPositive()) - - // *** Withdraw the validator commission. *** - - // validator commission - t.Log("Withdrawing the validator commission") - // withdraw the normal reward - withdrawCommissionMsg := &distributiontypes.MsgWithdrawValidatorCommission{ - ValidatorAddress: validatorAddress.String(), - } - - chain.FundAccountWithOptions(ctx, t, validatorStakerAddress, integration.BalancesOptions{ - Messages: []sdk.Msg{withdrawCommissionMsg}, - }) - - txResult, err = client.BroadcastTx( - ctx, - clientCtx.WithFromAddress(validatorStakerAddress), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(withdrawCommissionMsg)), - withdrawCommissionMsg, - ) - requireT.NoError(err) - // validate the deterministic gas - requireT.Equal(chain.GasLimitByMsgs(withdrawCommissionMsg), uint64(txResult.GasUsed)) - - validatorStakerBalanceRes, err = bankClient.Balance(ctx, &banktypes.QueryBalanceRequest{ - Address: validatorStakerAddress.String(), - Denom: delegatedCoin.Denom, - }) - requireT.NoError(err) - validatorStakerBalanceAfterWithdrawal := validatorStakerBalanceRes.Balance - - feeSpentOnWithdrawCommission := chain.ComputeNeededBalanceFromOptions(integration.BalancesOptions{ - Messages: []sdk.Msg{withdrawCommissionMsg}, - }) - - validatorStakerCommissionReward := validatorStakerBalanceAfterWithdrawal.Amount. - Sub(validatorStakerBalanceBeforeWithdrawal.Amount.Sub(feeSpentOnWithdrawCommission)) - requireT.True(validatorStakerCommissionReward.IsPositive()) - t.Logf("Withdrawing of the validator commission is done, amount:%s", validatorStakerCommissionReward.String()) -} - func getCommunityPoolCoin( ctx context.Context, requireT *require.Assertions, diff --git a/integration-tests/modules/group_test.go b/integration-tests/modules/group_test.go index 86e6a2c60..5493197d8 100644 --- a/integration-tests/modules/group_test.go +++ b/integration-tests/modules/group_test.go @@ -112,7 +112,7 @@ func TestGroupCreationAndBankSend(t *testing.T) { groupPolicy := groupPolicies.GroupPolicies[0] t.Logf("created group policy, groupPolicyAddress:%s txHash:%s", groupPolicy.Address, result.TxHash) - groupSendCoin := chain.NewCoin(sdkmath.NewInt(100_000_000)) + groupSendCoin := chain.NewCoin(sdkmath.NewInt(1_000_000)) chain.FundAccountWithOptions(ctx, t, sdk.MustAccAddressFromBech32(groupPolicy.Address), integration.BalancesOptions{ Messages: []sdk.Msg{}, Amount: groupSendCoin.Amount, diff --git a/integration-tests/modules/wasm_test.go b/integration-tests/modules/wasm_test.go index 276b48389..6a40f2efa 100644 --- a/integration-tests/modules/wasm_test.go +++ b/integration-tests/modules/wasm_test.go @@ -206,9 +206,9 @@ func TestContractInstantiation(t *testing.T) { admin := chain.GenAccount() requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(admin, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, admin, integration.BalancesOptions{ + Amount: sdkmath.NewInt(2_000_000), + }) txf := chain.TxFactoryAuto() @@ -317,9 +317,9 @@ func TestWASMBankSendContract(t *testing.T) { nativeDenom := chain.ChainSettings.Denom requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(admin, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, admin, integration.BalancesOptions{ + Amount: sdkmath.NewInt(1_000_000), + }) clientCtx := chain.ClientContext txf := chain.TxFactoryAuto() @@ -430,9 +430,9 @@ func TestWASMGasBankSendAndBankSend(t *testing.T) { requireT := require.New(t) admin := chain.GenAccount() - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(admin, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, admin, integration.BalancesOptions{ + Amount: sdkmath.NewInt(1_000_000), + }) // deployWASMContract and init contract with the initial coins amount clientCtx := chain.ClientContext @@ -497,12 +497,14 @@ func TestWASMPinningAndUnpinningSmartContractUsingGovernance(t *testing.T) { proposerBalance, err := chain.Governance.ComputeProposerBalance(ctx, false) requireT.NoError(err) proposerBalance.Amount = proposerBalance.Amount.MulRaw(2) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(admin, chain.NewCoin(sdkmath.NewInt(5000000000))), integration.NewFundedAccount(proposer, proposerBalance), ) + chain.FundAccountWithOptions(ctx, t, admin, integration.BalancesOptions{ + Amount: sdkmath.NewInt(1_000_000), + }) + // instantiateWASMContract the contract and set the initial counter state. initialPayload, err := json.Marshal(moduleswasm.SimpleState{ Count: 1337, @@ -635,10 +637,12 @@ func TestWASMContractUpgrade(t *testing.T) { wasmClient := wasmtypes.NewQueryClient(chain.ClientContext) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(admin, chain.NewCoin(sdkmath.NewInt(5000000))), - integration.NewFundedAccount(noneAdmin, chain.NewCoin(sdkmath.NewInt(5000000))), - ) + chain.FundAccountWithOptions(ctx, t, admin, integration.BalancesOptions{ + Amount: sdkmath.NewInt(1_000_000), + }) + chain.FundAccountWithOptions(ctx, t, noneAdmin, integration.BalancesOptions{ + Amount: sdkmath.NewInt(500_000), + }) // instantiateWASMContract the contract and set the initial counter state. initialPayload, err := json.Marshal(moduleswasm.SimpleState{ @@ -717,9 +721,9 @@ func TestUpdateAndClearAdminOfContract(t *testing.T) { newAdmin := chain.GenAccount() requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(admin, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, admin, integration.BalancesOptions{ + Amount: sdkmath.NewInt(1_000_000), + }) chain.FundAccountWithOptions(ctx, t, newAdmin, integration.BalancesOptions{ Messages: []sdk.Msg{ &wasmtypes.MsgClearAdmin{}, @@ -814,9 +818,9 @@ func TestWASMAuthzContract(t *testing.T) { totalAmountToSend := sdkmath.NewInt(2_000) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(granter, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, granter, integration.BalancesOptions{ + Amount: sdkmath.NewInt(2_000_000), + }) // deployWASMContract and init contract with the granter. initialPayloadAuthzTransfer, err := json.Marshal(authz{ @@ -994,9 +998,10 @@ func TestWASMAuthzContract(t *testing.T) { // Issue an AssetFT that will be used to buy the NFT - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(receiver, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, receiver, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(500_000)), + }) issueAssetFTMsg := &assetfttypes.MsgIssue{ Issuer: receiver.String(), @@ -1119,9 +1124,10 @@ func TestWASMFungibleTokenInContract(t *testing.T) { recipient2 := chain.GenAccount() requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(admin, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, admin, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(4_000_000)), + }) clientCtx := chain.ClientContext txf := chain.TxFactoryAuto() @@ -1506,9 +1512,10 @@ func TestWASMFungibleTokenInContractLegacy(t *testing.T) { recipient2 := chain.GenAccount() requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(admin, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, admin, integration.BalancesOptions{ + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(1_000_000)), + }) clientCtx := chain.ClientContext txf := chain.TxFactoryAuto() @@ -1929,9 +1936,9 @@ func TestWASMNonFungibleTokenInContract(t *testing.T) { mintRecipient := chain.GenAccount() requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(admin, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, admin, integration.BalancesOptions{ + Amount: sdkmath.NewInt(4_000_000), + }) clientCtx := chain.ClientContext txf := chain.TxFactoryAuto() @@ -2517,9 +2524,9 @@ func TestWASMNonFungibleTokenInContractLegacy(t *testing.T) { mintRecipient := chain.GenAccount() requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(admin, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, admin, integration.BalancesOptions{ + Amount: sdkmath.NewInt(4_000_000), + }) clientCtx := chain.ClientContext txf := chain.TxFactoryAuto() @@ -3370,11 +3377,11 @@ func TestWASMContractInstantiationIsNotRejectedIfAccountExists(t *testing.T) { requireT := require.New(t) ctx, chain := integrationtests.NewCoreumTestingContext(t) - fundAmount := chain.NewCoin(sdkmath.NewInt(5000000000)) + adminAccount := chain.GenAccount() - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(adminAccount, fundAmount), - ) + chain.FundAccountWithOptions(ctx, t, adminAccount, integration.BalancesOptions{ + Amount: sdkmath.NewInt(1_000_000), + }) // Deploy smart contract. @@ -3441,9 +3448,9 @@ func TestWASMContractInstantiationIsNotRejectedIfAccountExists(t *testing.T) { requireT := require.New(t) adminAccount := chain.GenAccount() - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(adminAccount, fundAmount), - ) + chain.FundAccountWithOptions(ctx, t, adminAccount, integration.BalancesOptions{ + Amount: sdkmath.NewInt(1_000_000), + }) salt, err := chain.Wasm.GenerateSalt() requireT.NoError(err) @@ -3491,9 +3498,9 @@ func TestVestingToWASMContract(t *testing.T) { amount := chain.NewCoin(sdkmath.NewInt(500)) requireT := require.New(t) - chain.Faucet.FundAccounts(ctx, t, - integration.NewFundedAccount(admin, chain.NewCoin(sdkmath.NewInt(5000000000))), - ) + chain.FundAccountWithOptions(ctx, t, admin, integration.BalancesOptions{ + Amount: sdkmath.NewInt(1_000_000), + }) txf := chain.TxFactoryAuto() @@ -3619,7 +3626,8 @@ func TestWASMDEXInContract(t *testing.T) { Messages: []sdk.Msg{ &banktypes.MsgSend{}, }, - Amount: sdkmath.NewInt(5_000_000_000), + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdkmath.NewInt(1_000_000)), }) clientCtx := chain.ClientContext @@ -3628,6 +3636,8 @@ func TestWASMDEXInContract(t *testing.T) { assetftClient := assetfttypes.NewQueryClient(clientCtx) tmQueryClient := cmtservice.NewServiceClient(chain.ClientContext) + dexParms := chain.QueryDEXParams(ctx, t) + chain.FundAccountWithOptions(ctx, t, issuer, integration.BalancesOptions{ Messages: []sdk.Msg{ &assetfttypes.MsgIssue{}, @@ -3704,28 +3714,12 @@ func TestWASMDEXInContract(t *testing.T) { denom2 := assetfttypes.BuildDenom(issuanceReq.Subunit, sdk.MustAccAddressFromBech32(contractAddr)) - // send some coins to the contract to cover needed fees - sendMsg := &banktypes.MsgSend{ - FromAddress: admin.String(), - ToAddress: contractAddr, - Amount: sdk.NewCoins(chain.NewCoin(sdkmath.NewInt(10_000_000))), - } - - _, err = client.BroadcastTx( - ctx, - chain.ClientContext.WithFromAddress(admin), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(sendMsg)), - sendMsg, - ) - requireT.NoError(err) - // send some denom1 coin to the contract - sendMsg = &banktypes.MsgSend{ + sendMsg := &banktypes.MsgSend{ FromAddress: issuer.String(), ToAddress: contractAddr, Amount: sdk.NewCoins(sdk.NewCoin(denom1, sdkmath.NewInt(10_000_000))), } - _, err = client.BroadcastTx( ctx, chain.ClientContext.WithFromAddress(issuer), @@ -3739,14 +3733,11 @@ func TestWASMDEXInContract(t *testing.T) { Denom: denom1, }) requireT.NoError(err) - requireT.Equal("10000000", balanceRes.Balance.Amount.String()) + requireT.Equal(sendMsg.Amount.AmountOf(denom1).String(), balanceRes.Balance.Amount.String()) - balanceRes, err = bankClient.Balance(ctx, &banktypes.QueryBalanceRequest{ - Address: contractAddr, - Denom: denom2, + chain.FundAccountWithOptions(ctx, t, sdk.MustAccAddressFromBech32(contractAddr), integration.BalancesOptions{ + Amount: dexParms.OrderReserve.Amount, }) - requireT.NoError(err) - requireT.Equal("10000000", balanceRes.Balance.Amount.String()) blockRes, err := tmQueryClient.GetLatestBlock(ctx, &cmtservice.GetLatestBlockRequest{}) requireT.NoError(err) @@ -3762,13 +3753,13 @@ func TestWASMDEXInContract(t *testing.T) { var wasmParamsRes dextypes.QueryParamsResponse requireT.NoError(json.Unmarshal(queryOut, &wasmParamsRes)) requireT.Equal( - chain.QueryDEXParams(ctx, t).OrderReserve.String(), wasmParamsRes.Params.OrderReserve.String(), + dexParms.OrderReserve.Amount.String(), wasmParamsRes.Params.OrderReserve.Amount.String(), ) requireT.Equal( - chain.QueryDEXParams(ctx, t).MaxOrdersPerDenom, wasmParamsRes.Params.MaxOrdersPerDenom, + dexParms.MaxOrdersPerDenom, wasmParamsRes.Params.MaxOrdersPerDenom, ) requireT.Equal( - chain.QueryDEXParams(ctx, t).PriceTickExponent, wasmParamsRes.Params.PriceTickExponent, + dexParms.PriceTickExponent, wasmParamsRes.Params.PriceTickExponent, ) // ********** Place Order ********** @@ -3824,7 +3815,7 @@ func TestWASMDEXInContract(t *testing.T) { TimeInForce: dextypes.TIME_IN_FORCE_GTC, RemainingQuantity: orderQuantity, RemainingBalance: orderQuantity, - Reserve: chain.QueryDEXParams(ctx, t).OrderReserve, + Reserve: dexParms.OrderReserve, } orderPayload, err := json.Marshal(map[dexMethod]OrderBodyDEXRequest{ diff --git a/integration-tests/stress/bank_test.go b/integration-tests/stress/bank_test.go new file mode 100644 index 000000000..8b7550098 --- /dev/null +++ b/integration-tests/stress/bank_test.go @@ -0,0 +1,212 @@ +//go:build integrationtests + +package stress + +import ( + "context" + "testing" + "time" + + sdkmath "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/stretchr/testify/require" + + integrationtests "github.com/CoreumFoundation/coreum/v5/integration-tests" + "github.com/CoreumFoundation/coreum/v5/pkg/client" + "github.com/CoreumFoundation/coreum/v5/testutil/integration" + assetfttypes "github.com/CoreumFoundation/coreum/v5/x/asset/ft/types" +) + +// TestBankMultiSendBatchOutputs tests MultiSend message with maximum amount of addresses. +func TestBankMultiSendBatchOutputs(t *testing.T) { + t.Parallel() + + ctx, chain := integrationtests.NewCoreumTestingContext(t) + + issuer := chain.GenAccount() + requireT := require.New(t) + + issueMsg := &assetfttypes.MsgIssue{ + Issuer: issuer.String(), + Symbol: "TOK1", + Subunit: "tok1", + Precision: 1, + Description: "TOK1 Description", + InitialAmount: sdkmath.NewInt(100_000_000_000_000_000), + Features: []assetfttypes.Feature{ + assetfttypes.Feature_freezing, // enable the feature to make the computation more complicated + }, + } + + numAccountsToFund := 20 // 1700 was the max accepted + iterationsToFund := 2 + + inputItem := banktypes.Input{ + Address: issuer.String(), + Coins: sdk.NewCoins(), + } + denom := assetfttypes.BuildDenom(issueMsg.Subunit, issuer) + outputItems := make([]banktypes.Output, 0, numAccountsToFund) + fundedAccounts := make([]sdk.AccAddress, 0, numAccountsToFund) + coinToFund := sdk.NewCoin(denom, sdkmath.NewInt(10_000_000_000)) + + for i := 0; i < numAccountsToFund; i++ { + inputItem.Coins = inputItem.Coins.Add(coinToFund) + recipient := sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address()) + fundedAccounts = append(fundedAccounts, recipient) + outputItems = append(outputItems, banktypes.Output{ + Address: recipient.String(), + Coins: sdk.NewCoins(coinToFund), + }) + } + // prepare MultiSend messages + multiSendMsgs := make([]sdk.Msg, 0, iterationsToFund) + for i := 0; i < iterationsToFund; i++ { + multiSendMsgs = append(multiSendMsgs, &banktypes.MsgMultiSend{ + Inputs: []banktypes.Input{ + inputItem, + }, + Outputs: outputItems, + }) + } + + chain.FundAccountWithOptions(ctx, t, issuer, integration.BalancesOptions{ + Messages: append([]sdk.Msg{issueMsg}, multiSendMsgs...), + NondeterministicMessagesGas: 50_000_000, // to cover extra bytes because of the message size + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount, + }) + + // issue fungible tokens + _, err := client.BroadcastTx( + ctx, + chain.ClientContext.WithFromAddress(issuer), + chain.TxFactory().WithGas(chain.GasLimitByMsgs(issueMsg)), + issueMsg, + ) + requireT.NoError(err) + + // send coins in loop + start := time.Now() + for _, msg := range multiSendMsgs { + res, err := client.BroadcastTx( + ctx, + chain.ClientContext.WithFromAddress(issuer), + // we estimate here since the th size is grater then allowed for the deterministic fee + chain.TxFactoryAuto(), + msg, + ) + requireT.NoError(err) + t.Logf("Successfully sent batch MultiSend tx, hash: %s, gasUse:%d", res.TxHash, res.GasUsed) + } + t.Logf("It takes %s to fund %d accounts with MultiSend", time.Since(start), numAccountsToFund*iterationsToFund) + + assertBatchAccounts( + ctx, + chain, + sdk.NewCoins(sdk.NewCoin(coinToFund.Denom, coinToFund.Amount.MulRaw(int64(iterationsToFund)))), + fundedAccounts, + denom, + requireT, + ) +} + +// TestBankSendBatchMsgs tests BankSend message with maximum amount of accounts. +func TestBankSendBatchMsgs(t *testing.T) { + t.Parallel() + + ctx, chain := integrationtests.NewCoreumTestingContext(t) + + issuer := chain.GenAccount() + requireT := require.New(t) + + issueMsg := &assetfttypes.MsgIssue{ + Issuer: issuer.String(), + Symbol: "TOK1", + Subunit: "tok1", + Precision: 1, + Description: "TOK1 Description", + InitialAmount: sdkmath.NewInt(100_000_000_000_000_000), + Features: []assetfttypes.Feature{ + assetfttypes.Feature_freezing, // enable the feature to make the computation more complicated + }, + } + + numAccountsToFund := 20 // 600 was the max accepted + iterationsToFund := 3 + + denom := assetfttypes.BuildDenom(issueMsg.Subunit, issuer) + bankSendSendMsgs := make([]sdk.Msg, 0, numAccountsToFund) + coinToFund := sdk.NewCoin(denom, sdkmath.NewInt(10_000_000_000)) + fundedAccounts := make([]sdk.AccAddress, 0, numAccountsToFund) + for i := 0; i < numAccountsToFund; i++ { + recipient := sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address()) + fundedAccounts = append(fundedAccounts, recipient) + bankSendSendMsgs = append(bankSendSendMsgs, &banktypes.MsgSend{ + FromAddress: issuer.String(), + ToAddress: recipient.String(), + Amount: sdk.NewCoins(coinToFund), + }) + } + + fundMsgs := make([]sdk.Msg, 0) + fundMsgs = append(fundMsgs, issueMsg) + for i := 0; i < iterationsToFund; i++ { + fundMsgs = append(fundMsgs, bankSendSendMsgs...) + } + chain.FundAccountWithOptions(ctx, t, issuer, integration.BalancesOptions{ + Messages: fundMsgs, + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount, + }) + + // issue fungible tokens + _, err := client.BroadcastTx( + ctx, + chain.ClientContext.WithFromAddress(issuer), + chain.TxFactory().WithGas(chain.GasLimitByMsgs(issueMsg)), + issueMsg, + ) + requireT.NoError(err) + + // send coins in loop + start := time.Now() + for i := 0; i < iterationsToFund; i++ { + res, err := client.BroadcastTx( + ctx, + chain.ClientContext.WithFromAddress(issuer), + chain.TxFactory().WithGas(chain.GasLimitByMsgs(bankSendSendMsgs...)), + bankSendSendMsgs...) + requireT.NoError(err) + t.Logf("Successfully sent batch BankSend tx, hash: %s, gasUsed:%d", res.TxHash, res.GasUsed) + } + t.Logf("It takes %s to fund %d accounts with BankSend", time.Since(start), numAccountsToFund*iterationsToFund) + + assertBatchAccounts( + ctx, + chain, + sdk.NewCoins(sdk.NewCoin(coinToFund.Denom, coinToFund.Amount.MulRaw(int64(iterationsToFund)))), + fundedAccounts, + denom, + requireT, + ) +} + +func assertBatchAccounts( + ctx context.Context, + chain integration.CoreumChain, + expectedCoins sdk.Coins, + fundedAccounts []sdk.AccAddress, + denom string, + requireT *require.Assertions, +) { + bankClient := banktypes.NewQueryClient(chain.ClientContext) + for _, acc := range fundedAccounts { + res, err := bankClient.Balance(ctx, &banktypes.QueryBalanceRequest{ + Address: acc.String(), + Denom: denom, + }) + requireT.NoError(err) + requireT.Equal(expectedCoins.String(), res.Balance.String()) + } +} diff --git a/integration-tests/modules/crisis_test.go b/integration-tests/stress/crisis_test.go similarity index 98% rename from integration-tests/modules/crisis_test.go rename to integration-tests/stress/crisis_test.go index ef6efa37c..99ea9c9de 100644 --- a/integration-tests/modules/crisis_test.go +++ b/integration-tests/stress/crisis_test.go @@ -1,6 +1,6 @@ //go:build integrationtests -package modules +package stress import ( "testing" diff --git a/integration-tests/stress/distribution_test.go b/integration-tests/stress/distribution_test.go new file mode 100644 index 000000000..f76c4a14b --- /dev/null +++ b/integration-tests/stress/distribution_test.go @@ -0,0 +1,224 @@ +//go:build integrationtests + +package stress + +import ( + "testing" + + sdkmath "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/stretchr/testify/require" + + integrationtests "github.com/CoreumFoundation/coreum/v5/integration-tests" + "github.com/CoreumFoundation/coreum/v5/pkg/client" + "github.com/CoreumFoundation/coreum/v5/testutil/integration" + customparamstypes "github.com/CoreumFoundation/coreum/v5/x/customparams/types" +) + +// TestDistributionWithdrawRewardWithDeterministicGas checks that withdraw reward works correctly and +// gas is deterministic. +func TestDistributionWithdrawRewardWithDeterministicGas(t *testing.T) { + t.Parallel() + + ctx, chain := integrationtests.NewCoreumTestingContext(t) + + delegator := chain.GenAccount() + delegatorRewardRecipient := chain.GenAccount() + + bankClient := banktypes.NewQueryClient(chain.ClientContext) + customParamsClient := customparamstypes.NewQueryClient(chain.ClientContext) + + requireT := require.New(t) + // the amount of the delegation should be big enough to get at least some reward for the few blocks + amountToDelegate := sdkmath.NewInt(1_000_000_000) + chain.FundAccountWithOptions(ctx, t, delegator, integration.BalancesOptions{ + Messages: []sdk.Msg{ + &stakingtypes.MsgDelegate{}, + &distributiontypes.MsgDepositValidatorRewardsPool{}, + &distributiontypes.MsgWithdrawDelegatorReward{}, + &distributiontypes.MsgSetWithdrawAddress{}, + &distributiontypes.MsgWithdrawDelegatorReward{}, + }, + Amount: amountToDelegate.Add(sdkmath.NewInt(1_000)), + }) + + delegatedCoin := chain.NewCoin(amountToDelegate) + + // *** Create new validator to use it in the test and capture all required balances. *** + customStakingParams, err := customParamsClient.StakingParams(ctx, &customparamstypes.QueryStakingParamsRequest{}) + require.NoError(t, err) + // we multiply not to conflict with the tests which increases the min amount + validatorStakingAmount := customStakingParams.Params.MinSelfDelegation.Mul(sdkmath.NewInt(2)) + validatorStakerAddress, validatorAddress, deactivateValidator, err := chain.CreateValidator( + ctx, t, validatorStakingAmount, validatorStakingAmount, + ) + require.NoError(t, err) + defer deactivateValidator() + + // delegate coins + delegateMsg := &stakingtypes.MsgDelegate{ + DelegatorAddress: delegator.String(), + ValidatorAddress: validatorAddress.String(), + Amount: delegatedCoin, + } + + clientCtx := chain.ClientContext + + t.Log("Delegating some coins to validator to withdraw later") + _, err = client.BroadcastTx( + ctx, + clientCtx.WithFromAddress(delegator), + chain.TxFactory().WithGas(chain.GasLimitByMsgs(delegateMsg)), + delegateMsg, + ) + requireT.NoError(err) + + // deposit in validator rewards pool + t.Log("Deposit some more amount in the validator rewards pool") + // withdraw the normal reward + depositValidatorRewardsPoolMsg := &distributiontypes.MsgDepositValidatorRewardsPool{ + Depositor: delegator.String(), + ValidatorAddress: validatorAddress.String(), + Amount: sdk.NewCoins(chain.NewCoin(sdkmath.NewInt(1000))), + } + txResult, err := client.BroadcastTx( + ctx, + clientCtx.WithFromAddress(delegator), + chain.TxFactory().WithGas(chain.GasLimitByMsgs(depositValidatorRewardsPoolMsg)), + depositValidatorRewardsPoolMsg, + ) + requireT.NoError(err) + // validate the deterministic gas + requireT.Equal(chain.GasLimitByMsgs(depositValidatorRewardsPoolMsg), uint64(txResult.GasUsed)) + + // capture the normal staker balance + delegatorBalanceRes, err := bankClient.Balance(ctx, &banktypes.QueryBalanceRequest{ + Address: delegator.String(), + Denom: delegatedCoin.Denom, + }) + requireT.NoError(err) + delegatorBalanceBeforeWithdrawal := delegatorBalanceRes.Balance + + // capture validator staker balance + validatorStakerBalanceRes, err := bankClient.Balance(ctx, &banktypes.QueryBalanceRequest{ + Address: validatorStakerAddress.String(), + Denom: delegatedCoin.Denom, + }) + requireT.NoError(err) + validatorStakerBalanceBeforeWithdrawal := validatorStakerBalanceRes.Balance + + // await next 5 blocks + requireT.NoError(client.AwaitNextBlocks(ctx, clientCtx, 5)) + + // *** Withdraw and check the delegator reward. *** + + // normal delegator + t.Log("Withdrawing the delegator reward") + // withdraw the normal reward + withdrawRewardMsg := &distributiontypes.MsgWithdrawDelegatorReward{ + DelegatorAddress: delegator.String(), + ValidatorAddress: validatorAddress.String(), + } + txResult, err = client.BroadcastTx( + ctx, + clientCtx.WithFromAddress(delegator), + chain.TxFactory().WithGas(chain.GasLimitByMsgs(withdrawRewardMsg)), + withdrawRewardMsg, + ) + requireT.NoError(err) + // validate the deterministic gas + requireT.Equal(chain.GasLimitByMsgs(withdrawRewardMsg), uint64(txResult.GasUsed)) + + delegatorBalanceRes, err = bankClient.Balance(ctx, &banktypes.QueryBalanceRequest{ + Address: delegator.String(), + Denom: delegatedCoin.Denom, + }) + requireT.NoError(err) + delegatorBalanceAfterWithdrawal := delegatorBalanceRes.Balance + + feeSpentOnWithdrawReward := chain.ComputeNeededBalanceFromOptions(integration.BalancesOptions{ + Messages: []sdk.Msg{withdrawRewardMsg}, + }) + + delegatorReward := delegatorBalanceAfterWithdrawal.Amount. + Sub(delegatorBalanceBeforeWithdrawal.Amount.Sub(feeSpentOnWithdrawReward)) + requireT.True(delegatorReward.IsPositive()) + t.Logf("Withdrawing of the delegator reward is done, amount:%s", delegatorReward.String()) + + // *** Change the reward owner and withdraw the delegator reward. *** + + // Change the reward owner and withdraw the reward + t.Log("Changing the reward recipient and windowing the reward") + // change withdraw address + setWithdrawAddressMsg := &distributiontypes.MsgSetWithdrawAddress{ + DelegatorAddress: delegator.String(), + WithdrawAddress: delegatorRewardRecipient.String(), + } + txResult, err = client.BroadcastTx( + ctx, + clientCtx.WithFromAddress(delegator), + chain.TxFactory().WithGas(chain.GasLimitByMsgs(setWithdrawAddressMsg)), + setWithdrawAddressMsg, + ) + requireT.NoError(err) + // validate the deterministic gas + requireT.Equal(chain.GasLimitByMsgs(setWithdrawAddressMsg), uint64(txResult.GasUsed)) + // withdraw the reward second time + txResult, err = client.BroadcastTx( + ctx, + clientCtx.WithFromAddress(delegator), + chain.TxFactory().WithGas(chain.GasLimitByMsgs(withdrawRewardMsg)), + withdrawRewardMsg, + ) + requireT.NoError(err) + // validate the deterministic gas + requireT.Equal(chain.GasLimitByMsgs(withdrawRewardMsg), uint64(txResult.GasUsed)) + delegatorRewardRecipientBalanceRes, err := bankClient.Balance(ctx, &banktypes.QueryBalanceRequest{ + Address: delegatorRewardRecipient.String(), + Denom: delegatedCoin.Denom, + }) + requireT.NoError(err) + requireT.True(delegatorRewardRecipientBalanceRes.Balance.IsPositive()) + + // *** Withdraw the validator commission. *** + + // validator commission + t.Log("Withdrawing the validator commission") + // withdraw the normal reward + withdrawCommissionMsg := &distributiontypes.MsgWithdrawValidatorCommission{ + ValidatorAddress: validatorAddress.String(), + } + + chain.FundAccountWithOptions(ctx, t, validatorStakerAddress, integration.BalancesOptions{ + Messages: []sdk.Msg{withdrawCommissionMsg}, + }) + + txResult, err = client.BroadcastTx( + ctx, + clientCtx.WithFromAddress(validatorStakerAddress), + chain.TxFactory().WithGas(chain.GasLimitByMsgs(withdrawCommissionMsg)), + withdrawCommissionMsg, + ) + requireT.NoError(err) + // validate the deterministic gas + requireT.Equal(chain.GasLimitByMsgs(withdrawCommissionMsg), uint64(txResult.GasUsed)) + + validatorStakerBalanceRes, err = bankClient.Balance(ctx, &banktypes.QueryBalanceRequest{ + Address: validatorStakerAddress.String(), + Denom: delegatedCoin.Denom, + }) + requireT.NoError(err) + validatorStakerBalanceAfterWithdrawal := validatorStakerBalanceRes.Balance + + feeSpentOnWithdrawCommission := chain.ComputeNeededBalanceFromOptions(integration.BalancesOptions{ + Messages: []sdk.Msg{withdrawCommissionMsg}, + }) + + validatorStakerCommissionReward := validatorStakerBalanceAfterWithdrawal.Amount. + Sub(validatorStakerBalanceBeforeWithdrawal.Amount.Sub(feeSpentOnWithdrawCommission)) + requireT.True(validatorStakerCommissionReward.IsPositive()) + t.Logf("Withdrawing of the validator commission is done, amount:%s", validatorStakerCommissionReward.String()) +} diff --git a/integration-tests/modules/gas_estimation_test.go b/integration-tests/stress/gas_estimation_test.go similarity index 93% rename from integration-tests/modules/gas_estimation_test.go rename to integration-tests/stress/gas_estimation_test.go index 52c8fe374..c14d120d1 100644 --- a/integration-tests/modules/gas_estimation_test.go +++ b/integration-tests/stress/gas_estimation_test.go @@ -1,6 +1,6 @@ -//go:build integrationtests && gasestimationtests +//go:build integrationtests -package modules +package stress import ( "fmt" @@ -23,8 +23,12 @@ import ( // TestBankSendEstimation is used to estimate gas required by each additional token present in bank send message. // It executes transactions sending from 1 to 201 tokens in single message and reports gas estimated by each of them. // Then you may copy the results to a spreadsheet and calculate the gas required by each transfer. -// Spreadsheet example might be found here: https://docs.google.com/spreadsheets/d/1qoKa8udTPYdS_-ofJ8xNbnZFDh-gqGb4n0_OgcTHUOA/edit?usp=sharing -// Keep in mind that to estimate the gas you need to move bank send message to nondeterministic section inside deterministic gas config. +// Spreadsheet example might be found here: +// +// https://docs.google.com/spreadsheets/d/1qoKa8udTPYdS_-ofJ8xNbnZFDh-gqGb4n0_OgcTHUOA/edit?usp=sharing. +// +// Keep in mind that to estimate the gas you need to move bank send message to nondeterministic section inside +// deterministic gas config. func TestBankSendEstimation(t *testing.T) { const ( nTokens = 101 @@ -138,11 +142,11 @@ func TestAuthzEstimation(t *testing.T) { chain.Faucet.FundAccounts(ctx, t, integration.FundedAccount{ Address: granter, - Amount: chain.NewCoin(sdkmath.NewInt(50000000)), + Amount: chain.NewCoin(sdkmath.NewInt(1_000_000)), }, integration.FundedAccount{ Address: grantee, - Amount: chain.NewCoin(sdkmath.NewInt(50000000)), + Amount: chain.NewCoin(sdkmath.NewInt(1_000_000)), }, )