Safe Haskell | Safe-Inferred |
---|---|
Language | GHC2021 |
Implements the Head Protocol's state machine as pure functions in an event sourced manner.
More specifically, the update
will handle Input
s (or rather "commands" in
event sourcing speak) and convert that into a list of side-Effect
s and
StateChanged
events, which in turn are aggregate
d into a single
HeadState
.
As the specification is using a more imperative way of specifying the protocl
behavior, one would find the decision logic in update
while state updates
can be found in the corresponding aggregate
branch.
Synopsis
- update :: IsChainState tx => Environment -> Ledger tx -> HeadState tx -> Input tx -> Outcome tx
- defaultTTL :: TTL
- aggregateState :: IsChainState tx => HeadState tx -> Outcome tx -> HeadState tx
- recoverChainStateHistory :: (Foldable t, IsChainState tx) => ChainStateType tx -> t (StateChanged tx) -> ChainStateHistory tx
- recoverState :: (Foldable t, IsChainState tx) => HeadState tx -> t (StateChanged tx) -> HeadState tx
- aggregate :: IsChainState tx => HeadState tx -> StateChanged tx -> HeadState tx
- isLeader :: HeadParameters -> Party -> SnapshotNumber -> Bool
- onConnectionEvent :: Connectivity -> Outcome tx
- onIdleClientInit :: Environment -> Outcome tx
- onIdleChainInitTx :: Environment -> ChainStateType tx -> HeadId -> HeadSeed -> HeadParameters -> [OnChainId] -> Outcome tx
- onInitialChainCommitTx :: Monoid (UTxOType tx) => InitialState tx -> ChainStateType tx -> Party -> UTxOType tx -> Outcome tx
- onInitialClientAbort :: Monoid (UTxOType tx) => InitialState tx -> Outcome tx
- onInitialChainAbortTx :: Monoid (UTxOType tx) => ChainStateType tx -> Committed tx -> HeadId -> Outcome tx
- onInitialChainCollectTx :: IsChainState tx => InitialState tx -> ChainStateType tx -> Outcome tx
- onOpenClientNewTx :: tx -> Outcome tx
- onOpenNetworkReqTx :: IsTx tx => Environment -> Ledger tx -> OpenState tx -> TTL -> tx -> Outcome tx
- onOpenNetworkReqSn :: IsTx tx => Environment -> Ledger tx -> OpenState tx -> Party -> SnapshotVersion -> SnapshotNumber -> [TxIdType tx] -> Maybe tx -> Maybe (UTxOType tx) -> Outcome tx
- onOpenNetworkAckSn :: IsTx tx => Environment -> OpenState tx -> Party -> Signature (Snapshot tx) -> SnapshotNumber -> Outcome tx
- onOpenClientRecover :: IsTx tx => HeadId -> ChainSlot -> CoordinatedHeadState tx -> TxIdType tx -> Outcome tx
- onOpenClientDecommit :: IsTx tx => HeadId -> Ledger tx -> ChainSlot -> CoordinatedHeadState tx -> tx -> Outcome tx
- onOpenNetworkReqDec :: IsTx tx => Environment -> Ledger tx -> TTL -> OpenState tx -> tx -> Outcome tx
- onOpenChainDepositTx :: IsTx tx => HeadId -> Environment -> OpenState tx -> UTxOType tx -> TxIdType tx -> UTCTime -> Outcome tx
- onOpenChainRecoverTx :: IsTx tx => HeadId -> OpenState tx -> TxIdType tx -> Outcome tx
- onOpenChainIncrementTx :: OpenState tx -> SnapshotVersion -> TxIdType tx -> Outcome tx
- onOpenChainDecrementTx :: IsTx tx => OpenState tx -> SnapshotVersion -> [TxOutType tx] -> Outcome tx
- onOpenClientClose :: OpenState tx -> Outcome tx
- onOpenChainCloseTx :: OpenState tx -> ChainStateType tx -> SnapshotNumber -> UTCTime -> Outcome tx
- onClosedChainContestTx :: ClosedState tx -> ChainStateType tx -> SnapshotNumber -> UTCTime -> Outcome tx
- onClosedClientFanout :: Monoid (UTxOType tx) => ClosedState tx -> Outcome tx
- onClosedChainFanoutTx :: ClosedState tx -> ChainStateType tx -> Outcome tx
- data Input tx
- = ClientInput {
- clientInput :: ClientInput tx
- | NetworkInput {
- ttl :: TTL
- networkEvent :: NetworkEvent (Message tx)
- | ChainInput {
- chainEvent :: ChainEvent tx
- = ClientInput {
- type TTL = Natural
- data LogicError tx
- = UnhandledInput {
- input :: Input tx
- currentHeadState :: HeadState tx
- | RequireFailed { }
- | AssertionFailed { }
- | NotOurHead {
- ourHeadId :: HeadId
- otherHeadId :: HeadId
- = UnhandledInput {
- data RequirementFailure tx
- = ReqSnNumberInvalid {
- requestedSn :: SnapshotNumber
- lastSeenSn :: SnapshotNumber
- | ReqSvNumberInvalid {
- requestedSv :: SnapshotVersion
- lastSeenSv :: SnapshotVersion
- | ReqSnNotLeader {
- requestedSn :: SnapshotNumber
- leader :: Party
- | ReqSnDecommitNotSettled
- | ReqSnCommitNotSettled
- | InvalidMultisignature { }
- | SnapshotAlreadySigned {
- knownSignatures :: [Party]
- receivedSignature :: Party
- | AckSnNumberInvalid {
- requestedSn :: SnapshotNumber
- lastSeenSn :: SnapshotNumber
- | SnapshotDoesNotApply {
- requestedSn :: SnapshotNumber
- txid :: TxIdType tx
- error :: ValidationError
- | RecoverNotMatchingDeposit
- = ReqSnNumberInvalid {
- data HeadState tx
- = Idle (IdleState tx)
- | Initial (InitialState tx)
- | Open (OpenState tx)
- | Closed (ClosedState tx)
- data ClosedState tx = ClosedState {
- parameters :: HeadParameters
- confirmedSnapshot :: ConfirmedSnapshot tx
- contestationDeadline :: UTCTime
- readyToFanoutSent :: Bool
- chainState :: ChainStateType tx
- headId :: HeadId
- headSeed :: HeadSeed
- version :: SnapshotVersion
- type Committed tx = Map Party (UTxOType tx)
- data CoordinatedHeadState tx = CoordinatedHeadState {
- localUTxO :: UTxOType tx
- localTxs :: [tx]
- allTxs :: Map (TxIdType tx) tx
- confirmedSnapshot :: ConfirmedSnapshot tx
- seenSnapshot :: SeenSnapshot tx
- pendingDeposits :: Map (TxIdType tx) (UTxOType tx)
- decommitTx :: Maybe tx
- version :: SnapshotVersion
- newtype IdleState tx = IdleState {
- chainState :: ChainStateType tx
- data InitialState tx = InitialState {
- parameters :: HeadParameters
- pendingCommits :: PendingCommits
- committed :: Committed tx
- chainState :: ChainStateType tx
- headId :: HeadId
- headSeed :: HeadSeed
- data OpenState tx = OpenState {
- parameters :: HeadParameters
- coordinatedHeadState :: CoordinatedHeadState tx
- chainState :: ChainStateType tx
- headId :: HeadId
- currentSlot :: ChainSlot
- headSeed :: HeadSeed
- type PendingCommits = Set Party
- data SeenSnapshot tx
- = NoSeenSnapshot
- | LastSeenSnapshot {
- lastSeen :: SnapshotNumber
- | RequestedSnapshot { }
- | SeenSnapshot {
- snapshot :: Snapshot tx
- signatories :: Map Party (Signature (Snapshot tx))
- seenSnapshotNumber :: SeenSnapshot tx -> SnapshotNumber
- setChainState :: ChainStateType tx -> HeadState tx -> HeadState tx
- data Effect tx
- = ClientEffect {
- serverOutput :: ServerOutput tx
- | NetworkEffect { }
- | OnChainEffect {
- postChainTx :: PostChainTx tx
- = ClientEffect {
- data StateChanged tx
- = HeadInitialized {
- parameters :: HeadParameters
- chainState :: ChainStateType tx
- headId :: HeadId
- headSeed :: HeadSeed
- | CommittedUTxO {
- party :: Party
- committedUTxO :: UTxOType tx
- chainState :: ChainStateType tx
- | HeadAborted {
- chainState :: ChainStateType tx
- | HeadOpened {
- chainState :: ChainStateType tx
- initialUTxO :: UTxOType tx
- | TransactionReceived {
- tx :: tx
- | TransactionAppliedToLocalUTxO {
- tx :: tx
- newLocalUTxO :: UTxOType tx
- | CommitRecorded {
- pendingDeposits :: Map (TxIdType tx) (UTxOType tx)
- newLocalUTxO :: UTxOType tx
- | CommitRecovered {
- recoveredUTxO :: UTxOType tx
- newLocalUTxO :: UTxOType tx
- recoveredTxId :: TxIdType tx
- | DecommitRecorded {
- decommitTx :: tx
- newLocalUTxO :: UTxOType tx
- | SnapshotRequestDecided {
- snapshotNumber :: SnapshotNumber
- | SnapshotRequested {
- snapshot :: Snapshot tx
- requestedTxIds :: [TxIdType tx]
- newLocalUTxO :: UTxOType tx
- newLocalTxs :: [tx]
- | CommitFinalized {
- newVersion :: SnapshotVersion
- depositTxId :: TxIdType tx
- | DecommitFinalized {
- newVersion :: SnapshotVersion
- | PartySignedSnapshot { }
- | SnapshotConfirmed {
- snapshot :: Snapshot tx
- signatures :: MultiSignature (Snapshot tx)
- | HeadClosed {
- chainState :: ChainStateType tx
- contestationDeadline :: UTCTime
- | HeadContested {
- chainState :: ChainStateType tx
- contestationDeadline :: UTCTime
- | HeadIsReadyToFanout
- | HeadFannedOut {
- chainState :: ChainStateType tx
- | ChainRolledBack {
- chainState :: ChainStateType tx
- | TickObserved {
- chainSlot :: ChainSlot
- = HeadInitialized {
- data Outcome tx
- = Continue {
- stateChanges :: [StateChanged tx]
- effects :: [Effect tx]
- | Wait {
- reason :: WaitReason tx
- stateChanges :: [StateChanged tx]
- | Error {
- error :: LogicError tx
- = Continue {
- data WaitReason tx
- = WaitOnNotApplicableTx { }
- | WaitOnSnapshotNumber {
- waitingForNumber :: SnapshotNumber
- | WaitOnSnapshotVersion {
- waitingForVersion :: SnapshotVersion
- | WaitOnSeenSnapshot
- | WaitOnTxs {
- waitingForTxIds :: [TxIdType tx]
- | WaitOnContestationDeadline
- | WaitOnNotApplicableDecommitTx { }
- | WaitOnUnresolvedCommit {
- commitUTxO :: UTxOType tx
- | WaitOnUnresolvedDecommit {
- decommitTx :: tx
- wait :: WaitReason tx -> Outcome tx
- cause :: Effect tx -> Outcome tx
- causes :: [Effect tx] -> Outcome tx
- newState :: StateChanged tx -> Outcome tx
- noop :: Outcome tx
Documentation
:: IsChainState tx | |
=> Environment | |
-> Ledger tx | |
-> HeadState tx | Current HeadState to validate the command against. |
-> Input tx | Input to be processed. |
-> Outcome tx |
Handles inputs and converts them into StateChanged
events along with
Effect
s, in case it is processed succesfully. Later, the Node will
aggregate
the events, resulting in a new HeadState
.
defaultTTL :: TTL Source #
recoverChainStateHistory :: (Foldable t, IsChainState tx) => ChainStateType tx -> t (StateChanged tx) -> ChainStateHistory tx Source #
recoverState :: (Foldable t, IsChainState tx) => HeadState tx -> t (StateChanged tx) -> HeadState tx Source #
aggregate :: IsChainState tx => HeadState tx -> StateChanged tx -> HeadState tx Source #
Reflect StateChanged
events onto the HeadState
aggregate.
onConnectionEvent :: Connectivity -> Outcome tx Source #
onIdleClientInit :: Environment -> Outcome tx Source #
:: Environment | |
-> ChainStateType tx | New chain state. |
-> HeadId | |
-> HeadSeed | |
-> HeadParameters | |
-> [OnChainId] | |
-> Outcome tx |
Observe an init transaction, initialize parameters in an InitialState
and
notify clients that they can now commit.
Transition: IdleState
→ InitialState
onInitialChainCommitTx Source #
:: Monoid (UTxOType tx) | |
=> InitialState tx | |
-> ChainStateType tx | New chain state |
-> Party | Comitting party |
-> UTxOType tx | Committed UTxO |
-> Outcome tx |
Observe a commit transaction and record the committed UTxO in the state. Also, if this is the last commit to be observed, post a collect-com transaction on-chain.
Transition: InitialState
→ InitialState
onInitialClientAbort :: Monoid (UTxOType tx) => InitialState tx -> Outcome tx Source #
Client request to abort the head. This leads to an abort transaction on chain, reimbursing already committed UTxOs.
Transition: InitialState
→ InitialState
onInitialChainAbortTx Source #
Observe an abort transaction by switching the state and notifying clients about it.
Transition: InitialState
→ IdleState
onInitialChainCollectTx Source #
:: IsChainState tx | |
=> InitialState tx | |
-> ChainStateType tx | New chain state |
-> Outcome tx |
Observe a collectCom transaction. We initialize the OpenState
using the
head parameters from IdleState
and construct an InitialSnapshot
holding
u0
from the committed UTxOs.
Transition: InitialState
→ OpenState
:: tx | The transaction to be submitted to the head. |
-> Outcome tx |
:: IsTx tx | |
=> Environment | |
-> Ledger tx | |
-> OpenState tx | |
-> TTL | |
-> tx | The transaction to be submitted to the head. |
-> Outcome tx |
Process a transaction request (ReqTx
) from a party.
We apply this transaction to the seen utxo (ledger state). If not applicable,
we wait and retry later. If it applies, this yields an updated seen ledger
state. Then, we check whether we are the leader for the next snapshot and
emit a snapshot request ReqSn
including this transaction if needed.
:: IsTx tx | |
=> Environment | |
-> Ledger tx | |
-> OpenState tx | |
-> Party | Party which sent the ReqSn. |
-> SnapshotVersion | Requested snapshot version. |
-> SnapshotNumber | Requested snapshot number. |
-> [TxIdType tx] | List of transactions to snapshot. |
-> Maybe tx | Optional decommit transaction of removing funds from the head. |
-> Maybe (UTxOType tx) | |
-> Outcome tx |
Process a snapshot request (ReqSn
) from party.
This checks that s is the next snapshot number and that the party is
responsible for leading that snapshot. Then, we potentially wait until the
previous snapshot is confirmed (no snapshot is in flight), before we apply
(or wait until applicable) the requested transactions to the last confirmed
snapshot. Only then, we start tracking this new "seen" snapshot, compute a
signature of it and send the corresponding AckSn
to all parties. Finally,
the pending transaction set gets pruned to only contain still applicable
transactions.
:: IsTx tx | |
=> Environment | |
-> OpenState tx | |
-> Party | Party which sent the AckSn. |
-> Signature (Snapshot tx) | Signature from other party. |
-> SnapshotNumber | Snapshot number of this AckSn. |
-> Outcome tx |
Process a snapshot acknowledgement (AckSn
) from a party.
We do require that the is from the last seen or next expected snapshot, and
potentially wait wait for the corresponding ReqSn
before proceeding. If the
party hasn't sent us a signature yet, we store it. Once a signature from each
party has been collected, we aggregate a multi-signature and verify it is
correct. If everything is fine, the snapshot can be considered as the latest
confirmed one. Similar to processing a ReqTx
, we check whether we are
leading the next snapshot and craft a corresponding ReqSn
if needed.
onOpenClientRecover :: IsTx tx => HeadId -> ChainSlot -> CoordinatedHeadState tx -> TxIdType tx -> Outcome tx Source #
:: IsTx tx | |
=> HeadId | |
-> Ledger tx | |
-> ChainSlot | |
-> CoordinatedHeadState tx | |
-> tx | Decommit transaction. |
-> Outcome tx |
onOpenNetworkReqDec :: IsTx tx => Environment -> Ledger tx -> TTL -> OpenState tx -> tx -> Outcome tx Source #
Process the request ReqDec
to decommit something from the Open head.
Transition: OpenState
→ OpenState
When node receives ReqDec
network message it should:
- Check there is no decommit in flight:
- Alter it's state to record what is to be decommitted
- Issue a server output DecommitRequested
with the relevant utxo
- Issue a ReqSn
since all parties need to agree in order for decommit to
be taken out of a Head.
- Check if we are the leader
onOpenChainRecoverTx :: IsTx tx => HeadId -> OpenState tx -> TxIdType tx -> Outcome tx Source #
onOpenChainIncrementTx Source #
Observe a increment transaction. If the outputs match the ones of the
pending commit UTxO, then we consider the deposit/increment finalized, and remove the
increment UTxO from StateChanged
from the local state.
onOpenClientClose :: OpenState tx -> Outcome tx Source #
:: OpenState tx | |
-> ChainStateType tx | New chain state. |
-> SnapshotNumber | Closed snapshot number. |
-> UTCTime | Contestation deadline. |
-> Outcome tx |
Observe a close transaction. If the closed snapshot number is smaller than our last confirmed, we post a contest transaction. Also, we do schedule a notification for clients to fanout at the deadline.
Transition: OpenState
→ ClosedState
onClosedChainContestTx Source #
:: ClosedState tx | |
-> ChainStateType tx | New chain state. |
-> SnapshotNumber | |
-> UTCTime | Contestation deadline. |
-> Outcome tx |
Observe a contest transaction. If the contested snapshot number is smaller than our last confirmed snapshot, we post a contest transaction.
Transition: ClosedState
→ ClosedState
onClosedClientFanout :: Monoid (UTxOType tx) => ClosedState tx -> Outcome tx Source #
Client request to fanout leads to a fanout transaction on chain using the
latest confirmed snapshot from ClosedState
.
Transition: ClosedState
→ ClosedState
onClosedChainFanoutTx Source #
:: ClosedState tx | |
-> ChainStateType tx | New chain state |
-> Outcome tx |
Observe a fanout transaction by finalize the head state and notifying clients about it.
Transition: ClosedState
→ IdleState
Inputs that are processed by the head logic (the "core"). Corresponding to each of the "shell" layers, we distinguish between inputs from the client, the network and the chain.
ClientInput | Input received from clients via the Hydra.API. |
| |
NetworkInput | Input received from peers via a Hydra.Network.
|
| |
ChainInput | Input received from the chain via a Hydra.Chain. |
|
Instances
(ArbitraryIsTx tx, IsChainState tx) => Arbitrary (Input tx) Source # | |
IsChainState tx => FromJSON (Input tx) Source # | |
Defined in Hydra.HeadLogic.Input parseJSON :: Value -> Parser (Input tx) parseJSONList :: Value -> Parser [Input tx] omittedField :: Maybe (Input tx) | |
IsChainState tx => ToJSON (Input tx) Source # | |
Defined in Hydra.HeadLogic.Input toEncoding :: Input tx -> Encoding toJSONList :: [Input tx] -> Value toEncodingList :: [Input tx] -> Encoding | |
Generic (Input tx) Source # | |
IsChainState tx => Show (Input tx) Source # | |
IsChainState tx => Eq (Input tx) Source # | |
type Rep (Input tx) Source # | |
Defined in Hydra.HeadLogic.Input type Rep (Input tx) = D1 ('MetaData "Input" "Hydra.HeadLogic.Input" "hydra-node-0.20.0-5pXAEiXeWsXH8K4KfwlMxW" 'False) (C1 ('MetaCons "ClientInput" 'PrefixI 'True) (S1 ('MetaSel ('Just "clientInput") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (ClientInput tx))) :+: (C1 ('MetaCons "NetworkInput" 'PrefixI 'True) (S1 ('MetaSel ('Just "ttl") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 TTL) :*: S1 ('MetaSel ('Just "networkEvent") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (NetworkEvent (Message tx)))) :+: C1 ('MetaCons "ChainInput" 'PrefixI 'True) (S1 ('MetaSel ('Just "chainEvent") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (ChainEvent tx))))) |
data LogicError tx Source #
UnhandledInput | |
| |
RequireFailed | |
AssertionFailed | |
NotOurHead | |
|
Instances
data RequirementFailure tx Source #
ReqSnNumberInvalid | |
| |
ReqSvNumberInvalid | |
| |
ReqSnNotLeader | |
| |
ReqSnDecommitNotSettled | |
ReqSnCommitNotSettled | |
InvalidMultisignature | |
SnapshotAlreadySigned | |
| |
AckSnNumberInvalid | |
| |
SnapshotDoesNotApply | |
| |
RecoverNotMatchingDeposit |
Instances
The main state of the Hydra protocol state machine. It holds both, the
overall protocol state, but also the off-chain CoordinatedHeadState
.
Each of the sub-types (InitialState, OpenState, etc.) contain a black-box
IdleState
corresponding to the ChainEvent
that has been observed leading
to the state.
Note that rollbacks are currently not fully handled in the head logic and only this internal chain state gets replaced with the "rolled back to" version.
TODO: chainState would actualy not be needed in the HeadState anymore as we
do not persist the HeadState
and not access it in the HeadLogic either.
Idle (IdleState tx) | |
Initial (InitialState tx) | |
Open (OpenState tx) | |
Closed (ClosedState tx) |
Instances
data ClosedState tx Source #
An Closed
head with an current candidate ConfirmedSnapshot
, which may
be contested before the $sel:contestationDeadline:ClosedState
.
ClosedState | |
|
Instances
data CoordinatedHeadState tx Source #
Off-chain state of the Coordinated Head protocol.
CoordinatedHeadState | |
|
Instances
An Idle
head only having a chain state with things seen on chain so far.
IdleState | |
|
Instances
Arbitrary (ChainStateType tx) => Arbitrary (IdleState tx) Source # | |
FromJSON (ChainStateType tx) => FromJSON (IdleState tx) Source # | |
Defined in Hydra.HeadLogic.State parseJSON :: Value -> Parser (IdleState tx) parseJSONList :: Value -> Parser [IdleState tx] omittedField :: Maybe (IdleState tx) | |
ToJSON (ChainStateType tx) => ToJSON (IdleState tx) Source # | |
Defined in Hydra.HeadLogic.State toJSON :: IdleState tx -> Value toEncoding :: IdleState tx -> Encoding toJSONList :: [IdleState tx] -> Value toEncodingList :: [IdleState tx] -> Encoding | |
Generic (IdleState tx) Source # | |
Show (ChainStateType tx) => Show (IdleState tx) Source # | |
Eq (ChainStateType tx) => Eq (IdleState tx) Source # | |
type Rep (IdleState tx) Source # | |
Defined in Hydra.HeadLogic.State |
data InitialState tx Source #
An Initial
head which already has an identity and is collecting commits.
InitialState | |
|
Instances
An Open
head with a CoordinatedHeadState
tracking off-chain
transactions.
OpenState | |
|
Instances
(ArbitraryIsTx tx, Arbitrary (ChainStateType tx)) => Arbitrary (OpenState tx) Source # | |
(IsTx tx, FromJSON (ChainStateType tx)) => FromJSON (OpenState tx) Source # | |
Defined in Hydra.HeadLogic.State parseJSON :: Value -> Parser (OpenState tx) parseJSONList :: Value -> Parser [OpenState tx] omittedField :: Maybe (OpenState tx) | |
(IsTx tx, ToJSON (ChainStateType tx)) => ToJSON (OpenState tx) Source # | |
Defined in Hydra.HeadLogic.State toJSON :: OpenState tx -> Value toEncoding :: OpenState tx -> Encoding toJSONList :: [OpenState tx] -> Value toEncodingList :: [OpenState tx] -> Encoding | |
Generic (OpenState tx) Source # | |
(IsTx tx, Show (ChainStateType tx)) => Show (OpenState tx) Source # | |
(IsTx tx, Eq (ChainStateType tx)) => Eq (OpenState tx) Source # | |
type Rep (OpenState tx) Source # | |
Defined in Hydra.HeadLogic.State type Rep (OpenState tx) = D1 ('MetaData "OpenState" "Hydra.HeadLogic.State" "hydra-node-0.20.0-5pXAEiXeWsXH8K4KfwlMxW" 'False) (C1 ('MetaCons "OpenState" 'PrefixI 'True) ((S1 ('MetaSel ('Just "parameters") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 HeadParameters) :*: (S1 ('MetaSel ('Just "coordinatedHeadState") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (CoordinatedHeadState tx)) :*: S1 ('MetaSel ('Just "chainState") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (ChainStateType tx)))) :*: (S1 ('MetaSel ('Just "headId") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 HeadId) :*: (S1 ('MetaSel ('Just "currentSlot") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 ChainSlot) :*: S1 ('MetaSel ('Just "headSeed") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 HeadSeed))))) |
type PendingCommits = Set Party Source #
data SeenSnapshot tx Source #
Data structure to help in tracking whether we have seen or requested a ReqSn already and if seen, the signatures we collected already.
NoSeenSnapshot | Never saw a ReqSn. |
LastSeenSnapshot | No snapshot in flight with last seen snapshot number as given. |
| |
RequestedSnapshot | ReqSn was sent out and it should be considered already in flight. |
SeenSnapshot | ReqSn for given snapshot was received. |
|
Instances
seenSnapshotNumber :: SeenSnapshot tx -> SnapshotNumber Source #
Get the last seen snapshot number given a SeenSnapshot
.
setChainState :: ChainStateType tx -> HeadState tx -> HeadState tx Source #
Update the chain state in any HeadState
.
Analogous to inputs, the pure head logic "core" can have effects emited to the "shell" layers and we distinguish the same: effects onto the client, the network and the chain.
ClientEffect | Effect to be handled by the Hydra.API, results in sending this |
| |
NetworkEffect | Effect to be handled by a Hydra.Network, results in a |
OnChainEffect | Effect to be handled by a Hydra.Chain, results in a |
|
Instances
(ArbitraryIsTx tx, IsChainState tx) => Arbitrary (Effect tx) Source # | |
IsChainState tx => FromJSON (Effect tx) Source # | |
Defined in Hydra.HeadLogic.Outcome parseJSON :: Value -> Parser (Effect tx) parseJSONList :: Value -> Parser [Effect tx] omittedField :: Maybe (Effect tx) | |
IsChainState tx => ToJSON (Effect tx) Source # | |
Defined in Hydra.HeadLogic.Outcome toEncoding :: Effect tx -> Encoding toJSONList :: [Effect tx] -> Value toEncodingList :: [Effect tx] -> Encoding | |
Generic (Effect tx) Source # | |
IsChainState tx => Show (Effect tx) Source # | |
IsChainState tx => Eq (Effect tx) Source # | |
type Rep (Effect tx) Source # | |
Defined in Hydra.HeadLogic.Outcome type Rep (Effect tx) = D1 ('MetaData "Effect" "Hydra.HeadLogic.Outcome" "hydra-node-0.20.0-5pXAEiXeWsXH8K4KfwlMxW" 'False) (C1 ('MetaCons "ClientEffect" 'PrefixI 'True) (S1 ('MetaSel ('Just "serverOutput") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (ServerOutput tx))) :+: (C1 ('MetaCons "NetworkEffect" 'PrefixI 'True) (S1 ('MetaSel ('Just "message") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Message tx))) :+: C1 ('MetaCons "OnChainEffect" 'PrefixI 'True) (S1 ('MetaSel ('Just "postChainTx") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (PostChainTx tx))))) |
data StateChanged tx Source #
Head state changed event. These events represent all the internal state changes, get persisted and processed in an event sourcing manner.
HeadInitialized | |
| |
CommittedUTxO | |
| |
HeadAborted | |
| |
HeadOpened | |
| |
TransactionReceived | |
| |
TransactionAppliedToLocalUTxO | |
| |
CommitRecorded | |
| |
CommitRecovered | |
| |
DecommitRecorded | |
| |
SnapshotRequestDecided | |
| |
SnapshotRequested | 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. |
| |
CommitFinalized | |
| |
DecommitFinalized | |
| |
PartySignedSnapshot | |
SnapshotConfirmed | |
| |
HeadClosed | |
| |
HeadContested | |
| |
HeadIsReadyToFanout | |
HeadFannedOut | |
| |
ChainRolledBack | |
| |
TickObserved | |
|
Instances
Continue | Continue with the given state updates and side effects. |
| |
Wait | Wait for some condition to be met with optional state updates. |
| |
Error | Processing resulted in an error. |
|
Instances
data WaitReason tx Source #
WaitOnNotApplicableTx | |
WaitOnSnapshotNumber | |
| |
WaitOnSnapshotVersion | |
| |
WaitOnSeenSnapshot | |
WaitOnTxs | |
| |
WaitOnContestationDeadline | |
WaitOnNotApplicableDecommitTx | |
WaitOnUnresolvedCommit | |
| |
WaitOnUnresolvedDecommit | |
|
Instances
wait :: WaitReason tx -> Outcome tx Source #
newState :: StateChanged tx -> Outcome tx Source #