Fix typo in tx_head.nim delta calculator

why:
  Causes havoc in most bit fringe cases.

details:
  When setting the head forward, the delta was wrongly registered from
  the static "left" end (which limits the loop) rather than the moving
  "right" end.
This commit is contained in:
Jordan Hrycaj 2022-04-04 16:56:21 +01:00
parent 4ad566a86a
commit f11b1a8d8e
No known key found for this signature in database
GPG Key ID: 4101B9BC5A0DB080
4 changed files with 49 additions and 22 deletions

View File

@ -600,6 +600,10 @@ proc jobDeltaTxsHead*(xp: TxPoolRef; newHead: BlockHeader): bool
# Re-inject transactions, do that via job queue # Re-inject transactions, do that via job queue
if 0 < changes.addTxs.len: if 0 < changes.addTxs.len:
debug "queuing delta txs",
mode = "inject",
num = changes.addTxs.len
discard xp.job(TxJobDataRef( discard xp.job(TxJobDataRef(
kind: txJobAddTxs, kind: txJobAddTxs,
addTxsArgs: ( addTxsArgs: (
@ -608,6 +612,10 @@ proc jobDeltaTxsHead*(xp: TxPoolRef; newHead: BlockHeader): bool
# Delete already *mined* transactions # Delete already *mined* transactions
if 0 < changes.remTxs.len: if 0 < changes.remTxs.len:
debug "queuing delta txs",
mode = "remove",
num = changes.remTxs.len
discard xp.job(TxJobDataRef( discard xp.job(TxJobDataRef(
kind: txJobDelItemIDs, kind: txJobDelItemIDs,
delItemIDsArgs: ( delItemIDsArgs: (

View File

@ -164,8 +164,10 @@ proc headDiff*(xp: TxPoolRef;
# | | # | |
# new << current (step back this one) # new << current (step back this one)
# #
# preserve transactions on the upper branch block numbers # + preserve transactions on the upper branch blocks,
# between #new..#current to be re-inserted into the pool #
# + txs of blocks with numbers between #new..#current need to be
# re-inserted into the pool
# #
while newHead.blockNumber < curBranchHead.blockNumber: while newHead.blockNumber < curBranchHead.blockNumber:
xp.insert(txDiffs, curBranchHash) xp.insert(txDiffs, curBranchHash)
@ -190,11 +192,13 @@ proc headDiff*(xp: TxPoolRef;
# | | # | |
# current << new (step back this one) # current << new (step back this one)
# #
# preserve transactions on the upper branch block numbers # + preserve some transactions on the upper branch blocks,
# between #current..#new to be deleted from the pool #
# + txs of blocks with numbers between #current..#new need to be
# deleted from the pool (as they are on the block chain, now)
# #
while curHead.blockNumber < newBranchHead.blockNumber: while curHead.blockNumber < newBranchHead.blockNumber:
xp.remove(txDiffs, curBranchHash) xp.remove(txDiffs, newBranchHash)
let let
tmpHead = newBranchHead # cache value for error logging tmpHead = newBranchHead # cache value for error logging
tmpHash = newBranchHash tmpHash = newBranchHash

View File

@ -905,8 +905,9 @@ proc txPoolMain*(noisy = defined(debug)) =
noisy.runTxLoader noisy.runTxLoader
noisy.runTxPoolTests noisy.runTxPoolTests
noisy.runTxPackerTests noisy.runTxPackerTests
test_txpool2.runTxPoolCliqueTest() runTxPoolCliqueTest()
test_txpool2.runTxPoolPosTest() runTxPoolPosTest()
noisy.runTxHeadDelta
when isMainModule: when isMainModule:
const const
@ -922,8 +923,9 @@ when isMainModule:
noisy.runTxPoolTests noisy.runTxPoolTests
noisy.runTxPackerTests noisy.runTxPackerTests
#runTxPoolCliqueTest() runTxPoolCliqueTest()
#runTxPoolPosTest() runTxPoolPosTest()
noisy.runTxHeadDelta
#noisy.runTxLoader(dir = ".") #noisy.runTxLoader(dir = ".")
#noisy.runTxPoolTests #noisy.runTxPoolTests

View File

@ -6,7 +6,7 @@ import
../nimbus/p2p/chain, ../nimbus/p2p/chain,
../nimbus/p2p/clique/[clique_sealer, clique_desc], ../nimbus/p2p/clique/[clique_sealer, clique_desc],
../nimbus/[chain_config, config, genesis, transaction, constants], ../nimbus/[chain_config, config, genesis, transaction, constants],
../nimbus/utils/[tx_pool], ../nimbus/utils/tx_pool,
./test_txpool/helpers, ./test_txpool/helpers,
./macro_assembler ./macro_assembler
@ -234,11 +234,11 @@ proc runTxPoolPosTest*() =
#runTxPoolPosTest() #runTxPoolPosTest()
proc runTxMissingTxNoce*(noisy = true) = proc runTxHeadDelta*(noisy = true) =
## see github.com/status-im/nimbus-eth1/issues/1031 ## see github.com/status-im/nimbus-eth1/issues/1031
suite "TxPool: Issue #1031": suite "TxPool: Synthesising blocks (covers issue #1031)":
test "Reproducing issue #1031": test "Packing and adding multiple blocks to chain":
var var
env = initEnv(some(100.u256)) env = initEnv(some(100.u256))
xp = env.xp xp = env.xp
@ -266,9 +266,10 @@ proc runTxMissingTxNoce*(noisy = true) =
xp.jobCommit() xp.jobCommit()
noisy.say "***", "stats", noisy.say "***", "txDB",
&" n={n}", &" n={n}",
&" pending/staged/packed:total/disposed={xp.nItems.pp}" # pending/staged/packed : total/disposed
&" stats={xp.nItems.pp}"
xp.prevRandao = prevRandao xp.prevRandao = prevRandao
var blk = xp.ethBlock() var blk = xp.ethBlock()
@ -285,15 +286,27 @@ proc runTxMissingTxNoce*(noisy = true) =
transactions: blk.txs, transactions: blk.txs,
uncles: blk.uncles) uncles: blk.uncles)
let rr = chain.persistBlocks([blk.header], [body]) # Commit to block chain
check rr.isOk check chain.persistBlocks([blk.header], [body]).isOk
# PoS block canonical head must be explicitly set using setHead # PoS block canonical head must be explicitly set using setHead. The
# function `persistHeaderToDb()` used in `persistBlocks()` does not
# reliably do so due to scoring.
chainDB.setHead(blk.header) chainDB.setHead(blk.header)
discard xp.jobDeltaTxsHead(blk.header) # Synchronise TxPool against new chain head, register txs differences.
# In this particular case, these differences will simply flush the
# packer bucket.
check xp.jobDeltaTxsHead(blk.header)
check xp.nJobs == 1
# Move TxPool chain head to new chain head and apply delta jobs
xp.head = blk.header xp.head = blk.header
xp.jobCommit() xp.jobCommit()
check xp.nItems.staged == 0
check xp.nItems.packed == 0
setErrorLevel() # in case we set trace level
check chainDB.currentBlock == 10.toBlockNumber check chainDB.currentBlock == 10.toBlockNumber
head = chainDB.getBlockHeader(chainDB.currentBlock) head = chainDB.getBlockHeader(chainDB.currentBlock)
@ -311,7 +324,7 @@ when isMainModule:
setErrorLevel() # mute logger setErrorLevel() # mute logger
runTxPoolCliqueTest() #runTxPoolCliqueTest()
runTxPoolPosTest() #runTxPoolPosTest()
true.runTxMissingTxNoce true.runTxHeadDelta