-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
191 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package ante | ||
|
||
import ( | ||
errorsmod "cosmossdk.io/errors" | ||
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" | ||
sdkante "github.com/cosmos/cosmos-sdk/x/auth/ante" | ||
ibcante "github.com/cosmos/ibc-go/v7/modules/core/ante" | ||
) | ||
|
||
// NewAnteHandler returns an AnteHandler that checks and increments sequence | ||
// numbers, checks signatures & account numbers, and deducts fees from the first | ||
// signer. | ||
func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { | ||
if options.AccountKeeper == nil { | ||
return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "account keeper is required for ante builder") | ||
} | ||
|
||
if options.BankKeeper == nil { | ||
return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "bank keeper is required for ante builder") | ||
} | ||
|
||
if options.SignModeHandler == nil { | ||
return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder") | ||
} | ||
|
||
if options.WasmConfig == nil { | ||
return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "wasm config is required for ante builder") | ||
} | ||
|
||
if options.FeegrantKeeper == nil { | ||
return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "feegrant keeper is required for ante builder") | ||
} | ||
|
||
sigGasConsumer := options.SigGasConsumer | ||
if sigGasConsumer == nil { | ||
sigGasConsumer = sdkante.DefaultSigVerificationGasConsumer | ||
} | ||
|
||
txFeeChecker := options.TxFeeChecker | ||
if txFeeChecker == nil { | ||
txFeeChecker = CheckTxFeeWithValidatorMinGasPrices | ||
} | ||
|
||
anteDecorators := []sdk.AnteDecorator{ | ||
sdkante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first | ||
wasmkeeper.NewLimitSimulationGasDecorator(options.WasmConfig.SimulationGasLimit), // after setup context to enforce limits early | ||
wasmkeeper.NewCountTXDecorator(options.TXCounterStoreKey), | ||
NewMinCommissionDecorator(options.Cdc, options.StakingKeeper, options.BankKeeper, options.ParameterKeeper), | ||
sdkante.NewExtensionOptionsDecorator(options.ExtensionOptionChecker), | ||
sdkante.NewValidateBasicDecorator(), | ||
sdkante.NewTxTimeoutHeightDecorator(), | ||
sdkante.NewValidateMemoDecorator(options.AccountKeeper), | ||
sdkante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper), | ||
sdkante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, txFeeChecker), | ||
sdkante.NewSetPubKeyDecorator(options.AccountKeeper), // SetPubKeyDecorator must be called before all signature verification decorators | ||
sdkante.NewValidateSigCountDecorator(options.AccountKeeper), | ||
sdkante.NewSigGasConsumeDecorator(options.AccountKeeper, sigGasConsumer), | ||
sdkante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler), | ||
sdkante.NewIncrementSequenceDecorator(options.AccountKeeper), | ||
ibcante.NewRedundantRelayDecorator(options.IBCKeeper), | ||
} | ||
|
||
return sdk.ChainAnteDecorators(anteDecorators...), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package ante | ||
|
||
import ( | ||
wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" | ||
"github.com/cosmos/cosmos-sdk/codec" | ||
storetypes "github.com/cosmos/cosmos-sdk/store/types" | ||
sdkante "github.com/cosmos/cosmos-sdk/x/auth/ante" | ||
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" | ||
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" | ||
ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" | ||
parameterkeeper "github.com/elys-network/elys/x/parameter/keeper" | ||
) | ||
|
||
// HandlerOptions extends the SDK's AnteHandler options by requiring the IBC | ||
// channel keeper. | ||
type HandlerOptions struct { | ||
sdkante.HandlerOptions | ||
Cdc codec.BinaryCodec | ||
StakingKeeper *stakingkeeper.Keeper | ||
BankKeeper bankkeeper.Keeper | ||
IBCKeeper *ibckeeper.Keeper | ||
WasmConfig *wasmtypes.WasmConfig | ||
ParameterKeeper parameterkeeper.Keeper | ||
TXCounterStoreKey storetypes.StoreKey | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package ante | ||
|
||
import ( | ||
"math" | ||
"strings" | ||
|
||
errorsmod "cosmossdk.io/errors" | ||
sdkmath "cosmossdk.io/math" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" | ||
parametertypes "github.com/elys-network/elys/x/parameter/types" | ||
) | ||
|
||
// 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() | ||
|
||
// 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() | ||
|
||
// Check for specific message types to adjust gas price | ||
msgs := tx.GetMsgs() | ||
if len(msgs) == 1 { | ||
msgType := strings.ToLower(sdk.MsgTypeURL(msgs[0])) | ||
if strings.Contains(msgType, "/elys.oracle.msgfeedprice") || | ||
strings.Contains(msgType, "/elys.oracle.msgfeedmultipleprices") { | ||
// set the minimum gas price to 0 ELYS if the message is a feed price | ||
minGasPrice := sdk.DecCoin{ | ||
Denom: parametertypes.Elys, | ||
Amount: sdk.ZeroDec(), | ||
} | ||
if !minGasPrice.IsValid() { | ||
return nil, 0, errorsmod.Wrap(sdkerrors.ErrLogic, "invalid gas price") | ||
} | ||
minGasPrices = sdk.NewDecCoins(minGasPrice) | ||
} | ||
|
||
// print minGasPrices | ||
ctx.Logger().Info("Minimum gas prices: " + minGasPrices.String()) | ||
} | ||
|
||
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters