4
4
{-# LANGUAGE FlexibleContexts #-}
5
5
{-# LANGUAGE FlexibleInstances #-}
6
6
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
7
+ {-# LANGUAGE LambdaCase #-}
7
8
{-# LANGUAGE MultiParamTypeClasses #-}
8
9
{-# LANGUAGE PatternSynonyms #-}
9
10
{-# LANGUAGE RankNTypes #-}
12
13
{-# LANGUAGE StandaloneDeriving #-}
13
14
{-# LANGUAGE TypeApplications #-}
14
15
{-# LANGUAGE TypeFamilies #-}
16
+ {-# LANGUAGE UndecidableSuperClasses #-}
15
17
{-# LANGUAGE ViewPatterns #-}
16
18
{-# OPTIONS_GHC -Wno-orphans #-}
17
19
18
20
module Cardano.Ledger.Dijkstra.TxBody (
21
+ DijkstraEraTxBody (.. ),
19
22
TxBody (
20
23
MkDijkstraTxBody ,
21
24
DijkstraTxBody ,
@@ -29,15 +32,15 @@ module Cardano.Ledger.Dijkstra.TxBody (
29
32
dtbWithdrawals ,
30
33
dtbTxfee ,
31
34
dtbVldt ,
32
- dtbReqSignerHashes ,
33
35
dtbMint ,
34
36
dtbScriptIntegrityHash ,
35
37
dtbAdHash ,
36
38
dtbTxNetworkId ,
37
39
dtbVotingProcedures ,
38
40
dtbProposalProcedures ,
39
41
dtbCurrentTreasuryValue ,
40
- dtbTreasuryDonation
42
+ dtbTreasuryDonation ,
43
+ dtbGuards
41
44
),
42
45
upgradeProposals ,
43
46
upgradeGovAction ,
@@ -53,10 +56,14 @@ import Cardano.Ledger.BaseTypes (Network, StrictMaybe (..), fromSMaybe)
53
56
import Cardano.Ledger.Binary (
54
57
Annotator ,
55
58
DecCBOR (.. ),
59
+ Decoder ,
56
60
EncCBOR (.. ),
57
61
Sized (.. ),
58
62
ToCBOR ,
63
+ TokenType (.. ),
64
+ liftST ,
59
65
mkSized ,
66
+ peekTokenType ,
60
67
)
61
68
import Cardano.Ledger.Binary.Coders (
62
69
Decode (.. ),
@@ -87,9 +94,11 @@ import Cardano.Ledger.Conway.TxBody (
87
94
conwayRedeemerPointerInverse ,
88
95
)
89
96
import Cardano.Ledger.Core (EraPParams (.. ))
97
+ import Cardano.Ledger.Credential (Credential (.. ))
90
98
import Cardano.Ledger.Dijkstra.Era (DijkstraEra )
91
99
import Cardano.Ledger.Dijkstra.Scripts ()
92
100
import Cardano.Ledger.Dijkstra.TxOut ()
101
+ import Cardano.Ledger.Keys (HasKeyRole (.. ))
93
102
import Cardano.Ledger.Mary.Value (MultiAsset , policies )
94
103
import Cardano.Ledger.MemoBytes (
95
104
EqRaw ,
@@ -106,11 +115,14 @@ import Cardano.Ledger.TxIn (TxIn)
106
115
import Cardano.Ledger.Val (Val (.. ))
107
116
import Control.DeepSeq (NFData )
108
117
import Data.Coerce (coerce )
118
+ import Data.OSet.Strict (OSet , decodeOSet )
109
119
import qualified Data.OSet.Strict as OSet
120
+ import Data.STRef (newSTRef , readSTRef , writeSTRef )
110
121
import Data.Sequence.Strict (StrictSeq )
111
- import Data.Set (Set )
122
+ import Data.Set (Set , foldr' )
123
+ import qualified Data.Set as Set
112
124
import GHC.Generics (Generic )
113
- import Lens.Micro (to , (^.) )
125
+ import Lens.Micro (Lens' , to , (^.) )
114
126
import NoThunks.Class (NoThunks )
115
127
116
128
data DijkstraTxBodyRaw = DijkstraTxBodyRaw
@@ -124,7 +136,7 @@ data DijkstraTxBodyRaw = DijkstraTxBodyRaw
124
136
, dtbrWithdrawals :: ! Withdrawals
125
137
, dtbrFee :: ! Coin
126
138
, dtbrVldt :: ! ValidityInterval
127
- , dtbrReqSignerHashes :: ! (Set ( KeyHash 'Witness ))
139
+ , dtbrGuards :: ! (OSet ( Credential Guard ))
128
140
, dtbrMint :: ! MultiAsset
129
141
, dtbrScriptIntegrityHash :: ! (StrictMaybe ScriptIntegrityHash )
130
142
, dtbrAuxDataHash :: ! (StrictMaybe TxAuxDataHash )
@@ -217,11 +229,9 @@ instance DecCBOR DijkstraTxBodyRaw where
217
229
(\ x tx -> tx {dtbrCollateralInputs = x})
218
230
From
219
231
bodyFields 14 =
220
- fieldGuarded
221
- (emptyFailure " Required Signer Hashes" " non-empty" )
222
- null
223
- (\ x tx -> tx {dtbrReqSignerHashes = x})
224
- From
232
+ ofield
233
+ (\ x tx -> tx {dtbrGuards = fromSMaybe mempty x})
234
+ (D decodeGuards)
225
235
bodyFields 15 = ofield (\ x tx -> tx {dtbrNetworkId = x}) From
226
236
bodyFields 16 = ofield (\ x tx -> tx {dtbrCollateralReturn = x}) From
227
237
bodyFields 17 = ofield (\ x tx -> tx {dtbrTotalCollateral = x}) From
@@ -278,7 +288,7 @@ encodeTxBodyRaw DijkstraTxBodyRaw {..} =
278
288
!> Omit OSet. null (Key 4 (To dtbrCerts))
279
289
!> Omit (null . unWithdrawals) (Key 5 (To dtbrWithdrawals))
280
290
!> encodeKeyedStrictMaybe 8 bot
281
- !> Omit null (Key 14 (To dtbrReqSignerHashes ))
291
+ !> Omit null (Key 14 (To dtbrGuards ))
282
292
!> Omit (== mempty ) (Key 9 (To dtbrMint))
283
293
!> encodeKeyedStrictMaybe 11 dtbrScriptIntegrityHash
284
294
!> encodeKeyedStrictMaybe 7 dtbrAuxDataHash
@@ -310,7 +320,7 @@ pattern DijkstraTxBody ::
310
320
Withdrawals ->
311
321
Coin ->
312
322
ValidityInterval ->
313
- Set ( KeyHash 'Witness ) ->
323
+ OSet ( Credential Guard ) ->
314
324
MultiAsset ->
315
325
StrictMaybe ScriptIntegrityHash ->
316
326
StrictMaybe TxAuxDataHash ->
@@ -331,7 +341,7 @@ pattern DijkstraTxBody
331
341
, dtbWithdrawals
332
342
, dtbTxfee
333
343
, dtbVldt
334
- , dtbReqSignerHashes
344
+ , dtbGuards
335
345
, dtbMint
336
346
, dtbScriptIntegrityHash
337
347
, dtbAdHash
@@ -353,7 +363,7 @@ pattern DijkstraTxBody
353
363
, dtbrWithdrawals = dtbWithdrawals
354
364
, dtbrFee = dtbTxfee
355
365
, dtbrVldt = dtbVldt
356
- , dtbrReqSignerHashes = dtbReqSignerHashes
366
+ , dtbrGuards = dtbGuards
357
367
, dtbrMint = dtbMint
358
368
, dtbrScriptIntegrityHash = dtbScriptIntegrityHash
359
369
, dtbrAuxDataHash = dtbAdHash
@@ -376,7 +386,7 @@ pattern DijkstraTxBody
376
386
withdrawalsX
377
387
txfeeX
378
388
vldtX
379
- reqSignerHashesX
389
+ guards
380
390
mintX
381
391
scriptIntegrityHashX
382
392
adHashX
@@ -397,7 +407,7 @@ pattern DijkstraTxBody
397
407
withdrawalsX
398
408
txfeeX
399
409
vldtX
400
- reqSignerHashesX
410
+ guards
401
411
mintX
402
412
scriptIntegrityHashX
403
413
adHashX
@@ -514,11 +524,15 @@ instance AlonzoEraTxBody DijkstraEra where
514
524
\ txb x -> txb {dtbrCollateralInputs = x}
515
525
{-# INLINE collateralInputsTxBodyL #-}
516
526
517
- reqSignerHashesTxBodyL =
518
- lensMemoRawType @ DijkstraEra dtbrReqSignerHashes $
519
- \ txb x -> txb {dtbrReqSignerHashes = x}
527
+ reqSignerHashesTxBodyL = notSupportedInThisEraL
520
528
{-# INLINE reqSignerHashesTxBodyL #-}
521
529
530
+ reqSignerHashesTxBodyG = guardsTxBodyL . to (foldr' insertKeyHash mempty . OSet. toSet)
531
+ where
532
+ insertKeyHash (KeyHashObj kh) = Set. insert $ coerceKeyRole kh
533
+ insertKeyHash (ScriptHashObj _) = id
534
+ {-# INLINE reqSignerHashesTxBodyG #-}
535
+
522
536
scriptIntegrityHashTxBodyL =
523
537
lensMemoRawType @ DijkstraEra dtbrScriptIntegrityHash $
524
538
\ txb x -> txb {dtbrScriptIntegrityHash = x}
@@ -577,3 +591,34 @@ instance ConwayEraTxBody DijkstraEra where
577
591
lensMemoRawType @ DijkstraEra dtbrTreasuryDonation $
578
592
\ txb x -> txb {dtbrTreasuryDonation = x}
579
593
{-# INLINE treasuryDonationTxBodyL #-}
594
+
595
+ class ConwayEraTxBody era => DijkstraEraTxBody era where
596
+ guardsTxBodyL :: Lens' (TxBody era ) (OSet (Credential Guard ))
597
+
598
+ instance DijkstraEraTxBody DijkstraEra where
599
+ {-# INLINE guardsTxBodyL #-}
600
+ guardsTxBodyL =
601
+ lensMemoRawType @ DijkstraEra dtbrGuards $
602
+ \ txb x -> txb {dtbrGuards = x}
603
+
604
+ -- | Decoder for decoding guards in a backwards-compatible manner. It peeks at
605
+ -- the first element and if it's a credential, it decodes the rest of the
606
+ -- elements as credentials. If the first element is a plain keyhash, it will
607
+ -- decode rest of the elements as keyhashes.
608
+ decodeGuards :: Decoder s (OSet (Credential Guard ))
609
+ decodeGuards = do
610
+ elementsAreCredentials <- liftST $ newSTRef Nothing
611
+ let
612
+ decodeElement = do
613
+ liftST (readSTRef elementsAreCredentials) >>= \ case
614
+ Nothing -> do
615
+ tokenType <- peekTokenType
616
+ liftST . writeSTRef elementsAreCredentials . Just $ case tokenType of
617
+ TypeListLen -> True
618
+ TypeListLen64 -> True
619
+ TypeListLenIndef -> True
620
+ _ -> False
621
+ decodeElement
622
+ Just True -> decCBOR
623
+ Just False -> KeyHashObj <$> decCBOR
624
+ decodeOSet decodeElement
0 commit comments