Skip to content

Commit

Permalink
Changes to Handshake
Browse files Browse the repository at this point in the history
- Add new NodeToNode version that includes PeerSharing from Handshake
- Add PeerSharing to RunNodeArgs and NodeToNodeVersionData
  - Tweak ArbitraryNodeToNodeVersions so to have a custom Eq instance
    that ignores the new PeerSharing field. This is because PeerSharing
    breaks versionData symmetry because we eep only the remote side
    information.
- Add versionData (agreedOptions) to ConnectionHandler
  - Propagate versionData type parameter where needed
- Change connectionDataFlow field function type signature
- Add versionData to PeerConnectionHandle
  - Propagate changes to all type aliases
- Fix CDDL tests
  • Loading branch information
bolt12 committed Feb 8, 2023
1 parent 6e2f46c commit d63fded
Show file tree
Hide file tree
Showing 20 changed files with 449 additions and 231 deletions.
18 changes: 15 additions & 3 deletions ouroboros-consensus-diffusion/src/Ouroboros/Consensus/Node.hs
Expand Up @@ -122,6 +122,7 @@ import Ouroboros.Consensus.Storage.LedgerDB (SnapshotInterval (..),
defaultDiskPolicy)
import Ouroboros.Consensus.Storage.VolatileDB
(BlockValidationPolicy (..))
import Ouroboros.Network.PeerSelection.PeerSharing.Type (PeerSharing)

{-------------------------------------------------------------------------------
The arguments to the Consensus Layer node functionality
Expand Down Expand Up @@ -172,6 +173,9 @@ data RunNodeArgs m addrNTN addrNTC blk (p2p :: Diffusion.P2P) = RunNodeArgs {

-- | Network P2P Mode switch
, rnEnableP2P :: NetworkP2PMode p2p

-- | Network PeerSharing miniprotocol willingness flag
, rnPeerSharing :: PeerSharing
}

-- | Arguments that usually only tests /directly/ specify.
Expand Down Expand Up @@ -693,10 +697,14 @@ stdChainSyncTimeout = do
ix <- randomRIO (0, length xs - 1)
return $ xs !! ix

stdVersionDataNTN :: NetworkMagic -> DiffusionMode -> NodeToNodeVersionData
stdVersionDataNTN networkMagic diffusionMode = NodeToNodeVersionData
stdVersionDataNTN :: NetworkMagic
-> DiffusionMode
-> PeerSharing
-> NodeToNodeVersionData
stdVersionDataNTN networkMagic diffusionMode peerSharing = NodeToNodeVersionData
{ networkMagic
, diffusionMode
, peerSharing
}

stdVersionDataNTC :: NetworkMagic -> NodeToClientVersionData
Expand Down Expand Up @@ -767,7 +775,10 @@ stdLowLevelRunNodeArgsIO ::
NodeToClientVersionData
blk
p2p)
stdLowLevelRunNodeArgsIO RunNodeArgs{ rnProtocolInfo, rnEnableP2P }
stdLowLevelRunNodeArgsIO RunNodeArgs{ rnProtocolInfo
, rnEnableP2P
, rnPeerSharing
}
StdRunNodeArgs{..} = do
llrnBfcSalt <- stdBfcSaltIO
llrnKeepAliveRng <- stdKeepAliveRngIO
Expand Down Expand Up @@ -800,6 +811,7 @@ stdLowLevelRunNodeArgsIO RunNodeArgs{ rnProtocolInfo, rnEnableP2P }
-- `InitiatorAndResponderDiffusionMode`.
DisabledP2PMode -> InitiatorOnlyDiffusionMode
)
rnPeerSharing
, llrnNodeToNodeVersions =
limitToLatestReleasedVersion
fst
Expand Down
72 changes: 62 additions & 10 deletions ouroboros-network-api/src/Ouroboros/Network/NodeToNode/Version.hs
Expand Up @@ -22,6 +22,8 @@ import Ouroboros.Network.CodecCBORTerm
import Ouroboros.Network.Handshake.Acceptable (Accept (..),
Acceptable (..))
import Ouroboros.Network.Magic
import Ouroboros.Network.PeerSelection.PeerSharing.Type
(PeerSharing (..))


-- | Enumeration of node to node protocol versions.
Expand All @@ -48,6 +50,10 @@ data NodeToNodeVersion
-- ^ Changes:
--
-- * Enable @CardanoNodeToNodeVersion7@, i.e., Conway
-- * Adds a new extra parameter to handshake: PeerSharing
-- This version is needed to support the new Peer Sharing miniprotocol
-- older versions that are negotiated will appear as not participating
-- in Peer Sharing to newer versions.
deriving (Eq, Ord, Enum, Bounded, Show, Typeable)

nodeToNodeVersionCodec :: CodecCBORTerm (Text, Maybe Int) NodeToNodeVersion
Expand Down Expand Up @@ -98,6 +104,7 @@ data DiffusionMode
data NodeToNodeVersionData = NodeToNodeVersionData
{ networkMagic :: !NetworkMagic
, diffusionMode :: !DiffusionMode
, peerSharing :: !PeerSharing
}
deriving (Show, Typeable, Eq)
-- 'Eq' instance is not provided, it is not what we need in version
Expand All @@ -106,12 +113,14 @@ data NodeToNodeVersionData = NodeToNodeVersionData
instance Acceptable NodeToNodeVersionData where
-- | Check that both side use the same 'networkMagic'. Choose smaller one
-- from both 'diffusionMode's, e.g. if one is running in 'InitiatorOnlyMode'
-- agree on it.
-- agree on it. Keep the remote's PeerSharing information PeerSharing
-- information.
acceptableVersion local remote
| networkMagic local == networkMagic remote
= Accept NodeToNodeVersionData
{ networkMagic = networkMagic local
, diffusionMode = diffusionMode local `min` diffusionMode remote
, peerSharing = peerSharing remote
}
| otherwise
= Refuse $ T.pack $ "version data mismatch: "
Expand All @@ -120,32 +129,75 @@ instance Acceptable NodeToNodeVersionData where


nodeToNodeCodecCBORTerm :: NodeToNodeVersion -> CodecCBORTerm Text NodeToNodeVersionData
nodeToNodeCodecCBORTerm _version
= let encodeTerm :: NodeToNodeVersionData -> CBOR.Term
encodeTerm NodeToNodeVersionData { networkMagic, diffusionMode }
= CBOR.TList
nodeToNodeCodecCBORTerm version
| version >= NodeToNodeV_11 =
let encodeTerm :: NodeToNodeVersionData -> CBOR.Term
encodeTerm NodeToNodeVersionData { networkMagic, diffusionMode, peerSharing }
= CBOR.TList $
[ CBOR.TInt (fromIntegral $ unNetworkMagic networkMagic)
, CBOR.TBool (case diffusionMode of
InitiatorOnlyDiffusionMode -> True
InitiatorAndResponderDiffusionMode -> False)
, CBOR.TInt (case peerSharing of
NoPeerSharing -> 0
PeerSharingPrivate -> 1
PeerSharingPublic -> 2)
]

decodeTerm :: CBOR.Term -> Either Text NodeToNodeVersionData
decodeTerm (CBOR.TList [CBOR.TInt x, CBOR.TBool diffusionMode])
decodeTerm :: NodeToNodeVersion -> CBOR.Term -> Either Text NodeToNodeVersionData
decodeTerm _ (CBOR.TList [CBOR.TInt x, CBOR.TBool diffusionMode, CBOR.TInt peerSharing])
| x >= 0
, x <= 0xffffffff
, peerSharing >= 0
, peerSharing <= 2
= Right
NodeToNodeVersionData {
networkMagic = NetworkMagic (fromIntegral x),
diffusionMode = if diffusionMode
then InitiatorOnlyDiffusionMode
else InitiatorAndResponderDiffusionMode,
peerSharing = case peerSharing of
0 -> NoPeerSharing
1 -> PeerSharingPrivate
2 -> PeerSharingPublic
_ -> error "decodeTerm: impossible happened!"
}
| x < 0 || x > 0xffffffff
= Left $ T.pack $ "networkMagic out of bound: " <> show x
| otherwise -- peerSharing < 0 || peerSharing > 2
= Left $ T.pack $ "peerSharing out of bound: " <> show peerSharing
decodeTerm _ t
= Left $ T.pack $ "unknown encoding: " ++ show t
in CodecCBORTerm {encodeTerm, decodeTerm = decodeTerm version }
| otherwise =
let encodeTerm :: NodeToNodeVersionData -> CBOR.Term
encodeTerm NodeToNodeVersionData { networkMagic, diffusionMode }
= CBOR.TList $
[ CBOR.TInt (fromIntegral $ unNetworkMagic networkMagic)
, CBOR.TBool (case diffusionMode of
InitiatorOnlyDiffusionMode -> True
InitiatorAndResponderDiffusionMode -> False)
]

decodeTerm :: NodeToNodeVersion -> CBOR.Term -> Either Text NodeToNodeVersionData
decodeTerm _ (CBOR.TList [CBOR.TInt x, CBOR.TBool diffusionMode])
| x >= 0
, x <= 0xffffffff
= Right
NodeToNodeVersionData {
networkMagic = NetworkMagic (fromIntegral x),
diffusionMode = if diffusionMode
then InitiatorOnlyDiffusionMode
else InitiatorAndResponderDiffusionMode
else InitiatorAndResponderDiffusionMode,
-- By default older versions do not participate in Peer
-- Sharing, since they do not support the new miniprotocol
peerSharing = NoPeerSharing
}
| otherwise
= Left $ T.pack $ "networkMagic out of bound: " <> show x
decodeTerm t
decodeTerm _ t
= Left $ T.pack $ "unknown encoding: " ++ show t
in CodecCBORTerm {encodeTerm, decodeTerm}
in CodecCBORTerm {encodeTerm, decodeTerm = decodeTerm version }


data ConnectionMode = UnidirectionalMode | DuplexMode
Expand Down
10 changes: 5 additions & 5 deletions ouroboros-network-framework/demo/connection-manager.hs
Expand Up @@ -192,7 +192,7 @@ withBidirectionalConnectionManager
-- ^ series of request possible to do with the bidirectional connection
-- manager towards some peer.
-> (MuxConnectionManager
InitiatorResponderMode socket peerAddr
InitiatorResponderMode socket peerAddr UnversionedProtocolData
UnversionedProtocol ByteString m () ()
-> peerAddr
-> m a)
Expand Down Expand Up @@ -234,7 +234,7 @@ withBidirectionalConnectionManager snocket makeBearer socket
cmConfigureSocket = \_ _ -> return (),
cmTimeWaitTimeout = timeWaitTimeout,
cmOutboundIdleTimeout = protocolIdleTimeout,
connectionDataFlow = const Duplex,
connectionDataFlow = \_ _ -> Duplex,
cmPrunePolicy = simplePrunePolicy,
cmConnectionsLimits = AcceptedConnectionsLimit {
acceptedConnectionsHardLimit = maxBound,
Expand Down Expand Up @@ -458,7 +458,7 @@ bidirectionalExperiment
connHandle <-
connect 10 connectionManager
case connHandle of
Connected _ _ (Handle mux muxBundle _) -> do
Connected _ _ (Handle mux muxBundle _ _) -> do
traceWith debugTracer ( "initiator-loop"
, "connected"
)
Expand Down Expand Up @@ -512,11 +512,11 @@ bidirectionalExperiment
where
connect :: Int
-> MuxConnectionManager InitiatorResponderMode
socket peerAddr
socket peerAddr UnversionedProtocolData
UnversionedProtocol ByteString
IO () ()
-> IO (Connected peerAddr
(Handle InitiatorResponderMode peerAddr ByteString IO () ())
(Handle InitiatorResponderMode peerAddr UnversionedProtocolData ByteString IO () ())
(HandleError InitiatorResponderMode UnversionedProtocol))
connect n cm | n <= 1 =
requestOutboundConnection cm remoteAddr
Expand Down
Expand Up @@ -95,11 +95,12 @@ sduHandshakeTimeout = 10
-- * 'HandleError'
-- - the multiplexer thrown 'MuxError'.
--
data Handle (muxMode :: MuxMode) peerAddr bytes m a b =
data Handle (muxMode :: MuxMode) peerAddr versionData bytes m a b =
Handle {
hMux :: !(Mux muxMode m),
hMuxBundle :: !(MuxBundle muxMode bytes m a b),
hControlMessage :: !(TemperatureBundle (StrictTVar m ControlMessage))
hControlMessage :: !(TemperatureBundle (StrictTVar m ControlMessage)),
hVersionData :: !versionData
}


Expand Down Expand Up @@ -149,16 +150,16 @@ type MuxConnectionHandler muxMode socket peerAddr versionNumber versionData byte
(ConnectionHandlerTrace versionNumber versionData)
socket
peerAddr
(Handle muxMode peerAddr bytes m a b)
(Handle muxMode peerAddr versionData bytes m a b)
(HandleError muxMode versionNumber)
(versionNumber, versionData)
m

-- | Type alias for 'ConnectionManager' using 'Handle'.
--
type MuxConnectionManager muxMode socket peerAddr versionNumber bytes m a b =
type MuxConnectionManager muxMode socket peerAddr versionData versionNumber bytes m a b =
ConnectionManager muxMode socket peerAddr
(Handle muxMode peerAddr bytes m a b)
(Handle muxMode peerAddr versionData bytes m a b)
(HandleError muxMode versionNumber)
m

Expand Down Expand Up @@ -237,7 +238,7 @@ makeConnectionHandler muxTracer singMuxMode
=> ConnectionHandlerFn (ConnectionHandlerTrace versionNumber versionData)
socket
peerAddr
(Handle muxMode peerAddr ByteString m a b)
(Handle muxMode peerAddr versionData ByteString m a b)
(HandleError muxMode versionNumber)
(versionNumber, versionData)
m
Expand Down Expand Up @@ -291,7 +292,8 @@ makeConnectionHandler muxTracer singMuxMode
let !handle = Handle {
hMux = mux,
hMuxBundle = muxBundle,
hControlMessage = controlMessageBundle
hControlMessage = controlMessageBundle,
hVersionData = agreedOptions
}
atomically $ writePromise (Right (handle, (versionNumber, agreedOptions)))
bearer <- mkMuxBearer sduTimeout socket
Expand All @@ -304,7 +306,7 @@ makeConnectionHandler muxTracer singMuxMode
=> ConnectionHandlerFn (ConnectionHandlerTrace versionNumber versionData)
socket
peerAddr
(Handle muxMode peerAddr ByteString m a b)
(Handle muxMode peerAddr versionData ByteString m a b)
(HandleError muxMode versionNumber)
(versionNumber, versionData)
m
Expand Down Expand Up @@ -358,7 +360,8 @@ makeConnectionHandler muxTracer singMuxMode
let !handle = Handle {
hMux = mux,
hMuxBundle = muxBundle,
hControlMessage = controlMessageBundle
hControlMessage = controlMessageBundle,
hVersionData = agreedOptions
}
atomically $ writePromise (Right (handle, (versionNumber, agreedOptions)))
bearer <- mkMuxBearer sduTimeout socket
Expand Down

0 comments on commit d63fded

Please sign in to comment.