https://github.com/IntersectMBO/ouroboros-consensus/actions/runs/21832592717/job/62994870493?pr=1826#logs
The chain is:
Genesis -- A (0, -8986190201926803368, Valid)
\- B (2, -1486433721842374672, Invalid)
When the block B arrives, it is popped from the queue
TraceAddBlockEvent (PoppedBlockFromQueue (RealPoint (SlotNo 2) (TestHeaderHash (-1486433721842374672))))
and then it is ignored, because the block A has been boosted with Peras certificates, and the chainsel logic sees that it is at the same block number than the immutable tip so we should not switch:
TraceAddBlockEvent (IgnoreBlockOlderThanImmTip (RealPoint (SlotNo 2) (TestHeaderHash (-1486433721842374672))))
However when the ChainDB is then asked what is the MaxSlotNo, it reports 2. However this answer comes from:
curChainMaxSlotNo <-
maxSlotNoFromWithOrigin . AF.headSlot . icWithoutTime
<$> readTVar cdbChain
volatileDbMaxSlotNo <- VolatileDB.getMaxSlotNo cdbVolatileDB
queuedMaxSlotNo <- getMaxSlotNoChainSelQueue cdbChainSelQueue
return $ curChainMaxSlotNo `max` volatileDbMaxSlotNo `max` queuedMaxSlotNo
And the block is not in the cdbChain (as we saw no AddedToCurrentChain for this block), nor in the cdbVolatileDB (as we saw no AddedBlockToVolatileDB traces for this block) so it has to be in the chain sel queue? but it was unqueued precisely by the existance of the PoppedBlockFromQueue so something fishy is going on here.
Moreover, I cannot reproduce this test failure on my machine with the same seed and GHC
❯ cabal test storage-test --test-option="-p /ChainDB q-s-m.sequential/" --test-option="--quickcheck-replay=(SMGen 15194541575572225434 13540340026014931941,80)" --test-option="--hide-successes"
Build profile: -w ghc-9.12.2 -O1
In order, the following will be built (use -v for more details):
- ouroboros-consensus-0.28.0.0 (test:storage-test) (ephemeral targets)
Preprocessing test suite 'storage-test' for ouroboros-consensus-0.28.0.0...
Building test suite 'storage-test' for ouroboros-consensus-0.28.0.0...
Running 1 test suites...
Test suite storage-test: RUNNING...
All 1 tests passed (22.08s)
Test suite storage-test: PASS
Test suite logged to:
/home/javier/code/cardano/ouroboros-consensus/dist-newstyle/build/x86_64-linux/ghc-9.12.2/ouroboros-consensus-0.28.0.0/t/storage-test/test/ouroboros-consensus-0.28.0.0-storage-test.log
1 of 1 test suites (1 of 1 test cases) passed.
EDIT: actually, the reading from the queue happens from the set of known points:
data ChainSelQueue m blk = ChainSelQueue
{ varChainSelQueue :: TBQueue m (ChainSelMessage m blk)
, varChainSelPoints :: StrictTVar m (MultiSet (RealPoint blk))
}
but we only add when we add a block to the queue:
addBlockToAdd tracer (ChainSelQueue{varChainSelQueue, varChainSelPoints}) punish blk = do
...
modifyTVar varChainSelPoints $ MultiSet.insert pt
and we delete when we processed a block:
processedChainSelMessage ChainSelQueue{varChainSelPoints} = \case
ChainSelAddBlock BlockToAdd{blockToAdd = blk} ->
modifyTVar varChainSelPoints $ MultiSet.delete (blockRealPoint blk)
which gets called immediately after the chainSelSync:
( \message -> do
lift $ case message of
ChainSelReprocessLoEBlocks _ ->
trace PoppedReprocessLoEBlocksFromQueue
ChainSelAddBlock BlockToAdd{blockToAdd} ->
trace $ PoppedBlockFromQueue $ blockRealPoint blockToAdd
ChainSelAddPerasCert cert _varProcessed ->
traceWith cdbTracer $
TraceAddPerasCertEvent $
PoppedPerasCertFromQueue (getPerasCertRound cert) (getPerasCertBoostedBlock cert)
chainSelSync cdb message
lift $ atomically $ processedChainSelMessage cdbChainSelQueue message
)
https://github.com/IntersectMBO/ouroboros-consensus/actions/runs/21832592717/job/62994870493?pr=1826#logs
The chain is:
When the block B arrives, it is popped from the queue
and then it is ignored, because the block A has been boosted with Peras certificates, and the chainsel logic sees that it is at the same block number than the immutable tip so we should not switch:
However when the ChainDB is then asked what is the MaxSlotNo, it reports 2. However this answer comes from:
And the block is not in the cdbChain (as we saw no
AddedToCurrentChainfor this block), nor in the cdbVolatileDB (as we saw noAddedBlockToVolatileDBtraces for this block) so it has to be in the chain sel queue? but it was unqueued precisely by the existance of thePoppedBlockFromQueueso something fishy is going on here.Moreover, I cannot reproduce this test failure on my machine with the same seed and GHC
EDIT: actually, the reading from the queue happens from the set of known points:
but we only add when we add a block to the queue:
and we delete when we processed a block:
which gets called immediately after the chainSelSync: