Skip to content

Commit 8b5f077

Browse files
authored
Merge pull request #726 from IntersectMBO/mgalazyn/refactor/replace-txproposalprocedure-with-pattern
Update TxProposalProcedures type to make invalid states irrepresentable
2 parents 87afbdd + fbade80 commit 8b5f077

File tree

6 files changed

+49
-71
lines changed

6 files changed

+49
-71
lines changed

cardano-api/cardano-api.cabal

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,6 @@ library internal
194194
data-default-class,
195195
deepseq,
196196
directory,
197-
dlist,
198197
either,
199198
errors,
200199
filepath,

cardano-api/gen/Test/Gen/Cardano/Api/Typed.hs

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -260,38 +260,38 @@ genSimpleScript =
260260
-- plutus scripts as well as valid plutus scripts.
261261
genPlutusScript :: PlutusScriptVersion lang -> Gen (PlutusScript lang)
262262
genPlutusScript l =
263-
case l of
264-
PlutusScriptV1 -> do
263+
case l of
264+
PlutusScriptV1 -> do
265265
PlutusScript _ s <- genPlutusV1Script
266266
return s
267-
PlutusScriptV2 -> do
267+
PlutusScriptV2 -> do
268268
PlutusScript _ s <- genPlutusV2Script
269269
return s
270-
PlutusScriptV3 -> do
270+
PlutusScriptV3 -> do
271271
PlutusScript _ s <- genPlutusV3Script
272272
return s
273273

274274
genValidPlutusScript :: PlutusScriptVersion lang -> Gen (PlutusScript lang)
275275
genValidPlutusScript l =
276-
case l of
277-
PlutusScriptV1 -> do
276+
case l of
277+
PlutusScriptV1 -> do
278278
PlutusScript _ s <- genValidPlutusV1Script
279279
return s
280-
PlutusScriptV2 -> do
280+
PlutusScriptV2 -> do
281281
PlutusScript _ s <- genValidPlutusV2Script
282282
return s
283-
PlutusScriptV3 -> do
283+
PlutusScriptV3 -> do
284284
PlutusScript _ s <- genValidPlutusV3Script
285285
return s
286286

287287
genPlutusV1Script :: Gen (Script PlutusScriptV1)
288-
genPlutusV1Script = do
288+
genPlutusV1Script = do
289289
v1Script <- Gen.element [v1Loop2024PlutusScriptHexDoubleEncoded,v1Loop2024PlutusScriptHex]
290290
let v1ScriptBytes = Base16.decodeLenient v1Script
291291
return . PlutusScript PlutusScriptV1 . PlutusScriptSerialised $ SBS.toShort v1ScriptBytes
292292

293293
genValidPlutusV1Script :: Gen (Script PlutusScriptV1)
294-
genValidPlutusV1Script = do
294+
genValidPlutusV1Script = do
295295
v1Script <- Gen.element [v1Loop2024PlutusScriptHex]
296296
let v1ScriptBytes = Base16.decodeLenient v1Script
297297
return . PlutusScript PlutusScriptV1 . PlutusScriptSerialised $ SBS.toShort v1ScriptBytes
@@ -310,14 +310,14 @@ genValidPlutusV2Script = do
310310

311311
genPlutusV3Script :: Gen (Script PlutusScriptV3)
312312
genPlutusV3Script = do
313-
v3AlwaysSucceedsPlutusScriptHex
313+
v3AlwaysSucceedsPlutusScriptHex
314314
<- Gen.element [v3AlwaysSucceedsPlutusScriptDoubleEncoded, v3AlwaysSucceedsPlutusScript]
315315
let v3ScriptBytes = Base16.decodeLenient v3AlwaysSucceedsPlutusScriptHex
316316
return . PlutusScript PlutusScriptV3 . PlutusScriptSerialised $ SBS.toShort v3ScriptBytes
317317

318318
genValidPlutusV3Script :: Gen (Script PlutusScriptV3)
319319
genValidPlutusV3Script = do
320-
v3AlwaysSucceedsPlutusScriptHex
320+
v3AlwaysSucceedsPlutusScriptHex
321321
<- Gen.element [v3AlwaysSucceedsPlutusScript]
322322
let v3ScriptBytes = Base16.decodeLenient v3AlwaysSucceedsPlutusScriptHex
323323
return . PlutusScript PlutusScriptV3 . PlutusScriptSerialised $ SBS.toShort v3ScriptBytes
@@ -1341,18 +1341,12 @@ genProposals :: Applicative (BuildTxWith build)
13411341
=> ConwayEraOnwards era
13421342
-> Gen (TxProposalProcedures build era)
13431343
genProposals w = conwayEraOnwardsConstraints w $ do
1344-
proposals <- Gen.list (Range.constant 0 10) (genProposal w)
1345-
proposalsToBeWitnessed <- Gen.subsequence proposals
1346-
-- We're generating also some extra proposals, purposely not included in the proposals list, which results
1347-
-- in an invalid state of 'TxProposalProcedures'.
1348-
-- We're doing it for the complete representation of possible values space of TxProposalProcedures.
1349-
-- Proposal procedures code in cardano-api should handle such invalid values just fine.
1350-
extraProposals <- Gen.list (Range.constant 0 10) (genProposal w)
1344+
proposals <- Gen.list (Range.constant 0 15) (genProposal w)
13511345
let sbe = convert w
1352-
proposalsWithWitnesses <-
1353-
forM (extraProposals <> proposalsToBeWitnessed) $ \proposal ->
1354-
(proposal,) <$> genScriptWitnessForStake sbe
1355-
pure $ TxProposalProcedures (fromList proposals) (pure $ fromList proposalsWithWitnesses)
1346+
proposalsWithMaybeWitnesses <-
1347+
forM proposals $ \proposal ->
1348+
(proposal,) <$> Gen.maybe (genScriptWitnessForStake sbe)
1349+
pure $ mkTxProposalProcedures proposalsWithMaybeWitnesses
13561350

13571351
genProposal :: ConwayEraOnwards era -> Gen (L.ProposalProcedure (ShelleyLedgerEra era))
13581352
genProposal w =

cardano-api/internal/Cardano/Api/Fees.hs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1535,28 +1535,25 @@ substituteExecutionUnits
15351535
(Featured era (TxVotingProcedures vProcedures (BuildTxWith $ fromList substitutedExecutionUnits)))
15361536

15371537
mapScriptWitnessesProposals
1538-
:: Maybe (Featured ConwayEraOnwards era (TxProposalProcedures build era))
1538+
:: Maybe (Featured ConwayEraOnwards era (TxProposalProcedures BuildTx era))
15391539
-> Either
15401540
(TxBodyErrorAutoBalance era)
1541-
(Maybe (Featured ConwayEraOnwards era (TxProposalProcedures build era)))
1541+
(Maybe (Featured ConwayEraOnwards era (TxProposalProcedures BuildTx era)))
15421542
mapScriptWitnessesProposals Nothing = return Nothing
1543-
mapScriptWitnessesProposals (Just (Featured _ TxProposalProceduresNone)) = return Nothing
1544-
mapScriptWitnessesProposals (Just (Featured _ (TxProposalProcedures _ ViewTx))) = return Nothing
1545-
mapScriptWitnessesProposals (Just (Featured era txpp@(TxProposalProcedures osetProposalProcedures (BuildTxWith _)))) = do
1543+
mapScriptWitnessesProposals (Just (Featured era txpp)) = do
15461544
let eSubstitutedExecutionUnits =
15471545
[ (proposal, updatedWitness)
15481546
| (ix, proposal, scriptWitness) <- indexTxProposalProcedures txpp
15491547
, let updatedWitness = substituteExecUnits ix scriptWitness
15501548
]
1551-
15521549
substitutedExecutionUnits <- traverseScriptWitnesses eSubstitutedExecutionUnits
15531550

1554-
return $
1555-
Just
1556-
( Featured
1557-
era
1558-
(TxProposalProcedures osetProposalProcedures (BuildTxWith $ fromList substitutedExecutionUnits))
1559-
)
1551+
pure $
1552+
Just $
1553+
Featured era $
1554+
conwayEraOnwardsConstraints era $
1555+
mkTxProposalProcedures $
1556+
second Just <$> substitutedExecutionUnits
15601557

15611558
mapScriptWitnessesMinting
15621559
:: TxMintValue BuildTx era

cardano-api/internal/Cardano/Api/Tx/Body.hs

Lines changed: 20 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -296,9 +296,7 @@ import Data.Bifunctor (Bifunctor (..))
296296
import Data.ByteString (ByteString)
297297
import qualified Data.ByteString.Base16 as Base16
298298
import qualified Data.ByteString.Char8 as BSC
299-
import qualified Data.DList as DList
300299
import Data.Foldable (for_)
301-
import qualified Data.Foldable as Foldable
302300
import Data.Function (on)
303301
import Data.Functor (($>))
304302
import Data.List (sortBy)
@@ -309,7 +307,7 @@ import Data.Map.Strict (Map)
309307
import qualified Data.Map.Strict as Map
310308
import Data.Maybe
311309
import Data.Monoid
312-
import Data.OSet.Strict (OSet, (|><))
310+
import Data.OSet.Strict (OSet)
313311
import qualified Data.OSet.Strict as OSet
314312
import Data.Scientific (toBoundedInteger)
315313
import qualified Data.Sequence.Strict as Seq
@@ -1466,18 +1464,19 @@ indexTxVotingProcedures (TxVotingProcedures vProcedures (BuildTxWith sWitMap)) =
14661464
-- ----------------------------------------------------------------------------
14671465
-- Proposals within transactions (era-dependent)
14681466
--
1469-
1467+
-- A proposal procedure houses a governance action that is required to be voted into acceptance when submitted.
14701468
data TxProposalProcedures build era where
1469+
-- | No proposals in transaction..
14711470
TxProposalProceduresNone :: TxProposalProcedures build era
1472-
-- | Create Tx proposal procedures. Prefer 'mkTxProposalProcedures' smart constructor to using this constructor
1473-
-- directly.
1471+
-- | Represents proposal procedures present in transaction.
14741472
TxProposalProcedures
14751473
:: Ledger.EraPParams (ShelleyLedgerEra era)
1476-
=> OSet (L.ProposalProcedure (ShelleyLedgerEra era))
1477-
-- ^ a set of proposals
1478-
-> BuildTxWith build (Map (L.ProposalProcedure (ShelleyLedgerEra era)) (ScriptWitness WitCtxStake era))
1479-
-- ^ a map of witnesses for the proposals. If the proposals are not added to the first constructor
1480-
-- parameter too, the sky will fall on your head.
1474+
=> OMap
1475+
(L.ProposalProcedure (ShelleyLedgerEra era))
1476+
( BuildTxWith
1477+
build
1478+
(Maybe (ScriptWitness WitCtxStake era))
1479+
)
14811480
-> TxProposalProcedures build era
14821481

14831482
deriving instance Eq (TxProposalProcedures build era)
@@ -1492,27 +1491,21 @@ mkTxProposalProcedures
14921491
=> IsShelleyBasedEra era
14931492
=> [(L.ProposalProcedure (ShelleyLedgerEra era), Maybe (ScriptWitness WitCtxStake era))]
14941493
-> TxProposalProcedures build era
1495-
mkTxProposalProcedures proposalsWithWitnessesList = do
1496-
let (proposals, proposalsWithWitnesses) =
1497-
bimap toList toList $
1498-
Foldable.foldl' partitionProposals mempty proposalsWithWitnessesList
1494+
mkTxProposalProcedures proposals = do
14991495
shelleyBasedEraConstraints (shelleyBasedEra @era) $
1500-
TxProposalProcedures (fromList proposals) (pure $ fromList proposalsWithWitnesses)
1501-
where
1502-
partitionProposals (ps, pws) (p, Nothing) =
1503-
(DList.snoc ps p, pws) -- add a proposal to the list
1504-
partitionProposals (ps, pws) (p, Just w) =
1505-
(DList.snoc ps p, DList.snoc pws (p, w)) -- add a proposal both to the list and to the witnessed list
1496+
TxProposalProcedures $
1497+
fromList $
1498+
map (second pure) proposals
15061499

15071500
-- | Index proposal procedures by their order ('Ord').
15081501
indexTxProposalProcedures
15091502
:: TxProposalProcedures BuildTx era
15101503
-> [(ScriptWitnessIndex, L.ProposalProcedure (ShelleyLedgerEra era), ScriptWitness WitCtxStake era)]
15111504
indexTxProposalProcedures TxProposalProceduresNone = []
1512-
indexTxProposalProcedures txpp@(TxProposalProcedures _ (BuildTxWith witnesses)) = do
1513-
let allProposalsList = toList $ convProposalProcedures txpp
1505+
indexTxProposalProcedures (TxProposalProcedures proposals) = do
1506+
let allProposalsList = fst <$> toList proposals
15141507
[ (ScriptWitnessIndexProposing $ fromIntegral ix, proposal, scriptWitness)
1515-
| (proposal, scriptWitness) <- toList witnesses
1508+
| (proposal, BuildTxWith (Just scriptWitness)) <- toList proposals
15161509
, ix <- maybeToList $ List.elemIndex proposal allProposalsList
15171510
]
15181511

@@ -2228,9 +2221,8 @@ fromLedgerProposalProcedures sbe body =
22282221
forShelleyBasedEraInEonMaybe sbe $ \w ->
22292222
conwayEraOnwardsConstraints w $
22302223
Featured w $
2231-
TxProposalProcedures
2232-
(body ^. L.proposalProceduresTxBodyL)
2233-
ViewTx
2224+
mkTxProposalProcedures
2225+
(fmap (,Nothing) . toList $ body ^. L.proposalProceduresTxBodyL)
22342226

22352227
fromLedgerVotingProcedures
22362228
:: ()
@@ -2821,15 +2813,10 @@ convReferenceInputs txInsReference =
28212813
TxInsReference _ refTxins -> fromList $ map toShelleyTxIn refTxins
28222814

28232815
-- | Returns an OSet of proposals from 'TxProposalProcedures'.
2824-
--
2825-
-- If 'pws' in 'TxProposalProcedures pps (BuildTxWith pws)' contained proposals not present in 'pps', the'll
2826-
-- be sorted ascendingly and snoc-ed to 'pps' if they're not present in 'pps'.
28272816
convProposalProcedures
28282817
:: TxProposalProcedures build era -> OSet (L.ProposalProcedure (ShelleyLedgerEra era))
28292818
convProposalProcedures TxProposalProceduresNone = OSet.empty
2830-
convProposalProcedures (TxProposalProcedures pp bWits) = do
2831-
let wits = fromMaybe mempty $ buildTxWithToMaybe bWits
2832-
pp |>< fromList (Map.keys wits)
2819+
convProposalProcedures (TxProposalProcedures proposals) = fromList $ fst <$> toList proposals
28332820

28342821
convVotingProcedures :: TxVotingProcedures build era -> L.VotingProcedures (ShelleyLedgerEra era)
28352822
convVotingProcedures txVotingProcedures =

cardano-api/internal/Cardano/Api/Tx/Compatible.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ createCompatibleSignedTx sbe ins outs witnesses txFee' anyProtocolUpdate anyVote
8484
txb & L.updateTxBodyL .~ SJust ledgerPParamsUpdate
8585

8686
pure (updateTxBody, [])
87-
NoPParamsUpdate _ -> do
87+
NoPParamsUpdate _ ->
8888
pure (mempty, [])
8989
ProposalProcedures conwayOnwards proposalProcedures -> do
9090
let proposals = convProposalProcedures proposalProcedures

cardano-api/test/cardano-api-test/Test/Cardano/Api/TxBody.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# LANGUAGE FlexibleContexts #-}
12
{-# LANGUAGE GADTs #-}
23
{-# LANGUAGE LambdaCase #-}
34
{-# LANGUAGE OverloadedLists #-}
@@ -105,7 +106,7 @@ prop_roundtrip_txbodycontent_conway_fields = H.property $ do
105106
:: TxProposalProcedures build era
106107
-> Maybe [L.ProposalProcedure (ShelleyLedgerEra era)]
107108
getProposalProcedures TxProposalProceduresNone = Nothing
108-
getProposalProcedures txpp@(TxProposalProcedures _ _) = Just . toList $ convProposalProcedures txpp
109+
getProposalProcedures (TxProposalProcedures pp) = Just $ fst <$> toList pp
109110

110111
tests :: TestTree
111112
tests =

0 commit comments

Comments
 (0)