Skip to content

Commit 096896d

Browse files
committed
ChainDB q-s-m: test the interaction of VolatileDB and snapshots
1 parent 057b798 commit 096896d

2 files changed

Lines changed: 90 additions & 1 deletion

File tree

ouroboros-consensus/test/storage-test/Test/Ouroboros/Storage/ChainDB/StateMachine.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ module Test.Ouroboros.Storage.ChainDB.StateMachine
6262
, close
6363
, mkTestCfg
6464
, open
65+
, reopen
6566
, persistBlks
6667
, run
6768

ouroboros-consensus/test/storage-test/Test/Ouroboros/Storage/ChainDB/Unit.hs

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ import Ouroboros.Consensus.Storage.Common
5252
import Ouroboros.Consensus.Storage.ImmutableDB.Chunks as ImmutableDB
5353
import Ouroboros.Consensus.Util.IOLike
5454
import qualified Ouroboros.Network.AnchoredFragment as AF
55-
import Ouroboros.Network.Block (ChainUpdate (..), Point, blockPoint)
55+
import Ouroboros.Network.Block (ChainUpdate (..), Point, blockPoint, genesisPoint)
5656
import qualified Ouroboros.Network.Mock.Chain as Mock
5757
import Test.Ouroboros.Storage.ChainDB.Model (Model)
5858
import qualified Test.Ouroboros.Storage.ChainDB.Model as Model
@@ -116,6 +116,15 @@ tests =
116116
"Empty slot, returns block at next filled slot"
117117
[testCase "system" $ runSystemIO waitForImmutableBlock_emptySlot]
118118
]
119+
, testGroup
120+
"Interaction of ImmutableDB, wiping the VolatileDB and ledger state snapshots"
121+
[ testGroup
122+
"Chain not long enough to take a snapshot, so blocks are not persisted into ImmutableDB and are lost."
123+
[testCase "system" $ runSystemIO updateLedgerSnapshots_WipeVolatileDB_withoutSnapshot]
124+
, testGroup
125+
"Chain is long enough to take a snapshot, blocks are copied into ImmutableDB."
126+
[testCase "system" $ runSystemIO updateLedgerSnapshots_WipeVolatileDB_withSnapshot]
127+
]
119128
]
120129

121130
followerInstructionOnEmptyChain :: (SupportsUnitTest m, MonadError TestFailure m) => m ()
@@ -329,6 +338,63 @@ waitForImmutableBlock_emptySlot = do
329338
where
330339
fork0 = TestBody 0 True Nothing
331340

341+
-- | Taking a ledger state snapshot should only copy blocks to the
342+
-- ImmutableDB when the snapshot policy selects slots for snapshotting. When the
343+
-- immutable chain is too short, no blocks should be flushed, and WipeVolatileDB
344+
-- should recover to the tip of the (empty) ImmutableDB.
345+
--
346+
-- See 'updateLedgerSnapshots_WipeVolatileDB_withSnapshot' for the scenario where
347+
-- the snapshot is taken.
348+
updateLedgerSnapshots_WipeVolatileDB_withoutSnapshot ::
349+
forall m.
350+
( Block m ~ TestBlock
351+
, SupportsUnitTest m
352+
, MonadError TestFailure m
353+
) =>
354+
m ()
355+
updateLedgerSnapshots_WipeVolatileDB_withoutSnapshot = do
356+
b1 <- addBlock $ firstBlock 1 $ fork0
357+
b2 <- addBlock $ mkNextBlock b1 3 $ fork0
358+
_b3 <- addBlock $ mkNextBlock b2 5 $ fork0
359+
360+
-- With k=2, 3 blocks are not enough to trigger a snapshot,
361+
updateLedgerSnapshots
362+
363+
tip <- wipeVolatileDB
364+
tip
365+
== genesisPoint
366+
`orFailWith` ("Expected ChainDB tip after wiping VolatileDB to be at Genesis, but got: " <> show tip)
367+
where
368+
fork0 = TestBody 1 True Nothing
369+
370+
-- | See 'updateLedgerSnapshots_WipeVolatileDB_withoutSnapshot' for details.
371+
updateLedgerSnapshots_WipeVolatileDB_withSnapshot ::
372+
forall m.
373+
( Block m ~ TestBlock
374+
, SupportsUnitTest m
375+
, MonadError TestFailure m
376+
) =>
377+
m ()
378+
updateLedgerSnapshots_WipeVolatileDB_withSnapshot = do
379+
b1 <- addBlock $ firstBlock 1 $ fork0
380+
b2 <- addBlock $ mkNextBlock b1 3 $ fork0
381+
b3 <- addBlock $ mkNextBlock b2 5 $ fork0
382+
b4 <- addBlock $ mkNextBlock b3 7 $ fork0
383+
_ <- addBlock $ mkNextBlock b4 9 $ fork0
384+
385+
updateLedgerSnapshots
386+
387+
tip <- wipeVolatileDB
388+
tip
389+
/= genesisPoint
390+
`orFailWith` ("Expected ChainDB non-Origin tip after wiping VolatileDB, got: " <> show tip)
391+
where
392+
fork0 = TestBody 1 True Nothing
393+
394+
{-------------------------------------------------------------------------------
395+
Helpers and testing infrastructure
396+
-------------------------------------------------------------------------------}
397+
332398
streamAssertSuccess ::
333399
(MonadError TestFailure m, SupportsUnitTest m, Mock.HasHeader (Block m)) =>
334400
StreamFrom (Block m) -> StreamTo (Block m) -> m (IteratorId m)
@@ -444,6 +510,10 @@ class SupportsUnitTest m where
444510
IteratorId m ->
445511
m (API.IteratorResult (Block m) (AllComponents (Block m)))
446512

513+
updateLedgerSnapshots :: m ()
514+
515+
wipeVolatileDB :: m (Point (Block m))
516+
447517
waitForImmutableBlock ::
448518
RealPoint (Block m) -> m (Either API.SeekBlockError (RealPoint (Block m)))
449519

@@ -522,6 +592,15 @@ instance
522592
persistBlksThenGC =
523593
void $ runModelCmd SM.PersistBlksThenGC
524594

595+
updateLedgerSnapshots =
596+
void $ runModelCmd SM.UpdateLedgerSnapshots
597+
598+
wipeVolatileDB = do
599+
result <- runModelCmd SM.WipeVolatileDB
600+
case result of
601+
SM.Point p -> pure p
602+
_ -> error $ "wipeVolatileDB: unexpected result" <> show result
603+
525604
stream from to = do
526605
result <- runModelCmd (SM.Stream from to)
527606
case result of
@@ -656,6 +735,15 @@ instance (IOLike m, TestConstraints blk) => SupportsUnitTest (SystemM blk m) whe
656735
persistBlksThenGC =
657736
void $ runCmd SM.PersistBlksThenGC
658737

738+
updateLedgerSnapshots = do
739+
void $ runCmd SM.UpdateLedgerSnapshots
740+
741+
wipeVolatileDB = do
742+
result <- runCmd SM.WipeVolatileDB
743+
case result of
744+
SM.Point p -> pure p
745+
_ -> error $ "wipeVolatileDB: unexpected result"
746+
659747
newFollower = do
660748
result <- runCmd (SM.NewFollower API.SelectedChain)
661749
case result of

0 commit comments

Comments
 (0)