Skip to content

Commit

Permalink
Reference vHead in fanout transactions
Browse files Browse the repository at this point in the history
This reduces this transaction size substantially and makes it bound by
memory budget now.
  • Loading branch information
ch1bo committed Feb 6, 2023
1 parent c30ae95 commit 25e20ae
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 11 deletions.
4 changes: 2 additions & 2 deletions hydra-node/exe/tx-cost/TxCost.hs
Expand Up @@ -193,7 +193,7 @@ computeFanOutCost = do
pure $ interesting <> limit
where
compute numElems = do
(utxo, tx) <- generate $ genFanoutTx maximumNumberOfParties numElems
(tx, utxo) <- generate $ genFanoutTx maximumNumberOfParties numElems
case checkSizeAndEvaluate tx utxo of
Just (txSize, memUnit, cpuUnit, minFee) ->
pure $ Just (NumUTxO numElems, txSize, memUnit, cpuUnit, minFee)
Expand All @@ -212,7 +212,7 @@ computeFanOutCost = do
let closeTx = close cctx stOpen snapshot startSlot closePoint
let stClosed = snd . fromJust $ observeClose stOpen closeTx
let deadlineSlotNo = slotNoFromUTCTime (getContestationDeadline stClosed)
pure (getKnownUTxO stClosed, fanout stClosed utxo deadlineSlotNo)
pure (fanout cctx stClosed utxo deadlineSlotNo, getKnownUTxO stClosed <> getKnownUTxO cctx)

newtype NumParties = NumParties Int
deriving newtype (Eq, Show, Ord, Num, Real, Enum, Integral)
Expand Down
2 changes: 1 addition & 1 deletion hydra-node/src/Hydra/Chain/Direct/Handlers.hs
Expand Up @@ -273,7 +273,7 @@ prepareTxToPost timeHandle wallet ctx cst@ChainStateAt{chainState} tx =
pure (contest ctx st confirmedSnapshot upperBound)
(FanoutTx{utxo, contestationDeadline}, Closed st) -> do
deadlineSlot <- throwLeft $ slotFromUTCTime contestationDeadline
pure (fanout st utxo deadlineSlot)
pure (fanout ctx st utxo deadlineSlot)
(_, _) -> throwIO $ InvalidStateToPost{txTried = tx, chainState = cst}
where
-- XXX: Might want a dedicated exception type here
Expand Down
10 changes: 7 additions & 3 deletions hydra-node/src/Hydra/Chain/Direct/State.hs
Expand Up @@ -450,14 +450,17 @@ contest ctx st confirmedSnapshot pointInTime = do
-- | Construct a fanout transaction based on the 'ClosedState' and off-chain
-- agreed 'UTxO' set to fan out.
fanout ::
ChainContext ->
ClosedState ->
UTxO ->
-- | Contestation deadline as SlotNo, used to set lower tx validity bound.
SlotNo ->
Tx
fanout st utxo deadlineSlotNo = do
fanoutTx utxo (i, o, dat) deadlineSlotNo closedHeadTokenScript
fanout ctx st utxo deadlineSlotNo = do
fanoutTx scriptRegistry utxo (i, o, dat) deadlineSlotNo closedHeadTokenScript
where
ChainContext{scriptRegistry} = ctx

ClosedState{closedThreadOutput, closedHeadTokenScript} = st

ClosedThreadOutput{closedThreadUTxO = (i, o, dat)} = closedThreadOutput
Expand Down Expand Up @@ -882,8 +885,9 @@ genFanoutTx numParties numOutputs = do
ctx <- genHydraContext numParties
utxo <- genUTxOAdaOnlyOfSize numOutputs
(_, toFanout, stClosed) <- genStClosed ctx utxo
cctx <- pickChainContext ctx
let deadlineSlotNo = slotNoFromUTCTime (getContestationDeadline stClosed)
pure (ctx, stClosed, fanout stClosed toFanout deadlineSlotNo)
pure (ctx, stClosed, fanout cctx stClosed toFanout deadlineSlotNo)

getContestationDeadline :: ClosedState -> UTCTime
getContestationDeadline
Expand Down
12 changes: 9 additions & 3 deletions hydra-node/src/Hydra/Chain/Direct/Tx.hs
Expand Up @@ -432,6 +432,8 @@ contestTx vk Snapshot{number, utxo} sig (slotNo, _) ClosedThreadOutput{closedThr
-- accordingly. The head validator allows fanout only > deadline, so we need
-- to set the lower bound to be deadline + 1 slot.
fanoutTx ::
-- | Published Hydra scripts to reference.
ScriptRegistry ->
-- | Snapshotted UTxO to fanout on layer 1
UTxO ->
-- | Everything needed to spend the Head state-machine output.
Expand All @@ -441,17 +443,21 @@ fanoutTx ::
-- | Minting Policy script, made from initial seed
PlutusScript ->
Tx
fanoutTx utxo (headInput, headOutput, ScriptDatumForTxIn -> headDatumBefore) deadlineSlotNo headTokenScript =
fanoutTx scriptRegistry utxo (headInput, headOutput, ScriptDatumForTxIn -> headDatumBefore) deadlineSlotNo headTokenScript =
unsafeBuildTransaction $
emptyTxBody
& addInputs [(headInput, headWitness)]
& addReferenceInputs [headScriptRef]
& addOutputs orderedTxOutsToFanout
& burnTokens headTokenScript Burn headTokens
& setValidityLowerBound (deadlineSlotNo + 1)
where
headWitness =
BuildTxWith $ ScriptWitness scriptWitnessCtx $ mkScriptWitness headScript headDatumBefore headRedeemer

BuildTxWith $
ScriptWitness scriptWitnessCtx $
mkScriptReference headScriptRef headScript headDatumBefore headRedeemer
headScriptRef =
fst (headReference scriptRegistry)
headScript =
fromPlutusScript @PlutusScriptV2 Head.validatorScript
headRedeemer =
Expand Down
10 changes: 8 additions & 2 deletions hydra-node/test/Hydra/Chain/Direct/Contract/FanOut.hs
Expand Up @@ -11,6 +11,7 @@ import Hydra.Prelude hiding (label)
import Cardano.Api.UTxO as UTxO
import Hydra.Chain.Direct.Contract.Mutation (Mutation (..), SomeMutation (..))
import Hydra.Chain.Direct.Fixture (testNetworkId, testPolicyId, testSeedInput)
import Hydra.Chain.Direct.ScriptRegistry (genScriptRegistry, registryUTxO)
import Hydra.Chain.Direct.Tx (fanoutTx, mkHeadOutput)
import qualified Hydra.Contract.HeadState as Head
import Hydra.Contract.HeadTokens (mkHeadTokenScript)
Expand All @@ -33,13 +34,20 @@ healthyFanoutTx :: (Tx, UTxO)
healthyFanoutTx =
(tx, lookupUTxO)
where
lookupUTxO =
UTxO.singleton (headInput, headOutput)
<> registryUTxO scriptRegistry

tx =
fanoutTx
scriptRegistry
healthyFanoutUTxO
(headInput, headOutput, headDatum)
healthySlotNo
headTokenScript

scriptRegistry = genScriptRegistry `generateWith` 42

headInput = generateWith arbitrary 42

headTokenScript = mkHeadTokenScript testSeedInput
Expand All @@ -60,8 +68,6 @@ healthyFanoutTx =

headDatum = fromPlutusData $ toData healthyFanoutDatum

lookupUTxO = UTxO.singleton (headInput, headOutput)

healthyFanoutUTxO :: UTxO
healthyFanoutUTxO =
-- FIXME: fanoutTx would result in 0 outputs and MutateChangeOutputValue below fail
Expand Down

0 comments on commit 25e20ae

Please sign in to comment.