package app import ( _ "embed" "math" errorsmod "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "git.vdb.to/cerc-io/laconicd/app/params" ) // Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.50.10/x/auth/ante/validator_tx_fee.go#L15 // checkTxFeeWithValidatorMinGasPrices implements the default fee logic, where the minimum price per // unit of gas is fixed and set by each validator, can the tx priority is computed from the gas price. func checkTxFeeWithValidatorMinGasPrices(ctx sdk.Context, tx sdk.Tx) (sdk.Coins, int64, error) { feeTx, ok := tx.(sdk.FeeTx) if !ok { return nil, 0, errorsmod.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx") } feeCoins := feeTx.GetFee() gas := feeTx.GetGas() // Only allow alnt as a fee token for _, coin := range feeCoins { if coin.Denom != params.CoinUnit { return nil, 0, errorsmod.Wrapf(sdkerrors.ErrInvalidCoins, "invalid fee denom %s, only %s is accepted", coin.Denom, params.CoinUnit) } } // 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() { minGasPrices := ctx.MinGasPrices() if !minGasPrices.IsZero() { requiredFees := make(sdk.Coins, len(minGasPrices)) // Determine the required fees by multiplying each required minimum gas // price by the gas limit, where fee = ceil(minGasPrice * gasLimit). glDec := sdkmath.LegacyNewDec(int64(gas)) for i, gp := range minGasPrices { fee := gp.Amount.Mul(glDec) requiredFees[i] = sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt()) } if !feeCoins.IsAnyGTE(requiredFees) { return nil, 0, errorsmod.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeCoins, requiredFees) } } } priority := getTxPriority(feeCoins, int64(gas)) return feeCoins, priority, nil } // getTxPriority returns a naive tx priority based on the amount of the smallest denomination of the gas price // provided in a transaction. // NOTE: This implementation should be used with a great consideration as it opens potential attack vectors // where txs with multiple coins could not be prioritize as expected. func getTxPriority(fee sdk.Coins, gas int64) int64 { var priority int64 for _, c := range fee { p := int64(math.MaxInt64) gasPrice := c.Amount.QuoRaw(gas) if gasPrice.IsInt64() { p = gasPrice.Int64() } if priority == 0 || p < priority { priority = p } } return priority }