refactor(x/auth/ante): migrate antehandlers to use execmode (#19161)

Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>
This commit is contained in:
Marko 2024-01-24 09:58:54 +01:00 committed by GitHub
parent b981f9d359
commit 9945d31cc0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 30 additions and 32 deletions

View File

@ -884,6 +884,9 @@ func (app *BaseApp) runTx(mode execMode, txBytes []byte) (gInfo sdk.GasInfo, res
// performance benefits, but it'll be more difficult to get right.
anteCtx, msCache = app.cacheTxContext(ctx, txBytes)
anteCtx = anteCtx.WithEventManager(sdk.NewEventManager())
if mode == execModeSimulate {
anteCtx = anteCtx.WithExecMode(sdk.ExecMode(execModeSimulate))
}
newCtx, err := app.anteHandler(anteCtx, tx, mode == execModeSimulate)
if !newCtx.IsZero() {

View File

@ -49,8 +49,8 @@ type Context struct {
voteInfo []abci.VoteInfo // Deprecated: use Cometinfo.LastCommit.Votes instead, will be removed after 0.51
gasMeter storetypes.GasMeter
blockGasMeter storetypes.GasMeter
checkTx bool
recheckTx bool // if recheckTx == true, then checkTx must also be true
checkTx bool // Deprecated: use execMode instead, will be removed after 0.51
recheckTx bool // if recheckTx == true, then checkTx must also be true // Depreacted: use execMode instead, will be removed after 0.51
sigverifyTx bool // when run simulation, because the private key corresponding to the account in the genesis.json randomly generated, we must skip the sigverify.
execMode ExecMode
minGasPrice DecCoins
@ -78,8 +78,8 @@ func (c Context) Logger() log.Logger { return c.logge
func (c Context) VoteInfos() []abci.VoteInfo { return c.voteInfo }
func (c Context) GasMeter() storetypes.GasMeter { return c.gasMeter }
func (c Context) BlockGasMeter() storetypes.GasMeter { return c.blockGasMeter }
func (c Context) IsCheckTx() bool { return c.checkTx }
func (c Context) IsReCheckTx() bool { return c.recheckTx }
func (c Context) IsCheckTx() bool { return c.checkTx } // Deprecated: use execMode instead
func (c Context) IsReCheckTx() bool { return c.recheckTx } // Deprecated: use execMode instead
func (c Context) IsSigverifyTx() bool { return c.sigverifyTx }
func (c Context) ExecMode() ExecMode { return c.execMode }
func (c Context) MinGasPrices() DecCoins { return c.minGasPrice }

View File

@ -42,6 +42,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
### API Breaking Changes
* [#17985](https://github.com/cosmos/cosmos-sdk/pull/17985) Remove `StdTxConfig`
* [#19161](https://github.com/cosmos/cosmos-sdk/pull/19161) Remove `simulate` from `SetGasMeter`
### Consensus Breaking Changes

View File

@ -1321,7 +1321,7 @@ func TestAnteHandlerReCheck(t *testing.T) {
txBuilder, err := suite.clientCtx.TxConfig.WrapTxBuilder(tx)
require.NoError(t, err)
suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(2)
suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(3)
_, err = suite.anteHandler(suite.ctx, txBuilder.GetTx(), false)
require.Nil(t, err, "AnteHandler errored on recheck unexpectedly: %v", err)

View File

@ -26,7 +26,7 @@ func NewValidateBasicDecorator() ValidateBasicDecorator {
func (vbd ValidateBasicDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
// no need to validate basic on recheck tx, call next antehandler
if ctx.IsReCheckTx() {
if ctx.ExecMode() == sdk.ExecModeReCheck {
return next(ctx, tx, simulate)
}
@ -101,7 +101,7 @@ func (cgts ConsumeTxSizeGasDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, sim
ctx.GasMeter().ConsumeGas(params.TxSizeCostPerByte*storetypes.Gas(len(ctx.TxBytes())), "txSize")
// simulate gas cost for signatures in simulate mode
if simulate {
if ctx.ExecMode() == sdk.ExecModeSimulate {
// in simulate mode, each element should be a nil signature
sigs, err := sigTx.GetSignaturesV2()
if err != nil {

View File

@ -164,6 +164,7 @@ func TestConsumeGasForTxSize(t *testing.T) {
// Set suite.ctx with smaller simulated TxBytes manually
suite.ctx = suite.ctx.WithTxBytes(simTxBytes)
suite.ctx = suite.ctx.WithExecMode(sdk.ExecModeSimulate)
beforeSimGas := suite.ctx.GasMeter().GasConsumed()

View File

@ -45,7 +45,7 @@ func (dfd DeductFeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bo
return ctx, errorsmod.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx")
}
if !simulate && ctx.BlockHeight() > 0 && feeTx.GetGas() == 0 {
if ctx.ExecMode() != sdk.ExecModeSimulate && ctx.BlockHeight() > 0 && feeTx.GetGas() == 0 {
return ctx, errorsmod.Wrap(sdkerrors.ErrInvalidGasLimit, "must provide positive gas")
}
@ -55,7 +55,7 @@ func (dfd DeductFeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bo
)
fee := feeTx.GetFee()
if !simulate {
if ctx.ExecMode() != sdk.ExecModeSimulate {
fee, priority, err = dfd.txFeeChecker(ctx, tx)
if err != nil {
return ctx, err

View File

@ -45,6 +45,7 @@ func TestDeductFeeDecorator_ZeroGas(t *testing.T) {
require.Error(t, err)
// zero gas is accepted in simulation mode
s.ctx = s.ctx.WithExecMode(sdk.ExecModeSimulate)
_, err = antehandler(s.ctx, tx, true)
require.NoError(t, err)
}
@ -78,28 +79,21 @@ func TestEnsureMempoolFees(t *testing.T) {
highGasPrice := []sdk.DecCoin{atomPrice}
s.ctx = s.ctx.WithMinGasPrices(highGasPrice)
// Set IsCheckTx to true
s.ctx = s.ctx.WithIsCheckTx(true)
// antehandler errors with insufficient fees
_, err = antehandler(s.ctx, tx, false)
require.NotNil(t, err, "Decorator should have errored on too low fee for local gasPrice")
// antehandler should not error since we do not check minGasPrice in simulation mode
cacheCtx, _ := s.ctx.CacheContext()
cacheCtx = cacheCtx.WithExecMode(sdk.ExecModeSimulate)
_, err = antehandler(cacheCtx, tx, true)
require.Nil(t, err, "Decorator should not have errored in simulation mode")
// Set IsCheckTx to false
s.ctx = s.ctx.WithIsCheckTx(false)
// antehandler should not error since we do not check minGasPrice in DeliverTx
s.ctx = s.ctx.WithExecMode(sdk.ExecModeFinalize)
_, err = antehandler(s.ctx, tx, false)
require.Nil(t, err, "MempoolFeeDecorator returned error in DeliverTx")
// Set IsCheckTx back to true for testing sufficient mempool fee
s.ctx = s.ctx.WithIsCheckTx(true)
atomPrice = sdk.NewDecCoinFromDec("atom", math.LegacyNewDec(0).Quo(math.LegacyNewDec(100000)))
lowGasPrice := []sdk.DecCoin{atomPrice}
s.ctx = s.ctx.WithMinGasPrices(lowGasPrice)

View File

@ -33,11 +33,11 @@ func (sud SetUpContextDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate
if !ok {
// Set a gas meter with limit 0 as to prevent an infinite gas meter attack
// during runTx.
newCtx = SetGasMeter(simulate, ctx, 0)
newCtx = SetGasMeter(ctx, 0)
return newCtx, errorsmod.Wrap(sdkerrors.ErrTxDecode, "Tx must be GasTx")
}
newCtx = SetGasMeter(simulate, ctx, gasTx.GetGas())
newCtx = SetGasMeter(ctx, gasTx.GetGas())
if cp := ctx.ConsensusParams(); cp.Block != nil {
// If there exists a maximum block gas limit, we must ensure that the tx
@ -71,10 +71,10 @@ func (sud SetUpContextDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate
}
// SetGasMeter returns a new context with a gas meter set from a given context.
func SetGasMeter(simulate bool, ctx sdk.Context, gasLimit uint64) sdk.Context {
func SetGasMeter(ctx sdk.Context, gasLimit uint64) sdk.Context {
// In various cases such as simulation and during the genesis block, we do not
// meter any gas utilization.
if simulate || ctx.BlockHeight() == 0 {
if ctx.ExecMode() == sdk.ExecModeSimulate || ctx.BlockHeight() == 0 {
return ctx.WithGasMeter(storetypes.NewInfiniteGasMeter())
}

View File

@ -171,7 +171,7 @@ func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simul
}
for i := range signers {
err = svd.authenticate(ctx, sigTx, simulate, signers[i], signatures[i], pubKeys[i])
err = svd.authenticate(ctx, sigTx, signers[i], signatures[i], pubKeys[i])
if err != nil {
return ctx, err
}
@ -204,7 +204,7 @@ func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simul
}
// authenticate the authentication of the TX for a specific tx signer.
func (svd SigVerificationDecorator) authenticate(ctx sdk.Context, tx authsigning.Tx, simulate bool, signer []byte, sig signing.SignatureV2, txPubKey cryptotypes.PubKey) error {
func (svd SigVerificationDecorator) authenticate(ctx sdk.Context, tx authsigning.Tx, signer []byte, sig signing.SignatureV2, txPubKey cryptotypes.PubKey) error {
acc, err := GetSignerAcc(ctx, svd.ak, signer)
if err != nil {
return err
@ -213,18 +213,18 @@ func (svd SigVerificationDecorator) authenticate(ctx sdk.Context, tx authsigning
// the account is without a pubkey, let's attempt to check if in the
// tx we were correctly provided a valid pubkey.
if acc.GetPubKey() == nil {
err = svd.setPubKey(ctx.IsSigverifyTx(), simulate, acc, txPubKey)
err = svd.setPubKey(ctx.IsSigverifyTx(), ctx.ExecMode() == sdk.ExecModeSimulate, acc, txPubKey)
if err != nil {
return err
}
}
err = svd.consumeSignatureGas(ctx, simulate, acc.GetPubKey(), sig)
err = svd.consumeSignatureGas(ctx, acc.GetPubKey(), sig)
if err != nil {
return err
}
err = svd.verifySig(ctx, simulate, tx, acc, sig)
err = svd.verifySig(ctx, tx, acc, sig)
if err != nil {
return err
}
@ -241,11 +241,10 @@ func (svd SigVerificationDecorator) authenticate(ctx sdk.Context, tx authsigning
// consumeSignatureGas will consume gas according to the pub-key being verified.
func (svd SigVerificationDecorator) consumeSignatureGas(
ctx sdk.Context,
simulate bool,
pubKey cryptotypes.PubKey,
signature signing.SignatureV2,
) error {
if simulate && pubKey == nil {
if ctx.ExecMode() == sdk.ExecModeSimulate && pubKey == nil {
pubKey = simSecp256k1Pubkey
}
@ -264,7 +263,7 @@ func (svd SigVerificationDecorator) consumeSignatureGas(
}
// verifySig will verify the signature of the provided signer account.
func (svd SigVerificationDecorator) verifySig(ctx sdk.Context, simulate bool, tx sdk.Tx, acc sdk.AccountI, sig signing.SignatureV2) error {
func (svd SigVerificationDecorator) verifySig(ctx sdk.Context, tx sdk.Tx, acc sdk.AccountI, sig signing.SignatureV2) error {
if sig.Sequence != acc.GetSequence() {
return errorsmod.Wrapf(
sdkerrors.ErrWrongSequence,
@ -275,7 +274,7 @@ func (svd SigVerificationDecorator) verifySig(ctx sdk.Context, simulate bool, tx
// we're in simulation mode, or in ReCheckTx, or context is not
// on sig verify tx, then we do not need to verify the signatures
// in the tx.
if simulate || ctx.IsReCheckTx() || !ctx.IsSigverifyTx() {
if ctx.ExecMode() == sdk.ExecModeSimulate || ctx.IsReCheckTx() || !ctx.IsSigverifyTx() {
return nil
}

View File

@ -24,7 +24,7 @@ func checkTxFeeWithValidatorMinGasPrices(ctx sdk.Context, tx sdk.Tx) (sdk.Coins,
// Ensure that the provided fees meet a minimum threshold for the validator,
// if this is a CheckTx. This is only for local mempool purposes, and thus
// is only ran on check tx.
if ctx.IsCheckTx() {
if ctx.ExecMode() == sdk.ExecModeCheck {
minGasPrices := ctx.MinGasPrices()
if !minGasPrices.IsZero() {
requiredFees := make(sdk.Coins, len(minGasPrices))