{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -fno-specialize #-}

module Hydra.Contract.HeadState where

import PlutusTx.Prelude

import GHC.Generics (Generic)
import Hydra.Data.ContestationPeriod (ContestationPeriod)
import Hydra.Data.DepositPeriod (DepositPeriod)
import Hydra.Data.Party (Party)
import PlutusLedgerApi.V3 (CurrencySymbol, POSIXTime, PubKeyHash, TxOutRef)
import PlutusTx qualified
import Text.Show (Show)

type SnapshotNumber = Integer

type SnapshotVersion = Integer

type Hash = BuiltinByteString

type Signature = BuiltinByteString

-- | Sub-type for the open state-machine state.
data OpenDatum = OpenDatum
  { OpenDatum -> TxOutRef
headSeed :: TxOutRef
  -- ^ TODO: Spec?
  , OpenDatum -> CurrencySymbol
headId :: CurrencySymbol
  -- ^ Spec: cid
  , OpenDatum -> [Party]
parties :: [Party]
  -- ^ Spec: kH
  , OpenDatum -> ContestationPeriod
contestationPeriod :: ContestationPeriod
  -- ^ Spec: T
  , OpenDatum -> DepositPeriod
depositPeriod :: DepositPeriod
  -- ^ Must match the --deposit-period of all participating nodes.
  , OpenDatum -> SnapshotVersion
version :: SnapshotVersion
  -- ^ Spec: v
  , OpenDatum -> Hash
accumulatorHash :: Hash
  -- ^ Digest of the accumulator hash for the last confirmed snapshot
  , OpenDatum -> SnapshotVersion
headAdaOverhead :: Integer
  -- ^ Lovelace in the head UTxO not belonging to any L2 UTxO (min-UTxO overhead).
  -- Set once at init time and invariant for the head's lifetime.
  }
  deriving stock ((forall x. OpenDatum -> Rep OpenDatum x)
-> (forall x. Rep OpenDatum x -> OpenDatum) -> Generic OpenDatum
forall x. Rep OpenDatum x -> OpenDatum
forall x. OpenDatum -> Rep OpenDatum x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. OpenDatum -> Rep OpenDatum x
from :: forall x. OpenDatum -> Rep OpenDatum x
$cto :: forall x. Rep OpenDatum x -> OpenDatum
to :: forall x. Rep OpenDatum x -> OpenDatum
Generic, Int -> OpenDatum -> ShowS
[OpenDatum] -> ShowS
OpenDatum -> String
(Int -> OpenDatum -> ShowS)
-> (OpenDatum -> String)
-> ([OpenDatum] -> ShowS)
-> Show OpenDatum
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> OpenDatum -> ShowS
showsPrec :: Int -> OpenDatum -> ShowS
$cshow :: OpenDatum -> String
show :: OpenDatum -> String
$cshowList :: [OpenDatum] -> ShowS
showList :: [OpenDatum] -> ShowS
Show)

PlutusTx.unstableMakeIsData ''OpenDatum

-- | Sub-type for the closed state-machine state.
data ClosedDatum = ClosedDatum
  { ClosedDatum -> CurrencySymbol
headId :: CurrencySymbol
  -- ^ Spec: cid
  , ClosedDatum -> [Party]
parties :: [Party]
  -- ^ Spec: kH
  , ClosedDatum -> ContestationPeriod
contestationPeriod :: ContestationPeriod
  -- ^ Spec: T
  , ClosedDatum -> DepositPeriod
depositPeriod :: DepositPeriod
  -- ^ Must match the --deposit-period of all participating nodes.
  , ClosedDatum -> SnapshotVersion
version :: SnapshotVersion
  -- ^ Spec: v
  , ClosedDatum -> SnapshotVersion
snapshotNumber :: SnapshotNumber
  -- ^ Spec: s
  , ClosedDatum -> [PubKeyHash]
contesters :: [PubKeyHash]
  -- ^ Spec: C
  , ClosedDatum -> POSIXTime
contestationDeadline :: POSIXTime
  -- ^ Spec: tfinal
  , ClosedDatum -> BuiltinBLS12_381_G1_Element
accumulatorCommitment :: BuiltinBLS12_381_G1_Element
  -- ^ KZG commitment to the full UTxO set.
  , ClosedDatum -> SnapshotVersion
headAdaOverhead :: Integer
  -- ^ Lovelace in the head UTxO not belonging to any L2 UTxO (min-UTxO overhead).
  -- Propagated unchanged from OpenDatum via Close.
  }
  deriving stock ((forall x. ClosedDatum -> Rep ClosedDatum x)
-> (forall x. Rep ClosedDatum x -> ClosedDatum)
-> Generic ClosedDatum
forall x. Rep ClosedDatum x -> ClosedDatum
forall x. ClosedDatum -> Rep ClosedDatum x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ClosedDatum -> Rep ClosedDatum x
from :: forall x. ClosedDatum -> Rep ClosedDatum x
$cto :: forall x. Rep ClosedDatum x -> ClosedDatum
to :: forall x. Rep ClosedDatum x -> ClosedDatum
Generic, Int -> ClosedDatum -> ShowS
[ClosedDatum] -> ShowS
ClosedDatum -> String
(Int -> ClosedDatum -> ShowS)
-> (ClosedDatum -> String)
-> ([ClosedDatum] -> ShowS)
-> Show ClosedDatum
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ClosedDatum -> ShowS
showsPrec :: Int -> ClosedDatum -> ShowS
$cshow :: ClosedDatum -> String
show :: ClosedDatum -> String
$cshowList :: [ClosedDatum] -> ShowS
showList :: [ClosedDatum] -> ShowS
Show)

PlutusTx.unstableMakeIsData ''ClosedDatum

-- | Sub-type for intermediate partial fanout state. Carries only the fields
-- needed for subsequent partial fanout steps.
data FanoutProgressDatum = FanoutProgressDatum
  { FanoutProgressDatum -> CurrencySymbol
headId :: CurrencySymbol
  , FanoutProgressDatum -> [Party]
parties :: [Party]
  , FanoutProgressDatum -> POSIXTime
contestationDeadline :: POSIXTime
  , FanoutProgressDatum -> BuiltinBLS12_381_G1_Element
accumulatorCommitment :: BuiltinBLS12_381_G1_Element
  , FanoutProgressDatum -> SnapshotVersion
headAdaOverhead :: Integer
  -- ^ Lovelace in the head UTxO not belonging to any L2 UTxO. Propagated from ClosedDatum.
  }
  deriving stock ((forall x. FanoutProgressDatum -> Rep FanoutProgressDatum x)
-> (forall x. Rep FanoutProgressDatum x -> FanoutProgressDatum)
-> Generic FanoutProgressDatum
forall x. Rep FanoutProgressDatum x -> FanoutProgressDatum
forall x. FanoutProgressDatum -> Rep FanoutProgressDatum x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. FanoutProgressDatum -> Rep FanoutProgressDatum x
from :: forall x. FanoutProgressDatum -> Rep FanoutProgressDatum x
$cto :: forall x. Rep FanoutProgressDatum x -> FanoutProgressDatum
to :: forall x. Rep FanoutProgressDatum x -> FanoutProgressDatum
Generic, Int -> FanoutProgressDatum -> ShowS
[FanoutProgressDatum] -> ShowS
FanoutProgressDatum -> String
(Int -> FanoutProgressDatum -> ShowS)
-> (FanoutProgressDatum -> String)
-> ([FanoutProgressDatum] -> ShowS)
-> Show FanoutProgressDatum
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> FanoutProgressDatum -> ShowS
showsPrec :: Int -> FanoutProgressDatum -> ShowS
$cshow :: FanoutProgressDatum -> String
show :: FanoutProgressDatum -> String
$cshowList :: [FanoutProgressDatum] -> ShowS
showList :: [FanoutProgressDatum] -> ShowS
Show)

PlutusTx.unstableMakeIsData ''FanoutProgressDatum

-- | Extract the fields needed for partial fanout steps from a ClosedDatum.
-- Called both on-chain (in the validator dispatch) and off-chain (in tx building).
progressFromClosed :: ClosedDatum -> FanoutProgressDatum
progressFromClosed :: ClosedDatum -> FanoutProgressDatum
progressFromClosed ClosedDatum{CurrencySymbol
$sel:headId:ClosedDatum :: ClosedDatum -> CurrencySymbol
headId :: CurrencySymbol
headId, [Party]
$sel:parties:ClosedDatum :: ClosedDatum -> [Party]
parties :: [Party]
parties, POSIXTime
$sel:contestationDeadline:ClosedDatum :: ClosedDatum -> POSIXTime
contestationDeadline :: POSIXTime
contestationDeadline, BuiltinBLS12_381_G1_Element
$sel:accumulatorCommitment:ClosedDatum :: ClosedDatum -> BuiltinBLS12_381_G1_Element
accumulatorCommitment :: BuiltinBLS12_381_G1_Element
accumulatorCommitment, SnapshotVersion
$sel:headAdaOverhead:ClosedDatum :: ClosedDatum -> SnapshotVersion
headAdaOverhead :: SnapshotVersion
headAdaOverhead} =
  FanoutProgressDatum{CurrencySymbol
$sel:headId:FanoutProgressDatum :: CurrencySymbol
headId :: CurrencySymbol
headId, [Party]
$sel:parties:FanoutProgressDatum :: [Party]
parties :: [Party]
parties, POSIXTime
$sel:contestationDeadline:FanoutProgressDatum :: POSIXTime
contestationDeadline :: POSIXTime
contestationDeadline, BuiltinBLS12_381_G1_Element
$sel:accumulatorCommitment:FanoutProgressDatum :: BuiltinBLS12_381_G1_Element
accumulatorCommitment :: BuiltinBLS12_381_G1_Element
accumulatorCommitment, SnapshotVersion
$sel:headAdaOverhead:FanoutProgressDatum :: SnapshotVersion
headAdaOverhead :: SnapshotVersion
headAdaOverhead}
{-# INLINEABLE progressFromClosed #-}

data State
  = Open OpenDatum
  | Closed ClosedDatum
  | Final
  | FanoutProgress FanoutProgressDatum
  deriving stock ((forall x. State -> Rep State x)
-> (forall x. Rep State x -> State) -> Generic State
forall x. Rep State x -> State
forall x. State -> Rep State x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. State -> Rep State x
from :: forall x. State -> Rep State x
$cto :: forall x. Rep State x -> State
to :: forall x. Rep State x -> State
Generic, Int -> State -> ShowS
[State] -> ShowS
State -> String
(Int -> State -> ShowS)
-> (State -> String) -> ([State] -> ShowS) -> Show State
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> State -> ShowS
showsPrec :: Int -> State -> ShowS
$cshow :: State -> String
show :: State -> String
$cshowList :: [State] -> ShowS
showList :: [State] -> ShowS
Show)

PlutusTx.makeIsDataIndexed
  ''State
  [ ('Open, 0)
  , ('Closed, 1)
  , ('Final, 2)
  , ('FanoutProgress, 3)
  ]

-- | Sub-type for close transition with auxiliary data as needed.
data CloseRedeemer
  = -- | Initial snapshot is used to close.
    CloseInitial
  | -- | Any snapshot which doesn't contain anything to inc/decrement but snapshot number is higher than zero.
    CloseAny
      { CloseRedeemer -> [Hash]
signature :: [Signature]
      , CloseRedeemer -> Hash
accumulatorHash :: Hash
      -- ^ Digest of the accumulator hash
      , CloseRedeemer -> Hash
decommitOutputsHash :: Hash
      -- ^ Digest of the ordered decommit outputs (Uω); empty-list hash when the
      -- signed snapshot has no pending decommit. Binds Uω into the multi-signature.
      , CloseRedeemer -> Hash
commitOutputsHash :: Hash
      -- ^ Digest of the ordered commit outputs (Uα); empty-list hash when the
      -- signed snapshot has no pending commit. Binds Uα into the multi-signature.
      }
  | -- | Closing snapshot refers to the current state version (pending inc/dec not yet applied)
    CloseUnused
      { signature :: [Signature]
      -- ^ Multi-signature of a snapshot ξ
      , accumulatorHash :: Hash
      -- ^ Digest of the accumulator hash
      , decommitOutputsHash :: Hash
      -- ^ Digest of the ordered decommit outputs (Uω); empty-list hash when the
      -- signed snapshot has no pending decommit. Binds Uω into the multi-signature.
      , commitOutputsHash :: Hash
      -- ^ Digest of the ordered commit outputs (Uα); empty-list hash when the
      -- signed snapshot has no pending commit. Binds Uα into the multi-signature.
      }
  | -- | Closing snapshot refers to the previous state version (pending inc/dec already applied)
    CloseUsed
      { signature :: [Signature]
      -- ^ Multi-signature of a snapshot ξ
      , accumulatorHash :: Hash
      -- ^ Digest of the accumulator hash
      , decommitOutputsHash :: Hash
      -- ^ Digest of the ordered decommit outputs (Uω); empty-list hash when the
      -- signed snapshot has no pending decommit. Binds Uω into the multi-signature.
      , commitOutputsHash :: Hash
      -- ^ Digest of the ordered commit outputs (Uα); empty-list hash when the
      -- signed snapshot has no pending commit. Binds Uα into the multi-signature.
      }
  deriving stock (Int -> CloseRedeemer -> ShowS
[CloseRedeemer] -> ShowS
CloseRedeemer -> String
(Int -> CloseRedeemer -> ShowS)
-> (CloseRedeemer -> String)
-> ([CloseRedeemer] -> ShowS)
-> Show CloseRedeemer
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CloseRedeemer -> ShowS
showsPrec :: Int -> CloseRedeemer -> ShowS
$cshow :: CloseRedeemer -> String
show :: CloseRedeemer -> String
$cshowList :: [CloseRedeemer] -> ShowS
showList :: [CloseRedeemer] -> ShowS
Show, (forall x. CloseRedeemer -> Rep CloseRedeemer x)
-> (forall x. Rep CloseRedeemer x -> CloseRedeemer)
-> Generic CloseRedeemer
forall x. Rep CloseRedeemer x -> CloseRedeemer
forall x. CloseRedeemer -> Rep CloseRedeemer x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. CloseRedeemer -> Rep CloseRedeemer x
from :: forall x. CloseRedeemer -> Rep CloseRedeemer x
$cto :: forall x. Rep CloseRedeemer x -> CloseRedeemer
to :: forall x. Rep CloseRedeemer x -> CloseRedeemer
Generic)

PlutusTx.makeIsDataIndexed
  ''CloseRedeemer
  [ ('CloseInitial, 0)
  , ('CloseAny, 1)
  , ('CloseUnused, 2)
  , ('CloseUsed, 3)
  ]

-- | Sub-type for contest transition with auxiliary data as needed.
data ContestRedeemer
  = -- | Contesting snapshot refers to the current state version (inc/dec not yet applied, or no pending action)
    ContestUnused
      { ContestRedeemer -> [Hash]
signature :: [Signature]
      -- ^ Multi-signature of a snapshot ξ
      , ContestRedeemer -> Hash
accumulatorHash :: Hash
      -- ^ Digest of the accumulator hash
      , ContestRedeemer -> Hash
decommitOutputsHash :: Hash
      -- ^ Digest of the ordered decommit outputs (Uω); empty-list hash when the
      -- signed snapshot has no pending decommit. Binds Uω into the multi-signature.
      , ContestRedeemer -> Hash
commitOutputsHash :: Hash
      -- ^ Digest of the ordered commit outputs (Uα); empty-list hash when the
      -- signed snapshot has no pending commit. Binds Uα into the multi-signature.
      }
  | -- | Contesting snapshot refers to the previous state version (pending inc/dec already applied)
    ContestUsed
      { signature :: [Signature]
      -- ^ Multi-signature of a snapshot ξ
      , accumulatorHash :: Hash
      -- ^ Digest of the accumulator hash
      , decommitOutputsHash :: Hash
      -- ^ Digest of the ordered decommit outputs (Uω); empty-list hash when the
      -- signed snapshot has no pending decommit. Binds Uω into the multi-signature.
      , commitOutputsHash :: Hash
      -- ^ Digest of the ordered commit outputs (Uα); empty-list hash when the
      -- signed snapshot has no pending commit. Binds Uα into the multi-signature.
      }
  deriving stock (Int -> ContestRedeemer -> ShowS
[ContestRedeemer] -> ShowS
ContestRedeemer -> String
(Int -> ContestRedeemer -> ShowS)
-> (ContestRedeemer -> String)
-> ([ContestRedeemer] -> ShowS)
-> Show ContestRedeemer
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ContestRedeemer -> ShowS
showsPrec :: Int -> ContestRedeemer -> ShowS
$cshow :: ContestRedeemer -> String
show :: ContestRedeemer -> String
$cshowList :: [ContestRedeemer] -> ShowS
showList :: [ContestRedeemer] -> ShowS
Show, (forall x. ContestRedeemer -> Rep ContestRedeemer x)
-> (forall x. Rep ContestRedeemer x -> ContestRedeemer)
-> Generic ContestRedeemer
forall x. Rep ContestRedeemer x -> ContestRedeemer
forall x. ContestRedeemer -> Rep ContestRedeemer x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ContestRedeemer -> Rep ContestRedeemer x
from :: forall x. ContestRedeemer -> Rep ContestRedeemer x
$cto :: forall x. Rep ContestRedeemer x -> ContestRedeemer
to :: forall x. Rep ContestRedeemer x -> ContestRedeemer
Generic)

PlutusTx.makeIsDataIndexed
  ''ContestRedeemer
  [ ('ContestUnused, 0)
  , ('ContestUsed, 1)
  ]

-- | Sub-type for increment transition
data IncrementRedeemer = IncrementRedeemer
  { IncrementRedeemer -> [Hash]
signature :: [Signature]
  , IncrementRedeemer -> SnapshotVersion
snapshotNumber :: SnapshotNumber
  , IncrementRedeemer -> TxOutRef
increment :: TxOutRef
  , IncrementRedeemer -> Hash
decommitOutputsHash :: Hash
  -- ^ Digest of the ordered decommit outputs (Uω) of the signed snapshot. Needed
  -- to reconstruct the multi-signed message; commit and decommit are not mutually
  -- exclusive in a snapshot, so an increment's snapshot may still carry a decommit.
  }
  deriving stock (Int -> IncrementRedeemer -> ShowS
[IncrementRedeemer] -> ShowS
IncrementRedeemer -> String
(Int -> IncrementRedeemer -> ShowS)
-> (IncrementRedeemer -> String)
-> ([IncrementRedeemer] -> ShowS)
-> Show IncrementRedeemer
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> IncrementRedeemer -> ShowS
showsPrec :: Int -> IncrementRedeemer -> ShowS
$cshow :: IncrementRedeemer -> String
show :: IncrementRedeemer -> String
$cshowList :: [IncrementRedeemer] -> ShowS
showList :: [IncrementRedeemer] -> ShowS
Show, (forall x. IncrementRedeemer -> Rep IncrementRedeemer x)
-> (forall x. Rep IncrementRedeemer x -> IncrementRedeemer)
-> Generic IncrementRedeemer
forall x. Rep IncrementRedeemer x -> IncrementRedeemer
forall x. IncrementRedeemer -> Rep IncrementRedeemer x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. IncrementRedeemer -> Rep IncrementRedeemer x
from :: forall x. IncrementRedeemer -> Rep IncrementRedeemer x
$cto :: forall x. Rep IncrementRedeemer x -> IncrementRedeemer
to :: forall x. Rep IncrementRedeemer x -> IncrementRedeemer
Generic)

PlutusTx.unstableMakeIsData ''IncrementRedeemer

-- | Sub-type for decrement transition with auxiliary data as needed.
data DecrementRedeemer = DecrementRedeemer
  { DecrementRedeemer -> [Hash]
signature :: [Signature]
  -- ^ Spec: ξ
  , DecrementRedeemer -> SnapshotVersion
snapshotNumber :: SnapshotNumber
  -- ^ Spec: s
  , DecrementRedeemer -> SnapshotVersion
numberOfDecommitOutputs :: Integer
  -- ^ Spec: m
  , DecrementRedeemer -> Hash
commitOutputsHash :: Hash
  -- ^ Digest of the ordered commit outputs (Uα) of the signed snapshot. Needed to
  -- reconstruct the multi-signed message; a decrement's snapshot may still carry a
  -- pending commit (commit and decommit are not mutually exclusive).
  }
  deriving stock (Int -> DecrementRedeemer -> ShowS
[DecrementRedeemer] -> ShowS
DecrementRedeemer -> String
(Int -> DecrementRedeemer -> ShowS)
-> (DecrementRedeemer -> String)
-> ([DecrementRedeemer] -> ShowS)
-> Show DecrementRedeemer
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DecrementRedeemer -> ShowS
showsPrec :: Int -> DecrementRedeemer -> ShowS
$cshow :: DecrementRedeemer -> String
show :: DecrementRedeemer -> String
$cshowList :: [DecrementRedeemer] -> ShowS
showList :: [DecrementRedeemer] -> ShowS
Show, (forall x. DecrementRedeemer -> Rep DecrementRedeemer x)
-> (forall x. Rep DecrementRedeemer x -> DecrementRedeemer)
-> Generic DecrementRedeemer
forall x. Rep DecrementRedeemer x -> DecrementRedeemer
forall x. DecrementRedeemer -> Rep DecrementRedeemer x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. DecrementRedeemer -> Rep DecrementRedeemer x
from :: forall x. DecrementRedeemer -> Rep DecrementRedeemer x
$cto :: forall x. Rep DecrementRedeemer x -> DecrementRedeemer
to :: forall x. Rep DecrementRedeemer x -> DecrementRedeemer
Generic)

PlutusTx.unstableMakeIsData ''DecrementRedeemer

data Input
  = Increment IncrementRedeemer
  | Decrement DecrementRedeemer
  | Close CloseRedeemer
  | Contest ContestRedeemer
  | Fanout
      { Input -> SnapshotVersion
numberOfFanoutOutputs :: Integer
      , Input -> BuiltinBLS12_381_G1_Element
proof :: BuiltinBLS12_381_G1_Element
      , Input -> TxOutRef
crsRef :: TxOutRef
      }
  | PartialFanout
      { Input -> SnapshotVersion
numberOfPartialOutputs :: Integer
      , crsRef :: TxOutRef
      }
  | FinalPartialFanout
      { numberOfPartialOutputs :: Integer
      , proof :: BuiltinBLS12_381_G1_Element
      , crsRef :: TxOutRef
      }
  deriving stock ((forall x. Input -> Rep Input x)
-> (forall x. Rep Input x -> Input) -> Generic Input
forall x. Rep Input x -> Input
forall x. Input -> Rep Input x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Input -> Rep Input x
from :: forall x. Input -> Rep Input x
$cto :: forall x. Rep Input x -> Input
to :: forall x. Rep Input x -> Input
Generic, Int -> Input -> ShowS
[Input] -> ShowS
Input -> String
(Int -> Input -> ShowS)
-> (Input -> String) -> ([Input] -> ShowS) -> Show Input
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Input -> ShowS
showsPrec :: Int -> Input -> ShowS
$cshow :: Input -> String
show :: Input -> String
$cshowList :: [Input] -> ShowS
showList :: [Input] -> ShowS
Show)

-- NOTE: The constructor indices here are load-bearing: the @deposit.ak@
-- validator reads the @Input@ redeemer's constructor index directly via
-- @builtin.un_constr_data@ to check that the head input is being spent with
-- the @Increment@ redeemer. Keep this list and @validators/deposit.ak@ in
-- sync.
PlutusTx.makeIsDataIndexed
  ''Input
  [ ('Increment, 0)
  , ('Decrement, 1)
  , ('Close, 2)
  , ('Contest, 3)
  , ('Fanout, 4)
  , ('PartialFanout, 5)
  , ('FinalPartialFanout, 6)
  ]