Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
4b281cc1
Unverified
Commit
4b281cc1
authored
Jun 22, 2023
by
mergify[bot]
Committed by
GitHub
Jun 22, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' into inphi/cannon-docs
parents
3782c561
09a63f3d
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
99 additions
and
62 deletions
+99
-62
price_bump_test.go
op-service/txmgr/price_bump_test.go
+10
-9
txmgr.go
op-service/txmgr/txmgr.go
+63
-33
txmgr_test.go
op-service/txmgr/txmgr_test.go
+26
-20
No files found.
op-service/txmgr/price_bump_test.go
View file @
4b281cc1
...
@@ -30,51 +30,52 @@ func (tc *priceBumpTest) run(t *testing.T) {
...
@@ -30,51 +30,52 @@ func (tc *priceBumpTest) run(t *testing.T) {
}
}
func
TestUpdateFees
(
t
*
testing
.
T
)
{
func
TestUpdateFees
(
t
*
testing
.
T
)
{
require
.
Equal
(
t
,
int64
(
10
),
priceBump
,
"test must be updated if priceBump is adjusted"
)
tests
:=
[]
priceBumpTest
{
tests
:=
[]
priceBumpTest
{
{
{
prevGasTip
:
100
,
prevBasefee
:
1000
,
prevGasTip
:
100
,
prevBasefee
:
1000
,
newGasTip
:
90
,
newBasefee
:
900
,
newGasTip
:
90
,
newBasefee
:
900
,
expectedTip
:
1
00
,
expectedFC
:
210
0
,
expectedTip
:
1
10
,
expectedFC
:
231
0
,
},
},
{
{
prevGasTip
:
100
,
prevBasefee
:
1000
,
prevGasTip
:
100
,
prevBasefee
:
1000
,
newGasTip
:
101
,
newBasefee
:
1000
,
newGasTip
:
101
,
newBasefee
:
1000
,
expectedTip
:
11
5
,
expectedFC
:
2415
,
expectedTip
:
11
0
,
expectedFC
:
2310
,
},
},
{
{
prevGasTip
:
100
,
prevBasefee
:
1000
,
prevGasTip
:
100
,
prevBasefee
:
1000
,
newGasTip
:
100
,
newBasefee
:
1001
,
newGasTip
:
100
,
newBasefee
:
1001
,
expectedTip
:
11
5
,
expectedFC
:
2415
,
expectedTip
:
11
0
,
expectedFC
:
2310
,
},
},
{
{
prevGasTip
:
100
,
prevBasefee
:
1000
,
prevGasTip
:
100
,
prevBasefee
:
1000
,
newGasTip
:
101
,
newBasefee
:
900
,
newGasTip
:
101
,
newBasefee
:
900
,
expectedTip
:
11
5
,
expectedFC
:
2415
,
expectedTip
:
11
0
,
expectedFC
:
2310
,
},
},
{
{
prevGasTip
:
100
,
prevBasefee
:
1000
,
prevGasTip
:
100
,
prevBasefee
:
1000
,
newGasTip
:
90
,
newBasefee
:
1010
,
newGasTip
:
90
,
newBasefee
:
1010
,
expectedTip
:
11
5
,
expectedFC
:
2415
,
expectedTip
:
11
0
,
expectedFC
:
2310
,
},
},
{
{
prevGasTip
:
100
,
prevBasefee
:
1000
,
prevGasTip
:
100
,
prevBasefee
:
1000
,
newGasTip
:
101
,
newBasefee
:
2000
,
newGasTip
:
101
,
newBasefee
:
2000
,
expectedTip
:
11
5
,
expectedFC
:
4115
,
expectedTip
:
11
0
,
expectedFC
:
4110
,
},
},
{
{
prevGasTip
:
100
,
prevBasefee
:
1000
,
prevGasTip
:
100
,
prevBasefee
:
1000
,
newGasTip
:
120
,
newBasefee
:
900
,
newGasTip
:
120
,
newBasefee
:
900
,
expectedTip
:
120
,
expectedFC
:
2
415
,
expectedTip
:
120
,
expectedFC
:
2
310
,
},
},
{
{
prevGasTip
:
100
,
prevBasefee
:
1000
,
prevGasTip
:
100
,
prevBasefee
:
1000
,
newGasTip
:
120
,
newBasefee
:
1100
,
newGasTip
:
120
,
newBasefee
:
1100
,
expectedTip
:
120
,
expectedFC
:
2
415
,
expectedTip
:
120
,
expectedFC
:
2
320
,
},
},
{
{
prevGasTip
:
100
,
prevBasefee
:
1000
,
prevGasTip
:
100
,
prevBasefee
:
1000
,
newGasTip
:
120
,
newBasefee
:
1140
,
newGasTip
:
120
,
newBasefee
:
1140
,
expectedTip
:
120
,
expectedFC
:
24
15
,
expectedTip
:
120
,
expectedFC
:
24
00
,
},
},
{
{
prevGasTip
:
100
,
prevBasefee
:
1000
,
prevGasTip
:
100
,
prevBasefee
:
1000
,
...
...
op-service/txmgr/txmgr.go
View file @
4b281cc1
...
@@ -20,9 +20,13 @@ import (
...
@@ -20,9 +20,13 @@ import (
"github.com/ethereum-optimism/optimism/op-service/txmgr/metrics"
"github.com/ethereum-optimism/optimism/op-service/txmgr/metrics"
)
)
// Geth defaults the priceBump to 10
const
(
// Set it to 15% to be more aggressive about including transactions
// Geth requires a minimum fee bump of 10% for tx resubmission
const
priceBump
int64
=
15
priceBump
int64
=
10
// The multiplier applied to fee suggestions to put a hard limit on fee increases
feeLimitMultiplier
=
5
)
// new = old * (100 + priceBump) / 100
// new = old * (100 + priceBump) / 100
var
priceBumpPercent
=
big
.
NewInt
(
100
+
priceBump
)
var
priceBumpPercent
=
big
.
NewInt
(
100
+
priceBump
)
...
@@ -280,7 +284,15 @@ func (m *SimpleTxManager) sendTx(ctx context.Context, tx *types.Transaction) (*t
...
@@ -280,7 +284,15 @@ func (m *SimpleTxManager) sendTx(ctx context.Context, tx *types.Transaction) (*t
return
nil
,
errors
.
New
(
"aborted transaction sending"
)
return
nil
,
errors
.
New
(
"aborted transaction sending"
)
}
}
// Increase the gas price & submit the new transaction
// Increase the gas price & submit the new transaction
tx
=
m
.
increaseGasPrice
(
ctx
,
tx
)
newTx
,
err
:=
m
.
increaseGasPrice
(
ctx
,
tx
)
if
err
!=
nil
||
sendState
.
IsWaitingForConfirmation
()
{
// there is a chance the previous tx goes into "waiting for confirmation" state
// during the increaseGasPrice call. In some (but not all) cases increaseGasPrice
// will error out during gas estimation. In either case we should continue waiting
// rather than resubmit the tx.
continue
}
tx
=
newTx
wg
.
Add
(
1
)
wg
.
Add
(
1
)
bumpCounter
+=
1
bumpCounter
+=
1
go
sendTxAsync
(
tx
)
go
sendTxAsync
(
tx
)
...
@@ -418,46 +430,67 @@ func (m *SimpleTxManager) queryReceipt(ctx context.Context, txHash common.Hash,
...
@@ -418,46 +430,67 @@ func (m *SimpleTxManager) queryReceipt(ctx context.Context, txHash common.Hash,
return
nil
return
nil
}
}
// increaseGasPrice takes the previous transaction & potentially clones then signs it with a higher tip.
// increaseGasPrice takes the previous transaction, clones it, and returns it with fee values that
// If the tip + basefee suggested by the network are not greater than the previous values, the same transaction
// are at least `priceBump` percent higher than the previous ones to satisfy Geth's replacement
// will be returned. If they are greater, this function will ensure that they are at least greater by 15% than
// rules, and no lower than the values returned by the fee suggestion algorithm to ensure it
// the previous transaction's value to ensure that the price bump is large enough.
// doesn't linger in the mempool. Finally to avoid runaway price increases, fees are capped at a
//
// `feeLimitMultiplier` multiple of the suggested values.
// We do not re-estimate the amount of gas used because for some stateful transactions (like output proposals) the
func
(
m
*
SimpleTxManager
)
increaseGasPrice
(
ctx
context
.
Context
,
tx
*
types
.
Transaction
)
(
*
types
.
Transaction
,
error
)
{
// act of including the transaction renders the repeat of the transaction invalid.
m
.
l
.
Info
(
"bumping gas price for tx"
,
"hash"
,
tx
.
Hash
(),
"tip"
,
tx
.
GasTipCap
(),
"fee"
,
tx
.
GasFeeCap
(),
"gaslimit"
,
tx
.
Gas
())
//
// If it encounters an error with creating the new transaction, it will return the old transaction.
func
(
m
*
SimpleTxManager
)
increaseGasPrice
(
ctx
context
.
Context
,
tx
*
types
.
Transaction
)
*
types
.
Transaction
{
tip
,
basefee
,
err
:=
m
.
suggestGasPriceCaps
(
ctx
)
tip
,
basefee
,
err
:=
m
.
suggestGasPriceCaps
(
ctx
)
if
err
!=
nil
{
if
err
!=
nil
{
m
.
l
.
Warn
(
"failed to get suggested gas tip and basefee"
,
"err"
,
err
)
m
.
l
.
Warn
(
"failed to get suggested gas tip and basefee"
,
"err"
,
err
)
return
tx
return
nil
,
err
}
}
gasTipCap
,
gasFeeCap
:=
updateFees
(
tx
.
GasTipCap
(),
tx
.
GasFeeCap
(),
tip
,
basefee
,
m
.
l
)
bumpedTip
,
bumpedFee
:=
updateFees
(
tx
.
GasTipCap
(),
tx
.
GasFeeCap
(),
tip
,
basefee
,
m
.
l
)
if
tx
.
GasTipCapIntCmp
(
gasTipCap
)
==
0
&&
tx
.
GasFeeCapIntCmp
(
gasFeeCap
)
==
0
{
// Make sure increase is at most 5x the suggested values
return
tx
maxTip
:=
new
(
big
.
Int
)
.
Mul
(
tip
,
big
.
NewInt
(
feeLimitMultiplier
))
if
bumpedTip
.
Cmp
(
maxTip
)
>
0
{
m
.
l
.
Warn
(
fmt
.
Sprintf
(
"bumped tip getting capped at %dx multiple of the suggested value"
,
feeLimitMultiplier
),
"bumped"
,
bumpedTip
,
"suggestion"
,
tip
)
bumpedTip
.
Set
(
maxTip
)
}
maxFee
:=
calcGasFeeCap
(
new
(
big
.
Int
)
.
Mul
(
basefee
,
big
.
NewInt
(
feeLimitMultiplier
)),
maxTip
)
if
bumpedFee
.
Cmp
(
maxFee
)
>
0
{
m
.
l
.
Warn
(
"bumped fee getting capped at multiple of the implied suggested value"
,
"bumped"
,
bumpedFee
,
"suggestion"
,
maxFee
)
bumpedFee
.
Set
(
maxFee
)
}
}
rawTx
:=
&
types
.
DynamicFeeTx
{
rawTx
:=
&
types
.
DynamicFeeTx
{
ChainID
:
tx
.
ChainId
(),
ChainID
:
tx
.
ChainId
(),
Nonce
:
tx
.
Nonce
(),
Nonce
:
tx
.
Nonce
(),
GasTipCap
:
gasTipCap
,
GasTipCap
:
bumpedTip
,
GasFeeCap
:
gasFeeCap
,
GasFeeCap
:
bumpedFee
,
Gas
:
tx
.
Gas
(),
To
:
tx
.
To
(),
To
:
tx
.
To
(),
Value
:
tx
.
Value
(),
Value
:
tx
.
Value
(),
Data
:
tx
.
Data
(),
Data
:
tx
.
Data
(),
AccessList
:
tx
.
AccessList
(),
AccessList
:
tx
.
AccessList
(),
}
}
// Re-estimate gaslimit in case things have changed or a previous gaslimit estimate was wrong
gas
,
err
:=
m
.
backend
.
EstimateGas
(
ctx
,
ethereum
.
CallMsg
{
From
:
m
.
cfg
.
From
,
To
:
rawTx
.
To
,
GasFeeCap
:
bumpedTip
,
GasTipCap
:
bumpedFee
,
Data
:
rawTx
.
Data
,
})
if
err
!=
nil
{
m
.
l
.
Warn
(
"failed to re-estimate gas"
,
"err"
,
err
,
"gaslimit"
,
tx
.
Gas
())
return
nil
,
err
}
if
tx
.
Gas
()
!=
gas
{
m
.
l
.
Info
(
"re-estimated gas differs"
,
"oldgas"
,
tx
.
Gas
(),
"newgas"
,
gas
)
}
rawTx
.
Gas
=
gas
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
m
.
cfg
.
NetworkTimeout
)
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
m
.
cfg
.
NetworkTimeout
)
defer
cancel
()
defer
cancel
()
newTx
,
err
:=
m
.
cfg
.
Signer
(
ctx
,
m
.
cfg
.
From
,
types
.
NewTx
(
rawTx
))
newTx
,
err
:=
m
.
cfg
.
Signer
(
ctx
,
m
.
cfg
.
From
,
types
.
NewTx
(
rawTx
))
if
err
!=
nil
{
if
err
!=
nil
{
m
.
l
.
Warn
(
"failed to sign new transaction"
,
"err"
,
err
)
m
.
l
.
Warn
(
"failed to sign new transaction"
,
"err"
,
err
)
return
tx
return
tx
,
nil
}
}
return
newTx
return
newTx
,
nil
}
}
// suggestGasPriceCaps suggests what the new tip & new basefee should be based on the current L1 conditions
// suggestGasPriceCaps suggests what the new tip & new basefee should be based on the current L1 conditions
...
@@ -490,18 +523,15 @@ func calcThresholdValue(x *big.Int) *big.Int {
...
@@ -490,18 +523,15 @@ func calcThresholdValue(x *big.Int) *big.Int {
return
threshold
return
threshold
}
}
// updateFees takes the old tip/basefee & the new tip/basefee and then suggests
// updateFees takes an old transaction's tip & fee cap plus a new tip & basefee, and returns
// a gasTipCap and gasFeeCap that satisfies geth's required fee bumps
// a suggested tip and fee cap such that:
// Geth: FC and Tip must be bumped if any increase
//
// (a) each satisfies geth's required tx-replacement fee bumps (we use a 10% increase), and
// (b) gasTipCap is no less than new tip, and
// (c) gasFeeCap is no less than calcGasFee(newBaseFee, newTip)
func
updateFees
(
oldTip
,
oldFeeCap
,
newTip
,
newBaseFee
*
big
.
Int
,
lgr
log
.
Logger
)
(
*
big
.
Int
,
*
big
.
Int
)
{
func
updateFees
(
oldTip
,
oldFeeCap
,
newTip
,
newBaseFee
*
big
.
Int
,
lgr
log
.
Logger
)
(
*
big
.
Int
,
*
big
.
Int
)
{
newFeeCap
:=
calcGasFeeCap
(
newBaseFee
,
newTip
)
newFeeCap
:=
calcGasFeeCap
(
newBaseFee
,
newTip
)
lgr
=
lgr
.
New
(
"old_tip"
,
oldTip
,
"old_feecap"
,
oldFeeCap
,
"new_tip"
,
newTip
,
"new_feecap"
,
newFeeCap
)
lgr
=
lgr
.
New
(
"old_tip"
,
oldTip
,
"old_feecap"
,
oldFeeCap
,
"new_tip"
,
newTip
,
"new_feecap"
,
newFeeCap
)
// If the new prices are less than the old price, reuse the old prices
if
oldTip
.
Cmp
(
newTip
)
>=
0
&&
oldFeeCap
.
Cmp
(
newFeeCap
)
>=
0
{
lgr
.
Debug
(
"Reusing old tip and feecap"
)
return
oldTip
,
oldFeeCap
}
// Determine if we need to increase the suggested values
thresholdTip
:=
calcThresholdValue
(
oldTip
)
thresholdTip
:=
calcThresholdValue
(
oldTip
)
thresholdFeeCap
:=
calcThresholdValue
(
oldFeeCap
)
thresholdFeeCap
:=
calcThresholdValue
(
oldFeeCap
)
if
newTip
.
Cmp
(
thresholdTip
)
>=
0
&&
newFeeCap
.
Cmp
(
thresholdFeeCap
)
>=
0
{
if
newTip
.
Cmp
(
thresholdTip
)
>=
0
&&
newFeeCap
.
Cmp
(
thresholdFeeCap
)
>=
0
{
...
...
op-service/txmgr/txmgr_test.go
View file @
4b281cc1
...
@@ -734,12 +734,14 @@ func doGasPriceIncrease(t *testing.T, txTipCap, txFeeCap, newTip, newBaseFee int
...
@@ -734,12 +734,14 @@ func doGasPriceIncrease(t *testing.T, txTipCap, txFeeCap, newTip, newBaseFee int
GasTipCap
:
big
.
NewInt
(
txTipCap
),
GasTipCap
:
big
.
NewInt
(
txTipCap
),
GasFeeCap
:
big
.
NewInt
(
txFeeCap
),
GasFeeCap
:
big
.
NewInt
(
txFeeCap
),
})
})
newTx
:=
mgr
.
increaseGasPrice
(
context
.
Background
(),
tx
)
newTx
,
err
:=
mgr
.
increaseGasPrice
(
context
.
Background
(),
tx
)
require
.
NoError
(
t
,
err
)
return
tx
,
newTx
return
tx
,
newTx
}
}
func
TestIncreaseGasPrice
(
t
*
testing
.
T
)
{
func
TestIncreaseGasPrice
(
t
*
testing
.
T
)
{
// t.Parallel()
// t.Parallel()
require
.
Equal
(
t
,
int64
(
10
),
priceBump
,
"test must be updated if priceBump is adjusted"
)
tests
:=
[]
struct
{
tests
:=
[]
struct
{
name
string
name
string
run
func
(
t
*
testing
.
T
)
run
func
(
t
*
testing
.
T
)
...
@@ -781,22 +783,16 @@ func TestIncreaseGasPrice(t *testing.T) {
...
@@ -781,22 +783,16 @@ func TestIncreaseGasPrice(t *testing.T) {
run
:
func
(
t
*
testing
.
T
)
{
run
:
func
(
t
*
testing
.
T
)
{
_
,
newTx
:=
doGasPriceIncrease
(
t
,
100
,
2200
,
120
,
1050
)
_
,
newTx
:=
doGasPriceIncrease
(
t
,
100
,
2200
,
120
,
1050
)
require
.
True
(
t
,
newTx
.
GasTipCap
()
.
Cmp
(
big
.
NewInt
(
120
))
==
0
,
"new tx tip must be equal L1"
)
require
.
True
(
t
,
newTx
.
GasTipCap
()
.
Cmp
(
big
.
NewInt
(
120
))
==
0
,
"new tx tip must be equal L1"
)
require
.
True
(
t
,
newTx
.
GasFeeCap
()
.
Cmp
(
big
.
NewInt
(
2
53
0
))
==
0
,
"new tx fee cap must be equal to the threshold value"
)
require
.
True
(
t
,
newTx
.
GasFeeCap
()
.
Cmp
(
big
.
NewInt
(
2
42
0
))
==
0
,
"new tx fee cap must be equal to the threshold value"
)
},
},
},
},
{
{
name
:
"uses L1 FC when larger and threshold tip"
,
name
:
"uses L1 FC when larger and threshold tip"
,
run
:
func
(
t
*
testing
.
T
)
{
run
:
func
(
t
*
testing
.
T
)
{
_
,
newTx
:=
doGasPriceIncrease
(
t
,
100
,
2200
,
100
,
2000
)
_
,
newTx
:=
doGasPriceIncrease
(
t
,
100
,
2200
,
100
,
2000
)
require
.
True
(
t
,
newTx
.
GasTipCap
()
.
Cmp
(
big
.
NewInt
(
115
))
==
0
,
"new tx tip must be equal the threshold value"
)
require
.
True
(
t
,
newTx
.
GasTipCap
()
.
Cmp
(
big
.
NewInt
(
110
))
==
0
,
"new tx tip must be equal the threshold value"
)
require
.
True
(
t
,
newTx
.
GasFeeCap
()
.
Cmp
(
big
.
NewInt
(
4115
))
==
0
,
"new tx fee cap must be equal L1"
)
t
.
Log
(
"Vals:"
,
newTx
.
GasFeeCap
())
},
require
.
True
(
t
,
newTx
.
GasFeeCap
()
.
Cmp
(
big
.
NewInt
(
4110
))
==
0
,
"new tx fee cap must be equal L1"
)
},
{
name
:
"reuses tx when no bump"
,
run
:
func
(
t
*
testing
.
T
)
{
tx
,
newTx
:=
doGasPriceIncrease
(
t
,
10
,
100
,
10
,
45
)
require
.
Equal
(
t
,
tx
.
Hash
(),
newTx
.
Hash
(),
"tx hash must be the same"
)
},
},
},
},
}
}
...
@@ -811,11 +807,12 @@ func TestIncreaseGasPrice(t *testing.T) {
...
@@ -811,11 +807,12 @@ func TestIncreaseGasPrice(t *testing.T) {
func
TestIncreaseGasPriceNotExponential
(
t
*
testing
.
T
)
{
func
TestIncreaseGasPriceNotExponential
(
t
*
testing
.
T
)
{
t
.
Parallel
()
t
.
Parallel
()
borkedTip
:=
int64
(
10
)
borkedFee
:=
int64
(
45
)
borkedBackend
:=
failingBackend
{
borkedBackend
:=
failingBackend
{
gasTip
:
big
.
NewInt
(
10
),
gasTip
:
big
.
NewInt
(
borkedTip
),
baseFee
:
big
.
NewInt
(
45
),
baseFee
:
big
.
NewInt
(
borkedFee
),
}
}
feeCap
:=
calcGasFeeCap
(
borkedBackend
.
baseFee
,
borkedBackend
.
gasTip
)
mgr
:=
&
SimpleTxManager
{
mgr
:=
&
SimpleTxManager
{
cfg
:
Config
{
cfg
:
Config
{
...
@@ -839,14 +836,23 @@ func TestIncreaseGasPriceNotExponential(t *testing.T) {
...
@@ -839,14 +836,23 @@ func TestIncreaseGasPriceNotExponential(t *testing.T) {
})
})
// Run IncreaseGasPrice a bunch of times in a row to simulate a very fast resubmit loop.
// Run IncreaseGasPrice a bunch of times in a row to simulate a very fast resubmit loop.
for
i
:=
0
;
i
<
20
;
i
++
{
var
err
error
for
i
:=
0
;
i
<
30
;
i
++
{
ctx
:=
context
.
Background
()
ctx
:=
context
.
Background
()
newTx
:=
mgr
.
increaseGasPrice
(
ctx
,
tx
)
tx
,
err
=
mgr
.
increaseGasPrice
(
ctx
,
tx
)
require
.
True
(
t
,
newTx
.
GasFeeCap
()
.
Cmp
(
feeCap
)
==
0
,
"new tx fee cap must be equal L1"
)
require
.
NoError
(
t
,
err
)
require
.
True
(
t
,
newTx
.
GasTipCap
()
.
Cmp
(
borkedBackend
.
gasTip
)
==
0
,
"new tx tip must be equal L1"
)
}
tx
=
newTx
lastTip
,
lastFee
:=
tx
.
GasTipCap
(),
tx
.
GasFeeCap
()
require
.
Equal
(
t
,
lastTip
.
Int64
(),
feeLimitMultiplier
*
borkedTip
)
require
.
Equal
(
t
,
lastFee
.
Int64
(),
feeLimitMultiplier
*
(
borkedTip
+
2
*
borkedFee
))
// Confirm that fees stop rising
for
i
:=
0
;
i
<
5
;
i
++
{
ctx
:=
context
.
Background
()
tx
,
err
:=
mgr
.
increaseGasPrice
(
ctx
,
tx
)
require
.
NoError
(
t
,
err
)
require
.
True
(
t
,
tx
.
GasTipCap
()
.
Cmp
(
lastTip
)
==
0
,
"suggested tx tip must stop increasing"
)
require
.
True
(
t
,
tx
.
GasFeeCap
()
.
Cmp
(
lastFee
)
==
0
,
"suggested tx fee must stop increasing"
)
}
}
}
}
func
TestErrStringMatch
(
t
*
testing
.
T
)
{
func
TestErrStringMatch
(
t
*
testing
.
T
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment