Skip to content

Commit d6a611f

Browse files
committed
Refactor performTx and TxResult + some documentation
This should make it clear how this is currently used in between perform and postcondition.
1 parent 0ca9288 commit d6a611f

File tree

1 file changed

+50
-28
lines changed

1 file changed

+50
-28
lines changed

hydra-node/test/Hydra/Chain/Direct/TxTraceSpec.hs

Lines changed: 50 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,17 @@ import Hydra.Cardano.Api.Pretty (renderTxWithUTxO)
2929
import Hydra.Chain.Direct.Contract.Mutation (addParticipationTokens)
3030
import Hydra.Chain.Direct.Fixture qualified as Fixture
3131
import Hydra.Chain.Direct.ScriptRegistry (ScriptRegistry, genScriptRegistry, registryUTxO)
32-
import Hydra.Chain.Direct.State (ChainContext (..), close, contest, decrement, fanout)
33-
import Hydra.Chain.Direct.Tx (FanoutTxError, HeadObservation, headIdToCurrencySymbol, mkHeadId, mkHeadOutput, observeHeadTx)
32+
import Hydra.Chain.Direct.State (ChainContext (..), DecrementTxError, close, contest, decrement, fanout)
33+
import Hydra.Chain.Direct.Tx (
34+
CloseTxError,
35+
ContestTxError,
36+
FanoutTxError,
37+
HeadObservation (NoHeadTx),
38+
headIdToCurrencySymbol,
39+
mkHeadId,
40+
mkHeadOutput,
41+
observeHeadTx,
42+
)
3443
import Hydra.Chain.Direct.Tx qualified as Tx
3544
import Hydra.ContestationPeriod qualified as CP
3645
import Hydra.Contract.HeadState qualified as Head
@@ -183,8 +192,11 @@ data State
183192
data Actor = Alice | Bob | Carol
184193
deriving (Show, Eq)
185194

195+
-- | Result of constructing and performing a transaction. Notably there are
196+
-- three stages to this which can fail: construction, validation, and
197+
-- observation. Results from all stages are needed to express post-conditions.
186198
data TxResult = TxResult
187-
{ tx :: Either String Tx
199+
{ constructedTx :: Either String Tx
188200
, validationError :: Maybe String
189201
, observation :: HeadObservation
190202
}
@@ -270,6 +282,8 @@ instance StateModel Model where
270282
]
271283
Final -> pure $ Some Stop
272284

285+
-- Determine actions we want to perform and expect to work. If this is False,
286+
-- validFailingAction is checked too.
273287
precondition :: Model -> Action Model a -> Bool
274288
precondition Model{headState, latestSnapshot, alreadyContested, utxoInHead} = \case
275289
Stop -> headState /= Final
@@ -291,6 +305,9 @@ instance StateModel Model where
291305
headState == Closed
292306
&& snapshotUTxO snapshot == utxoInHead
293307

308+
-- Determine actions we want to perform and want to see failing. If this is
309+
-- False, the action is discarded (e.g. it's invalid or we don't want to see
310+
-- it tried to perform).
294311
validFailingAction :: Model -> Action Model a -> Bool
295312
validFailingAction Model{headState, latestSnapshot, alreadyContested, utxoInHead} = \case
296313
Decrement{snapshot} ->
@@ -377,9 +394,7 @@ instance RunModel Model AppM where
377394
Contest{actor, snapshot} ->
378395
performTx =<< newContestTx actor (confirmedSnapshot snapshot)
379396
Fanout{snapshot} -> do
380-
newFanoutTx Alice snapshot >>= \case
381-
Left err -> pure $ TxResult{tx = Left (show err), validationError = Nothing, observation = Tx.NoHeadTx}
382-
Right tx -> performTx tx
397+
performTx =<< newFanoutTx Alice snapshot
383398
Stop -> pure ()
384399

385400
postcondition (modelBefore, modelAfter) action _lookup result = runPostconditionM' $ do
@@ -399,8 +414,8 @@ instance RunModel Model AppM where
399414
_ -> fail "Expected Contest"
400415
Fanout{snapshot} -> do
401416
case result of
402-
TxResult{tx = Left err} -> fail $ "Failed to construct transaction: " <> err
403-
TxResult{tx = Right tx} -> do
417+
TxResult{constructedTx = Left err} -> fail $ "Failed to construct transaction: " <> err
418+
TxResult{constructedTx = Right tx} -> do
404419
-- NOTE: Sort `[TxOut]` by the address and values. We want to make
405420
-- sure that the fanout outputs match what we had in the open Head
406421
-- exactly.
@@ -432,20 +447,27 @@ instance RunModel Model AppM where
432447
-- | Perform a transaction by evaluating and observing it. This updates the
433448
-- 'UTxO' in the 'AppM' if a transaction is valid and produces a 'TxResult' that
434449
-- can be used to assert expected success / failure.
435-
performTx :: Tx -> AppM TxResult
436-
performTx tx = do
437-
utxo <- get
438-
let validationError = getValidationError tx utxo
439-
when (isNothing validationError) $ do
440-
put $ adjustUTxO tx utxo
441-
pure
442-
TxResult
443-
{ -- TODO: this is wonky since there could be validation errors but we
444-
-- set the tx as Right?
445-
tx = Right tx
446-
, validationError
447-
, observation = observeHeadTx Fixture.testNetworkId utxo tx
448-
}
450+
performTx :: Show err => Either err Tx -> AppM TxResult
451+
performTx = \case
452+
Left err ->
453+
pure
454+
TxResult
455+
{ constructedTx = Left $ show err
456+
, validationError = Nothing
457+
, observation = NoHeadTx
458+
}
459+
Right tx -> do
460+
utxo <- get
461+
let validationError = getValidationError tx utxo
462+
when (isNothing validationError) $ do
463+
put $ adjustUTxO tx utxo
464+
let observation = observeHeadTx Fixture.testNetworkId utxo tx
465+
pure
466+
TxResult
467+
{ constructedTx = Right tx
468+
, validationError
469+
, observation
470+
}
449471

450472
getValidationError :: Tx -> UTxO -> Maybe String
451473
getValidationError tx utxo =
@@ -547,10 +569,10 @@ openHeadUTxO =
547569
}
548570

549571
-- | Creates a decrement transaction using given utxo and given snapshot.
550-
newDecrementTx :: HasCallStack => Actor -> (Snapshot Tx, MultiSignature (Snapshot Tx)) -> AppM Tx
572+
newDecrementTx :: Actor -> (Snapshot Tx, MultiSignature (Snapshot Tx)) -> AppM (Either DecrementTxError Tx)
551573
newDecrementTx actor (snapshot, signatures) = do
552574
spendableUTxO <- get
553-
either (failure . show) pure $
575+
pure $
554576
decrement
555577
(actorChainContext actor)
556578
(mkHeadId Fixture.testPolicyId)
@@ -563,10 +585,10 @@ newDecrementTx actor (snapshot, signatures) = do
563585
-- NOTE: This uses fixtures for headId, parties (alice, bob, carol),
564586
-- contestation period and also claims to close at time 0 resulting in a
565587
-- contestation deadline of 0 + cperiod.
566-
newCloseTx :: HasCallStack => Actor -> ConfirmedSnapshot Tx -> AppM Tx
588+
newCloseTx :: Actor -> ConfirmedSnapshot Tx -> AppM (Either CloseTxError Tx)
567589
newCloseTx actor snapshot = do
568590
spendableUTxO <- get
569-
either (failure . show) pure $
591+
pure $
570592
close
571593
(actorChainContext actor)
572594
spendableUTxO
@@ -583,10 +605,10 @@ newCloseTx actor snapshot = do
583605
-- | Creates a contest transaction using given utxo and contesting with given
584606
-- snapshot. NOTE: This uses fixtures for headId, contestation period and also
585607
-- claims to contest at time 0.
586-
newContestTx :: HasCallStack => Actor -> ConfirmedSnapshot Tx -> AppM Tx
608+
newContestTx :: Actor -> ConfirmedSnapshot Tx -> AppM (Either ContestTxError Tx)
587609
newContestTx actor snapshot = do
588610
spendableUTxO <- get
589-
either (failure . show) pure $
611+
pure $
590612
contest
591613
(actorChainContext actor)
592614
spendableUTxO

0 commit comments

Comments
 (0)