Skip to content

Commit 481311e

Browse files
committed
Add cluster ID mismatch to connectivity messages
Signed-off-by: Sasha Bogicevic <[email protected]>
1 parent 9657e17 commit 481311e

File tree

11 files changed

+114
-9
lines changed

11 files changed

+114
-9
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"samples": [
3+
{
4+
"localClusterID": "",
5+
"remotePeerClusterID": "",
6+
"tag": "NetworkClusterIDMismatch"
7+
}
8+
],
9+
"seed": 1341180695
10+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"samples": [
3+
{
4+
"configuredParties": [
5+
{
6+
"vkey": "d05f801e08648c87a1182768655803d4261ae2545573cd3a58b837f1541691de"
7+
}
8+
],
9+
"localClusterID": "",
10+
"remotePeerClusterID": "",
11+
"tag": "NetworkClusterIDMismatch"
12+
}
13+
],
14+
"seed": 1702753294
15+
}

hydra-node/json-schemas/api.yaml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ channels:
8080
- $ref: "api.yaml#/components/messages/NetworkConnected"
8181
- $ref: "api.yaml#/components/messages/NetworkDisconnected"
8282
- $ref: "api.yaml#/components/messages/NetworkVersionMismatch"
83+
- $ref: "api.yaml#/components/messages/NetworkClusterIDMismatch"
8384
- $ref: "api.yaml#/components/messages/HeadIsInitializing"
8485
- $ref: "api.yaml#/components/messages/Committed"
8586
- $ref: "api.yaml#/components/messages/HeadIsOpen"
@@ -487,6 +488,13 @@ components:
487488
payload:
488489
$ref: "api.yaml#/components/schemas/NetworkVersionMismatch"
489490

491+
NetworkClusterIDMismatch:
492+
title: NetworkClusterIDMismatch
493+
description: |
494+
The configured peers do not match with other nodes on the network.
495+
payload:
496+
$ref: "api.yaml#/components/schemas/NetworkClusterIDMismatch"
497+
490498
HeadIsInitializing:
491499
title: HeadIsInitializing
492500
description: |
@@ -732,6 +740,7 @@ components:
732740
- $ref: "api.yaml#/components/schemas/NetworkConnected"
733741
- $ref: "api.yaml#/components/schemas/NetworkDisconnected"
734742
- $ref: "api.yaml#/components/schemas/NetworkVersionMismatch"
743+
- $ref: "api.yaml#/components/schemas/NetworkClusterIDMismatch"
735744
- $ref: "api.yaml#/components/schemas/PeerConnected"
736745
- $ref: "api.yaml#/components/schemas/PeerDisconnected"
737746
- $ref: "api.yaml#/components/schemas/HeadIsInitializing"
@@ -985,6 +994,29 @@ components:
985994
timestamp:
986995
$ref: "api.yaml#/components/schemas/UTCTime"
987996

997+
NetworkClusterIDMismatch:
998+
type: object
999+
required:
1000+
- tag
1001+
- seq
1002+
- timestamp
1003+
properties:
1004+
tag:
1005+
type: string
1006+
enum: ["NetworkClusterIDMismatch"]
1007+
localClusterID:
1008+
type: string
1009+
remotePeerClusterID:
1010+
type: string
1011+
configuredParties:
1012+
type: array
1013+
items:
1014+
$ref: "api.yaml#/components/schemas/Party"
1015+
seq:
1016+
$ref: "api.yaml#/components/schemas/SequenceNumber"
1017+
timestamp:
1018+
$ref: "api.yaml#/components/schemas/UTCTime"
1019+
9881020
HeadIsInitializing:
9891021
type: object
9901022
required:

hydra-node/src/Hydra/API/Server.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ mkTimedServerOutputFromStateEvent event =
249249
StateChanged.NetworkConnected -> Just NetworkConnected
250250
StateChanged.NetworkDisconnected -> Just NetworkDisconnected
251251
StateChanged.NetworkVersionMismatch{..} -> Just NetworkVersionMismatch{..}
252+
StateChanged.NetworkClusterIDMismatch{..} -> Just NetworkClusterIDMismatch{..}
252253
StateChanged.PeerConnected{..} -> Just PeerConnected{..}
253254
StateChanged.PeerDisconnected{..} -> Just PeerDisconnected{..}
254255
StateChanged.TransactionReceived{} -> Nothing

hydra-node/src/Hydra/API/ServerOutput.hs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ data ServerOutput tx
142142
{ ourVersion :: ProtocolVersion
143143
, theirVersion :: Maybe ProtocolVersion
144144
}
145+
| NetworkClusterIDMismatch
146+
{ localClusterID :: Text
147+
, remotePeerClusterID :: Text
148+
}
145149
| PeerConnected {peer :: Host}
146150
| PeerDisconnected {peer :: Host}
147151
| HeadIsInitializing {headId :: HeadId, parties :: [Party]}
@@ -273,6 +277,7 @@ prepareServerOutput config response =
273277
NetworkConnected -> encodedResponse
274278
NetworkDisconnected -> encodedResponse
275279
NetworkVersionMismatch{} -> encodedResponse
280+
NetworkClusterIDMismatch{} -> encodedResponse
276281
PeerConnected{} -> encodedResponse
277282
PeerDisconnected{} -> encodedResponse
278283
SnapshotSideLoaded{} -> encodedResponse

hydra-node/src/Hydra/HeadLogic.hs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,17 @@ import Hydra.Tx.OnChainId (OnChainId)
103103
import Hydra.Tx.Party (Party (vkey))
104104
import Hydra.Tx.Snapshot (ConfirmedSnapshot (..), Snapshot (..), SnapshotNumber, SnapshotVersion, getSnapshot)
105105

106-
onConnectionEvent :: Network.Connectivity -> Outcome tx
107-
onConnectionEvent = \case
106+
107+
onConnectionEvent :: [Party] -> Network.Connectivity -> Outcome tx
108+
onConnectionEvent configuredParties = \case
108109
Network.NetworkConnected ->
109110
newState NetworkConnected
110111
Network.NetworkDisconnected ->
111112
newState NetworkDisconnected
112113
Network.VersionMismatch{ourVersion, theirVersion} ->
113114
newState NetworkVersionMismatch{ourVersion, theirVersion}
115+
Network.ClusterIDMismatch{localClusterID, remotePeerClusterID} ->
116+
newState NetworkClusterIDMismatch{localClusterID, remotePeerClusterID, configuredParties}
114117
Network.PeerConnected{peer} ->
115118
newState PeerConnected{peer}
116119
Network.PeerDisconnected{peer} ->
@@ -1313,7 +1316,7 @@ update ::
13131316
Outcome tx
13141317
update env ledger st ev = case (st, ev) of
13151318
(_, NetworkInput _ (ConnectivityEvent conn)) ->
1316-
onConnectionEvent conn
1319+
onConnectionEvent env.otherParties conn
13171320
(Idle _, ClientInput Init) ->
13181321
onIdleClientInit env
13191322
(Idle _, ChainInput Observation{observedTx = OnInitTx{headId, headSeed, headParameters, participants}, newChainState}) ->
@@ -1426,6 +1429,7 @@ aggregate st = \case
14261429
NetworkConnected -> st
14271430
NetworkDisconnected -> st
14281431
NetworkVersionMismatch{} -> st
1432+
NetworkClusterIDMismatch{} -> st
14291433
PeerConnected{} -> st
14301434
PeerDisconnected{} -> st
14311435
HeadInitialized{parameters = parameters@HeadParameters{parties}, headId, headSeed, chainState} ->
@@ -1793,6 +1797,7 @@ aggregateChainStateHistory history = \case
17931797
NetworkConnected -> history
17941798
NetworkDisconnected -> history
17951799
NetworkVersionMismatch{} -> history
1800+
NetworkClusterIDMismatch{} -> history
17961801
PeerConnected{} -> history
17971802
PeerDisconnected{} -> history
17981803
HeadInitialized{chainState} -> pushNewState chainState history

hydra-node/src/Hydra/HeadLogic/Outcome.hs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ data StateChanged tx
6060
{ ourVersion :: ProtocolVersion
6161
, theirVersion :: Maybe ProtocolVersion
6262
}
63+
| NetworkClusterIDMismatch
64+
{ localClusterID :: Text
65+
, remotePeerClusterID :: Text
66+
, configuredParties :: [Party]
67+
}
6368
| HeadInitialized
6469
{ parameters :: HeadParameters
6570
, chainState :: ChainStateType tx

hydra-node/src/Hydra/Network.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ data Connectivity
185185
{ ourVersion :: ProtocolVersion
186186
, theirVersion :: Maybe ProtocolVersion
187187
}
188+
| ClusterIDMismatch
189+
{ localClusterID :: Text
190+
, remotePeerClusterID :: Text
191+
}
188192
deriving stock (Generic, Eq, Show)
189193
deriving anyclass (ToJSON)
190194

hydra-node/src/Hydra/Network/Etcd.hs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,10 @@ import Control.Concurrent.Class.MonadSTM (
5656
writeTVar,
5757
)
5858
import Control.Exception (IOException)
59-
import Control.Lens ((^.), (^..))
59+
import Control.Lens ((^.), (^..), (^?))
6060
import Data.Aeson (decodeFileStrict', encodeFile)
6161
import Data.Aeson qualified as Aeson
62+
import Data.Aeson.Lens qualified as Aeson
6263
import Data.Aeson.Types (Value)
6364
import Data.Bits ((.|.))
6465
import Data.ByteString qualified as BS
@@ -138,12 +139,12 @@ withEtcdNetwork tracer protocolVersion config callback action = do
138139
envVars <- Map.fromList <$> getEnvironment
139140
withProcessInterrupt (etcdCmd etcdBinPath envVars) $ \p -> do
140141
race_ (waitExitCode p >>= \ec -> fail $ "Sub-process etcd exited with: " <> show ec) $ do
141-
race_ (traceStderr p) $ do
142+
race_ (traceStderr p callback) $ do
142143
-- XXX: cleanup reconnecting through policy if other threads fail
143144
doneVar <- newTVarIO False
144145
-- NOTE: The connection to the server is set up asynchronously; the
145146
-- first rpc call will block until the connection has been established.
146-
withConnection (connParams doneVar) grpcServer $ \conn ->
147+
withConnection (connParams doneVar) grpcServer $ \conn -> do
147148
-- REVIEW: checkVersion blocks if used on main thread - why?
148149
withAsync (checkVersion tracer conn protocolVersion callback) $ \_ -> do
149150
race_ (pollConnectivity tracer conn advertise callback) $
@@ -188,12 +189,22 @@ withEtcdNetwork tracer protocolVersion config callback action = do
188189
-- be used by default still.
189190
clientPort = 2379 + port listen - 5001
190191

191-
traceStderr p =
192+
traceStderr p NetworkCallback{onConnectivity} =
192193
forever $ do
193194
bs <- BS.hGetLine (getStderr p)
194195
case Aeson.eitherDecodeStrict bs of
195196
Left err -> traceWith tracer FailedToDecodeLog{log = decodeUtf8 bs, reason = show err}
196-
Right v -> traceWith tracer $ EtcdLog{etcd = v}
197+
Right v -> do
198+
let expectedClusterMismatch = do
199+
level' <- bs ^? Aeson.key "level" . Aeson.nonNull
200+
msg' <- bs ^? Aeson.key "msg" . Aeson.nonNull
201+
localClusterId <- bs ^? Aeson.key "local-member-cluster-id" . Aeson.nonNull
202+
remoteClusterId <- bs ^? Aeson.key "remote-peer-cluster-id" . Aeson.nonNull
203+
pure (level', msg', localClusterId, remoteClusterId)
204+
case expectedClusterMismatch of
205+
Just (Aeson.String "error", Aeson.String "request sent was ignored due to cluster ID mismatch", Aeson.String localClusterID, Aeson.String remotePeerClusterID) ->
206+
onConnectivity ClusterIDMismatch{localClusterID, remotePeerClusterID}
207+
_ -> traceWith tracer $ EtcdLog{etcd = v}
197208

198209
-- XXX: Could use TLS to secure peer connections
199210
-- XXX: Could use discovery to simplify configuration

hydra-node/test/Hydra/HeadLogicSpec.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,7 @@ spec =
657657
PeerConnected{} -> True
658658
PeerDisconnected{} -> True
659659
NetworkVersionMismatch{} -> True
660+
NetworkClusterIDMismatch{} -> True
660661
NetworkConnected{} -> True
661662
NetworkDisconnected{} -> True
662663
_ -> False

0 commit comments

Comments
 (0)