Skip to content

Commit

Permalink
Keep old constructor names for StateChanged and only add new ones
Browse files Browse the repository at this point in the history
Signed-off-by: Sasha Bogicevic <[email protected]>
  • Loading branch information
v0d1ch committed Feb 12, 2025
1 parent 45b60e9 commit 9a6f54a
Show file tree
Hide file tree
Showing 17 changed files with 6,625 additions and 4,042 deletions.
982 changes: 612 additions & 370 deletions hydra-node/golden/StateChanged/CommittedUTxO.json

Large diffs are not rendered by default.

2,006 changes: 1,207 additions & 799 deletions hydra-node/golden/StateChanged/HeadAborted.json

Large diffs are not rendered by default.

749 changes: 405 additions & 344 deletions hydra-node/golden/StateChanged/HeadClosed.json

Large diffs are not rendered by default.

698 changes: 25 additions & 673 deletions hydra-node/golden/StateChanged/HeadContested.json

Large diffs are not rendered by default.

891 changes: 800 additions & 91 deletions hydra-node/golden/StateChanged/HeadFannedOut.json

Large diffs are not rendered by default.

858 changes: 751 additions & 107 deletions hydra-node/golden/StateChanged/HeadInitialized.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions hydra-node/golden/StateChanged/HeadIsReadyToFanout.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"samples": [
{
"headId": "3791f3a9d167b2c119c61bb9fa8eb86b",
"tag": "HeadIsReadyToFanout"
}
],
Expand Down
1,258 changes: 1,122 additions & 136 deletions hydra-node/golden/StateChanged/HeadOpened.json

Large diffs are not rendered by default.

1,536 changes: 792 additions & 744 deletions hydra-node/golden/StateChanged/TransactionAppliedToLocalUTxO.json

Large diffs are not rendered by default.

1,393 changes: 766 additions & 627 deletions hydra-node/golden/StateEvent (Tx ConwayEra).json

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions hydra-node/src/Hydra/API/ServerOutput.hs
Original file line number Diff line number Diff line change
Expand Up @@ -311,27 +311,27 @@ projectSnapshotUtxo snapshotUtxo = \case
HeadIsOpen _ utxos -> Just utxos
_other -> snapshotUtxo

mapStateChangedToServerOutput :: StateChanged.StateChanged tx -> Maybe (ServerOutput tx)
mapStateChangedToServerOutput :: IsTx tx => StateChanged.StateChanged tx -> Maybe (ServerOutput tx)
mapStateChangedToServerOutput = \case
StateChanged.PeerConnected{peer} -> Just $ PeerConnected{peer}
StateChanged.PeerDisconnected{peer} -> Just $ PeerDisconnected{peer}
StateChanged.PeerHandshakeFailure{remoteHost, ourVersion, theirVersions} ->
Just $
PeerHandshakeFailure{remoteHost, ourVersion, theirVersions}
StateChanged.HeadIsInitializing{headId, parties} -> Just $ HeadIsInitializing{headId, parties}
StateChanged.Committed{headId, party, utxo} -> Just $ Committed{headId, party, utxo}
StateChanged.HeadIsOpen{headId, utxo} -> Just $ HeadIsOpen{headId, utxo}
StateChanged.HeadIsClosed{headId, snapshotNumber, contestationDeadline} ->
StateChanged.HeadInitialized{headId, parties} -> Just $ HeadIsInitializing{headId, parties}
StateChanged.CommittedUTxO{headId, party, committedUTxO} -> Just $ Committed{headId, party, utxo = committedUTxO}
StateChanged.HeadOpened{headId, utxo} -> Just $ HeadIsOpen{headId, utxo}
StateChanged.HeadClosed{headId, snapshotNumber, contestationDeadline} ->
Just $
HeadIsClosed{headId, snapshotNumber, contestationDeadline}
StateChanged.HeadIsContested{headId, snapshotNumber, contestationDeadline} ->
StateChanged.HeadContested{headId, snapshotNumber, contestationDeadline} ->
Just $
HeadIsContested{headId, snapshotNumber, contestationDeadline}
StateChanged.ReadyToFanout{headId} -> Just $ ReadyToFanout{headId}
StateChanged.HeadIsAborted{headId, utxo} -> Just $ HeadIsAborted{headId, utxo}
StateChanged.HeadIsFinalized{headId, utxo} -> Just $ HeadIsFinalized{headId, utxo}
StateChanged.HeadIsReadyToFanout{headId} -> Just $ ReadyToFanout{headId}
StateChanged.HeadAborted{headId, utxo} -> Just $ HeadIsAborted{headId, utxo}
StateChanged.HeadFannedOut{headId, utxo} -> Just $ HeadIsFinalized{headId, utxo}
StateChanged.CommandFailed{clientInput, state} -> Just $ CommandFailed{clientInput, state}
StateChanged.TxValid{headId, transactionId, transaction} -> Just $ TxValid{headId, transactionId, transaction}
StateChanged.TransactionAppliedToLocalUTxO{headId, tx} -> Just $ TxValid{headId, transactionId = txId tx, transaction = tx}
StateChanged.TxInvalid{headId, utxo, transaction, validationError} -> Just $ TxInvalid{headId, utxo, transaction, validationError}
StateChanged.SnapshotConfirmed{headId, snapshot, signatures} -> Just $ SnapshotConfirmed{headId, snapshot, signatures}
StateChanged.GetUTxOResponse{headId, utxo} -> Just $ GetUTxOResponse{headId, utxo}
Expand Down
114 changes: 56 additions & 58 deletions hydra-node/src/Hydra/HeadLogic.hs

Large diffs are not rendered by default.

137 changes: 66 additions & 71 deletions hydra-node/src/Hydra/HeadLogic/Outcome.hs
Original file line number Diff line number Diff line change
Expand Up @@ -69,127 +69,122 @@ instance Arbitrary HeadStatus where
arbitrary = genericArbitrary

-- | Head state changed event. These events represent all the internal state
-- changes that get persisted and processed in an event sourcing manner and
-- also displayed as outcomes at the API level.
-- changes, get persisted and processed in an event sourcing manner.
data StateChanged tx
= PeerConnected {peer :: NodeId}
| PeerDisconnected {peer :: NodeId}
| PeerHandshakeFailure
{ remoteHost :: Host
, ourVersion :: Natural
, theirVersions :: [Natural]
}
| HeadIsInitializing
{ headId :: HeadId
, parties :: [Party]
, parameters :: HeadParameters
= HeadInitialized
{ parameters :: HeadParameters
, chainState :: ChainStateType tx
, headId :: HeadId
, parties :: [Party]
, headSeed :: HeadSeed
}
| Committed
| CommittedUTxO
{ headId :: HeadId
, party :: Party
, utxo :: UTxOType tx
, committedUTxO :: UTxOType tx
, chainState :: ChainStateType tx
}
| HeadIsOpen {headId :: HeadId, utxo :: UTxOType tx, chainState :: ChainStateType tx}
| HeadIsAborted {headId :: HeadId, utxo :: UTxOType tx, chainState :: ChainStateType tx}
| HeadAborted {headId :: HeadId, utxo :: UTxOType tx, chainState :: ChainStateType tx}
| HeadOpened {headId :: HeadId, utxo :: UTxOType tx, chainState :: ChainStateType tx}
| TransactionReceived {tx :: tx}
| TxValid
| TransactionAppliedToLocalUTxO
{ headId :: HeadId
, transaction :: tx
, transactionId :: TxIdType tx
, newLocalUTxO :: UTxOType tx
}
| -- | Given transaction was not not applicable to the given UTxO in time and
-- has been dropped.
TxInvalid {headId :: HeadId, utxo :: UTxOType tx, transaction :: tx, validationError :: ValidationError}
| CommitRecorded {headId :: HeadId, utxoToCommit :: UTxOType tx, pendingDeposit :: TxIdType tx, pendingDeposits :: Map (TxIdType tx) (UTxOType tx), newLocalUTxO :: UTxOType tx, deadline :: UTCTime}
| -- | A snapshot was requested by some party.
-- NOTE: We deliberately already include an updated local ledger state to
-- not need a ledger to interpret this event.
SnapshotRequested
{ snapshot :: Snapshot tx
, requestedTxIds :: [TxIdType tx]
, tx :: tx
, newLocalUTxO :: UTxOType tx
, newLocalTxs :: [tx]
}
| TxInvalid {headId :: HeadId, utxo :: UTxOType tx, transaction :: tx, validationError :: ValidationError}
| CommitApproved {headId :: HeadId, utxoToCommit :: UTxOType tx}
| CommitIgnored {headId :: HeadId, depositUTxO :: [UTxOType tx], snapshotUTxO :: Maybe (UTxOType tx)}
| CommitRecorded {headId :: HeadId, utxoToCommit :: UTxOType tx, pendingDeposit :: TxIdType tx, deadline :: UTCTime, pendingDeposits :: Map (TxIdType tx) (UTxOType tx), newLocalUTxO :: UTxOType tx}
| CommitRecovered {headId :: HeadId, recoveredUTxO :: UTxOType tx, newLocalUTxO :: UTxOType tx, recoveredTxId :: TxIdType tx}
| CommitFinalized {headId :: HeadId, newVersion :: SnapshotVersion, depositTxId :: TxIdType tx}
| DecommitRecorded {decommitTx :: tx, newLocalUTxO :: UTxOType tx}
| DecommitRequested {headId :: HeadId, decommitTx :: tx, utxoToDecommit :: UTxOType tx}
| DecommitRecorded {decommitTx :: tx, newLocalUTxO :: UTxOType tx}
| DecommitInvalid {headId :: HeadId, decommitTx :: tx, decommitInvalidReason :: DecommitInvalidReason tx}
| DecommitApproved {headId :: HeadId, decommitTxId :: TxIdType tx, utxoToDecommit :: UTxOType tx}
| DecommitFinalized {headId :: HeadId, decommitTxId :: TxIdType tx, newVersion :: SnapshotVersion}
| SnapshotRequestDecided {snapshotNumber :: SnapshotNumber}
| -- | A snapshot was requested by some party.
-- NOTE: We deliberately already include an updated local ledger state to
-- not need a ledger to interpret this event.
SnapshotRequested
{ snapshot :: Snapshot tx
, requestedTxIds :: [TxIdType tx]
, newLocalUTxO :: UTxOType tx
, newLocalTxs :: [tx]
}
| PartySignedSnapshot {snapshot :: Snapshot tx, party :: Party, signature :: Signature (Snapshot tx)}
| SnapshotConfirmed {headId :: HeadId, snapshot :: Snapshot tx, signatures :: MultiSignature (Snapshot tx)}
| HeadIsClosed {headId :: HeadId, snapshotNumber :: SnapshotNumber, chainState :: ChainStateType tx, contestationDeadline :: UTCTime}
| HeadIsContested {headId :: HeadId, snapshotNumber :: SnapshotNumber, chainState :: ChainStateType tx, contestationDeadline :: UTCTime}
| ReadyToFanout {headId :: HeadId}
| HeadIsFinalized {headId :: HeadId, chainState :: ChainStateType tx, utxo :: UTxOType tx}
| -- | A friendly welcome message which tells a client something about the
-- node. Currently used for knowing what signing key the server uses (it
-- only knows one), 'HeadStatus' and optionally (if 'HeadIsOpen' or
-- 'SnapshotConfirmed' message is emitted) UTxO's present in the Hydra Head.
Greetings
{ me :: Party
, headStatus :: HeadStatus
, hydraHeadId :: Maybe HeadId
, snapshotUtxo :: Maybe (UTxOType tx)
, hydraNodeVersion :: String
| HeadClosed {headId :: HeadId, snapshotNumber :: SnapshotNumber, chainState :: ChainStateType tx, contestationDeadline :: UTCTime}
| HeadContested {headId :: HeadId, snapshotNumber :: SnapshotNumber, chainState :: ChainStateType tx, contestationDeadline :: UTCTime}
| HeadIsReadyToFanout {headId :: HeadId}
| HeadFannedOut {headId :: HeadId, utxo :: UTxOType tx, chainState :: ChainStateType tx}
| -- More constructors to match the mapping needed for the 'ServerOutput' type.
ChainRolledBack {chainState :: ChainStateType tx}
| TickObserved {chainSlot :: ChainSlot}
| PeerHandshakeFailure
{ remoteHost :: Host
, ourVersion :: Natural
, theirVersions :: [Natural]
}
| GetUTxOResponse {headId :: HeadId, utxo :: UTxOType tx}
| PostTxOnChainFailed {postChainTx :: PostChainTx tx, postTxError :: PostTxError tx}
| IgnoredHeadInitializing
{ headId :: HeadId
, contestationPeriod :: ContestationPeriod
, parties :: [Party]
, participants :: [OnChainId]
}
| InvalidInput {reason :: String, input :: Text}
| ChainRolledBack {chainState :: ChainStateType tx}
| TickObserved {chainSlot :: ChainSlot}
| PostTxOnChainFailed {postChainTx :: PostChainTx tx, postTxError :: PostTxError tx}
| PeerConnected {peer :: NodeId}
| PeerDisconnected {peer :: NodeId}
| CommandFailed {clientInput :: ClientInput tx, state :: HeadState tx}
| GetUTxOResponse {headId :: HeadId, utxo :: UTxOType tx}
| InvalidInput {reason :: String, input :: Text}
| Greetings
{ me :: Party
, headStatus :: HeadStatus
, hydraHeadId :: Maybe HeadId
, snapshotUtxo :: Maybe (UTxOType tx)
, hydraNodeVersion :: String
}
deriving stock (Generic)

deriving stock instance (IsTx tx, IsChainState tx, Eq (HeadState tx), Eq (ChainStateType tx)) => Eq (StateChanged tx)
deriving stock instance (IsTx tx, IsChainState tx, Show (HeadState tx), Show (ChainStateType tx)) => Show (StateChanged tx)
deriving anyclass instance (IsTx tx, IsChainState tx, ToJSON (ChainStateType tx)) => ToJSON (StateChanged tx)
deriving anyclass instance (IsTx tx, IsChainState tx, FromJSON (HeadState tx), FromJSON (ChainStateType tx)) => FromJSON (StateChanged tx)
deriving stock instance (IsChainState tx, Eq (HeadState tx), Eq (ChainStateType tx)) => Eq (StateChanged tx)
deriving stock instance (IsChainState tx, Show (HeadState tx), Show (ChainStateType tx)) => Show (StateChanged tx)
deriving anyclass instance (IsChainState tx, ToJSON (ChainStateType tx)) => ToJSON (StateChanged tx)
deriving anyclass instance (IsChainState tx, FromJSON (HeadState tx), FromJSON (ChainStateType tx)) => FromJSON (StateChanged tx)

instance (ArbitraryIsTx tx, IsChainState tx) => Arbitrary (StateChanged tx) where
arbitrary = arbitrary >>= genStateChanged

instance (ArbitraryIsTx tx, IsChainState tx) => ToADTArbitrary (StateChanged tx)

genStateChanged :: (ArbitraryIsTx tx, IsChainState tx) => Environment -> Gen (StateChanged tx)
genStateChanged env =
oneof
[ HeadIsInitializing <$> arbitrary <*> arbitrary <*> pure (mkHeadParameters env) <*> arbitrary <*> arbitrary
, Committed <$> arbitrary <*> pure party <*> arbitrary <*> arbitrary
, HeadIsAborted <$> arbitrary <*> arbitrary <*> arbitrary
, HeadIsOpen <$> arbitrary <*> arbitrary <*> arbitrary
[ HeadInitialized (mkHeadParameters env) <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
, CommittedUTxO <$> arbitrary <*> pure party <*> arbitrary <*> arbitrary
, HeadAborted <$> arbitrary <*> arbitrary <*> arbitrary
, HeadOpened <$> arbitrary <*> arbitrary <*> arbitrary
, TransactionReceived <$> arbitrary
, TxValid <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
, TransactionAppliedToLocalUTxO <$> arbitrary <*> arbitrary <*> arbitrary
, CommitRecorded <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
, DecommitRecorded <$> arbitrary <*> arbitrary
, SnapshotRequestDecided <$> arbitrary
, SnapshotRequested <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
, PartySignedSnapshot <$> arbitrary <*> arbitrary <*> arbitrary
, SnapshotConfirmed <$> arbitrary <*> arbitrary <*> arbitrary
, CommitFinalized <$> arbitrary <*> arbitrary <*> arbitrary
, DecommitFinalized <$> arbitrary <*> arbitrary <*> arbitrary
, HeadIsClosed <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
, HeadIsContested <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
, ReadyToFanout <$> arbitrary
, HeadIsFinalized <$> arbitrary <*> arbitrary <*> arbitrary
, HeadClosed <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
, HeadContested <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
, HeadIsReadyToFanout <$> arbitrary
, HeadFannedOut <$> arbitrary <*> arbitrary <*> arbitrary
, ChainRolledBack <$> arbitrary
, TickObserved <$> arbitrary
]
where
Environment{party} = env

instance (ArbitraryIsTx tx, IsChainState tx) => Arbitrary (StateChanged tx) where
arbitrary = arbitrary >>= genStateChanged

instance (ArbitraryIsTx tx, IsChainState tx) => ToADTArbitrary (StateChanged tx)

data DecommitInvalidReason tx
= DecommitTxInvalid {localUTxO :: UTxOType tx, validationError :: ValidationError}
| DecommitAlreadyInFlight {otherDecommitTxId :: TxIdType tx}
Expand Down
2 changes: 1 addition & 1 deletion hydra-node/test/Hydra/BehaviorSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -849,7 +849,7 @@ spec = parallel $ do

logs = selectTraceEventsDynamic @_ @(HydraNodeLog SimpleTx) result

logs `shouldContain` [BeginEffect alice 2 0 (ClientEffect $ Outcome.HeadIsInitializing{headId = testHeadId, parties = fromList [alice], parameters = testHeadParameters, headSeed = testHeadSeed, chainState = SimpleChainState 1})]
logs `shouldContain` [BeginEffect alice 2 0 (ClientEffect $ Outcome.HeadInitialized{headId = testHeadId, parties = fromList [alice], parameters = testHeadParameters, headSeed = testHeadSeed, chainState = SimpleChainState 1})]
logs `shouldContain` [EndEffect alice 2 0]

describe "rolling back & forward does not make the node crash" $ do
Expand Down
6 changes: 3 additions & 3 deletions hydra-node/test/Hydra/HeadLogicSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -599,21 +599,21 @@ spec =
, snapshotNumber
, contestationDeadline
}
clientEffect = ClientEffect HeadIsClosed{headId = testHeadId, snapshotNumber, contestationDeadline, chainState = SimpleChainState 0}
clientEffect = ClientEffect HeadClosed{headId = testHeadId, snapshotNumber, contestationDeadline, chainState = SimpleChainState 0}
runHeadLogic bobEnv ledger s0 $ do
outcome1 <- step observeCloseTx
lift $ do
outcome1 `hasEffect` clientEffect
outcome1
`hasNoEffectSatisfying` \case
ClientEffect (ReadyToFanout _) -> True
ClientEffect (HeadIsReadyToFanout _) -> True
_ -> False

let oneSecondsPastDeadline = addUTCTime 1 contestationDeadline
someChainSlot = arbitrary `generateWith` 42
stepTimePastDeadline = ChainInput $ Tick oneSecondsPastDeadline someChainSlot
outcome2 <- step stepTimePastDeadline
lift $ outcome2 `hasEffect` ClientEffect (ReadyToFanout testHeadId)
lift $ outcome2 `hasEffect` ClientEffect (HeadIsReadyToFanout testHeadId)

it "contests when detecting close with old snapshot" $ do
let snapshotVersion = 0
Expand Down
12 changes: 6 additions & 6 deletions hydra-node/test/Hydra/NodeSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import Hydra.Chain (Chain (..), ChainEvent (..), OnChainTx (..), PostTxError (No
import Hydra.Chain.ChainState (ChainSlot (ChainSlot), IsChainState)
import Hydra.Events (EventSink (..), EventSource (..), StateEvent (..), genStateEvent, getEventId)
import Hydra.HeadLogic (Input (..))
import Hydra.HeadLogic.Outcome qualified as Outcome
import Hydra.HeadLogic.Outcome (StateChanged (..), genStateChanged)
import Hydra.HeadLogicSpec (inInitialState, receiveMessage, receiveMessageFrom, testSnapshot)
import Hydra.Ledger.Simple (SimpleChainState (..), SimpleTx (..), simpleLedger, utxoRef, utxoRefs)
import Hydra.Logging (Tracer, showLogsOnFailure, traceInTVar)
Expand Down Expand Up @@ -69,7 +69,7 @@ spec = parallel $ do
describe "hydrate" $ do
around setupHydrate $ do
it "loads events from source into all sinks" $ \testHydrate ->
forAllShrink (listOf $ Outcome.genStateChanged testEnvironment >>= genStateEvent) shrink $
forAllShrink (listOf $ genStateChanged testEnvironment >>= genStateEvent) shrink $
\someEvents -> do
(mockSink1, getMockSinkEvents1) <- createRecordingSink
(mockSink2, getMockSinkEvents2) <- createRecordingSink
Expand All @@ -80,7 +80,7 @@ spec = parallel $ do
getMockSinkEvents2 `shouldReturn` someEvents

it "event ids are consistent" $ \testHydrate ->
forAllShrink (listOf $ Outcome.genStateChanged testEnvironment >>= genStateEvent) shrink $
forAllShrink (listOf $ genStateChanged testEnvironment >>= genStateEvent) shrink $
\someEvents -> do
(sink, getSinkEvents) <- createRecordingSink

Expand All @@ -90,7 +90,7 @@ spec = parallel $ do
getEventId <$> seenEvents `shouldBe` getEventId <$> someEvents

it "fails if one sink fails" $ \testHydrate ->
forAllShrink (listOf1 $ Outcome.genStateChanged testEnvironment >>= genStateEvent) shrink $
forAllShrink (listOf1 $ genStateChanged testEnvironment >>= genStateEvent) shrink $
\someEvents -> do
let genSinks = elements [mockSink, failingSink]
failingSink = EventSink{putEvent = \_ -> failure "failing sink called"}
Expand All @@ -106,7 +106,7 @@ spec = parallel $ do
let genEvent = do
StateEvent
<$> arbitrary
<*> (Outcome.HeadIsInitializing <$> arbitrary <*> arbitrary <*> pure (mkHeadParameters env) <*> arbitrary <*> arbitrary)
<*> (HeadInitialized (mkHeadParameters env) <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary)
forAllShrink genEvent shrink $ \incompatibleEvent ->
testHydrate (mockSource [incompatibleEvent]) []
`shouldThrow` \(_ :: ParameterMismatch) -> True
Expand Down Expand Up @@ -246,7 +246,7 @@ spec = parallel $ do

outputs <- getServerOutputs
let isPostTxOnChainFailed = \case
PostTxOnChainFailed{postTxError} -> postTxError == NoSeedInput
Hydra.API.ServerOutput.PostTxOnChainFailed{postTxError} -> postTxError == NoSeedInput
_ -> False
any isPostTxOnChainFailed outputs `shouldBe` True

Expand Down
4 changes: 2 additions & 2 deletions hydraw/src/Hydra/Painter.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import Cardano.Api.UTxO qualified as UTxO
import Control.Exception (IOException)
import Data.Aeson qualified as Aeson
import Hydra.API.ClientInput (ClientInput (GetUTxO, NewTx))
import Hydra.API.ServerOutput (ServerOutput (GetUTxOResponse))
import Hydra.Chain.Direct.State ()
import Hydra.Chain.Direct.Util (readFileTextEnvelopeThrow)
import Hydra.HeadLogic.Outcome (StateChanged (GetUTxOResponse))
import Hydra.Network (Host (..))
import Network.WebSockets (Connection, runClient, sendTextData)
import Network.WebSockets.Connection (receive, receiveData)
Expand All @@ -26,7 +26,7 @@ paintPixel networkId signingKeyPath cnx pixel = do
sendTextData @Text cnx $ decodeUtf8 $ Aeson.encode (GetUTxO @Tx)
msg <- receiveData cnx
putStrLn $ "Received from hydra-node: " <> show msg
case Aeson.eitherDecode @(StateChanged Tx) msg of
case Aeson.eitherDecode @(ServerOutput Tx) msg of
Right (GetUTxOResponse _ utxo) ->
case UTxO.find (\TxOut{txOutAddress} -> txOutAddress == myAddress) utxo of
Nothing -> fail $ "No UTxO owned by " <> show myAddress
Expand Down

0 comments on commit 9a6f54a

Please sign in to comment.