From 9a2a3eeed1e8329d95f248eace808b10707127e9 Mon Sep 17 00:00:00 2001 From: Alex Johnson <alex@skip.money> Date: Sun, 16 Jun 2024 11:46:31 -0400 Subject: [PATCH] fix: don't fail post handler on simulate tx with no fee (#122) * ok * ok * format * ok * clean readme * retract * mod bump --- README.md | 6 ++-- go.mod | 7 ++-- go.sum | 10 +++--- x/feemarket/ante/fee.go | 2 +- x/feemarket/ante/fee_test.go | 54 ++++++++++++++++++++++++++-- x/feemarket/post/fee.go | 19 ++++++---- x/feemarket/post/fee_test.go | 68 ++++++++++++++++++++++++++++++++++++ 7 files changed, 146 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 29acdee..e48b9be 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,11 @@ -# `x/feemarket` Specification +# `x/feemarket` Module ## Abstract -This document specifies the feemarket module. - The feemarket module is an implementation of the Additive Increase Multiplicative Decrease (AIMD) EIP-1559 feemarket. More information about the implementation can be found [here](./x/feemarket/README.md). -## Upgrading to FeeMarket +## Upgrading to Feemarket More information about upgrading your chain to `x/feemarket` can be found in our dedicated [guide](docs/UPGRADING.md). diff --git a/go.mod b/go.mod index d168268..c0225cc 100644 --- a/go.mod +++ b/go.mod @@ -29,14 +29,14 @@ require ( github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/skip-mev/chaintestutil v0.0.0-20240514161515-056d7ba45610 github.com/spf13/cast v1.6.0 - github.com/spf13/cobra v1.8.0 + github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.9.0 github.com/vektra/mockery/v2 v2.43.2 golang.org/x/tools v0.22.0 google.golang.org/genproto/googleapis/api v0.0.0-20240610135401-a8a62080eff3 google.golang.org/grpc v1.64.0 - google.golang.org/protobuf v1.34.1 + google.golang.org/protobuf v1.34.2 mvdan.cc/gofumpt v0.6.0 pgregory.net/rapid v1.1.0 ) @@ -351,3 +351,6 @@ replace ( github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 ) + +// simulation and fee UX +retract [v1.0.0, v1.0.2] diff --git a/go.sum b/go.sum index 9de85c3..3b7fea5 100644 --- a/go.sum +++ b/go.sum @@ -442,7 +442,7 @@ github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5n github.com/cosmos/ledger-cosmos-go v0.13.3/go.mod h1:HENcEP+VtahZFw38HZ3+LS3Iv5XV6svsnkk9vdJtLr8= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creachadair/atomicfile v0.3.3 h1:yJlDq8qk9QmD/6ol+jq1X4bcoLNVdYq95+owOnauziE= github.com/creachadair/atomicfile v0.3.3/go.mod h1:X1r9P4wigJlGkYJO1HXZREdkVn+b1yHrsBBMLSj7tak= github.com/creachadair/mtest v0.0.0-20231015022703-31f2ea539dce h1:BFjvg2Oq88/2DOcUFu1ScIwKUn7KJYYvLr6AeuCJD54= @@ -1236,8 +1236,8 @@ github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -2026,8 +2026,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/x/feemarket/ante/fee.go b/x/feemarket/ante/fee.go index 912624b..1e6c6dc 100644 --- a/x/feemarket/ante/fee.go +++ b/x/feemarket/ante/fee.go @@ -104,7 +104,7 @@ func (dfd feeMarketCheckDecorator) anteHandle(ctx sdk.Context, tx sdk.Tx, simula var feeCoin sdk.Coin if simulate && len(feeCoins) == 0 { - feeCoin = sdk.NewCoin(params.FeeDenom, sdkmath.NewInt(0)) + feeCoin = sdk.NewCoin(params.FeeDenom, sdkmath.ZeroInt()) } else { feeCoin = feeCoins[0] } diff --git a/x/feemarket/ante/fee_test.go b/x/feemarket/ante/fee_test.go index c520035..69e36ab 100644 --- a/x/feemarket/ante/fee_test.go +++ b/x/feemarket/ante/fee_test.go @@ -5,7 +5,6 @@ import ( "testing" "cosmossdk.io/math" - "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -77,7 +76,7 @@ func TestAnteHandle(t *testing.T) { ExpErr: sdkerrors.ErrOutOfGas, }, { - Name: "0 gas given should pass in simulate", + Name: "0 gas given should pass in simulate - no fee", Malleate: func(suite *antesuite.TestSuite) antesuite.TestCaseArgs { accs := suite.CreateTestAccounts(1) @@ -93,6 +92,23 @@ func TestAnteHandle(t *testing.T) { ExpPass: true, ExpErr: nil, }, + { + Name: "0 gas given should pass in simulate - fee", + Malleate: func(suite *antesuite.TestSuite) antesuite.TestCaseArgs { + accs := suite.CreateTestAccounts(1) + + return antesuite.TestCaseArgs{ + Msgs: []sdk.Msg{testdata.NewTestMsg(accs[0].Account.GetAddress())}, + GasLimit: 0, + FeeAmount: validFee, + } + }, + RunAnte: true, + RunPost: false, + Simulate: true, + ExpPass: true, + ExpErr: nil, + }, { Name: "signer has enough funds, should pass", Malleate: func(suite *antesuite.TestSuite) antesuite.TestCaseArgs { @@ -125,6 +141,40 @@ func TestAnteHandle(t *testing.T) { ExpPass: true, ExpErr: nil, }, + { + Name: "no fee - fail", + Malleate: func(s *antesuite.TestSuite) antesuite.TestCaseArgs { + accs := s.CreateTestAccounts(1) + + return antesuite.TestCaseArgs{ + Msgs: []sdk.Msg{testdata.NewTestMsg(accs[0].Account.GetAddress())}, + GasLimit: 1000000000, + FeeAmount: nil, + } + }, + RunAnte: true, + RunPost: true, + Simulate: false, + ExpPass: false, + ExpErr: types.ErrNoFeeCoins, + }, + { + Name: "no gas limit - fail", + Malleate: func(s *antesuite.TestSuite) antesuite.TestCaseArgs { + accs := s.CreateTestAccounts(1) + + return antesuite.TestCaseArgs{ + Msgs: []sdk.Msg{testdata.NewTestMsg(accs[0].Account.GetAddress())}, + GasLimit: 0, + FeeAmount: nil, + } + }, + RunAnte: true, + RunPost: true, + Simulate: false, + ExpPass: false, + ExpErr: sdkerrors.ErrInvalidGasLimit, + }, } for _, tc := range testCases { diff --git a/x/feemarket/post/fee.go b/x/feemarket/post/fee.go index 18a5b24..0433d0b 100644 --- a/x/feemarket/post/fee.go +++ b/x/feemarket/post/fee.go @@ -2,9 +2,10 @@ package post import ( "bytes" - "cosmossdk.io/math" "fmt" + "cosmossdk.io/math" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" @@ -75,14 +76,20 @@ func (dfd FeeMarketDeductDecorator) PostHandle(ctx sdk.Context, tx sdk.Tx, simul feeCoins := feeTx.GetFee() gas := ctx.GasMeter().GasConsumed() // use context gas consumed - if len(feeCoins) != 1 { - if len(feeCoins) == 0 { - return ctx, errorsmod.Wrapf(feemarkettypes.ErrNoFeeCoins, "got length %d", len(feeCoins)) - } + if len(feeCoins) == 0 && !simulate { + return ctx, errorsmod.Wrapf(feemarkettypes.ErrNoFeeCoins, "got length %d", len(feeCoins)) + } + if len(feeCoins) > 1 { return ctx, errorsmod.Wrapf(feemarkettypes.ErrTooManyFeeCoins, "got length %d", len(feeCoins)) } - feeCoin := feeCoins[0] + var feeCoin sdk.Coin + if simulate && len(feeCoins) == 0 { + feeCoin = sdk.NewCoin(params.FeeDenom, math.ZeroInt()) + } else { + feeCoin = feeCoins[0] + } + feeGas := int64(feeTx.GetGas()) var ( diff --git a/x/feemarket/post/fee_test.go b/x/feemarket/post/fee_test.go index a23a5bd..4a6d5a0 100644 --- a/x/feemarket/post/fee_test.go +++ b/x/feemarket/post/fee_test.go @@ -343,6 +343,74 @@ func TestPostHandle(t *testing.T) { ExpPass: true, ExpErr: nil, }, + { + Name: "0 gas given should pass in simulate - no fee", + Malleate: func(suite *antesuite.TestSuite) antesuite.TestCaseArgs { + accs := suite.CreateTestAccounts(1) + + return antesuite.TestCaseArgs{ + Msgs: []sdk.Msg{testdata.NewTestMsg(accs[0].Account.GetAddress())}, + GasLimit: 0, + FeeAmount: nil, + } + }, + RunAnte: true, + RunPost: false, + Simulate: true, + ExpPass: true, + ExpErr: nil, + }, + { + Name: "0 gas given should pass in simulate - fee", + Malleate: func(suite *antesuite.TestSuite) antesuite.TestCaseArgs { + accs := suite.CreateTestAccounts(1) + + return antesuite.TestCaseArgs{ + Msgs: []sdk.Msg{testdata.NewTestMsg(accs[0].Account.GetAddress())}, + GasLimit: 0, + FeeAmount: validFee, + } + }, + RunAnte: true, + RunPost: false, + Simulate: true, + ExpPass: true, + ExpErr: nil, + }, + { + Name: "no fee - fail", + Malleate: func(s *antesuite.TestSuite) antesuite.TestCaseArgs { + accs := s.CreateTestAccounts(1) + + return antesuite.TestCaseArgs{ + Msgs: []sdk.Msg{testdata.NewTestMsg(accs[0].Account.GetAddress())}, + GasLimit: 1000000000, + FeeAmount: nil, + } + }, + RunAnte: true, + RunPost: true, + Simulate: false, + ExpPass: false, + ExpErr: types.ErrNoFeeCoins, + }, + { + Name: "no gas limit - fail", + Malleate: func(s *antesuite.TestSuite) antesuite.TestCaseArgs { + accs := s.CreateTestAccounts(1) + + return antesuite.TestCaseArgs{ + Msgs: []sdk.Msg{testdata.NewTestMsg(accs[0].Account.GetAddress())}, + GasLimit: 0, + FeeAmount: nil, + } + }, + RunAnte: true, + RunPost: true, + Simulate: false, + ExpPass: false, + ExpErr: sdkerrors.ErrInvalidGasLimit, + }, } for _, tc := range testCases {