| Safe Haskell | Safe-Inferred |
|---|---|
| Language | GHC2021 |
Hydra.Model
Description
A Model of the Hydra head Protocol.
This model integrates in a single state-machine like abstraction the whole behaviour of a Hydra Head, taking into account both on-chain state and contracts, and off-chain interactions. It is written from the point of view of a pre-defined set of Hydra node operators that want to create a channel between them. It's a "happy path" model that does not implement any kind of adversarial behaviour and whose transactions are very simple: Each tx is a payment of one Ada-only UTxO transferred to another party in full, without any change.
More intricate and specialised models shall be developed once we get a firmer grasp of the whole framework, injecting faults, taking into account more parts of the stack, modelling more complex transactions schemes...
Synopsis
- data WorldState = WorldState {
- hydraParties :: [(Secret (SigningKey HydraKey), CardanoSigningKey)]
- hydraState :: GlobalState
- availableToDeposit :: UTxOType Payment
- pendingCommits :: [(Var TxId, UTxOType Payment)]
- pendingDecommits :: [(Var UTxO, Payment)]
- settledCommits :: [Var TxId]
- settledDecommits :: [Var UTxO]
- concurrentSettlements :: Bool
- data GlobalState
- = Start
- | Idle {
- idleParties :: [Party]
- cardanoKeys :: [VerificationKey PaymentKey]
- contestationPeriod :: ContestationPeriod
- | Open {
- headIdVar :: Var HeadId
- headParameters :: HeadParameters
- offChainState :: OffChainState
- committed :: Map Party (UTxOType Payment)
- onChainVersion :: Natural
- | Closed {
- headParameters :: HeadParameters
- closedUTxO :: UTxOType Payment
- unsettledAtClose :: UTxOType Payment
- fanoutDriving :: FanoutDriving
- fannedOut :: UTxOType Payment
- | Final {
- finalUTxO :: UTxOType Payment
- unsettledAtFinal :: UTxOType Payment
- newtype OffChainState = OffChainState {
- confirmedUTxO :: UTxOType Payment
- data FanoutDriving
- settleCommit :: UTxOType Payment -> GlobalState -> GlobalState
- removeDecommitted :: Payment -> GlobalState -> GlobalState
- settleDecommit :: Payment -> GlobalState -> GlobalState
- restartNodeEnabled :: Bool
- genSeed :: Gen (Action WorldState ())
- genSeedWith :: Bool -> Gen (Action WorldState ())
- genContestationPeriod :: Gen ContestationPeriod
- genInit :: [(Secret (SigningKey HydraKey), b)] -> Gen (Action WorldState HeadId)
- genPayment :: WorldState -> Gen (Party, Payment)
- unsafeConstructorName :: Show a => a -> String
- partyKeys :: Gen [(Secret (SigningKey HydraKey), CardanoSigningKey)]
- genPartyKeysExactly :: Int -> Gen [(Secret (SigningKey HydraKey), CardanoSigningKey)]
- data Nodes m = Nodes {
- nodes :: Map Party (TestHydraClient Tx m)
- logger :: Tracer m (HydraLog Tx)
- threads :: [Async m ()]
- chain :: SimulatedChainNetwork Tx m
- eventStores :: Map Party (EventStore (StateEvent Tx) m, m [StateEvent Tx])
- nodeThreads :: Map Party (Async m ())
- newtype RunState m = RunState {
- nodesState :: TVar m (Nodes m)
- newtype RunMonad m a = RunMonad {}
- data RunException
- = TransactionNotObserved Payment UTxO
- | UnexpectedParty Party
- | UnknownAddress AddressInEra [(AddressInEra, CardanoSigningKey)]
- | CannotFindSpendableUTxO Payment UTxO
- sortTxOuts :: [TxOut ctx] -> [TxOut ctx]
- testDepositPeriod :: DepositPeriod
- seedWorld :: (MonadAsync m, MonadTimer m, MonadThrow (STM m), MonadLabelledSTM m, MonadFork m, MonadMask m, MonadDelay m, MonadTime m) => [(Secret (SigningKey HydraKey), CardanoSigningKey)] -> ContestationPeriod -> RunMonad m ()
- startNode :: (MonadAsync m, MonadLabelledSTM m, MonadFork m, MonadDelay m, MonadMask m, MonadTime m) => Tracer m (HydraLog Tx) -> SimulatedChainNetwork Tx m -> ContestationPeriod -> (EventStore (StateEvent Tx) m, m [StateEvent Tx]) -> Secret (SigningKey HydraKey) -> [Party] -> RunMonad m (TestHydraClient Tx m, Async m ())
- performDeposit :: (MonadThrow m, MonadTimer m, MonadAsync m, MonadTime m, MonadLabelledSTM m) => HeadId -> [(CardanoSigningKey, Value)] -> RunMonad m ()
- depositDeadline :: MonadTime m => RunMonad m UTCTime
- performSubmitDeposit :: (MonadThrow m, MonadTimer m, MonadDelay m, MonadTime m) => HeadId -> [(CardanoSigningKey, Value)] -> RunMonad m TxId
- performObserveCommitApproved :: (MonadThrow m, MonadTimer m, MonadDelay m) => UTxOType Payment -> RunMonad m ()
- performObserveCommitFinalized :: (MonadThrow m, MonadTimer m, MonadDelay m) => Int -> TxId -> RunMonad m ()
- waitForOutputs :: (MonadThrow m, MonadTimer m, MonadDelay m) => String -> Int -> [TestHydraClient Tx m] -> (ServerOutput Tx -> Bool) -> m ()
- waitUntilHistory :: (MonadThrow m, MonadTimer m, MonadDelay m) => String -> [TestHydraClient Tx m] -> ([ServerOutput Tx] -> Bool) -> m ()
- observationTimeout :: DiffTime
- performSubmitDecommit :: forall m. (MonadThrow m, MonadTimer m, MonadDelay m) => Party -> Payment -> RunMonad m UTxO
- performObserveDecommitFinalized :: (MonadThrow m, MonadTimer m, MonadDelay m) => Int -> UTxO -> RunMonad m ()
- decommitRecipient :: Payment -> AddressInEra
- performDecommit :: (MonadThrow m, MonadTimer m, MonadAsync m, MonadDelay m, MonadLabelledSTM m) => Party -> Payment -> RunMonad m ()
- performNewTx :: (MonadThrow m, MonadAsync m, MonadTimer m, MonadDelay m, MonadLabelledSTM m) => Party -> Payment -> RunMonad m Payment
- waitForOpen :: MonadDelay m => TestHydraClient tx m -> RunMonad m ()
- waitForReadyToFanout :: MonadDelay m => TestHydraClient tx m -> RunMonad m ()
- sendsInput :: forall m. (MonadSTM m, MonadThrow m, MonadDelay m) => Party -> ClientInput Tx -> RunMonad m ()
- getActorNode :: (MonadSTM m, MonadThrow m) => Party -> RunMonad m (TestHydraClient Tx m)
- performInit :: (MonadThrow m, MonadAsync m, MonadTimer m, MonadDelay m, MonadLabelledSTM m) => Party -> RunMonad m HeadId
- performClose :: forall m. (MonadThrow m, MonadDelay m, MonadLabelledSTM m) => Party -> RunMonad m ()
- performFanout :: (MonadThrow m, MonadAsync m, MonadDelay m) => Party -> RunMonad m UTxO
- performStartFanout :: (MonadSTM m, MonadThrow m, MonadDelay m) => Party -> RunMonad m ()
- performObserveFanoutFinalized :: (MonadSTM m, MonadThrow m, MonadDelay m) => Party -> RunMonad m UTxO
- performPartialFanoutStep :: (MonadThrow m, MonadTimer m, MonadDelay m) => Party -> UTxOType Payment -> RunMonad m ()
- performObservePartialFanoutSteps :: (MonadThrow m, MonadTimer m, MonadDelay m) => Int -> RunMonad m ()
- performCloseWithInitialSnapshot :: (MonadThrow m, MonadTimer m, MonadDelay m, MonadAsync m, MonadLabelledSTM m) => WorldState -> Party -> RunMonad m ()
- performRollbackAndForward :: (MonadThrow m, MonadTimer m) => Natural -> RunMonad m ()
- performRollbackAndFork :: (MonadThrow m, MonadTimer m) => Natural -> RequeueMode -> RunMonad m ()
- performRestartNode :: (MonadAsync m, MonadLabelledSTM m, MonadFork m, MonadMask m, MonadDelay m, MonadTime m) => WorldState -> Party -> RunMonad m ()
- stopTheWorld :: MonadAsync m => RunMonad m ()
- toTxOuts :: [(CardanoSigningKey, Value)] -> [TxOut CtxUTxO]
- toRealUTxO :: UTxOType Payment -> UTxOType Tx
- mkTxOut :: CardanoSigningKey -> Value -> TxOut CtxUTxO
- mkMockTxIn :: CardanoSigningKey -> Word -> TxIn
- waitForUTxOToSpend :: forall m. MonadDelay m => UTxO -> CardanoSigningKey -> Value -> TestHydraClient Tx m -> m (Either UTxO (TxIn, TxOut CtxUTxO))
- headUTxO :: (IsTx tx, MonadDelay m) => TestHydraClient tx m -> m (UTxOType tx)
- isOwned :: CardanoSigningKey -> (TxIn, TxOut ctx) -> Bool
- headIsOpen :: ServerOutput tx -> Bool
- headIsReadyToFanout :: ServerOutput tx -> Bool
The Model
data WorldState Source #
State maintained by the model.
Constructors
| WorldState | |
Fields
| |
Instances
| Show WorldState Source # | |
Defined in Hydra.Model | |
| Eq WorldState Source # | |
Defined in Hydra.Model Methods (==) :: WorldState -> WorldState -> Bool Source # (/=) :: WorldState -> WorldState -> Bool Source # | |
| DynLogicModel WorldState Source # | |
Defined in Hydra.Model Methods restricted :: Action WorldState a -> Bool | |
| StateModel WorldState Source # | Basic instantiation of |
Defined in Hydra.Model Methods actionName :: Action WorldState a -> String arbitraryAction :: VarContext -> WorldState -> Gen (Any (Action WorldState)) shrinkAction :: Typeable a => VarContext -> WorldState -> Action WorldState a -> [Any (Action WorldState)] nextState :: Typeable a => WorldState -> Action WorldState a -> Var a -> WorldState failureNextState :: Typeable a => WorldState -> Action WorldState a -> WorldState precondition :: WorldState -> Action WorldState a -> Bool validFailingAction :: WorldState -> Action WorldState a -> Bool | |
| HasVariables WorldState Source # | |
Defined in Hydra.Model Methods getAllVariables :: WorldState -> Set (Any Var) | |
| (MonadAsync m, MonadFork m, MonadMask m, MonadTimer m, MonadThrow (STM m), MonadLabelledSTM m, MonadDelay m, MonadTime m) => RunModel WorldState (RunMonad m) Source # | |
Defined in Hydra.Model Methods perform :: Typeable a => WorldState -> Action WorldState a -> LookUp (RunMonad m) -> RunMonad m (PerformResult (Error WorldState) (Realized (RunMonad m) a)) postcondition :: (WorldState, WorldState) -> Action WorldState a -> LookUp (RunMonad m) -> Realized (RunMonad m) a -> PostconditionM (RunMonad m) Bool postconditionOnFailure :: (WorldState, WorldState) -> Action WorldState a -> LookUp (RunMonad m) -> Either (Error WorldState) (Realized (RunMonad m) a) -> PostconditionM (RunMonad m) Bool monitoring :: (WorldState, WorldState) -> Action WorldState a -> LookUp (RunMonad m) -> Either (Error WorldState) (Realized (RunMonad m) a) -> Property -> Property monitoringFailure :: WorldState -> Action WorldState a -> LookUp (RunMonad m) -> Error WorldState -> Property -> Property | |
| Show (Action WorldState a) Source # | |
Defined in Hydra.Model | |
| Eq (Action WorldState a) Source # | |
Defined in Hydra.Model Methods (==) :: Action WorldState a -> Action WorldState a -> Bool Source # (/=) :: Action WorldState a -> Action WorldState a -> Bool Source # | |
| HasVariables (Action WorldState a) Source # | |
Defined in Hydra.Model Methods getAllVariables :: Action WorldState a -> Set (Any Var) | |
| data Action WorldState a Source # | |
Defined in Hydra.Model data Action WorldState a where
| |
| type Error WorldState Source # | |
Defined in Hydra.Model | |
data GlobalState Source #
Global state of the Head protocol. While each participant in the Hydra Head protocol has its own private view of the state, we model the expected global state whose properties stem from the consensus built into the Head protocol. In other words, this state is what each node's local state should be eventually.
Constructors
| Start | Start of the "world". This state is left implicit in the node's logic as it represents that state where the node does not even exist. |
| Idle | |
Fields
| |
| Open | |
Fields
| |
| Closed | |
Fields
| |
| Final | |
Fields
| |
Instances
| Show GlobalState Source # | |
Defined in Hydra.Model | |
| Eq GlobalState Source # | |
Defined in Hydra.Model Methods (==) :: GlobalState -> GlobalState -> Bool Source # (/=) :: GlobalState -> GlobalState -> Bool Source # | |
newtype OffChainState Source #
Constructors
| OffChainState | |
Fields
| |
Instances
| Show OffChainState Source # | |
Defined in Hydra.Model | |
| Eq OffChainState Source # | |
Defined in Hydra.Model Methods (==) :: OffChainState -> OffChainState -> Bool Source # (/=) :: OffChainState -> OffChainState -> Bool Source # | |
data FanoutDriving Source #
How a closed head's fanout is driven. A plain Fanout drains the head
automatically, possibly in several steps; PartialFanoutStep hands the node
one selection at a time and the node only drains what it was given. The two
cannot be mixed: once a partial fanout started, Fanout is rejected.
Constructors
| FanoutNotStarted | |
| FanoutAutoDraining | |
| FanoutManual |
Instances
| Show FanoutDriving Source # | |
Defined in Hydra.Model | |
| Eq FanoutDriving Source # | |
Defined in Hydra.Model Methods (==) :: FanoutDriving -> FanoutDriving -> Bool Source # (/=) :: FanoutDriving -> FanoutDriving -> Bool Source # | |
settleCommit :: UTxOType Payment -> GlobalState -> GlobalState Source #
Add a finalized commit to the head's UTxO and bump the on-chain version.
removeDecommitted :: Payment -> GlobalState -> GlobalState Source #
Remove a decommitted output from the head's UTxO (it leaves the L2 ledger with the snapshot carrying the decommit).
settleDecommit :: Payment -> GlobalState -> GlobalState Source #
Account for a finalized decrement: bump the on-chain version.
Generator Helper
restartNodeEnabled :: Bool Source #
Whether random RestartNode actions are generated. On: a restarted node
recovers head state (event store), chain point, network consumer offset
(etcd-style) and the full chain-sync localChainState history, so it
converges under load like a real fail-recovery. Flip to False to drop the
fail-recovery dimension if it ever proves flaky.
genSeed :: Gen (Action WorldState ()) Source #
The default seed settles each deposit and decommit before the next
action, see WorldState.
genSeedWith :: Bool -> Gen (Action WorldState ()) Source #
genContestationPeriod :: Gen ContestationPeriod Source #
genInit :: [(Secret (SigningKey HydraKey), b)] -> Gen (Action WorldState HeadId) Source #
genPayment :: WorldState -> Gen (Party, Payment) Source #
unsafeConstructorName :: Show a => a -> String Source #
partyKeys :: Gen [(Secret (SigningKey HydraKey), CardanoSigningKey)] Source #
Generate a list of pairs of Hydra/Cardano signing keys. All the keys in this list are guaranteed to be unique.
genPartyKeysExactly :: Int -> Gen [(Secret (SigningKey HydraKey), CardanoSigningKey)] Source #
Exactly n distinct parties, for scripted scenarios (see partyKeys).
Running the model
Concrete state needed to run actions against the implementation.
This state is used and might be updated when actually performing actions generated from the StateModel.
Constructors
| Nodes | |
Fields
| |
Constructors
| RunState | |
Fields
| |
Our execution MonadTransformer.
This type is needed in order to keep the execution monad m abstract and thus
simplify the definition of the RunModel instance which requires a proper definition
of Realized type family. See this issue
for a discussion on why this monad is needed.
We could perhaps getaway with it and just have a type based on IOSim monad
but this is cumbersome to write.
Instances
| MonadTrans RunMonad Source # | |
| (MonadAsync m, MonadFork m, MonadMask m, MonadTimer m, MonadThrow (STM m), MonadLabelledSTM m, MonadDelay m, MonadTime m) => RunModel WorldState (RunMonad m) Source # | |
Defined in Hydra.Model Methods perform :: Typeable a => WorldState -> Action WorldState a -> LookUp (RunMonad m) -> RunMonad m (PerformResult (Error WorldState) (Realized (RunMonad m) a)) postcondition :: (WorldState, WorldState) -> Action WorldState a -> LookUp (RunMonad m) -> Realized (RunMonad m) a -> PostconditionM (RunMonad m) Bool postconditionOnFailure :: (WorldState, WorldState) -> Action WorldState a -> LookUp (RunMonad m) -> Either (Error WorldState) (Realized (RunMonad m) a) -> PostconditionM (RunMonad m) Bool monitoring :: (WorldState, WorldState) -> Action WorldState a -> LookUp (RunMonad m) -> Either (Error WorldState) (Realized (RunMonad m) a) -> Property -> Property monitoringFailure :: WorldState -> Action WorldState a -> LookUp (RunMonad m) -> Error WorldState -> Property -> Property | |
| Applicative m => Applicative (RunMonad m) Source # | |
Defined in Hydra.Model Methods pure :: a -> RunMonad m a Source # (<*>) :: RunMonad m (a -> b) -> RunMonad m a -> RunMonad m b Source # liftA2 :: (a -> b -> c) -> RunMonad m a -> RunMonad m b -> RunMonad m c Source # (*>) :: RunMonad m a -> RunMonad m b -> RunMonad m b Source # (<*) :: RunMonad m a -> RunMonad m b -> RunMonad m a Source # | |
| Functor m => Functor (RunMonad m) Source # | |
| Monad m => Monad (RunMonad m) Source # | |
| MonadThrow m => MonadThrow (RunMonad m) Source # | |
| MonadTime m => MonadTime (RunMonad m) Source # | |
Defined in Hydra.Model Methods | |
| Monad m => MonadReader (RunState m) (RunMonad m) Source # | |
| MonadSTM m => MonadState (Nodes m) (RunMonad m) Source # | |
| type Realized (RunMonad m) a Source # | This type family is needed to link the _actual_ output from running actions with the ones that are modelled. In our case we can keep things simple and use the same types on both side of the fence. |
Defined in Hydra.Model type Realized (RunMonad m) a = a | |
data RunException Source #
Constructors
| TransactionNotObserved Payment UTxO | |
| UnexpectedParty Party | |
| UnknownAddress AddressInEra [(AddressInEra, CardanoSigningKey)] | |
| CannotFindSpendableUTxO Payment UTxO |
Instances
| Exception RunException Source # | |
Defined in Hydra.Model Methods toException :: RunException -> SomeException Source # fromException :: SomeException -> Maybe RunException Source # | |
| Show RunException Source # | |
Defined in Hydra.Model | |
| Eq RunException Source # | |
Defined in Hydra.Model Methods (==) :: RunException -> RunException -> Bool Source # (/=) :: RunException -> RunException -> Bool Source # | |
sortTxOuts :: [TxOut ctx] -> [TxOut ctx] Source #
Performing actions
testDepositPeriod :: DepositPeriod Source #
Deposit period used by all nodes and the performDeposit.
seedWorld :: (MonadAsync m, MonadTimer m, MonadThrow (STM m), MonadLabelledSTM m, MonadFork m, MonadMask m, MonadDelay m, MonadTime m) => [(Secret (SigningKey HydraKey), CardanoSigningKey)] -> ContestationPeriod -> RunMonad m () Source #
startNode :: (MonadAsync m, MonadLabelledSTM m, MonadFork m, MonadDelay m, MonadMask m, MonadTime m) => Tracer m (HydraLog Tx) -> SimulatedChainNetwork Tx m -> ContestationPeriod -> (EventStore (StateEvent Tx) m, m [StateEvent Tx]) -> Secret (SigningKey HydraKey) -> [Party] -> RunMonad m (TestHydraClient Tx m, Async m ()) Source #
(Re-)create and start a single hydra node on the given event store,
recovering its state from the store's events, and wait for it to be in sync
with the chain. Shared by seedWorld and performRestartNode.
performDeposit :: (MonadThrow m, MonadTimer m, MonadAsync m, MonadTime m, MonadLabelledSTM m) => HeadId -> [(CardanoSigningKey, Value)] -> RunMonad m () Source #
depositDeadline :: MonadTime m => RunMonad m UTCTime Source #
Deadline for deposits made by the model: far enough in the future that the
deposit is still claimable once it activates (at created +
depositActivation, with created up to half a deposit period ahead of
submission) even when several deposits settle one after the other, each
taking a few blocks. It expires at deadline - depositPeriod.
performSubmitDeposit :: (MonadThrow m, MonadTimer m, MonadDelay m, MonadTime m) => HeadId -> [(CardanoSigningKey, Value)] -> RunMonad m TxId Source #
Submit a deposit and wait until every node has recorded it on chain. Its
settlement is observed separately, see performObserveCommitFinalized.
performObserveCommitApproved :: (MonadThrow m, MonadTimer m, MonadDelay m) => UTxOType Payment -> RunMonad m () Source #
Wait until every node has confirmed a snapshot claiming the given deposit
(CommitApproved): the increment is now in flight.
performObserveCommitFinalized :: (MonadThrow m, MonadTimer m, MonadDelay m) => Int -> TxId -> RunMonad m () Source #
Wait until every node has reported the increment claiming the given deposit for the n-th time. A wedged settlement surfaces here as a timeout.
waitForOutputs :: (MonadThrow m, MonadTimer m, MonadDelay m) => String -> Int -> [TestHydraClient Tx m] -> (ServerOutput Tx -> Bool) -> m () Source #
Wait until every node's output history holds at least n outputs
matching the predicate, or fail after observationTimeout.
Unlike waitUntilMatch this does not consume outputs, so settlements can
be observed in any order (several may be in flight and finalize in an order
the model does not control) and repeatedly (a settlement re-landing after a
fork is reported again). It also does not swallow reports that arrive
earlier than expected, e.g. a decrement observed on chain before its
snapshot confirmed locally.
waitUntilHistory :: (MonadThrow m, MonadTimer m, MonadDelay m) => String -> [TestHydraClient Tx m] -> ([ServerOutput Tx] -> Bool) -> m () Source #
Wait until every node's output history satisfies the predicate, or fail
after observationTimeout. See waitForOutputs.
observationTimeout :: DiffTime Source #
How long an observation waits for the nodes to report something. Every observed step (a settlement landing, re-landing after a fork, a snapshot confirming) takes a handful of blocks of 20s, so an hour is generous while still failing a wedged head reasonably fast.
performSubmitDecommit :: forall m. (MonadThrow m, MonadTimer m, MonadDelay m) => Party -> Payment -> RunMonad m UTxO Source #
Request a decommit and wait until every node has confirmed the snapshot
carrying it (DecommitApproved), i.e. the outputs have left the L2 ledger
and the decrement is in flight. Its settlement is observed separately, see
performObserveDecommitFinalized.
performObserveDecommitFinalized :: (MonadThrow m, MonadTimer m, MonadDelay m) => Int -> UTxO -> RunMonad m () Source #
Wait until every node has reported the decrement distributing the given decommitted UTxO for the n-th time.
decommitRecipient :: Payment -> AddressInEra Source #
performDecommit :: (MonadThrow m, MonadTimer m, MonadAsync m, MonadDelay m, MonadLabelledSTM m) => Party -> Payment -> RunMonad m () Source #
performNewTx :: (MonadThrow m, MonadAsync m, MonadTimer m, MonadDelay m, MonadLabelledSTM m) => Party -> Payment -> RunMonad m Payment Source #
waitForOpen :: MonadDelay m => TestHydraClient tx m -> RunMonad m () Source #
Wait for the head to be open by searching from the beginning. Note that there rollbacks or multiple life-cycles of heads are not handled here.
waitForReadyToFanout :: MonadDelay m => TestHydraClient tx m -> RunMonad m () Source #
Wait for the head to be closed by searching from the beginning. Note that there rollbacks or multiple life-cycles of heads are not handled here.
sendsInput :: forall m. (MonadSTM m, MonadThrow m, MonadDelay m) => Party -> ClientInput Tx -> RunMonad m () Source #
getActorNode :: (MonadSTM m, MonadThrow m) => Party -> RunMonad m (TestHydraClient Tx m) Source #
performInit :: (MonadThrow m, MonadAsync m, MonadTimer m, MonadDelay m, MonadLabelledSTM m) => Party -> RunMonad m HeadId Source #
performClose :: forall m. (MonadThrow m, MonadDelay m, MonadLabelledSTM m) => Party -> RunMonad m () Source #
performFanout :: (MonadThrow m, MonadAsync m, MonadDelay m) => Party -> RunMonad m UTxO Source #
performStartFanout :: (MonadSTM m, MonadThrow m, MonadDelay m) => Party -> RunMonad m () Source #
Send Fanout once the head is ready for it, without waiting for the
fanout to complete.
performObserveFanoutFinalized :: (MonadSTM m, MonadThrow m, MonadDelay m) => Party -> RunMonad m UTxO Source #
Wait for the head to be finalized on the given party's node and return what the fanout distributed.
performPartialFanoutStep :: (MonadThrow m, MonadTimer m, MonadDelay m) => Party -> UTxOType Payment -> RunMonad m () Source #
Hand the node a selection to fan out (manual mode) and wait until every node reports all of it distributed: over one or more partial steps, or by the final fanout if the selection drains the head.
performObservePartialFanoutSteps :: (MonadThrow m, MonadTimer m, MonadDelay m) => Int -> RunMonad m () Source #
Wait until every node has reported at least n partial fanout steps.
performCloseWithInitialSnapshot :: (MonadThrow m, MonadTimer m, MonadDelay m, MonadAsync m, MonadLabelledSTM m) => WorldState -> Party -> RunMonad m () Source #
performRollbackAndForward :: (MonadThrow m, MonadTimer m) => Natural -> RunMonad m () Source #
performRollbackAndFork :: (MonadThrow m, MonadTimer m) => Natural -> RequeueMode -> RunMonad m () Source #
performRestartNode :: (MonadAsync m, MonadLabelledSTM m, MonadFork m, MonadMask m, MonadDelay m, MonadTime m) => WorldState -> Party -> RunMonad m () Source #
Crash a node (cancelling its main thread, so any in-flight inputs and in-memory-only state are lost) and start it again from its own event store, re-syncing the chain from genesis. Models a node operator restart / fail-recovery under load: the head must stay live through it.
stopTheWorld :: MonadAsync m => RunMonad m () Source #
Utility functions
toTxOuts :: [(CardanoSigningKey, Value)] -> [TxOut CtxUTxO] Source #
Convert payment-style utxos into transaction outputs.
toRealUTxO :: UTxOType Payment -> UTxOType Tx Source #
Convert payment-style utxos into real utxos. The Payment tx domain is
smaller than UTxO and we map every unique signer + value entry to a mocked
TxIn on the real cardano domain.
mkTxOut :: CardanoSigningKey -> Value -> TxOut CtxUTxO Source #
mkMockTxIn :: CardanoSigningKey -> Word -> TxIn Source #
waitForUTxOToSpend :: forall m. MonadDelay m => UTxO -> CardanoSigningKey -> Value -> TestHydraClient Tx m -> m (Either UTxO (TxIn, TxOut CtxUTxO)) Source #
headUTxO :: (IsTx tx, MonadDelay m) => TestHydraClient tx m -> m (UTxOType tx) Source #
isOwned :: CardanoSigningKey -> (TxIn, TxOut ctx) -> Bool Source #
headIsOpen :: ServerOutput tx -> Bool Source #
headIsReadyToFanout :: ServerOutput tx -> Bool Source #