{-# LANGUAGE DuplicateRecordFields #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Hydra.Chain.Direct.State where
import Hydra.Prelude hiding (init)
import Cardano.Api.UTxO qualified as UTxO
import Cardano.Ledger.Api (PParams)
import GHC.IsList qualified as IsList
import Hydra.Cardano.Api (
AssetId (..),
ChainPoint (..),
CtxUTxO,
Key (SigningKey, VerificationKey),
LedgerEra,
NetworkId,
PaymentKey,
PolicyId,
SlotNo (SlotNo),
Tx,
TxId,
TxIn,
TxIx (..),
TxOut,
UTxO,
chainPointToSlotNo,
fromCtxUTxOTxOut,
fromPlutusTxOutRef,
fromScriptData,
isScriptTxOut,
negateValue,
toShelleyNetwork,
txOutScriptData,
txOutValue,
utxoFromTx,
pattern TxIn,
)
import Hydra.Chain.ChainState (ChainSlot (ChainSlot), IsChainState (..))
import Hydra.Contract.Head qualified as Head
import Hydra.Contract.HeadState qualified as Head
import Hydra.Contract.HeadTokens (headPolicyId, mkHeadTokenScript)
import Hydra.Plutus (depositValidatorScript)
import Hydra.Tx (
ConfirmedSnapshot (..),
HeadId (..),
HeadParameters (..),
HeadSeed,
Party,
ScriptRegistry (..),
Snapshot (..),
SnapshotVersion (..),
getSnapshot,
headIdToPolicyId,
headSeedToTxIn,
partyFromChain,
partyToChain,
registryUTxO,
txInToHeadSeed,
)
import Hydra.Tx.Accumulator (HydraAccumulator)
import Hydra.Tx.Accumulator qualified as Accumulator
import Hydra.Tx.Close (OpenThreadOutput (..), PointInTime, closeTx)
import Hydra.Tx.Contest (ClosedThreadOutput (..), contestTx)
import Hydra.Tx.ContestationPeriod (ContestationPeriod)
import Hydra.Tx.ContestationPeriod qualified as ContestationPeriod
import Hydra.Tx.Crypto (HydraKey, aggregate, generateSigningKey, sign)
import Hydra.Tx.Decrement (decrementTx)
import Hydra.Tx.Deposit (DepositObservation (..), observeDepositTx, observeDepositTxOut)
import Hydra.Tx.DepositPeriod (DepositPeriod)
import Hydra.Tx.DepositPeriod qualified as DepositPeriod
import Hydra.Tx.Fanout (fanoutTx, finalPartialFanoutTx, partialFanoutTx)
import Hydra.Tx.Increment (incrementTx)
import Hydra.Tx.Init (initTx)
import Hydra.Tx.OnChainId (OnChainId)
import Hydra.Tx.Recover (recoverTx)
import Hydra.Tx.Secret (Secret)
import Hydra.Tx.Utils (setIncrementalActionMaybe)
class HasKnownUTxO a where
getKnownUTxO :: a -> UTxO
data ChainStateAt = ChainStateAt
{ ChainStateAt -> UTxO
spendableUTxO :: UTxO
, ChainStateAt -> Maybe ChainPoint
recordedAt :: Maybe ChainPoint
}
deriving stock (ChainStateAt -> ChainStateAt -> Bool
(ChainStateAt -> ChainStateAt -> Bool)
-> (ChainStateAt -> ChainStateAt -> Bool) -> Eq ChainStateAt
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ChainStateAt -> ChainStateAt -> Bool
== :: ChainStateAt -> ChainStateAt -> Bool
$c/= :: ChainStateAt -> ChainStateAt -> Bool
/= :: ChainStateAt -> ChainStateAt -> Bool
Eq, Int -> ChainStateAt -> ShowS
[ChainStateAt] -> ShowS
ChainStateAt -> String
(Int -> ChainStateAt -> ShowS)
-> (ChainStateAt -> String)
-> ([ChainStateAt] -> ShowS)
-> Show ChainStateAt
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ChainStateAt -> ShowS
showsPrec :: Int -> ChainStateAt -> ShowS
$cshow :: ChainStateAt -> String
show :: ChainStateAt -> String
$cshowList :: [ChainStateAt] -> ShowS
showList :: [ChainStateAt] -> ShowS
Show, (forall x. ChainStateAt -> Rep ChainStateAt x)
-> (forall x. Rep ChainStateAt x -> ChainStateAt)
-> Generic ChainStateAt
forall x. Rep ChainStateAt x -> ChainStateAt
forall x. ChainStateAt -> Rep ChainStateAt x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ChainStateAt -> Rep ChainStateAt x
from :: forall x. ChainStateAt -> Rep ChainStateAt x
$cto :: forall x. Rep ChainStateAt x -> ChainStateAt
to :: forall x. Rep ChainStateAt x -> ChainStateAt
Generic)
deriving anyclass ([ChainStateAt] -> Value
[ChainStateAt] -> Encoding
ChainStateAt -> Bool
ChainStateAt -> Value
ChainStateAt -> Encoding
(ChainStateAt -> Value)
-> (ChainStateAt -> Encoding)
-> ([ChainStateAt] -> Value)
-> ([ChainStateAt] -> Encoding)
-> (ChainStateAt -> Bool)
-> ToJSON ChainStateAt
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: ChainStateAt -> Value
toJSON :: ChainStateAt -> Value
$ctoEncoding :: ChainStateAt -> Encoding
toEncoding :: ChainStateAt -> Encoding
$ctoJSONList :: [ChainStateAt] -> Value
toJSONList :: [ChainStateAt] -> Value
$ctoEncodingList :: [ChainStateAt] -> Encoding
toEncodingList :: [ChainStateAt] -> Encoding
$comitField :: ChainStateAt -> Bool
omitField :: ChainStateAt -> Bool
ToJSON, Maybe ChainStateAt
Value -> Parser [ChainStateAt]
Value -> Parser ChainStateAt
(Value -> Parser ChainStateAt)
-> (Value -> Parser [ChainStateAt])
-> Maybe ChainStateAt
-> FromJSON ChainStateAt
forall a.
(Value -> Parser a)
-> (Value -> Parser [a]) -> Maybe a -> FromJSON a
$cparseJSON :: Value -> Parser ChainStateAt
parseJSON :: Value -> Parser ChainStateAt
$cparseJSONList :: Value -> Parser [ChainStateAt]
parseJSONList :: Value -> Parser [ChainStateAt]
$comittedField :: Maybe ChainStateAt
omittedField :: Maybe ChainStateAt
FromJSON)
instance ToCBOR ChainStateAt where
toCBOR :: ChainStateAt -> Encoding
toCBOR = ChainStateAt -> Encoding
forall a. (Generic a, GToCBOR (Rep a)) => a -> Encoding
genericToCBOR
instance FromCBOR ChainStateAt where
fromCBOR :: forall s. Decoder s ChainStateAt
fromCBOR = Decoder s ChainStateAt
forall a s. (Generic a, GFromCBOR (Rep a)) => Decoder s a
genericFromCBOR
instance IsChainState Tx where
type ChainPointType Tx = ChainPoint
type ChainStateType Tx = ChainStateAt
chainStatePoint :: ChainStateType Tx -> ChainPointType Tx
chainStatePoint ChainStateAt{Maybe ChainPoint
$sel:recordedAt:ChainStateAt :: ChainStateAt -> Maybe ChainPoint
recordedAt :: Maybe ChainPoint
recordedAt} =
ChainPoint -> Maybe ChainPoint -> ChainPoint
forall a. a -> Maybe a -> a
fromMaybe ChainPoint
ChainPointAtGenesis Maybe ChainPoint
recordedAt
chainPointSlot :: ChainPointType Tx -> ChainSlot
chainPointSlot = ChainPoint -> ChainSlot
ChainPointType Tx -> ChainSlot
chainSlotFromPoint
chainSlotFromPoint :: ChainPoint -> ChainSlot
chainSlotFromPoint :: ChainPoint -> ChainSlot
chainSlotFromPoint ChainPoint
p =
case ChainPoint -> Maybe SlotNo
chainPointToSlotNo ChainPoint
p of
Maybe SlotNo
Nothing -> Natural -> ChainSlot
ChainSlot Natural
0
Just (SlotNo Word64
s) -> Natural -> ChainSlot
ChainSlot (Natural -> ChainSlot) -> Natural -> ChainSlot
forall a b. (a -> b) -> a -> b
$ Word64 -> Natural
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
s
data ChainState
=
Idle
| Open OpenState
| Closed ClosedState
deriving stock (ChainState -> ChainState -> Bool
(ChainState -> ChainState -> Bool)
-> (ChainState -> ChainState -> Bool) -> Eq ChainState
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ChainState -> ChainState -> Bool
== :: ChainState -> ChainState -> Bool
$c/= :: ChainState -> ChainState -> Bool
/= :: ChainState -> ChainState -> Bool
Eq, Int -> ChainState -> ShowS
[ChainState] -> ShowS
ChainState -> String
(Int -> ChainState -> ShowS)
-> (ChainState -> String)
-> ([ChainState] -> ShowS)
-> Show ChainState
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ChainState -> ShowS
showsPrec :: Int -> ChainState -> ShowS
$cshow :: ChainState -> String
show :: ChainState -> String
$cshowList :: [ChainState] -> ShowS
showList :: [ChainState] -> ShowS
Show, (forall x. ChainState -> Rep ChainState x)
-> (forall x. Rep ChainState x -> ChainState) -> Generic ChainState
forall x. Rep ChainState x -> ChainState
forall x. ChainState -> Rep ChainState x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ChainState -> Rep ChainState x
from :: forall x. ChainState -> Rep ChainState x
$cto :: forall x. Rep ChainState x -> ChainState
to :: forall x. Rep ChainState x -> ChainState
Generic)
instance HasKnownUTxO ChainState where
getKnownUTxO :: ChainState -> UTxO
getKnownUTxO :: ChainState -> UTxO
getKnownUTxO = \case
ChainState
Idle -> UTxO
forall a. Monoid a => a
mempty
Open OpenState
st -> OpenState -> UTxO
forall a. HasKnownUTxO a => a -> UTxO
getKnownUTxO OpenState
st
Closed ClosedState
st -> ClosedState -> UTxO
forall a. HasKnownUTxO a => a -> UTxO
getKnownUTxO ClosedState
st
initialChainState :: ChainStateType Tx
initialChainState :: ChainStateType Tx
initialChainState =
ChainStateAt
{ $sel:spendableUTxO:ChainStateAt :: UTxO
spendableUTxO = UTxO
forall a. Monoid a => a
mempty
, $sel:recordedAt:ChainStateAt :: Maybe ChainPoint
recordedAt = Maybe ChainPoint
forall a. Maybe a
Nothing
}
data ChainContext = ChainContext
{ ChainContext -> NetworkId
networkId :: NetworkId
, ChainContext -> VerificationKey PaymentKey
ownVerificationKey :: VerificationKey PaymentKey
, ChainContext -> Party
ownParty :: Party
, ChainContext -> ScriptRegistry
scriptRegistry :: ScriptRegistry
}
deriving stock (ChainContext -> ChainContext -> Bool
(ChainContext -> ChainContext -> Bool)
-> (ChainContext -> ChainContext -> Bool) -> Eq ChainContext
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ChainContext -> ChainContext -> Bool
== :: ChainContext -> ChainContext -> Bool
$c/= :: ChainContext -> ChainContext -> Bool
/= :: ChainContext -> ChainContext -> Bool
Eq, Int -> ChainContext -> ShowS
[ChainContext] -> ShowS
ChainContext -> String
(Int -> ChainContext -> ShowS)
-> (ChainContext -> String)
-> ([ChainContext] -> ShowS)
-> Show ChainContext
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ChainContext -> ShowS
showsPrec :: Int -> ChainContext -> ShowS
$cshow :: ChainContext -> String
show :: ChainContext -> String
$cshowList :: [ChainContext] -> ShowS
showList :: [ChainContext] -> ShowS
Show, (forall x. ChainContext -> Rep ChainContext x)
-> (forall x. Rep ChainContext x -> ChainContext)
-> Generic ChainContext
forall x. Rep ChainContext x -> ChainContext
forall x. ChainContext -> Rep ChainContext x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ChainContext -> Rep ChainContext x
from :: forall x. ChainContext -> Rep ChainContext x
$cto :: forall x. Rep ChainContext x -> ChainContext
to :: forall x. Rep ChainContext x -> ChainContext
Generic)
instance HasKnownUTxO ChainContext where
getKnownUTxO :: ChainContext -> UTxO
getKnownUTxO ChainContext{ScriptRegistry
$sel:scriptRegistry:ChainContext :: ChainContext -> ScriptRegistry
scriptRegistry :: ScriptRegistry
scriptRegistry} = ScriptRegistry -> UTxO
registryUTxO ScriptRegistry
scriptRegistry
data OpenState = OpenState
{ OpenState -> UTxO
openUTxO :: UTxO
, OpenState -> HeadId
headId :: HeadId
, OpenState -> TxIn
seedTxIn :: TxIn
}
deriving stock (OpenState -> OpenState -> Bool
(OpenState -> OpenState -> Bool)
-> (OpenState -> OpenState -> Bool) -> Eq OpenState
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: OpenState -> OpenState -> Bool
== :: OpenState -> OpenState -> Bool
$c/= :: OpenState -> OpenState -> Bool
/= :: OpenState -> OpenState -> Bool
Eq, Int -> OpenState -> ShowS
[OpenState] -> ShowS
OpenState -> String
(Int -> OpenState -> ShowS)
-> (OpenState -> String)
-> ([OpenState] -> ShowS)
-> Show OpenState
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> OpenState -> ShowS
showsPrec :: Int -> OpenState -> ShowS
$cshow :: OpenState -> String
show :: OpenState -> String
$cshowList :: [OpenState] -> ShowS
showList :: [OpenState] -> ShowS
Show, (forall x. OpenState -> Rep OpenState x)
-> (forall x. Rep OpenState x -> OpenState) -> Generic OpenState
forall x. Rep OpenState x -> OpenState
forall x. OpenState -> Rep OpenState x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. OpenState -> Rep OpenState x
from :: forall x. OpenState -> Rep OpenState x
$cto :: forall x. Rep OpenState x -> OpenState
to :: forall x. Rep OpenState x -> OpenState
Generic)
instance HasKnownUTxO OpenState where
getKnownUTxO :: OpenState -> UTxO
getKnownUTxO OpenState{UTxO
$sel:openUTxO:OpenState :: OpenState -> UTxO
openUTxO :: UTxO
openUTxO} =
UTxO
openUTxO
data ClosedState = ClosedState
{ ClosedState -> UTxO
closedUTxO :: UTxO
, ClosedState -> HeadId
headId :: HeadId
, ClosedState -> TxIn
seedTxIn :: TxIn
, ClosedState -> UTCTime
contestationDeadline :: UTCTime
}
deriving stock (ClosedState -> ClosedState -> Bool
(ClosedState -> ClosedState -> Bool)
-> (ClosedState -> ClosedState -> Bool) -> Eq ClosedState
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ClosedState -> ClosedState -> Bool
== :: ClosedState -> ClosedState -> Bool
$c/= :: ClosedState -> ClosedState -> Bool
/= :: ClosedState -> ClosedState -> Bool
Eq, Int -> ClosedState -> ShowS
[ClosedState] -> ShowS
ClosedState -> String
(Int -> ClosedState -> ShowS)
-> (ClosedState -> String)
-> ([ClosedState] -> ShowS)
-> Show ClosedState
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ClosedState -> ShowS
showsPrec :: Int -> ClosedState -> ShowS
$cshow :: ClosedState -> String
show :: ClosedState -> String
$cshowList :: [ClosedState] -> ShowS
showList :: [ClosedState] -> ShowS
Show, (forall x. ClosedState -> Rep ClosedState x)
-> (forall x. Rep ClosedState x -> ClosedState)
-> Generic ClosedState
forall x. Rep ClosedState x -> ClosedState
forall x. ClosedState -> Rep ClosedState x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ClosedState -> Rep ClosedState x
from :: forall x. ClosedState -> Rep ClosedState x
$cto :: forall x. Rep ClosedState x -> ClosedState
to :: forall x. Rep ClosedState x -> ClosedState
Generic)
instance HasKnownUTxO ClosedState where
getKnownUTxO :: ClosedState -> UTxO
getKnownUTxO ClosedState{UTxO
$sel:closedUTxO:ClosedState :: ClosedState -> UTxO
closedUTxO :: UTxO
closedUTxO} =
UTxO
closedUTxO
initialize ::
ChainContext ->
PParams LedgerEra ->
TxIn ->
[OnChainId] ->
HeadParameters ->
Tx
initialize :: ChainContext
-> PParams LedgerEra -> TxIn -> [OnChainId] -> HeadParameters -> Tx
initialize ChainContext
ctx =
NetworkId
-> PParams LedgerEra -> TxIn -> [OnChainId] -> HeadParameters -> Tx
initTx NetworkId
networkId
where
ChainContext{NetworkId
$sel:networkId:ChainContext :: ChainContext -> NetworkId
networkId :: NetworkId
networkId} = ChainContext
ctx
data IncrementTxError
= InvalidHeadSeedInIncrement {IncrementTxError -> HeadSeed
headSeed :: HeadSeed}
| InvalidHeadIdInIncrement {IncrementTxError -> HeadId
headId :: HeadId}
| CannotFindHeadOutputInIncrement
| CannotFindDepositOutputInIncrement {IncrementTxError -> TxId
depositTxId :: TxId}
| SnapshotMissingIncrementUTxO
| SnapshotIncrementUTxOIsNull
| CannotObserveDraftedDeposit
| CannotDecodeHeadDatumInIncrement
deriving stock (Int -> IncrementTxError -> ShowS
[IncrementTxError] -> ShowS
IncrementTxError -> String
(Int -> IncrementTxError -> ShowS)
-> (IncrementTxError -> String)
-> ([IncrementTxError] -> ShowS)
-> Show IncrementTxError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> IncrementTxError -> ShowS
showsPrec :: Int -> IncrementTxError -> ShowS
$cshow :: IncrementTxError -> String
show :: IncrementTxError -> String
$cshowList :: [IncrementTxError] -> ShowS
showList :: [IncrementTxError] -> ShowS
Show)
increment ::
ChainContext ->
UTxO ->
(HeadSeed, HeadId) ->
HeadParameters ->
ConfirmedSnapshot Tx ->
SlotNo ->
Either IncrementTxError Tx
increment :: ChainContext
-> UTxO
-> (HeadSeed, HeadId)
-> HeadParameters
-> ConfirmedSnapshot Tx
-> SlotNo
-> Either IncrementTxError Tx
increment ChainContext
ctx UTxO
spendableUTxO (HeadSeed
headSeed, HeadId
headId) HeadParameters
headParameters ConfirmedSnapshot Tx
incrementingSnapshot SlotNo
upperValiditySlot = do
TxIn
seedTxIn <- HeadSeed -> Maybe TxIn
forall (m :: * -> *). MonadFail m => HeadSeed -> m TxIn
headSeedToTxIn HeadSeed
headSeed Maybe TxIn -> IncrementTxError -> Either IncrementTxError TxIn
forall a e. Maybe a -> e -> Either e a
?> InvalidHeadSeedInIncrement{HeadSeed
$sel:headSeed:InvalidHeadSeedInIncrement :: HeadSeed
headSeed :: HeadSeed
headSeed}
PolicyId
pid <- HeadId -> Maybe PolicyId
forall (m :: * -> *). MonadFail m => HeadId -> m PolicyId
headIdToPolicyId HeadId
headId Maybe PolicyId
-> IncrementTxError -> Either IncrementTxError PolicyId
forall a e. Maybe a -> e -> Either e a
?> InvalidHeadIdInIncrement{HeadId
$sel:headId:InvalidHeadSeedInIncrement :: HeadId
headId :: HeadId
headId}
let utxoOfThisHead' :: UTxO
utxoOfThisHead' = PolicyId -> UTxO -> UTxO
utxoOfThisHead PolicyId
pid UTxO
spendableUTxO
(TxIn, TxOut CtxUTxO ConwayEra)
headUTxO <- (TxOut CtxUTxO ConwayEra -> Bool)
-> UTxO -> Maybe (TxIn, TxOut CtxUTxO ConwayEra)
forall era.
(TxOut CtxUTxO era -> Bool)
-> UTxO era -> Maybe (TxIn, TxOut CtxUTxO era)
UTxO.find (PlutusScript PlutusScriptV3 -> TxOut CtxUTxO ConwayEra -> Bool
forall lang ctx era.
IsPlutusScriptLanguage lang =>
PlutusScript lang -> TxOut ctx era -> Bool
isScriptTxOut PlutusScript PlutusScriptV3
Head.validatorScript) UTxO
utxoOfThisHead' Maybe (TxIn, TxOut CtxUTxO ConwayEra)
-> IncrementTxError
-> Either IncrementTxError (TxIn, TxOut CtxUTxO ConwayEra)
forall a e. Maybe a -> e -> Either e a
?> IncrementTxError
CannotFindHeadOutputInIncrement
TxId
depositTxId <- Maybe (TxIdType Tx)
Maybe TxId
snapshotDepositTxId Maybe TxId -> IncrementTxError -> Either IncrementTxError TxId
forall a e. Maybe a -> e -> Either e a
?> IncrementTxError
SnapshotMissingIncrementUTxO
(TxIn
depositedIn, TxOut CtxUTxO ConwayEra
depositedOut) <-
(TxIn -> TxOut CtxUTxO ConwayEra -> Bool)
-> UTxO -> Maybe (TxIn, TxOut CtxUTxO ConwayEra)
forall era.
(TxIn -> TxOut CtxUTxO era -> Bool)
-> UTxO era -> Maybe (TxIn, TxOut CtxUTxO era)
UTxO.findWithKey
( \TxIn
txin TxOut CtxUTxO ConwayEra
txout ->
TxIn
txin TxIn -> TxIn -> Bool
forall a. Eq a => a -> a -> Bool
== TxId -> TxIx -> TxIn
TxIn TxId
depositTxId (Word -> TxIx
TxIx Word
0) Bool -> Bool -> Bool
&& PlutusScript PlutusScriptV3 -> TxOut CtxUTxO ConwayEra -> Bool
forall lang ctx era.
IsPlutusScriptLanguage lang =>
PlutusScript lang -> TxOut ctx era -> Bool
isScriptTxOut PlutusScript PlutusScriptV3
depositValidatorScript TxOut CtxUTxO ConwayEra
txout
)
UTxO
spendableUTxO
Maybe (TxIn, TxOut CtxUTxO ConwayEra)
-> IncrementTxError
-> Either IncrementTxError (TxIn, TxOut CtxUTxO ConwayEra)
forall a e. Maybe a -> e -> Either e a
?> CannotFindDepositOutputInIncrement{TxId
$sel:depositTxId:InvalidHeadSeedInIncrement :: TxId
depositTxId :: TxId
depositTxId}
case Maybe (UTxOType Tx)
utxoToCommit of
Maybe (UTxOType Tx)
Nothing ->
IncrementTxError -> Either IncrementTxError Tx
forall a b. a -> Either a b
Left IncrementTxError
SnapshotMissingIncrementUTxO
Just UTxOType Tx
deposit
| UTxO -> Bool
forall era. UTxO era -> Bool
UTxO.null UTxOType Tx
UTxO
deposit ->
IncrementTxError -> Either IncrementTxError Tx
forall a b. a -> Either a b
Left IncrementTxError
SnapshotIncrementUTxOIsNull
| Bool
otherwise ->
Tx -> Either IncrementTxError Tx
forall a b. b -> Either a b
Right (Tx -> Either IncrementTxError Tx)
-> Tx -> Either IncrementTxError Tx
forall a b. (a -> b) -> a -> b
$
ScriptRegistry
-> VerificationKey PaymentKey
-> (TxIn, HeadId)
-> HeadParameters
-> (TxIn, TxOut CtxUTxO ConwayEra)
-> Snapshot Tx
-> UTxO
-> SlotNo
-> MultiSignature (Snapshot Tx)
-> Tx
incrementTx
ScriptRegistry
scriptRegistry
VerificationKey PaymentKey
ownVerificationKey
(TxIn
seedTxIn, HeadId
headId)
HeadParameters
headParameters
(TxIn, TxOut CtxUTxO ConwayEra)
headUTxO
Snapshot Tx
sn
(TxIn -> TxOut CtxUTxO ConwayEra -> UTxO
forall era. TxIn -> TxOut CtxUTxO era -> UTxO era
UTxO.singleton TxIn
depositedIn TxOut CtxUTxO ConwayEra
depositedOut)
SlotNo
upperValiditySlot
MultiSignature (Snapshot Tx)
sigs
where
Snapshot{Maybe (UTxOType Tx)
utxoToCommit :: forall tx. Snapshot tx -> Maybe (UTxOType tx)
utxoToCommit :: Maybe (UTxOType Tx)
utxoToCommit, $sel:depositTxId:Snapshot :: forall tx. Snapshot tx -> Maybe (TxIdType tx)
depositTxId = Maybe (TxIdType Tx)
snapshotDepositTxId} = Snapshot Tx
sn
(Snapshot Tx
sn, MultiSignature (Snapshot Tx)
sigs) =
case ConfirmedSnapshot Tx
incrementingSnapshot of
ConfirmedSnapshot{Snapshot Tx
snapshot :: Snapshot Tx
$sel:snapshot:InitialSnapshot :: forall tx. ConfirmedSnapshot tx -> Snapshot tx
snapshot, MultiSignature (Snapshot Tx)
signatures :: MultiSignature (Snapshot Tx)
$sel:signatures:InitialSnapshot :: forall tx. ConfirmedSnapshot tx -> MultiSignature (Snapshot tx)
signatures} -> (Snapshot Tx
snapshot, MultiSignature (Snapshot Tx)
signatures)
ConfirmedSnapshot Tx
_ -> (ConfirmedSnapshot Tx -> Snapshot Tx
forall tx. IsTx tx => ConfirmedSnapshot tx -> Snapshot tx
getSnapshot ConfirmedSnapshot Tx
incrementingSnapshot, MultiSignature (Snapshot Tx)
forall a. Monoid a => a
mempty)
ChainContext{VerificationKey PaymentKey
$sel:ownVerificationKey:ChainContext :: ChainContext -> VerificationKey PaymentKey
ownVerificationKey :: VerificationKey PaymentKey
ownVerificationKey, ScriptRegistry
$sel:scriptRegistry:ChainContext :: ChainContext -> ScriptRegistry
scriptRegistry :: ScriptRegistry
scriptRegistry} = ChainContext
ctx
dryRunIncrementTx ::
ChainContext ->
UTxO ->
HeadId ->
ConfirmedSnapshot Tx ->
Tx ->
SlotNo ->
Either IncrementTxError Tx
dryRunIncrementTx :: ChainContext
-> UTxO
-> HeadId
-> ConfirmedSnapshot Tx
-> Tx
-> SlotNo
-> Either IncrementTxError Tx
dryRunIncrementTx ChainContext
ctx UTxO
spendableUTxO HeadId
headId ConfirmedSnapshot Tx
currentSnapshot Tx
depositDraftTx SlotNo
upperValiditySlot = do
DepositObservation{UTxO
deposited :: UTxO
$sel:deposited:DepositObservation :: DepositObservation -> UTxO
deposited, TxId
depositTxId :: TxId
$sel:depositTxId:DepositObservation :: DepositObservation -> TxId
depositTxId} <-
NetworkId -> Tx -> Maybe DepositObservation
observeDepositTx NetworkId
networkId Tx
depositDraftTx Maybe DepositObservation
-> IncrementTxError -> Either IncrementTxError DepositObservation
forall a e. Maybe a -> e -> Either e a
?> IncrementTxError
CannotObserveDraftedDeposit
PolicyId
pid <- HeadId -> Maybe PolicyId
forall (m :: * -> *). MonadFail m => HeadId -> m PolicyId
headIdToPolicyId HeadId
headId Maybe PolicyId
-> IncrementTxError -> Either IncrementTxError PolicyId
forall a e. Maybe a -> e -> Either e a
?> InvalidHeadIdInIncrement{HeadId
$sel:headId:InvalidHeadSeedInIncrement :: HeadId
headId :: HeadId
headId}
(TxIn
_, TxOut CtxUTxO ConwayEra
headOut) <-
(TxOut CtxUTxO ConwayEra -> Bool)
-> UTxO -> Maybe (TxIn, TxOut CtxUTxO ConwayEra)
forall era.
(TxOut CtxUTxO era -> Bool)
-> UTxO era -> Maybe (TxIn, TxOut CtxUTxO era)
UTxO.find (PlutusScript PlutusScriptV3 -> TxOut CtxUTxO ConwayEra -> Bool
forall lang ctx era.
IsPlutusScriptLanguage lang =>
PlutusScript lang -> TxOut ctx era -> Bool
isScriptTxOut PlutusScript PlutusScriptV3
Head.validatorScript) (PolicyId -> UTxO -> UTxO
utxoOfThisHead PolicyId
pid UTxO
spendableUTxO)
Maybe (TxIn, TxOut CtxUTxO ConwayEra)
-> IncrementTxError
-> Either IncrementTxError (TxIn, TxOut CtxUTxO ConwayEra)
forall a e. Maybe a -> e -> Either e a
?> IncrementTxError
CannotFindHeadOutputInIncrement
(HeadSeed
headSeed, HeadParameters
headParameters) <- TxOut CtxUTxO ConwayEra
-> Either IncrementTxError (HeadSeed, HeadParameters)
decodeOpenDatum TxOut CtxUTxO ConwayEra
headOut
let HeadParameters{[Party]
parties :: [Party]
$sel:parties:HeadParameters :: HeadParameters -> [Party]
parties} = HeadParameters
headParameters
Snapshot{SnapshotVersion
version :: SnapshotVersion
$sel:version:Snapshot :: forall tx. Snapshot tx -> SnapshotVersion
version, SnapshotNumber
number :: SnapshotNumber
$sel:number:Snapshot :: forall tx. Snapshot tx -> SnapshotNumber
number, UTxOType Tx
utxo :: UTxOType Tx
$sel:utxo:Snapshot :: forall tx. Snapshot tx -> UTxOType tx
utxo, HydraAccumulator
accumulator :: HydraAccumulator
$sel:accumulator:Snapshot :: forall tx. Snapshot tx -> HydraAccumulator
accumulator} = ConfirmedSnapshot Tx -> Snapshot Tx
forall tx. IsTx tx => ConfirmedSnapshot tx -> Snapshot tx
getSnapshot ConfirmedSnapshot Tx
currentSnapshot
snapshot :: Snapshot Tx
snapshot =
Snapshot
{ HeadId
headId :: HeadId
$sel:headId:Snapshot :: HeadId
headId
, SnapshotVersion
version :: SnapshotVersion
$sel:version:Snapshot :: SnapshotVersion
version
, $sel:number:Snapshot :: SnapshotNumber
number = SnapshotNumber
number SnapshotNumber -> SnapshotNumber -> SnapshotNumber
forall a. Num a => a -> a -> a
+ SnapshotNumber
1
, $sel:confirmed:Snapshot :: [Tx]
confirmed = []
, UTxOType Tx
utxo :: UTxOType Tx
$sel:utxo:Snapshot :: UTxOType Tx
utxo
, utxoToCommit :: Maybe (UTxOType Tx)
utxoToCommit = UTxO -> Maybe UTxO
forall a. a -> Maybe a
Just UTxO
deposited
, $sel:utxoToDecommit:Snapshot :: Maybe (UTxOType Tx)
utxoToDecommit = Maybe (UTxOType Tx)
Maybe UTxO
forall a. Maybe a
Nothing
, $sel:depositTxId:Snapshot :: Maybe (TxIdType Tx)
depositTxId = TxId -> Maybe TxId
forall a. a -> Maybe a
Just TxId
depositTxId
,
HydraAccumulator
accumulator :: HydraAccumulator
$sel:accumulator:Snapshot :: HydraAccumulator
accumulator
}
signatures :: MultiSignature (Snapshot Tx)
signatures = case ConfirmedSnapshot Tx
currentSnapshot of
ConfirmedSnapshot{$sel:signatures:InitialSnapshot :: forall tx. ConfirmedSnapshot tx -> MultiSignature (Snapshot tx)
signatures = MultiSignature (Snapshot Tx)
sigs} -> MultiSignature (Snapshot Tx)
sigs
ConfirmedSnapshot Tx
_ -> [Signature (Snapshot Tx)] -> MultiSignature (Snapshot Tx)
forall a. [Signature a] -> MultiSignature a
aggregate (Secret (SigningKey HydraKey)
-> Snapshot Tx -> Signature (Snapshot Tx)
forall a.
SignableRepresentation a =>
Secret (SigningKey HydraKey) -> a -> Signature a
sign Secret (SigningKey HydraKey)
dummySigningKey Snapshot Tx
snapshot Signature (Snapshot Tx) -> [Party] -> [Signature (Snapshot Tx)]
forall a b. a -> [b] -> [a]
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ [Party]
parties)
ChainContext
-> UTxO
-> (HeadSeed, HeadId)
-> HeadParameters
-> ConfirmedSnapshot Tx
-> SlotNo
-> Either IncrementTxError Tx
increment
ChainContext
ctx
(UTxO
spendableUTxO UTxO -> UTxO -> UTxO
forall a. Semigroup a => a -> a -> a
<> Tx -> UTxO
utxoFromTx Tx
depositDraftTx)
(HeadSeed
headSeed, HeadId
headId)
HeadParameters
headParameters
ConfirmedSnapshot{Snapshot Tx
$sel:snapshot:InitialSnapshot :: Snapshot Tx
snapshot :: Snapshot Tx
snapshot, MultiSignature (Snapshot Tx)
$sel:signatures:InitialSnapshot :: MultiSignature (Snapshot Tx)
signatures :: MultiSignature (Snapshot Tx)
signatures}
SlotNo
upperValiditySlot
where
dummySigningKey :: Secret (SigningKey HydraKey)
dummySigningKey = ByteString -> Secret (SigningKey HydraKey)
generateSigningKey ByteString
"hydra-dry-run-increment"
ChainContext{NetworkId
$sel:networkId:ChainContext :: ChainContext -> NetworkId
networkId :: NetworkId
networkId} = ChainContext
ctx
decodeOpenDatum :: TxOut CtxUTxO -> Either IncrementTxError (HeadSeed, HeadParameters)
decodeOpenDatum :: TxOut CtxUTxO ConwayEra
-> Either IncrementTxError (HeadSeed, HeadParameters)
decodeOpenDatum TxOut CtxUTxO ConwayEra
headOut =
case HashableScriptData -> Maybe State
forall a. FromScriptData a => HashableScriptData -> Maybe a
fromScriptData (HashableScriptData -> Maybe State)
-> Maybe HashableScriptData -> Maybe State
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< TxOut CtxTx ConwayEra -> Maybe HashableScriptData
forall era. TxOut CtxTx era -> Maybe HashableScriptData
txOutScriptData (TxOut CtxUTxO ConwayEra -> TxOut CtxTx ConwayEra
forall era. TxOut CtxUTxO era -> TxOut CtxTx era
fromCtxUTxOTxOut TxOut CtxUTxO ConwayEra
headOut) of
Just (Head.Open Head.OpenDatum{TxOutRef
headSeed :: TxOutRef
$sel:headSeed:OpenDatum :: OpenDatum -> TxOutRef
headSeed, $sel:parties:OpenDatum :: OpenDatum -> [Party]
parties = [Party]
onChainParties, ContestationPeriod
contestationPeriod :: ContestationPeriod
$sel:contestationPeriod:OpenDatum :: OpenDatum -> ContestationPeriod
contestationPeriod, DepositPeriod
depositPeriod :: DepositPeriod
$sel:depositPeriod:OpenDatum :: OpenDatum -> DepositPeriod
depositPeriod}) -> do
[Party]
parties <- (Party -> Maybe Party) -> [Party] -> Maybe [Party]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse Party -> Maybe Party
forall (m :: * -> *). MonadFail m => Party -> m Party
partyFromChain [Party]
onChainParties Maybe [Party]
-> IncrementTxError -> Either IncrementTxError [Party]
forall a e. Maybe a -> e -> Either e a
?> IncrementTxError
CannotDecodeHeadDatumInIncrement
(HeadSeed, HeadParameters)
-> Either IncrementTxError (HeadSeed, HeadParameters)
forall a. a -> Either IncrementTxError a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
( TxIn -> HeadSeed
txInToHeadSeed (TxOutRef -> TxIn
fromPlutusTxOutRef TxOutRef
headSeed)
, HeadParameters
{ $sel:contestationPeriod:HeadParameters :: ContestationPeriod
contestationPeriod = ContestationPeriod -> ContestationPeriod
ContestationPeriod.fromChain ContestationPeriod
contestationPeriod
, $sel:depositPeriod:HeadParameters :: DepositPeriod
depositPeriod = DepositPeriod -> DepositPeriod
DepositPeriod.fromChain DepositPeriod
depositPeriod
, [Party]
$sel:parties:HeadParameters :: [Party]
parties :: [Party]
parties
}
)
Maybe State
_ -> IncrementTxError
-> Either IncrementTxError (HeadSeed, HeadParameters)
forall a b. a -> Either a b
Left IncrementTxError
CannotDecodeHeadDatumInIncrement
data DecrementTxError
= InvalidHeadSeedInDecrement {DecrementTxError -> HeadSeed
headSeed :: HeadSeed}
| InvalidHeadIdInDecrement {DecrementTxError -> HeadId
headId :: HeadId}
| CannotFindHeadOutputInDecrement
| DecrementValueNegative
| SnapshotDecrementUTxOIsNull
deriving stock (Int -> DecrementTxError -> ShowS
[DecrementTxError] -> ShowS
DecrementTxError -> String
(Int -> DecrementTxError -> ShowS)
-> (DecrementTxError -> String)
-> ([DecrementTxError] -> ShowS)
-> Show DecrementTxError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DecrementTxError -> ShowS
showsPrec :: Int -> DecrementTxError -> ShowS
$cshow :: DecrementTxError -> String
show :: DecrementTxError -> String
$cshowList :: [DecrementTxError] -> ShowS
showList :: [DecrementTxError] -> ShowS
Show)
decrement ::
ChainContext ->
UTxO ->
(HeadSeed, HeadId) ->
HeadParameters ->
ConfirmedSnapshot Tx ->
Either DecrementTxError Tx
decrement :: ChainContext
-> UTxO
-> (HeadSeed, HeadId)
-> HeadParameters
-> ConfirmedSnapshot Tx
-> Either DecrementTxError Tx
decrement ChainContext
ctx UTxO
spendableUTxO (HeadSeed
headSeed, HeadId
headId) HeadParameters
headParameters ConfirmedSnapshot Tx
decrementingSnapshot = do
TxIn
seedTxIn <- HeadSeed -> Maybe TxIn
forall (m :: * -> *). MonadFail m => HeadSeed -> m TxIn
headSeedToTxIn HeadSeed
headSeed Maybe TxIn -> DecrementTxError -> Either DecrementTxError TxIn
forall a e. Maybe a -> e -> Either e a
?> InvalidHeadSeedInDecrement{HeadSeed
$sel:headSeed:InvalidHeadSeedInDecrement :: HeadSeed
headSeed :: HeadSeed
headSeed}
PolicyId
pid <- HeadId -> Maybe PolicyId
forall (m :: * -> *). MonadFail m => HeadId -> m PolicyId
headIdToPolicyId HeadId
headId Maybe PolicyId
-> DecrementTxError -> Either DecrementTxError PolicyId
forall a e. Maybe a -> e -> Either e a
?> InvalidHeadIdInDecrement{HeadId
$sel:headId:InvalidHeadSeedInDecrement :: HeadId
headId :: HeadId
headId}
let utxoOfThisHead' :: UTxO
utxoOfThisHead' = PolicyId -> UTxO -> UTxO
utxoOfThisHead PolicyId
pid UTxO
spendableUTxO
headUTxO :: (TxIn, TxOut CtxUTxO ConwayEra)
headUTxO@(TxIn
_, TxOut CtxUTxO ConwayEra
headOut) <- (TxOut CtxUTxO ConwayEra -> Bool)
-> UTxO -> Maybe (TxIn, TxOut CtxUTxO ConwayEra)
forall era.
(TxOut CtxUTxO era -> Bool)
-> UTxO era -> Maybe (TxIn, TxOut CtxUTxO era)
UTxO.find (PlutusScript PlutusScriptV3 -> TxOut CtxUTxO ConwayEra -> Bool
forall lang ctx era.
IsPlutusScriptLanguage lang =>
PlutusScript lang -> TxOut ctx era -> Bool
isScriptTxOut PlutusScript PlutusScriptV3
Head.validatorScript) UTxO
utxoOfThisHead' Maybe (TxIn, TxOut CtxUTxO ConwayEra)
-> DecrementTxError
-> Either DecrementTxError (TxIn, TxOut CtxUTxO ConwayEra)
forall a e. Maybe a -> e -> Either e a
?> DecrementTxError
CannotFindHeadOutputInDecrement
let balance :: Value
balance = TxOut CtxUTxO ConwayEra -> Value
forall ctx. TxOut ctx -> Value
txOutValue TxOut CtxUTxO ConwayEra
headOut Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value -> Value
negateValue Value
decommitValue
Bool -> Either DecrementTxError () -> Either DecrementTxError ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Value -> Bool
isNegative Value
balance) (Either DecrementTxError () -> Either DecrementTxError ())
-> Either DecrementTxError () -> Either DecrementTxError ()
forall a b. (a -> b) -> a -> b
$
DecrementTxError -> Either DecrementTxError ()
forall a b. a -> Either a b
Left DecrementTxError
DecrementValueNegative
Tx -> Either DecrementTxError Tx
forall a b. b -> Either a b
Right (Tx -> Either DecrementTxError Tx)
-> Tx -> Either DecrementTxError Tx
forall a b. (a -> b) -> a -> b
$
ScriptRegistry
-> VerificationKey PaymentKey
-> (TxIn, HeadId)
-> HeadParameters
-> (TxIn, TxOut CtxUTxO ConwayEra)
-> Snapshot Tx
-> MultiSignature (Snapshot Tx)
-> Tx
decrementTx
ScriptRegistry
scriptRegistry
VerificationKey PaymentKey
ownVerificationKey
(TxIn
seedTxIn, HeadId
headId)
HeadParameters
headParameters
(TxIn, TxOut CtxUTxO ConwayEra)
headUTxO
Snapshot Tx
sn
MultiSignature (Snapshot Tx)
sigs
where
decommitValue :: Value
decommitValue = UTxO -> Value
forall era. UTxO era -> Value
UTxO.totalValue (UTxO -> Value) -> UTxO -> Value
forall a b. (a -> b) -> a -> b
$ UTxO -> Maybe UTxO -> UTxO
forall a. a -> Maybe a -> a
fromMaybe UTxO
forall a. Monoid a => a
mempty (Maybe UTxO -> UTxO) -> Maybe UTxO -> UTxO
forall a b. (a -> b) -> a -> b
$ Snapshot Tx -> Maybe (UTxOType Tx)
forall tx. Snapshot tx -> Maybe (UTxOType tx)
utxoToDecommit Snapshot Tx
sn
isNegative :: Value -> Bool
isNegative = ((AssetId, Quantity) -> Bool) -> [(AssetId, Quantity)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ((Quantity -> Quantity -> Bool
forall a. Ord a => a -> a -> Bool
< Quantity
0) (Quantity -> Bool)
-> ((AssetId, Quantity) -> Quantity) -> (AssetId, Quantity) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (AssetId, Quantity) -> Quantity
forall a b. (a, b) -> b
snd) ([(AssetId, Quantity)] -> Bool)
-> (Value -> [(AssetId, Quantity)]) -> Value -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> [(AssetId, Quantity)]
Value -> [Item Value]
forall l. IsList l => l -> [Item l]
IsList.toList
(Snapshot Tx
sn, MultiSignature (Snapshot Tx)
sigs) =
case ConfirmedSnapshot Tx
decrementingSnapshot of
ConfirmedSnapshot{Snapshot Tx
$sel:snapshot:InitialSnapshot :: forall tx. ConfirmedSnapshot tx -> Snapshot tx
snapshot :: Snapshot Tx
snapshot, MultiSignature (Snapshot Tx)
$sel:signatures:InitialSnapshot :: forall tx. ConfirmedSnapshot tx -> MultiSignature (Snapshot tx)
signatures :: MultiSignature (Snapshot Tx)
signatures} -> (Snapshot Tx
snapshot, MultiSignature (Snapshot Tx)
signatures)
ConfirmedSnapshot Tx
_ -> (ConfirmedSnapshot Tx -> Snapshot Tx
forall tx. IsTx tx => ConfirmedSnapshot tx -> Snapshot tx
getSnapshot ConfirmedSnapshot Tx
decrementingSnapshot, MultiSignature (Snapshot Tx)
forall a. Monoid a => a
mempty)
ChainContext{VerificationKey PaymentKey
$sel:ownVerificationKey:ChainContext :: ChainContext -> VerificationKey PaymentKey
ownVerificationKey :: VerificationKey PaymentKey
ownVerificationKey, ScriptRegistry
$sel:scriptRegistry:ChainContext :: ChainContext -> ScriptRegistry
scriptRegistry :: ScriptRegistry
scriptRegistry} = ChainContext
ctx
data CloseTxError
= InvalidHeadIdInClose {CloseTxError -> HeadId
headId :: HeadId}
| CannotFindHeadOutputToClose
| BothCommitAndDecommitInClose
deriving stock (Int -> CloseTxError -> ShowS
[CloseTxError] -> ShowS
CloseTxError -> String
(Int -> CloseTxError -> ShowS)
-> (CloseTxError -> String)
-> ([CloseTxError] -> ShowS)
-> Show CloseTxError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CloseTxError -> ShowS
showsPrec :: Int -> CloseTxError -> ShowS
$cshow :: CloseTxError -> String
show :: CloseTxError -> String
$cshowList :: [CloseTxError] -> ShowS
showList :: [CloseTxError] -> ShowS
Show)
data RecoverTxError
= InvalidHeadIdInRecover {RecoverTxError -> HeadId
headId :: HeadId}
| CannotFindDepositOutputToRecover {RecoverTxError -> TxId
depositTxId :: TxId}
| CannotFindDepositedOutputToRecover {RecoverTxError -> TxId
depositedTxId :: TxId}
deriving stock (Int -> RecoverTxError -> ShowS
[RecoverTxError] -> ShowS
RecoverTxError -> String
(Int -> RecoverTxError -> ShowS)
-> (RecoverTxError -> String)
-> ([RecoverTxError] -> ShowS)
-> Show RecoverTxError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> RecoverTxError -> ShowS
showsPrec :: Int -> RecoverTxError -> ShowS
$cshow :: RecoverTxError -> String
show :: RecoverTxError -> String
$cshowList :: [RecoverTxError] -> ShowS
showList :: [RecoverTxError] -> ShowS
Show)
recover ::
ChainContext ->
HeadId ->
TxId ->
UTxO ->
SlotNo ->
Either RecoverTxError Tx
recover :: ChainContext
-> HeadId -> TxId -> UTxO -> SlotNo -> Either RecoverTxError Tx
recover ChainContext
ctx HeadId
headId TxId
depositedTxId UTxO
spendableUTxO SlotNo
lowerValiditySlot = do
(TxIn
_, TxOut CtxUTxO ConwayEra
depositedOut) <-
(TxIn -> TxOut CtxUTxO ConwayEra -> Bool)
-> UTxO -> Maybe (TxIn, TxOut CtxUTxO ConwayEra)
forall era.
(TxIn -> TxOut CtxUTxO era -> Bool)
-> UTxO era -> Maybe (TxIn, TxOut CtxUTxO era)
UTxO.findWithKey
( \TxIn
txin TxOut CtxUTxO ConwayEra
txout ->
TxIn
txin TxIn -> TxIn -> Bool
forall a. Eq a => a -> a -> Bool
== TxId -> TxIx -> TxIn
TxIn TxId
depositedTxId (Word -> TxIx
TxIx Word
0) Bool -> Bool -> Bool
&& PlutusScript PlutusScriptV3 -> TxOut CtxUTxO ConwayEra -> Bool
forall lang ctx era.
IsPlutusScriptLanguage lang =>
PlutusScript lang -> TxOut ctx era -> Bool
isScriptTxOut PlutusScript PlutusScriptV3
depositValidatorScript TxOut CtxUTxO ConwayEra
txout
)
UTxO
spendableUTxO
Maybe (TxIn, TxOut CtxUTxO ConwayEra)
-> RecoverTxError
-> Either RecoverTxError (TxIn, TxOut CtxUTxO ConwayEra)
forall a e. Maybe a -> e -> Either e a
?> CannotFindDepositOutputToRecover{$sel:depositTxId:InvalidHeadIdInRecover :: TxId
depositTxId = TxId
depositedTxId}
(HeadId
headId', UTxO
deposited, POSIXTime
_deadline) <-
Network
-> TxOut CtxUTxO ConwayEra -> Maybe (HeadId, UTxO, POSIXTime)
observeDepositTxOut (NetworkId -> Network
toShelleyNetwork NetworkId
networkId) TxOut CtxUTxO ConwayEra
depositedOut
Maybe (HeadId, UTxO, POSIXTime)
-> RecoverTxError
-> Either RecoverTxError (HeadId, UTxO, POSIXTime)
forall a e. Maybe a -> e -> Either e a
?> CannotFindDepositedOutputToRecover{$sel:depositedTxId:InvalidHeadIdInRecover :: TxId
depositedTxId = TxId
depositedTxId}
if HeadId
headId HeadId -> HeadId -> Bool
forall a. Eq a => a -> a -> Bool
/= HeadId
headId'
then RecoverTxError -> Either RecoverTxError Tx
forall a b. a -> Either a b
Left InvalidHeadIdInRecover{HeadId
$sel:headId:InvalidHeadIdInRecover :: HeadId
headId :: HeadId
headId}
else Tx -> Either RecoverTxError Tx
forall a b. b -> Either a b
Right (Tx -> Either RecoverTxError Tx) -> Tx -> Either RecoverTxError Tx
forall a b. (a -> b) -> a -> b
$ TxId -> UTxO -> SlotNo -> Tx
recoverTx TxId
depositedTxId UTxO
deposited SlotNo
lowerValiditySlot
where
ChainContext{NetworkId
$sel:networkId:ChainContext :: ChainContext -> NetworkId
networkId :: NetworkId
networkId} = ChainContext
ctx
close ::
ChainContext ->
UTxO ->
HeadId ->
HeadParameters ->
SnapshotVersion ->
ConfirmedSnapshot Tx ->
SlotNo ->
PointInTime ->
Either CloseTxError Tx
close :: ChainContext
-> UTxO
-> HeadId
-> HeadParameters
-> SnapshotVersion
-> ConfirmedSnapshot Tx
-> SlotNo
-> PointInTime
-> Either CloseTxError Tx
close ChainContext
ctx UTxO
spendableUTxO HeadId
headId HeadParameters{[Party]
$sel:parties:HeadParameters :: HeadParameters -> [Party]
parties :: [Party]
parties, ContestationPeriod
$sel:contestationPeriod:HeadParameters :: HeadParameters -> ContestationPeriod
contestationPeriod :: ContestationPeriod
contestationPeriod, DepositPeriod
$sel:depositPeriod:HeadParameters :: HeadParameters -> DepositPeriod
depositPeriod :: DepositPeriod
depositPeriod} SnapshotVersion
openVersion ConfirmedSnapshot Tx
confirmedSnapshot SlotNo
startSlotNo PointInTime
pointInTime = do
PolicyId
pid <- HeadId -> Maybe PolicyId
forall (m :: * -> *). MonadFail m => HeadId -> m PolicyId
headIdToPolicyId HeadId
headId Maybe PolicyId -> CloseTxError -> Either CloseTxError PolicyId
forall a e. Maybe a -> e -> Either e a
?> InvalidHeadIdInClose{HeadId
$sel:headId:InvalidHeadIdInClose :: HeadId
headId :: HeadId
headId}
(TxIn, TxOut CtxUTxO ConwayEra)
headUTxO <-
(TxOut CtxUTxO ConwayEra -> Bool)
-> UTxO -> Maybe (TxIn, TxOut CtxUTxO ConwayEra)
forall era.
(TxOut CtxUTxO era -> Bool)
-> UTxO era -> Maybe (TxIn, TxOut CtxUTxO era)
UTxO.find (PlutusScript PlutusScriptV3 -> TxOut CtxUTxO ConwayEra -> Bool
forall lang ctx era.
IsPlutusScriptLanguage lang =>
PlutusScript lang -> TxOut ctx era -> Bool
isScriptTxOut PlutusScript PlutusScriptV3
Head.validatorScript) (PolicyId -> UTxO -> UTxO
utxoOfThisHead PolicyId
pid UTxO
spendableUTxO)
Maybe (TxIn, TxOut CtxUTxO ConwayEra)
-> CloseTxError
-> Either CloseTxError (TxIn, TxOut CtxUTxO ConwayEra)
forall a e. Maybe a -> e -> Either e a
?> CloseTxError
CannotFindHeadOutputToClose
let openThreadOutput :: OpenThreadOutput
openThreadOutput =
OpenThreadOutput
{ $sel:openThreadUTxO:OpenThreadOutput :: (TxIn, TxOut CtxUTxO ConwayEra)
openThreadUTxO = (TxIn, TxOut CtxUTxO ConwayEra)
headUTxO
, $sel:openContestationPeriod:OpenThreadOutput :: ContestationPeriod
openContestationPeriod = ContestationPeriod -> ContestationPeriod
ContestationPeriod.toChain ContestationPeriod
contestationPeriod
, $sel:openDepositPeriod:OpenThreadOutput :: DepositPeriod
openDepositPeriod = DepositPeriod -> DepositPeriod
DepositPeriod.toChain DepositPeriod
depositPeriod
, $sel:openParties:OpenThreadOutput :: [Party]
openParties = Party -> Party
partyToChain (Party -> Party) -> [Party] -> [Party]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Party]
parties
}
IncrementalAction
incrementalAction <- Maybe UTxO -> Maybe UTxO -> Maybe IncrementalAction
setIncrementalActionMaybe Maybe (UTxOType Tx)
Maybe UTxO
utxoToCommit Maybe (UTxOType Tx)
Maybe UTxO
utxoToDecommit Maybe IncrementalAction
-> CloseTxError -> Either CloseTxError IncrementalAction
forall a e. Maybe a -> e -> Either e a
?> CloseTxError
BothCommitAndDecommitInClose
Tx -> Either CloseTxError Tx
forall a. a -> Either CloseTxError a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Tx -> Either CloseTxError Tx) -> Tx -> Either CloseTxError Tx
forall a b. (a -> b) -> a -> b
$ ScriptRegistry
-> VerificationKey PaymentKey
-> HeadId
-> SnapshotVersion
-> ConfirmedSnapshot Tx
-> SlotNo
-> PointInTime
-> OpenThreadOutput
-> IncrementalAction
-> Tx
closeTx ScriptRegistry
scriptRegistry VerificationKey PaymentKey
ownVerificationKey HeadId
headId SnapshotVersion
openVersion ConfirmedSnapshot Tx
confirmedSnapshot SlotNo
startSlotNo PointInTime
pointInTime OpenThreadOutput
openThreadOutput IncrementalAction
incrementalAction
where
Snapshot{Maybe (UTxOType Tx)
utxoToCommit :: forall tx. Snapshot tx -> Maybe (UTxOType tx)
utxoToCommit :: Maybe (UTxOType Tx)
utxoToCommit, Maybe (UTxOType Tx)
$sel:utxoToDecommit:Snapshot :: forall tx. Snapshot tx -> Maybe (UTxOType tx)
utxoToDecommit :: Maybe (UTxOType Tx)
utxoToDecommit} = ConfirmedSnapshot Tx -> Snapshot Tx
forall tx. IsTx tx => ConfirmedSnapshot tx -> Snapshot tx
getSnapshot ConfirmedSnapshot Tx
confirmedSnapshot
ChainContext{VerificationKey PaymentKey
$sel:ownVerificationKey:ChainContext :: ChainContext -> VerificationKey PaymentKey
ownVerificationKey :: VerificationKey PaymentKey
ownVerificationKey, ScriptRegistry
$sel:scriptRegistry:ChainContext :: ChainContext -> ScriptRegistry
scriptRegistry :: ScriptRegistry
scriptRegistry} = ChainContext
ctx
data ContestTxError
= InvalidHeadIdInContest {ContestTxError -> HeadId
headId :: HeadId}
| CannotFindHeadOutputToContest
| MissingHeadDatumInContest
| MissingHeadRedeemerInContest
| WrongDatumInContest
| FailedToConvertFromScriptDataInContest
deriving stock (Int -> ContestTxError -> ShowS
[ContestTxError] -> ShowS
ContestTxError -> String
(Int -> ContestTxError -> ShowS)
-> (ContestTxError -> String)
-> ([ContestTxError] -> ShowS)
-> Show ContestTxError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ContestTxError -> ShowS
showsPrec :: Int -> ContestTxError -> ShowS
$cshow :: ContestTxError -> String
show :: ContestTxError -> String
$cshowList :: [ContestTxError] -> ShowS
showList :: [ContestTxError] -> ShowS
Show)
contest ::
ChainContext ->
UTxO ->
HeadId ->
ContestationPeriod ->
SnapshotVersion ->
ConfirmedSnapshot Tx ->
PointInTime ->
Either ContestTxError Tx
contest :: ChainContext
-> UTxO
-> HeadId
-> ContestationPeriod
-> SnapshotVersion
-> ConfirmedSnapshot Tx
-> PointInTime
-> Either ContestTxError Tx
contest ChainContext
ctx UTxO
spendableUTxO HeadId
headId ContestationPeriod
contestationPeriod SnapshotVersion
openVersion ConfirmedSnapshot Tx
contestingSnapshot PointInTime
pointInTime = do
PolicyId
pid <- HeadId -> Maybe PolicyId
forall (m :: * -> *). MonadFail m => HeadId -> m PolicyId
headIdToPolicyId HeadId
headId Maybe PolicyId -> ContestTxError -> Either ContestTxError PolicyId
forall a e. Maybe a -> e -> Either e a
?> InvalidHeadIdInContest{HeadId
$sel:headId:InvalidHeadIdInContest :: HeadId
headId :: HeadId
headId}
(TxIn, TxOut CtxUTxO ConwayEra)
headUTxO <-
(TxOut CtxUTxO ConwayEra -> Bool)
-> UTxO -> Maybe (TxIn, TxOut CtxUTxO ConwayEra)
forall era.
(TxOut CtxUTxO era -> Bool)
-> UTxO era -> Maybe (TxIn, TxOut CtxUTxO era)
UTxO.find (PlutusScript PlutusScriptV3 -> TxOut CtxUTxO ConwayEra -> Bool
forall lang ctx era.
IsPlutusScriptLanguage lang =>
PlutusScript lang -> TxOut ctx era -> Bool
isScriptTxOut PlutusScript PlutusScriptV3
Head.validatorScript) (PolicyId -> UTxO -> UTxO
utxoOfThisHead PolicyId
pid UTxO
spendableUTxO)
Maybe (TxIn, TxOut CtxUTxO ConwayEra)
-> ContestTxError
-> Either ContestTxError (TxIn, TxOut CtxUTxO ConwayEra)
forall a e. Maybe a -> e -> Either e a
?> ContestTxError
CannotFindHeadOutputToContest
ClosedThreadOutput
closedThreadOutput <- (TxIn, TxOut CtxUTxO ConwayEra)
-> Either ContestTxError ClosedThreadOutput
extractProgressDatum (TxIn, TxOut CtxUTxO ConwayEra)
headUTxO
Tx -> Either ContestTxError Tx
forall a. a -> Either ContestTxError a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Tx -> Either ContestTxError Tx) -> Tx -> Either ContestTxError Tx
forall a b. (a -> b) -> a -> b
$ ScriptRegistry
-> VerificationKey PaymentKey
-> HeadId
-> ContestationPeriod
-> SnapshotVersion
-> Snapshot Tx
-> MultiSignature (Snapshot Tx)
-> PointInTime
-> ClosedThreadOutput
-> Tx
contestTx ScriptRegistry
scriptRegistry VerificationKey PaymentKey
ownVerificationKey HeadId
headId ContestationPeriod
contestationPeriod SnapshotVersion
openVersion Snapshot Tx
sn MultiSignature (Snapshot Tx)
sigs PointInTime
pointInTime ClosedThreadOutput
closedThreadOutput
where
extractProgressDatum :: (TxIn, TxOut CtxUTxO ConwayEra)
-> Either ContestTxError ClosedThreadOutput
extractProgressDatum headUTxO :: (TxIn, TxOut CtxUTxO ConwayEra)
headUTxO@(TxIn
_, TxOut CtxUTxO ConwayEra
headOutput) = do
HashableScriptData
headDatum <- TxOut CtxTx ConwayEra -> Maybe HashableScriptData
forall era. TxOut CtxTx era -> Maybe HashableScriptData
txOutScriptData (TxOut CtxUTxO ConwayEra -> TxOut CtxTx ConwayEra
forall era. TxOut CtxUTxO era -> TxOut CtxTx era
fromCtxUTxOTxOut TxOut CtxUTxO ConwayEra
headOutput) Maybe HashableScriptData
-> ContestTxError -> Either ContestTxError HashableScriptData
forall a e. Maybe a -> e -> Either e a
?> ContestTxError
MissingHeadDatumInContest
State
datum <- HashableScriptData -> Maybe State
forall a. FromScriptData a => HashableScriptData -> Maybe a
fromScriptData HashableScriptData
headDatum Maybe State -> ContestTxError -> Either ContestTxError State
forall a e. Maybe a -> e -> Either e a
?> ContestTxError
FailedToConvertFromScriptDataInContest
case State
datum of
Head.Closed Head.ClosedDatum{[PubKeyHash]
contesters :: [PubKeyHash]
$sel:contesters:ClosedDatum :: ClosedDatum -> [PubKeyHash]
contesters, [Party]
parties :: [Party]
$sel:parties:ClosedDatum :: ClosedDatum -> [Party]
parties, POSIXTime
contestationDeadline :: POSIXTime
$sel:contestationDeadline:ClosedDatum :: ClosedDatum -> POSIXTime
contestationDeadline, Integer
headAdaOverhead :: Integer
$sel:headAdaOverhead:ClosedDatum :: ClosedDatum -> Integer
headAdaOverhead, DepositPeriod
depositPeriod :: DepositPeriod
$sel:depositPeriod:ClosedDatum :: ClosedDatum -> DepositPeriod
depositPeriod} -> do
let closedThreadUTxO :: (TxIn, TxOut CtxUTxO ConwayEra)
closedThreadUTxO = (TxIn, TxOut CtxUTxO ConwayEra)
headUTxO
closedParties :: [Party]
closedParties = [Party]
parties
closedContestationDeadline :: POSIXTime
closedContestationDeadline = POSIXTime
contestationDeadline
closedContesters :: [PubKeyHash]
closedContesters = [PubKeyHash]
contesters
ClosedThreadOutput -> Either ContestTxError ClosedThreadOutput
forall a. a -> Either ContestTxError a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ClosedThreadOutput -> Either ContestTxError ClosedThreadOutput)
-> ClosedThreadOutput -> Either ContestTxError ClosedThreadOutput
forall a b. (a -> b) -> a -> b
$
ClosedThreadOutput
{ (TxIn, TxOut CtxUTxO ConwayEra)
closedThreadUTxO :: (TxIn, TxOut CtxUTxO ConwayEra)
$sel:closedThreadUTxO:ClosedThreadOutput :: (TxIn, TxOut CtxUTxO ConwayEra)
closedThreadUTxO
, [Party]
closedParties :: [Party]
$sel:closedParties:ClosedThreadOutput :: [Party]
closedParties
, POSIXTime
closedContestationDeadline :: POSIXTime
$sel:closedContestationDeadline:ClosedThreadOutput :: POSIXTime
closedContestationDeadline
, [PubKeyHash]
closedContesters :: [PubKeyHash]
$sel:closedContesters:ClosedThreadOutput :: [PubKeyHash]
closedContesters
, $sel:closedHeadAdaOverhead:ClosedThreadOutput :: Integer
closedHeadAdaOverhead = Integer
headAdaOverhead
, $sel:closedDepositPeriod:ClosedThreadOutput :: DepositPeriod
closedDepositPeriod = DepositPeriod
depositPeriod
}
State
_ -> ContestTxError -> Either ContestTxError ClosedThreadOutput
forall a b. a -> Either a b
Left ContestTxError
WrongDatumInContest
(Snapshot Tx
sn, MultiSignature (Snapshot Tx)
sigs) =
case ConfirmedSnapshot Tx
contestingSnapshot of
ConfirmedSnapshot{Snapshot Tx
$sel:snapshot:InitialSnapshot :: forall tx. ConfirmedSnapshot tx -> Snapshot tx
snapshot :: Snapshot Tx
snapshot, MultiSignature (Snapshot Tx)
$sel:signatures:InitialSnapshot :: forall tx. ConfirmedSnapshot tx -> MultiSignature (Snapshot tx)
signatures :: MultiSignature (Snapshot Tx)
signatures} -> (Snapshot Tx
snapshot, MultiSignature (Snapshot Tx)
signatures)
ConfirmedSnapshot Tx
_ -> (ConfirmedSnapshot Tx -> Snapshot Tx
forall tx. IsTx tx => ConfirmedSnapshot tx -> Snapshot tx
getSnapshot ConfirmedSnapshot Tx
contestingSnapshot, MultiSignature (Snapshot Tx)
forall a. Monoid a => a
mempty)
ChainContext{VerificationKey PaymentKey
$sel:ownVerificationKey:ChainContext :: ChainContext -> VerificationKey PaymentKey
ownVerificationKey :: VerificationKey PaymentKey
ownVerificationKey, ScriptRegistry
$sel:scriptRegistry:ChainContext :: ChainContext -> ScriptRegistry
scriptRegistry :: ScriptRegistry
scriptRegistry} = ChainContext
ctx
data FanoutTxError
= CannotFindHeadOutputToFanout
| MissingHeadDatumInFanout
| WrongDatumInFanout
| FailedToConvertFromScriptDataInFanout
| BothCommitAndDecommitInFanout
| FailedToCreateFanoutProof Text
deriving stock (Int -> FanoutTxError -> ShowS
[FanoutTxError] -> ShowS
FanoutTxError -> String
(Int -> FanoutTxError -> ShowS)
-> (FanoutTxError -> String)
-> ([FanoutTxError] -> ShowS)
-> Show FanoutTxError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> FanoutTxError -> ShowS
showsPrec :: Int -> FanoutTxError -> ShowS
$cshow :: FanoutTxError -> String
show :: FanoutTxError -> String
$cshowList :: [FanoutTxError] -> ShowS
showList :: [FanoutTxError] -> ShowS
Show)
fanout ::
ChainContext ->
UTxO ->
TxIn ->
UTxO ->
Maybe UTxO ->
Maybe UTxO ->
UTxO ->
SlotNo ->
Either FanoutTxError Tx
fanout :: ChainContext
-> UTxO
-> TxIn
-> UTxO
-> Maybe UTxO
-> Maybe UTxO
-> UTxO
-> SlotNo
-> Either FanoutTxError Tx
fanout ChainContext
ctx UTxO
spendableUTxO TxIn
seedTxIn UTxO
utxo Maybe UTxO
utxoToCommit Maybe UTxO
utxoToDecommit UTxO
utxoForProof SlotNo
deadlineSlotNo = do
(TxIn, TxOut CtxUTxO ConwayEra)
headUTxO <-
(TxOut CtxUTxO ConwayEra -> Bool)
-> UTxO -> Maybe (TxIn, TxOut CtxUTxO ConwayEra)
forall era.
(TxOut CtxUTxO era -> Bool)
-> UTxO era -> Maybe (TxIn, TxOut CtxUTxO era)
UTxO.find (PlutusScript PlutusScriptV3 -> TxOut CtxUTxO ConwayEra -> Bool
forall lang ctx era.
IsPlutusScriptLanguage lang =>
PlutusScript lang -> TxOut ctx era -> Bool
isScriptTxOut PlutusScript PlutusScriptV3
Head.validatorScript) (PolicyId -> UTxO -> UTxO
utxoOfThisHead (TxIn -> PolicyId
headPolicyId TxIn
seedTxIn) UTxO
spendableUTxO)
Maybe (TxIn, TxOut CtxUTxO ConwayEra)
-> FanoutTxError
-> Either FanoutTxError (TxIn, TxOut CtxUTxO ConwayEra)
forall a e. Maybe a -> e -> Either e a
?> FanoutTxError
CannotFindHeadOutputToFanout
(TxIn, TxOut CtxUTxO ConwayEra)
closedThreadUTxO <- (TxIn, TxOut CtxUTxO ConwayEra)
-> Either FanoutTxError (TxIn, TxOut CtxUTxO ConwayEra)
extractProgressDatum (TxIn, TxOut CtxUTxO ConwayEra)
headUTxO
IncrementalAction
_ <- Maybe UTxO -> Maybe UTxO -> Maybe IncrementalAction
setIncrementalActionMaybe Maybe UTxO
utxoToCommit Maybe UTxO
utxoToDecommit Maybe IncrementalAction
-> FanoutTxError -> Either FanoutTxError IncrementalAction
forall a e. Maybe a -> e -> Either e a
?> FanoutTxError
BothCommitAndDecommitInFanout
ScriptRegistry
-> UTxO
-> Maybe UTxO
-> Maybe UTxO
-> UTxO
-> (TxIn, TxOut CtxUTxO ConwayEra)
-> SlotNo
-> PlutusScript PlutusScriptV3
-> Either Text Tx
fanoutTx ScriptRegistry
scriptRegistry UTxO
utxo Maybe UTxO
utxoToCommit Maybe UTxO
utxoToDecommit UTxO
utxoForProof (TxIn, TxOut CtxUTxO ConwayEra)
closedThreadUTxO SlotNo
deadlineSlotNo PlutusScript PlutusScriptV3
headTokenScript
Either Text Tx
-> (Either Text Tx -> Either FanoutTxError Tx)
-> Either FanoutTxError Tx
forall a b. a -> (a -> b) -> b
& (Text -> FanoutTxError)
-> Either Text Tx -> Either FanoutTxError Tx
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first Text -> FanoutTxError
FailedToCreateFanoutProof
where
headTokenScript :: PlutusScript PlutusScriptV3
headTokenScript = TxIn -> PlutusScript PlutusScriptV3
mkHeadTokenScript TxIn
seedTxIn
ChainContext{ScriptRegistry
$sel:scriptRegistry:ChainContext :: ChainContext -> ScriptRegistry
scriptRegistry :: ScriptRegistry
scriptRegistry} = ChainContext
ctx
extractProgressDatum :: (TxIn, TxOut CtxUTxO) -> Either FanoutTxError (TxIn, TxOut CtxUTxO)
extractProgressDatum :: (TxIn, TxOut CtxUTxO ConwayEra)
-> Either FanoutTxError (TxIn, TxOut CtxUTxO ConwayEra)
extractProgressDatum headUTxO :: (TxIn, TxOut CtxUTxO ConwayEra)
headUTxO@(TxIn
_, TxOut CtxUTxO ConwayEra
headOutput) = do
HashableScriptData
headDatum <-
TxOut CtxTx ConwayEra -> Maybe HashableScriptData
forall era. TxOut CtxTx era -> Maybe HashableScriptData
txOutScriptData (TxOut CtxUTxO ConwayEra -> TxOut CtxTx ConwayEra
forall era. TxOut CtxUTxO era -> TxOut CtxTx era
fromCtxUTxOTxOut TxOut CtxUTxO ConwayEra
headOutput) Maybe HashableScriptData
-> FanoutTxError -> Either FanoutTxError HashableScriptData
forall a e. Maybe a -> e -> Either e a
?> FanoutTxError
MissingHeadDatumInFanout
State
datum <-
HashableScriptData -> Maybe State
forall a. FromScriptData a => HashableScriptData -> Maybe a
fromScriptData HashableScriptData
headDatum Maybe State -> FanoutTxError -> Either FanoutTxError State
forall a e. Maybe a -> e -> Either e a
?> FanoutTxError
FailedToConvertFromScriptDataInFanout
case State
datum of
Head.Closed{} -> (TxIn, TxOut CtxUTxO ConwayEra)
-> Either FanoutTxError (TxIn, TxOut CtxUTxO ConwayEra)
forall a. a -> Either FanoutTxError a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (TxIn, TxOut CtxUTxO ConwayEra)
headUTxO
State
_ -> FanoutTxError
-> Either FanoutTxError (TxIn, TxOut CtxUTxO ConwayEra)
forall a b. a -> Either a b
Left FanoutTxError
WrongDatumInFanout
data PartialFanoutError
= CannotFindHeadOutput
| MissingHeadDatum
| WrongDatum
| FailedToConvertFromScriptData
|
StaleChainState
|
CannotCreateProof Text
deriving stock (PartialFanoutError -> PartialFanoutError -> Bool
(PartialFanoutError -> PartialFanoutError -> Bool)
-> (PartialFanoutError -> PartialFanoutError -> Bool)
-> Eq PartialFanoutError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PartialFanoutError -> PartialFanoutError -> Bool
== :: PartialFanoutError -> PartialFanoutError -> Bool
$c/= :: PartialFanoutError -> PartialFanoutError -> Bool
/= :: PartialFanoutError -> PartialFanoutError -> Bool
Eq, Int -> PartialFanoutError -> ShowS
[PartialFanoutError] -> ShowS
PartialFanoutError -> String
(Int -> PartialFanoutError -> ShowS)
-> (PartialFanoutError -> String)
-> ([PartialFanoutError] -> ShowS)
-> Show PartialFanoutError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PartialFanoutError -> ShowS
showsPrec :: Int -> PartialFanoutError -> ShowS
$cshow :: PartialFanoutError -> String
show :: PartialFanoutError -> String
$cshowList :: [PartialFanoutError] -> ShowS
showList :: [PartialFanoutError] -> ShowS
Show)
partialFanout ::
ChainContext ->
UTxO ->
TxIn ->
Int ->
UTxO ->
UTxO ->
SlotNo ->
Either PartialFanoutError Tx
partialFanout :: ChainContext
-> UTxO
-> TxIn
-> Int
-> UTxO
-> UTxO
-> SlotNo
-> Either PartialFanoutError Tx
partialFanout ChainContext
ctx UTxO
spendableUTxO TxIn
seedTxIn Int
chunkSize UTxO
proofUTxO UTxO
remainingUTxO SlotNo
deadlineSlotNo = do
(TxIn, TxOut CtxUTxO ConwayEra)
headUTxO <-
(TxOut CtxUTxO ConwayEra -> Bool)
-> UTxO -> Maybe (TxIn, TxOut CtxUTxO ConwayEra)
forall era.
(TxOut CtxUTxO era -> Bool)
-> UTxO era -> Maybe (TxIn, TxOut CtxUTxO era)
UTxO.find (PlutusScript PlutusScriptV3 -> TxOut CtxUTxO ConwayEra -> Bool
forall lang ctx era.
IsPlutusScriptLanguage lang =>
PlutusScript lang -> TxOut ctx era -> Bool
isScriptTxOut PlutusScript PlutusScriptV3
Head.validatorScript) (PolicyId -> UTxO -> UTxO
utxoOfThisHead (TxIn -> PolicyId
headPolicyId TxIn
seedTxIn) UTxO
spendableUTxO)
Maybe (TxIn, TxOut CtxUTxO ConwayEra)
-> PartialFanoutError
-> Either PartialFanoutError (TxIn, TxOut CtxUTxO ConwayEra)
forall a e. Maybe a -> e -> Either e a
?> PartialFanoutError
CannotFindHeadOutput
State
headState <- (TxIn, TxOut CtxUTxO ConwayEra) -> Either PartialFanoutError State
readHeadState (TxIn, TxOut CtxUTxO ConwayEra)
headUTxO
FanoutProgressDatum
progressDatum <- case State
headState of
Head.Closed ClosedDatum
closedDatum -> FanoutProgressDatum
-> Either PartialFanoutError FanoutProgressDatum
forall a. a -> Either PartialFanoutError a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ClosedDatum -> FanoutProgressDatum
Head.progressFromClosed ClosedDatum
closedDatum)
Head.FanoutProgress FanoutProgressDatum
d -> FanoutProgressDatum
-> Either PartialFanoutError FanoutProgressDatum
forall a. a -> Either PartialFanoutError a
forall (f :: * -> *) a. Applicative f => a -> f a
pure FanoutProgressDatum
d
State
_ -> PartialFanoutError -> Either PartialFanoutError FanoutProgressDatum
forall a b. a -> Either a b
Left PartialFanoutError
WrongDatum
HydraAccumulator
_fullAccumulator <- FanoutProgressDatum
-> UTxO -> Either PartialFanoutError HydraAccumulator
buildAndVerifyAccumulator FanoutProgressDatum
progressDatum UTxO
proofUTxO
let allPairs :: [(TxIn, TxOut CtxUTxO ConwayEra)]
allPairs = UTxO -> [(TxIn, TxOut CtxUTxO ConwayEra)]
forall era. UTxO era -> [(TxIn, TxOut CtxUTxO era)]
UTxO.toList UTxO
remainingUTxO
utxoToDistribute :: UTxO
utxoToDistribute = [(TxIn, TxOut CtxUTxO ConwayEra)] -> UTxO
forall era. [(TxIn, TxOut CtxUTxO era)] -> UTxO era
UTxO.fromList (Int
-> [(TxIn, TxOut CtxUTxO ConwayEra)]
-> [(TxIn, TxOut CtxUTxO ConwayEra)]
forall a. Int -> [a] -> [a]
take Int
chunkSize [(TxIn, TxOut CtxUTxO ConwayEra)]
allPairs)
Bool
-> Either PartialFanoutError () -> Either PartialFanoutError ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (UTxO -> Bool
forall era. UTxO era -> Bool
UTxO.null UTxO
utxoToDistribute) (Either PartialFanoutError () -> Either PartialFanoutError ())
-> Either PartialFanoutError () -> Either PartialFanoutError ()
forall a b. (a -> b) -> a -> b
$ PartialFanoutError -> Either PartialFanoutError ()
forall a b. a -> Either a b
Left (Text -> PartialFanoutError
CannotCreateProof Text
"utxoToDistribute must not be empty")
let rest :: UTxO
rest = [(TxIn, TxOut CtxUTxO ConwayEra)] -> UTxO
forall era. [(TxIn, TxOut CtxUTxO era)] -> UTxO era
UTxO.fromList (Int
-> [(TxIn, TxOut CtxUTxO ConwayEra)]
-> [(TxIn, TxOut CtxUTxO ConwayEra)]
forall a. Int -> [a] -> [a]
drop Int
chunkSize [(TxIn, TxOut CtxUTxO ConwayEra)]
allPairs)
presettled :: UTxO
presettled = UTxO -> UTxO -> UTxO
forall era. UTxO era -> UTxO era -> UTxO era
UTxO.difference UTxO
proofUTxO UTxO
remainingUTxO
let remainingAccumulator :: HydraAccumulator
remainingAccumulator = forall tx. IsTx tx => UTxOType tx -> HydraAccumulator
Accumulator.buildFromUTxO @Tx (UTxO
rest UTxO -> UTxO -> UTxO
forall a. Semigroup a => a -> a -> a
<> UTxO
presettled)
Tx -> Either PartialFanoutError Tx
forall a. a -> Either PartialFanoutError a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Tx -> Either PartialFanoutError Tx)
-> Tx -> Either PartialFanoutError Tx
forall a b. (a -> b) -> a -> b
$ ScriptRegistry
-> UTxO
-> (TxIn, TxOut CtxUTxO ConwayEra)
-> SlotNo
-> FanoutProgressDatum
-> HydraAccumulator
-> Tx
partialFanoutTx ScriptRegistry
scriptRegistry UTxO
utxoToDistribute (TxIn, TxOut CtxUTxO ConwayEra)
headUTxO SlotNo
deadlineSlotNo FanoutProgressDatum
progressDatum HydraAccumulator
remainingAccumulator
where
ChainContext{ScriptRegistry
$sel:scriptRegistry:ChainContext :: ChainContext -> ScriptRegistry
scriptRegistry :: ScriptRegistry
scriptRegistry} = ChainContext
ctx
finalPartialFanout ::
ChainContext ->
UTxO ->
TxIn ->
UTxO ->
UTxO ->
SlotNo ->
Either PartialFanoutError Tx
finalPartialFanout :: ChainContext
-> UTxO
-> TxIn
-> UTxO
-> UTxO
-> SlotNo
-> Either PartialFanoutError Tx
finalPartialFanout ChainContext
ctx UTxO
spendableUTxO TxIn
seedTxIn UTxO
utxoToDistribute UTxO
presettledUTxO SlotNo
deadlineSlotNo = do
(TxIn, TxOut CtxUTxO ConwayEra)
headUTxO <-
(TxOut CtxUTxO ConwayEra -> Bool)
-> UTxO -> Maybe (TxIn, TxOut CtxUTxO ConwayEra)
forall era.
(TxOut CtxUTxO era -> Bool)
-> UTxO era -> Maybe (TxIn, TxOut CtxUTxO era)
UTxO.find (PlutusScript PlutusScriptV3 -> TxOut CtxUTxO ConwayEra -> Bool
forall lang ctx era.
IsPlutusScriptLanguage lang =>
PlutusScript lang -> TxOut ctx era -> Bool
isScriptTxOut PlutusScript PlutusScriptV3
Head.validatorScript) (PolicyId -> UTxO -> UTxO
utxoOfThisHead (TxIn -> PolicyId
headPolicyId TxIn
seedTxIn) UTxO
spendableUTxO)
Maybe (TxIn, TxOut CtxUTxO ConwayEra)
-> PartialFanoutError
-> Either PartialFanoutError (TxIn, TxOut CtxUTxO ConwayEra)
forall a e. Maybe a -> e -> Either e a
?> PartialFanoutError
CannotFindHeadOutput
State
headState <- (TxIn, TxOut CtxUTxO ConwayEra) -> Either PartialFanoutError State
readHeadState (TxIn, TxOut CtxUTxO ConwayEra)
headUTxO
FanoutProgressDatum
progressDatum <- case State
headState of
Head.FanoutProgress FanoutProgressDatum
d -> FanoutProgressDatum
-> Either PartialFanoutError FanoutProgressDatum
forall a. a -> Either PartialFanoutError a
forall (f :: * -> *) a. Applicative f => a -> f a
pure FanoutProgressDatum
d
State
_ -> PartialFanoutError -> Either PartialFanoutError FanoutProgressDatum
forall a b. a -> Either a b
Left PartialFanoutError
WrongDatum
HydraAccumulator
_fullAccumulator <- FanoutProgressDatum
-> UTxO -> Either PartialFanoutError HydraAccumulator
buildAndVerifyAccumulator FanoutProgressDatum
progressDatum (UTxO
utxoToDistribute UTxO -> UTxO -> UTxO
forall a. Semigroup a => a -> a -> a
<> UTxO
presettledUTxO)
(Text -> PartialFanoutError)
-> Either Text Tx -> Either PartialFanoutError Tx
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first Text -> PartialFanoutError
CannotCreateProof (Either Text Tx -> Either PartialFanoutError Tx)
-> Either Text Tx -> Either PartialFanoutError Tx
forall a b. (a -> b) -> a -> b
$
ScriptRegistry
-> UTxO
-> UTxO
-> (TxIn, TxOut CtxUTxO ConwayEra)
-> SlotNo
-> PlutusScript PlutusScriptV3
-> Either Text Tx
finalPartialFanoutTx
ScriptRegistry
scriptRegistry
UTxO
utxoToDistribute
UTxO
presettledUTxO
(TxIn, TxOut CtxUTxO ConwayEra)
headUTxO
SlotNo
deadlineSlotNo
PlutusScript PlutusScriptV3
headTokenScript
where
headTokenScript :: PlutusScript PlutusScriptV3
headTokenScript = TxIn -> PlutusScript PlutusScriptV3
mkHeadTokenScript TxIn
seedTxIn
ChainContext{ScriptRegistry
$sel:scriptRegistry:ChainContext :: ChainContext -> ScriptRegistry
scriptRegistry :: ScriptRegistry
scriptRegistry} = ChainContext
ctx
readHeadState :: (TxIn, TxOut CtxUTxO) -> Either PartialFanoutError Head.State
readHeadState :: (TxIn, TxOut CtxUTxO ConwayEra) -> Either PartialFanoutError State
readHeadState (TxIn
_, TxOut CtxUTxO ConwayEra
headOutput) = do
HashableScriptData
headDatum <- TxOut CtxTx ConwayEra -> Maybe HashableScriptData
forall era. TxOut CtxTx era -> Maybe HashableScriptData
txOutScriptData (TxOut CtxUTxO ConwayEra -> TxOut CtxTx ConwayEra
forall era. TxOut CtxUTxO era -> TxOut CtxTx era
fromCtxUTxOTxOut TxOut CtxUTxO ConwayEra
headOutput) Maybe HashableScriptData
-> PartialFanoutError
-> Either PartialFanoutError HashableScriptData
forall a e. Maybe a -> e -> Either e a
?> PartialFanoutError
MissingHeadDatum
HashableScriptData -> Maybe State
forall a. FromScriptData a => HashableScriptData -> Maybe a
fromScriptData HashableScriptData
headDatum Maybe State
-> PartialFanoutError -> Either PartialFanoutError State
forall a e. Maybe a -> e -> Either e a
?> PartialFanoutError
FailedToConvertFromScriptData
buildAndVerifyAccumulator ::
Head.FanoutProgressDatum ->
UTxO ->
Either PartialFanoutError HydraAccumulator
buildAndVerifyAccumulator :: FanoutProgressDatum
-> UTxO -> Either PartialFanoutError HydraAccumulator
buildAndVerifyAccumulator FanoutProgressDatum
progressDatum UTxO
utxo = do
let acc :: HydraAccumulator
acc = forall tx. IsTx tx => UTxOType tx -> HydraAccumulator
Accumulator.buildFromUTxO @Tx UTxOType Tx
UTxO
utxo
Head.FanoutProgressDatum{$sel:accumulatorCommitment:FanoutProgressDatum :: FanoutProgressDatum -> BuiltinBLS12_381_G1_Element
accumulatorCommitment = BuiltinBLS12_381_G1_Element
onChain} = FanoutProgressDatum
progressDatum
Bool
-> Either PartialFanoutError () -> Either PartialFanoutError ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (HydraAccumulator -> BuiltinBLS12_381_G1_Element
Accumulator.getAccumulatorCommitment HydraAccumulator
acc BuiltinBLS12_381_G1_Element -> BuiltinBLS12_381_G1_Element -> Bool
forall a. Eq a => a -> a -> Bool
== BuiltinBLS12_381_G1_Element
onChain) (Either PartialFanoutError () -> Either PartialFanoutError ())
-> Either PartialFanoutError () -> Either PartialFanoutError ()
forall a b. (a -> b) -> a -> b
$
PartialFanoutError -> Either PartialFanoutError ()
forall a b. a -> Either a b
Left PartialFanoutError
StaleChainState
HydraAccumulator -> Either PartialFanoutError HydraAccumulator
forall a. a -> Either PartialFanoutError a
forall (f :: * -> *) a. Applicative f => a -> f a
pure HydraAccumulator
acc
utxoOfThisHead :: PolicyId -> UTxO -> UTxO
utxoOfThisHead :: PolicyId -> UTxO -> UTxO
utxoOfThisHead PolicyId
policy = (TxOut CtxUTxO ConwayEra -> Bool) -> UTxO -> UTxO
forall era. (TxOut CtxUTxO era -> Bool) -> UTxO era -> UTxO era
UTxO.filter TxOut CtxUTxO ConwayEra -> Bool
hasHeadToken
where
hasHeadToken :: TxOut CtxUTxO ConwayEra -> Bool
hasHeadToken =
Maybe (AssetId, Quantity) -> Bool
forall a. Maybe a -> Bool
isJust (Maybe (AssetId, Quantity) -> Bool)
-> (TxOut CtxUTxO ConwayEra -> Maybe (AssetId, Quantity))
-> TxOut CtxUTxO ConwayEra
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((AssetId, Quantity) -> Bool)
-> [(AssetId, Quantity)] -> Maybe (AssetId, Quantity)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (AssetId, Quantity) -> Bool
isHeadToken ([(AssetId, Quantity)] -> Maybe (AssetId, Quantity))
-> (TxOut CtxUTxO ConwayEra -> [(AssetId, Quantity)])
-> TxOut CtxUTxO ConwayEra
-> Maybe (AssetId, Quantity)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> [(AssetId, Quantity)]
Value -> [Item Value]
forall l. IsList l => l -> [Item l]
IsList.toList (Value -> [(AssetId, Quantity)])
-> (TxOut CtxUTxO ConwayEra -> Value)
-> TxOut CtxUTxO ConwayEra
-> [(AssetId, Quantity)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TxOut CtxUTxO ConwayEra -> Value
forall ctx. TxOut ctx -> Value
txOutValue
isHeadToken :: (AssetId, Quantity) -> Bool
isHeadToken (AssetId
assetId, Quantity
quantity) =
case AssetId
assetId of
AssetId
AdaAssetId -> Bool
False
AssetId PolicyId
pid AssetName
_ -> PolicyId
pid PolicyId -> PolicyId -> Bool
forall a. Eq a => a -> a -> Bool
== PolicyId
policy Bool -> Bool -> Bool
&& Quantity
quantity Quantity -> Quantity -> Bool
forall a. Eq a => a -> a -> Bool
== Quantity
1
data HydraContext = HydraContext
{ HydraContext -> [VerificationKey PaymentKey]
ctxVerificationKeys :: [VerificationKey PaymentKey]
, HydraContext -> [Secret (SigningKey HydraKey)]
ctxHydraSigningKeys :: [Secret (SigningKey HydraKey)]
, HydraContext -> NetworkId
ctxNetworkId :: NetworkId
, HydraContext -> ContestationPeriod
ctxContestationPeriod :: ContestationPeriod
, HydraContext -> DepositPeriod
ctxDepositPeriod :: DepositPeriod
, HydraContext -> ScriptRegistry
ctxScriptRegistry :: ScriptRegistry
}
deriving stock (Int -> HydraContext -> ShowS
[HydraContext] -> ShowS
HydraContext -> String
(Int -> HydraContext -> ShowS)
-> (HydraContext -> String)
-> ([HydraContext] -> ShowS)
-> Show HydraContext
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> HydraContext -> ShowS
showsPrec :: Int -> HydraContext -> ShowS
$cshow :: HydraContext -> String
show :: HydraContext -> String
$cshowList :: [HydraContext] -> ShowS
showList :: [HydraContext] -> ShowS
Show)