Skip to content

Commit 6308a39

Browse files
authored
[Peras 2] Introduce PerasCertDB and related tests (#1674)
This pull request introduces the `PerasCertDB` datatype, used to hold and access all `PerasCert`s known by a node that could affect chain selection. In the mid/near-term future, this will be enriched to persist certificates across restarts, and probably also to store historical certificates. --- ### **Peras types** - Added modules `Ouroboros.Consensus.Storage.PerasCertDB{,.API,.Impl}`, notably defining the types`PerasCertDB`, `PerasCertSnapshot` (read-only snapshot of certs contained in the DB), and `AddPerasCertResult`; alongside their respectives methods --- ### **Tests** - Added modules `Test.Ouroboros.Storage.PerasCertDB{,.StateMachine,.Model}` for q-s-m testing of the `PerasCertDB` datatype. The corresponding tests have been included in the test suite defined by `Test.Ouroboros.Storage` --- ### **Regression** As the [previous PR](#1673), all the components introduced by this PR are not used at the moment by the rest of the code, so no regression is expected.
2 parents 31a1bef + 3f2b421 commit 6308a39

File tree

9 files changed

+694
-0
lines changed

9 files changed

+694
-0
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<!--
2+
A new scriv changelog fragment.
3+
4+
Uncomment the section that is right (remove the HTML comment wrapper).
5+
For top level release notes, leave all the headers commented out.
6+
-->
7+
8+
<!--
9+
### Patch
10+
11+
- A bullet item for the Patch category.
12+
13+
-->
14+
<!--
15+
### Non-Breaking
16+
17+
- A bullet item for the Non-Breaking category.
18+
19+
-->
20+
21+
### Breaking
22+
23+
- Add modules `Ouroboros.Consensus.Storage.PerasCertDB{,.API,.Impl}`, notably defining the types`PerasCertDB`, `PerasCertSnapshot` (read-only snapshot of certs contained in the DB), and `AddPerasCertResult`; alongside their respective methods
24+
- Add modules `Test.Ouroboros.Storage.PerasCertDB{,.StateMachine,.Model}` for q-s-m testing of the `PerasCertDB` datatype. The corresponding tests are included in the test suite defined by `Test.Ouroboros.Storage`

ouroboros-consensus/ouroboros-consensus.cabal

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,9 @@ library
265265
Ouroboros.Consensus.Storage.LedgerDB.V2.InMemory
266266
Ouroboros.Consensus.Storage.LedgerDB.V2.LSM
267267
Ouroboros.Consensus.Storage.LedgerDB.V2.LedgerSeq
268+
Ouroboros.Consensus.Storage.PerasCertDB
269+
Ouroboros.Consensus.Storage.PerasCertDB.API
270+
Ouroboros.Consensus.Storage.PerasCertDB.Impl
268271
Ouroboros.Consensus.Storage.Serialisation
269272
Ouroboros.Consensus.Storage.VolatileDB
270273
Ouroboros.Consensus.Storage.VolatileDB.API
@@ -723,6 +726,9 @@ test-suite storage-test
723726
Test.Ouroboros.Storage.LedgerDB.V1.DbChangelog
724727
Test.Ouroboros.Storage.LedgerDB.V1.LMDB
725728
Test.Ouroboros.Storage.Orphans
729+
Test.Ouroboros.Storage.PerasCertDB
730+
Test.Ouroboros.Storage.PerasCertDB.Model
731+
Test.Ouroboros.Storage.PerasCertDB.StateMachine
726732
Test.Ouroboros.Storage.VolatileDB
727733
Test.Ouroboros.Storage.VolatileDB.Mock
728734
Test.Ouroboros.Storage.VolatileDB.Model
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Ouroboros.Consensus.Storage.PerasCertDB (module X) where
2+
3+
import Ouroboros.Consensus.Storage.PerasCertDB.API as X
4+
import Ouroboros.Consensus.Storage.PerasCertDB.Impl as X
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
{-# LANGUAGE DataKinds #-}
2+
{-# LANGUAGE DerivingVia #-}
3+
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
4+
{-# LANGUAGE ScopedTypeVariables #-}
5+
6+
module Ouroboros.Consensus.Storage.PerasCertDB.API
7+
( PerasCertDB (..)
8+
, AddPerasCertResult (..)
9+
10+
-- * 'PerasCertSnapshot'
11+
, PerasCertSnapshot (..)
12+
, PerasCertTicketNo
13+
, zeroPerasCertTicketNo
14+
) where
15+
16+
import Data.Map (Map)
17+
import Data.Word (Word64)
18+
import NoThunks.Class
19+
import Ouroboros.Consensus.Block
20+
import Ouroboros.Consensus.Peras.Weight
21+
import Ouroboros.Consensus.Util.IOLike
22+
import Ouroboros.Consensus.Util.STM (WithFingerprint (..))
23+
24+
data PerasCertDB m blk = PerasCertDB
25+
{ addCert :: ValidatedPerasCert blk -> m AddPerasCertResult
26+
-- ^ Add a Peras certificate to the database. The result indicates whether
27+
-- the certificate was actually added, or if it was already present.
28+
, getWeightSnapshot :: STM m (WithFingerprint (PerasWeightSnapshot blk))
29+
-- ^ Return the Peras weights in order compare the current selection against
30+
-- potential candidate chains, namely the weights for blocks not older than
31+
-- the current immutable tip. It might contain weights for even older blocks
32+
-- if they have not yet been garbage-collected.
33+
--
34+
-- The 'Fingerprint' is updated every time a new certificate is added, but it
35+
-- stays the same when certificates are garbage-collected.
36+
, getCertSnapshot :: STM m (PerasCertSnapshot blk)
37+
, garbageCollect :: SlotNo -> m ()
38+
-- ^ Garbage-collect state older than the given slot number.
39+
, closeDB :: m ()
40+
}
41+
deriving NoThunks via OnlyCheckWhnfNamed "PerasCertDB" (PerasCertDB m blk)
42+
43+
data AddPerasCertResult = AddedPerasCertToDB | PerasCertAlreadyInDB
44+
deriving stock (Show, Eq)
45+
46+
data PerasCertSnapshot blk = PerasCertSnapshot
47+
{ containsCert :: PerasRoundNo -> Bool
48+
-- ^ Do we have the certificate for this round?
49+
, getCertsAfter :: PerasCertTicketNo -> Map PerasCertTicketNo (ValidatedPerasCert blk)
50+
-- ^ Get certificates after the given ticket number (excluded).
51+
-- The result is a map of ticket numbers to validated certificates.
52+
}
53+
54+
-- | A sequence number, incremented every time we receive a new certificate.
55+
--
56+
-- Note that we will /usually/ receive certificates monotonically by round
57+
-- number, so round numbers could /almost/ fulfill the role of ticket numbers.
58+
-- However, in certain edge cases (while catching up, or during cooldowns), this
59+
-- might not be true, such as during syncing or during cooldown periods.
60+
-- Therefore, for robustness, we choose to maintain dedicated ticket numbers
61+
-- separately.
62+
newtype PerasCertTicketNo = PerasCertTicketNo Word64
63+
deriving stock Show
64+
deriving newtype (Eq, Ord, Enum, NoThunks)
65+
66+
zeroPerasCertTicketNo :: PerasCertTicketNo
67+
zeroPerasCertTicketNo = PerasCertTicketNo 0

0 commit comments

Comments
 (0)