-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A race condition sometimes causes a transaction to have an invalid pair of maxFeePerGas/maxPriorityFeePerGas #3052
Labels
Comments
evgeny-osipenko
changed the title
A race condition sometimes causes a transaction to have invalid pair of maxFeePerGas/maxPriorityFeePerGas
A race condition sometimes causes a transaction to have an invalid pair of maxFeePerGas/maxPriorityFeePerGas
Jul 19, 2023
On the probability and severity of this bug: we actually encountered it in the wild when working with the Polygon Mumbai testnet. It has two important properties with regards to this bug:
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
When
Web3
is asked to construct a transaction without gas fees set explicitly, the values of themaxFeePerGas
andmaxPriorityFeePerGas
fields are filled as part of the defaulting process, governed by this code:web3.py/web3/_utils/transactions.py
Lines 69 to 80 in 4b509a7
web3.py/web3/_utils/transactions.py
Lines 103 to 137 in 4b509a7
If a new block is created right as the defaulting process takes place, then
w3.eth.max_priority_fee
will return different values for different fields of the same transaction. This can cause the transaction to end up withtx['maxFeePerGas'] < tx['maxPriorityFeePerGas']
, which is invalid and will cause it to fail further down the line with something likeAs for the fix, I propose to change the behavior like this:
"maxPriorityFeePerGas"
goes before"maxFeePerGas "
. Since Python dictionaries remember the insertion order of their keys and respect it during iteration, changing their order in theTRANSACTION_DEFAULTS
map will correspondingly change the order the initializers are actually run.defaults
accumulator to the initializers together withw3
and the initial transaction. Again, since Python guarantees to iterate over maps in the key insertion order, it's perfectly fine to carry state in-between iterations and rely on some actions being done before others."maxFeePerGas"
initializer, instead of asking forw3.eth.max_priority_fee
again, usetx.get('maxPriorityFeePerGas', defaults['maxPriorityFeePerGas'])
.So, with these considerations, the fix in code would look somewhat like this:
The text was updated successfully, but these errors were encountered: