Skip to content

Commit 3e437fe

Browse files
amesgenagustinmista
authored andcommitted
Super basic scaffolding
1 parent de3deab commit 3e437fe

File tree

14 files changed

+143
-43
lines changed

14 files changed

+143
-43
lines changed

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Block/SupportsPeras.hs

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ module Ouroboros.Consensus.Block.SupportsPeras
1414
, boostPerCert
1515
, BlockSupportsPeras (..)
1616
, PerasCert (..)
17+
, ValidatedPerasCert (..)
18+
, makePerasCfg
1719
) where
1820

1921
import Data.Monoid (Sum (..))
@@ -45,24 +47,78 @@ instance Condense PerasWeight where
4547
boostPerCert :: PerasWeight
4648
boostPerCert = PerasWeight 15
4749

50+
-- TODO using 'Validated' for extra safety? Or some @.Unsafe@ module?
51+
data ValidatedPerasCert blk = ValidatedPerasCert
52+
{ validatedPerasCert :: !(PerasCert blk)
53+
, validatedPerasCertBoost :: !PerasWeight
54+
}
55+
deriving stock (Show, Eq, Ord, Generic)
56+
deriving anyclass NoThunks
57+
4858
class
49-
NoThunks (PerasCert blk) =>
59+
( Show (PerasCfg blk)
60+
, NoThunks (PerasCert blk)
61+
) =>
5062
BlockSupportsPeras blk
5163
where
64+
data PerasCfg blk
65+
5266
data PerasCert blk
5367

68+
data PerasValidationErr blk
69+
5470
perasCertRound :: PerasCert blk -> PerasRoundNo
5571

5672
perasCertBoostedBlock :: PerasCert blk -> Point blk
5773

74+
validatePerasCert ::
75+
PerasCfg blk ->
76+
-- | Current round number
77+
PerasRoundNo ->
78+
PerasCert blk ->
79+
Either (PerasValidationErr blk) (ValidatedPerasCert blk)
80+
5881
-- TODO degenerate instance for all blks to get things to compile
5982
instance StandardHash blk => BlockSupportsPeras blk where
83+
newtype PerasCfg blk = PerasCfg
84+
{ -- TODO eventually, this will come from the protocol parameters from the
85+
-- ledger state
86+
perasCfgWeightBoost :: PerasWeight
87+
}
88+
deriving stock (Show, Eq)
89+
6090
data PerasCert blk = PerasCert
6191
{ pcCertRound :: PerasRoundNo
6292
, pcCertBoostedBlock :: Point blk
6393
}
6494
deriving stock (Generic, Eq, Ord, Show)
6595
deriving anyclass NoThunks
6696

97+
data PerasValidationErr blk
98+
= PerasInFuture
99+
-- current round
100+
PerasRoundNo
101+
-- round of cert
102+
PerasRoundNo
103+
deriving stock (Show, Eq)
104+
67105
perasCertRound = pcCertRound
68106
perasCertBoostedBlock = pcCertBoostedBlock
107+
108+
validatePerasCert cfg curRound cert
109+
| pcCertRound cert > curRound =
110+
Left $ PerasInFuture curRound (pcCertRound cert)
111+
| otherwise =
112+
Right
113+
ValidatedPerasCert
114+
{ validatedPerasCert = cert
115+
, validatedPerasCertBoost = perasCfgWeightBoost cfg
116+
}
117+
118+
-- | Derive a 'PerasCfg' from a 'BlockConfig'
119+
-- TODO this currently doesn't depend on 'BlockConfig' at all, but likely will
120+
makePerasCfg :: Maybe (BlockConfig blk) -> PerasCfg blk
121+
makePerasCfg _ =
122+
PerasCfg
123+
{ perasCfgWeightBoost = boostPerCert
124+
}

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/MiniProtocol/ObjectDiffusion/ObjectPool/PerasCert.hs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module Ouroboros.Consensus.MiniProtocol.ObjectDiffusion.ObjectPool.PerasCert
88
, makePerasCertPoolWriterFromChainDB
99
) where
1010

11+
import GHC.Exception (throw)
1112
import Ouroboros.Consensus.Block
1213
import Ouroboros.Consensus.MiniProtocol.ObjectDiffusion.ObjectPool.API
1314
import Ouroboros.Consensus.Storage.ChainDB.API (ChainDB)
@@ -32,7 +33,10 @@ makePerasCertPoolReaderFromSnapshot getCertSnapshot =
3233
certSnapshot <- getCertSnapshot
3334
pure $
3435
take (fromIntegral limit) $
35-
[ (ticketNo, perasCertRound cert, pure cert)
36+
[ ( ticketNo
37+
, perasCertRound (validatedPerasCert cert)
38+
, pure (validatedPerasCert cert)
39+
)
3640
| (cert, ticketNo) <- PerasCertDB.getCertsAfter certSnapshot lastKnown
3741
]
3842
}
@@ -49,8 +53,9 @@ makePerasCertPoolWriterFromCertDB ::
4953
makePerasCertPoolWriterFromCertDB perasCertDB =
5054
ObjectPoolWriter
5155
{ opwObjectId = perasCertRound
52-
, opwAddObjects =
53-
mapM_ $ PerasCertDB.addCert perasCertDB
56+
, opwAddObjects = \certs -> do
57+
validatePerasCerts certs >>=
58+
mapM_ (PerasCertDB.addCert perasCertDB)
5459
, opwHasObject = do
5560
certSnapshot <- atomically $ PerasCertDB.getCertSnapshot perasCertDB
5661
pure $ PerasCertDB.containsCert certSnapshot
@@ -68,9 +73,24 @@ makePerasCertPoolWriterFromChainDB ::
6873
makePerasCertPoolWriterFromChainDB chainDB =
6974
ObjectPoolWriter
7075
{ opwObjectId = perasCertRound
71-
, opwAddObjects =
72-
mapM_ $ ChainDB.addPerasCertAsync chainDB
76+
, opwAddObjects = \certs -> do
77+
validatePerasCerts certs >>=
78+
mapM_ (ChainDB.addPerasCertAsync chainDB)
7379
, opwHasObject = do
7480
certSnapshot <- atomically $ ChainDB.getPerasCertSnapshot chainDB
7581
pure $ PerasCertDB.containsCert certSnapshot
7682
}
83+
84+
validatePerasCerts ::
85+
(StandardHash blk, Monad m) =>
86+
[PerasCert blk] ->
87+
m [ValidatedPerasCert blk]
88+
validatePerasCerts certs = do
89+
let perasCfg = makePerasCfg Nothing
90+
perasRoundNo = PerasRoundNo 999
91+
-- ^ TODO replace these mocked-up values with real
92+
-- ones when all the required plumbing is in place
93+
case sequence (validatePerasCert perasCfg perasRoundNo <$> certs) of
94+
Left validationError -> throw (userError (show validationError))
95+
-- TODO ^ refine this exception
96+
Right validatedCerts -> return validatedCerts

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Storage/ChainDB/API.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -392,8 +392,8 @@ data ChainDB m blk = ChainDB
392392
, getStatistics :: m (Maybe Statistics)
393393
-- ^ Get statistics from the LedgerDB, in particular the number of entries
394394
-- in the tables.
395-
, addPerasCertAsync :: PerasCert blk -> m (AddPerasCertPromise m)
396-
-- ^ TODO
395+
, addPerasCertAsync :: ValidatedPerasCert blk -> m (AddPerasCertPromise m)
396+
-- ^ TODO docs
397397
, getPerasWeightSnapshot :: STM m (WithFingerprint (PerasWeightSnapshot blk))
398398
-- ^ TODO
399399
, getPerasCertSnapshot :: STM m (PerasCertSnapshot blk)
@@ -530,7 +530,7 @@ newtype AddPerasCertPromise m = AddPerasCertPromise
530530
-- impossible).
531531
}
532532

533-
addPerasCertSync :: IOLike m => ChainDB m blk -> PerasCert blk -> m ()
533+
addPerasCertSync :: IOLike m => ChainDB m blk -> ValidatedPerasCert blk -> m ()
534534
addPerasCertSync chainDB cert =
535535
waitPerasCertProcessed =<< addPerasCertAsync chainDB cert
536536

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Storage/ChainDB/Impl/Background.hs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,9 @@ addBlockRunner fuse cdb@CDB{..} = forever $ do
647647
ChainSelAddPerasCert cert _varProcessed ->
648648
traceWith cdbTracer $
649649
TraceAddPerasCertEvent $
650-
PoppedPerasCertFromQueue (perasCertRound cert) (perasCertBoostedBlock cert)
650+
PoppedPerasCertFromQueue
651+
(perasCertRound (validatedPerasCert cert))
652+
(perasCertBoostedBlock (validatedPerasCert cert))
651653
chainSelSync cdb message
652654
lift $ atomically $ processedChainSelMessage cdbChainSelQueue message
653655
)

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Storage/ChainDB/Impl/ChainSel.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ addPerasCertAsync ::
331331
forall m blk.
332332
(IOLike m, HasHeader blk) =>
333333
ChainDbEnv m blk ->
334-
PerasCert blk ->
334+
ValidatedPerasCert blk ->
335335
m (AddPerasCertPromise m)
336336
addPerasCertAsync CDB{cdbTracer, cdbChainSelQueue} =
337337
addPerasCertToQueue (TraceAddPerasCertEvent >$< cdbTracer) cdbChainSelQueue
@@ -529,10 +529,10 @@ chainSelSync cdb@CDB{..} (ChainSelAddPerasCert cert varProcessed) = do
529529
tracer = TraceAddPerasCertEvent >$< cdbTracer
530530

531531
certRound :: PerasRoundNo
532-
certRound = perasCertRound cert
532+
certRound = perasCertRound (validatedPerasCert cert)
533533

534534
boostedBlock :: Point blk
535-
boostedBlock = perasCertBoostedBlock cert
535+
boostedBlock = perasCertBoostedBlock (validatedPerasCert cert)
536536

537537
-- | Return 'True' when the given header should be ignored when adding it
538538
-- because it is too old, i.e., we wouldn't be able to switch to a chain

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Storage/ChainDB/Impl/Types.hs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ data ChainSelMessage m blk
553553
ChainSelAddBlock !(BlockToAdd m blk)
554554
| -- | Add a Peras certificate
555555
ChainSelAddPerasCert
556-
!(PerasCert blk)
556+
!(ValidatedPerasCert blk)
557557
-- | Used for 'AddPerasCertPromise'.
558558
!(StrictTMVar m ())
559559
| -- | Reprocess blocks that have been postponed by the LoE.
@@ -609,7 +609,7 @@ addPerasCertToQueue ::
609609
(IOLike m, StandardHash blk) =>
610610
Tracer m (TraceAddPerasCertEvent blk) ->
611611
ChainSelQueue m blk ->
612-
PerasCert blk ->
612+
ValidatedPerasCert blk ->
613613
m (AddPerasCertPromise m)
614614
addPerasCertToQueue tracer ChainSelQueue{varChainSelQueue} cert = do
615615
varProcessed <- newEmptyTMVarIO
@@ -624,7 +624,9 @@ addPerasCertToQueue tracer ChainSelQueue{varChainSelQueue} cert = do
624624
}
625625
where
626626
addedToQueue =
627-
AddedPerasCertToQueue (perasCertRound cert) (perasCertBoostedBlock cert)
627+
AddedPerasCertToQueue
628+
(perasCertRound (validatedPerasCert cert))
629+
(perasCertBoostedBlock (validatedPerasCert cert))
628630

629631
-- | Try to add blocks again that were postponed due to the LoE.
630632
addReprocessLoEBlocks ::

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Storage/PerasCertDB/API.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ import Ouroboros.Consensus.Util.IOLike
2121
import Ouroboros.Consensus.Util.STM (WithFingerprint (..))
2222

2323
data PerasCertDB m blk = PerasCertDB
24-
{ addCert :: PerasCert blk -> m AddPerasCertResult
24+
{ addCert :: ValidatedPerasCert blk -> m AddPerasCertResult
25+
-- ^ TODO docs
2526
, getWeightSnapshot :: STM m (WithFingerprint (PerasWeightSnapshot blk))
2627
-- ^ Return the Peras weights in order compare the current selection against
2728
-- potential candidate chains, namely the weights for blocks not older than
@@ -44,7 +45,7 @@ data AddPerasCertResult = AddedPerasCertToDB | PerasCertAlreadyInDB
4445
data PerasCertSnapshot blk = PerasCertSnapshot
4546
{ containsCert :: PerasRoundNo -> Bool
4647
-- ^ Do we have the certificate for this round?
47-
, getCertsAfter :: PerasCertTicketNo -> [(PerasCert blk, PerasCertTicketNo)]
48+
, getCertsAfter :: PerasCertTicketNo -> [(ValidatedPerasCert blk, PerasCertTicketNo)]
4849
}
4950

5051
-- TODO: Once we store historical certificates on disk, this should (also) track

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Storage/PerasCertDB/Impl.hs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ implAddCert ::
144144
, StandardHash blk
145145
) =>
146146
PerasCertDbEnv m blk ->
147-
PerasCert blk ->
147+
ValidatedPerasCert blk ->
148148
m AddPerasCertResult
149149
implAddCert env cert = do
150150
traceWith pcdbTracer $ AddingPerasCert roundNo boostedPt
@@ -186,8 +186,8 @@ implAddCert env cert = do
186186
, pcdbVolatileState
187187
} = env
188188

189-
roundNo = perasCertRound cert
190-
boostedPt = perasCertBoostedBlock cert
189+
boostedPt = perasCertBoostedBlock (validatedPerasCert cert)
190+
roundNo = perasCertRound (validatedPerasCert cert)
191191

192192
implGetWeightSnapshot ::
193193
IOLike m =>
@@ -237,7 +237,7 @@ implGarbageCollect PerasCertDbEnv{pcdbVolatileState} slot =
237237
}
238238
where
239239
keepCert cert =
240-
pointSlot (perasCertBoostedBlock cert) >= NotOrigin slot
240+
pointSlot (perasCertBoostedBlock (validatedPerasCert cert)) >= NotOrigin slot
241241

242242
{-------------------------------------------------------------------------------
243243
Implementation-internal types
@@ -246,13 +246,13 @@ implGarbageCollect PerasCertDbEnv{pcdbVolatileState} slot =
246246
-- | Volatile Peras certificate state, i.e. certificates that could influence
247247
-- chain selection by boosting a volatile block.
248248
data PerasVolatileCertState blk = PerasVolatileCertState
249-
{ pvcsCerts :: !(Map PerasRoundNo (PerasCert blk))
249+
{ pvcsCerts :: !(Map PerasRoundNo (ValidatedPerasCert blk))
250250
-- ^ The boosted blocks by 'RoundNo' of all certificates currently in the db.
251251
, pvcsWeightByPoint :: !(PerasWeightSnapshot blk)
252252
-- ^ The weight of boosted blocks w.r.t. the certificates currently in the db.
253253
--
254254
-- INVARIANT: In sync with 'pvcsCerts'.
255-
, pvcsCertsByTicket :: !(Map PerasCertTicketNo (PerasCert blk))
255+
, pvcsCertsByTicket :: !(Map PerasCertTicketNo (ValidatedPerasCert blk))
256256
-- ^ The certificates by 'PerasCertTicketNo'.
257257
--
258258
-- INVARIANT: In sync with 'pvcsCerts'.

ouroboros-consensus/src/unstable-consensus-testlib/Test/Util/Orphans/ToExpr.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ deriving anyclass instance ToExpr PerasWeight
125125

126126
deriving anyclass instance ToExpr (HeaderHash blk) => ToExpr (PerasCert blk)
127127

128+
deriving anyclass instance ToExpr (HeaderHash blk) => ToExpr (ValidatedPerasCert blk)
129+
128130
{-------------------------------------------------------------------------------
129131
si-timers
130132
--------------------------------------------------------------------------------}

ouroboros-consensus/test/consensus-test/Test/Consensus/MiniProtocol/ObjectDiffusion/PerasCert/Smoke.hs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,16 @@ instance Arbitrary (Point blk) => Arbitrary (PerasCert blk) where
7070
pcCertBoostedBlock <- arbitrary
7171
pure $ PerasCert{pcCertRound, pcCertBoostedBlock}
7272

73-
instance WithId (PerasCert blk) PerasRoundNo where
74-
getId = pcCertRound
73+
instance Arbitrary (Point blk) => Arbitrary (ValidatedPerasCert blk) where
74+
arbitrary = do
75+
validatedPerasCert <- arbitrary
76+
validatedPerasCertBoost <- pure boostPerCert
77+
return $ ValidatedPerasCert{validatedPerasCert, validatedPerasCertBoost}
78+
79+
instance WithId (ValidatedPerasCert blk) PerasRoundNo where
80+
getId = pcCertRound . validatedPerasCert
7581

76-
newCertDB :: (IOLike m, StandardHash blk) => [PerasCert blk] -> m (PerasCertDB m blk)
82+
newCertDB :: (IOLike m, StandardHash blk) => [ValidatedPerasCert blk] -> m (PerasCertDB m blk)
7783
newCertDB certs = do
7884
db <- PerasCertDB.openDB (PerasCertDB.PerasCertDbArgs @Identity nullTracer)
7985
mapM_

0 commit comments

Comments
 (0)