diff --git a/integration-tests/modules/assetft_extension_test.go b/integration-tests/modules/assetft_extension_test.go index 2ee876b7f..85fd53f59 100644 --- a/integration-tests/modules/assetft_extension_test.go +++ b/integration-tests/modules/assetft_extension_test.go @@ -1488,14 +1488,13 @@ func TestAssetFTExtensionMintingAndSendingOnBehalfOfIssuingSmartContractIsPossib Amount: sdk.NewInt(3 * 500_000), }) - res, err := client.BroadcastTx( + _, err = client.BroadcastTx( ctx, chain.ClientContext.WithFromAddress(grantee), chain.TxFactoryAuto(), &execMsg, ) requireT.NoError(err) - requireT.NotEqualValues(chain.GasLimitByMsgs(&execMsg), res.GasUsed) // check balances diff --git a/integration-tests/modules/assetft_test.go b/integration-tests/modules/assetft_test.go index 4a57f092b..7aeec5961 100644 --- a/integration-tests/modules/assetft_test.go +++ b/integration-tests/modules/assetft_test.go @@ -1683,15 +1683,13 @@ func TestAssetFTFeesAreNotChargedWhenTokensAreTransferredFromSmartContractUsingA }}) chain.FundAccountWithOptions(ctx, t, grantee, integration.BalancesOptions{ - Messages: []sdk.Msg{ - &execMsg, - }, + Amount: sdk.NewInt(20_000), }) _, err = client.BroadcastTx( ctx, chain.ClientContext.WithFromAddress(grantee), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(&execMsg)), + chain.TxFactoryAuto(), &execMsg, ) requireT.NoError(err) @@ -3682,15 +3680,13 @@ func TestAuthzWithAssetFT(t *testing.T) { execMsg := authztypes.NewMsgExec(grantee, []sdk.Msg{msgFreeze, msgWhitelist}) chain.FundAccountWithOptions(ctx, t, grantee, integration.BalancesOptions{ - Messages: []sdk.Msg{ - &execMsg, - }, + Amount: sdk.NewInt(40_000), }) _, err = client.BroadcastTx( ctx, chain.ClientContext.WithFromAddress(grantee), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(&execMsg)), + chain.TxFactoryAuto(), &execMsg, ) requireT.NoError(err) @@ -3727,10 +3723,9 @@ func TestAuthzMintAuthorizationLimit(t *testing.T) { chain.FundAccountWithOptions(ctx, t, granter, integration.BalancesOptions{ Messages: []sdk.Msg{ &assetfttypes.MsgIssue{}, - &authztypes.MsgGrant{}, - &authztypes.MsgGrant{}, }, - Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount, + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount. + Add(sdk.NewInt(40_000)), }) // mint and grant authorization @@ -3777,15 +3772,13 @@ func TestAuthzMintAuthorizationLimit(t *testing.T) { execMsg := authztypes.NewMsgExec(grantee, []sdk.Msg{msgMint}) chain.FundAccountWithOptions(ctx, t, grantee, integration.BalancesOptions{ - Messages: []sdk.Msg{ - &execMsg, - }, + Amount: sdk.NewInt(20_000), }) _, err = client.BroadcastTx( ctx, chain.ClientContext.WithFromAddress(grantee), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(&execMsg)), + chain.TxFactoryAuto(), &execMsg, ) requireT.NoError(err) @@ -3812,15 +3805,13 @@ func TestAuthzMintAuthorizationLimit(t *testing.T) { execMsg = authztypes.NewMsgExec(grantee, []sdk.Msg{msgMint}) chain.FundAccountWithOptions(ctx, t, grantee, integration.BalancesOptions{ - Messages: []sdk.Msg{ - &execMsg, - }, + Amount: sdk.NewInt(20_000), }) _, err = client.BroadcastTx( ctx, chain.ClientContext.WithFromAddress(grantee), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(&execMsg)), + chain.TxFactory().WithGas(200_000), &execMsg, ) requireT.Error(err) @@ -3834,15 +3825,13 @@ func TestAuthzMintAuthorizationLimit(t *testing.T) { execMsg = authztypes.NewMsgExec(grantee, []sdk.Msg{msgMint}) chain.FundAccountWithOptions(ctx, t, grantee, integration.BalancesOptions{ - Messages: []sdk.Msg{ - &execMsg, - }, + Amount: sdk.NewInt(20_000), }) _, err = client.BroadcastTx( ctx, chain.ClientContext.WithFromAddress(grantee), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(&execMsg)), + chain.TxFactoryAuto(), &execMsg, ) requireT.NoError(err) @@ -3877,10 +3866,7 @@ func TestAuthzMintAuthorizationLimit_GrantFromNonIssuer(t *testing.T) { }) chain.FundAccountWithOptions(ctx, t, granter, integration.BalancesOptions{ - Messages: []sdk.Msg{ - &authztypes.MsgGrant{}, - &authztypes.MsgGrant{}, - }, + Amount: sdk.NewInt(40_000), }) // issue and grant authorization @@ -3938,15 +3924,13 @@ func TestAuthzMintAuthorizationLimit_GrantFromNonIssuer(t *testing.T) { execMsg := authztypes.NewMsgExec(grantee, []sdk.Msg{msgMint}) chain.FundAccountWithOptions(ctx, t, grantee, integration.BalancesOptions{ - Messages: []sdk.Msg{ - &execMsg, - }, + Amount: sdk.NewInt(20_000), }) _, err = client.BroadcastTx( ctx, chain.ClientContext.WithFromAddress(grantee), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(&execMsg)), + chain.TxFactory().WithGas(200_000), &execMsg, ) requireT.Error(err) @@ -3971,9 +3955,9 @@ func TestAuthzMintAuthorizationLimit_MultipleCoins(t *testing.T) { Messages: []sdk.Msg{ &assetfttypes.MsgIssue{}, &assetfttypes.MsgIssue{}, - &authztypes.MsgGrant{}, }, - Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount.Mul(sdk.NewInt(2)), + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount.Mul(sdk.NewInt(2)). + Add(sdk.NewInt(20_000)), }) // issue and grant authorization @@ -4042,15 +4026,13 @@ func TestAuthzMintAuthorizationLimit_MultipleCoins(t *testing.T) { execMsg := authztypes.NewMsgExec(grantee, []sdk.Msg{msgMint}) chain.FundAccountWithOptions(ctx, t, grantee, integration.BalancesOptions{ - Messages: []sdk.Msg{ - &execMsg, - }, + Amount: sdk.NewInt(20_000), }) _, err = client.BroadcastTx( ctx, chain.ClientContext.WithFromAddress(grantee), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(&execMsg)), + chain.TxFactoryAuto(), &execMsg, ) requireT.NoError(err) @@ -4084,10 +4066,8 @@ func TestAuthzBurnAuthorizationLimit(t *testing.T) { chain.FundAccountWithOptions(ctx, t, granter, integration.BalancesOptions{ Messages: []sdk.Msg{ &assetfttypes.MsgIssue{}, - &authztypes.MsgGrant{}, - &authztypes.MsgGrant{}, }, - Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount, + Amount: chain.QueryAssetFTParams(ctx, t).IssueFee.Amount.Add(sdk.NewInt(40_000)), }) // grant authorization @@ -4132,15 +4112,13 @@ func TestAuthzBurnAuthorizationLimit(t *testing.T) { execMsg := authztypes.NewMsgExec(grantee, []sdk.Msg{msgBurn}) chain.FundAccountWithOptions(ctx, t, grantee, integration.BalancesOptions{ - Messages: []sdk.Msg{ - &execMsg, - }, + Amount: sdk.NewInt(20_000), }) _, err = client.BroadcastTx( ctx, chain.ClientContext.WithFromAddress(grantee), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(&execMsg)), + chain.TxFactoryAuto(), &execMsg, ) requireT.NoError(err) @@ -4167,15 +4145,13 @@ func TestAuthzBurnAuthorizationLimit(t *testing.T) { execMsg = authztypes.NewMsgExec(grantee, []sdk.Msg{msgBurn}) chain.FundAccountWithOptions(ctx, t, grantee, integration.BalancesOptions{ - Messages: []sdk.Msg{ - &execMsg, - }, + Amount: sdk.NewInt(20_000), }) _, err = client.BroadcastTx( ctx, chain.ClientContext.WithFromAddress(grantee), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(&execMsg)), + chain.TxFactory().WithGas(200_000), &execMsg, ) requireT.Error(err) @@ -4189,15 +4165,13 @@ func TestAuthzBurnAuthorizationLimit(t *testing.T) { execMsg = authztypes.NewMsgExec(grantee, []sdk.Msg{msgBurn}) chain.FundAccountWithOptions(ctx, t, grantee, integration.BalancesOptions{ - Messages: []sdk.Msg{ - &execMsg, - }, + Amount: sdk.NewInt(20_000), }) _, err = client.BroadcastTx( ctx, chain.ClientContext.WithFromAddress(grantee), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(&execMsg)), + chain.TxFactoryAuto(), &execMsg, ) requireT.NoError(err) @@ -4239,10 +4213,7 @@ func TestAuthzBurnAuthorizationLimit_GrantFromNonIssuer(t *testing.T) { }) chain.FundAccountWithOptions(ctx, t, granter, integration.BalancesOptions{ - Messages: []sdk.Msg{ - &authztypes.MsgGrant{}, - &authztypes.MsgGrant{}, - }, + Amount: sdk.NewInt(40_000), }) // issue and grant authorization @@ -4330,15 +4301,13 @@ func TestAuthzBurnAuthorizationLimit_GrantFromNonIssuer(t *testing.T) { execMsg := authztypes.NewMsgExec(grantee, []sdk.Msg{msgBurn}) chain.FundAccountWithOptions(ctx, t, grantee, integration.BalancesOptions{ - Messages: []sdk.Msg{ - &execMsg, - }, + Amount: sdk.NewInt(20_000), }) _, err = client.BroadcastTx( ctx, chain.ClientContext.WithFromAddress(grantee), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(&execMsg)), + chain.TxFactoryAuto(), &execMsg, ) requireT.NoError(err) @@ -4351,15 +4320,13 @@ func TestAuthzBurnAuthorizationLimit_GrantFromNonIssuer(t *testing.T) { execMsg = authztypes.NewMsgExec(grantee, []sdk.Msg{msgBurn}) chain.FundAccountWithOptions(ctx, t, grantee, integration.BalancesOptions{ - Messages: []sdk.Msg{ - &execMsg, - }, + Amount: sdk.NewInt(20_000), }) _, err = client.BroadcastTx( ctx, chain.ClientContext.WithFromAddress(grantee), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(&execMsg)), + chain.TxFactory().WithGas(200_000), &execMsg, ) requireT.Error(err) @@ -4925,15 +4892,13 @@ func TestAssetFTAminoMultisigWithAuthz(t *testing.T) { execMsg := authztypes.NewMsgExec(multisigGranteeAddress, []sdk.Msg{issueMsg}) chain.FundAccountWithOptions(ctx, t, multisigGranteeAddress, integration.BalancesOptions{ - Messages: []sdk.Msg{ - &execMsg, - }, + Amount: sdk.NewInt(20_000), }) _, err = chain.SignAndBroadcastMultisigTx( ctx, chain.ClientContext.WithFromAddress(multisigGranteeAddress), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(&execMsg)), + chain.TxFactoryAuto(), &execMsg, granteeSigner1KeyName, granteeSigner2KeyName) requireT.NoError(err) @@ -5662,15 +5627,13 @@ func TestAssetFTMintingAndSendingOnBehalfOfIssuingSmartContractIsPossibleEvenIfS }) chain.FundAccountWithOptions(ctx, t, grantee, integration.BalancesOptions{ - Messages: []sdk.Msg{ - &execMsg, - }, + Amount: sdk.NewInt(40_000), }) _, err = client.BroadcastTx( ctx, chain.ClientContext.WithFromAddress(grantee), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(&execMsg)), + chain.TxFactoryAuto(), &execMsg, ) requireT.NoError(err) diff --git a/integration-tests/modules/assetnft_test.go b/integration-tests/modules/assetnft_test.go index 55da2491d..69cb008ca 100644 --- a/integration-tests/modules/assetnft_test.go +++ b/integration-tests/modules/assetnft_test.go @@ -1902,16 +1902,14 @@ func TestAssetNFTAuthZ(t *testing.T) { execMsg := authztypes.NewMsgExec(grantee, []sdk.Msg{freezeMsg}) chain.FundAccountWithOptions(ctx, t, grantee, integration.BalancesOptions{ - Messages: []sdk.Msg{ - &execMsg, - }, - Amount: chain.QueryAssetNFTParams(ctx, t).MintFee.Amount, + Amount: chain.QueryAssetNFTParams(ctx, t).MintFee.Amount. + Add(sdk.NewInt(20_000)), }) _, err = client.BroadcastTx( ctx, chain.ClientContext.WithFromAddress(grantee), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(&execMsg)), + chain.TxFactoryAuto(), &execMsg, ) requireT.NoError(err) @@ -2389,9 +2387,9 @@ func TestAssetNFTSendAuthorization(t *testing.T) { Messages: []sdk.Msg{ &assetnfttypes.MsgIssueClass{}, &assetnfttypes.MsgMint{}, - &authztypes.MsgGrant{}, }, - Amount: chain.QueryAssetNFTParams(ctx, t).MintFee.Amount, + Amount: chain.QueryAssetNFTParams(ctx, t).MintFee.Amount. + Add(sdk.NewInt(20_000)), // added 20k for the grant msg }) chain.FundAccountWithOptions(ctx, t, grantee, integration.BalancesOptions{ @@ -2433,16 +2431,13 @@ func TestAssetNFTSendAuthorization(t *testing.T) { execMsg := authztypes.NewMsgExec(grantee, []sdk.Msg{sendMsg}) chain.FundAccountWithOptions(ctx, t, grantee, integration.BalancesOptions{ - Messages: []sdk.Msg{ - &execMsg, - &execMsg, - }, + Amount: sdk.NewInt(40_000), }) _, err = client.BroadcastTx( ctx, chain.ClientContext.WithFromAddress(grantee), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(&execMsg)), + chain.TxFactory().WithGas(200_000), &execMsg, ) requireT.Error(err) @@ -2485,7 +2480,7 @@ func TestAssetNFTSendAuthorization(t *testing.T) { _, err = client.BroadcastTx( ctx, chain.ClientContext.WithFromAddress(grantee), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(&execMsg)), + chain.TxFactoryAuto(), &execMsg, ) requireT.NoError(err) diff --git a/integration-tests/modules/auth_test.go b/integration-tests/modules/auth_test.go index d79fdef46..26633e8a2 100644 --- a/integration-tests/modules/auth_test.go +++ b/integration-tests/modules/auth_test.go @@ -15,9 +15,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/tx/signing" authsign "github.com/cosmos/cosmos-sdk/x/auth/signing" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - authztypes "github.com/cosmos/cosmos-sdk/x/authz" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/samber/lo" "github.com/stretchr/testify/require" integrationtests "github.com/CoreumFoundation/coreum/v4/integration-tests" @@ -313,30 +311,6 @@ func TestGasEstimation(t *testing.T) { // 10 is price for each extra byte over FreeBytes. expectedGas: dgc.FixedGas + 1*deterministicgas.BankSendPerCoinGas + 1133*authParams.Params.TxSizeCostPerByte, }, - { - name: "singlesig_auth_exec_and_bank_send", - fromAddress: singlesigAddress, - msgs: []sdk.Msg{ - lo.ToPtr( - authztypes.NewMsgExec(singlesigAddress, []sdk.Msg{ - &banktypes.MsgSend{ - FromAddress: singlesigAddress.String(), - ToAddress: singlesigAddress.String(), - Amount: sdk.NewCoins(chain.NewCoin(sdkmath.NewInt(1))), - }, - })), - &banktypes.MsgSend{ - FromAddress: singlesigAddress.String(), - ToAddress: singlesigAddress.String(), - Amount: sdk.NewCoins(chain.NewCoin(sdkmath.NewInt(1))), - }, - }, - // single signature no extra bytes. - expectedGas: dgc.FixedGas + - 1*deterministicgas.BankSendPerCoinGas + - 1*deterministicgas.AuthzExecOverhead + - 1*deterministicgas.BankSendPerCoinGas, - }, } for _, tt := range testsDeterm { tt := tt diff --git a/integration-tests/modules/authz_test.go b/integration-tests/modules/authz_test.go index adcd0e371..dfc199923 100644 --- a/integration-tests/modules/authz_test.go +++ b/integration-tests/modules/authz_test.go @@ -108,10 +108,9 @@ func TestAuthz(t *testing.T) { }) chain.FundAccountWithOptions(ctx, t, grantee, integration.BalancesOptions{ + Amount: sdk.NewInt(40_000), Messages: []sdk.Msg{ msgBankSend, - &execMsg, - &execMsg, }, }) @@ -142,14 +141,13 @@ func TestAuthz(t *testing.T) { requireT.Len(gransRes.Grants, 1) // try to send using the authz - txResult, err = client.BroadcastTx( + _, err = client.BroadcastTx( ctx, chain.ClientContext.WithFromAddress(grantee), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(&execMsg)), + chain.TxFactoryAuto(), &execMsg, ) requireT.NoError(err) - requireT.Equal(chain.GasLimitByMsgs(&execMsg), uint64(txResult.GasUsed)) recipientBalancesRes, err := bankClient.AllBalances(ctx, &banktypes.QueryAllBalancesRequest{ Address: recipient.String(), @@ -179,7 +177,7 @@ func TestAuthz(t *testing.T) { _, err = client.BroadcastTx( ctx, chain.ClientContext.WithFromAddress(grantee), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(&execMsg)), + chain.TxFactory().WithGas(200_000), &execMsg, ) requireT.ErrorIs(err, authztypes.ErrNoAuthorizationFound) @@ -236,15 +234,13 @@ func TestAuthZWithMultisigGrantee(t *testing.T) { } execMsg := authztypes.NewMsgExec(multisigAddress, []sdk.Msg{msgBankSend}) chain.FundAccountWithOptions(ctx, t, multisigAddress, integration.BalancesOptions{ - Messages: []sdk.Msg{ - &execMsg, - }, + Amount: sdk.NewInt(20_000), }) _, err = chain.SignAndBroadcastMultisigTx( ctx, chain.ClientContext.WithFromAddress(multisigAddress), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(&execMsg)), + chain.TxFactory().WithGas(200_000), &execMsg, signer1KeyName) requireT.ErrorIs(err, cosmoserrors.ErrUnauthorized) @@ -254,7 +250,7 @@ func TestAuthZWithMultisigGrantee(t *testing.T) { txRes, err := chain.SignAndBroadcastMultisigTx( ctx, chain.ClientContext.WithFromAddress(multisigAddress), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(&execMsg)), + chain.TxFactoryAuto(), &execMsg, signer1KeyName, signer2KeyName) requireT.NoError(err) @@ -322,15 +318,13 @@ func TestAuthZWithMultisigGranter(t *testing.T) { execMsg := authztypes.NewMsgExec(grantee, []sdk.Msg{msgBankSend}) chain.FundAccountWithOptions(ctx, t, grantee, integration.BalancesOptions{ - Messages: []sdk.Msg{ - &execMsg, - }, + Amount: sdk.NewInt(20_000), }) _, err = client.BroadcastTx( ctx, chain.ClientContext.WithFromAddress(grantee), - chain.TxFactory().WithGas(chain.GasLimitByMsgs(&execMsg)), + chain.TxFactoryAuto(), &execMsg, ) requireT.NoError(err) diff --git a/x/deterministicgas/config.go b/x/deterministicgas/config.go index c1afbbbeb..1a9b3979f 100644 --- a/x/deterministicgas/config.go +++ b/x/deterministicgas/config.go @@ -22,6 +22,7 @@ import ( slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + "github.com/cosmos/gogoproto/proto" packetforwardtypes "github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7/packetforward/types" icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" @@ -41,10 +42,10 @@ import ( const ( BankSendPerCoinGas = 50000 BankMultiSendPerOperationsGas = 35000 - AuthzExecOverhead = 1500 NFTIssueClassBaseGas = 16_000 NFTMintBaseGas = 39_000 NFTUpdateBaseGas = 40_000 + MsgGrantBaseGas = 25000 ) type ( @@ -75,7 +76,7 @@ func DefaultConfig() Config { FreeBytes: 2048, FreeSignatures: 1, } - + storeConfig := storetypes.KVGasConfig() cfg.gasByMsg = map[MsgURL]gasByMsgFunc{ // asset/ft MsgToMsgURL(&assetfttypes.MsgIssue{}): constantGasFunc(70_000), @@ -108,8 +109,7 @@ func DefaultConfig() Config { MsgToMsgURL(&assetnfttypes.MsgRemoveFromClassWhitelist{}): constantGasFunc(3_500), // authz - MsgToMsgURL(&authz.MsgExec{}): cfg.authzMsgExecGasFunc(AuthzExecOverhead), - MsgToMsgURL(&authz.MsgGrant{}): constantGasFunc(28_000), + MsgToMsgURL(&authz.MsgGrant{}): authzMsgGrantGasFunc(MsgGrantBaseGas, storeConfig.WriteCostPerByte), MsgToMsgURL(&authz.MsgRevoke{}): constantGasFunc(8_000), // bank @@ -210,6 +210,9 @@ func DefaultConfig() Config { // auth &authtypes.MsgUpdateParams{}, // This is non-deterministic because all the gov proposals are non-deterministic anyway + // authz + &authz.MsgExec{}, // This is non-deterministic because the authorization object might be a listing object and quite big + // bank &banktypes.MsgSetSendEnabled{}, // This is non-deterministic because all the gov proposals are non-deterministic anyway &banktypes.MsgUpdateParams{}, // This is non-deterministic because all the gov proposals are non-deterministic anyway @@ -365,28 +368,22 @@ func MsgToMsgURL(msg sdk.Msg) MsgURL { return MsgURL(sdk.MsgTypeURL(msg)) } -// NOTE: we need to pass Config by pointer here because -// it needs to be initialized later map with all msg types inside to estimate gas recursively. -func (cfg *Config) authzMsgExecGasFunc(authzMsgExecOverhead uint64) gasByMsgFunc { +func authzMsgGrantGasFunc(baseGas uint64, gasPerByte uint64) gasByMsgFunc { return func(msg sdk.Msg) (uint64, bool) { - m, ok := msg.(*authz.MsgExec) + m, ok := msg.(*authz.MsgGrant) if !ok { return 0, false } - totalGas := authzMsgExecOverhead - childMsgs, err := m.GetMessages() - if err != nil { - return 0, false - } - for _, childMsg := range childMsgs { - gas, isDeterministic := cfg.GasRequiredByMessage(childMsg) - if !isDeterministic { - return 0, false - } - totalGas += gas + var overHead uint64 + if m.Grant.Authorization != nil && lo.Contains([]string{ + "/" + proto.MessageName(&assetnfttypes.SendAuthorization{}), + "/" + proto.MessageName(&assetfttypes.MintAuthorization{}), + "/" + proto.MessageName(&assetfttypes.BurnAuthorization{}), + }, m.Grant.Authorization.TypeUrl) { + overHead = uint64(len(m.Grant.Authorization.Value)) * gasPerByte } - return totalGas, true + return baseGas + overHead, true } } diff --git a/x/deterministicgas/config_test.go b/x/deterministicgas/config_test.go index f4a8b628a..fae41e73e 100644 --- a/x/deterministicgas/config_test.go +++ b/x/deterministicgas/config_test.go @@ -4,10 +4,12 @@ import ( "fmt" "reflect" "testing" + "time" _ "unsafe" sdkmath "cosmossdk.io/math" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + "github.com/cometbft/cometbft/crypto/ed25519" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/authz" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" @@ -17,6 +19,7 @@ import ( "github.com/CoreumFoundation/coreum/v4/testutil/simapp" assetfttypes "github.com/CoreumFoundation/coreum/v4/x/asset/ft/types" + assetnfttypes "github.com/CoreumFoundation/coreum/v4/x/asset/nft/types" "github.com/CoreumFoundation/coreum/v4/x/deterministicgas" "github.com/CoreumFoundation/coreum/v4/x/deterministicgas/types" ) @@ -93,8 +96,8 @@ func TestDeterministicGas_DeterministicMessages(t *testing.T) { // To make sure we do not increase/decrease deterministic and extension types accidentally, // we assert length to be equal to exact number, so each change requires // explicit adjustment of tests. - assert.Equal(t, 62, nondeterministicMsgCount) - assert.Equal(t, 69, deterministicMsgCount) + assert.Equal(t, 63, nondeterministicMsgCount) + assert.Equal(t, 68, deterministicMsgCount) assert.Equal(t, 14, extensionMsgCount) assert.Equal(t, 117, nonextensionMsgCount) } @@ -107,7 +110,6 @@ func TestDeterministicGas_GasRequiredByMessage(t *testing.T) { assetFTIssue = 70000 bankSendPerCoinGas = deterministicgas.BankSendPerCoinGas bankMultiSendPerOperationGas = deterministicgas.BankMultiSendPerOperationsGas - authzMsgExecOverhead = deterministicgas.AuthzExecOverhead ) cfg := deterministicgas.DefaultConfig() @@ -201,41 +203,6 @@ func TestDeterministicGas_GasRequiredByMessage(t *testing.T) { expectedGas: 5 * bankMultiSendPerOperationGas, expectedIsDeterministic: true, }, - { - name: "authz.MsgExec: 0 messages", - msg: &authz.MsgExec{}, - expectedGas: authzMsgExecOverhead, - expectedIsDeterministic: true, - }, - { - name: "authz.MsgExec: 1 bank.MsgSend & 1 bank.MsgMultiSend", - msg: lo.ToPtr( - authz.NewMsgExec( - sdk.AccAddress(address), - []sdk.Msg{&banktypes.MsgSend{}, &banktypes.MsgMultiSend{}}, - ), - ), - expectedGas: authzMsgExecOverhead + bankSendPerCoinGas + 2*bankMultiSendPerOperationGas, - expectedIsDeterministic: true, - }, - { - name: "authz.MsgExec: 1 authz.MsgExec (1 bank.MsgSend & 1 bank.MsgMultiSend) & bank.MsgSend", - msg: lo.ToPtr( - authz.NewMsgExec( - sdk.AccAddress(address), - []sdk.Msg{ - lo.ToPtr(authz.NewMsgExec(sdk.AccAddress(address), []sdk.Msg{&banktypes.MsgSend{}, &banktypes.MsgMultiSend{}})), - &banktypes.MsgSend{}, - }, - ), - ), - expectedGas: authzMsgExecOverhead + - authzMsgExecOverhead + - bankSendPerCoinGas + - 2*bankMultiSendPerOperationGas + - bankSendPerCoinGas, - expectedIsDeterministic: true, - }, { name: "authz.MsgExec: 1 bank.MsgSend & 1 wasm.MsgExecuteContract", msg: lo.ToPtr( @@ -258,3 +225,95 @@ func TestDeterministicGas_GasRequiredByMessage(t *testing.T) { }) } } + +func TestDeterministicGas_AuthzGrant(t *testing.T) { + address := sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address()) + testCases := []struct { + name string + authzItemsCount int + expectedGas uint64 + }{ + { + name: "1_item", + authzItemsCount: 1, + expectedGas: 28000, + }, + { + name: "50_items", + authzItemsCount: 50, + expectedGas: 187000, + }, + { + name: "100_items", + authzItemsCount: 100, + expectedGas: 350000, + }, + } + genAuthFuncs := []struct { + name string + fn func(itemsCount int) authz.Authorization + }{ + { + name: "send_auth", + fn: func(itemsCount int) authz.Authorization { + authorization := &assetnfttypes.SendAuthorization{} + for i := 0; i < itemsCount; i++ { + authorization.Nfts = append(authorization.Nfts, assetnfttypes.NFTIdentifier{ + ClassId: "class-id-" + address.String(), + Id: "id-" + address.String(), + }) + } + return authorization + }, + }, + { + name: "mint_auth", + fn: func(itemsCount int) authz.Authorization { + authorization := &assetfttypes.MintAuthorization{} + for i := 0; i < itemsCount; i++ { + authorization.MintLimit = append( + authorization.MintLimit, + sdk.NewCoin("random-denom-"+address.String(), sdk.NewInt(1_000_000_000_000)), + ) + } + return authorization + }, + }, + { + name: "burn_auth", + fn: func(itemsCount int) authz.Authorization { + authorization := &assetfttypes.BurnAuthorization{} + for i := 0; i < itemsCount; i++ { + authorization.BurnLimit = append( + authorization.BurnLimit, + sdk.NewCoin("random-denom-"+address.String(), sdk.NewInt(1_000_000_000_000)), + ) + } + return authorization + }, + }, + } + + cfg := deterministicgas.DefaultConfig() + for _, gen := range genAuthFuncs { + for _, tc := range testCases { + tc := tc + gen := gen + t.Run(tc.name+"_"+gen.name, func(t *testing.T) { + requireT := require.New(t) + authorization := gen.fn(tc.authzItemsCount) + grantMsg, err := authz.NewMsgGrant( + address, + address, + authorization, + lo.ToPtr(time.Now().Add(time.Minute)), + ) + requireT.NoError(err) + + deterministicGas, ok := cfg.GasRequiredByMessage(grantMsg) + requireT.True(ok) + requireT.InEpsilon(tc.expectedGas, deterministicGas, 0.3) + }) + } + } +} diff --git a/x/deterministicgas/spec/README.md b/x/deterministicgas/spec/README.md index 5ed24c6aa..816f3d388 100644 --- a/x/deterministicgas/spec/README.md +++ b/x/deterministicgas/spec/README.md @@ -91,7 +91,7 @@ It should also be mentioned that this rule applies for all the messages inside ` | `/coreum.asset.nft.v1.MsgIssueClass` | [special case](#special-cases) | | `/coreum.asset.nft.v1.MsgMint` | [special case](#special-cases) | | `/coreum.asset.nft.v1.MsgUpdateData` | [special case](#special-cases) | -| `/cosmos.authz.v1beta1.MsgExec` | [special case](#special-cases) | +| `/cosmos.authz.v1beta1.MsgGrant` | [special case](#special-cases) | | `/cosmos.bank.v1beta1.MsgMultiSend` | [special case](#special-cases) | | `/cosmos.bank.v1beta1.MsgSend` | [special case](#special-cases) | | `/coreum.asset.ft.v1.MsgBurn` | 35000 | @@ -117,7 +117,6 @@ It should also be mentioned that this rule applies for all the messages inside ` | `/coreum.asset.nft.v1.MsgRemoveFromWhitelist` | 3500 | | `/coreum.asset.nft.v1.MsgUnfreeze` | 5000 | | `/coreum.nft.v1beta1.MsgSend` | 25000 | -| `/cosmos.authz.v1beta1.MsgGrant` | 28000 | | `/cosmos.authz.v1beta1.MsgRevoke` | 8000 | | `/cosmos.distribution.v1beta1.MsgFundCommunityPool` | 17000 | | `/cosmos.distribution.v1beta1.MsgSetWithdrawAddress` | 5000 | @@ -175,11 +174,17 @@ Real examples of special case tests could be found [here](https://github.com/Cor `bankMultiSendPerOperationGas` is currently equal to `35000`. -##### `/cosmos.authz.v1beta1.MsgExec` +##### `/cosmos.authz.v1beta1.MsgGrant` +MsgGrant is deterministic with gas value of `25000`, but if the authorization type is +one of the following, then it gets an overhead for every byte of the authorization. +The authorization types with overhead are: +- `/coreum.assert.nft.SendAuthorization` +- `/coreum.assert.ft.MintAuthorization` +- `/coreum.assert.ft.BurnAuthorization` -`DeterministicGasForMsg = authzMsgExecOverhead + Sum(DeterministicGas(ChildMsg))` +and the formula for them is +`DeterministicGas = MsgGrantBaseGas + Size(Authorization) * WriteCostPerByte ` -`authzMsgExecOverhead` is currently equal to `1500`. ##### `/coreum.asset.nft.v1.MsgIssueClass` @@ -202,6 +207,7 @@ Real examples of special case tests could be found [here](https://github.com/Cor | `/coreum.customparams.v1.MsgUpdateStakingParams` | | `/coreum.feemodel.v1.MsgUpdateParams` | | `/cosmos.auth.v1beta1.MsgUpdateParams` | +| `/cosmos.authz.v1beta1.MsgExec` | | `/cosmos.bank.v1beta1.MsgSetSendEnabled` | | `/cosmos.bank.v1beta1.MsgUpdateParams` | | `/cosmos.consensus.v1.MsgUpdateParams` | diff --git a/x/deterministicgas/spec/README.tmpl.md b/x/deterministicgas/spec/README.tmpl.md index f61bbe672..47f25e929 100644 --- a/x/deterministicgas/spec/README.tmpl.md +++ b/x/deterministicgas/spec/README.tmpl.md @@ -111,11 +111,17 @@ Real examples of special case tests could be found [here](https://github.com/Cor `bankMultiSendPerOperationGas` is currently equal to `{{ .BankMultiSendPerOperationsGas }}`. -##### `/cosmos.authz.v1beta1.MsgExec` +##### `/cosmos.authz.v1beta1.MsgGrant` +MsgGrant is deterministic with gas value of `{{ .MsgGrantBaseGas}}`, but if the authorization type is +one of the following, then it gets an overhead for every byte of the authorization. +The authorization types with overhead are: +- `/coreum.assert.nft.SendAuthorization` +- `/coreum.assert.ft.MintAuthorization` +- `/coreum.assert.ft.BurnAuthorization` -`DeterministicGasForMsg = authzMsgExecOverhead + Sum(DeterministicGas(ChildMsg))` +and the formula for them is +`DeterministicGas = MsgGrantBaseGas + Size(Authorization) * WriteCostPerByte ` -`authzMsgExecOverhead` is currently equal to `{{ .AuthzExecOverhead }}`. ##### `/coreum.asset.nft.v1.MsgIssueClass` diff --git a/x/deterministicgas/spec/generate.go b/x/deterministicgas/spec/generate.go index 2a303f628..1917f78bd 100644 --- a/x/deterministicgas/spec/generate.go +++ b/x/deterministicgas/spec/generate.go @@ -90,7 +90,7 @@ func main() { MsgIssueGasPrice uint64 BankSendPerCoinGas uint64 BankMultiSendPerOperationsGas uint64 - AuthzExecOverhead uint64 + MsgGrantBaseGas uint64 NFTMsgIssueClassCost uint64 NFTMsgMintCost uint64 @@ -113,7 +113,7 @@ func main() { MsgIssueGasPrice: msgIssueGasPrice, BankSendPerCoinGas: deterministicgas.BankSendPerCoinGas, BankMultiSendPerOperationsGas: deterministicgas.BankMultiSendPerOperationsGas, - AuthzExecOverhead: deterministicgas.AuthzExecOverhead, + MsgGrantBaseGas: deterministicgas.MsgGrantBaseGas, NFTMsgIssueClassCost: deterministicgas.NFTIssueClassBaseGas, NFTMsgMintCost: deterministicgas.NFTMintBaseGas,