From f33944ee849c66f1b51d5d29e6e4f3b6ce41797a Mon Sep 17 00:00:00 2001 From: mmsqe Date: Mon, 15 Jul 2024 15:23:23 +0800 Subject: [PATCH] Problem: gas consumed differs after enabled cache --- CHANGELOG.md | 2 +- x/auth/ante/sigverify.go | 51 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed9aea5a9f73..66de214fab81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,7 +48,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [#252](https://github.com/crypto-org-chain/cosmos-sdk/pull/252) Add `BlockGasWanted` to `Context` to support feemarket module. * [#269](https://github.com/crypto-org-chain/cosmos-sdk/pull/269) Add `StreamingManager` to baseapp to extend the abci listeners. * (crypto/keyring) [#20212](https://github.com/cosmos/cosmos-sdk/pull/20212) Expose the db keyring used in the keystore. -* (baseapp) [#565](https://github.com/crypto-org-chain/cosmos-sdk/pull/565) Support incarnation cache when executed in block-stm. +* (baseapp) [#565](https://github.com/crypto-org-chain/cosmos-sdk/pull/565) Support incarnation cache when executed in block-stm, [#570](https://github.com/crypto-org-chain/cosmos-sdk/pull/570) Align gas consumed in cache. ### Improvements diff --git a/x/auth/ante/sigverify.go b/x/auth/ante/sigverify.go index 341ccf65cf85..c68d1570765c 100644 --- a/x/auth/ante/sigverify.go +++ b/x/auth/ante/sigverify.go @@ -31,10 +31,10 @@ var ( key = make([]byte, secp256k1.PubKeySize) simSecp256k1Pubkey = &secp256k1.PubKey{Key: key} simSecp256k1Sig [64]byte - - SigVerificationResultCacheKey = "ante:SigVerificationResult" ) +const SigVerificationResultCacheKey = "ante:SigVerificationResult" + func init() { // This decodes a valid hex string into a sepc256k1Pubkey for use in transaction simulation bz, _ := hex.DecodeString("035AD6810A47F073553FF30D2FCC7E0D3B1C0B74B61A1AAA2582344037151E143A") @@ -340,15 +340,58 @@ func (svd SigVerificationDecorator) anteHandle(ctx sdk.Context, tx sdk.Tx, simul return nil } +type gasConsumeRecord struct { + Amount storetypes.Gas + Descriptor string + Consume bool +} + +type recordingGasMeter struct { + storetypes.GasMeter + GasConsumes []gasConsumeRecord +} + +func (m *recordingGasMeter) ConsumeGas(amount storetypes.Gas, descriptor string) { + m.GasMeter.ConsumeGas(amount, descriptor) + m.GasConsumes = append(m.GasConsumes, gasConsumeRecord{amount, descriptor, true}) +} + +func (m *recordingGasMeter) RefundGas(amount storetypes.Gas, descriptor string) { + m.GasMeter.RefundGas(amount, descriptor) + m.GasConsumes = append(m.GasConsumes, gasConsumeRecord{amount, descriptor, false}) +} + +type sigVerifyResult struct { + GasRecords []gasConsumeRecord + Error error +} + func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { if v, ok := ctx.GetIncarnationCache(SigVerificationResultCacheKey); ok { // can't convert `nil` to interface if v != nil { - err = v.(error) + result := v.(*sigVerifyResult) + err = result.Error + for _, record := range result.GasRecords { + if record.Consume { + ctx.GasMeter().ConsumeGas(record.Amount, record.Descriptor) + } else { + ctx.GasMeter().RefundGas(record.Amount, record.Descriptor) + } + } } } else { + meter := ctx.GasMeter() + recordingMeter := &recordingGasMeter{ + GasMeter: meter, + } + ctx = ctx.WithGasMeter(recordingMeter) err = svd.anteHandle(ctx, tx, simulate) - ctx.SetIncarnationCache(SigVerificationResultCacheKey, err) + ctx = ctx.WithGasMeter(meter) + ctx.SetIncarnationCache(SigVerificationResultCacheKey, &sigVerifyResult{ + GasRecords: recordingMeter.GasConsumes, + Error: err, + }) } if err != nil { return ctx, err