From 34a3dd8fdf9a78851d72e4f59128d947fb22ad9a Mon Sep 17 00:00:00 2001 From: cwbhhjl Date: Wed, 9 Mar 2022 23:29:30 +0800 Subject: [PATCH] Merge PR: gas error fix (#1660) * test * update gas consumed calc logic * revert * revert Co-authored-by: xiangjianmeng <805442788@qq.com> --- app/ante/utils.go | 14 +++------- app/refund/refund.go | 7 ++--- libs/cosmos-sdk/types/context.go | 4 +++ libs/cosmos-sdk/x/auth/exported/utils.go | 27 ++++++++++++++++--- libs/cosmos-sdk/x/auth/refund/refund.go | 4 +-- .../x/bank/internal/keeper/keeper.go | 19 +++++-------- 6 files changed, 43 insertions(+), 32 deletions(-) diff --git a/app/ante/utils.go b/app/ante/utils.go index 16925ace82..1dc404a316 100644 --- a/app/ante/utils.go +++ b/app/ante/utils.go @@ -7,19 +7,13 @@ import ( ) func getAccount(ak *auth.AccountKeeper, ctx *sdk.Context, addr sdk.AccAddress, accCache auth.Account) (auth.Account, sdk.Gas) { - var acc auth.Account gasMeter := ctx.GasMeter() - gasBefore := gasMeter.GasConsumed() var gasUsed sdk.Gas if accCache != nil { - if exported.TryAddGetAccountGas(gasMeter, ak, accCache) { - acc = accCache - gasUsed = gasMeter.GasConsumed() - gasBefore + var ok bool + if ok, gasUsed = exported.TryAddGetAccountGas(gasMeter, ak, accCache); ok { + return accCache, gasUsed } } - if acc == nil { - acc = ak.GetAccount(*ctx, addr) - gasUsed = gasMeter.GasConsumed() - gasBefore - } - return acc, gasUsed + return exported.GetAccountAndGas(*ctx, ak, addr) } diff --git a/app/refund/refund.go b/app/refund/refund.go index b8fdddcb36..a9204c4f0a 100644 --- a/app/refund/refund.go +++ b/app/refund/refund.go @@ -3,6 +3,8 @@ package refund import ( "math/big" + "github.com/okex/exchain/libs/cosmos-sdk/x/auth/exported" + "github.com/okex/exchain/libs/cosmos-sdk/x/auth/ante" "github.com/okex/exchain/libs/cosmos-sdk/x/auth/keeper" @@ -57,12 +59,11 @@ func (handler Handler) GasRefund(ctx sdk.Context, tx sdk.Tx) (refundGasFee sdk.C } feePayer := feeTx.FeePayer(ctx) - gasBefore := ctx.GasMeter().GasConsumed() - feePayerAcc := handler.ak.GetAccount(ctx, feePayer) + + feePayerAcc, getAccountGasUsed := exported.GetAccountAndGas(ctx, handler.ak, feePayer) if feePayerAcc == nil { return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "fee payer address: %s does not exist", feePayer) } - getAccountGasUsed := ctx.GasMeter().GasConsumed() - gasBefore gas := feeTx.GetGas() fees := feeTx.GetFee() diff --git a/libs/cosmos-sdk/types/context.go b/libs/cosmos-sdk/types/context.go index 2ed44944d3..75195322bb 100644 --- a/libs/cosmos-sdk/types/context.go +++ b/libs/cosmos-sdk/types/context.go @@ -315,6 +315,10 @@ func (c Context) WithValue(key, value interface{}) Context { return c } +func (c *Context) SetGasMeter(meter GasMeter) { + c.gasMeter = meter +} + // Value is deprecated, provided for backwards compatibility // Please use // ctx.Context().Value(key) diff --git a/libs/cosmos-sdk/x/auth/exported/utils.go b/libs/cosmos-sdk/x/auth/exported/utils.go index bf0bb6b535..dc1563fad5 100644 --- a/libs/cosmos-sdk/x/auth/exported/utils.go +++ b/libs/cosmos-sdk/x/auth/exported/utils.go @@ -15,17 +15,21 @@ type SizerAccountKeeper interface { GetEncodedAccountSize(acc Account) int } -func TryAddGetAccountGas(gasMeter sdk.GasMeter, ak SizerAccountKeeper, acc Account) bool { +type AccountKeeper interface { + GetAccount(ctx sdk.Context, addr sdk.AccAddress) Account +} + +func TryAddGetAccountGas(gasMeter sdk.GasMeter, ak SizerAccountKeeper, acc Account) (bool, sdk.Gas) { if ak == nil || gasMeter == nil || acc == nil { - return false + return false, 0 } size := ak.GetEncodedAccountSize(acc) if size == 0 { - return false + return false, 0 } gas := kvGasConfig.ReadCostFlat + storetypes.Gas(size)*kvGasConfig.ReadCostPerByte gasMeter.ConsumeGas(gas, "x/bank/internal/keeper/keeper.BaseSendKeeper") - return true + return true, gas } func GetAccountGas(ak SizerAccountKeeper, acc Account) (sdk.Gas, bool) { @@ -39,3 +43,18 @@ func GetAccountGas(ak SizerAccountKeeper, acc Account) (sdk.Gas, bool) { gas := kvGasConfig.ReadCostFlat + storetypes.Gas(size)*kvGasConfig.ReadCostPerByte return gas, true } + +func GetAccountAndGas(ctx sdk.Context, keeper AccountKeeper, addr sdk.AccAddress) (Account, sdk.Gas) { + gasMeter := ctx.GasMeter() + tmpGasMeter := sdk.NewInfiniteGasMeter() + ctx.SetGasMeter(tmpGasMeter) + gasBefore := tmpGasMeter.GasConsumed() + + acc := keeper.GetAccount(ctx, addr) + + gasUsed := tmpGasMeter.GasConsumed() - gasBefore + gasMeter.ConsumeGas(gasUsed, "get account") + ctx.SetGasMeter(gasMeter) + + return acc, gasUsed +} diff --git a/libs/cosmos-sdk/x/auth/refund/refund.go b/libs/cosmos-sdk/x/auth/refund/refund.go index 3ca3a77250..c3563260ee 100644 --- a/libs/cosmos-sdk/x/auth/refund/refund.go +++ b/libs/cosmos-sdk/x/auth/refund/refund.go @@ -8,9 +8,7 @@ import ( func RefundFees(supplyKeeper types.SupplyKeeper, ctx sdk.Context, acc sdk.AccAddress, refundFees sdk.Coins) error { blockTime := ctx.BlockTime() - gasBefore := ctx.GasMeter().GasConsumed() feeCollector := supplyKeeper.GetModuleAccount(ctx, types.FeeCollectorName) - gasUsed := ctx.GasMeter().GasConsumed() - gasBefore coins := feeCollector.GetCoins() if !refundFees.IsValid() { @@ -31,7 +29,7 @@ func RefundFees(supplyKeeper types.SupplyKeeper, ctx sdk.Context, acc sdk.AccAdd return sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "insufficient funds to pay for refund fees; %s < %s", spendableCoins, refundFees) } - ctx.UpdateFromAccountCache(feeCollector, gasUsed) + ctx.UpdateFromAccountCache(feeCollector, 0) err := supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.FeeCollectorName, acc, refundFees) if err != nil { return sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, err.Error()) diff --git a/libs/cosmos-sdk/x/bank/internal/keeper/keeper.go b/libs/cosmos-sdk/x/bank/internal/keeper/keeper.go index b9ef7e7c34..c2ac141d75 100644 --- a/libs/cosmos-sdk/x/bank/internal/keeper/keeper.go +++ b/libs/cosmos-sdk/x/bank/internal/keeper/keeper.go @@ -311,9 +311,8 @@ func (keeper BaseSendKeeper) SubtractCoins(ctx sdk.Context, addr sdk.AccAddress, if !amt.IsValid() { return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, amt.String()) } - gasBefore := ctx.GasMeter().GasConsumed() - acc := keeper.ak.GetAccount(ctx, addr) - return keeper.subtractCoins(ctx, addr, acc, ctx.GasMeter().GasConsumed()-gasBefore, amt) + acc, gasUsed := authexported.GetAccountAndGas(ctx, keeper.ak, addr) + return keeper.subtractCoins(ctx, addr, acc, gasUsed, amt) } func (keeper *BaseSendKeeper) subtractCoins(ctx sdk.Context, addr sdk.AccAddress, acc authexported.Account, accGas sdk.Gas, amt sdk.Coins) (sdk.Coins, error) { @@ -346,9 +345,8 @@ func (keeper BaseSendKeeper) AddCoins(ctx sdk.Context, addr sdk.AccAddress, amt // oldCoins := keeper.GetCoins(ctx, addr) - gasBefore := ctx.GasMeter().GasConsumed() - acc := keeper.ak.GetAccount(ctx, addr) - return keeper.addCoins(ctx, addr, acc, ctx.GasMeter().GasConsumed()-gasBefore, amt) + acc, gasUsed := authexported.GetAccountAndGas(ctx, keeper.ak, addr) + return keeper.addCoins(ctx, addr, acc, gasUsed, amt) } func (keeper *BaseSendKeeper) addCoins(ctx sdk.Context, addr sdk.AccAddress, acc authexported.Account, accGas sdk.Gas, amt sdk.Coins) (sdk.Coins, error) { @@ -399,14 +397,11 @@ func (keeper *BaseSendKeeper) getAccount(ctx *sdk.Context, addr sdk.AccAddress, gasMeter.ConsumeGas(getgas, "get account") return acc, getgas } - gasBefore := gasMeter.GasConsumed() - if authexported.TryAddGetAccountGas(gasMeter, keeper.ask, acc) { - return acc, gasMeter.GasConsumed() - gasBefore + if ok, gasused := authexported.TryAddGetAccountGas(gasMeter, keeper.ask, acc); ok { + return acc, gasused } } - gasBefore := gasMeter.GasConsumed() - acc = keeper.ak.GetAccount(*ctx, addr) - return acc, gasMeter.GasConsumed() - gasBefore + return authexported.GetAccountAndGas(*ctx, keeper.ak, addr) } func (keeper *BaseSendKeeper) setCoinsToAccount(ctx sdk.Context, addr sdk.AccAddress, acc authexported.Account, accGas sdk.Gas, amt sdk.Coins) error {