{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-ambiguous-fields #-}

module Hydra.HeadLogic.State where

import Hydra.Prelude

import Data.Map qualified as Map
import Hydra.Chain (ChainStateType, HeadParameters)
import Hydra.Crypto (Signature)
import Hydra.HeadId (HeadId, HeadSeed)
import Hydra.Ledger (ChainSlot, IsTx (..))
import Hydra.Party (Party)
import Hydra.Snapshot (ConfirmedSnapshot, Snapshot (..), SnapshotNumber)

-- | 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
-- 'chainState' 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.
data HeadState tx
  = Idle (IdleState tx)
  | Initial (InitialState tx)
  | Open (OpenState tx)
  | Closed (ClosedState tx)
  deriving stock ((forall x. HeadState tx -> Rep (HeadState tx) x)
-> (forall x. Rep (HeadState tx) x -> HeadState tx)
-> Generic (HeadState tx)
forall x. Rep (HeadState tx) x -> HeadState tx
forall x. HeadState tx -> Rep (HeadState tx) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall tx x. Rep (HeadState tx) x -> HeadState tx
forall tx x. HeadState tx -> Rep (HeadState tx) x
$cfrom :: forall tx x. HeadState tx -> Rep (HeadState tx) x
from :: forall x. HeadState tx -> Rep (HeadState tx) x
$cto :: forall tx x. Rep (HeadState tx) x -> HeadState tx
to :: forall x. Rep (HeadState tx) x -> HeadState tx
Generic)

instance (IsTx tx, Arbitrary (ChainStateType tx)) => Arbitrary (HeadState tx) where
  arbitrary :: Gen (HeadState tx)
arbitrary = Gen (HeadState tx)
forall a.
(Generic a, GA UnsizedOpts (Rep a),
 UniformWeight (Weights_ (Rep a))) =>
Gen a
genericArbitrary

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

-- | Update the chain state in any 'HeadState'.
setChainState :: ChainStateType tx -> HeadState tx -> HeadState tx
setChainState :: forall tx. ChainStateType tx -> HeadState tx -> HeadState tx
setChainState ChainStateType tx
chainState = \case
  Idle IdleState tx
st -> IdleState tx -> HeadState tx
forall tx. IdleState tx -> HeadState tx
Idle IdleState tx
st{chainState}
  Initial InitialState tx
st -> InitialState tx -> HeadState tx
forall tx. InitialState tx -> HeadState tx
Initial InitialState tx
st{chainState}
  Open OpenState tx
st -> OpenState tx -> HeadState tx
forall tx. OpenState tx -> HeadState tx
Open OpenState tx
st{chainState}
  Closed ClosedState tx
st -> ClosedState tx -> HeadState tx
forall tx. ClosedState tx -> HeadState tx
Closed ClosedState tx
st{chainState}

-- | Get the head parameters in any 'HeadState'.
getHeadParameters :: HeadState tx -> Maybe HeadParameters
getHeadParameters :: forall tx. HeadState tx -> Maybe HeadParameters
getHeadParameters = \case
  Idle IdleState tx
_ -> Maybe HeadParameters
forall a. Maybe a
Nothing
  Initial InitialState{HeadParameters
parameters :: HeadParameters
$sel:parameters:InitialState :: forall tx. InitialState tx -> HeadParameters
parameters} -> HeadParameters -> Maybe HeadParameters
forall a. a -> Maybe a
Just HeadParameters
parameters
  Open OpenState{HeadParameters
parameters :: HeadParameters
$sel:parameters:OpenState :: forall tx. OpenState tx -> HeadParameters
parameters} -> HeadParameters -> Maybe HeadParameters
forall a. a -> Maybe a
Just HeadParameters
parameters
  Closed ClosedState{HeadParameters
parameters :: HeadParameters
$sel:parameters:ClosedState :: forall tx. ClosedState tx -> HeadParameters
parameters} -> HeadParameters -> Maybe HeadParameters
forall a. a -> Maybe a
Just HeadParameters
parameters

-- ** Idle

-- | An 'Idle' head only having a chain state with things seen on chain so far.
newtype IdleState tx = IdleState {forall tx. IdleState tx -> ChainStateType tx
chainState :: ChainStateType tx}
  deriving stock ((forall x. IdleState tx -> Rep (IdleState tx) x)
-> (forall x. Rep (IdleState tx) x -> IdleState tx)
-> Generic (IdleState tx)
forall x. Rep (IdleState tx) x -> IdleState tx
forall x. IdleState tx -> Rep (IdleState tx) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall tx x. Rep (IdleState tx) x -> IdleState tx
forall tx x. IdleState tx -> Rep (IdleState tx) x
$cfrom :: forall tx x. IdleState tx -> Rep (IdleState tx) x
from :: forall x. IdleState tx -> Rep (IdleState tx) x
$cto :: forall tx x. Rep (IdleState tx) x -> IdleState tx
to :: forall x. Rep (IdleState tx) x -> IdleState tx
Generic)

deriving stock instance Eq (ChainStateType tx) => Eq (IdleState tx)
deriving stock instance Show (ChainStateType tx) => Show (IdleState tx)
deriving anyclass instance ToJSON (ChainStateType tx) => ToJSON (IdleState tx)
deriving anyclass instance FromJSON (ChainStateType tx) => FromJSON (IdleState tx)

instance Arbitrary (ChainStateType tx) => Arbitrary (IdleState tx) where
  arbitrary :: Gen (IdleState tx)
arbitrary = Gen (IdleState tx)
forall a.
(Generic a, GA UnsizedOpts (Rep a),
 UniformWeight (Weights_ (Rep a))) =>
Gen a
genericArbitrary

-- ** Initial

-- | An 'Initial' head which already has an identity and is collecting commits.
data InitialState tx = InitialState
  { forall tx. InitialState tx -> HeadParameters
parameters :: HeadParameters
  , forall tx. InitialState tx -> PendingCommits
pendingCommits :: PendingCommits
  , forall tx. InitialState tx -> Committed tx
committed :: Committed tx
  , forall tx. InitialState tx -> ChainStateType tx
chainState :: ChainStateType tx
  , forall tx. InitialState tx -> HeadId
headId :: HeadId
  , forall tx. InitialState tx -> HeadSeed
headSeed :: HeadSeed
  }
  deriving stock ((forall x. InitialState tx -> Rep (InitialState tx) x)
-> (forall x. Rep (InitialState tx) x -> InitialState tx)
-> Generic (InitialState tx)
forall x. Rep (InitialState tx) x -> InitialState tx
forall x. InitialState tx -> Rep (InitialState tx) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall tx x. Rep (InitialState tx) x -> InitialState tx
forall tx x. InitialState tx -> Rep (InitialState tx) x
$cfrom :: forall tx x. InitialState tx -> Rep (InitialState tx) x
from :: forall x. InitialState tx -> Rep (InitialState tx) x
$cto :: forall tx x. Rep (InitialState tx) x -> InitialState tx
to :: forall x. Rep (InitialState tx) x -> InitialState tx
Generic)

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

instance (IsTx tx, Arbitrary (ChainStateType tx)) => Arbitrary (InitialState tx) where
  arbitrary :: Gen (InitialState tx)
arbitrary = do
    HeadParameters
-> PendingCommits
-> Map Party (UTxOType tx)
-> ChainStateType tx
-> HeadId
-> HeadSeed
-> InitialState tx
forall tx.
HeadParameters
-> PendingCommits
-> Committed tx
-> ChainStateType tx
-> HeadId
-> HeadSeed
-> InitialState tx
InitialState
      (HeadParameters
 -> PendingCommits
 -> Map Party (UTxOType tx)
 -> ChainStateType tx
 -> HeadId
 -> HeadSeed
 -> InitialState tx)
-> Gen HeadParameters
-> Gen
     (PendingCommits
      -> Map Party (UTxOType tx)
      -> ChainStateType tx
      -> HeadId
      -> HeadSeed
      -> InitialState tx)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen HeadParameters
forall a. Arbitrary a => Gen a
arbitrary
      Gen
  (PendingCommits
   -> Map Party (UTxOType tx)
   -> ChainStateType tx
   -> HeadId
   -> HeadSeed
   -> InitialState tx)
-> Gen PendingCommits
-> Gen
     (Map Party (UTxOType tx)
      -> ChainStateType tx -> HeadId -> HeadSeed -> InitialState tx)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen PendingCommits
forall a. Arbitrary a => Gen a
arbitrary
      Gen
  (Map Party (UTxOType tx)
   -> ChainStateType tx -> HeadId -> HeadSeed -> InitialState tx)
-> Gen (Map Party (UTxOType tx))
-> Gen (ChainStateType tx -> HeadId -> HeadSeed -> InitialState tx)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen (Map Party (UTxOType tx))
forall a. Arbitrary a => Gen a
arbitrary
      Gen (ChainStateType tx -> HeadId -> HeadSeed -> InitialState tx)
-> Gen (ChainStateType tx)
-> Gen (HeadId -> HeadSeed -> InitialState tx)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen (ChainStateType tx)
forall a. Arbitrary a => Gen a
arbitrary
      Gen (HeadId -> HeadSeed -> InitialState tx)
-> Gen HeadId -> Gen (HeadSeed -> InitialState tx)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen HeadId
forall a. Arbitrary a => Gen a
arbitrary
      Gen (HeadSeed -> InitialState tx)
-> Gen HeadSeed -> Gen (InitialState tx)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen HeadSeed
forall a. Arbitrary a => Gen a
arbitrary

type PendingCommits = Set Party

type Committed tx = Map Party (UTxOType tx)

-- ** Open

-- | An 'Open' head with a 'CoordinatedHeadState' tracking off-chain
-- transactions.
data OpenState tx = OpenState
  { forall tx. OpenState tx -> HeadParameters
parameters :: HeadParameters
  , forall tx. OpenState tx -> CoordinatedHeadState tx
coordinatedHeadState :: CoordinatedHeadState tx
  , forall tx. OpenState tx -> ChainStateType tx
chainState :: ChainStateType tx
  , forall tx. OpenState tx -> HeadId
headId :: HeadId
  , forall tx. OpenState tx -> ChainSlot
currentSlot :: ChainSlot
  , forall tx. OpenState tx -> HeadSeed
headSeed :: HeadSeed
  }
  deriving stock ((forall x. OpenState tx -> Rep (OpenState tx) x)
-> (forall x. Rep (OpenState tx) x -> OpenState tx)
-> Generic (OpenState tx)
forall x. Rep (OpenState tx) x -> OpenState tx
forall x. OpenState tx -> Rep (OpenState tx) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall tx x. Rep (OpenState tx) x -> OpenState tx
forall tx x. OpenState tx -> Rep (OpenState tx) x
$cfrom :: forall tx x. OpenState tx -> Rep (OpenState tx) x
from :: forall x. OpenState tx -> Rep (OpenState tx) x
$cto :: forall tx x. Rep (OpenState tx) x -> OpenState tx
to :: forall x. Rep (OpenState tx) x -> OpenState tx
Generic)

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

instance (IsTx tx, Arbitrary (ChainStateType tx)) => Arbitrary (OpenState tx) where
  arbitrary :: Gen (OpenState tx)
arbitrary =
    HeadParameters
-> CoordinatedHeadState tx
-> ChainStateType tx
-> HeadId
-> ChainSlot
-> HeadSeed
-> OpenState tx
forall tx.
HeadParameters
-> CoordinatedHeadState tx
-> ChainStateType tx
-> HeadId
-> ChainSlot
-> HeadSeed
-> OpenState tx
OpenState
      (HeadParameters
 -> CoordinatedHeadState tx
 -> ChainStateType tx
 -> HeadId
 -> ChainSlot
 -> HeadSeed
 -> OpenState tx)
-> Gen HeadParameters
-> Gen
     (CoordinatedHeadState tx
      -> ChainStateType tx
      -> HeadId
      -> ChainSlot
      -> HeadSeed
      -> OpenState tx)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen HeadParameters
forall a. Arbitrary a => Gen a
arbitrary
      Gen
  (CoordinatedHeadState tx
   -> ChainStateType tx
   -> HeadId
   -> ChainSlot
   -> HeadSeed
   -> OpenState tx)
-> Gen (CoordinatedHeadState tx)
-> Gen
     (ChainStateType tx
      -> HeadId -> ChainSlot -> HeadSeed -> OpenState tx)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen (CoordinatedHeadState tx)
forall a. Arbitrary a => Gen a
arbitrary
      Gen
  (ChainStateType tx
   -> HeadId -> ChainSlot -> HeadSeed -> OpenState tx)
-> Gen (ChainStateType tx)
-> Gen (HeadId -> ChainSlot -> HeadSeed -> OpenState tx)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen (ChainStateType tx)
forall a. Arbitrary a => Gen a
arbitrary
      Gen (HeadId -> ChainSlot -> HeadSeed -> OpenState tx)
-> Gen HeadId -> Gen (ChainSlot -> HeadSeed -> OpenState tx)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen HeadId
forall a. Arbitrary a => Gen a
arbitrary
      Gen (ChainSlot -> HeadSeed -> OpenState tx)
-> Gen ChainSlot -> Gen (HeadSeed -> OpenState tx)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen ChainSlot
forall a. Arbitrary a => Gen a
arbitrary
      Gen (HeadSeed -> OpenState tx)
-> Gen HeadSeed -> Gen (OpenState tx)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen HeadSeed
forall a. Arbitrary a => Gen a
arbitrary

-- | Off-chain state of the Coordinated Head protocol.
data CoordinatedHeadState tx = CoordinatedHeadState
  { forall tx. CoordinatedHeadState tx -> UTxOType tx
localUTxO :: UTxOType tx
  -- ^ The latest UTxO resulting from applying 'localTxs' to
  -- 'confirmedSnapshot'. Spec: L̂
  , forall tx. CoordinatedHeadState tx -> [tx]
localTxs :: [tx]
  -- ^ List of transactions applied locally and pending inclusion in a snapshot. Spec: T̂
  , forall tx. CoordinatedHeadState tx -> Map (TxIdType tx) tx
allTxs :: Map.Map (TxIdType tx) tx
  -- ^ Map containing all the transactions ever seen by this node and not yet
  -- included in a snapshot. Spec: Tall
  , forall tx. CoordinatedHeadState tx -> ConfirmedSnapshot tx
confirmedSnapshot :: ConfirmedSnapshot tx
  -- ^ The latest confirmed snapshot. Spec: U̅, s̅ and σ̅
  , forall tx. CoordinatedHeadState tx -> SeenSnapshot tx
seenSnapshot :: SeenSnapshot tx
  -- ^ Last seen snapshot and signatures accumulator. Spec: Û, ŝ and Σ̂
  }
  deriving stock ((forall x.
 CoordinatedHeadState tx -> Rep (CoordinatedHeadState tx) x)
-> (forall x.
    Rep (CoordinatedHeadState tx) x -> CoordinatedHeadState tx)
-> Generic (CoordinatedHeadState tx)
forall x.
Rep (CoordinatedHeadState tx) x -> CoordinatedHeadState tx
forall x.
CoordinatedHeadState tx -> Rep (CoordinatedHeadState tx) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall tx x.
Rep (CoordinatedHeadState tx) x -> CoordinatedHeadState tx
forall tx x.
CoordinatedHeadState tx -> Rep (CoordinatedHeadState tx) x
$cfrom :: forall tx x.
CoordinatedHeadState tx -> Rep (CoordinatedHeadState tx) x
from :: forall x.
CoordinatedHeadState tx -> Rep (CoordinatedHeadState tx) x
$cto :: forall tx x.
Rep (CoordinatedHeadState tx) x -> CoordinatedHeadState tx
to :: forall x.
Rep (CoordinatedHeadState tx) x -> CoordinatedHeadState tx
Generic)

deriving stock instance IsTx tx => Eq (CoordinatedHeadState tx)
deriving stock instance IsTx tx => Show (CoordinatedHeadState tx)
deriving anyclass instance IsTx tx => ToJSON (CoordinatedHeadState tx)
deriving anyclass instance IsTx tx => FromJSON (CoordinatedHeadState tx)

instance IsTx tx => Arbitrary (CoordinatedHeadState tx) where
  arbitrary :: Gen (CoordinatedHeadState tx)
arbitrary = Gen (CoordinatedHeadState tx)
forall a.
(Generic a, GA UnsizedOpts (Rep a),
 UniformWeight (Weights_ (Rep a))) =>
Gen a
genericArbitrary

-- | Data structure to help in tracking whether we have seen or requested a
-- ReqSn already and if seen, the signatures we collected already.
data SeenSnapshot tx
  = -- | Never saw a ReqSn.
    NoSeenSnapshot
  | -- | No snapshot in flight with last seen snapshot number as given.
    LastSeenSnapshot {forall tx. SeenSnapshot tx -> SnapshotNumber
lastSeen :: SnapshotNumber}
  | -- | ReqSn was sent out and it should be considered already in flight.
    RequestedSnapshot
      { lastSeen :: SnapshotNumber
      , forall tx. SeenSnapshot tx -> SnapshotNumber
requested :: SnapshotNumber
      }
  | -- | ReqSn for given snapshot was received.
    SeenSnapshot
      { forall tx. SeenSnapshot tx -> Snapshot tx
snapshot :: Snapshot tx
      , forall tx. SeenSnapshot tx -> Map Party (Signature (Snapshot tx))
signatories :: Map Party (Signature (Snapshot tx))
      -- ^ Collected signatures and so far.
      }
  deriving stock ((forall x. SeenSnapshot tx -> Rep (SeenSnapshot tx) x)
-> (forall x. Rep (SeenSnapshot tx) x -> SeenSnapshot tx)
-> Generic (SeenSnapshot tx)
forall x. Rep (SeenSnapshot tx) x -> SeenSnapshot tx
forall x. SeenSnapshot tx -> Rep (SeenSnapshot tx) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall tx x. Rep (SeenSnapshot tx) x -> SeenSnapshot tx
forall tx x. SeenSnapshot tx -> Rep (SeenSnapshot tx) x
$cfrom :: forall tx x. SeenSnapshot tx -> Rep (SeenSnapshot tx) x
from :: forall x. SeenSnapshot tx -> Rep (SeenSnapshot tx) x
$cto :: forall tx x. Rep (SeenSnapshot tx) x -> SeenSnapshot tx
to :: forall x. Rep (SeenSnapshot tx) x -> SeenSnapshot tx
Generic)

instance IsTx tx => Arbitrary (SeenSnapshot tx) where
  arbitrary :: Gen (SeenSnapshot tx)
arbitrary = Gen (SeenSnapshot tx)
forall a.
(Generic a, GA UnsizedOpts (Rep a),
 UniformWeight (Weights_ (Rep a))) =>
Gen a
genericArbitrary

deriving stock instance IsTx tx => Eq (SeenSnapshot tx)
deriving stock instance IsTx tx => Show (SeenSnapshot tx)
deriving anyclass instance IsTx tx => ToJSON (SeenSnapshot tx)
deriving anyclass instance IsTx tx => FromJSON (SeenSnapshot tx)

-- | Get the last seen snapshot number given a 'SeenSnapshot'.
seenSnapshotNumber :: SeenSnapshot tx -> SnapshotNumber
seenSnapshotNumber :: forall tx. SeenSnapshot tx -> SnapshotNumber
seenSnapshotNumber = \case
  SeenSnapshot tx
NoSeenSnapshot -> SnapshotNumber
0
  LastSeenSnapshot{SnapshotNumber
$sel:lastSeen:NoSeenSnapshot :: forall tx. SeenSnapshot tx -> SnapshotNumber
lastSeen :: SnapshotNumber
lastSeen} -> SnapshotNumber
lastSeen
  RequestedSnapshot{SnapshotNumber
$sel:lastSeen:NoSeenSnapshot :: forall tx. SeenSnapshot tx -> SnapshotNumber
lastSeen :: SnapshotNumber
lastSeen} -> SnapshotNumber
lastSeen
  SeenSnapshot{$sel:snapshot:NoSeenSnapshot :: forall tx. SeenSnapshot tx -> Snapshot tx
snapshot = Snapshot{SnapshotNumber
number :: SnapshotNumber
$sel:number:Snapshot :: forall tx. Snapshot tx -> SnapshotNumber
number}} -> SnapshotNumber
number

-- ** Closed

-- | An 'Closed' head with an current candidate 'ConfirmedSnapshot', which may
-- be contested before the 'contestationDeadline'.
data ClosedState tx = ClosedState
  { forall tx. ClosedState tx -> HeadParameters
parameters :: HeadParameters
  , forall tx. ClosedState tx -> ConfirmedSnapshot tx
confirmedSnapshot :: ConfirmedSnapshot tx
  , forall tx. ClosedState tx -> UTCTime
contestationDeadline :: UTCTime
  , forall tx. ClosedState tx -> Bool
readyToFanoutSent :: Bool
  -- ^ Tracks whether we have informed clients already about being
  -- 'ReadyToFanout'.
  , forall tx. ClosedState tx -> ChainStateType tx
chainState :: ChainStateType tx
  , forall tx. ClosedState tx -> HeadId
headId :: HeadId
  , forall tx. ClosedState tx -> HeadSeed
headSeed :: HeadSeed
  }
  deriving stock ((forall x. ClosedState tx -> Rep (ClosedState tx) x)
-> (forall x. Rep (ClosedState tx) x -> ClosedState tx)
-> Generic (ClosedState tx)
forall x. Rep (ClosedState tx) x -> ClosedState tx
forall x. ClosedState tx -> Rep (ClosedState tx) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall tx x. Rep (ClosedState tx) x -> ClosedState tx
forall tx x. ClosedState tx -> Rep (ClosedState tx) x
$cfrom :: forall tx x. ClosedState tx -> Rep (ClosedState tx) x
from :: forall x. ClosedState tx -> Rep (ClosedState tx) x
$cto :: forall tx x. Rep (ClosedState tx) x -> ClosedState tx
to :: forall x. Rep (ClosedState tx) x -> ClosedState tx
Generic)

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

instance (IsTx tx, Arbitrary (ChainStateType tx)) => Arbitrary (ClosedState tx) where
  arbitrary :: Gen (ClosedState tx)
arbitrary =
    HeadParameters
-> ConfirmedSnapshot tx
-> UTCTime
-> Bool
-> ChainStateType tx
-> HeadId
-> HeadSeed
-> ClosedState tx
forall tx.
HeadParameters
-> ConfirmedSnapshot tx
-> UTCTime
-> Bool
-> ChainStateType tx
-> HeadId
-> HeadSeed
-> ClosedState tx
ClosedState
      (HeadParameters
 -> ConfirmedSnapshot tx
 -> UTCTime
 -> Bool
 -> ChainStateType tx
 -> HeadId
 -> HeadSeed
 -> ClosedState tx)
-> Gen HeadParameters
-> Gen
     (ConfirmedSnapshot tx
      -> UTCTime
      -> Bool
      -> ChainStateType tx
      -> HeadId
      -> HeadSeed
      -> ClosedState tx)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen HeadParameters
forall a. Arbitrary a => Gen a
arbitrary
      Gen
  (ConfirmedSnapshot tx
   -> UTCTime
   -> Bool
   -> ChainStateType tx
   -> HeadId
   -> HeadSeed
   -> ClosedState tx)
-> Gen (ConfirmedSnapshot tx)
-> Gen
     (UTCTime
      -> Bool
      -> ChainStateType tx
      -> HeadId
      -> HeadSeed
      -> ClosedState tx)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen (ConfirmedSnapshot tx)
forall a. Arbitrary a => Gen a
arbitrary
      Gen
  (UTCTime
   -> Bool
   -> ChainStateType tx
   -> HeadId
   -> HeadSeed
   -> ClosedState tx)
-> Gen UTCTime
-> Gen
     (Bool -> ChainStateType tx -> HeadId -> HeadSeed -> ClosedState tx)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen UTCTime
forall a. Arbitrary a => Gen a
arbitrary
      Gen
  (Bool -> ChainStateType tx -> HeadId -> HeadSeed -> ClosedState tx)
-> Gen Bool
-> Gen (ChainStateType tx -> HeadId -> HeadSeed -> ClosedState tx)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen Bool
forall a. Arbitrary a => Gen a
arbitrary
      Gen (ChainStateType tx -> HeadId -> HeadSeed -> ClosedState tx)
-> Gen (ChainStateType tx)
-> Gen (HeadId -> HeadSeed -> ClosedState tx)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen (ChainStateType tx)
forall a. Arbitrary a => Gen a
arbitrary
      Gen (HeadId -> HeadSeed -> ClosedState tx)
-> Gen HeadId -> Gen (HeadSeed -> ClosedState tx)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen HeadId
forall a. Arbitrary a => Gen a
arbitrary
      Gen (HeadSeed -> ClosedState tx)
-> Gen HeadSeed -> Gen (ClosedState tx)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen HeadSeed
forall a. Arbitrary a => Gen a
arbitrary