Skip to content

Commit e5fd8f4

Browse files
committed
WIP
1 parent 21b6bd9 commit e5fd8f4

File tree

6 files changed

+85
-7
lines changed

6 files changed

+85
-7
lines changed

eras/babbage/impl/src/Cardano/Ledger/Babbage/Rules/Utxo.hs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ module Cardano.Ledger.Babbage.Rules.Utxo (
2424
validateTotalCollateral,
2525
validateCollateralEqBalance,
2626
validateOutputTooSmallUTxO,
27+
disjointRefInputs,
2728
) where
2829

2930
import Cardano.Ledger.Allegra.Rules (AllegraUtxoPredFailure, shelleyToAllegraUtxoPredFailure)
@@ -60,7 +61,7 @@ import Cardano.Ledger.BaseTypes (
6061
networkId,
6162
systemStart,
6263
)
63-
import Cardano.Ledger.Binary (DecCBOR (..), EncCBOR (..), Sized (..))
64+
import Cardano.Ledger.Binary (DecCBOR (..), EncCBOR (..), Sized (..), natVersion)
6465
import Cardano.Ledger.Binary.Coders
6566
import Cardano.Ledger.Coin (Coin (..), DeltaCoin, toDeltaCoin)
6667
import Cardano.Ledger.Rules.ValidationMode (
@@ -231,7 +232,9 @@ disjointRefInputs ::
231232
Test (BabbageUtxoPredFailure era)
232233
disjointRefInputs pp inputs refInputs =
233234
when
234-
(pvMajor (pp ^. ppProtocolVersionL) > eraProtVerHigh @BabbageEra)
235+
( pvMajor (pp ^. ppProtocolVersionL) > eraProtVerHigh @BabbageEra
236+
&& pvMajor (pp ^. ppProtocolVersionL) < natVersion @11
237+
)
235238
(failureOnNonEmpty common BabbageNonDisjointRefInputs)
236239
where
237240
common = inputs `Set.intersection` refInputs

eras/conway/impl/cardano-ledger-conway.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ library testlib
185185
microlens-mtl,
186186
mtl,
187187
plutus-ledger-api,
188+
plutus-preprocessor,
188189
prettyprinter,
189190
small-steps >=1.1,
190191
text,

eras/conway/impl/src/Cardano/Ledger/Conway/TxInfo.hs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ data ConwayContextError era
160160
| VotingProceduresFieldNotSupported !(VotingProcedures era)
161161
| ProposalProceduresFieldNotSupported !(OSet.OSet (ProposalProcedure era))
162162
| TreasuryDonationFieldNotSupported !Coin
163+
| ReferenceInputsNotDisjointFromInputs !(Set.Set TxIn)
163164
deriving (Generic)
164165

165166
deriving instance
@@ -226,6 +227,8 @@ instance
226227
encode $ Sum ProposalProceduresFieldNotSupported 13 !> To proposalProcedures
227228
TreasuryDonationFieldNotSupported coin ->
228229
encode $ Sum TreasuryDonationFieldNotSupported 14 !> To coin
230+
ReferenceInputsNotDisjointFromInputs common ->
231+
encode $ Sum ReferenceInputsNotDisjointFromInputs 15 !> To common
229232

230233
instance
231234
( EraPParams era
@@ -243,6 +246,7 @@ instance
243246
12 -> SumD VotingProceduresFieldNotSupported <! From
244247
13 -> SumD ProposalProceduresFieldNotSupported <! From
245248
14 -> SumD TreasuryDonationFieldNotSupported <! From
249+
15 -> SumD ReferenceInputsNotDisjointFromInputs <! From
246250
n -> Invalid n
247251

248252
instance
@@ -275,6 +279,10 @@ instance
275279
kindObject
276280
"TreasuryDonationFieldNotSupported"
277281
["treasury_donation" .= toJSON coin]
282+
ReferenceInputsNotDisjointFromInputs common ->
283+
kindObject
284+
"ReferenceInputsNotDisjointFromInputs"
285+
["common" .= toJSON common]
278286

279287
-- | Given a TxOut, translate it for V2 and return (Right transalation).
280288
-- If the transaction contains any Byron addresses or Babbage features, return Left.
@@ -451,8 +459,14 @@ instance EraPlutusTxInfo 'PlutusV3 ConwayEra where
451459
toPlutusTxInfo proxy LedgerTxInfo {ltiProtVer, ltiEpochInfo, ltiSystemStart, ltiUTxO, ltiTx} = do
452460
timeRange <-
453461
Alonzo.transValidityInterval ltiTx ltiProtVer ltiEpochInfo ltiSystemStart (txBody ^. vldtTxBodyL)
454-
inputs <- mapM (transTxInInfoV3 ltiUTxO) (Set.toList (txBody ^. inputsTxBodyL))
455-
refInputs <- mapM (transTxInInfoV3 ltiUTxO) (Set.toList (txBody ^. referenceInputsTxBodyL))
462+
let
463+
txInputs = txBody ^. inputsTxBodyL
464+
refInputs = txBody ^. referenceInputsTxBodyL
465+
inputsInfo <- mapM (transTxInInfoV3 ltiUTxO) (Set.toList txInputs)
466+
refInputsInfo <- mapM (transTxInInfoV3 ltiUTxO) (Set.toList refInputs)
467+
let
468+
commonInputs = txInputs `Set.intersection` refInputs
469+
unless (Set.null commonInputs) . Left $ ReferenceInputsNotDisjointFromInputs commonInputs
456470
outputs <-
457471
zipWithM
458472
(Babbage.transTxOutV2 . TxOutFromOutput)
@@ -462,9 +476,9 @@ instance EraPlutusTxInfo 'PlutusV3 ConwayEra where
462476
plutusRedeemers <- Babbage.transTxRedeemers proxy ltiProtVer ltiTx
463477
pure
464478
PV3.TxInfo
465-
{ PV3.txInfoInputs = inputs
479+
{ PV3.txInfoInputs = inputsInfo
466480
, PV3.txInfoOutputs = outputs
467-
, PV3.txInfoReferenceInputs = refInputs
481+
, PV3.txInfoReferenceInputs = refInputsInfo
468482
, PV3.txInfoFee = transCoinToLovelace (txBody ^. feeTxBodyL)
469483
, PV3.txInfoMint = transMintValue (txBody ^. mintTxBodyL)
470484
, PV3.txInfoTxCerts = txCerts

eras/conway/impl/testlib/Test/Cardano/Ledger/Conway/Imp/UtxoSpec.hs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
{-# LANGUAGE AllowAmbiguousTypes #-}
12
{-# LANGUAGE DataKinds #-}
23
{-# LANGUAGE FlexibleContexts #-}
34
{-# LANGUAGE LambdaCase #-}
5+
{-# LANGUAGE NumericUnderscores #-}
46
{-# LANGUAGE OverloadedStrings #-}
57
{-# LANGUAGE PatternSynonyms #-}
68
{-# LANGUAGE ScopedTypeVariables #-}
@@ -16,8 +18,10 @@ import Cardano.Ledger.Babbage.TxOut (referenceScriptTxOutL)
1618
import Cardano.Ledger.BaseTypes
1719
import Cardano.Ledger.Coin (Coin (..))
1820
import Cardano.Ledger.Conway.PParams (ppMinFeeRefScriptCostPerByteL)
21+
import Cardano.Ledger.Credential (Credential (..), StakeReference (..))
1922
import Cardano.Ledger.MemoBytes (getMemoRawBytes)
20-
import Cardano.Ledger.Plutus.Language (SLanguage (..), hashPlutusScript, plutusBinary)
23+
import Cardano.Ledger.Plutus.Language (Language (..), Plutus (..), PlutusLanguage, SLanguage (..), hashPlutusScript)
24+
import Cardano.Ledger.Plutus.Preprocessor.Binary.V2 (inputsIsSubsetOfRefInputsBytes)
2125
import Cardano.Ledger.Shelley.Core
2226
import Cardano.Ledger.Shelley.LedgerState
2327
import Cardano.Ledger.Shelley.Scripts (
@@ -39,6 +43,11 @@ import Test.Cardano.Ledger.Core.Rational ((%!))
3943
import Test.Cardano.Ledger.Core.Utils (txInAt)
4044
import Test.Cardano.Ledger.Imp.Common
4145
import Test.Cardano.Ledger.Plutus.Examples (alwaysSucceedsNoDatum)
46+
import Data.Maybe (fromJust)
47+
import Cardano.Ledger.Conway.Core (AlonzoEraTxWits(..), ppMaxTxExUnitsL, AlonzoEraTxBody (..))
48+
import Cardano.Ledger.Alonzo.TxWits (Redeemers(..))
49+
import Cardano.Ledger.Plutus (Data(..))
50+
import qualified PlutusLedgerApi.Common as P
4251

4352
spec ::
4453
forall era.
@@ -63,6 +72,37 @@ spec =
6372
[fromNativeScript spendingScript, fromNativeScript spendingScript]
6473
++ extraScripts
6574
++ extraScripts
75+
describe "disjoint inputs and reference inputs" $ do
76+
let
77+
plutus = Plutus $ snd inputsIsSubsetOfRefInputsBytes
78+
scriptAddr :: forall (pv :: Language). PlutusLanguage pv => Addr
79+
scriptAddr =
80+
mkAddr
81+
(ScriptHashObj @'Payment $ hashPlutusScript @pv plutus)
82+
StakeRefNull
83+
script :: forall (pv :: Language). PlutusLanguage pv => PlutusScript era
84+
script = fromJust $ mkPlutusScript @era @pv plutus
85+
--it "Same script can appear in regular and reference inputs in PlutusV2" $ do
86+
-- txIn <- sendCoinTo (scriptAddr @'PlutusV2) $ Coin 1_000_000
87+
-- submitTx_ $
88+
-- mkBasicTx mkBasicTxBody
89+
-- & bodyTxL . inputsTxBodyL .~ Set.singleton txIn
90+
-- & bodyTxL . referenceInputsTxBodyL .~ Set.singleton txIn
91+
-- & witsTxL . scriptTxWitsL .~ Map.singleton (hashPlutusScript @'PlutusV2 plutus) (PlutusScript $ script @'PlutusV2)
92+
it "Same script cannot appear in regular and reference inputs in PlutusV3" $ do
93+
maxExUnits <- getsNES $ nesEsL . curPParamsEpochStateL . ppMaxTxExUnitsL
94+
txIn <- sendCoinTo (scriptAddr @'PlutusV3) $ Coin 1_000_000
95+
collateralIn <- sendCoinTo (scriptAddr @'PlutusV3) $ Coin 1_000_000_000
96+
let
97+
tx =
98+
mkBasicTx mkBasicTxBody
99+
& bodyTxL . inputsTxBodyL .~ Set.singleton txIn
100+
& bodyTxL . referenceInputsTxBodyL .~ Set.singleton txIn
101+
& bodyTxL . collateralInputsTxBodyL .~ Set.singleton collateralIn
102+
& bodyTxL . feeTxBodyL .~ Coin 100_000_000
103+
& witsTxL . scriptTxWitsL .~ Map.singleton (hashPlutusScript @'PlutusV3 plutus) (PlutusScript $ script @'PlutusV3)
104+
& witsTxL . rdmrsTxWitsL .~ Redeemers (Map.singleton (SpendingPurpose (AsIx 0)) (Data $ P.I 0, maxExUnits))
105+
submitTx_ @era tx
66106
where
67107
checkMinFee :: HasCallStack => NativeScript era -> [Script era] -> ImpTestM era ()
68108
checkMinFee scriptToSpend refScripts = do

libs/plutus-preprocessor/src/Cardano/Ledger/Plutus/Preprocessor/Binary/V2.hs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ $purposeIsWellformedWithDatumQ
2828
$datumIsWellformedQ
2929
$inputsOutputsAreNotEmptyNoDatumQ
3030
$inputsOutputsAreNotEmptyWithDatumQ
31+
$inputsIsSubsetOfRefInputsQ
3132

3233
-- ================================================================
3334
-- Compile and serialize the real functions as Plutus scripts.
@@ -110,3 +111,9 @@ inputsOutputsAreNotEmptyWithDatumBytes =
110111
( inputsOutputsAreNotEmptyWithDatumQ
111112
, PlutusBinary $ PV2.serialiseCompiledCode $$(P.compile [||inputsOutputsAreNotEmptyWithDatum||])
112113
)
114+
115+
inputsIsSubsetOfRefInputsBytes :: (Q [Dec], PlutusBinary)
116+
inputsIsSubsetOfRefInputsBytes =
117+
( inputsIsSubsetOfRefInputsQ
118+
, PlutusBinary $ PV2.serialiseCompiledCode $$(P.compile [||inputsIsSubsetOfRefInputs||])
119+
)

libs/plutus-preprocessor/src/Cardano/Ledger/Plutus/Preprocessor/Source/V2.hs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,3 +228,16 @@ inputsOutputsAreNotEmptyWithDatumQ =
228228
then P.error ()
229229
else ()
230230
|]
231+
232+
inputsIsSubsetOfRefInputsQ :: Q [Dec]
233+
inputsIsSubsetOfRefInputsQ =
234+
[d|
235+
inputsIsSubsetOfRefInputs :: P.BuiltinData -> P.BuiltinData -> P.BuiltinData -> ()
236+
inputsIsSubsetOfRefInputs _datum _redeemer context =
237+
case unsafeFromBuiltinData context of
238+
PV2D.ScriptContext txInfo _scriptPurpose ->
239+
if PLD.all (\x -> P.isJust . PLD.find (P.== x) $ PV2D.txInfoReferenceInputs txInfo) $
240+
PV2D.txInfoInputs txInfo
241+
then ()
242+
else P.error ()
243+
|]

0 commit comments

Comments
 (0)