Skip to content

Commit 14152aa

Browse files
committed
WIP: Start with the changes needed for on-chain check
Signed-off-by: Sasha Bogicevic <sasha.bogicevic@iohk.io>
1 parent 67d29a6 commit 14152aa

File tree

7 files changed

+72
-15
lines changed

7 files changed

+72
-15
lines changed

hydra-plutus/src/Hydra/Contract/Head.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,7 @@ checkFanout ScriptContext{scriptContextTxInfo = txInfo} closedDatum numberOfFano
672672

673673
decommitUtxoHash = hashTxOuts $ L.take numberOfDecommitOutputs $ L.drop numberOfFanoutOutputs txInfoOutputs
674674

675-
ClosedDatum{utxoHash, alphaUTxOHash, omegaUTxOHash, parties, headId, contestationDeadline} = closedDatum
675+
ClosedDatum{utxoHash, alphaUTxOHash, omegaUTxOHash, parties, headId, contestationDeadline, accumulatorHash, proof} = closedDatum
676676

677677
TxInfo{txInfoOutputs} = txInfo
678678

hydra-plutus/src/Hydra/Contract/HeadState.hs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ data ClosedDatum = ClosedDatum
6161
-- ^ Spec: tfinal
6262
, accumulatorHash :: Hash
6363
-- ^ Spec: ηA. Digest of the accumulator
64+
, proof :: BuiltinBLS12_381_G2_Element
6465
}
6566
deriving stock (Generic, Show)
6667

@@ -86,7 +87,8 @@ data CloseRedeemer
8687
CloseInitial
8788
| -- | Any snapshot which doesn't contain anything to inc/decrement but snapshot number is higher than zero.
8889
CloseAny
89-
{signature :: [Signature]}
90+
{ signature :: [Signature]
91+
}
9092
| -- | Closing snapshot refers to the current state version
9193
CloseUnusedDec
9294
{ signature :: [Signature]
@@ -187,6 +189,7 @@ data Input
187189
{ numberOfFanoutOutputs :: Integer
188190
, numberOfCommitOutputs :: Integer
189191
, numberOfDecommitOutputs :: Integer
192+
, crs :: [BuiltinBLS12_381_G1_Element]
190193
}
191194
deriving stock (Generic, Show)
192195

hydra-tx/src/Hydra/Tx/Accumulator.hs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -169,16 +169,15 @@ createMembershipProof ::
169169
-- | Common Reference String (CRS) for the cryptographic proof
170170
[Point2] ->
171171
-- | Returns a string: "Success: 0x..." or "Error: ..."
172-
Text
172+
ByteString
173173
createMembershipProof subsetElements (HydraAccumulator fullAcc) crs =
174174
-- Use getPolyCommitOverG2 to generate the proof
175175
case getPolyCommitOverG2 subsetElements fullAcc crs of
176-
Left err -> "Error: " <> toText err
176+
Left err -> "Error: " <> encodeUtf8 (toText err)
177177
Right proof ->
178178
-- Compress the Point2 to a ByteString and encode as hex
179179
let proofBytes = blsCompress proof
180-
proofHex = decodeUtf8 $ Base16.encode proofBytes
181-
in "Success: 0x" <> proofHex
180+
in Base16.encode proofBytes
182181

183182
-- | Create a membership proof from a UTxO subset.
184183
--
@@ -212,7 +211,7 @@ createMembershipProofFromUTxO ::
212211
-- | Common Reference String (CRS) for the cryptographic proof
213212
[Point2] ->
214213
-- | Returns a string: "Success: 0x..." or "Error: ..."
215-
Text
214+
ByteString
216215
createMembershipProofFromUTxO subsetUTxO fullAcc crs = do
217216
-- Extract individual TxOut elements from the subset
218217
-- This matches how buildFromUTxO serializes each TxOut

hydra-tx/src/Hydra/Tx/Close.hs

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
module Hydra.Tx.Close where
44

5-
import Hydra.Cardano.Api
5+
import Hydra.Cardano.Api hiding (utxo)
66
import Hydra.Prelude
77

88
import Hydra.Contract.Head qualified as Head
@@ -29,6 +29,7 @@ import Hydra.Tx.Accumulator qualified as Accumulator
2929
import Hydra.Tx.Crypto (toPlutusSignatures)
3030
import Hydra.Tx.Utils (IncrementalAction (..), findStateToken, mkHydraHeadV1TxName)
3131
import PlutusLedgerApi.V3 (toBuiltin)
32+
import PlutusTx.Builtins (bls12_381_G2_uncompress, toBuiltin)
3233

3334
-- * Construction
3435

@@ -92,7 +93,8 @@ closeTx scriptRegistry vk headId openVersion confirmedSnapshot startSlotNo (endS
9293

9394
closeRedeemer =
9495
case confirmedSnapshot of
95-
InitialSnapshot{} -> Head.CloseInitial
96+
InitialSnapshot{} ->
97+
Head.CloseInitial
9698
ConfirmedSnapshot{signatures, snapshot = Snapshot{version}} ->
9799
case incrementalAction of
98100
ToCommit utxo' ->
@@ -109,17 +111,38 @@ closeTx scriptRegistry vk headId openVersion confirmedSnapshot startSlotNo (endS
109111
}
110112
ToDecommit utxo' ->
111113
if version == openVersion
112-
then Head.CloseUnusedDec{signature = toPlutusSignatures signatures}
114+
then
115+
Head.CloseUnusedDec
116+
{ signature = toPlutusSignatures signatures
117+
}
113118
else
114119
Head.CloseUsedDec
115120
{ signature = toPlutusSignatures signatures
116121
, alreadyDecommittedUTxOHash = toBuiltin $ hashUTxO utxo'
117122
}
118-
NoThing -> Head.CloseAny{signature = toPlutusSignatures signatures}
123+
NoThing ->
124+
Head.CloseAny
125+
{ signature = toPlutusSignatures signatures
126+
}
119127

120128
headOutputAfter =
121129
modifyTxOutDatum (const headDatumAfter) headOutputBefore
122130

131+
snapshot = getSnapshot confirmedSnapshot
132+
133+
proof =
134+
let snapshotUTxO =
135+
utxo snapshot
136+
<> case closeRedeemer of
137+
Head.CloseUsedInc{} ->
138+
fromMaybe mempty (utxoToCommit snapshot)
139+
Head.CloseUnusedDec{} ->
140+
fromMaybe mempty (utxoToDecommit snapshot)
141+
_ -> mempty
142+
in bls12_381_G2_uncompress $
143+
toBuiltin $
144+
Accumulator.createMembershipProofFromUTxO @Tx snapshotUTxO (accumulator snapshot) Accumulator.defaultCRS
145+
123146
headDatumAfter =
124147
mkTxOutDatumInline $
125148
Head.Closed
@@ -145,10 +168,10 @@ closeTx scriptRegistry vk headId openVersion confirmedSnapshot startSlotNo (endS
145168
, contesters = []
146169
, version = fromIntegral openVersion
147170
, accumulatorHash = toBuiltin closedAccumulatorHash
171+
, proof
148172
}
149173
where
150-
snapshot = getSnapshot confirmedSnapshot
151-
closedAccumulatorHash = Accumulator.getAccumulatorHash $ accumulator snapshot
174+
closedAccumulatorHash = Accumulator.getAccumulatorHash $ accumulator $ getSnapshot confirmedSnapshot
152175

153176
contestationDeadline =
154177
addContestationPeriod (posixFromUTCTime utcTime) openContestationPeriod

hydra-tx/src/Hydra/Tx/Contest.hs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import Hydra.Tx.Utils (IncrementalAction (..), findStateToken, mkHydraHeadV1TxNa
2121
import PlutusLedgerApi.V1.Crypto qualified as Plutus
2222
import PlutusLedgerApi.V3 (toBuiltin)
2323
import PlutusLedgerApi.V3 qualified as Plutus
24+
import PlutusTx.Builtins (bls12_381_G2_uncompress)
2425

2526
import Hydra.Plutus.Orphans ()
2627

@@ -124,6 +125,19 @@ contestTx scriptRegistry vk headId contestationPeriod openVersion snapshot sig (
124125
then closedContestationDeadline
125126
else addContestationPeriod closedContestationDeadline onChainConstestationPeriod
126127

128+
proof =
129+
let snapshotUTxO =
130+
utxo
131+
<> case contestRedeemer of
132+
Head.ContestUsedInc{} ->
133+
fromMaybe mempty utxoToCommit
134+
Head.ContestUnusedDec{} ->
135+
fromMaybe mempty utxoToDecommit
136+
_ -> mempty
137+
in bls12_381_G2_uncompress $
138+
toBuiltin $
139+
Accumulator.createMembershipProofFromUTxO @Tx snapshotUTxO accumulator Accumulator.defaultCRS
140+
127141
headDatumAfter =
128142
mkTxOutDatumInline $
129143
Head.Closed
@@ -147,6 +161,7 @@ contestTx scriptRegistry vk headId contestationPeriod openVersion snapshot sig (
147161
, contesters = contester : closedContesters
148162
, version = toInteger openVersion
149163
, accumulatorHash = toBuiltin contestAccumulatorHash
164+
, proof
150165
}
151166
where
152167
contestAccumulatorHash = Accumulator.getAccumulatorHash accumulator

hydra-tx/src/Hydra/Tx/Fanout.hs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@ import Hydra.Cardano.Api
44
import Hydra.Prelude
55

66
import Cardano.Api.UTxO qualified as UTxO
7+
import Cardano.Crypto.EllipticCurve.BLS12_381 (blsSerialize)
78
import Hydra.Contract.Head qualified as Head
89
import Hydra.Contract.HeadState qualified as Head
910
import Hydra.Contract.MintAction (MintAction (..))
1011
import Hydra.Ledger.Cardano.Builder (burnTokens, unsafeBuildTransaction)
12+
import Hydra.Tx.Accumulator qualified as Accumulator
1113
import Hydra.Tx.HeadId (HeadId)
1214
import Hydra.Tx.ScriptRegistry (ScriptRegistry (..))
1315
import Hydra.Tx.Utils (findStateToken, headTokensFromValue, mkHydraHeadV1TxName)
16+
import PlutusTx.Builtins (bls12_381_G1_uncompress, bls12_381_G2_uncompress, toBuiltin)
1417

1518
-- * Creation
1619

@@ -43,18 +46,23 @@ fanoutTx scriptRegistry utxo utxoToCommit utxoToDecommit (headInput, headOutput)
4346
& setTxValidityLowerBound (TxValidityLowerBound $ deadlineSlotNo + 1)
4447
& setTxMetadata (TxMetadataInEra $ mkHydraHeadV1TxName "FanoutTx")
4548
where
49+
crs = bls12_381_G1_uncompress . toBuiltin . blsSerialize <$> Accumulator.defaultCRS
50+
4651
headWitness =
4752
BuildTxWith $
4853
ScriptWitness scriptWitnessInCtx $
4954
mkScriptReference headScriptRef Head.validatorScript InlineScriptDatum headRedeemer
55+
5056
headScriptRef =
5157
fst (headReference scriptRegistry)
58+
5259
headRedeemer =
5360
toScriptData $
5461
Head.Fanout
5562
{ numberOfFanoutOutputs = fromIntegral $ UTxO.size utxo
5663
, numberOfCommitOutputs = fromIntegral $ length orderedTxOutsToCommit
5764
, numberOfDecommitOutputs = fromIntegral $ length orderedTxOutsToDecommit
65+
, crs
5866
}
5967

6068
headTokens =

hydra-tx/test/Hydra/Tx/Contract/FanOut.hs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import Hydra.Tx.Init (mkHeadOutput)
2323
import Hydra.Tx.IsTx (IsTx (hashUTxO))
2424
import Hydra.Tx.Party (Party, partyToChain, vkey)
2525
import Hydra.Tx.Utils (adaOnly, splitUTxO)
26-
import PlutusTx.Builtins (toBuiltin)
26+
import PlutusTx.Builtins (bls12_381_G2_uncompress, toBuiltin)
2727
import Test.Hydra.Tx.Fixture (slotLength, systemStart, testNetworkId, testPolicyId, testSeedInput)
2828
import Test.Hydra.Tx.Gen (genOutputFor, genScriptRegistry, genUTxOWithSimplifiedAddresses, genValue)
2929
import Test.Hydra.Tx.Mutation (Mutation (..), SomeMutation (..), changeMintedTokens)
@@ -81,6 +81,9 @@ healthyContestationDeadline =
8181
healthyFanoutSnapshotUTxO :: (UTxO, UTxO)
8282
healthyFanoutSnapshotUTxO = splitUTxO healthyFanoutUTxO
8383

84+
accumulator :: Accumulator.HydraAccumulator
85+
accumulator = Accumulator.buildFromUTxO @Tx (uncurry (<>) healthyFanoutSnapshotUTxO)
86+
8487
healthyFanoutDatum :: Head.State
8588
healthyFanoutDatum =
8689
Head.Closed
@@ -96,7 +99,13 @@ healthyFanoutDatum =
9699
, headId = toPlutusCurrencySymbol testPolicyId
97100
, contesters = []
98101
, version = 0
99-
, accumulatorHash = toBuiltin $ Accumulator.getAccumulatorHash (Accumulator.buildFromUTxO (fst healthyFanoutSnapshotUTxO))
102+
, accumulatorHash = toBuiltin $ Accumulator.getAccumulatorHash accumulator
103+
, proof =
104+
let snapshotUTxO =
105+
uncurry (<>) healthyFanoutSnapshotUTxO
106+
in bls12_381_G2_uncompress $
107+
toBuiltin $
108+
Accumulator.createMembershipProofFromUTxO @Tx snapshotUTxO accumulator Accumulator.defaultCRS
100109
}
101110
where
102111
healthyContestationPeriodSeconds = 10

0 commit comments

Comments
 (0)