Skip to content

Commit 73d18f3

Browse files
authored
Updated ouroboros-consensus-diffusion to ouroboros-network-0.16.0.0 (#1091)
Closes #974
2 parents 5d75864 + fda94ad commit 73d18f3

File tree

8 files changed

+73
-64
lines changed

8 files changed

+73
-64
lines changed

cabal.project

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ index-state:
1616
-- Bump this if you need newer packages from Hackage
1717
, hackage.haskell.org 2024-03-26T06:28:59Z
1818
-- Bump this if you need newer packages from CHaP
19-
, cardano-haskell-packages 2024-04-05T13:36:27Z
19+
, cardano-haskell-packages 2024-05-07T20:35:20Z
2020

2121
packages:
2222
ouroboros-consensus

docs/website/contents/for-developers/BootstrapPeersIER.md

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,32 +12,48 @@ The following state machine depicts the desired behavior of the node.
1212

1313
```mermaid
1414
graph
15-
OnlyBootstrap[OnlyBootstrap]
16-
CaughtUp[CaughtUp]
15+
subgraph OnlyBootstrap
16+
direction TB
17+
PreSyncing[PreSyncing]
18+
Syncing[Syncing]
19+
PreSyncing -- "Honest Availability Assumption\nis satisfied" --> Syncing
20+
Syncing -- "Honest Availability Assumption\nis no longer satisfied" --> PreSyncing
21+
end
1722
18-
OnlyBootstrap -- "no peers claim to have\nsubsequent headers,\nand its selection is ≥\nthe best header" --> CaughtUp
19-
CaughtUp -- "vol tip became older than X" --> OnlyBootstrap
23+
CaughtUp[CaughtUp]
24+
Syncing -- "no peers claim to have\nsubsequent headers,\nand its selection is ≥\nthe best header" --> CaughtUp
25+
CaughtUp -- "vol tip became older than X" ----> PreSyncing
2026
2127
StartUp[[Node start-up]]
2228
StartUp -- "node was most recently in CaughtUp\nand vol tip is younger than X" --> CaughtUp
23-
StartUp -- "otherwise" --> OnlyBootstrap
29+
StartUp -- "otherwise" --> PreSyncing
2430
```
2531

26-
- `OnlyBootstrap` state - All upstream peers must reside in a centralized set of trusted _bootstrap peers_.
32+
- `OnlyBootstrap` - All upstream peers must be trusted.
33+
34+
In the context of bootstrap peers, as all peers are trusted, the _Honest Availability Assumption_ is satisfied in the following cases:
35+
36+
- The node is configured to connect to bootstrap peers, and it has established a connection to a bootstrap peer.
37+
38+
- The node is not configured to connect to bootstrap peers. This is the case for eg block producers and hidden relays. They will only be connected to trusted local root peers (eg the relays for a block-producing node).
2739

2840
- `CaughtUp` state - The peers are chosen according to the P2P design, including the _ledger peers_ etc.
2941

3042
**Desideratum 2.**
3143
In particular, the transitions should happen promptly.
3244

33-
- `CaughtUp -> OnlyBootstrap` should be prompt in order to minimize the duration that the node is exposed to untrusted peers (aka non-bootstrap peers) while its stale volatile tip is making it vulnerable.
45+
- `CaughtUp -> PreSyncing` should be prompt in order to minimize the duration that the node is exposed to untrusted peers (aka non-bootstrap peers) while its stale volatile tip is making it vulnerable.
3446
Delays here would directly threaten the security of the node.
3547

36-
- `OnlyBootstrap -> CaughtUp` should be prompt so that the centralized, relatively-few bootstrap peers are relieved of load as soon as possible.
48+
- `Syncing -> CaughtUp` should be prompt so that the centralized, relatively-few bootstrap peers are relieved of load as soon as possible.
3749
Delays here would not directly threaten the security of the node.
3850
However, wasting the centralized resources would threaten the ability of nodes to join the net, ie the availability of the whole net.
3951
Determining the exact load constraints for the bootstrap peers is not yet finalized.
4052

53+
- `PreSyncing -> Syncing` should be prompt to allow the node to conclude that is is caught up as a follow-up.
54+
55+
- `Syncing -> PreSyncing` should be prompt to prevent the node from concluding that it is caught up while it is not actually connected to a bootstrap peers.
56+
4157
**Desideratum 3.**
4258
The node should not return to `OnlyBootstrap` every time it restarts/briefly loses network/etc.
4359
Such unnecessary connections would also put unnecessary load on the centralized, relatively-few bootstrap peers.
@@ -59,11 +75,11 @@ This is the point of the "Node start-up" pseudo state in the diagram above.
5975

6076
As the volatile tip age approaches X, the Consensus Layer could forewarn the Diffusion Layer, eg "it seems like the transition back to OnlyBootstrap will be necessary soon; please prepare", if that would be helpful.
6177

62-
- For similar reasons, the Diffusion Layer should also manage the disconections from all peers upon the `OnlyBootstrap -> CaughtUp` transition.
78+
- For similar reasons, the Diffusion Layer should also manage the disconections from all (bootstrap) peers upon the `OnlyBootstrap -> CaughtUp` transition.
6379

6480
## Anticipated Interface
6581

66-
See [IntersectMBO/ouroboros-network#4555](https://github.com/IntersectMBO/ouroboros-network/pull/4555) for the definition/implementation of this interface on the Network side.
82+
See [IntersectMBO/ouroboros-network#4555](https://github.com/IntersectMBO/ouroboros-network/pull/4555) and [IntersectMBO/ouroboros-network#4846](https://github.com/IntersectMBO/ouroboros-network/pull/4846) for the definition/implementation of this interface on the Network side.
6783

6884
- The Diffusion Layer should monitor a `TVar State` (maybe via a `STM State` action).
6985
The Consensus Layer will update that state promptly.
@@ -75,6 +91,12 @@ See [IntersectMBO/ouroboros-network#4555](https://github.com/IntersectMBO/ourobo
7591
Here, `YoungEnough` signals that the ledger state's distribution among stake relays is sufficiently close to that of the actual real world.
7692
For now, we conservatively return `YoungEnough` only when the node concludes it has fully caught-up, and `TooOld` otherwise.
7793

94+
- The Diffusion Layer will inform the Consensus Layer whether the Honest Availability Assumption is satisfied.
95+
```haskell
96+
data OutboundConnectionsState = TrustedStateWithExternalPeers | UntrustedState
97+
daUpdateOutboundConnectionsState :: OutboundConnectionsState -> STM m ()
98+
```
99+
78100
- Whenever necessary, the Diffusion Layer can ask the Consensus Layer for the ledger peer information, eg
79101
```haskell
80102
lpGetLedgerPeers :: STM m [(PoolStake, NonEmpty RelayAccessPoint)]

flake.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
### Non-Breaking
2+
3+
- Implemented the Honest Availability Assumption properly (both for
4+
Praos/"Genesis Lite" and Genesis) based on newly exposed state by the
5+
diffusion layer.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### Non-Breaking
2+
3+
- Upgraded to `ouroboros-network-0.16`

ouroboros-consensus-diffusion/ouroboros-consensus-diffusion.cabal

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,10 @@ library
8989
io-classes ^>=1.4.1,
9090
mtl,
9191
ouroboros-consensus ^>=0.17,
92-
ouroboros-network ^>=0.14,
93-
ouroboros-network-api ^>=0.7,
94-
ouroboros-network-framework ^>=0.12,
95-
ouroboros-network-protocols ^>=0.8,
92+
ouroboros-network ^>=0.16,
93+
ouroboros-network-api ^>=0.7.2,
94+
ouroboros-network-framework ^>=0.13,
95+
ouroboros-network-protocols ^>=0.8.1,
9696
random,
9797
safe-wild-cards ^>=1.0,
9898
serialise ^>=0.2,

ouroboros-consensus-diffusion/src/ouroboros-consensus-diffusion/Ouroboros/Consensus/Node.hs

Lines changed: 10 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ module Ouroboros.Consensus.Node (
2222
-- * Standard arguments
2323
, StdRunNodeArgs (..)
2424
, stdBfcSaltIO
25-
, stdChainSyncTimeout
2625
, stdGsmAntiThunderingHerdIO
2726
, stdKeepAliveRngIO
2827
, stdLowLevelRunNodeArgsIO
@@ -60,6 +59,7 @@ import qualified Codec.CBOR.Encoding as CBOR
6059
import Codec.Serialise (DeserialiseFailure)
6160
import qualified Control.Concurrent.Class.MonadSTM.Strict as StrictSTM
6261
import Control.DeepSeq (NFData)
62+
import Control.Monad (when)
6363
import Control.Monad.Class.MonadTime.SI (MonadTime)
6464
import Control.Monad.Class.MonadTimer.SI (MonadTimer)
6565
import Control.Tracer (Tracer, contramap, traceWith)
@@ -110,9 +110,9 @@ import Ouroboros.Consensus.Util.ResourceRegistry
110110
import Ouroboros.Consensus.Util.Time (secondsToNominalDiffTime)
111111
import Ouroboros.Network.BlockFetch (BlockFetchConfiguration (..))
112112
import qualified Ouroboros.Network.Diffusion as Diffusion
113+
import qualified Ouroboros.Network.Diffusion.Configuration as Diffusion
113114
import qualified Ouroboros.Network.Diffusion.NonP2P as NonP2P
114115
import qualified Ouroboros.Network.Diffusion.P2P as P2P
115-
import qualified Ouroboros.Network.Diffusion.Policies as Diffusion
116116
import Ouroboros.Network.Magic
117117
import Ouroboros.Network.NodeToClient (ConnectionId, LocalAddress,
118118
LocalSocket, NodeToClientVersionData (..), combineVersions,
@@ -129,15 +129,14 @@ import Ouroboros.Network.PeerSelection.PeerMetric (PeerMetrics,
129129
import Ouroboros.Network.PeerSelection.PeerSharing (PeerSharing)
130130
import Ouroboros.Network.PeerSelection.PeerSharing.Codec
131131
(decodeRemoteAddress, encodeRemoteAddress)
132-
import Ouroboros.Network.Protocol.Limits (shortWait)
133132
import Ouroboros.Network.RethrowPolicy
134133
import qualified SafeWildCards
135134
import System.Exit (ExitCode (..))
136135
import System.FilePath ((</>))
137136
import System.FS.API (SomeHasFS (..))
138137
import System.FS.API.Types
139138
import System.FS.IO (ioHasFS)
140-
import System.Random (StdGen, newStdGen, randomIO, randomRIO, split)
139+
import System.Random (StdGen, newStdGen, randomIO, split)
141140

142141
{-------------------------------------------------------------------------------
143142
The arguments to the Consensus Layer node functionality
@@ -626,7 +625,11 @@ runWith RunNodeArgs{..} encAddrNtN decAddrNtN LowLevelRunNodeArgs{..} =
626625
lpGetLatestSlot = getImmTipSlot kernel,
627626
lpGetLedgerPeers = fromMaybe [] <$> getPeersFromCurrentLedger kernel (const True),
628627
lpGetLedgerStateJudgement = getLedgerStateJudgement kernel
629-
}
628+
},
629+
Diffusion.daUpdateOutboundConnectionsState =
630+
let varOcs = getOutboundConnectionsState kernel in \newOcs -> do
631+
oldOcs <- readTVar varOcs
632+
when (newOcs /= oldOcs) $ writeTVar varOcs newOcs
630633
}
631634

632635
localRethrowPolicy :: RethrowPolicy
@@ -732,7 +735,7 @@ mkNodeKernelArgs
732735
, blockFetchSize = estimateBlockSize
733736
, mempoolCapacityOverride = NoMempoolCapacityBytesOverride
734737
, miniProtocolParameters = defaultMiniProtocolParameters
735-
, blockFetchConfiguration = defaultBlockFetchConfiguration
738+
, blockFetchConfiguration = Diffusion.defaultBlockFetchConfiguration bfcSalt
736739
, gsmArgs = GsmNodeKernelArgs {
737740
gsmAntiThunderingHerd
738741
, gsmDurationUntilTooOld
@@ -744,15 +747,6 @@ mkNodeKernelArgs
744747
, peerSharingRng = psRng
745748
, publicPeerSelectionStateVar
746749
}
747-
where
748-
defaultBlockFetchConfiguration :: BlockFetchConfiguration
749-
defaultBlockFetchConfiguration = BlockFetchConfiguration
750-
{ bfcMaxConcurrencyBulkSync = 1
751-
, bfcMaxConcurrencyDeadline = 1
752-
, bfcMaxRequestsInflight = fromIntegral $ blockFetchPipeliningMax defaultMiniProtocolParameters
753-
, bfcDecisionLoopInterval = 0.01 -- 10ms
754-
, bfcSalt
755-
}
756750

757751
-- | We allow the user running the node to customise the 'NodeKernelArgs'
758752
-- through 'llrnCustomiseNodeKernelArgs', but there are some limits to some
@@ -800,33 +794,6 @@ stdGsmAntiThunderingHerdIO = newStdGen
800794
stdKeepAliveRngIO :: IO StdGen
801795
stdKeepAliveRngIO = newStdGen
802796

803-
stdChainSyncTimeout :: IO NTN.ChainSyncTimeout
804-
stdChainSyncTimeout = do
805-
-- These values approximately correspond to false positive
806-
-- thresholds for streaks of empty slots with 99% probability,
807-
-- 99.9% probability up to 99.999% probability.
808-
-- t = T_s [log (1-Y) / log (1-f)]
809-
-- Y = [0.99, 0.999...]
810-
-- T_s = slot length of 1s.
811-
-- f = 0.05
812-
-- The timeout is randomly picked per bearer to avoid all bearers
813-
-- going down at the same time in case of a long streak of empty
814-
-- slots.
815-
-- To avoid global synchronosation the timeout is picked uniformly
816-
-- from the interval 135 - 269, corresponds to the a 99.9% to
817-
-- 99.9999% thresholds.
818-
-- TODO: The timeout should be drawn at random everytime chainsync
819-
-- enters the must reply state. A static per connection timeout
820-
-- leads to selection preassure for connections with a large
821-
-- timeout, see #4244.
822-
mustReplyTimeout <- Just <$> realToFrac <$> randomRIO (135,269 :: Double)
823-
return NTN.ChainSyncTimeout
824-
{ canAwaitTimeout = shortWait
825-
, intersectTimeout = shortWait
826-
, mustReplyTimeout
827-
, idleTimeout = Just 3673
828-
}
829-
830797
stdVersionDataNTN :: NetworkMagic
831798
-> DiffusionMode
832799
-> PeerSharing
@@ -887,7 +854,7 @@ stdLowLevelRunNodeArgsIO RunNodeArgs{ rnProtocolInfo
887854
llrnKeepAliveRng <- stdKeepAliveRngIO
888855
pure LowLevelRunNodeArgs
889856
{ llrnBfcSalt
890-
, llrnChainSyncTimeout = fromMaybe stdChainSyncTimeout srnChainSyncTimeout
857+
, llrnChainSyncTimeout = fromMaybe Diffusion.defaultChainSyncTimeout srnChainSyncTimeout
891858
, llrnChainSyncLoPBucketConfig = ChainSyncLoPBucketDisabled
892859
, llrnCustomiseHardForkBlockchainTimeArgs = id
893860
, llrnGsmAntiThunderingHerd

ouroboros-consensus-diffusion/src/ouroboros-consensus-diffusion/Ouroboros/Consensus/NodeKernel.hs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ import Ouroboros.Network.NodeToNode (ConnectionId,
9494
import Ouroboros.Network.PeerSelection.Bootstrap (UseBootstrapPeers)
9595
import Ouroboros.Network.PeerSelection.LedgerPeers.Type
9696
(LedgerStateJudgement (..))
97+
import Ouroboros.Network.PeerSelection.LocalRootPeers
98+
(OutboundConnectionsState (..))
9799
import Ouroboros.Network.PeerSharing (PeerSharingAPI,
98100
PeerSharingRegistry, newPeerSharingAPI,
99101
newPeerSharingRegistry, ps_POLICY_PEER_SHARE_MAX_PEERS,
@@ -149,6 +151,9 @@ data NodeKernel m addrNTN addrNTC blk = NodeKernel {
149151
, setBlockForging :: [BlockForging m blk] -> m ()
150152

151153
, getPeerSharingAPI :: PeerSharingAPI addrNTN StdGen m
154+
155+
, getOutboundConnectionsState
156+
:: StrictTVar m OutboundConnectionsState
152157
}
153158

154159
-- | Arguments required when initializing a node
@@ -204,6 +209,8 @@ initNodeKernel args@NodeKernelArgs { registry, cfg, tracers
204209
, varLedgerJudgement
205210
} = st
206211

212+
varOutboundConnectionsState <- newTVarIO UntrustedState
213+
207214
do let GsmNodeKernelArgs {..} = gsmArgs
208215
gsmTracerArgs =
209216
( castTip . either AF.anchorToTip tipFromHeader . AF.head . fst
@@ -239,9 +246,12 @@ initNodeKernel args@NodeKernelArgs { registry, cfg, tracers
239246
gsmMarkerFileView
240247
, GSM.writeGsmState = \x -> atomically $ do
241248
writeTVar varLedgerJudgement $ GSM.gsmStateToLedgerJudgement x
242-
, -- In the context of bootstrap peers, it is fine to always
243-
-- return 'True' as all peers are trusted during syncing.
244-
GSM.isHaaSatisfied = pure True
249+
, GSM.isHaaSatisfied = do
250+
readTVar varOutboundConnectionsState <&> \case
251+
-- See the upstream Haddocks for the exact conditions under
252+
-- which the diffusion layer is in this state.
253+
TrustedStateWithExternalPeers -> True
254+
UntrustedState -> False
245255
}
246256
judgment <- readTVarIO varLedgerJudgement
247257
void $ forkLinkedThread registry "NodeKernel.GSM" $ case judgment of
@@ -278,6 +288,8 @@ initNodeKernel args@NodeKernelArgs { registry, cfg, tracers
278288
, getTracers = tracers
279289
, setBlockForging = \a -> atomically . LazySTM.putTMVar blockForgingVar $! a
280290
, getPeerSharingAPI = peerSharingAPI
291+
, getOutboundConnectionsState
292+
= varOutboundConnectionsState
281293
}
282294
where
283295
blockForgingController :: InternalState m remotePeer localPeer blk

0 commit comments

Comments
 (0)