Skip to content

Commit

Permalink
Merge pull request #644 from IntersectMBO/jordan/simple-tx-interface
Browse files Browse the repository at this point in the history
Add Cardano.Api.Tx.Compatible
  • Loading branch information
Jimbo4350 authored Oct 3, 2024
2 parents 17eb46f + d6e71bd commit b5e8819
Show file tree
Hide file tree
Showing 8 changed files with 188 additions and 13 deletions.
2 changes: 2 additions & 0 deletions cardano-api/cardano-api.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ library internal
Cardano.Api.SpecialByron
Cardano.Api.StakePoolMetadata
Cardano.Api.Tx.Body
Cardano.Api.Tx.Compatible
Cardano.Api.Tx.Sign
Cardano.Api.TxIn
Cardano.Api.TxMetadata
Expand Down Expand Up @@ -236,6 +237,7 @@ library
Cardano.Api.Byron
Cardano.Api.ChainSync.Client
Cardano.Api.ChainSync.ClientPipelined
Cardano.Api.Compatible
Cardano.Api.Crypto.Ed25519Bip32
Cardano.Api.Experimental
Cardano.Api.Ledger
Expand Down
1 change: 1 addition & 0 deletions cardano-api/internal/Cardano/Api/Eon/ConwayEraOnwards.hs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ type ConwayEraOnwardsConstraints era =
, Consensus.ShelleyCompatible (ConsensusProtocol era) (ShelleyLedgerEra era)
, L.ADDRHASH (Consensus.PraosProtocolSupportsNodeCrypto (ConsensusProtocol era)) ~ Blake2b.Blake2b_224
, L.AlonzoEraTxOut (ShelleyLedgerEra era)
, L.AlonzoEraTxWits (ShelleyLedgerEra era)
, L.BabbageEraTxBody (ShelleyLedgerEra era)
, L.ConwayEraGov (ShelleyLedgerEra era)
, L.ConwayEraPParams (ShelleyLedgerEra era)
Expand Down
1 change: 1 addition & 0 deletions cardano-api/internal/Cardano/Api/Eon/ShelleyBasedEra.hs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ type ShelleyBasedEraConstraints era =
, L.EraTxBody (ShelleyLedgerEra era)
, L.EraTxOut (ShelleyLedgerEra era)
, L.EraUTxO (ShelleyLedgerEra era)
, L.EraTxWits (ShelleyLedgerEra era)
, L.HashAnnotated (L.TxBody (ShelleyLedgerEra era)) L.EraIndependentTxBody L.StandardCrypto
, L.ShelleyEraTxCert (ShelleyLedgerEra era)
, FromCBOR (Consensus.ChainDepState (ConsensusProtocol era))
Expand Down
9 changes: 9 additions & 0 deletions cardano-api/internal/Cardano/Api/Script.hs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ module Cardano.Api.Script
-- * Reference scripts
, ReferenceScript (..)
, refScriptToShelleyScript
, getScriptWitnessReferenceInput

-- * Use of a script in an era as a witness
, WitCtxTxIn
Expand Down Expand Up @@ -694,6 +695,14 @@ data SimpleScriptOrReferenceInput lang
| SReferenceScript TxIn (Maybe ScriptHash)
deriving (Eq, Show)

getScriptWitnessReferenceInput :: ScriptWitness witctx era -> Maybe TxIn
getScriptWitnessReferenceInput (SimpleScriptWitness _ (SReferenceScript txIn _)) =
Just txIn
getScriptWitnessReferenceInput (PlutusScriptWitness _ _ (PReferenceScript txIn _) _ _ _) =
Just txIn
getScriptWitnessReferenceInput (SimpleScriptWitness _ (SScript _)) = Nothing
getScriptWitnessReferenceInput (PlutusScriptWitness _ _ (PScript _) _ _ _) = Nothing

-- | A /use/ of a script within a transaction body to witness that something is
-- being used in an authorised manner. That can be
--
Expand Down
25 changes: 13 additions & 12 deletions cardano-api/internal/Cardano/Api/Tx/Body.hs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ module Cardano.Api.Tx.Body
, convWithdrawals
, getScriptIntegrityHash
, mkCommonTxBody
, scriptWitnessesProposing
, toAuxiliaryData
, toByronTxId
, toShelleyTxId
Expand Down Expand Up @@ -3367,18 +3368,18 @@ collectTxBodyScriptWitnesses
, witness <- maybeToList (Map.lookup voter witnesses)
]

scriptWitnessesProposing
:: TxProposalProcedures BuildTx era
-> [(ScriptWitnessIndex, AnyScriptWitness era)]
scriptWitnessesProposing TxProposalProceduresNone = []
scriptWitnessesProposing (TxProposalProcedures proposalProcedures (BuildTxWith mScriptWitnesses))
| Map.null mScriptWitnesses = []
| otherwise =
[ (ScriptWitnessIndexProposing ix, AnyScriptWitness witness)
| let proposalsList = toList proposalProcedures
, (ix, proposal) <- zip [0 ..] proposalsList
, witness <- maybeToList (Map.lookup proposal mScriptWitnesses)
]
scriptWitnessesProposing
:: TxProposalProcedures BuildTx era
-> [(ScriptWitnessIndex, AnyScriptWitness era)]
scriptWitnessesProposing TxProposalProceduresNone = []
scriptWitnessesProposing (TxProposalProcedures proposalProcedures (BuildTxWith mScriptWitnesses))
| Map.null mScriptWitnesses = []
| otherwise =
[ (ScriptWitnessIndexProposing ix, AnyScriptWitness witness)
| let proposalsList = toList proposalProcedures
, (ix, proposal) <- zip [0 ..] proposalsList
, witness <- maybeToList (Map.lookup proposal mScriptWitnesses)
]

-- This relies on the TxId Ord instance being consistent with the
-- Ledger.TxId Ord instance via the toShelleyTxId conversion
Expand Down
155 changes: 155 additions & 0 deletions cardano-api/internal/Cardano/Api/Tx/Compatible.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeOperators #-}

-- | This module provides a way to construct a simple transaction over all eras.
-- It is exposed for testing purposes only.
module Cardano.Api.Tx.Compatible
( AnyProtocolUpdate (..)
, createCompatibleSignedTx
)
where

import Cardano.Api.Eon.ConwayEraOnwards
import Cardano.Api.Eon.ShelleyBasedEra
import Cardano.Api.Eon.ShelleyToBabbageEra
import Cardano.Api.ProtocolParameters
import Cardano.Api.Script
import Cardano.Api.Tx.Body
import Cardano.Api.Tx.Sign
import Cardano.Api.Value

import qualified Cardano.Ledger.Api as L

import Control.Error (catMaybes)
import qualified Data.Map.Strict as Map
import Data.Maybe.Strict
import qualified Data.Sequence.Strict as Seq
import Data.Set (fromList)
import Lens.Micro

data AnyProtocolUpdate era where
ShelleyToBabbageProtocolUpdate
:: ShelleyToBabbageEra era
-> UpdateProposal
-> AnyProtocolUpdate era
ConwayEraOnwardsProtocolUpdate
:: ConwayEraOnwards era
-> TxProposalProcedures BuildTx era
-> AnyProtocolUpdate era
NoPParamsUpdate
:: ShelleyBasedEra era
-> AnyProtocolUpdate era

createCompatibleSignedTx
:: forall era
. ShelleyBasedEra era
-> [TxIn]
-> [TxOut CtxTx era]
-> [KeyWitness era]
-> Lovelace
-- ^ Fee
-> AnyProtocolUpdate era
-> Either ProtocolParametersConversionError (Tx era)
createCompatibleSignedTx sbeF ins outs witnesses txFee' anyProtocolUpdate =
shelleyBasedEraConstraints sbeF $
case anyProtocolUpdate of
ShelleyToBabbageProtocolUpdate shelleyToBabbageEra updateProposal -> do
let sbe = shelleyToBabbageEraToShelleyBasedEra shelleyToBabbageEra

ledgerPParamsUpdate <- toLedgerUpdate sbe updateProposal

let txbody = createCommonTxBody sbe ins outs txFee'
bodyWithProtocolUpdate =
shelleyToBabbageEraConstraints shelleyToBabbageEra $
txbody & L.updateTxBodyL .~ SJust ledgerPParamsUpdate
finalTx =
L.mkBasicTx bodyWithProtocolUpdate
& L.witsTxL .~ shelleyToBabbageEraConstraints shelleyToBabbageEra allShelleyToBabbageWitnesses

return $ ShelleyTx sbe finalTx
NoPParamsUpdate sbe -> do
let txbody = createCommonTxBody sbe ins outs txFee'
finalTx = L.mkBasicTx txbody & L.witsTxL .~ shelleyBasedEraConstraints sbe allShelleyToBabbageWitnesses

return $ ShelleyTx sbe finalTx
ConwayEraOnwardsProtocolUpdate conwayOnwards proposalProcedures -> do
let sbe = conwayEraOnwardsToShelleyBasedEra conwayOnwards
proposals = convProposalProcedures proposalProcedures
apiScriptWitnesses = scriptWitnessesProposing proposalProcedures
ledgerScripts = convScripts apiScriptWitnesses
referenceInputs =
map toShelleyTxIn $
catMaybes [getScriptWitnessReferenceInput sWit | (_, AnyScriptWitness sWit) <- apiScriptWitnesses]
sData = convScriptData sbe outs apiScriptWitnesses (BuildTxWith TxSupplementalDataNone)
txbody =
conwayEraOnwardsConstraints conwayOnwards $
createCommonTxBody sbe ins outs txFee'
& L.referenceInputsTxBodyL .~ fromList referenceInputs
& L.proposalProceduresTxBodyL
.~ proposals

finalTx =
L.mkBasicTx txbody
& L.witsTxL
.~ conwayEraOnwardsConstraints conwayOnwards (allConwayEraOnwardsWitnesses sData ledgerScripts)

return $ ShelleyTx sbe finalTx
where
shelleyKeywitnesses =
fromList [w | ShelleyKeyWitness _ w <- witnesses]

shelleyBootstrapWitnesses =
fromList [w | ShelleyBootstrapWitness _ w <- witnesses]

allConwayEraOnwardsWitnesses
:: L.AlonzoEraTxWits (ShelleyLedgerEra era)
=> L.EraCrypto (ShelleyLedgerEra era) ~ L.StandardCrypto
=> TxBodyScriptData era -> [L.Script (ShelleyLedgerEra era)] -> L.TxWits (ShelleyLedgerEra era)
allConwayEraOnwardsWitnesses sData ledgerScripts =
let (datums, redeemers) = case sData of
TxBodyScriptData _ ds rs -> (ds, rs)
TxBodyNoScriptData -> (mempty, L.Redeemers mempty)
in L.mkBasicTxWits
& L.addrTxWitsL
.~ shelleyKeywitnesses
& L.bootAddrTxWitsL
.~ shelleyBootstrapWitnesses
& L.datsTxWitsL .~ datums
& L.rdmrsTxWitsL .~ redeemers
& L.scriptTxWitsL
.~ Map.fromList
[ (L.hashScript sw, sw)
| sw <- ledgerScripts
]

allShelleyToBabbageWitnesses
:: L.EraTxWits (ShelleyLedgerEra era)
=> L.EraCrypto (ShelleyLedgerEra era) ~ L.StandardCrypto
=> L.TxWits (ShelleyLedgerEra era)
allShelleyToBabbageWitnesses =
L.mkBasicTxWits
& L.addrTxWitsL
.~ shelleyKeywitnesses
& L.bootAddrTxWitsL
.~ shelleyBootstrapWitnesses

createCommonTxBody
:: ShelleyBasedEra era
-> [TxIn]
-> [TxOut ctx era]
-> Lovelace
-> L.TxBody (ShelleyLedgerEra era)
createCommonTxBody era ins outs txFee' =
let txIns' = map toShelleyTxIn ins
txOuts' = map (toShelleyTxOutAny era) outs
in shelleyBasedEraConstraints era $
L.mkBasicTxBody
& L.inputsTxBodyL
.~ fromList txIns'
& L.outputsTxBodyL
.~ Seq.fromList txOuts'
& L.feeTxBodyL
.~ txFee'
2 changes: 1 addition & 1 deletion cardano-api/internal/Cardano/Api/TxMetadata.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
-- | Metadata embedded in transactions
module Cardano.Api.TxMetadata
( -- * Types
TxMetadata (TxMetadata)
TxMetadata (..)

-- * Class
, AsTxMetadata (..)
Expand Down
6 changes: 6 additions & 0 deletions cardano-api/src/Cardano/Api/Compatible.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module Cardano.Api.Compatible
( module Cardano.Api.Tx.Compatible
)
where

import Cardano.Api.Tx.Compatible

0 comments on commit b5e8819

Please sign in to comment.