Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
c7632eb
`LedgerDB.garbageCollect`: allow (non-STM) effectful cleanup
amesgen May 19, 2025
d2262cf
ChainDB: perform LedgerDB tasks in separate background thread
amesgen Jun 5, 2025
211941a
LedgerDB: introduce slot-based pruning
amesgen May 20, 2025
f4f8214
LedgerDB.V1: prune on garbage collection instead of on every change
amesgen May 19, 2025
56d18ce
LedgerDB.V1: adapt queries for `DbChangelog` of length >k
amesgen May 19, 2025
5810be8
LedgerDB.V2: prune on garbage collection instead of on every change
amesgen May 19, 2025
afeac4e
LedgerDB.V2: adapt queries for `DbChangelog` of length >k
amesgen May 19, 2025
86887dc
`LedgerDB.garbageCollect`: update documentation
amesgen May 20, 2025
f35767a
Remove `LedgerDbPruneKeeping`
amesgen Jul 2, 2025
8059f84
LedgerDB.StateMachine test: test invalid rollbacks
amesgen Jul 2, 2025
dec284f
Add changelogs
amesgen Jun 26, 2025
7977e6d
ChainSel: `olderThanK` -> `olderThanImmTip`
amesgen Jul 28, 2025
7b95734
ChainDB.Background: avoid hardcoding immutability criterion
amesgen Jul 28, 2025
c66b0aa
LedgerDB: abstract out immutability criterion
amesgen Aug 8, 2025
cfae3c7
ChainDB: define `LedgerDB.GetVolatileSuffix` via `getCurrentChain`
amesgen Aug 11, 2025
572b241
ChainSync.Client: remove overzealous assertion
amesgen Aug 11, 2025
2ce3053
Scaffolding for Peras certs and PerasCertDB
amesgen Jul 3, 2025
5246a54
[WIP] set structure for model-based testing for PerasCertDB
tbagrel1 Jul 7, 2025
aa94e92
Fix missing instances
tbagrel1 Jul 8, 2025
5fc441d
Pairing
amesgen Jul 8, 2025
b5cea47
Minor polishing
amesgen Jul 9, 2025
5a58067
PerasCertDB: implement garbage collection
amesgen Jul 9, 2025
45b3add
Mention ChainSync Client benchmark
geo2a Jul 7, 2025
046e0ff
ouroboros-consensus: add Peras chain weight benchmark
geo2a Jul 7, 2025
1380783
ChainDB: expose PerasCertDB functionality
amesgen Jul 17, 2025
5eca085
ChainDB: invoke PerasCertDB GC
amesgen Jul 17, 2025
f727c6c
Move `PerasWeightSnapshot` to separate module
amesgen Jul 17, 2025
9231e68
PerasCertDB.getWeightSnapshot: add `Fingerprint`
amesgen Jul 21, 2025
395381d
PerasCertDB.addCert: return whether we added the cert
amesgen Jul 21, 2025
04f48fb
Peras: minor tweaks
amesgen Jul 23, 2025
f919246
Make `PerasWeightSnapshot` opaque
amesgen Jul 24, 2025
bee6981
Nomenclature: "weight boost" instead of "boosted weight"
amesgen Jul 28, 2025
a5ad9ed
Glossary: add Peras weight-related terms
amesgen Jul 28, 2025
1cfcd95
PerasWeightSnapshot: minimize API
amesgen Jul 28, 2025
0a217b9
PerasRoundNo/PerasWeight: terse output
amesgen Jul 28, 2025
e975d0d
O.C.Peras.Weight: add haddocks
amesgen Jul 28, 2025
c1df482
`SecurityParam`: mention weighted nature
amesgen Jul 28, 2025
6b44e97
`PerasRoundNo`/`PerasWeight`: add `Condense` instances
amesgen Jul 29, 2025
6fd217e
O.C.Peras.Weight: add `totalWeightForFragment`/`takeVolatileSuffix`
amesgen Jul 28, 2025
dd53c36
Add test for `PerasWeightSnapshot`
amesgen Jul 29, 2025
3fbf549
ChainDB.StateMachine: check immutable tip monotonicity
amesgen Jul 30, 2025
2e865cd
ChainDB: define `getCurrentChain` in terms of weight
amesgen Jul 28, 2025
f8a0c06
GSM: allow `candidateOverSelection` to be stateful
amesgen Jul 17, 2025
25512c2
Add `WeightedSelectView`
amesgen Jul 28, 2025
f4f27b6
ChainSel: make `rollbackExceedsSuffix` weight-aware
amesgen Jul 23, 2025
f95a485
Introduce weighted chain comparisons
amesgen Jul 17, 2025
6c4caed
Integrate weighted BlockFetch decision logic
amesgen Jul 21, 2025
7b76810
ChainDB: implement chain selection for certificates
amesgen Jul 21, 2025
7df2c92
MockChainSel: switch to weighted chain selection
amesgen Jul 24, 2025
8a299a9
ChainDB q-s-m: test weighted chain selection
amesgen Jul 24, 2025
c971d39
Fix cabal-docspec
amesgen Aug 13, 2025
7cd459e
Modify PerasCertDB (and to some extent, ChainDB) to allow snapshot of…
amesgen Aug 6, 2025
d8ec0d7
Replace hardcoded miniprotocol parameters by default ones in unstable…
tbagrel1 Aug 6, 2025
c734c36
Introduce the (generic) ObjectDiffusion protocol, ObjectPool, and the…
tbagrel1 Aug 6, 2025
9279da4
Introduce the PerasCertDiffusion protocol (instance of ObjectDiffusio…
tbagrel1 Aug 6, 2025
de3deab
Wire-in the PerasCertDiffusion protocol in NodeToNode
tbagrel1 Aug 6, 2025
02044e1
Change signature of `opwHasObject` to use `STM m` instead of `m`
tbagrel1 Sep 2, 2025
cd32fac
Add module docstring to ObjectPool API
tbagrel1 Sep 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,17 @@ allow-newer:
, fin:QuickCheck
, bin:QuickCheck

source-repository-package
type: git
location: https://github.com/IntersectMBO/ouroboros-network
tag: c2e936f454a0026b9a854e5f230714de81b9965c
--sha256: sha256-139VtT1VJkBqIcqf+vak7h4Fh+Z748dHoHwaCCpKOy4=
subdir:
ouroboros-network
ouroboros-network-protocols
ouroboros-network-api
ouroboros-network

source-repository-package
type: git
location: https://github.com/IntersectMBO/cardano-ledger
Expand Down
23 changes: 22 additions & 1 deletion docs/website/contents/for-developers/Benchmarks.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
# Consensus benchmarks

We are in the process of adding component level microbenchmarks for Consensus.

We check for regressions in performance on CI.

## Mempool Benchmark

We started with microbenchmarks for adding transactions to the mempool. The
mempool benchmarks can be run using the following command.

```sh
cabal new-run ouroboros-consensus:mempool-bench
```

We check for regressions in performance on CI. We might publish benchmark results in this site shortly.
## ChainSync Client Benchmark

To aid the refactoring of the ChainSync client, we added a benchmark for it in [PR#823](https://github.com/IntersectMBO/ouroboros-consensus/pull/823). The benchmark could be invoked as follows:

```sh
cabal new-run ouroboros-consensus:ChainSync-client-bench -- 10 10
```

## PerasCertDB Benchmark

We have a microbenchmark for the boosted chain fragment weight calculation, which could be run as follows:

```sh
cabal run ouroboros-consensus:PerasCertDB-bench -- +RTS -T -A32m -RTS
```

We request GHC runtime system statistics with `-T` to get a memory usage estimate, and also request a large nursery with `-A32m` to minimise garbage collection. See `tasty-bench` [documentation](https://github.com/Bodigrim/tasty-bench?tab=readme-ov-file#troubleshooting) for more tips.
13 changes: 13 additions & 0 deletions docs/website/contents/for-developers/Glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,19 @@ These kinds are maintained by the Networking layer:
- [Public root peers](#public-root-peers).
- [Shared peers](#shared-peers).

## ;Peras ;weight ;boost

Peras is an extension of Praos enabling faster settlement under optimistic conditions.
To this end, Peras can result in a block `B` receiving a *boost*, which means that any chain containing `B` gets additional weight when being compared to other chains.

Consider a chain fragment `F`:

- Its ;*weight boost* is the sum of all boosts received by points on this fragment (excluding the anchor). Note that the same point can be boosted multiple times.

- Its ;*total weight* is its tip block number plus its weight boost.

Note that these notions are always relative to a particular anchor, so different chain fragments must have the same anchor when their total weight is to be compared.

## ;Phases

Byron, Shelley, Goguen (current one as of August 2023), Basho, Voltaire.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ openLedgerDB [email protected]{LedgerDB.lgrFlavorArgs = LedgerDB.L
lgrDbArgs
bss
(\_ -> error "no replay")
(LedgerDB.praosGetVolatileSuffix $ LedgerDB.ledgerDbCfgSecParam $ LedgerDB.lgrConfig lgrDbArgs)
)
emptyStream
genesisPoint
Expand All @@ -83,6 +84,7 @@ openLedgerDB [email protected]{LedgerDB.lgrFlavorArgs = LedgerDB.L
lgrDbArgs
args
(\_ -> error "no replay")
(LedgerDB.praosGetVolatileSuffix $ LedgerDB.ledgerDbCfgSecParam $ LedgerDB.lgrConfig lgrDbArgs)
)
emptyStream
genesisPoint
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ import Ouroboros.Consensus.MiniProtocol.ChainSync.Client
)
import qualified Ouroboros.Consensus.MiniProtocol.ChainSync.Client as CsClient
import Ouroboros.Consensus.MiniProtocol.ChainSync.Server
import Ouroboros.Consensus.MiniProtocol.ObjectDiffusion.Inbound (objectDiffusionInbound)
import Ouroboros.Consensus.MiniProtocol.ObjectDiffusion.ObjectPool.PerasCert
import Ouroboros.Consensus.MiniProtocol.ObjectDiffusion.Outbound (objectDiffusionOutbound)
import Ouroboros.Consensus.MiniProtocol.ObjectDiffusion.PerasCert
import Ouroboros.Consensus.Node.ExitPolicy
import Ouroboros.Consensus.Node.NetworkProtocolVersion
import Ouroboros.Consensus.Node.Run
Expand Down Expand Up @@ -197,6 +201,19 @@ data Handlers m addr blk = Handlers
NodeToNodeVersion ->
ConnectionId addr ->
TxSubmissionServerPipelined (GenTxId blk) (GenTx blk) m ()
, hPerasCertDiffusionInbound ::
NodeToNodeVersion ->
ConnectionId addr ->
PerasCertDiffusionInboundPipelined blk m ()
-- ^ TODO: We should pass 'hPerasCertDiffusionInbound' to the network
-- layer, as per https://github.com/tweag/cardano-peras/issues/78
, hPerasCertDiffusionOutbound ::
NodeToNodeVersion ->
ControlMessageSTM m ->
ConnectionId addr ->
PerasCertDiffusionOutbound blk m ()
-- ^ TODO: We should pass 'hPerasCertDiffusionOutbound' to the network
-- layer, as per https://github.com/tweag/cardano-peras/issues/78
, hKeepAliveClient ::
NodeToNodeVersion ->
ControlMessageSTM m ->
Expand Down Expand Up @@ -293,6 +310,22 @@ mkHandlers
(mapTxSubmissionMempoolReader txForgetValidated $ getMempoolReader getMempool)
(getMempoolWriter getMempool)
version
, hPerasCertDiffusionInbound = \version peer ->
objectDiffusionInbound
(contramap (TraceLabelPeer peer) (Node.perasCertDiffusionInboundTracer tracers))
( perasCertDiffusionMaxFifoLength miniProtocolParameters
, 10 -- TODO https://github.com/tweag/cardano-peras/issues/97
, 10 -- TODO https://github.com/tweag/cardano-peras/issues/97
)
(makePerasCertPoolWriterFromChainDB $ getChainDB)
version
, hPerasCertDiffusionOutbound = \version controlMessageSTM peer ->
objectDiffusionOutbound
(contramap (TraceLabelPeer peer) (Node.perasCertDiffusionOutboundTracer tracers))
(perasCertDiffusionMaxFifoLength miniProtocolParameters)
(makePerasCertPoolReaderFromChainDB $ getChainDB)
version
controlMessageSTM
, hKeepAliveClient = \_version -> keepAliveClient (Node.keepAliveClientTracer tracers) keepAliveRng
, hKeepAliveServer = \_version _peer -> keepAliveServer
, hPeerSharingClient = \_version controlMessageSTM _peer -> peerSharingClient controlMessageSTM
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,16 @@ data GsmView m upstreamPeer selection chainSyncState = GsmView
-- thundering herd phenomenon.
--
-- 'Nothing' should only be used for testing.
, candidateOverSelection ::
selection ->
chainSyncState ->
CandidateVersusSelection
, getCandidateOverSelection ::
STM
m
( selection ->
chainSyncState ->
CandidateVersusSelection
)
-- ^ Whether the candidate from the @chainSyncState@ is preferable to the
-- selection. This can depend on external state (Peras certificates boosting
-- blocks).
, peerIsIdle :: chainSyncState -> Bool
, durationUntilTooOld :: Maybe (selection -> m DurationFromNow)
-- ^ How long from now until the selection will be so old that the node
Expand Down Expand Up @@ -234,7 +240,7 @@ realGsmEntryPoints tracerArgs gsmView =

GsmView
{ antiThunderingHerd
, candidateOverSelection
, getCandidateOverSelection
, peerIsIdle
, durationUntilTooOld
, equivalent
Expand Down Expand Up @@ -383,6 +389,7 @@ realGsmEntryPoints tracerArgs gsmView =
-- long.
selection <- getCurrentSelection
candidates <- traverse StrictSTM.readTVar varsState
candidateOverSelection <- getCandidateOverSelection
let ok candidate =
WhetherCandidateIsBetter False
== candidateOverSelection selection candidate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import Ouroboros.Consensus.MiniProtocol.ChainSync.Server
import Ouroboros.Consensus.MiniProtocol.LocalTxSubmission.Server
( TraceLocalTxSubmissionServerEvent (..)
)
import Ouroboros.Consensus.MiniProtocol.ObjectDiffusion.PerasCert
import Ouroboros.Consensus.Node.GSM (TraceGsmEvent)
import Ouroboros.Network.Block (Tip)
import Ouroboros.Network.BlockFetch
Expand Down Expand Up @@ -87,6 +88,10 @@ data Tracers' remotePeer localPeer blk f = Tracers
, csjTracer ::
f (TraceLabelPeer remotePeer (CSJumping.TraceEventCsj remotePeer blk))
, dbfTracer :: f (CSJumping.TraceEventDbf remotePeer)
, perasCertDiffusionInboundTracer ::
f (TraceLabelPeer remotePeer (TracePerasCertDiffusionInbound blk))
, perasCertDiffusionOutboundTracer ::
f (TraceLabelPeer remotePeer (TracePerasCertDiffusionOutbound blk))
}

instance
Expand Down Expand Up @@ -115,6 +120,8 @@ instance
, gddTracer = f gddTracer
, csjTracer = f csjTracer
, dbfTracer = f dbfTracer
, perasCertDiffusionInboundTracer = f perasCertDiffusionInboundTracer
, perasCertDiffusionOutboundTracer = f perasCertDiffusionOutboundTracer
}
where
f ::
Expand Down Expand Up @@ -151,6 +158,8 @@ nullTracers =
, gddTracer = nullTracer
, csjTracer = nullTracer
, dbfTracer = nullTracer
, perasCertDiffusionInboundTracer = nullTracer
, perasCertDiffusionOutboundTracer = nullTracer
}

showTracers ::
Expand Down Expand Up @@ -189,6 +198,8 @@ showTracers tr =
, gddTracer = showTracing tr
, csjTracer = showTracing tr
, dbfTracer = showTracing tr
, perasCertDiffusionInboundTracer = showTracing tr
, perasCertDiffusionOutboundTracer = showTracing tr
}

{-------------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,15 +271,18 @@ initNodeKernel
gsmTracerArgs
GSM.GsmView
{ GSM.antiThunderingHerd = Just gsmAntiThunderingHerd
, GSM.candidateOverSelection = \(headers, _lst) state ->
case AF.intersectionPoint headers (csCandidate state) of
Nothing -> GSM.CandidateDoesNotIntersect
Just{} ->
GSM.WhetherCandidateIsBetter $ -- precondition requires intersection
preferAnchoredCandidate
(configBlock cfg)
headers
(csCandidate state)
, GSM.getCandidateOverSelection = do
weights <- ChainDB.getPerasWeightSnapshot chainDB
pure $ \(headers, _lst) state ->
case AF.intersectionPoint headers (csCandidate state) of
Nothing -> GSM.CandidateDoesNotIntersect
Just{} ->
GSM.WhetherCandidateIsBetter $ -- precondition requires intersection
preferAnchoredCandidate
(configBlock cfg)
(forgetFingerprint weights)
headers
(csCandidate state)
, GSM.peerIsIdle = csIdling
, GSM.durationUntilTooOld =
gsmDurationUntilTooOld
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ import Ouroboros.Network.NodeToNode
( ConnectionId (..)
, ExpandedInitiatorContext (..)
, IsBigLedgerPeer (..)
, MiniProtocolParameters (..)
, ResponderContext (..)
, defaultMiniProtocolParameters
)
import Ouroboros.Network.PeerSelection.Governor
( makePublicPeerSelectionStateVar
Expand Down Expand Up @@ -1056,13 +1056,7 @@ runThreadNetwork
, mempoolCapacityOverride = NoMempoolCapacityBytesOverride
, keepAliveRng = kaRng
, peerSharingRng = psRng
, miniProtocolParameters =
MiniProtocolParameters
{ chainSyncPipeliningHighMark = 4
, chainSyncPipeliningLowMark = 2
, blockFetchPipeliningMax = 10
, txSubmissionMaxUnacked = 1000 -- TODO ?
}
, miniProtocolParameters = defaultMiniProtocolParameters
, blockFetchConfiguration =
BlockFetchConfiguration
{ bfcMaxConcurrencyBulkSync = 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ setupGsm isHaaSatisfied vars = do
(id, tracer)
GSM.GsmView
{ GSM.antiThunderingHerd = Nothing
, GSM.candidateOverSelection = \s (PeerState c _) -> candidateOverSelection s c
, GSM.getCandidateOverSelection = pure $ \s (PeerState c _) ->
candidateOverSelection s c
, GSM.peerIsIdle = isIdling
, GSM.durationUntilTooOld = Just durationUntilTooOld
, GSM.equivalent = (==) -- unsound, but harmless in this test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import qualified Ouroboros.Consensus.Node.GSM as GSM
import Ouroboros.Consensus.Node.Genesis (setGetLoEFragment)
import Ouroboros.Consensus.Node.GsmState
import Ouroboros.Consensus.NodeId
import Ouroboros.Consensus.Peras.Weight (emptyPerasWeightSnapshot)
import qualified Ouroboros.Consensus.Storage.ChainDB as ChainDB
import Ouroboros.Consensus.Storage.ChainDB.API (ChainDB)
import qualified Ouroboros.Consensus.Storage.ChainDB.API.Types.InvalidBlockPunishment as Punishment
Expand Down Expand Up @@ -279,7 +280,7 @@ mkGsmEntryPoints varChainSyncHandles chainDB writeGsmState =
GSM.realGsmEntryPoints
(id, nullTracer)
GSM.GsmView
{ GSM.candidateOverSelection
{ GSM.getCandidateOverSelection = pure candidateOverSelection
, GSM.peerIsIdle = csIdling
, GSM.equivalent = (==) `on` AF.headPoint
, GSM.getChainSyncStates = fmap cschState <$> cschcMap varChainSyncHandles
Expand All @@ -301,10 +302,13 @@ mkGsmEntryPoints varChainSyncHandles chainDB writeGsmState =
Just{} ->
-- precondition requires intersection
GSM.WhetherCandidateIsBetter $
preferAnchoredCandidate (configBlock cfg) selection candFrag
preferAnchoredCandidate (configBlock cfg) weights selection candFrag
where
candFrag = csCandidate candidateState

-- TODO https://github.com/tweag/cardano-peras/issues/67
weights = emptyPerasWeightSnapshot

forkGDD ::
forall m.
IOLike m =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -418,8 +418,8 @@ traceChainDBEventTestBlockWith tracer = \case
trace $ "Switched to a fork; now: " ++ terseHFragment newFragment
StoreButDontChange point ->
trace $ "Did not select block due to LoE: " ++ terseRealPoint point
IgnoreBlockOlderThanK point ->
trace $ "Ignored block older than k: " ++ terseRealPoint point
IgnoreBlockOlderThanImmTip point ->
trace $ "Ignored block older than imm tip: " ++ terseRealPoint point
ChainSelectionLoEDebug curChain (LoEEnabled loeFrag0) -> do
trace $ "Current chain: " ++ terseHFragment curChain
trace $ "LoE fragment: " ++ terseHFragment loeFrag0
Expand Down
Loading