Skip to content

Commit f0997fb

Browse files
author
Alex Johnson
authored
fix: nil check in post (#118)
* fix * fix with check * add early exit * fix
1 parent efbd10d commit f0997fb

File tree

4 files changed

+134
-68
lines changed

4 files changed

+134
-68
lines changed

docs/INTEGRATIONS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ There are two ways to construct a transaction with `gasPrice`:
6767

6868
### Understanding Fee Deducted
6969

70-
The actual amount of fee deducted from the fee payer is based on gas consumed, not `gasLimit`.
70+
The actual amount of fee deducted from the fee payer is based on gas consumed, not `gasLimit`. The total amount deducted (`fee + tip`) will be equal to the amount of fee specified on your transaction.
7171

7272
The amount consumed is equal to the `inferredTip + gasPrice * gasConsumed`, where `inferredTip = feeAmount - gasLimit * gasPrice` (This may be different than the tip you specified when building the transaction because the `gasPrice` on chain may have changed since when you queried it.)
7373

x/feemarket/ante/fee.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,6 @@ func (dfd feeMarketCheckDecorator) anteHandle(ctx sdk.Context, tx sdk.Tx, simula
135135
}
136136

137137
ctx = ctx.WithPriority(GetTxPriority(priorityFee, int64(gas), baseGasPrice))
138-
return next(ctx, tx, simulate)
139138
}
140139
return next(ctx, tx, simulate)
141140
}

x/feemarket/post/fee.go

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package post
22

33
import (
44
"bytes"
5+
"cosmossdk.io/math"
56
"fmt"
67

78
errorsmod "cosmossdk.io/errors"
@@ -54,11 +55,6 @@ func (dfd FeeMarketDeductDecorator) PostHandle(ctx sdk.Context, tx sdk.Tx, simul
5455
return ctx, errorsmod.Wrap(sdkerrors.ErrInvalidGasLimit, "must provide positive gas")
5556
}
5657

57-
var (
58-
tip sdk.Coin
59-
payCoin sdk.Coin
60-
)
61-
6258
// update fee market params
6359
params, err := dfd.feemarketKeeper.GetParams(ctx)
6460
if err != nil {
@@ -89,6 +85,11 @@ func (dfd FeeMarketDeductDecorator) PostHandle(ctx sdk.Context, tx sdk.Tx, simul
8985
feeCoin := feeCoins[0]
9086
feeGas := int64(feeTx.GetGas())
9187

88+
var (
89+
tip = sdk.NewCoin(feeCoin.Denom, math.ZeroInt())
90+
payCoin = feeCoin
91+
)
92+
9293
minGasPrice, err := dfd.feemarketKeeper.GetMinGasPrice(ctx, feeCoin.GetDenom())
9394
if err != nil {
9495
return ctx, errorsmod.Wrapf(err, "unable to get min gas price for denom %s", feeCoins[0].GetDenom())
@@ -107,7 +108,7 @@ func (dfd FeeMarketDeductDecorator) PostHandle(ctx sdk.Context, tx sdk.Tx, simul
107108
}
108109

109110
ctx.Logger().Info("fee deduct post handle",
110-
"fee", feeCoins,
111+
"fee", payCoin,
111112
"tip", tip,
112113
)
113114

@@ -160,9 +161,11 @@ func (dfd FeeMarketDeductDecorator) DeductFeeAndTip(ctx sdk.Context, sdkTx sdk.T
160161
if dfd.feegrantKeeper == nil {
161162
return sdkerrors.ErrInvalidRequest.Wrap("fee grants are not enabled")
162163
} else if !bytes.Equal(feeGranter, feePayer) {
163-
err := dfd.feegrantKeeper.UseGrantedFees(ctx, feeGranter, feePayer, sdk.NewCoins(fee), sdkTx.GetMsgs())
164-
if err != nil {
165-
return errorsmod.Wrapf(err, "%s does not allow to pay fees for %s", feeGranter, feePayer)
164+
if !fee.IsNil() {
165+
err := dfd.feegrantKeeper.UseGrantedFees(ctx, feeGranter, feePayer, sdk.NewCoins(fee), sdkTx.GetMsgs())
166+
if err != nil {
167+
return errorsmod.Wrapf(err, "%s does not allow to pay fees for %s", feeGranter, feePayer)
168+
}
166169
}
167170
}
168171

@@ -177,7 +180,7 @@ func (dfd FeeMarketDeductDecorator) DeductFeeAndTip(ctx sdk.Context, sdkTx sdk.T
177180
var events sdk.Events
178181

179182
// deduct the fees and tip
180-
if !fee.Amount.IsNil() && !fee.IsZero() {
183+
if !fee.IsNil() {
181184
err := DeductCoins(dfd.bankKeeper, ctx, deductFeesFromAcc, sdk.NewCoins(fee), distributeFees)
182185
if err != nil {
183186
return err
@@ -191,7 +194,7 @@ func (dfd FeeMarketDeductDecorator) DeductFeeAndTip(ctx sdk.Context, sdkTx sdk.T
191194
}
192195

193196
proposer := sdk.AccAddress(ctx.BlockHeader().ProposerAddress)
194-
if !tip.Amount.IsNil() && !tip.IsZero() {
197+
if !tip.IsNil() {
195198
err := SendTip(dfd.bankKeeper, ctx, deductFeesFromAcc.GetAddress(), proposer, sdk.NewCoins(tip))
196199
if err != nil {
197200
return err
@@ -212,10 +215,6 @@ func (dfd FeeMarketDeductDecorator) DeductFeeAndTip(ctx sdk.Context, sdkTx sdk.T
212215
// DeductCoins deducts coins from the given account.
213216
// Coins can be sent to the default fee collector (causes coins to be distributed to stakers) or sent to the feemarket fee collector account (causes coins to be burned).
214217
func DeductCoins(bankKeeper BankKeeper, ctx sdk.Context, acc sdk.AccountI, coins sdk.Coins, distributeFees bool) error {
215-
if !coins.IsValid() {
216-
return errorsmod.Wrapf(sdkerrors.ErrInsufficientFee, "invalid coin amount: %s", coins)
217-
}
218-
219218
targetModuleAcc := feemarkettypes.FeeCollectorName
220219
if distributeFees {
221220
targetModuleAcc = authtypes.FeeCollectorName
@@ -231,10 +230,6 @@ func DeductCoins(bankKeeper BankKeeper, ctx sdk.Context, acc sdk.AccountI, coins
231230

232231
// SendTip sends a tip to the current block proposer.
233232
func SendTip(bankKeeper BankKeeper, ctx sdk.Context, acc, proposer sdk.AccAddress, coins sdk.Coins) error {
234-
if !coins.IsValid() {
235-
return errorsmod.Wrapf(sdkerrors.ErrInsufficientFee, "invalid coin amount: %s", coins)
236-
}
237-
238233
err := bankKeeper.SendCoins(ctx, acc, proposer, coins)
239234
if err != nil {
240235
return err

x/feemarket/post/fee_test.go

Lines changed: 119 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@ import (
1818

1919
func TestDeductCoins(t *testing.T) {
2020
tests := []struct {
21-
name string
22-
coins sdk.Coins
23-
wantErr bool
24-
invalidCoin bool
21+
name string
22+
coins sdk.Coins
23+
wantErr bool
2524
}{
2625
{
2726
name: "valid",
@@ -34,25 +33,16 @@ func TestDeductCoins(t *testing.T) {
3433
wantErr: false,
3534
},
3635
{
37-
name: "invalid coins negative amount",
38-
coins: sdk.Coins{sdk.Coin{Denom: "test", Amount: math.NewInt(-1)}},
39-
wantErr: true,
40-
invalidCoin: true,
41-
},
42-
{
43-
name: "invalid coins invalid denom",
44-
coins: sdk.Coins{sdk.Coin{Amount: math.NewInt(1)}},
45-
wantErr: true,
46-
invalidCoin: true,
36+
name: "valid zero coin",
37+
coins: sdk.NewCoins(sdk.NewCoin("test", math.ZeroInt())),
38+
wantErr: false,
4739
},
4840
}
4941
for _, tc := range tests {
5042
t.Run(fmt.Sprintf("Case %s", tc.name), func(t *testing.T) {
5143
s := antesuite.SetupTestSuite(t, true)
5244
acc := s.CreateTestAccounts(1)[0]
53-
if !tc.invalidCoin {
54-
s.MockBankKeeper.On("SendCoinsFromAccountToModule", s.Ctx, acc.Account.GetAddress(), types.FeeCollectorName, tc.coins).Return(nil).Once()
55-
}
45+
s.MockBankKeeper.On("SendCoinsFromAccountToModule", s.Ctx, acc.Account.GetAddress(), types.FeeCollectorName, tc.coins).Return(nil).Once()
5646

5747
if err := post.DeductCoins(s.MockBankKeeper, s.Ctx, acc.Account, tc.coins, false); (err != nil) != tc.wantErr {
5848
s.Errorf(err, "DeductCoins() error = %v, wantErr %v", err, tc.wantErr)
@@ -63,10 +53,9 @@ func TestDeductCoins(t *testing.T) {
6353

6454
func TestDeductCoinsAndDistribute(t *testing.T) {
6555
tests := []struct {
66-
name string
67-
coins sdk.Coins
68-
wantErr bool
69-
invalidCoin bool
56+
name string
57+
coins sdk.Coins
58+
wantErr bool
7059
}{
7160
{
7261
name: "valid",
@@ -79,25 +68,16 @@ func TestDeductCoinsAndDistribute(t *testing.T) {
7968
wantErr: false,
8069
},
8170
{
82-
name: "invalid coins negative amount",
83-
coins: sdk.Coins{sdk.Coin{Denom: "test", Amount: math.NewInt(-1)}},
84-
wantErr: true,
85-
invalidCoin: true,
86-
},
87-
{
88-
name: "invalid coins invalid denom",
89-
coins: sdk.Coins{sdk.Coin{Amount: math.NewInt(1)}},
90-
wantErr: true,
91-
invalidCoin: true,
71+
name: "valid zero coin",
72+
coins: sdk.NewCoins(sdk.NewCoin("test", math.ZeroInt())),
73+
wantErr: false,
9274
},
9375
}
9476
for _, tc := range tests {
9577
t.Run(fmt.Sprintf("Case %s", tc.name), func(t *testing.T) {
9678
s := antesuite.SetupTestSuite(t, true)
9779
acc := s.CreateTestAccounts(1)[0]
98-
if !tc.invalidCoin {
99-
s.MockBankKeeper.On("SendCoinsFromAccountToModule", s.Ctx, acc.Account.GetAddress(), authtypes.FeeCollectorName, tc.coins).Return(nil).Once()
100-
}
80+
s.MockBankKeeper.On("SendCoinsFromAccountToModule", s.Ctx, acc.Account.GetAddress(), authtypes.FeeCollectorName, tc.coins).Return(nil).Once()
10181

10282
if err := post.DeductCoins(s.MockBankKeeper, s.Ctx, acc.Account, tc.coins, true); (err != nil) != tc.wantErr {
10383
s.Errorf(err, "DeductCoins() error = %v, wantErr %v", err, tc.wantErr)
@@ -108,10 +88,9 @@ func TestDeductCoinsAndDistribute(t *testing.T) {
10888

10989
func TestSendTip(t *testing.T) {
11090
tests := []struct {
111-
name string
112-
coins sdk.Coins
113-
wantErr bool
114-
invalidCoin bool
91+
name string
92+
coins sdk.Coins
93+
wantErr bool
11594
}{
11695
{
11796
name: "valid",
@@ -124,19 +103,16 @@ func TestSendTip(t *testing.T) {
124103
wantErr: false,
125104
},
126105
{
127-
name: "invalid coins",
128-
coins: sdk.Coins{sdk.Coin{Amount: math.NewInt(-1)}},
129-
wantErr: true,
130-
invalidCoin: true,
106+
name: "valid zero coin",
107+
coins: sdk.NewCoins(sdk.NewCoin("test", math.ZeroInt())),
108+
wantErr: false,
131109
},
132110
}
133111
for _, tc := range tests {
134112
t.Run(fmt.Sprintf("Case %s", tc.name), func(t *testing.T) {
135113
s := antesuite.SetupTestSuite(t, true)
136114
accs := s.CreateTestAccounts(2)
137-
if !tc.invalidCoin {
138-
s.MockBankKeeper.On("SendCoins", s.Ctx, mock.Anything, mock.Anything, tc.coins).Return(nil).Once()
139-
}
115+
s.MockBankKeeper.On("SendCoins", s.Ctx, mock.Anything, mock.Anything, tc.coins).Return(nil).Once()
140116

141117
if err := post.SendTip(s.MockBankKeeper, s.Ctx, accs[0].Account.GetAddress(), accs[1].Account.GetAddress(), tc.coins); (err != nil) != tc.wantErr {
142118
s.Errorf(err, "SendTip() error = %v, wantErr %v", err, tc.wantErr)
@@ -180,10 +156,28 @@ func TestPostHandle(t *testing.T) {
180156
ExpPass: false,
181157
ExpErr: sdkerrors.ErrInsufficientFunds,
182158
},
159+
{
160+
Name: "signer has no funds - simulate",
161+
Malleate: func(s *antesuite.TestSuite) antesuite.TestCaseArgs {
162+
accs := s.CreateTestAccounts(1)
163+
s.MockBankKeeper.On("SendCoinsFromAccountToModule", mock.Anything, accs[0].Account.GetAddress(), types.FeeCollectorName, mock.Anything).Return(sdkerrors.ErrInsufficientFunds)
164+
165+
return antesuite.TestCaseArgs{
166+
Msgs: []sdk.Msg{testdata.NewTestMsg(accs[0].Account.GetAddress())},
167+
GasLimit: gasLimit,
168+
FeeAmount: validFee,
169+
}
170+
},
171+
RunAnte: true,
172+
RunPost: true,
173+
Simulate: true,
174+
ExpPass: false,
175+
ExpErr: sdkerrors.ErrInsufficientFunds,
176+
},
183177
{
184178
Name: "0 gas given should fail",
185-
Malleate: func(suite *antesuite.TestSuite) antesuite.TestCaseArgs {
186-
accs := suite.CreateTestAccounts(1)
179+
Malleate: func(s *antesuite.TestSuite) antesuite.TestCaseArgs {
180+
accs := s.CreateTestAccounts(1)
187181

188182
return antesuite.TestCaseArgs{
189183
Msgs: []sdk.Msg{testdata.NewTestMsg(accs[0].Account.GetAddress())},
@@ -197,11 +191,31 @@ func TestPostHandle(t *testing.T) {
197191
ExpPass: false,
198192
ExpErr: sdkerrors.ErrInvalidGasLimit,
199193
},
194+
{
195+
Name: "0 gas given should pass - simulate",
196+
Malleate: func(s *antesuite.TestSuite) antesuite.TestCaseArgs {
197+
accs := s.CreateTestAccounts(1)
198+
s.MockBankKeeper.On("SendCoinsFromAccountToModule", mock.Anything, accs[0].Account.GetAddress(), types.FeeCollectorName, mock.Anything).Return(nil)
199+
s.MockBankKeeper.On("SendCoins", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
200+
201+
return antesuite.TestCaseArgs{
202+
Msgs: []sdk.Msg{testdata.NewTestMsg(accs[0].Account.GetAddress())},
203+
GasLimit: 0,
204+
FeeAmount: validFee,
205+
}
206+
},
207+
RunAnte: true,
208+
RunPost: true,
209+
Simulate: true,
210+
ExpPass: true,
211+
ExpErr: nil,
212+
},
200213
{
201214
Name: "signer has enough funds, should pass, no tip",
202215
Malleate: func(s *antesuite.TestSuite) antesuite.TestCaseArgs {
203216
accs := s.CreateTestAccounts(1)
204217
s.MockBankKeeper.On("SendCoinsFromAccountToModule", mock.Anything, accs[0].Account.GetAddress(), types.FeeCollectorName, mock.Anything).Return(nil)
218+
s.MockBankKeeper.On("SendCoins", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
205219

206220
return antesuite.TestCaseArgs{
207221
Msgs: []sdk.Msg{testdata.NewTestMsg(accs[0].Account.GetAddress())},
@@ -234,11 +248,31 @@ func TestPostHandle(t *testing.T) {
234248
ExpPass: true,
235249
ExpErr: nil,
236250
},
251+
{
252+
Name: "signer has enough funds, should pass with tip - simulate",
253+
Malleate: func(s *antesuite.TestSuite) antesuite.TestCaseArgs {
254+
accs := s.CreateTestAccounts(1)
255+
s.MockBankKeeper.On("SendCoinsFromAccountToModule", mock.Anything, accs[0].Account.GetAddress(), types.FeeCollectorName, mock.Anything).Return(nil)
256+
s.MockBankKeeper.On("SendCoins", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
257+
258+
return antesuite.TestCaseArgs{
259+
Msgs: []sdk.Msg{testdata.NewTestMsg(accs[0].Account.GetAddress())},
260+
GasLimit: gasLimit,
261+
FeeAmount: validFeeWithTip,
262+
}
263+
},
264+
RunAnte: true,
265+
RunPost: true,
266+
Simulate: true,
267+
ExpPass: true,
268+
ExpErr: nil,
269+
},
237270
{
238271
Name: "signer has enough funds, should pass, no tip - resolvable denom",
239272
Malleate: func(s *antesuite.TestSuite) antesuite.TestCaseArgs {
240273
accs := s.CreateTestAccounts(1)
241274
s.MockBankKeeper.On("SendCoinsFromAccountToModule", mock.Anything, accs[0].Account.GetAddress(), types.FeeCollectorName, mock.Anything).Return(nil)
275+
s.MockBankKeeper.On("SendCoins", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
242276

243277
return antesuite.TestCaseArgs{
244278
Msgs: []sdk.Msg{testdata.NewTestMsg(accs[0].Account.GetAddress())},
@@ -252,6 +286,25 @@ func TestPostHandle(t *testing.T) {
252286
ExpPass: true,
253287
ExpErr: nil,
254288
},
289+
{
290+
Name: "signer has enough funds, should pass, no tip - resolvable denom - simulate",
291+
Malleate: func(s *antesuite.TestSuite) antesuite.TestCaseArgs {
292+
accs := s.CreateTestAccounts(1)
293+
s.MockBankKeeper.On("SendCoinsFromAccountToModule", mock.Anything, accs[0].Account.GetAddress(), types.FeeCollectorName, mock.Anything).Return(nil)
294+
s.MockBankKeeper.On("SendCoins", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
295+
296+
return antesuite.TestCaseArgs{
297+
Msgs: []sdk.Msg{testdata.NewTestMsg(accs[0].Account.GetAddress())},
298+
GasLimit: gasLimit,
299+
FeeAmount: validResolvableFee,
300+
}
301+
},
302+
RunAnte: true,
303+
RunPost: true,
304+
Simulate: true,
305+
ExpPass: true,
306+
ExpErr: nil,
307+
},
255308
{
256309
Name: "signer has enough funds, should pass with tip - resolvable denom",
257310
Malleate: func(s *antesuite.TestSuite) antesuite.TestCaseArgs {
@@ -271,6 +324,25 @@ func TestPostHandle(t *testing.T) {
271324
ExpPass: true,
272325
ExpErr: nil,
273326
},
327+
{
328+
Name: "signer has enough funds, should pass with tip - resolvable denom - simulate",
329+
Malleate: func(s *antesuite.TestSuite) antesuite.TestCaseArgs {
330+
accs := s.CreateTestAccounts(1)
331+
s.MockBankKeeper.On("SendCoinsFromAccountToModule", mock.Anything, accs[0].Account.GetAddress(), types.FeeCollectorName, mock.Anything).Return(nil)
332+
s.MockBankKeeper.On("SendCoins", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
333+
334+
return antesuite.TestCaseArgs{
335+
Msgs: []sdk.Msg{testdata.NewTestMsg(accs[0].Account.GetAddress())},
336+
GasLimit: gasLimit,
337+
FeeAmount: validResolvableFeeWithTip,
338+
}
339+
},
340+
RunAnte: true,
341+
RunPost: true,
342+
Simulate: true,
343+
ExpPass: true,
344+
ExpErr: nil,
345+
},
274346
}
275347

276348
for _, tc := range testCases {

0 commit comments

Comments
 (0)