|
| 1 | +module Ouroboros.Consensus.Node.GSM.PeerState |
| 2 | + ( GsmPeerState (..) |
| 3 | + , maybeChainSyncState |
| 4 | + , maybePerasCertDiffusionState |
| 5 | + , mkGsmPeerStates |
| 6 | + , gsmPeerIsIdle |
| 7 | + ) |
| 8 | +where |
| 9 | + |
| 10 | +import Cardano.Base.FeatureFlags (CardanoFeatureFlag (..)) |
| 11 | +import Data.Align (Semialign (..)) |
| 12 | +import Data.Map.Strict (Map) |
| 13 | +import Data.Set (Set) |
| 14 | +import Data.These (These (..)) |
| 15 | +import Ouroboros.Consensus.MiniProtocol.ChainSync.Client.State |
| 16 | + ( ChainSyncClientHandle (..) |
| 17 | + , ChainSyncClientHandleCollection (..) |
| 18 | + , ChainSyncState (..) |
| 19 | + ) |
| 20 | +import Ouroboros.Consensus.MiniProtocol.ObjectDiffusion.Inbound.State |
| 21 | + ( ObjectDiffusionInboundHandle (..) |
| 22 | + , ObjectDiffusionInboundHandleCollection (..) |
| 23 | + , ObjectDiffusionInboundState (..) |
| 24 | + ) |
| 25 | +import Ouroboros.Consensus.MiniProtocol.ObjectDiffusion.PerasCert (PerasCertDiffusionInboundState) |
| 26 | +import Ouroboros.Consensus.Util.IOLike (MonadSTM (..), readTVar) |
| 27 | +import Ouroboros.Network.NodeToNode.Version (NodeToNodeVersion (..), isPerasEnabled) |
| 28 | + |
| 29 | +-- | State about peers we are connected to during initialization. |
| 30 | +newtype GsmPeerState blk = GsmPeerState |
| 31 | + { unGsmPeerState :: |
| 32 | + These |
| 33 | + (ChainSyncState blk) |
| 34 | + (PerasCertDiffusionInboundState blk) |
| 35 | + } |
| 36 | + |
| 37 | +-- | Retrieve the 'ChainSync' state of this peer, if such a connection is established. |
| 38 | +maybeChainSyncState :: GsmPeerState blk -> Maybe (ChainSyncState blk) |
| 39 | +maybeChainSyncState (GsmPeerState these) = |
| 40 | + case these of |
| 41 | + This csState -> Just csState |
| 42 | + That _ -> Nothing |
| 43 | + These csState _ -> Just csState |
| 44 | + |
| 45 | +-- | Retrieve the 'PerasCertDiffusion' state of this peer, if such a connection is established. |
| 46 | +maybePerasCertDiffusionState :: GsmPeerState blk -> Maybe (PerasCertDiffusionInboundState blk) |
| 47 | +maybePerasCertDiffusionState (GsmPeerState these) = |
| 48 | + case these of |
| 49 | + This _ -> Nothing |
| 50 | + That pcdState -> Just pcdState |
| 51 | + These _ pcdState -> Just pcdState |
| 52 | + |
| 53 | +-- | Construct a 'GsmPeerState' for all peers we are connected to. |
| 54 | +mkGsmPeerStates :: |
| 55 | + (Ord peer, MonadSTM m) => |
| 56 | + ChainSyncClientHandleCollection peer m blk -> |
| 57 | + ObjectDiffusionInboundHandleCollection peer m blk -> |
| 58 | + STM m (Map peer (GsmPeerState blk)) |
| 59 | +mkGsmPeerStates csHandles pcdHandles = do |
| 60 | + csPeerStates <- traverse (readTVar . cschState) =<< cschcMap csHandles |
| 61 | + pcdPeerStates <- traverse (readTVar . odihState) =<< odihcMap pcdHandles |
| 62 | + pure (GsmPeerState <$> align csPeerStates pcdPeerStates) |
| 63 | + |
| 64 | +-- | Determine whether our connections to this peer are idle. |
| 65 | +gsmPeerIsIdle :: Set CardanoFeatureFlag -> GsmPeerState blk -> Bool |
| 66 | +gsmPeerIsIdle featureFlags (GsmPeerState these) = |
| 67 | + case these of |
| 68 | + -- We have both ChainSync and PerasCertDiffusion connections => idle if both are idling |
| 69 | + These csState pcdState -> csIdling csState && odisIdling pcdState |
| 70 | + -- Only a ChainSync connection is available => idle if the ChainSync connection is idling |
| 71 | + This csState | not (perasIsEnabled csState) -> csIdling csState |
| 72 | + This csState | not (peerUsesPeras csState) -> csIdling csState |
| 73 | + -- We will soon establish a PerasCertDiffusion connection => not idling |
| 74 | + This _ -> False |
| 75 | + -- We will soon establish a ChainSync connection => not idling |
| 76 | + That _ -> False |
| 77 | + where |
| 78 | + -- Is the Peras feature flag enabled? |
| 79 | + perasIsEnabled csState = isPerasEnabled featureFlags (csNodeToNodeVersion csState) |
| 80 | + |
| 81 | + -- Does the peer support the Peras mini-protocol? |
| 82 | + peerUsesPeras csState = csNodeToNodeVersion csState >= NodeToNodeV_16 |
0 commit comments