Skip to content
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

Fix model/SUT discrepancy in Chain DB tests #3389

Closed
dnadales opened this issue Sep 23, 2021 · 4 comments · Fixed by #3651
Closed

Fix model/SUT discrepancy in Chain DB tests #3389

dnadales opened this issue Sep 23, 2021 · 4 comments · Fixed by #3651
Labels
bug Something isn't working consensus issues related to ouroboros-consensus testing

Comments

@dnadales
Copy link
Member

dnadales commented Sep 23, 2021

The error

The model and SUT disagree on the validity of a point. More precisely, the point that corresponds to block with slot 11, block number 5.

For ease of reference, the ultimate error message is this:

PostconditionFailed
  "AnnotateC \"real response didn't match model response\" 
  (PredicateC 
    (    Resp {getResp = Right (IsValid (IsValidResult {real = True, isValid = Just True}))}
     :/= Resp {getResp = Right (IsValid (IsValidResult {real = False, isValid = Nothing}))})
  )" /= Ok
Click to see the full error message
FAIL (135.08s)
          *** Failed! Falsified (after 59650 tests and 12 shrinks):
          MaxClockSkew 100000
          SmallChunkInfo (UniformChunkSize (ChunkSize {chunkCanContainEBB = False, numRegularBlocks = 13}))
          Commands
            { unCommands =
                [ Command
                    At
                      { unAt =
                          AddBlock
                            TestBlock
                              { testHeader =
                                  TestHeader
                                    { thHash = TestHeaderHash (-8556510898270155945)
                                    , thPrevHash = GenesisHash
                                    , thBodyHash = TestBodyHash (-7234408896584323076)
                                    , thSlotNo = SlotNo 1
                                    , thBlockNo = BlockNo 0
                                    , thChainLength = ChainLength 1
                                    , thIsEBB = RegularBlock
                                    }
                              , testBody = TestBody { tbForkNo = 3 , tbIsValid = True }
                              }
                      }
                    At
                      { unAt =
                          Resp
                            { getResp =
                                Right
                                  (Point
                                     (At
                                        Block
                                          { blockPointSlot = SlotNo 1
                                          , blockPointHash = TestHeaderHash (-8556510898270155945)
                                          }))
                            }
                      }
                    []
                , Command
                    At
                      { unAt =
                          AddBlock
                            TestBlock
                              { testHeader =
                                  TestHeader
                                    { thHash = TestHeaderHash (-2888999216768647131)
                                    , thPrevHash = BlockHash (TestHeaderHash (-8556510898270155945))
                                    , thBodyHash = TestBodyHash (-7234408896584323076)
                                    , thSlotNo = SlotNo 3
                                    , thBlockNo = BlockNo 1
                                    , thChainLength = ChainLength 2
                                    , thIsEBB = RegularBlock
                                    }
                              , testBody = TestBody { tbForkNo = 3 , tbIsValid = True }
                              }
                      }
                    At
                      { unAt =
                          Resp
                            { getResp =
                                Right
                                  (Point
                                     (At
                                        Block
                                          { blockPointSlot = SlotNo 3
                                          , blockPointHash = TestHeaderHash (-2888999216768647131)
                                          }))
                            }
                      }
                    []
                , Command
                    At
                      { unAt =
                          AddBlock
                            TestBlock
                              { testHeader =
                                  TestHeader
                                    { thHash = TestHeaderHash 2102088202601657634
                                    , thPrevHash = BlockHash (TestHeaderHash (-2888999216768647131))
                                    , thBodyHash = TestBodyHash (-7234408896601100693)
                                    , thSlotNo = SlotNo 5
                                    , thBlockNo = BlockNo 2
                                    , thChainLength = ChainLength 3
                                    , thIsEBB = RegularBlock
                                    }
                              , testBody = TestBody { tbForkNo = 2 , tbIsValid = True }
                              }
                      }
                    At
                      { unAt =
                          Resp
                            { getResp =
                                Right
                                  (Point
                                     (At
                                        Block
                                          { blockPointSlot = SlotNo 5
                                          , blockPointHash = TestHeaderHash 2102088202601657634
                                          }))
                            }
                      }
                    []
                , Command
                    At
                      { unAt =
                          AddBlock
                            TestBlock
                              { testHeader =
                                  TestHeader
                                    { thHash = TestHeaderHash (-8617166116099525105)
                                    , thPrevHash = BlockHash (TestHeaderHash 7412945834010847025)
                                    , thBodyHash = TestBodyHash (-7234408896584323076)
                                    , thSlotNo = SlotNo 11
                                    , thBlockNo = BlockNo 4
                                    , thChainLength = ChainLength 5
                                    , thIsEBB = RegularBlock
                                    }
                              , testBody = TestBody { tbForkNo = 3 , tbIsValid = True }
                              }
                      }
                    At
                      { unAt =
                          Resp
                            { getResp =
                                Right
                                  (Point
                                     (At
                                        Block
                                          { blockPointSlot = SlotNo 5
                                          , blockPointHash = TestHeaderHash 2102088202601657634
                                          }))
                            }
                      }
                    []
                , Command
                    At
                      { unAt =
                          AddBlock
                            TestBlock
                              { testHeader =
                                  TestHeader
                                    { thHash = TestHeaderHash 7412945834010847025
                                    , thPrevHash = BlockHash (TestHeaderHash 2102088202601657634)
                                    , thBodyHash = TestBodyHash (-7234408896617878314)
                                    , thSlotNo = SlotNo 8
                                    , thBlockNo = BlockNo 3
                                    , thChainLength = ChainLength 4
                                    , thIsEBB = RegularBlock
                                    }
                              , testBody = TestBody { tbForkNo = 1 , tbIsValid = True }
                              }
                      }
                    At
                      { unAt =
                          Resp
                            { getResp =
                                Right
                                  (Point
                                     (At
                                        Block
                                          { blockPointSlot = SlotNo 11
                                          , blockPointHash = TestHeaderHash (-8617166116099525105)
                                          }))
                            }
                      }
                    []
                , Command
                    At
                      { unAt =
                          AddBlock
                            TestBlock
                              { testHeader =
                                  TestHeader
                                    { thHash = TestHeaderHash (-8276854694911826380)
                                    , thPrevHash = BlockHash (TestHeaderHash 7412945834010847025)
                                    , thBodyHash = TestBodyHash (-7234408896584323076)
                                    , thSlotNo = SlotNo 10
                                    , thBlockNo = BlockNo 4
                                    , thChainLength = ChainLength 5
                                    , thIsEBB = RegularBlock
                                    }
                              , testBody = TestBody { tbForkNo = 3 , tbIsValid = True }
                              }
                      }
                    At
                      { unAt =
                          Resp
                            { getResp =
                                Right
                                  (Point
                                     (At
                                        Block
                                          { blockPointSlot = SlotNo 10
                                          , blockPointHash = TestHeaderHash (-8276854694911826380)
                                          }))
                            }
                      }
                    []
                , Command
                    At
                      { unAt =
                          AddBlock
                            TestBlock
                              { testHeader =
                                  TestHeader
                                    { thHash = TestHeaderHash 455202168906668063
                                    , thPrevHash = BlockHash (TestHeaderHash (-8276854694911826380))
                                    , thBodyHash = TestBodyHash (-7234408896601100693)
                                    , thSlotNo = SlotNo 11
                                    , thBlockNo = BlockNo 5
                                    , thChainLength = ChainLength 6
                                    , thIsEBB = RegularBlock
                                    }
                              , testBody = TestBody { tbForkNo = 2 , tbIsValid = True }
                              }
                      }
                    At
                      { unAt =
                          Resp
                            { getResp =
                                Right
                                  (Point
                                     (At
                                        Block
                                          { blockPointSlot = SlotNo 11
                                          , blockPointHash = TestHeaderHash 455202168906668063
                                          }))
                            }
                      }
                    []
                , Command
                    At
                      { unAt =
                          AddBlock
                            TestBlock
                              { testHeader =
                                  TestHeader
                                    { thHash = TestHeaderHash 5691200944682986263
                                    , thPrevHash = BlockHash (TestHeaderHash (-8617166116099525105))
                                    , thBodyHash = TestBodyHash (-7234408896601100693)
                                    , thSlotNo = SlotNo 12
                                    , thBlockNo = BlockNo 5
                                    , thChainLength = ChainLength 6
                                    , thIsEBB = RegularBlock
                                    }
                              , testBody = TestBody { tbForkNo = 2 , tbIsValid = True }
                              }
                      }
                    At
                      { unAt =
                          Resp
                            { getResp =
                                Right
                                  (Point
                                     (At
                                        Block
                                          { blockPointSlot = SlotNo 12
                                          , blockPointHash = TestHeaderHash 5691200944682986263
                                          }))
                            }
                      }
                    []
                , Command
                    At
                      { unAt =
                          AddBlock
                            TestBlock
                              { testHeader =
                                  TestHeader
                                    { thHash = TestHeaderHash (-5397328272732179662)
                                    , thPrevHash = BlockHash (TestHeaderHash 5691200944682986263)
                                    , thBodyHash = TestBodyHash (-7234408896584323076)
                                    , thSlotNo = SlotNo 14
                                    , thBlockNo = BlockNo 6
                                    , thChainLength = ChainLength 7
                                    , thIsEBB = RegularBlock
                                    }
                              , testBody = TestBody { tbForkNo = 3 , tbIsValid = True }
                              }
                      }
                    At
                      { unAt =
                          Resp
                            { getResp =
                                Right
                                  (Point
                                     (At
                                        Block
                                          { blockPointSlot = SlotNo 14
                                          , blockPointHash = TestHeaderHash (-5397328272732179662)
                                          }))
                            }
                      }
                    []
                , Command
                    At { unAt = PersistBlksThenGC }
                    At { unAt = Resp { getResp = Right (Unit ()) } }
                    []
                , Command
                    At
                      { unAt =
                          GetIsValid
                            (RealPoint (SlotNo 11) (TestHeaderHash 455202168906668063))
                      }
                    At
                      { unAt =
                          Resp
                            { getResp =
                                Right (IsValid IsValidResult { real = False , isValid = Nothing })
                            }
                      }
                    []
                ]
            }
          Model chain: Genesis :> TestBlock {testHeader = TestHeader {thHash = TestHeaderHash (-8556510898270155945), thPrevHash = GenesisHash, thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 1, thBlockNo = BlockNo 0, thChainLength = ChainLength 1, thIsEBB = RegularBlock}, testBody = TestBody {tbForkNo = 3, tbIsValid = True}} :> TestBlock {testHeader = TestHeader {thHash = TestHeaderHash (-2888999216768647131), thPrevHash = BlockHash (TestHeaderHash (-8556510898270155945)), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 3, thBlockNo = BlockNo 1, thChainLength = ChainLength 2, thIsEBB = RegularBlock}, testBody = TestBody {tbForkNo = 3, tbIsValid = True}} :> TestBlock {testHeader = TestHeader {thHash = TestHeaderHash 2102088202601657634, thPrevHash = BlockHash (TestHeaderHash (-2888999216768647131)), thBodyHash = TestBodyHash (-7234408896601100693), thSlotNo = SlotNo 5, thBlockNo = BlockNo 2, thChainLength = ChainLength 3, thIsEBB = RegularBlock}, testBody = TestBody {tbForkNo = 2, tbIsValid = True}} :> TestBlock {testHeader = TestHeader {thHash = TestHeaderHash 7412945834010847025, thPrevHash = BlockHash (TestHeaderHash 2102088202601657634), thBodyHash = TestBodyHash (-7234408896617878314), thSlotNo = SlotNo 8, thBlockNo = BlockNo 3, thChainLength = ChainLength 4, thIsEBB = RegularBlock}, testBody = TestBody {tbForkNo = 1, tbIsValid = True}} :> TestBlock {testHeader = TestHeader {thHash = TestHeaderHash (-8617166116099525105), thPrevHash = BlockHash (TestHeaderHash 7412945834010847025), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 11, thBlockNo = BlockNo 4, thChainLength = ChainLength 5, thIsEBB = RegularBlock}, testBody = TestBody {tbForkNo = 3, tbIsValid = True}} :> TestBlock {testHeader = TestHeader {thHash = TestHeaderHash 5691200944682986263, thPrevHash = BlockHash (TestHeaderHash (-8617166116099525105)), thBodyHash = TestBodyHash (-7234408896601100693), thSlotNo = SlotNo 12, thBlockNo = BlockNo 5, thChainLength = ChainLength 6, thIsEBB = RegularBlock}, testBody = TestBody {tbForkNo = 2, tbIsValid = True}} :> TestBlock {testHeader = TestHeader {thHash = TestHeaderHash (-5397328272732179662), thPrevHash = BlockHash (TestHeaderHash 5691200944682986263), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 14, thBlockNo = BlockNo 6, thChainLength = ChainLength 7, thIsEBB = RegularBlock}, testBody = TestBody {tbForkNo = 3, tbIsValid = True}}
          TraceEvents: TraceImmutableDBEvent NoValidLastLocation
          TraceOpenEvent (OpenedImmutableDB Origin 0)
          TraceOpenEvent OpenedVolatileDB
          TraceLedgerReplayEvent (ReplayFromGenesis Origin)
          TraceOpenEvent OpenedLgrDB
          TraceOpenEvent (OpenedDB Origin Origin)
          TraceAddBlockEvent (AddedBlockToQueue (RealPoint (SlotNo 1) (TestHeaderHash (-8556510898270155945))) 1)
          TraceAddBlockEvent (AddedBlockToVolatileDB (RealPoint (SlotNo 1) (TestHeaderHash (-8556510898270155945))) (BlockNo 0) IsNotEBB)
          TraceAddBlockEvent (TryAddToCurrentChain (RealPoint (SlotNo 1) (TestHeaderHash (-8556510898270155945))))
          TraceAddBlockEvent (AddBlockValidation (ValidCandidate (AnchoredSeq {anchor = AnchorGenesis, unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8556510898270155945), thPrevHash = GenesisHash, thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 1, thBlockNo = BlockNo 0, thChainLength = ChainLength 1, thIsEBB = RegularBlock}}]}})))
          TraceAddBlockEvent (AddedToCurrentChain [] (NewTipInfo {newTipPoint = RealPoint (SlotNo 1) (TestHeaderHash (-8556510898270155945)), newTipEpoch = EpochNo 0, newTipSlotInEpoch = 1, newTipTrigger = RealPoint (SlotNo 1) (TestHeaderHash (-8556510898270155945))}) (AnchoredSeq {anchor = AnchorGenesis, unanchorSeq = SFT {fromStrict = fromList []}}) (AnchoredSeq {anchor = AnchorGenesis, unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8556510898270155945), thPrevHash = GenesisHash, thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 1, thBlockNo = BlockNo 0, thChainLength = ChainLength 1, thIsEBB = RegularBlock}}]}}))
          TraceAddBlockEvent (AddedBlockToQueue (RealPoint (SlotNo 3) (TestHeaderHash (-2888999216768647131))) 1)
          TraceAddBlockEvent (AddedBlockToVolatileDB (RealPoint (SlotNo 3) (TestHeaderHash (-2888999216768647131))) (BlockNo 1) IsNotEBB)
          TraceAddBlockEvent (TryAddToCurrentChain (RealPoint (SlotNo 3) (TestHeaderHash (-2888999216768647131))))
          TraceAddBlockEvent (AddBlockValidation (ValidCandidate (AnchoredSeq {anchor = Anchor (SlotNo 1) (TestHeaderHash (-8556510898270155945)) (BlockNo 0), unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-2888999216768647131), thPrevHash = BlockHash (TestHeaderHash (-8556510898270155945)), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 3, thBlockNo = BlockNo 1, thChainLength = ChainLength 2, thIsEBB = RegularBlock}}]}})))
          TraceAddBlockEvent (AddedToCurrentChain [] (NewTipInfo {newTipPoint = RealPoint (SlotNo 3) (TestHeaderHash (-2888999216768647131)), newTipEpoch = EpochNo 0, newTipSlotInEpoch = 3, newTipTrigger = RealPoint (SlotNo 3) (TestHeaderHash (-2888999216768647131))}) (AnchoredSeq {anchor = AnchorGenesis, unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8556510898270155945), thPrevHash = GenesisHash, thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 1, thBlockNo = BlockNo 0, thChainLength = ChainLength 1, thIsEBB = RegularBlock}}]}}) (AnchoredSeq {anchor = AnchorGenesis, unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8556510898270155945), thPrevHash = GenesisHash, thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 1, thBlockNo = BlockNo 0, thChainLength = ChainLength 1, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-2888999216768647131), thPrevHash = BlockHash (TestHeaderHash (-8556510898270155945)), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 3, thBlockNo = BlockNo 1, thChainLength = ChainLength 2, thIsEBB = RegularBlock}}]}}))
          TraceAddBlockEvent (AddedBlockToQueue (RealPoint (SlotNo 5) (TestHeaderHash 2102088202601657634)) 1)
          TraceAddBlockEvent (AddedBlockToVolatileDB (RealPoint (SlotNo 5) (TestHeaderHash 2102088202601657634)) (BlockNo 2) IsNotEBB)
          TraceAddBlockEvent (TryAddToCurrentChain (RealPoint (SlotNo 5) (TestHeaderHash 2102088202601657634)))
          TraceAddBlockEvent (AddBlockValidation (ValidCandidate (AnchoredSeq {anchor = Anchor (SlotNo 3) (TestHeaderHash (-2888999216768647131)) (BlockNo 1), unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 2102088202601657634, thPrevHash = BlockHash (TestHeaderHash (-2888999216768647131)), thBodyHash = TestBodyHash (-7234408896601100693), thSlotNo = SlotNo 5, thBlockNo = BlockNo 2, thChainLength = ChainLength 3, thIsEBB = RegularBlock}}]}})))
          TraceAddBlockEvent (AddedToCurrentChain [] (NewTipInfo {newTipPoint = RealPoint (SlotNo 5) (TestHeaderHash 2102088202601657634), newTipEpoch = EpochNo 0, newTipSlotInEpoch = 5, newTipTrigger = RealPoint (SlotNo 5) (TestHeaderHash 2102088202601657634)}) (AnchoredSeq {anchor = AnchorGenesis, unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8556510898270155945), thPrevHash = GenesisHash, thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 1, thBlockNo = BlockNo 0, thChainLength = ChainLength 1, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-2888999216768647131), thPrevHash = BlockHash (TestHeaderHash (-8556510898270155945)), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 3, thBlockNo = BlockNo 1, thChainLength = ChainLength 2, thIsEBB = RegularBlock}}]}}) (AnchoredSeq {anchor = AnchorGenesis, unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8556510898270155945), thPrevHash = GenesisHash, thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 1, thBlockNo = BlockNo 0, thChainLength = ChainLength 1, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-2888999216768647131), thPrevHash = BlockHash (TestHeaderHash (-8556510898270155945)), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 3, thBlockNo = BlockNo 1, thChainLength = ChainLength 2, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 2102088202601657634, thPrevHash = BlockHash (TestHeaderHash (-2888999216768647131)), thBodyHash = TestBodyHash (-7234408896601100693), thSlotNo = SlotNo 5, thBlockNo = BlockNo 2, thChainLength = ChainLength 3, thIsEBB = RegularBlock}}]}}))
          TraceAddBlockEvent (AddedBlockToQueue (RealPoint (SlotNo 11) (TestHeaderHash (-8617166116099525105))) 1)
          TraceAddBlockEvent (AddedBlockToVolatileDB (RealPoint (SlotNo 11) (TestHeaderHash (-8617166116099525105))) (BlockNo 4) IsNotEBB)
          TraceAddBlockEvent (StoreButDontChange (RealPoint (SlotNo 11) (TestHeaderHash (-8617166116099525105))))
          TraceAddBlockEvent (AddedBlockToQueue (RealPoint (SlotNo 8) (TestHeaderHash 7412945834010847025)) 1)
          TraceAddBlockEvent (AddedBlockToVolatileDB (RealPoint (SlotNo 8) (TestHeaderHash 7412945834010847025)) (BlockNo 3) IsNotEBB)
          TraceAddBlockEvent (TryAddToCurrentChain (RealPoint (SlotNo 8) (TestHeaderHash 7412945834010847025)))
          TraceAddBlockEvent (AddBlockValidation (ValidCandidate (AnchoredSeq {anchor = Anchor (SlotNo 5) (TestHeaderHash 2102088202601657634) (BlockNo 2), unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 7412945834010847025, thPrevHash = BlockHash (TestHeaderHash 2102088202601657634), thBodyHash = TestBodyHash (-7234408896617878314), thSlotNo = SlotNo 8, thBlockNo = BlockNo 3, thChainLength = ChainLength 4, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8617166116099525105), thPrevHash = BlockHash (TestHeaderHash 7412945834010847025), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 11, thBlockNo = BlockNo 4, thChainLength = ChainLength 5, thIsEBB = RegularBlock}}]}})))
          TraceAddBlockEvent (AddedToCurrentChain [] (NewTipInfo {newTipPoint = RealPoint (SlotNo 11) (TestHeaderHash (-8617166116099525105)), newTipEpoch = EpochNo 0, newTipSlotInEpoch = 11, newTipTrigger = RealPoint (SlotNo 8) (TestHeaderHash 7412945834010847025)}) (AnchoredSeq {anchor = AnchorGenesis, unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8556510898270155945), thPrevHash = GenesisHash, thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 1, thBlockNo = BlockNo 0, thChainLength = ChainLength 1, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-2888999216768647131), thPrevHash = BlockHash (TestHeaderHash (-8556510898270155945)), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 3, thBlockNo = BlockNo 1, thChainLength = ChainLength 2, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 2102088202601657634, thPrevHash = BlockHash (TestHeaderHash (-2888999216768647131)), thBodyHash = TestBodyHash (-7234408896601100693), thSlotNo = SlotNo 5, thBlockNo = BlockNo 2, thChainLength = ChainLength 3, thIsEBB = RegularBlock}}]}}) (AnchoredSeq {anchor = AnchorGenesis, unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8556510898270155945), thPrevHash = GenesisHash, thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 1, thBlockNo = BlockNo 0, thChainLength = ChainLength 1, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-2888999216768647131), thPrevHash = BlockHash (TestHeaderHash (-8556510898270155945)), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 3, thBlockNo = BlockNo 1, thChainLength = ChainLength 2, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 2102088202601657634, thPrevHash = BlockHash (TestHeaderHash (-2888999216768647131)), thBodyHash = TestBodyHash (-7234408896601100693), thSlotNo = SlotNo 5, thBlockNo = BlockNo 2, thChainLength = ChainLength 3, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 7412945834010847025, thPrevHash = BlockHash (TestHeaderHash 2102088202601657634), thBodyHash = TestBodyHash (-7234408896617878314), thSlotNo = SlotNo 8, thBlockNo = BlockNo 3, thChainLength = ChainLength 4, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8617166116099525105), thPrevHash = BlockHash (TestHeaderHash 7412945834010847025), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 11, thBlockNo = BlockNo 4, thChainLength = ChainLength 5, thIsEBB = RegularBlock}}]}}))
          TraceAddBlockEvent (AddedBlockToQueue (RealPoint (SlotNo 10) (TestHeaderHash (-8276854694911826380))) 1)
          TraceAddBlockEvent (AddedBlockToVolatileDB (RealPoint (SlotNo 10) (TestHeaderHash (-8276854694911826380))) (BlockNo 4) IsNotEBB)
          TraceAddBlockEvent (TrySwitchToAFork (RealPoint (SlotNo 10) (TestHeaderHash (-8276854694911826380))) (ChainDiff {getRollback = 1, getSuffix = AnchoredSeq {anchor = Anchor (SlotNo 8) (TestHeaderHash 7412945834010847025) (BlockNo 3), unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = HeaderFields {headerFieldSlot = SlotNo 10, headerFieldBlockNo = BlockNo 4, headerFieldHash = TestHeaderHash (-8276854694911826380)}}]}}}))
          TraceAddBlockEvent (AddBlockValidation (ValidCandidate (AnchoredSeq {anchor = Anchor (SlotNo 8) (TestHeaderHash 7412945834010847025) (BlockNo 3), unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8276854694911826380), thPrevHash = BlockHash (TestHeaderHash 7412945834010847025), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 10, thBlockNo = BlockNo 4, thChainLength = ChainLength 5, thIsEBB = RegularBlock}}]}})))
          TraceAddBlockEvent (SwitchedToAFork [] (NewTipInfo {newTipPoint = RealPoint (SlotNo 10) (TestHeaderHash (-8276854694911826380)), newTipEpoch = EpochNo 0, newTipSlotInEpoch = 10, newTipTrigger = RealPoint (SlotNo 10) (TestHeaderHash (-8276854694911826380))}) (AnchoredSeq {anchor = AnchorGenesis, unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8556510898270155945), thPrevHash = GenesisHash, thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 1, thBlockNo = BlockNo 0, thChainLength = ChainLength 1, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-2888999216768647131), thPrevHash = BlockHash (TestHeaderHash (-8556510898270155945)), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 3, thBlockNo = BlockNo 1, thChainLength = ChainLength 2, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 2102088202601657634, thPrevHash = BlockHash (TestHeaderHash (-2888999216768647131)), thBodyHash = TestBodyHash (-7234408896601100693), thSlotNo = SlotNo 5, thBlockNo = BlockNo 2, thChainLength = ChainLength 3, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 7412945834010847025, thPrevHash = BlockHash (TestHeaderHash 2102088202601657634), thBodyHash = TestBodyHash (-7234408896617878314), thSlotNo = SlotNo 8, thBlockNo = BlockNo 3, thChainLength = ChainLength 4, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8617166116099525105), thPrevHash = BlockHash (TestHeaderHash 7412945834010847025), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 11, thBlockNo = BlockNo 4, thChainLength = ChainLength 5, thIsEBB = RegularBlock}}]}}) (AnchoredSeq {anchor = AnchorGenesis, unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8556510898270155945), thPrevHash = GenesisHash, thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 1, thBlockNo = BlockNo 0, thChainLength = ChainLength 1, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-2888999216768647131), thPrevHash = BlockHash (TestHeaderHash (-8556510898270155945)), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 3, thBlockNo = BlockNo 1, thChainLength = ChainLength 2, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 2102088202601657634, thPrevHash = BlockHash (TestHeaderHash (-2888999216768647131)), thBodyHash = TestBodyHash (-7234408896601100693), thSlotNo = SlotNo 5, thBlockNo = BlockNo 2, thChainLength = ChainLength 3, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 7412945834010847025, thPrevHash = BlockHash (TestHeaderHash 2102088202601657634), thBodyHash = TestBodyHash (-7234408896617878314), thSlotNo = SlotNo 8, thBlockNo = BlockNo 3, thChainLength = ChainLength 4, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8276854694911826380), thPrevHash = BlockHash (TestHeaderHash 7412945834010847025), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 10, thBlockNo = BlockNo 4, thChainLength = ChainLength 5, thIsEBB = RegularBlock}}]}}))
          TraceAddBlockEvent (AddedBlockToQueue (RealPoint (SlotNo 11) (TestHeaderHash 455202168906668063)) 1)
          TraceAddBlockEvent (AddedBlockToVolatileDB (RealPoint (SlotNo 11) (TestHeaderHash 455202168906668063)) (BlockNo 5) IsNotEBB)
          TraceAddBlockEvent (TryAddToCurrentChain (RealPoint (SlotNo 11) (TestHeaderHash 455202168906668063)))
          TraceAddBlockEvent (AddBlockValidation (ValidCandidate (AnchoredSeq {anchor = Anchor (SlotNo 10) (TestHeaderHash (-8276854694911826380)) (BlockNo 4), unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 455202168906668063, thPrevHash = BlockHash (TestHeaderHash (-8276854694911826380)), thBodyHash = TestBodyHash (-7234408896601100693), thSlotNo = SlotNo 11, thBlockNo = BlockNo 5, thChainLength = ChainLength 6, thIsEBB = RegularBlock}}]}})))
          TraceAddBlockEvent (AddedToCurrentChain [] (NewTipInfo {newTipPoint = RealPoint (SlotNo 11) (TestHeaderHash 455202168906668063), newTipEpoch = EpochNo 0, newTipSlotInEpoch = 11, newTipTrigger = RealPoint (SlotNo 11) (TestHeaderHash 455202168906668063)}) (AnchoredSeq {anchor = AnchorGenesis, unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8556510898270155945), thPrevHash = GenesisHash, thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 1, thBlockNo = BlockNo 0, thChainLength = ChainLength 1, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-2888999216768647131), thPrevHash = BlockHash (TestHeaderHash (-8556510898270155945)), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 3, thBlockNo = BlockNo 1, thChainLength = ChainLength 2, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 2102088202601657634, thPrevHash = BlockHash (TestHeaderHash (-2888999216768647131)), thBodyHash = TestBodyHash (-7234408896601100693), thSlotNo = SlotNo 5, thBlockNo = BlockNo 2, thChainLength = ChainLength 3, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 7412945834010847025, thPrevHash = BlockHash (TestHeaderHash 2102088202601657634), thBodyHash = TestBodyHash (-7234408896617878314), thSlotNo = SlotNo 8, thBlockNo = BlockNo 3, thChainLength = ChainLength 4, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8276854694911826380), thPrevHash = BlockHash (TestHeaderHash 7412945834010847025), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 10, thBlockNo = BlockNo 4, thChainLength = ChainLength 5, thIsEBB = RegularBlock}}]}}) (AnchoredSeq {anchor = AnchorGenesis, unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8556510898270155945), thPrevHash = GenesisHash, thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 1, thBlockNo = BlockNo 0, thChainLength = ChainLength 1, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-2888999216768647131), thPrevHash = BlockHash (TestHeaderHash (-8556510898270155945)), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 3, thBlockNo = BlockNo 1, thChainLength = ChainLength 2, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 2102088202601657634, thPrevHash = BlockHash (TestHeaderHash (-2888999216768647131)), thBodyHash = TestBodyHash (-7234408896601100693), thSlotNo = SlotNo 5, thBlockNo = BlockNo 2, thChainLength = ChainLength 3, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 7412945834010847025, thPrevHash = BlockHash (TestHeaderHash 2102088202601657634), thBodyHash = TestBodyHash (-7234408896617878314), thSlotNo = SlotNo 8, thBlockNo = BlockNo 3, thChainLength = ChainLength 4, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8276854694911826380), thPrevHash = BlockHash (TestHeaderHash 7412945834010847025), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 10, thBlockNo = BlockNo 4, thChainLength = ChainLength 5, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 455202168906668063, thPrevHash = BlockHash (TestHeaderHash (-8276854694911826380)), thBodyHash = TestBodyHash (-7234408896601100693), thSlotNo = SlotNo 11, thBlockNo = BlockNo 5, thChainLength = ChainLength 6, thIsEBB = RegularBlock}}]}}))
          TraceAddBlockEvent (AddedBlockToQueue (RealPoint (SlotNo 12) (TestHeaderHash 5691200944682986263)) 1)
          TraceAddBlockEvent (AddedBlockToVolatileDB (RealPoint (SlotNo 12) (TestHeaderHash 5691200944682986263)) (BlockNo 5) IsNotEBB)
          TraceAddBlockEvent (TrySwitchToAFork (RealPoint (SlotNo 12) (TestHeaderHash 5691200944682986263)) (ChainDiff {getRollback = 2, getSuffix = AnchoredSeq {anchor = Anchor (SlotNo 8) (TestHeaderHash 7412945834010847025) (BlockNo 3), unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = HeaderFields {headerFieldSlot = SlotNo 11, headerFieldBlockNo = BlockNo 4, headerFieldHash = TestHeaderHash (-8617166116099525105)}},MeasuredWith {unMeasuredWith = HeaderFields {headerFieldSlot = SlotNo 12, headerFieldBlockNo = BlockNo 5, headerFieldHash = TestHeaderHash 5691200944682986263}}]}}}))
          TraceAddBlockEvent (AddBlockValidation (ValidCandidate (AnchoredSeq {anchor = Anchor (SlotNo 8) (TestHeaderHash 7412945834010847025) (BlockNo 3), unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8617166116099525105), thPrevHash = BlockHash (TestHeaderHash 7412945834010847025), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 11, thBlockNo = BlockNo 4, thChainLength = ChainLength 5, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 5691200944682986263, thPrevHash = BlockHash (TestHeaderHash (-8617166116099525105)), thBodyHash = TestBodyHash (-7234408896601100693), thSlotNo = SlotNo 12, thBlockNo = BlockNo 5, thChainLength = ChainLength 6, thIsEBB = RegularBlock}}]}})))
          TraceAddBlockEvent (SwitchedToAFork [] (NewTipInfo {newTipPoint = RealPoint (SlotNo 12) (TestHeaderHash 5691200944682986263), newTipEpoch = EpochNo 0, newTipSlotInEpoch = 12, newTipTrigger = RealPoint (SlotNo 12) (TestHeaderHash 5691200944682986263)}) (AnchoredSeq {anchor = AnchorGenesis, unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8556510898270155945), thPrevHash = GenesisHash, thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 1, thBlockNo = BlockNo 0, thChainLength = ChainLength 1, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-2888999216768647131), thPrevHash = BlockHash (TestHeaderHash (-8556510898270155945)), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 3, thBlockNo = BlockNo 1, thChainLength = ChainLength 2, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 2102088202601657634, thPrevHash = BlockHash (TestHeaderHash (-2888999216768647131)), thBodyHash = TestBodyHash (-7234408896601100693), thSlotNo = SlotNo 5, thBlockNo = BlockNo 2, thChainLength = ChainLength 3, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 7412945834010847025, thPrevHash = BlockHash (TestHeaderHash 2102088202601657634), thBodyHash = TestBodyHash (-7234408896617878314), thSlotNo = SlotNo 8, thBlockNo = BlockNo 3, thChainLength = ChainLength 4, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8276854694911826380), thPrevHash = BlockHash (TestHeaderHash 7412945834010847025), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 10, thBlockNo = BlockNo 4, thChainLength = ChainLength 5, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 455202168906668063, thPrevHash = BlockHash (TestHeaderHash (-8276854694911826380)), thBodyHash = TestBodyHash (-7234408896601100693), thSlotNo = SlotNo 11, thBlockNo = BlockNo 5, thChainLength = ChainLength 6, thIsEBB = RegularBlock}}]}}) (AnchoredSeq {anchor = AnchorGenesis, unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8556510898270155945), thPrevHash = GenesisHash, thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 1, thBlockNo = BlockNo 0, thChainLength = ChainLength 1, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-2888999216768647131), thPrevHash = BlockHash (TestHeaderHash (-8556510898270155945)), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 3, thBlockNo = BlockNo 1, thChainLength = ChainLength 2, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 2102088202601657634, thPrevHash = BlockHash (TestHeaderHash (-2888999216768647131)), thBodyHash = TestBodyHash (-7234408896601100693), thSlotNo = SlotNo 5, thBlockNo = BlockNo 2, thChainLength = ChainLength 3, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 7412945834010847025, thPrevHash = BlockHash (TestHeaderHash 2102088202601657634), thBodyHash = TestBodyHash (-7234408896617878314), thSlotNo = SlotNo 8, thBlockNo = BlockNo 3, thChainLength = ChainLength 4, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8617166116099525105), thPrevHash = BlockHash (TestHeaderHash 7412945834010847025), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 11, thBlockNo = BlockNo 4, thChainLength = ChainLength 5, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 5691200944682986263, thPrevHash = BlockHash (TestHeaderHash (-8617166116099525105)), thBodyHash = TestBodyHash (-7234408896601100693), thSlotNo = SlotNo 12, thBlockNo = BlockNo 5, thChainLength = ChainLength 6, thIsEBB = RegularBlock}}]}}))
          TraceAddBlockEvent (AddedBlockToQueue (RealPoint (SlotNo 14) (TestHeaderHash (-5397328272732179662))) 1)
          TraceAddBlockEvent (AddedBlockToVolatileDB (RealPoint (SlotNo 14) (TestHeaderHash (-5397328272732179662))) (BlockNo 6) IsNotEBB)
          TraceAddBlockEvent (TryAddToCurrentChain (RealPoint (SlotNo 14) (TestHeaderHash (-5397328272732179662))))
          TraceAddBlockEvent (AddBlockValidation (ValidCandidate (AnchoredSeq {anchor = Anchor (SlotNo 12) (TestHeaderHash 5691200944682986263) (BlockNo 5), unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-5397328272732179662), thPrevHash = BlockHash (TestHeaderHash 5691200944682986263), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 14, thBlockNo = BlockNo 6, thChainLength = ChainLength 7, thIsEBB = RegularBlock}}]}})))
          TraceAddBlockEvent (AddedToCurrentChain [] (NewTipInfo {newTipPoint = RealPoint (SlotNo 14) (TestHeaderHash (-5397328272732179662)), newTipEpoch = EpochNo 1, newTipSlotInEpoch = 1, newTipTrigger = RealPoint (SlotNo 14) (TestHeaderHash (-5397328272732179662))}) (AnchoredSeq {anchor = AnchorGenesis, unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8556510898270155945), thPrevHash = GenesisHash, thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 1, thBlockNo = BlockNo 0, thChainLength = ChainLength 1, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-2888999216768647131), thPrevHash = BlockHash (TestHeaderHash (-8556510898270155945)), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 3, thBlockNo = BlockNo 1, thChainLength = ChainLength 2, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 2102088202601657634, thPrevHash = BlockHash (TestHeaderHash (-2888999216768647131)), thBodyHash = TestBodyHash (-7234408896601100693), thSlotNo = SlotNo 5, thBlockNo = BlockNo 2, thChainLength = ChainLength 3, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 7412945834010847025, thPrevHash = BlockHash (TestHeaderHash 2102088202601657634), thBodyHash = TestBodyHash (-7234408896617878314), thSlotNo = SlotNo 8, thBlockNo = BlockNo 3, thChainLength = ChainLength 4, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8617166116099525105), thPrevHash = BlockHash (TestHeaderHash 7412945834010847025), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 11, thBlockNo = BlockNo 4, thChainLength = ChainLength 5, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 5691200944682986263, thPrevHash = BlockHash (TestHeaderHash (-8617166116099525105)), thBodyHash = TestBodyHash (-7234408896601100693), thSlotNo = SlotNo 12, thBlockNo = BlockNo 5, thChainLength = ChainLength 6, thIsEBB = RegularBlock}}]}}) (AnchoredSeq {anchor = AnchorGenesis, unanchorSeq = SFT {fromStrict = fromList [MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8556510898270155945), thPrevHash = GenesisHash, thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 1, thBlockNo = BlockNo 0, thChainLength = ChainLength 1, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-2888999216768647131), thPrevHash = BlockHash (TestHeaderHash (-8556510898270155945)), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 3, thBlockNo = BlockNo 1, thChainLength = ChainLength 2, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 2102088202601657634, thPrevHash = BlockHash (TestHeaderHash (-2888999216768647131)), thBodyHash = TestBodyHash (-7234408896601100693), thSlotNo = SlotNo 5, thBlockNo = BlockNo 2, thChainLength = ChainLength 3, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 7412945834010847025, thPrevHash = BlockHash (TestHeaderHash 2102088202601657634), thBodyHash = TestBodyHash (-7234408896617878314), thSlotNo = SlotNo 8, thBlockNo = BlockNo 3, thChainLength = ChainLength 4, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-8617166116099525105), thPrevHash = BlockHash (TestHeaderHash 7412945834010847025), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 11, thBlockNo = BlockNo 4, thChainLength = ChainLength 5, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash 5691200944682986263, thPrevHash = BlockHash (TestHeaderHash (-8617166116099525105)), thBodyHash = TestBodyHash (-7234408896601100693), thSlotNo = SlotNo 12, thBlockNo = BlockNo 5, thChainLength = ChainLength 6, thIsEBB = RegularBlock}},MeasuredWith {unMeasuredWith = TestHeader {thHash = TestHeaderHash (-5397328272732179662), thPrevHash = BlockHash (TestHeaderHash 5691200944682986263), thBodyHash = TestBodyHash (-7234408896584323076), thSlotNo = SlotNo 14, thBlockNo = BlockNo 6, thChainLength = ChainLength 7, thIsEBB = RegularBlock}}]}}))
          TraceCopyToImmutableDBEvent (CopiedBlockToImmutableDB (At (Block {blockPointSlot = SlotNo 1, blockPointHash = TestHeaderHash (-8556510898270155945)})))
          TraceCopyToImmutableDBEvent (CopiedBlockToImmutableDB (At (Block {blockPointSlot = SlotNo 3, blockPointHash = TestHeaderHash (-2888999216768647131)})))
          TraceCopyToImmutableDBEvent (CopiedBlockToImmutableDB (At (Block {blockPointSlot = SlotNo 5, blockPointHash = TestHeaderHash 2102088202601657634})))
          TraceCopyToImmutableDBEvent (CopiedBlockToImmutableDB (At (Block {blockPointSlot = SlotNo 8, blockPointHash = TestHeaderHash 7412945834010847025})))
          TraceCopyToImmutableDBEvent (CopiedBlockToImmutableDB (At (Block {blockPointSlot = SlotNo 11, blockPointHash = TestHeaderHash (-8617166116099525105)})))
          TraceGCEvent (PerformedGC (SlotNo 11))


          PostconditionFailed "AnnotateC \"real response didn't match model response\" (PredicateC (Resp {getResp = Right (IsValid (IsValidResult {real = True, isValid = Just True}))} :/= Resp {getResp = Right (IsValid (IsValidResult {real = False, isValid = Nothing}))}))" /= Ok
          Use --quickcheck-replay=999301 to reproduce.

The error can be reproduced running:

cabal new-run test-storage -- -p "ChainDB q-s-m" --quickcheck-replay 999301

Counterexample actions

- Block (-8556510898270155945) (s 1)  (b 0) (<-  GenesisHash        )
- Block (-2888999216768647131) (s 3)  (b 1) (<- -8556510898270155945)
- Block (2102088202601657634)  (s 5)  (b 2) (<- -2888999216768647131)
- Block (-8617166116099525105) (s 11) (b 4) (<-  7412945834010847025)
- Block (7412945834010847025)  (s 8)  (b 3) (<-  2102088202601657634)
- Block (-8276854694911826380) (s 10) (b 4) (<-  7412945834010847025)
- Block (455202168906668063)   (s 11) (b 5) (<- -8276854694911826380)
- Block (5691200944682986263)  (s 12) (b 5) (<- -8617166116099525105)
- Block (-5397328272732179662) (s 14) (b 6) (<-  5691200944682986263)

Adding these blocks would result in this chain:

What might be going wrong

The SUT considers the point that corresponds to block s 11, b 5 as valid,
whereas the model does not have information about its validity.

The model reports that it does not know about the validity of point that
corresponds to block:

  • Block (455202168906668063) (s 11) (b 5) (<- -8276854694911826380)

i.e., it returns Nothing. Why?

  • Valid points according to the model are those that can form valid chains
    that start from genesis with the blocks from the immutable DB and the
    volatile DB
    .
  • We garbage collect blocks smaller than slot 11 (we can see this in
    the logs, and infer this from the fact that the last seen slot when we
    call GC is 14 and k=2, so block s 11, b 4 is at the tip of the
    immutable DB).
  • When we garbage collect blocks smaller than slot 11, block s 10, b 4
    gets removed from the volatile DB because its slot number is smaller than
    slot number of the immutable tip
    .
  • As a result, we cannot construct a path from genesis to block s 11, b 5
    using blocks in the volatile DB and immutable DB because its predecessor
    was removed from the volatile DB.
  • Thus the model reports that the validity of the point that corresponds to
    block at s 11, b 5 is unknown (it returns Nothing).

The SUT considers the point as valid because block s 11, b 5 is still in
the volatile DB after garbage collection.

Based on this analysis, I'd conclude that the comment about
IsValidResult
is wrong: the model does not know about all valid blocks.

I do not know how we want to fix this. Edsko seems to prefer weakening the
equality instance of IsValidResult so that it returns True when either
the SUT or the model return Nothing.

I am worried that the SUT and model definitions of getIsValid do not
match. I'd argue that in this case both the model and the SUT know that the
point that corresponds to s 11, b 5 is valid.

Additional questions

  • Why did the tests not catch this before?
  • Why can't QC shrink the counterexample further?
@dnadales dnadales added bug Something isn't working consensus issues related to ouroboros-consensus testing labels Sep 23, 2021
@nfrisby
Copy link
Contributor

nfrisby commented Sep 28, 2021

Here are some initial thoughts.


For ease of reference, the ultimate error message is this:

PostconditionFailed
  "AnnotateC \"real response didn't match model response\" 
  (PredicateC 
    (    Resp {getResp = Right (IsValid (IsValidResult {real = True, isValid = Just True}))}
     :/= Resp {getResp = Right (IsValid (IsValidResult {real = False, isValid = Nothing}))})
  )" /= Ok

The SUT considers the point as valid because block s 11, b 5 is still in the volatile DB after garbage collection.

Here is where the SUT actually concludes Just True for the GetIsValid p command.

https://github.com/input-output-hk/ouroboros-network/blob/c82309f403e99d916a76bb4d96d6812fb0a9db81/ouroboros-consensus/src/Ouroboros/Consensus/Storage/ChainDB/Impl/Query.hs#L156-L170

Note that LgrDB.getPrevApplied is what causes Just True. Here is the comment:

https://github.com/input-output-hk/ouroboros-network/blob/90b3bdfb5a83e4b55288fff66e9d72035cd29cdb/ouroboros-consensus/src/Ouroboros/Consensus/Storage/ChainDB/Impl/LgrDB.hs#L102-L113

So -- as a bit of a surprise to me -- it seems that this part of the LedgerDB tracking which points are in the VolDB. (Edit: After writing the rest of this, I just think the above comment is a bit confusing.)

Here is where the LgrDB.getPrevApplied set is pruned; it is according to the GC rules as you described.

https://github.com/input-output-hk/ouroboros-network/blob/90b3bdfb5a83e4b55288fff66e9d72035cd29cdb/ouroboros-consensus/src/Ouroboros/Consensus/Storage/ChainDB/Impl/LgrDB.hs#L456-L460

It's the LgrDB.validate function that adds blocks to this set.

https://github.com/input-output-hk/ouroboros-network/blob/90b3bdfb5a83e4b55288fff66e9d72035cd29cdb/ouroboros-consensus/src/Ouroboros/Consensus/Storage/ChainDB/Impl/LgrDB.hs#L362-L381

And that function is called only after chain selection: https://github.com/input-output-hk/ouroboros-network/blob/c82309f403e99d916a76bb4d96d6812fb0a9db81/ouroboros-consensus/src/Ouroboros/Consensus/Storage/ChainDB/Impl/ChainSel.hs#L808

So: the key point is not just that s 11, b 5 is still in the VolDB, but rather that it's still in the VolDB and it had been on our current chain at some previous time.

So maybe we can avoid this error by enriching the model to remember which blocks that were earlier on the selected chain (and have not been GCed) and refine its getIsValid query accordingly?

Why did the tests not catch this before?

Is it because it requires generating GetIsValid p for an interesting p? Randomly choosing the right p might just be unlikely.

@dnadales
Copy link
Member Author

it's still in the VolDB and it had been on our current chain at some previous time.

I thought validateCandidate adds blocks to prev applied even if they don't end up being in the current chain.

    go (candidate:candidates0) =
      validateCandidate chainSelEnv candidate >>= \case

So as I understand it, a point is in varPrevApplied if it was previously validated, and a point is considered valid if it is in this set and does not exceed the maximum clock skew. If this is the case wouldn't have to keep track of the valid blocks in the model's immutable DB?

@dnadales
Copy link
Member Author

Is it because it requires generating GetIsValid p for an interesting p? Randomly choosing the right p might just be unlikely.

I would not expect this. "All" we need to generate is a chain that forks after the immutable tip, and ask for the validity of a point at a fork. It might be worthwhile checking what is the percentage of chains with forks are generated.

@dnadales
Copy link
Member Author

dnadales commented Oct 6, 2021

Proposed next steps.

Understand why this error was not caught before

A necessary condition for this error is that we have a command sequence that:

  1. produces a chain that forks
  2. ask for the validity of a point in the volatile DB

The first step would be to add labelling to understand if the probability of
generating a sequence of commands that satisfies 1 and 2 is low (since they are independent events we can simply multiply the probabilities QC.cover gives us).

If we find out that the probability of generating GetIsValid p commands for points p in the volatile DB is low, we should adapt the generators to
increase said probability. This adaptation would not be biasing the generators towards this bug because it seems sensible we would want to generate GetIsValid p forp in volatile DB in a large proportion of the cases (say more than 25% or 30%).

If the probabilities above do not explain why this bug was not caught earlier, we can analyze was is the probability of asking for the validity of a point that is in the volatile DB, and in a fork of the current chain.

Fix the model

(Edit by @nfrisby: See my earlier comment for a tour of the analogous logic that is happening in the SUT: #3389 (comment))

We should adjust the model so that it keeps track of previously applied blocks that are still in the volatile DB. Below is a diff that sketches how this could be done.

-blocks m = volatileDbBlocks m <> immutableDbBlocks m
+blocks m = volatileDbBlocks m <> immutableDbBlocks m <> garbageCollectedBlocks m

 getIsValid cfg m = \pt@(RealPoint _ hash) -> if
+    | pt `in` garbageCollectedBlocks ... ->  Nothing
     | Set.member pt validPoints   -> Just True

garbageCollect :: forall blk. HasHeader blk
                => SecurityParam -> Model blk -> Model blk
 garbageCollect secParam m@Model{..} = m {
-      volatileDbBlocks = Map.filter (not . collectable) volatileDbBlocks
+      volatileDbBlocks = notGCed
+      garbageCollectedBlocks = gcEd
     }
     -- TODO what about iterators that will stream garbage collected blocks?
   where
+    (notGCed, gcEd) = Map.partion (not . collectable) volatileDbBlocks

Removing "unreachable" blocks from the SUT's volatile DB is not an option, since this will make garbage collection slower (we'd need to compute the set of unreachable blocks instead of simply having to filter them based on slot numbers).

jasagredo added a commit that referenced this issue Mar 3, 2022
ChainDB QSM didn't have a notion of validity for blocks that were in
chain suffixes no longer connected to the Genesis block. It now carries
a Set of known-valid blocks to answer the `GetIsValid` query.

Closes CAD-4002
Closes CAD-3590
Closes CAD-3601
Closes #3389
Closes #3440
iohk-bors bot added a commit that referenced this issue Mar 14, 2022
3651: Fix: ChainDB QSM test flakyness r=Jasagredo a=Jasagredo

ChainDB QSM didn't have a notion of validity for blocks that were in
chain suffixes no longer connected to the Genesis block. It now carries
a Set of known-valid blocks to answer the `GetIsValid` query.

Closes CAD-4002
Closes CAD-3590
Closes CAD-3601
Closes #3389
Closes #3440

Co-authored-by: Javier Sagredo <javier.sagredo@iohk.io>
iohk-bors bot added a commit that referenced this issue Mar 14, 2022
3651: Fix: ChainDB QSM test flakyness r=Jasagredo a=Jasagredo

ChainDB QSM didn't have a notion of validity for blocks that were in
chain suffixes no longer connected to the Genesis block. It now carries
a Set of known-valid blocks to answer the `GetIsValid` query.

Closes CAD-4002
Closes CAD-3590
Closes CAD-3601
Closes #3389
Closes #3440

Co-authored-by: Javier Sagredo <javier.sagredo@iohk.io>
iohk-bors bot added a commit that referenced this issue Mar 15, 2022
3651: Fix: ChainDB QSM test flakyness r=Jasagredo a=Jasagredo

ChainDB QSM didn't have a notion of validity for blocks that were in
chain suffixes no longer connected to the Genesis block. It now carries
a Set of known-valid blocks to answer the `GetIsValid` query.

Closes CAD-4002
Closes CAD-3590
Closes CAD-3601
Closes #3389
Closes #3440

Co-authored-by: Javier Sagredo <javier.sagredo@iohk.io>
iohk-bors bot added a commit that referenced this issue Mar 16, 2022
3651: Fix: ChainDB QSM test flakyness r=Jasagredo a=Jasagredo

ChainDB QSM didn't have a notion of validity for blocks that were in
chain suffixes no longer connected to the Genesis block. It now carries
a Set of known-valid blocks to answer the `GetIsValid` query.

Closes CAD-4002
Closes CAD-3590
Closes CAD-3601
Closes #3389
Closes #3440

Co-authored-by: Javier Sagredo <javier.sagredo@iohk.io>
iohk-bors bot added a commit that referenced this issue Mar 23, 2022
3651: Fix: ChainDB QSM test flakyness r=jbgi a=Jasagredo

ChainDB QSM didn't have a notion of validity for blocks that were in
chain suffixes no longer connected to the Genesis block. It now carries
a Set of known-valid blocks to answer the `GetIsValid` query.

Closes CAD-4002
Closes CAD-3590
Closes CAD-3601
Closes #3389
Closes #3440

Co-authored-by: Javier Sagredo <javier.sagredo@iohk.io>
amesgen added a commit to IntersectMBO/ouroboros-consensus that referenced this issue Aug 15, 2023
Previously, the model might forget about disconnected blocks still in the
VolatileDB that it had validated previously, which is not something that can
happen with the SUT, resulting in a test failure. This can arise in specific
cases after garbage collection, see
IntersectMBO/ouroboros-network#3389 for a concrete
example.
amesgen added a commit to IntersectMBO/ouroboros-consensus that referenced this issue Aug 15, 2023
Previously, the model might forget about disconnected blocks still in the
VolatileDB that it had validated previously, which is not something that can
happen with the SUT, resulting in a test failure. This can arise in specific
cases after garbage collection, see
IntersectMBO/ouroboros-network#3389 for a concrete
example.

Co-authored-by: Joris Dral <joris@well-typed.com>
amesgen added a commit to IntersectMBO/ouroboros-consensus that referenced this issue Aug 16, 2023
Previously, the model might forget about disconnected blocks still in the
VolatileDB that it had validated previously, which is not something that can
happen with the SUT, resulting in a test failure. This can arise in specific
cases after garbage collection, see
IntersectMBO/ouroboros-network#3389 for a concrete
example.

Co-authored-by: Joris Dral <joris@well-typed.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working consensus issues related to ouroboros-consensus testing
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants