From eac4c8ab8130af9da2a5d4eb7a949df7a65656d2 Mon Sep 17 00:00:00 2001 From: Wojtek Date: Thu, 26 Oct 2023 11:59:11 +0200 Subject: [PATCH] Estimate overhead required by authz execution --- .../modules/gas_estimation_test.go | 83 +++++++++++++++++++ x/deterministicgas/config.go | 7 +- x/deterministicgas/spec/README.md | 2 +- 3 files changed, 85 insertions(+), 7 deletions(-) diff --git a/integration-tests/modules/gas_estimation_test.go b/integration-tests/modules/gas_estimation_test.go index 04d08863e..73198c3e7 100644 --- a/integration-tests/modules/gas_estimation_test.go +++ b/integration-tests/modules/gas_estimation_test.go @@ -5,10 +5,13 @@ package modules import ( "fmt" "testing" + "time" sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/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/v3/integration-tests" @@ -114,3 +117,83 @@ func TestBankSendEstimation(t *testing.T) { fmt.Printf("%d\t%d\n", n, txRes.GasUsed) } } + +// TestAuthzEstimation it estimates gas overhead required by authz message execution. +// It executes regular message first. Then the same message is executed using authz. By subtracting those values +// we know what the overhead of authz is. +// To get correct results, both authz and bank send must be temporarily configured as non-deterministic messages, +// to get real results. +func TestAuthzEstimation(t *testing.T) { + t.Parallel() + + ctx, chain := integrationtests.NewCoreumTestingContext(t) + + requireT := require.New(t) + + granter := chain.GenAccount() + grantee := chain.GenAccount() + recipient1 := chain.GenAccount() + recipient2 := chain.GenAccount() + + chain.Faucet.FundAccounts(ctx, t, + integration.FundedAccount{ + Address: granter, + Amount: chain.NewCoin(sdk.NewInt(50000000)), + }, + integration.FundedAccount{ + Address: grantee, + Amount: chain.NewCoin(sdk.NewInt(50000000)), + }, + ) + + // grant the authorization + grantMsg, err := authztypes.NewMsgGrant( + granter, + grantee, + authztypes.NewGenericAuthorization(sdk.MsgTypeURL(&banktypes.MsgSend{})), + lo.ToPtr(time.Now().Add(time.Minute)), + ) + require.NoError(t, err) + + _, err = client.BroadcastTx( + ctx, + chain.ClientContext.WithFromAddress(granter), + chain.TxFactory().WithGas(chain.GasLimitByMsgs(grantMsg)), + grantMsg, + ) + requireT.NoError(err) + + // execute regular message + amountToSend := sdkmath.NewInt(2_000) + txf := chain.TxFactory().WithSimulateAndExecute(true) + resRegular, err := client.BroadcastTx( + ctx, + chain.ClientContext.WithFromAddress(granter), + txf, + &banktypes.MsgSend{ + FromAddress: granter.String(), + ToAddress: recipient1.String(), + Amount: sdk.NewCoins(chain.NewCoin(amountToSend)), + }, + ) + requireT.NoError(err) + + // execute authz message + execMsg := authztypes.NewMsgExec(grantee, []sdk.Msg{ + &banktypes.MsgSend{ + FromAddress: granter.String(), + ToAddress: recipient2.String(), + Amount: sdk.NewCoins(chain.NewCoin(amountToSend)), + }, + }) + + resAuthZ, err := client.BroadcastTx( + ctx, + chain.ClientContext.WithFromAddress(grantee), + txf, + &execMsg, + ) + requireT.NoError(err) + + fmt.Printf("Authz gas overhead: %d\n", resAuthZ.GasUsed-resRegular.GasUsed) +} diff --git a/x/deterministicgas/config.go b/x/deterministicgas/config.go index 1ec46fc28..072d757cf 100644 --- a/x/deterministicgas/config.go +++ b/x/deterministicgas/config.go @@ -35,7 +35,7 @@ import ( const ( BankSendPerCoinGas = 50000 BankMultiSendPerOperationsGas = 35000 - AuthzExecOverhead = 2000 + AuthzExecOverhead = 1500 ) type ( @@ -95,11 +95,6 @@ func DefaultConfig() Config { MsgToMsgURL(&assetnfttypes.MsgRemoveFromClassWhitelist{}): constantGasFunc(3500), // authz - // FIXME (v47-deterministic): We need a procedure to estimate the overhead of the authz. Proposal: - // 1. Estimate normal message - // 2. Estimate the same message executed using authz - // 3. Subtract one from the other - // We should have an integration test doing this. MsgToMsgURL(&authz.MsgExec{}): cfg.authzMsgExecGasFunc(AuthzExecOverhead), MsgToMsgURL(&authz.MsgGrant{}): constantGasFunc(28000), MsgToMsgURL(&authz.MsgRevoke{}): constantGasFunc(8000), diff --git a/x/deterministicgas/spec/README.md b/x/deterministicgas/spec/README.md index 656dcd616..c0adfac0a 100644 --- a/x/deterministicgas/spec/README.md +++ b/x/deterministicgas/spec/README.md @@ -143,7 +143,7 @@ Real examples of special case tests could be found [here](https://github.com/Cor `DeterministicGasForMsg = authzMsgExecOverhead + Sum(DeterministicGas(ChildMsg))` -`authzMsgExecOverhead` is currently equal to `2000`. +`authzMsgExecOverhead` is currently equal to `1500`. ### Nondeterministic messages