Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
Jimbo4350 committed Feb 28, 2025
1 parent 3011197 commit 7954288
Show file tree
Hide file tree
Showing 16 changed files with 1,142 additions and 43 deletions.
12 changes: 10 additions & 2 deletions cardano-api/cardano-api.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,6 @@ library
Cardano.Api.Internal.Eon.ShelleyBasedEra
Cardano.Api.Internal.Eras
Cardano.Api.Internal.Error
Cardano.Api.Internal.Experimental.Eras
Cardano.Api.Internal.Experimental.Tx
Cardano.Api.Internal.Fees
Cardano.Api.Internal.Genesis
Cardano.Api.Internal.GenesisParameters
Expand Down Expand Up @@ -200,6 +198,15 @@ library
Cardano.Api.Internal.Eon.ShelleyToMaryEra
Cardano.Api.Internal.Eras.Case
Cardano.Api.Internal.Eras.Core
Cardano.Api.Internal.Experimental.Eras
Cardano.Api.Internal.Experimental.Plutus.IndexedPlutusScriptWitness
Cardano.Api.Internal.Experimental.Plutus.Shim.LegacyScripts
Cardano.Api.Internal.Experimental.Plutus.Script
Cardano.Api.Internal.Experimental.Plutus.ScriptWitness
Cardano.Api.Internal.Experimental.Simple.Script
Cardano.Api.Internal.Experimental.Tx
Cardano.Api.Internal.Experimental.Witness.TxScriptWitnessRequirements
Cardano.Api.Internal.Experimental.Witness.AnyWitness
Cardano.Api.Internal.Feature
Cardano.Api.Internal.Governance.Actions.ProposalProcedure
Cardano.Api.Internal.Governance.Actions.VotingProcedure
Expand Down Expand Up @@ -248,6 +255,7 @@ library
Cardano.Api.Internal.SerialiseUsing
Cardano.Api.Internal.SpecialByron
Cardano.Api.Internal.StakePoolMetadata
Cardano.Api.Internal.Tx.BuildTxWith
Cardano.Api.Internal.Tx.UTxO
Cardano.Api.Internal.TxIn
Cardano.Api.Internal.TxMetadata
Expand Down
24 changes: 14 additions & 10 deletions cardano-api/gen/Test/Gen/Cardano/Api/Typed.hs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ import qualified Data.ByteString.Base16 as Base16
import Data.Ratio (Ratio, (%))
import Data.String
import Test.Gen.Cardano.Api.Hardcoded
import Data.Typeable
import Data.Word (Word16, Word32, Word64)
import GHC.Exts (IsList (..))
import GHC.Stack
Expand Down Expand Up @@ -707,7 +708,7 @@ genTxWithdrawals =
]
)

genTxCertificates :: CardanoEra era -> Gen (TxCertificates BuildTx era)
genTxCertificates :: Typeable era => CardanoEra era -> Gen (TxCertificates BuildTx era)
genTxCertificates =
inEonForEra
(pure TxCertificatesNone)
Expand All @@ -720,7 +721,7 @@ genTxCertificates =
]
)

genCertificate :: forall era. ShelleyBasedEra era -> Gen (Certificate era)
genCertificate :: forall era. Typeable era => ShelleyBasedEra era -> Gen (Certificate era)
genCertificate sbe =
Gen.choice
$ catMaybes
Expand Down Expand Up @@ -871,7 +872,7 @@ genTxMintValue =
, pure $ TxMintValue w (fromList assets)
]

genTxBodyContent :: ShelleyBasedEra era -> Gen (TxBodyContent BuildTx era)
genTxBodyContent :: Typeable era => ShelleyBasedEra era -> Gen (TxBodyContent BuildTx era)
genTxBodyContent sbe = do
let era = toCardanoEra sbe
txIns <-
Expand Down Expand Up @@ -992,7 +993,8 @@ genWitnessesByron = Gen.list (Range.constant 1 10) genByronKeyWitness

-- | This generator validates generated 'TxBodyContent' and backtracks when the generated body
-- fails the validation. That also means that it is quite slow.
genValidTxBody :: ShelleyBasedEra era
genValidTxBody :: Typeable era
=> ShelleyBasedEra era
-> Gen (TxBody era, TxBodyContent BuildTx era) -- ^ validated 'TxBody' and 'TxBodyContent'
genValidTxBody sbe =
Gen.mapMaybe
Expand All @@ -1003,7 +1005,7 @@ genValidTxBody sbe =
(genTxBodyContent sbe)

-- | Partial! This function will throw an error when the generated transaction is invalid.
genTxBody :: HasCallStack => ShelleyBasedEra era -> Gen (TxBody era)
genTxBody :: (HasCallStack, Typeable era) => ShelleyBasedEra era -> Gen (TxBody era)
genTxBody era = do
res <- Api.createTransactionBody era <$> genTxBodyContent era
case res of
Expand Down Expand Up @@ -1042,15 +1044,15 @@ genScriptValidity :: Gen ScriptValidity
genScriptValidity = Gen.element [ScriptInvalid, ScriptValid]

genTx
:: ()
:: Typeable era
=> ShelleyBasedEra era
-> Gen (Tx era)
genTx era =
makeSignedTransaction
<$> genWitnesses era
<*> (fst <$> genValidTxBody era)

genWitnesses :: ShelleyBasedEra era -> Gen [KeyWitness era]
genWitnesses :: Typeable era => ShelleyBasedEra era -> Gen [KeyWitness era]
genWitnesses sbe = do
bsWits <- Gen.list (Range.constant 0 10) (genShelleyBootstrapWitness sbe)
keyWits <- Gen.list (Range.constant 0 10) (genShelleyKeyWitness sbe)
Expand Down Expand Up @@ -1095,7 +1097,7 @@ genWitnessNetworkIdOrByronAddress =
]

genShelleyBootstrapWitness
:: ()
:: Typeable era
=> ShelleyBasedEra era
-> Gen (KeyWitness era)
genShelleyBootstrapWitness sbe =
Expand All @@ -1104,8 +1106,10 @@ genShelleyBootstrapWitness sbe =
<*> (fst <$> genValidTxBody sbe)
<*> genSigningKey AsByronKey


genShelleyKeyWitness
:: ()
=> Typeable era
=> ShelleyBasedEra era
-> Gen (KeyWitness era)
genShelleyKeyWitness sbe =
Expand All @@ -1114,7 +1118,7 @@ genShelleyKeyWitness sbe =
<*> genShelleyWitnessSigningKey

genShelleyWitness
:: ()
:: Typeable era
=> ShelleyBasedEra era
-> Gen (KeyWitness era)
genShelleyWitness sbe =
Expand All @@ -1135,7 +1139,7 @@ genShelleyWitnessSigningKey =
]

genCardanoKeyWitness
:: ()
:: Typeable era
=> ShelleyBasedEra era
-> Gen (KeyWitness era)
genCardanoKeyWitness = genShelleyWitness
Expand Down
2 changes: 2 additions & 0 deletions cardano-api/src/Cardano/Api/Internal/Eon/AlonzoEraOnwards.hs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import Cardano.Binary
import Cardano.Crypto.Hash.Blake2b qualified as Blake2b
import Cardano.Crypto.Hash.Class qualified as C
import Cardano.Crypto.VRF qualified as C
import Cardano.Ledger.Allegra.Scripts qualified as L
import Cardano.Ledger.Alonzo.Plutus.Context qualified as Plutus
import Cardano.Ledger.Alonzo.Scripts qualified as L
import Cardano.Ledger.Alonzo.Tx qualified as L
Expand Down Expand Up @@ -103,6 +104,7 @@ type AlonzoEraOnwardsConstraints era =
, L.EraUTxO (ShelleyLedgerEra era)
, L.HashAnnotated (L.TxBody (ShelleyLedgerEra era)) L.EraIndependentTxBody L.StandardCrypto
, L.MaryEraTxBody (ShelleyLedgerEra era)
, L.NativeScript (ShelleyLedgerEra era) ~ L.Timelock (ShelleyLedgerEra era)
, Plutus.EraPlutusContext (ShelleyLedgerEra era)
, L.Script (ShelleyLedgerEra era) ~ L.AlonzoScript (ShelleyLedgerEra era)
, L.ScriptsNeeded (ShelleyLedgerEra era) ~ L.AlonzoScriptsNeeded (ShelleyLedgerEra era)
Expand Down
6 changes: 6 additions & 0 deletions cardano-api/src/Cardano/Api/Internal/Experimental/Eras.hs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ module Cardano.Api.Internal.Experimental.Eras
)
where

import Cardano.Api.Internal.Eon.AlonzoEraOnwards
import Cardano.Api.Internal.Eon.BabbageEraOnwards
import Cardano.Api.Internal.Eon.Convert
import Cardano.Api.Internal.Eon.ShelleyBasedEra (ShelleyBasedEra (..), ShelleyLedgerEra)
Expand Down Expand Up @@ -206,6 +207,11 @@ instance Convert Era ShelleyBasedEra where
BabbageEra -> ShelleyBasedEraBabbage
ConwayEra -> ShelleyBasedEraConway

instance Convert Era AlonzoEraOnwards where
convert = \case
BabbageEra -> AlonzoEraOnwardsBabbage
ConwayEra -> AlonzoEraOnwardsConway

instance Convert Era BabbageEraOnwards where
convert = \case
BabbageEra -> BabbageEraOnwardsBabbage
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}

module Cardano.Api.Internal.Experimental.Plutus.IndexedPlutusScriptWitness
( -- * Constuct an indexed plutus script witness.
AnyIndexedPlutusScriptWitness (..)
, IndexedPlutusScriptWitness (..)
, createIndexedPlutusScriptWitnesses
, getAnyWitnessRedeemerPointerMap
)
where

import Cardano.Api.Internal.Eon.AlonzoEraOnwards
import Cardano.Api.Internal.Eon.ShelleyBasedEra
import Cardano.Api.Internal.Experimental.Plutus.ScriptWitness
import Cardano.Api.Internal.Experimental.Witness.AnyWitness
import Cardano.Api.Internal.Script (toAlonzoExUnits)
import Cardano.Api.Internal.ScriptData
import Cardano.Api.Ledger qualified as L

import Cardano.Ledger.Alonzo.TxWits qualified as L

import Data.Word
import GHC.Exts

-- | A Plutus script witness along the thing it is witnessing and the index of that thing.
-- E.g transaction input, certificate, withdrawal, minting policy, etc.
-- A Plutus script witness only makes sense in the context of what it is witnessing
-- and the index of the thing it is witnessing.
data IndexedPlutusScriptWitness witnessable (lang :: L.Language) (purpose :: PlutusScriptPurpose) era where
IndexedPlutusScriptWitness
:: Witnessable witnessable era
-> (L.PlutusPurpose L.AsIx era)
-> (PlutusScriptWitness lang purpose era)
-> IndexedPlutusScriptWitness witnessable lang purpose era

data AnyIndexedPlutusScriptWitness era where
AnyIndexedPlutusScriptWitness
:: GetPlutusScriptPurpose era
=> IndexedPlutusScriptWitness witnessable lang purpose era
-> AnyIndexedPlutusScriptWitness era

createIndexedPlutusScriptWitness
:: Word32
-> Witnessable witnessable era
-> PlutusScriptWitness lang purpose era
-> IndexedPlutusScriptWitness witnessable lang purpose era
createIndexedPlutusScriptWitness index witnessable =
IndexedPlutusScriptWitness witnessable (toPlutusScriptPurpose index witnessable)

createIndexedPlutusScriptWitnesses
:: [(Witnessable witnessable era, AnyWitness era)]
-> [AnyIndexedPlutusScriptWitness era]
createIndexedPlutusScriptWitnesses witnessableThings =
[ AnyIndexedPlutusScriptWitness $ createIndexedPlutusScriptWitness index thing sWit
| (index, (thing, AnyPlutusScriptWitness sWit)) <- zip [0 ..] witnessableThings
]

-- | The transaction's redeemer pointer map allows the ledger to connect a redeemer and execution unit pairing to the relevant
-- script. The ledger basically reconstructs the indicies (redeemer pointers) of this map can then look up the relevant
-- execution units/redeemer pairing. NB the redeemer pointer has been renamed to 'PlutusPurpose AsIndex' in the ledger.
getAnyWitnessRedeemerPointerMap
:: AlonzoEraOnwards era
-> (Witnessable witnessable (ShelleyLedgerEra era), AnyWitness (ShelleyLedgerEra era))
-> L.Redeemers (ShelleyLedgerEra era)
getAnyWitnessRedeemerPointerMap eon (_, AnyKeyWitness) = alonzoEraOnwardsConstraints eon mempty
getAnyWitnessRedeemerPointerMap eon (_, AnySimpleScriptWitness{}) = alonzoEraOnwardsConstraints eon mempty
getAnyWitnessRedeemerPointerMap eon anyWit =
constructRedeeemerPointerMap eon $
createIndexedPlutusScriptWitnesses [anyWit]

-- | An 'IndexedPlutusScriptWitness' contains everything we need to construct a single
-- entry in the redeemer pointer map.
constructRedeemerPointer
:: AlonzoEraOnwards era
-> AnyIndexedPlutusScriptWitness (ShelleyLedgerEra era)
-> L.Redeemers (ShelleyLedgerEra era)
constructRedeemerPointer eon (AnyIndexedPlutusScriptWitness (IndexedPlutusScriptWitness _ purpose scriptWit)) =
let PlutusScriptWitness _ _ _ redeemer execUnits = scriptWit
in alonzoEraOnwardsConstraints eon $
L.Redeemers $
fromList [(purpose, (toAlonzoData redeemer, toAlonzoExUnits execUnits))]

constructRedeeemerPointerMap
:: AlonzoEraOnwards era
-> [AnyIndexedPlutusScriptWitness ((ShelleyLedgerEra era))]

Check notice

Code scanning / HLint

Redundant bracket Note

cardano-api/src/Cardano/Api/Internal/Experimental/Plutus/IndexedPlutusScriptWitness.hs:169:38-59: Suggestion: Redundant bracket
  
Found:
  ((ShelleyLedgerEra era))
  
Perhaps:
  (ShelleyLedgerEra era)
-> L.Redeemers (ShelleyLedgerEra era)
constructRedeeemerPointerMap eon scriptWits =
let redeemerPointers = map (constructRedeemerPointer eon) scriptWits
in alonzoEraOnwardsConstraints eon $ mconcat redeemerPointers
45 changes: 45 additions & 0 deletions cardano-api/src/Cardano/Api/Internal/Experimental/Plutus/Script.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE StandaloneDeriving #-}

module Cardano.Api.Internal.Experimental.Plutus.Script
( PlutusScriptInEra (..)
, PlutusScriptOrReferenceInput (..)
)
where

import Cardano.Api.Internal.TxIn (TxIn)

import Cardano.Ledger.Plutus.Language (PlutusRunnable)
import Cardano.Ledger.Plutus.Language qualified as L

-- | A Plutus script in a particular era.
-- Why PlutusRunnable? Mainly for deserialization benefits.
-- The deserialization of this type looks at the
-- major protocol version and the script language to determine if
-- indeed the script is runnable. This is a dramatic improvement over the old api
-- which essentially read a 'ByteString' and hoped for the best.
-- Any failures due to malformed/invalid scripts were caught upon transaction
-- submission or running the script when attempting to predict the necessary execution units.
--
-- Where do we get the major protocol version from?
-- In order to access the major protocol version we pass in an 'era` type parameter which
-- can be translated to the major protocol version.
--
-- Where do we get the script language from?
-- The serialized version of 'PlutusRunnable' encodes the script language.
-- See `DecCBOR (PlutusRunnable l)` in cardano-ledger for more details.
data PlutusScriptInEra (lang :: L.Language) era where
PlutusScriptInEra :: PlutusRunnable lang -> PlutusScriptInEra lang era

deriving instance Show (PlutusScriptInEra lang era)

-- | You can provide the plutus script directly in the transaction
-- or a reference input that points to the script in the UTxO.
-- Using a reference script saves space in your transaction.
data PlutusScriptOrReferenceInput lang era
= PScript (PlutusScriptInEra lang era)
| PReferenceScript TxIn
deriving Show
Loading

0 comments on commit 7954288

Please sign in to comment.