From 07fa94278fc8785f9bae9c6f92f0aeade5df3dfb Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Wed, 16 Nov 2022 13:27:17 +0530 Subject: [PATCH] txpool: honour nonce while sorting txs (#737) In context of https://github.com/ledgerwatch/erigon/issues/5694, this PR fixes the tx ordering logic in the txpool. Also, a relevant change in erigon is made here: https://github.com/ledgerwatch/erigon/pull/6051. When the mining module used to query the best transactions, the response of transactions weren't sorted according to nonce (for same sender address). This caused the execution to fail (except 1). The txpool orders the transactions using this underlying `better()` and `worse()` functions. The `better()` function didn't have a nonce check for the pending pool, while the `worse()` function had. This PR adds a check which would compare and put a transaction with lower nonce ahead. Moreover, on further investigation, these checks were applied for all types of transactions. It only makes sense compare the nonce for transactions which has same sender account. Hence, this PR also adds an additional check along with. --- txpool/pool.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/txpool/pool.go b/txpool/pool.go index 8d66310d5..0983e5c0d 100644 --- a/txpool/pool.go +++ b/txpool/pool.go @@ -2231,6 +2231,16 @@ func (mt *metaTx) better(than *metaTx, pendingBaseFee uint256.Int) bool { if effectiveTip.Cmp(&thanEffectiveTip) != 0 { return effectiveTip.Cmp(&thanEffectiveTip) > 0 } + // Compare nonce and cumulative balance. Just as a side note, it doesn't + // matter if they're from same sender or not because we're comparing + // nonce distance of the sender from state's nonce and not the actual + // value of nonce. + if mt.nonceDistance != than.nonceDistance { + return mt.nonceDistance < than.nonceDistance + } + if mt.cumulativeBalanceDistance != than.cumulativeBalanceDistance { + return mt.cumulativeBalanceDistance < than.cumulativeBalanceDistance + } case BaseFeeSubPool: if mt.minFeeCap.Cmp(&than.minFeeCap) != 0 { return mt.minFeeCap.Cmp(&than.minFeeCap) > 0