Skip to content

Commit 37c7ac2

Browse files
committed
feat: increase gas tip caps on retry
1 parent a2e0ef2 commit 37c7ac2

4 files changed

Lines changed: 83 additions & 28 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## [UNRELEASED]
4+
5+
### Changed
6+
7+
- For type 2 gas configs, both MaximalMaxPriorityFe and MinimalMaxPriorityFee are increased by 11% on each retry to ensure valid replacement transactions
8+
39
## [v1.0.6] - 2026-2-13
410

511
### Added

client/config/client.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -258,18 +258,26 @@ type Gas struct {
258258
BaseFeePerGasCap *big.Int `toml:"base_fee_per_gas_cap"` // LEAVE UNSET UNLESS YOU KNOW WHAT YOU ARE DOING.
259259
}
260260

261+
var (
262+
DefaultMaxPriorityMultiplier = big.NewInt(2)
263+
DefaultMaximalMaxPriorityFee = big.NewInt(5000e9) // 5000 Gwei
264+
DefaultMinimalMaxPriorityFee = big.NewInt(100e9) // 100 Gwei
265+
266+
DefaultBaseFeeMultiplier = big.NewInt(4)
267+
)
268+
261269
// DefaultGas
262270
func DefaultGas() Gas {
263271
return Gas{
264272
TxType: 2,
265273

266274
GasLimit: 0,
267275

268-
MaxPriorityMultiplier: big.NewInt(2),
269-
MinimalMaxPriorityFee: big.NewInt(100e9),
270-
MaximalMaxPriorityFee: big.NewInt(5000e9),
276+
MaxPriorityMultiplier: DefaultMaxPriorityMultiplier,
277+
MinimalMaxPriorityFee: DefaultMinimalMaxPriorityFee,
278+
MaximalMaxPriorityFee: DefaultMaximalMaxPriorityFee,
271279

272-
BaseFeeMultiplier: big.NewInt(4),
280+
BaseFeeMultiplier: DefaultBaseFeeMultiplier,
273281
}
274282
}
275283

utils/chain/tx_utils.go

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ const (
3131
defaultTipMultiplier = 2
3232

3333
baseFeeCapMultiplier = 4
34+
35+
multiplierBumpTimes100 = 111
36+
normalizer = 100
3437
)
3538

3639
var (
@@ -331,7 +334,8 @@ func GetGasPrice(gasConfig *config.Gas, client *ethclient.Client, timeout time.D
331334
// up to a maximum of 10x the original value.
332335
// If GasPriceFixed is used, the retry multiplier will not be applied.
333336
//
334-
// For type 2 transaction, MaxPriorityFeePerGas on the n-the attempt is n-th power of 1,2 times the MaxPriorityFeePerGas of the initial attempt.
337+
// For type 2 transaction on i-th attempt,
338+
// the multipliers are increased by i, and caps are increased by 11% per attempt.
335339
func GasConfigForAttempt(cfg *config.Gas, attempt int) *config.Gas {
336340
switch cfg.TxType {
337341
case 0:
@@ -364,16 +368,43 @@ func GasConfigForAttempt(cfg *config.Gas, attempt int) *config.Gas {
364368
baseFeeMultiplier.Set(cfg.BaseFeeMultiplier)
365369
baseFeeMultiplier.Add(baseFeeMultiplier, attemptBig)
366370
} else {
367-
baseFeeMultiplier = big.NewInt(3 + int64(attempt))
371+
baseFeeMultiplier.Add(config.DefaultBaseFeeMultiplier, attemptBig)
372+
}
373+
374+
maxMaxPriorityFee := new(big.Int)
375+
if cfg.MaximalMaxPriorityFee != nil && cfg.MaximalMaxPriorityFee.Cmp(common.Big0) == 1 {
376+
maxMaxPriorityFee.Set(cfg.MaximalMaxPriorityFee)
377+
} else {
378+
maxMaxPriorityFee.Set(config.DefaultMaximalMaxPriorityFee)
379+
}
380+
381+
minMaxPriorityFee := new(big.Int)
382+
if cfg.MinimalMaxPriorityFee != nil && cfg.MinimalMaxPriorityFee.Cmp(common.Big0) == 1 {
383+
minMaxPriorityFee.Set(cfg.MinimalMaxPriorityFee)
384+
} else {
385+
minMaxPriorityFee.Set(config.DefaultMinimalMaxPriorityFee)
386+
}
387+
388+
// Increase caps by 11% per retry
389+
if attempt > 0 {
390+
multiplier := new(big.Int).Exp(big.NewInt(multiplierBumpTimes100), attemptBig, nil)
391+
normalizer := new(big.Int).Exp(big.NewInt(normalizer), attemptBig, nil)
392+
393+
maxMaxPriorityFee.Mul(maxMaxPriorityFee, multiplier)
394+
maxMaxPriorityFee.Div(maxMaxPriorityFee, normalizer)
395+
396+
minMaxPriorityFee.Mul(minMaxPriorityFee, multiplier)
397+
minMaxPriorityFee.Div(minMaxPriorityFee, normalizer)
368398
}
399+
369400
return &config.Gas{
370401
TxType: 2,
371402
GasLimit: cfg.GasLimit,
372403

373404
BaseFeeMultiplier: baseFeeMultiplier,
374405
MaxPriorityMultiplier: maxPriorityMultiplier,
375-
MaximalMaxPriorityFee: cfg.MaximalMaxPriorityFee,
376-
MinimalMaxPriorityFee: cfg.MinimalMaxPriorityFee,
406+
MaximalMaxPriorityFee: maxMaxPriorityFee,
407+
MinimalMaxPriorityFee: minMaxPriorityFee,
377408

378409
BaseFeePerGasCap: cfg.BaseFeePerGasCap,
379410
}

utils/chain/tx_utils_test.go

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -133,53 +133,61 @@ func TestGasConfigForAttemptType0(t *testing.T) {
133133
},
134134
},
135135
{
136-
name: "empty type 2",
137-
cfg: config2.Gas{TxType: 2},
138-
ri: 0,
139-
expected: config2.Gas{
140-
TxType: 2,
141-
GasLimit: 0,
142-
MaxPriorityMultiplier: big.NewInt(2),
143-
BaseFeeMultiplier: big.NewInt(3),
144-
BaseFeePerGasCap: nil,
145-
},
136+
name: "empty type 2",
137+
cfg: config2.Gas{TxType: 2},
138+
ri: 0,
139+
expected: config2.DefaultGas(),
146140
},
147141
{
148142
name: "zero type 2",
149143
cfg: config2.Gas{
150144
TxType: 2,
151145
MaxPriorityMultiplier: big.NewInt(0),
152146
BaseFeeMultiplier: big.NewInt(0),
147+
},
148+
ri: 0,
149+
expected: config2.DefaultGas(),
150+
},
151+
{
152+
name: "zero type 2,2 ",
153+
cfg: config2.Gas{
154+
TxType: 2,
155+
MaxPriorityMultiplier: big.NewInt(6),
156+
BaseFeeMultiplier: big.NewInt(2),
153157
BaseFeePerGasCap: big.NewInt(0),
154158
},
155-
ri: 0,
159+
ri: 2,
156160
expected: config2.Gas{
157161
TxType: 2,
158162
GasLimit: 0,
159-
MaxPriorityMultiplier: big.NewInt(2),
160-
BaseFeeMultiplier: big.NewInt(3),
163+
MaxPriorityMultiplier: big.NewInt(8),
164+
BaseFeeMultiplier: big.NewInt(4),
161165
BaseFeePerGasCap: big.NewInt(0),
166+
MaximalMaxPriorityFee: big.NewInt(6160500000000),
167+
MinimalMaxPriorityFee: big.NewInt(123210000000),
162168
},
163169
},
164170
{
165-
name: "zero type 2",
171+
name: "type 2",
166172
cfg: config2.Gas{
167173
TxType: 2,
168-
MaxPriorityMultiplier: big.NewInt(6),
174+
GasLimit: 0,
169175
BaseFeeMultiplier: big.NewInt(2),
170-
BaseFeePerGasCap: big.NewInt(0),
176+
MaxPriorityMultiplier: big.NewInt(6),
177+
MaximalMaxPriorityFee: big.NewInt(1000),
178+
MinimalMaxPriorityFee: big.NewInt(100),
171179
},
172180
ri: 2,
173181
expected: config2.Gas{
174182
TxType: 2,
175183
GasLimit: 0,
176-
MaxPriorityMultiplier: big.NewInt(8),
177184
BaseFeeMultiplier: big.NewInt(4),
178-
BaseFeePerGasCap: big.NewInt(0),
185+
MaxPriorityMultiplier: big.NewInt(8),
186+
MaximalMaxPriorityFee: big.NewInt(1232),
187+
MinimalMaxPriorityFee: big.NewInt(123),
179188
},
180189
},
181190
}
182-
183191
for _, test := range tests {
184192
t.Run(test.name, func(t *testing.T) {
185193
got := chain.GasConfigForAttempt(&test.cfg, test.ri)
@@ -196,8 +204,10 @@ func TestGasConfigForAttemptType0(t *testing.T) {
196204
}
197205
case 2:
198206
require.Equal(t, test.expected.BaseFeeMultiplier, got.BaseFeeMultiplier)
199-
require.Equal(t, test.expected.MaxPriorityMultiplier, got.MaxPriorityMultiplier)
207+
require.Equal(t, test.expected.MaxPriorityMultiplier, got.MaxPriorityMultiplier, "primul")
200208
require.Equal(t, test.expected.BaseFeePerGasCap, got.BaseFeePerGasCap)
209+
require.Equal(t, test.expected.MaximalMaxPriorityFee, got.MaximalMaxPriorityFee, "mincap")
210+
require.Equal(t, test.expected.MinimalMaxPriorityFee, got.MinimalMaxPriorityFee, "maxcap")
201211
}
202212
})
203213
}

0 commit comments

Comments
 (0)