Skip to content

Use a directory name that is the hash of the clusterPeers for etcd state #1965

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
42 changes: 42 additions & 0 deletions hydra-cluster/src/Hydra/Cluster/Scenarios.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1096,6 +1096,48 @@ threeNodesNoErrorsOnOpen tracer tmpDir node@RunningNode{nodeSocket} hydraScripts
Right _headIsOpen ->
pure ()

-- | Hydra nodes ABC run on ABC cluster and connect to each other.
-- Hydra nodes BC shut down.
-- Hydra nodes BC run on BC cluster and connect to each other.
-- Hydra nodes BC shut down.
-- Hydra nodes BC run and connect ABC cluster again.
nodeCanSupportMultipleEtcdClusters :: Tracer IO EndToEndLog -> FilePath -> RunningNode -> [TxId] -> IO ()
nodeCanSupportMultipleEtcdClusters tracer workDir RunningNode{networkId, nodeSocket} hydraScriptsTxId = do
let contestationPeriod = UnsafeContestationPeriod 2
let depositDeadline = UnsafeDepositDeadline 50

aliceChainConfig <-
chainConfigFor Alice workDir nodeSocket hydraScriptsTxId [Bob, Carol] contestationPeriod depositDeadline
<&> setNetworkId networkId
bobChainConfig <-
chainConfigFor Bob workDir nodeSocket hydraScriptsTxId [Alice, Carol] contestationPeriod depositDeadline
<&> setNetworkId networkId
carolChainConfig <-
chainConfigFor Carol workDir nodeSocket hydraScriptsTxId [Alice, Bob] contestationPeriod depositDeadline
<&> setNetworkId networkId

let hydraTracer = contramap FromHydraNode tracer

withHydraNode hydraTracer aliceChainConfig workDir 1 aliceSk [bobVk, carolVk] [1, 2, 3] $ \n1 -> do
withHydraNode hydraTracer bobChainConfig workDir 2 bobSk [aliceVk, carolVk] [1, 2, 3] $ \n2 -> do
withHydraNode hydraTracer carolChainConfig workDir 3 carolSk [aliceVk, bobVk] [1, 2, 3] $ \n3 -> do
waitForNodesConnected hydraTracer 30 $ n1 :| [n2, n3]

bobChainConfig' <-
chainConfigFor Bob workDir nodeSocket hydraScriptsTxId [Carol] contestationPeriod depositDeadline
<&> setNetworkId networkId
carolChainConfig' <-
chainConfigFor Carol workDir nodeSocket hydraScriptsTxId [Bob] contestationPeriod depositDeadline
<&> setNetworkId networkId

withHydraNode hydraTracer bobChainConfig' workDir 2 bobSk [carolVk] [2, 3] $ \n2 -> do
withHydraNode hydraTracer carolChainConfig' workDir 3 carolSk [bobVk] [2, 3] $ \n3 -> do
waitForNodesConnected hydraTracer 30 $ n2 :| [n3]

withHydraNode hydraTracer bobChainConfig workDir 2 bobSk [aliceVk, carolVk] [1, 2, 3] $ \n2 -> do
withHydraNode hydraTracer carolChainConfig workDir 3 carolSk [aliceVk, bobVk] [1, 2, 3] $ \n3 -> do
waitForNodesConnected hydraTracer 30 $ n1 :| [n2, n3]

-- | Two hydra node setup where Alice is wrongly configured to use Carol's
-- cardano keys instead of Bob's which will prevent him to be notified the
-- `HeadIsInitializing` but he should still receive some notification.
Expand Down
8 changes: 8 additions & 0 deletions hydra-cluster/test/Test/EndToEndSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import Hydra.Cluster.Scenarios (
checkFanout,
headIsInitializingWith,
initWithWrongKeys,
nodeCanSupportMultipleEtcdClusters,
nodeReObservesOnChainTxs,
oneOfThreeNodesStopsForAWhile,
persistenceCanLoadWithEmptyCommit,
Expand Down Expand Up @@ -282,6 +283,13 @@ spec = around (showLogsOnFailure "EndToEndSpec") $ do
publishHydraScriptsAs node Faucet
>>= threeNodesNoErrorsOnOpen tracer tmpDir node

it "node can support multiple etcd clusters" $ \tracer ->
failAfter 60 $
withClusterTempDir $ \tmpDir -> do
withCardanoNodeDevnet (contramap FromCardanoNode tracer) tmpDir $ \node -> do
publishHydraScriptsAs node Faucet
>>= nodeCanSupportMultipleEtcdClusters tracer tmpDir node

it "inits a Head, processes a single Cardano transaction and closes it again" $ \tracer ->
failAfter 60 $
withClusterTempDir $ \tmpDir -> do
Expand Down
4 changes: 3 additions & 1 deletion hydra-node/src/Hydra/Network/Etcd.hs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ module Hydra.Network.Etcd where
import Hydra.Prelude

import Cardano.Binary (decodeFull', serialize')
import Cardano.Crypto.Hash (SHA256, hashToStringAsHex, hashWithSerialiser)
import Control.Concurrent.Class.MonadSTM (
modifyTVar',
newTBQueueIO,
Expand All @@ -61,6 +62,7 @@ import Data.Aeson qualified as Aeson
import Data.Aeson.Types (Value)
import Data.Bits ((.|.))
import Data.ByteString qualified as BS
import Data.ByteString.Char8 qualified as BS8
import Data.List ((\\))
import Data.List qualified as List
import Data.Map qualified as Map
Expand Down Expand Up @@ -205,7 +207,7 @@ withEtcdNetwork tracer protocolVersion config callback action = do
$ concat
[ -- NOTE: Must be used in clusterPeers
["--name", show advertise]
, ["--data-dir", persistenceDir </> "etcd"]
, ["--data-dir", persistenceDir </> "etcd" </> hashToStringAsHex (hashWithSerialiser @SHA256 toCBOR $ BS8.pack clusterPeers)]
, ["--listen-peer-urls", httpUrl listen]
, ["--initial-advertise-peer-urls", httpUrl advertise]
, ["--listen-client-urls", httpUrl clientHost]
Expand Down
2 changes: 1 addition & 1 deletion hydra-node/test/Hydra/NetworkSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ spec = do

it "emits connectivity events" $ \tracer -> do
withTempDir "test-etcd" $ \tmp -> do
failAfter 20 $ do
failAfter 30 $ do
PeerConfig3{aliceConfig, bobConfig, carolConfig} <- setup3Peers tmp
-- Record and assert connectivity events from alice's perspective
(recordReceived, _, waitConnectivity) <- newRecordingCallback
Expand Down