From 545133f9dad92afa409aa67ea39b40af8d3695ac Mon Sep 17 00:00:00 2001 From: Xiaoyu Chen Date: Wed, 15 Jun 2022 16:29:43 -0700 Subject: [PATCH] Gasless transaction fixes --- app/ante.go | 5 +++- x/dex/ante.go | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 x/dex/ante.go diff --git a/app/ante.go b/app/ante.go index ffe6ec4807..974665b12e 100644 --- a/app/ante.go +++ b/app/ante.go @@ -8,6 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/ante" ibcante "github.com/cosmos/ibc-go/v3/modules/core/ante" ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper" + "github.com/sei-protocol/sei-chain/x/dex" "github.com/sei-protocol/sei-chain/x/oracle" oraclekeeper "github.com/sei-protocol/sei-chain/x/oracle/keeper" ) @@ -48,13 +49,15 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { sigGasConsumer = ante.DefaultSigVerificationGasConsumer } + memPoolDecorator := ante.NewMempoolFeeDecorator() anteDecorators := []sdk.AnteDecorator{ ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first + dex.NewGaslessDecorator(), wasmkeeper.NewLimitSimulationGasDecorator(options.WasmConfig.SimulationGasLimit), // after setup context to enforce limits early wasmkeeper.NewCountTXDecorator(options.TXCounterStoreKey), ante.NewRejectExtensionOptionsDecorator(), oracle.NewSpammingPreventionDecorator(*options.OracleKeeper), - ante.NewMempoolFeeDecorator(), + dex.NewGaslessDecoratorWrapper(&memPoolDecorator), ante.NewValidateBasicDecorator(), ante.NewTxTimeoutHeightDecorator(), ante.NewValidateMemoDecorator(options.AccountKeeper), diff --git a/x/dex/ante.go b/x/dex/ante.go new file mode 100644 index 0000000000..17c2ade8e0 --- /dev/null +++ b/x/dex/ante.go @@ -0,0 +1,77 @@ +package dex + +import ( + "bytes" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +// TODO: migrate this into params state +var WHITELISTED_GASLESS_CANCELLATION_ADDRS = []sdk.AccAddress{} + +type GaslessDecoratorWrapper struct { + wrapped sdk.AnteDecorator +} + +func NewGaslessDecoratorWrapper(wrapped sdk.AnteDecorator) GaslessDecoratorWrapper { + return GaslessDecoratorWrapper{wrapped: wrapped} +} + +func (gd GaslessDecoratorWrapper) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { + if !isTxGasless(tx) { + return gd.wrapped.AnteHandle(ctx, tx, simulate, next) + } + + // skip the wrapped if gasless + return next(ctx, tx, simulate) +} + +type GaslessDecorator struct{} + +func NewGaslessDecorator() GaslessDecorator { + return GaslessDecorator{} +} + +func (gd GaslessDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { + if !isTxGasless(tx) { + return next(ctx, tx, simulate) + } + gaslessMeter := sdk.NewInfiniteGasMeter() + + return next(ctx.WithGasMeter(gaslessMeter), tx, simulate) +} + +func isTxGasless(tx sdk.Tx) bool { + for _, msg := range tx.GetMsgs() { + switch msg.(type) { + case *types.MsgPlaceOrders: + continue + case *types.MsgCancelOrders: + if allSignersWhitelisted(msg) { + continue + } else { + return false + } + default: + return false + } + } + return true +} + +func allSignersWhitelisted(msg sdk.Msg) bool { + for _, signer := range msg.GetSigners() { + isWhitelisted := false + for _, whitelisted := range WHITELISTED_GASLESS_CANCELLATION_ADDRS { + if bytes.Compare(signer, whitelisted) == 0 { + isWhitelisted = true + break + } + } + if !isWhitelisted { + return false + } + } + return true +}