Skip to content

Commit 2ddefad

Browse files
committed
improve feemarket e2e tests
1 parent d23ef64 commit 2ddefad

File tree

4 files changed

+48
-408
lines changed

4 files changed

+48
-408
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ bin
44
# IDEs
55
.vscode
66
.cursor
7+
.claude
78

89
# OS
910
.DS_Store

interchaintest/suite/tx.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,12 +218,11 @@ func (s *E2ETestSuite) CreateTx(chain *cosmos.CosmosChain, user cosmos.User, fee
218218
) []byte {
219219
bc := cosmos.NewBroadcaster(s.T(), chain)
220220

221-
ctx := context.Background()
222221
// create tx factory + Client Context
223-
txf, err := bc.GetFactory(ctx, user)
222+
txf, err := bc.GetFactory(s.Ctx, user)
224223
s.Require().NoError(err)
225224

226-
cc, err := bc.GetClientContext(ctx, user)
225+
cc, err := bc.GetClientContext(s.Ctx, user)
227226
s.Require().NoError(err)
228227

229228
txf = txf.WithSimulateAndExecute(true)
Lines changed: 24 additions & 220 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package feemarket_test
22

33
import (
4-
"context"
54
"fmt"
65
"testing"
7-
"time"
86

97
"cosmossdk.io/math"
108
sdk "github.com/cosmos/cosmos-sdk/types"
@@ -60,143 +58,10 @@ func (s *FeemarketTestSuite) SetupSubTest() {
6058
s.T().Log("gas price at block height", height+1, ":", gasPrice.String())
6159
}
6260

63-
func (s *FeemarketTestSuite) TestQueryParams() {
64-
require := s.Require()
65-
s.Run("query params", func() {
66-
// query params
67-
params := s.QueryFeemarketParams()
68-
69-
s.T().Logf("feemarket params: %s", params.String())
70-
71-
// expect validate to pass
72-
require.NoError(params.ValidateBasic(), params)
73-
})
74-
}
75-
76-
func (s *FeemarketTestSuite) TestQueryState() {
77-
require := s.Require()
78-
s.Run("query state", func() {
79-
// query state
80-
state := s.QueryFeemarketState()
81-
82-
s.T().Logf("feemarket state: %s", state.String())
83-
84-
// expect validate to pass
85-
require.NoError(state.ValidateBasic(), state)
86-
})
87-
}
88-
89-
func (s *FeemarketTestSuite) TestQueryGasPrice() {
90-
require := s.Require()
91-
s.Run("query gas price", func() {
92-
// query gas price
93-
gasPrice := s.QueryFeemarketGasPrice(s.Denom)
94-
95-
s.T().Logf("feemarket gas price: %s", gasPrice.String())
96-
97-
// expect validate to pass
98-
require.NoError(gasPrice.Validate(), gasPrice)
99-
})
100-
}
101-
102-
// TestSendTxDecrease tests that the feemarket will decrease until it hits the min gas price
103-
// when gas utilization is below the target block utilization.
104-
func (s *FeemarketTestSuite) TestSendTxDecrease() {
105-
nodes := s.Chain.Nodes()
106-
s.Require().True(len(nodes) > 0)
107-
108-
params := s.QueryFeemarketParams()
109-
110-
// First, we need to ensure gas prices are elevated
111-
s.T().Log("Setting up elevated gas prices...")
112-
s.elevateGasPrices(params)
113-
114-
// Record initial elevated state
115-
initialGasPrice := s.QueryFeemarketGasPrice(s.Denom)
116-
s.T().Logf("Initial elevated gas price: %s", initialGasPrice.String())
117-
s.T().Logf("Target minimum gas price: %s", params.MinBaseGasPrice.String())
118-
119-
// Ensure we're starting from an elevated price
120-
s.Require().True(initialGasPrice.Amount.GT(params.MinBaseGasPrice),
121-
"Gas price not elevated. Initial: %s, Min: %s",
122-
initialGasPrice.String(), params.MinBaseGasPrice.String())
123-
124-
// Setup test users
125-
users := []ibc.Wallet{
126-
s.GetAndFundTestUser("user1", 200000000000, s.Chain),
127-
s.GetAndFundTestUser("user2", 200000000000, s.Chain),
128-
s.GetAndFundTestUser("user3", 200000000000, s.Chain),
129-
}
130-
131-
// Use reasonable gas that won't congest the network
132-
gasPerTx := int64(200000)
133-
sendAmt := int64(100)
134-
135-
// Wait for chain to stabilize
136-
err := testutil.WaitForBlocks(s.Ctx, 1, s.Chain)
137-
s.Require().NoError(err)
138-
139-
// Monitor gas prices
140-
priceUpdates := make(chan sdk.DecCoin, 100)
141-
stopMonitoring := make(chan struct{})
142-
monitoringDone := make(chan struct{})
143-
144-
go s.monitorGasPrice(priceUpdates, stopMonitoring, monitoringDone)
145-
146-
// Send minimal transactions to allow price to decrease
147-
txErrors := s.sendMinimalTransactions(users, gasPerTx, sendAmt)
148-
149-
// Wait for multiple blocks to allow price decay
150-
currentHeight, err := s.Chain.Height(s.Ctx)
151-
s.Require().NoError(err)
152-
s.WaitForHeight(s.Chain, currentHeight+5)
153-
154-
// Additional wait to capture more price movements
155-
time.Sleep(2 * time.Second)
156-
157-
// Stop monitoring and collect results
158-
close(stopMonitoring)
159-
<-monitoringDone
160-
close(priceUpdates)
161-
162-
// Analyze price changes
163-
prices := []sdk.DecCoin{}
164-
for price := range priceUpdates {
165-
prices = append(prices, price)
166-
}
167-
168-
// Verify results
169-
s.Require().True(len(prices) > 0, "No price updates captured")
170-
s.Require().True(len(txErrors) == 0, "Transactions failed: %v", txErrors)
171-
172-
// Check that gas price decreased
173-
finalGasPrice := s.QueryFeemarketGasPrice(s.Denom)
174-
s.T().Logf("Final gas price: %s", finalGasPrice.String())
175-
176-
s.Require().True(finalGasPrice.Amount.LTE(initialGasPrice.Amount),
177-
"Gas price did not decrease. Initial: %s, Final: %s",
178-
initialGasPrice.String(), finalGasPrice.String())
179-
180-
// Verify it reached the minimum
181-
s.Require().True(finalGasPrice.Amount.Equal(params.MinBaseGasPrice),
182-
"Gas price did not reach minimum. Current: %s, Min: %s",
183-
finalGasPrice.String(), params.MinBaseGasPrice.String())
184-
185-
// Verify price trend was decreasing
186-
s.verifyPriceDecreaseTrend(prices, params.MinBaseGasPrice)
187-
188-
// Verify user balances decreased (they paid for transactions)
189-
for _, user := range users {
190-
amt, err := s.Chain.GetBalance(s.Ctx, user.FormattedAddress(), s.Denom)
191-
s.Require().NoError(err)
192-
s.Require().True(amt.LT(math.NewInt(e2esuite.InitBalance)),
193-
"User balance did not decrease: %s", amt.String())
194-
}
195-
}
196-
197-
// TestSendTxIncrease tests that the feemarket will increase
198-
// when gas utilization is above the target block utilization.
199-
func (s *FeemarketTestSuite) TestSendTxIncrease() {
61+
// TestFeemarketUpdate tests that the feemarket will increase
62+
// when gas utilization is above the target block utilization
63+
// and that the gas price will decrease after the congestion ends
64+
func (s *FeemarketTestSuite) TestFeemarketUpdate() {
20065
nodes := s.Chain.Nodes()
20166
s.Require().True(len(nodes) > 0)
20267

@@ -221,10 +86,12 @@ func (s *FeemarketTestSuite) TestSendTxIncrease() {
22186
s.GetAndFundTestUser("user1", 200000000000, s.Chain),
22287
s.GetAndFundTestUser("user2", 200000000000, s.Chain),
22388
s.GetAndFundTestUser("user3", 200000000000, s.Chain),
89+
s.GetAndFundTestUser("user4", 200000000000, s.Chain),
90+
s.GetAndFundTestUser("user5", 200000000000, s.Chain),
22491
}
22592

22693
// Monitor gas prices in separate goroutine
227-
priceUpdates := make(chan sdk.DecCoin, 100)
94+
priceUpdates := make(chan sdk.DecCoin, 300)
22895
stopMonitoring := make(chan struct{})
22996
monitoringDone := make(chan struct{})
23097

@@ -260,7 +127,7 @@ func (s *FeemarketTestSuite) TestSendTxIncrease() {
260127
}
261128
}
262129

263-
// Check that gas price increased during congestion (but may have decreased afterward)
130+
// Check that gas price increased during congestion
264131
finalGasPrice := s.QueryFeemarketGasPrice(s.Denom)
265132
s.T().Logf("Final gas price: %s", finalGasPrice.String())
266133
s.T().Logf("Maximum gas price during congestion: %s%s", maxGasPrice.String(), s.Denom)
@@ -269,7 +136,7 @@ func (s *FeemarketTestSuite) TestSendTxIncrease() {
269136
"Gas price did not increase during congestion. Initial: %s, Maximum: %s%s",
270137
initialGasPrice.String(), maxGasPrice.String(), s.Denom)
271138

272-
// Verify there was indeed an increase (as a percentage)
139+
// Verify there was indeed an increase
273140
priceIncreaseRatio := maxGasPrice.Quo(initialGasPrice.Amount)
274141
s.T().Logf("Maximum price increase: %.2fx", priceIncreaseRatio.MustFloat64())
275142
s.Require().True(priceIncreaseRatio.GT(math.LegacyMustNewDecFromStr("1.1")),
@@ -286,7 +153,6 @@ func (s *FeemarketTestSuite) TestSendTxFailures() {
286153

287154
user1 := s.GetAndFundTestUser("user1", 200000000000, s.Chain)
288155
user2 := s.GetAndFundTestUser("user2", 200000000000, s.Chain)
289-
user3 := s.GetAndFundTestUser("user3", 200000000000, s.Chain)
290156

291157
err := testutil.WaitForBlocks(s.Ctx, 5, s.Chain)
292158
require.NoError(s.T(), err)
@@ -295,7 +161,7 @@ func (s *FeemarketTestSuite) TestSendTxFailures() {
295161
// send one tx with no gas or fee attached
296162
txResp, err := s.SendCoinsMultiBroadcast(
297163
user1,
298-
user3,
164+
user2,
299165
sdk.NewCoins(sdk.NewCoin(s.Chain.Config().Denom, math.NewInt(sendAmt))),
300166
sdk.NewCoins(sdk.NewCoin(s.Chain.Config().Denom, math.NewInt(1_000_000))),
301167
0,
@@ -311,7 +177,7 @@ func (s *FeemarketTestSuite) TestSendTxFailures() {
311177
s.Run("submit tx with no fee", func() {
312178
txResp, err := s.SendCoinsMultiBroadcast(
313179
user1,
314-
user3,
180+
user2,
315181
sdk.NewCoins(sdk.NewCoin(s.Chain.Config().Denom, math.NewInt(sendAmt))),
316182
sdk.NewCoins(),
317183
gas,
@@ -325,10 +191,10 @@ func (s *FeemarketTestSuite) TestSendTxFailures() {
325191
})
326192

327193
s.Run("fail a tx that uses full balance in fee - fail tx", func() {
328-
balance := s.QueryBankBalance(user3)
194+
balance := s.QueryBankBalance(user2)
329195

330196
txResp, err := s.SendCoinsMultiBroadcast(
331-
user3,
197+
user2,
332198
user1,
333199
sdk.NewCoins(balance),
334200
sdk.NewCoins(balance),
@@ -337,12 +203,12 @@ func (s *FeemarketTestSuite) TestSendTxFailures() {
337203
)
338204
s.Require().NoError(err)
339205
s.Require().NotNil(txResp)
340-
s.Require().True(txResp.CheckTx.Code != 0)
341-
s.T().Log(txResp.CheckTx.Log)
342-
s.Require().Contains(txResp.CheckTx.Log, "insufficient funds")
206+
s.Require().True(txResp.TxResult.Code != 0)
207+
s.T().Log(txResp.TxResult.Log)
208+
s.Require().Contains(txResp.TxResult.Log, "insufficient funds")
343209

344210
// ensure that balance is deducted for any tx passing checkTx
345-
newBalance := s.QueryBankBalance(user3)
211+
newBalance := s.QueryBankBalance(user2)
346212
s.Require().True(newBalance.IsLT(balance), fmt.Sprintf("new balance: %d, original balance: %d",
347213
balance.Amount.Int64(),
348214
newBalance.Amount.Int64()))
@@ -357,20 +223,21 @@ func (s *FeemarketTestSuite) TestSendTxFailures() {
357223
NewInt(100))))
358224
txResp, err := s.SendCoinsMultiBroadcast(
359225
user1,
360-
user3,
226+
user2,
361227
sdk.NewCoins(balance),
362228
minBaseFeeCoins,
363229
gas,
364230
1,
365231
)
366232
s.Require().NoError(err)
367233
s.Require().NotNil(txResp)
368-
s.Require().True(txResp.CheckTx.Code != 0)
369-
s.T().Log(txResp.CheckTx.Log)
370-
s.Require().Contains(txResp.CheckTx.Log, "insufficient funds")
234+
s.T().Log(txResp.TxResult)
235+
s.Require().True(txResp.TxResult.Code != 0)
236+
s.T().Log(txResp.TxResult.Log)
237+
s.Require().Contains(txResp.TxResult.Log, "insufficient funds")
371238

372239
// ensure that balance is deducted for any tx passing checkTx
373-
newBalance := s.QueryBankBalance(user3)
240+
newBalance := s.QueryBankBalance(user2)
374241
s.Require().True(newBalance.IsLT(balance), fmt.Sprintf("new balance: %d, original balance: %d",
375242
balance.Amount.Int64(),
376243
newBalance.Amount.Int64()))
@@ -380,7 +247,7 @@ func (s *FeemarketTestSuite) TestSendTxFailures() {
380247
balance := s.QueryBankBalance(user1)
381248
txResp, err := s.SendCoinsMultiBroadcast(
382249
user1,
383-
user3,
250+
user2,
384251
sdk.NewCoins(sdk.NewCoin(s.Chain.Config().Denom, math.NewInt(sendAmt))),
385252
sdk.NewCoins(balance.AddAmount(math.NewInt(110000))),
386253
gas,
@@ -398,67 +265,4 @@ func (s *FeemarketTestSuite) TestSendTxFailures() {
398265
balance.Amount.Int64(),
399266
newBalance.Amount.Int64()))
400267
})
401-
402-
s.Run("submit 2 tx in the same block - fail checktx in 2nd", func() {
403-
balance := s.QueryBankBalance(user2)
404-
405-
defaultGasPrice := s.QueryFeemarketGasPrice(s.Denom)
406-
minBaseFee := sdk.NewDecCoinFromDec(defaultGasPrice.Denom, defaultGasPrice.Amount.Mul(math.LegacyNewDec(gas)))
407-
minBaseFeeCoins := sdk.NewCoins(sdk.NewCoin(minBaseFee.Denom, minBaseFee.Amount.TruncateInt().Add(math.
408-
NewInt(100))))
409-
txResp, err := s.SendCoinsMultiBroadcastAsync(
410-
user2,
411-
user1,
412-
sdk.NewCoins(balance.SubAmount(minBaseFeeCoins.AmountOf(minBaseFee.Denom))),
413-
minBaseFeeCoins,
414-
gas,
415-
1,
416-
false,
417-
)
418-
s.Require().NoError(err)
419-
s.Require().NotNil(txResp)
420-
s.Require().True(txResp.Code == 0)
421-
hash1 := txResp.Hash
422-
423-
txResp, err = s.SendCoinsMultiBroadcastAsync(
424-
user2,
425-
user1,
426-
minBaseFeeCoins,
427-
minBaseFeeCoins,
428-
gas,
429-
1,
430-
true,
431-
)
432-
s.Require().NoError(err)
433-
s.Require().NotNil(txResp)
434-
s.Require().True(txResp.Code == 0)
435-
hash2 := txResp.Hash
436-
437-
nodes := s.Chain.Nodes()
438-
s.Require().True(len(nodes) > 0)
439-
440-
// wait for 1 block
441-
// query height
442-
height, err := s.Chain.Height(context.Background())
443-
s.Require().NoError(err)
444-
s.WaitForHeight(s.Chain, height+1)
445-
446-
// after waiting, we can now query the Tx Responses
447-
resp, err := nodes[0].TxHashToResponse(context.Background(), hash1.String())
448-
s.Require().NoError(err)
449-
s.Require().NotNil(resp)
450-
s.Require().True(resp.Code == 0)
451-
452-
resp, err = nodes[0].TxHashToResponse(context.Background(), hash2.String())
453-
s.Require().NoError(err)
454-
s.Require().NotNil(resp)
455-
s.Require().True(resp.Code != 0)
456-
s.Require().Contains(resp.RawLog, "error escrowing funds")
457-
s.T().Log(resp.RawLog)
458-
459-
// reset the users and balances
460-
user1 = s.GetAndFundTestUser("user1", 200000000000, s.Chain)
461-
user2 = s.GetAndFundTestUser("user2", 200000000000, s.Chain)
462-
user3 = s.GetAndFundTestUser("user3", 200000000000, s.Chain)
463-
})
464268
}

0 commit comments

Comments
 (0)