@@ -21,11 +21,13 @@ import Cardano.Ledger.Plutus (SLanguage (..), hashPlutusScript)
2121import Cardano.Ledger.Shelley.Scripts (
2222 pattern RequireSignature ,
2323 )
24- import Cardano.Ledger.TxIn
25- import Control.Monad ( forM )
24+ import Data.Foldable ( for_ )
25+ import Data.List ( inits )
2626import Data.List.NonEmpty (NonEmpty (.. ))
2727import qualified Data.List.NonEmpty as NE
2828import qualified Data.Sequence.Strict as SSeq
29+ import qualified Data.Set as Set
30+ import Data.Traversable (for )
2931import Data.Word (Word32 )
3032import Lens.Micro ((&) , (.~) , (^.) )
3133import Test.Cardano.Ledger.Babbage.ImpTest
@@ -48,38 +50,32 @@ spec = do
4850 let
4951 maxRefScriptSizePerTx = fromIntegral @ Word32 @ Int $ pp ^. ppMaxRefScriptSizePerTxG
5052 maxRefScriptSizePerBlock = fromIntegral @ Word32 @ Int $ pp ^. ppMaxRefScriptSizePerBlockG
53+
5154 txScriptCounts <-
5255 genNumAdditionsExceeding
5356 scriptSize
5457 maxRefScriptSizePerTx
5558 maxRefScriptSizePerBlock
5659
57- let mkTxWithNScripts n = do
58- -- Instead of using the rootTxIn, we are creating an input for each transaction
59- -- that we subsequently need to submit,
60- -- so that we can submit them independently of each other.
61- txIn <- freshKeyAddr_ >>= \ addr -> sendCoinTo addr (Coin 8_000_000 )
62- refIns <- replicateM n $ produceRefScript (fromPlutusScript plutusScript)
63- pure $ mkTxWithRefInputs txIn (NE. fromList refIns)
64-
65- txs <- do
66- forM txScriptCounts $ \ n -> do
67- mkTxWithNScripts n
68- >>= fixupFees
69- >>= updateAddrTxWits
70-
71- let expectedTotalRefScriptSize = scriptSize * sum txScriptCounts
72- predFailures <- expectLeftExpr =<< tryRunImpBBODY txs
73- predFailures
74- `shouldBe` NE. fromList
75- [ injectFailure
76- ( BodyRefScriptsSizeTooBig $
77- Mismatch
78- { mismatchSupplied = expectedTotalRefScriptSize
79- , mismatchExpected = maxRefScriptSizePerBlock
80- }
81- )
82- ]
60+ txs <- for txScriptCounts $ \ n -> do
61+ -- Instead of using the rootTxIn, we're creating an input for each transaction
62+ -- so that transactions that will be submitted in a block
63+ -- can be submitted independently from the ones that prepared the
64+ -- reference inputs
65+ txIn <- freshKeyAddr_ >>= \ addr -> sendCoinTo addr (Coin 100_000_000 )
66+ refIns <- replicateM n $ produceRefScript (fromPlutusScript plutusScript)
67+ pure $ mkTxWithRefInputs txIn (NE. fromList refIns)
68+
69+ submitFailingBlock
70+ txs
71+ [ injectFailure
72+ ( BodyRefScriptsSizeTooBig $
73+ Mismatch
74+ { mismatchSupplied = scriptSize * sum txScriptCounts
75+ , mismatchExpected = maxRefScriptSizePerBlock
76+ }
77+ )
78+ ]
8379
8480 it " BodyRefScriptsSizeTooBig with reference scripts in the same block" $
8581 whenMajorVersionAtLeast @ 11 $ do
@@ -96,37 +92,24 @@ spec = do
9692 maxRefScriptSizePerTx
9793 maxRefScriptSizePerBlock
9894
99- let expectedTotalRefScriptSize = scriptSize * sum txScriptCounts
100-
101- -- We are creating reference scripts and transaction that depend on them in a "simulation",
102- -- so the result will be correctly constructed that are not applied to the ledger state
103- txs :: [Tx TopTx era ] <- simulateThenRestore $ do
104- concat
105- <$> forM
106- txScriptCounts
107- ( \ n -> do
108- -- produce reference scripts
109- refScriptTxs <-
110- replicateM n (produceRefScriptsTx (fromPlutusScript plutusScript :| [] ))
95+ let
96+ -- These txs will be grouped into a block
97+ buildTxs = for_ txScriptCounts $ \ n -> do
98+ refIns <- replicateM n $ produceRefScript (fromPlutusScript plutusScript)
99+ submitTx $
100+ mkBasicTx mkBasicTxBody
101+ & bodyTxL . referenceInputsTxBodyL .~ Set. fromList refIns
111102
112- -- spend using the reference scripts
113- let txIns = (`mkTxInPartial` 0 ) . txIdTx <$> refScriptTxs
114- rootIn <- fst <$> getImpRootTxOut
115- spendTx <- submitTxWithRefInputs rootIn (NE. fromList txIns)
116- pure $ refScriptTxs ++ [spendTx]
103+ withTxsInFailingBlock
104+ buildTxs
105+ [ injectFailure
106+ ( BodyRefScriptsSizeTooBig $
107+ Mismatch
108+ { mismatchSupplied = scriptSize * sum txScriptCounts
109+ , mismatchExpected = maxRefScriptSizePerBlock
110+ }
117111 )
118-
119- predFailures <- expectLeftExpr =<< tryRunImpBBODY txs
120- predFailures
121- `shouldBe` NE. fromList
122- [ injectFailure
123- ( BodyRefScriptsSizeTooBig $
124- Mismatch
125- { mismatchSupplied = expectedTotalRefScriptSize
126- , mismatchExpected = maxRefScriptSizePerBlock
127- }
128- )
129- ]
112+ ]
130113
131114 it " totalRefScriptSizeInBlock" $ do
132115 script <- RequireSignature @ era <$> freshKeyHash
@@ -141,7 +124,7 @@ spec = do
141124 -- their individual reference script sizes, and then restore the original state -
142125 -- meaning the transactions are not actually applied.
143126 -- Finally, we check that the accumulated sizes from both before and after match.
144- txsWithRefScriptSizes :: ([( Tx TopTx era , Int )], Int ) <- simulateThenRestore $ do
127+ txsWithSizes <- simulateThenRestore $ do
145128 let mkTxWithExpectedSize expectedSize txAction = do
146129 tx <- txAction
147130 totalRefScriptSizeInBlock protVer [tx] <$> getUTxO `shouldReturn` expectedSize
@@ -187,24 +170,16 @@ spec = do
187170
188171 -- check and return the accumulated reference script size of all transactions,
189172 -- so we can check that the same sum for the unapplied transactions matches
190- let expectedTotalRefScriptSize = 5 * scriptSize
191- totalRefScriptSizeInBlock protVer (SSeq. fromList (fst <$> txsWithRefScriptSizes))
192- <$> getUTxO `shouldReturn` expectedTotalRefScriptSize
193- pure (txsWithRefScriptSizes, expectedTotalRefScriptSize)
173+ let (txs, sizes) = unzip txsWithRefScriptSizes
174+ totalRefScriptSizeInBlock protVer (SSeq. fromList txs) <$> getUTxO `shouldReturn` sum sizes
194175
195- let (txWithSizes, expectedTotalSize) = txsWithRefScriptSizes
176+ pure txsWithRefScriptSizes
196177
197178 -- for each prefix of the list, the accumulated sum should match the sum of the applied transactions
198- forM_ ([1 .. length txWithSizes] :: [Int ]) $ \ ix -> do
199- let slice = take ix txWithSizes
200-
201- totalRefScriptSizeInBlock protVer (SSeq. fromList (fst <$> slice))
202- <$> getUTxO
203- `shouldReturn` (if isPostV10 protVer then sum (snd <$> slice) else 0 )
204-
205- totalRefScriptSizeInBlock protVer (SSeq. fromList (fst <$> txWithSizes))
206- <$> getUTxO
207- `shouldReturn` (if isPostV10 protVer then expectedTotalSize else 0 )
179+ for_ (drop 1 $ inits txsWithSizes) $ \ prefix -> do
180+ let (txs, sizes) = unzip prefix
181+ expectedSize = if isPostV10 protVer then sum sizes else 0
182+ totalRefScriptSizeInBlock protVer (SSeq. fromList txs) <$> getUTxO `shouldReturn` expectedSize
208183
209184 -- disabled in conformance because submiting phase2-invalid transactions are not supported atm
210185 -- https://github.com/IntersectMBO/formal-ledger-specifications/issues/910
@@ -231,7 +206,7 @@ spec = do
231206 else freshKeyAddrNoPtr_
232207 pure $ mkBasicTxOut addr mempty & referenceScriptTxOutL .~ pure (fromNativeScript script)
233208
234- ( txs :: [ Tx TopTx era ]) <- simulateThenRestore $ do
209+ txs <- simulateThenRestore $ do
235210 -- submit an invalid transaction which attempts to consume the failing script
236211 -- and specifies as collateral return the txout with reference script
237212 createCollateralTx <-
0 commit comments