diff --git a/bench/cardano-profile/src/Cardano/Benchmarking/Profile/Builtin/Plutuscall.hs b/bench/cardano-profile/src/Cardano/Benchmarking/Profile/Builtin/Plutuscall.hs index ada6e81b6a1..8f6645b9d8c 100644 --- a/bench/cardano-profile/src/Cardano/Benchmarking/Profile/Builtin/Plutuscall.hs +++ b/bench/cardano-profile/src/Cardano/Benchmarking/Profile/Builtin/Plutuscall.hs @@ -44,13 +44,17 @@ profilesPlutuscall = . P.analysisStandard . P.desc "Small dataset, honest 15 epochs duration" - loop = plutusCall & V.plutusTypeLoop . V.plutusDoubleSaturation . P.analysisSizeModerate . P.analysisEpoch3Plus - ecdsa = plutusCall & V.plutusTypeECDSA . V.plutusDoubleSaturation . P.analysisSizeModerate . P.analysisEpoch3Plus - schnorr = plutusCall & V.plutusTypeSchnorr . V.plutusDoubleSaturation . P.analysisSizeModerate . P.analysisEpoch3Plus + loop = plutusCall & V.plutusTypeLoop . V.plutusDoubleSaturation . P.analysisSizeModerate . P.analysisEpoch3Plus + ecdsa = plutusCall & V.plutusTypeECDSA . V.plutusDoubleSaturation . P.analysisSizeModerate . P.analysisEpoch3Plus + schnorr = plutusCall & V.plutusTypeSchnorr . V.plutusDoubleSaturation . P.analysisSizeModerate . P.analysisEpoch3Plus + schnorrV3 = plutusCall & V.plutusTypeSchnorrV3 . V.plutusDoubleSaturation . P.analysisSizeSmall . P.analysisEpoch3Plus + mscalmul = plutusCall & V.plutusTypeMultScalarMultG1 . V.plutusDoubleSaturation . P.analysisSizeSmall . P.analysisEpoch3Plus + ripemdVolt4tx = plutusCall & V.plutusTypeRIPEMD_4tx . V.plutusDoubleSaturation . P.analysisSizeSmall . P.analysisEpoch3Plus + expmod = plutusCall & V.plutusTypeExpMod . V.plutusDoubleSaturation . P.analysisSizeSmall . P.analysisEpoch3Plus - loopVolt = plutusCall & V.plutusTypeLoop . V.plutusDoublePlusSaturation . P.analysisSizeSmall - blstVolt = plutusCall & V.plutusTypeBLST . V.plutusDoublePlusSaturation . P.analysisSizeModerate2 - ripemdVolt = plutusCall & V.plutusTypeRIPEMD . V.plutusDoublePlusSaturation . P.analysisSizeSmall + loopVolt = plutusCall & V.plutusTypeLoop . V.plutusDoublePlusSaturation . P.analysisSizeSmall + blstVolt = plutusCall & V.plutusTypeBLST . V.plutusDoublePlusSaturation . P.analysisSizeModerate2 + ripemdVolt = plutusCall & V.plutusTypeRIPEMD . V.plutusDoublePlusSaturation . P.analysisSizeSmall postPlomin = V.genesisVariantVoltaire in [ @@ -65,5 +69,9 @@ profilesPlutuscall = , blstVolt & P.name "plutuscall-volt-blst" . postPlomin , ripemdVolt & P.name "plutuscall-volt-ripemd" . postPlomin - , ripemdVolt & P.name "plutuscall-voltv11-ripemd" . postPlomin . P.v11Preview + -- PlutusV3 benchmarks, targeting PV11 + , ripemdVolt4tx & P.name "plutuscall-voltv11-ripemd" . postPlomin . P.v11Preview + , schnorrV3 & P.name "plutuscall-voltv11-schnorrv3" . postPlomin . P.v11Preview + , mscalmul & P.name "plutuscall-voltv11-mscalmul" . postPlomin . P.v11Preview + , expmod & P.name "plutuscall-voltv11-expmod" . postPlomin . P.v11Preview ] diff --git a/bench/cardano-profile/src/Cardano/Benchmarking/Profile/Primitives.hs b/bench/cardano-profile/src/Cardano/Benchmarking/Profile/Primitives.hs index c1bb327f986..1f9d9b901b0 100644 --- a/bench/cardano-profile/src/Cardano/Benchmarking/Profile/Primitives.hs +++ b/bench/cardano-profile/src/Cardano/Benchmarking/Profile/Primitives.hs @@ -894,15 +894,19 @@ analysisFiltersAppend str = analysis else a {Types.filters = Types.filters a ++ [str]} ) +-- for 88k blocks: from 2.6k to 8.8k analysisSizeSmall :: HasCallStack => Types.Profile -> Types.Profile analysisSizeSmall = analysisFiltersAppend "size-small" +-- for 88k blocks: from 7k to 9.8k analysisSizeModerate :: HasCallStack => Types.Profile -> Types.Profile analysisSizeModerate = analysisFiltersAppend "size-moderate" +-- for 88k blocks: from 6.7k to 9.2k analysisSizeModerate2 :: HasCallStack => Types.Profile -> Types.Profile analysisSizeModerate2 = analysisFiltersAppend "size-moderate-2" +-- for 88k blocks: larger than 79.2k analysisSizeFull :: HasCallStack => Types.Profile -> Types.Profile analysisSizeFull = analysisFiltersAppend "size-full" diff --git a/bench/cardano-profile/src/Cardano/Benchmarking/Profile/Vocabulary.hs b/bench/cardano-profile/src/Cardano/Benchmarking/Profile/Vocabulary.hs index b8f11c598fb..29efe971c79 100644 --- a/bench/cardano-profile/src/Cardano/Benchmarking/Profile/Vocabulary.hs +++ b/bench/cardano-profile/src/Cardano/Benchmarking/Profile/Vocabulary.hs @@ -20,7 +20,9 @@ module Cardano.Benchmarking.Profile.Vocabulary ( , plutusSaturation, plutusDoubleSaturation, plutusDoublePlusSaturation , plutusTypeLoop, plutusTypeLoopV3, plutusTypeLoop2024, plutusTypeECDSA, plutusTypeSchnorr -, plutusTypeBLST, plutusTypeRIPEMD +, plutusTypeBLST, plutusTypeRIPEMD, plutusTypeRIPEMD_4tx, plutusTypeMultScalarMultG1 +, plutusTypeSchnorrV3 +, plutusTypeExpMod ) where -------------------------------------------------------------------------------- @@ -250,3 +252,66 @@ plutusTypeRIPEMD = , KeyMap.fromList [("bytes", Aeson.String "5a56da88e6fd8419181dec4d3dd6997bab953d2f")] ] . P.txFee 940000 + + -- the bytes content is arbitrary, but should be of the same size as RIPEMD-160 output, i.e. 160 bits +plutusTypeRIPEMD_4tx :: Types.Profile -> Types.Profile +plutusTypeRIPEMD_4tx = + P.plutusType "LimitTxPerBlock_4" . P.plutusScript "Ripemd160" + . P.redeemerFields [ + KeyMap.fromList [("int", Aeson.Number 1000000.0)] + , KeyMap.fromList [("bytes", Aeson.String "5a56da88e6fd8419181dec4d3dd6997bab953d2f")] + ] + . P.txFee 915500 + +-- there must always be 1 scalar value less than there are points. +-- for the rationale about the redeemer structure, see note in +-- the script's source: bench/plutus-scripts-bench/src/Cardano/Benchmarking/PlutusScripts/MultiScalarMulG1.hs +plutusTypeMultScalarMultG1 :: Types.Profile -> Types.Profile +plutusTypeMultScalarMultG1 = + P.plutusType "LimitTxPerBlock_4" . P.plutusScript "MultiScalarMulG1" + . P.redeemerFields [ + KeyMap.fromList [("int", Aeson.Number 1000000.0)] + , KeyMap.fromList [("list", Aeson.Array $ Vector.fromList [ + Aeson.Object $ KeyMap.fromList [("int", Aeson.Number 871345174532.0)] + , Aeson.Object $ KeyMap.fromList [("int", Aeson.Number 987654321.0)] + ]) + ] + , KeyMap.fromList [("list", Aeson.Array $ Vector.fromList [ + Aeson.Object $ KeyMap.fromList [("bytes", Aeson.String "ab5d1d67b495361c3297c721cf3c9dc510fc5055bdf92fefc1e67d91a00a765520150428eb4c2fb01902d41d5ca62d85")] + , Aeson.Object $ KeyMap.fromList [("bytes", Aeson.String "88c7e388ee58f1db9a24d7098b01d13634298bebf2d159254975bd450cb0d287fcc622eb71edde8b469a8513551baf1f")] + , Aeson.Object $ KeyMap.fromList [("bytes", Aeson.String "95e4262f370607b2765312297461a04a3fb1fbb83e998a8e7d0f237017df86c5fb01f85101177c3dd41586df05b038cb")] + ]) + ] + ] + . P.txFee 572000 + +plutusTypeSchnorrV3 :: Types.Profile -> Types.Profile +plutusTypeSchnorrV3 = + P.plutusType "LimitTxPerBlock_4" . P.plutusScript "SchnorrSecp256k1LoopV3" + . P.redeemerFields [ + KeyMap.fromList [("int", Aeson.Number 1000000.0)] + , KeyMap.fromList [("bytes", Aeson.String "599de3e582e2a3779208a210dfeae8f330b9af00a47a7fb22e9bb8ef596f301b")] + , KeyMap.fromList [("bytes", Aeson.String "30303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030")] + , KeyMap.fromList [("bytes", Aeson.String "5a56da88e6fd8419181dec4d3dd6997bab953d2fc71ab65e23cfc9e7e3d1a310613454a60f6703819a39fdac2a410a094442afd1fc083354443e8d8bb4461a9b")] + ] + . P.txFee 586000 + +-- redeemer is a flat `(n, a, m)`: `n` (the loop counter) must stay the first +-- numeric value in the encoding, cf. bench/plutus-scripts-bench/src/Cardano/Benchmarking/PlutusScripts/ExpModInteger.hs +-- `n`'s placeholder here must NOT be 1000000: the mandatory `scriptDataModifyNumber +-- (const 1_000_000)` reset step (Cardano.TxGenerator.PlutusContext) detects "already +-- found a number to change" by comparing before/after values, so if this placeholder +-- already equals 1000000 the reset is a false-negative no-op and falls through to +-- corrupt `a` instead. Keep it at 0. +-- txFee is rounded up from the unscaled "txperblock_4" baseline fee (1262499) +-- reported by `calibrate-script run ExpModInteger txperblock_4`, +-- cf. bench/tx-generator/summaries_ExpModInteger.json +plutusTypeExpMod :: Types.Profile -> Types.Profile +plutusTypeExpMod = + P.plutusType "LimitTxPerBlock_4" . P.plutusScript "ExpModInteger" + . P.redeemerFields [ + KeyMap.fromList [("int", Aeson.Number 0.0)] + , KeyMap.fromList [("int", Aeson.Number 3.0)] + , KeyMap.fromList [("int", Aeson.Number 2305843009213693951.0)] + ] + . P.txFee 1275000 \ No newline at end of file diff --git a/bench/plutus-scripts-bench/plutus-scripts-bench.cabal b/bench/plutus-scripts-bench/plutus-scripts-bench.cabal index 410aab20bcd..99dc309ad3b 100644 --- a/bench/plutus-scripts-bench/plutus-scripts-bench.cabal +++ b/bench/plutus-scripts-bench/plutus-scripts-bench.cabal @@ -1,6 +1,6 @@ cabal-version: 3.0 name: plutus-scripts-bench -version: 1.0.4.3 +version: 1.0.5.0 synopsis: Plutus scripts used for benchmarking description: Plutus scripts used for benchmarking. category: Cardano, @@ -72,9 +72,11 @@ library Cardano.Benchmarking.PlutusScripts.CustomCallV3 Cardano.Benchmarking.PlutusScripts.EcdsaSecp256k1Loop Cardano.Benchmarking.PlutusScripts.EcdsaSecp256k1LoopV3 + Cardano.Benchmarking.PlutusScripts.ExpModInteger Cardano.Benchmarking.PlutusScripts.HashOntoG2AndAdd Cardano.Benchmarking.PlutusScripts.Loop2024 Cardano.Benchmarking.PlutusScripts.LoopV3 + Cardano.Benchmarking.PlutusScripts.MultiScalarMulG1 Cardano.Benchmarking.PlutusScripts.Ripemd160 Cardano.Benchmarking.PlutusScripts.SchnorrSecp256k1Loop Cardano.Benchmarking.PlutusScripts.SchnorrSecp256k1LoopV3 diff --git a/bench/plutus-scripts-bench/src/Cardano/Benchmarking/PlutusScripts.hs b/bench/plutus-scripts-bench/src/Cardano/Benchmarking/PlutusScripts.hs index 4a47da843fa..5f6c3b40f8e 100644 --- a/bench/plutus-scripts-bench/src/Cardano/Benchmarking/PlutusScripts.hs +++ b/bench/plutus-scripts-bench/src/Cardano/Benchmarking/PlutusScripts.hs @@ -26,9 +26,11 @@ import qualified Cardano.Benchmarking.PlutusScripts.CustomCall as CustomCall import qualified Cardano.Benchmarking.PlutusScripts.CustomCallV3 as CustomCallV3 import qualified Cardano.Benchmarking.PlutusScripts.EcdsaSecp256k1Loop as ECDSA import qualified Cardano.Benchmarking.PlutusScripts.EcdsaSecp256k1LoopV3 as ECDSAV3 +import qualified Cardano.Benchmarking.PlutusScripts.ExpModInteger as ExpModInteger import qualified Cardano.Benchmarking.PlutusScripts.HashOntoG2AndAdd as HashG2Add import qualified Cardano.Benchmarking.PlutusScripts.Loop2024 as Loop2024 import qualified Cardano.Benchmarking.PlutusScripts.LoopV3 as LoopV3 +import qualified Cardano.Benchmarking.PlutusScripts.MultiScalarMulG1 as MultiScalarMulG1 import qualified Cardano.Benchmarking.PlutusScripts.Ripemd160 as Ripemd160 import qualified Cardano.Benchmarking.PlutusScripts.SchnorrSecp256k1Loop as Schnorr import qualified Cardano.Benchmarking.PlutusScripts.SchnorrSecp256k1LoopV3 as SchnorrV3 @@ -42,9 +44,11 @@ getAllScripts = , CustomCallV3.script , ECDSA.script , ECDSAV3.script + , ExpModInteger.script , HashG2Add.script , Loop2024.script , LoopV3.script + , MultiScalarMulG1.script , Ripemd160.script , Schnorr.script , SchnorrV3.script diff --git a/bench/plutus-scripts-bench/src/Cardano/Benchmarking/PlutusScripts/ExpModInteger.hs b/bench/plutus-scripts-bench/src/Cardano/Benchmarking/PlutusScripts/ExpModInteger.hs new file mode 100644 index 00000000000..979420d3901 --- /dev/null +++ b/bench/plutus-scripts-bench/src/Cardano/Benchmarking/PlutusScripts/ExpModInteger.hs @@ -0,0 +1,76 @@ +{-# LANGUAGE BangPatterns #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE TemplateHaskell #-} + +-- | Fixed-iteration benchmark loop exercising the 'expModInteger' builtin, +-- ported from plutus-scripts-e2e's PlutusScripts.Batch6.ExpModInteger.Common. +module Cardano.Benchmarking.PlutusScripts.ExpModInteger + ( script + ) where + +import Cardano.Api (PlutusScriptVersion (PlutusScriptV3)) +import Cardano.Benchmarking.ScriptAPI (PlutusBenchScript, mkPlutusBenchScript) +import Language.Haskell.TH.Syntax (Exp (LitE), Lit (StringL), Loc (loc_module), qLocation) +import PlutusLedgerApi.Common (serialiseCompiledCode) +import qualified PlutusLedgerApi.V3 as PlutusV3 +import qualified PlutusTx +import qualified PlutusTx.Builtins as BI (expModInteger) +import qualified PlutusTx.Builtins.Internal as BI (BuiltinList, head, snd, tail, + unitval, unsafeDataAsConstr) +import PlutusTx.Prelude as P hiding (Semigroup (..), (.), (<$>)) +import Prelude as Haskell ((.), (<$>)) + + +-- while n > 1000000, force-evaluate expModInteger a e m (discarding the +-- result) and loop with n := n - 1, e := e + 1 +{-# INLINEABLE mkSimpleExpModIntegerPolicyBench #-} +mkSimpleExpModIntegerPolicyBench :: P.BuiltinData -> P.BuiltinUnit +mkSimpleExpModIntegerPolicyBench ctx = + if red_n P.< 1000000 -- large number ensures same bitsize for all counter values + then P.traceError "redeemer is < 1000000" + else go e0 red_n + where + -- lazily decode script context up to redeemer, which is less expensive and results in much smaller tx size + constrArgs :: P.BuiltinData -> BI.BuiltinList P.BuiltinData + constrArgs = BI.snd . BI.unsafeDataAsConstr + + redeemerFollowedByScriptInfo :: BI.BuiltinList P.BuiltinData + redeemerFollowedByScriptInfo = BI.tail (constrArgs ctx) + + redeemer :: P.BuiltinData + redeemer = BI.head redeemerFollowedByScriptInfo + + -- `n` must come first in the redeemer's (flat) Data encoding: tx-generator's + -- auto-budget calibration (Cardano.TxGenerator.PlutusContext.scriptDataModifyNumber) + -- bumps whichever ScriptDataNumber it encounters first in a depth-first walk. + red_n :: Integer + red_a :: Integer + red_m :: Integer + (red_n, red_a, red_m) = PlutusV3.unsafeFromBuiltinData redeemer + + -- e₀ = m - 2: a realistic, non-arbitrary exponent size, tracking `m`'s + -- own bit-length (not tied to `m` being prime -- there's no correctness + -- check against an expected result here, just a representative-sized + -- exponent to feed `expModInteger`). + -- + -- `e` only ever increments by 1 per iteration (never doubles), so its + -- bit-length -- and thus `expModInteger`'s per-call cost -- stays essentially + -- constant across the whole benchmark run, however many iterations it runs for. + -- This also keeps every iteration's arguments genuinely distinct (dependent on + -- the loop counter), so no compiler optimisation (e.g. full laziness) can + -- legally hoist/common up the `expModInteger` call across iterations. + e0 :: Integer + e0 = red_m - 2 + + go :: Integer -> Integer -> P.BuiltinUnit + go e n = + if n P.== 1000000 + then BI.unitval + else let !_ = BI.expModInteger red_a e red_m in go (e P.+ 1) (P.pred n) + +script :: PlutusBenchScript +script = mkPlutusBenchScript + $(LitE . StringL . loc_module <$> qLocation) + PlutusScriptV3 + (serialiseCompiledCode $$(PlutusTx.compile [|| mkSimpleExpModIntegerPolicyBench ||])) diff --git a/bench/plutus-scripts-bench/src/Cardano/Benchmarking/PlutusScripts/MultiScalarMulG1.hs b/bench/plutus-scripts-bench/src/Cardano/Benchmarking/PlutusScripts/MultiScalarMulG1.hs new file mode 100644 index 00000000000..27f3d2d8c20 --- /dev/null +++ b/bench/plutus-scripts-bench/src/Cardano/Benchmarking/PlutusScripts/MultiScalarMulG1.hs @@ -0,0 +1,69 @@ +{-# LANGUAGE BangPatterns #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE TemplateHaskell #-} + +module Cardano.Benchmarking.PlutusScripts.MultiScalarMulG1 (script) where + +import Cardano.Api (PlutusScriptVersion (PlutusScriptV3)) +import Cardano.Benchmarking.ScriptAPI (PlutusBenchScript, mkPlutusBenchScript) +import Language.Haskell.TH.Syntax (Exp (LitE), Lit (StringL), Loc (loc_module), qLocation) +import PlutusLedgerApi.Common (serialiseCompiledCode) +import qualified PlutusLedgerApi.V3 as PlutusV3 +import qualified PlutusTx (compile) +import qualified PlutusTx.Builtins.Internal as BI (BuiltinList, head, snd, tail, unitval, + unsafeDataAsConstr) +import PlutusTx.Builtins as BI (bls12_381_G1_multiScalarMul) +import PlutusTx.Prelude as Tx hiding (Semigroup (..), (.), (<$>)) +import Prelude as Haskell ((.), (<$>)) + + +script :: PlutusBenchScript +script = mkPlutusBenchScript + $(LitE . StringL . loc_module <$> qLocation) + PlutusScriptV3 + (serialiseCompiledCode $$(PlutusTx.compile [|| mkValidator ||])) + +{-# INLINABLE mkValidator #-} +mkValidator :: BuiltinData -> BuiltinUnit +mkValidator arg = + if red_n < 1000000 -- large number ensures same bitsize for all counter values + then traceError "redeemer is < 1000000" + else loop (fmap Tx.bls12_381_G1_uncompress red_bss) red_is red_n + where + -- lazily decode script context up to redeemer, which is less expensive and results in much smaller tx size + constrArgs :: BuiltinData -> BI.BuiltinList BuiltinData + constrArgs = BI.snd . BI.unsafeDataAsConstr + + redeemerFollowedByScriptInfo :: BI.BuiltinList BuiltinData + redeemerFollowedByScriptInfo = BI.tail (constrArgs arg) + + redeemer :: BuiltinData + redeemer = BI.head redeemerFollowedByScriptInfo + + red_n :: Integer + red_is :: [Integer] + red_bss :: [BuiltinByteString] + (red_n, red_is, red_bss) = PlutusV3.unsafeFromBuiltinData redeemer + + -- see Note[1] + loop points scalars n + | n == 1000000 = BI.unitval + | otherwise = let !_ = BI.bls12_381_G1_multiScalarMul (n : scalars) points in loop points scalars (pred n) + +{- +Note[1]: + + The benchmarking loop's counter will always be used as a nonce, prepended to the list of scalars. + Hence, make sure that in the redeemer args, + >> THE LIST OF SCALARS IS ALWAYS 1 ELEMENT SHORTER THAN THE LIST OF POINTS << + + == Reason for Nonce-as-Head ('n : scalars'): + 1. Defeats Pippenger Bucket-Caching: Mutating a single scalar + head element breaks the windowed bit-partitioning configuration. This forces + the 'blst' library to perform full, un-cached linear combination logic from + scratch rather than reusing pre-computed bucket structures. + 2. Minmize execution units to achieve 1.: Prepending a head nonce element + guarantees a predictable O(1) overhead, focusing execution cost purely on the underlying + curve arithmetic. Also, this guarantees a stable memory footprint. +-} diff --git a/bench/tx-generator/app/calibrate-script.hs b/bench/tx-generator/app/calibrate-script.hs index 2ba9f26af07..d41799eeea7 100644 --- a/bench/tx-generator/app/calibrate-script.hs +++ b/bench/tx-generator/app/calibrate-script.hs @@ -206,10 +206,10 @@ runScaling :: -> IO [(PlutusBudgetSummary, ScriptRedeemer)] runScaling script budgetType basePParams baseline baseBudget (scaleSanitize -> scalesArg) | null scalesArg = go1 scaleBaseLine scaleAutoFactors - | otherwise = mapM go0 scalesArg + | otherwise = catMaybes <$> mapM go0 scalesArg where -- specific scaling requested - go0 :: Scale -> IO (PlutusBudgetSummary, ScriptRedeemer) + go0 :: Scale -> IO (Maybe (PlutusBudgetSummary, ScriptRedeemer)) go0 scale = let fields@[txm, txs, bm, bs] = scaleFields scale @@ -218,9 +218,8 @@ runScaling script budgetType basePParams baseline baseBudget (scaleSanitize -> s budget = withHint (maximum fields) baseBudget in do putStrLn $ "--> run: " ++ show scope - evaluate $ - summaryAndRedeermerOrDie scope $ - plutusAutoScaleBlockfit pparams (scriptNameExt, scope) script budget strategy 1 + summaryAndRedeermerSafe scope $ + plutusAutoScaleBlockfit pparams (scriptNameExt, scope) script budget strategy 1 -- auto-scale until conditions are met (last list entry), but include intermediate results go1 :: Scale -> [Double] -> IO [(PlutusBudgetSummary, ScriptRedeemer)] @@ -228,12 +227,13 @@ runScaling script budgetType basePParams baseline baseBudget (scaleSanitize -> s go1 scale_ factors@(factor:fs) = case bumpLimit strategy budgetType factor scale_ of Nothing -> go1 scaleBaseLine fs -- no further bump possible: give up and auto-scale for next factor - Just scale -> do - run@(summary, _) <- go0 scale - (run :) <$> - if all (\cond -> cond summary baseline) happilyCalibrated - then go1 scaleBaseLine fs -- auto-scale next factor - else go1 scale factors -- apply next bump to current scaling, re-run + Just scale -> go0 scale >>= \case + Nothing -> pure [] -- if there was an error, skip all remaining scaling runs + Just run@(summary, _) -> + (run :) <$> + if all (\cond -> cond summary baseline) happilyCalibrated + then go1 scaleBaseLine fs -- auto-scale next factor + else go1 scale factors -- apply next bump to current scaling, re-run -- conditions for a succesful calibration: same limiting factors, same txn count per block -- NEXT RELEASE: does that need to be strategy dependent with TargetBlockExpenditure? diff --git a/bench/tx-generator/data/ExpModInteger.redeemer.json b/bench/tx-generator/data/ExpModInteger.redeemer.json new file mode 100644 index 00000000000..300847f4b37 --- /dev/null +++ b/bench/tx-generator/data/ExpModInteger.redeemer.json @@ -0,0 +1,14 @@ +{ + "constructor": 0, + "fields": [ + { + "int": 0 + }, + { + "int": 3 + }, + { + "int": 2305843009213693951 + } + ] +} diff --git a/bench/tx-generator/data/MultiScalarMulG1.redeemer.json b/bench/tx-generator/data/MultiScalarMulG1.redeemer.json new file mode 100644 index 00000000000..185873e0501 --- /dev/null +++ b/bench/tx-generator/data/MultiScalarMulG1.redeemer.json @@ -0,0 +1,31 @@ +{ + "constructor": 0, + "fields": [ + { + "int": 1000000 + }, + { + "list": [ + { + "int": 871345174532 + }, + { + "int": 987654321 + } + ] + }, + { + "list": [ + { + "bytes": "ab5d1d67b495361c3297c721cf3c9dc510fc5055bdf92fefc1e67d91a00a765520150428eb4c2fb01902d41d5ca62d85" + }, + { + "bytes": "88c7e388ee58f1db9a24d7098b01d13634298bebf2d159254975bd450cb0d287fcc622eb71edde8b469a8513551baf1f" + }, + { + "bytes": "95e4262f370607b2765312297461a04a3fb1fbb83e998a8e7d0f237017df86c5fb01f85101177c3dd41586df05b038cb" + } + ] + } + ] +} \ No newline at end of file diff --git a/bench/tx-generator/scripts-fallback/ExpModInteger.plutus b/bench/tx-generator/scripts-fallback/ExpModInteger.plutus new file mode 100644 index 00000000000..6e4a89ac61b --- /dev/null +++ b/bench/tx-generator/scripts-fallback/ExpModInteger.plutus @@ -0,0 +1,5 @@ +{ + "type": "PlutusScriptV3", + "description": "", + "cborHex": "58d10101009800aab9daba2ab9aaab9eaba1ab9c48888888c8c8c8c96600266e200052080897a89931980324811572656465656d6572206973203c20313030303030300080044cc008cdc0a801a4008002804a400e4440063230010012225980099b874820225e800629344c8ca600200b00199b810034800900519b804800800e6003200b222002400aa008bd72014190019110008c8c8c8d6600266e1d200000289194004dd698040014dd69804000cdd6980418058008c0280062c8040004c018008c020004dd51801980318021baa00101" +} diff --git a/bench/tx-generator/scripts-fallback/MultiScalarMulG1.plutus b/bench/tx-generator/scripts-fallback/MultiScalarMulG1.plutus new file mode 100644 index 00000000000..d1f4d1abcda --- /dev/null +++ b/bench/tx-generator/scripts-fallback/MultiScalarMulG1.plutus @@ -0,0 +1,5 @@ +{ + "type": "PlutusScriptV3", + "description": "", + "cborHex": "59015e0101009800aab9daba0aba2ab9aaab9eaba1ab9caab9f488888888c8c8c8c88c8c96600266e200052080897a899319804a491572656465656d6572206973203c203130303030303000800466002600f20052220016400a444004800a008403120032220031919191acc004cdc3a400000512328009bad300d0029919198008009bac0022259800800c6001132328019bad002998020020008c050008c04000500e1806800cc8c8cc004004dd6001112cc004006300089919400cdd70014cc010010004602800460200028070c034c040004601e0031640340026016004601c0026ea8c020c02cc024dd500099180080091112cc004cdc3a410112f4003149a2653001005802400e66e040092002401466f70c0160060030021803001a018323001001229001a5eb02446601a00466008008002323001001229001a5eb92446601800466008008002323001001229001c0024500337760053300400400101" +} diff --git a/bench/tx-generator/src-calibrate/Cardano/TxGenerator/Calibrate/Utils.hs b/bench/tx-generator/src-calibrate/Cardano/TxGenerator/Calibrate/Utils.hs index 1a438ee17ba..f3f808dfc90 100644 --- a/bench/tx-generator/src-calibrate/Cardano/TxGenerator/Calibrate/Utils.hs +++ b/bench/tx-generator/src-calibrate/Cardano/TxGenerator/Calibrate/Utils.hs @@ -41,6 +41,13 @@ summaryAndRedeermerOrDie scope = (\(summary, budget, _) -> (summary, autoBudgetRedeemer budget)) where withScope s = concat [scope, ": ", s] +summaryAndRedeermerSafe :: String -> Either TxGenError (PlutusBudgetSummary, PlutusAutoBudget, b) -> IO (Maybe (PlutusBudgetSummary, ScriptRedeemer)) +summaryAndRedeermerSafe scope = + either + (\err -> putStrLn (withScope $ show err) >> pure Nothing) + (\(summary, budget, _) -> pure (Just (summary, autoBudgetRedeemer budget))) + where withScope s = concat [scope, ": ", s] + resolveRedeemer :: Either ScriptData TxGenPlutusParams -> IO (Either TxGenError HashableScriptData) resolveRedeemer = resolveRedeemerQuiet False diff --git a/bench/tx-generator/tx-generator.cabal b/bench/tx-generator/tx-generator.cabal index 5ebadb43f08..d7e604674c1 100644 --- a/bench/tx-generator/tx-generator.cabal +++ b/bench/tx-generator/tx-generator.cabal @@ -30,7 +30,7 @@ common with-library -- It makes sure, we only depend on that package if it is buildable. -- The tx-generator will fall back to pre-serialized Plutus scripts if this package is not present. if flag(withplutuslib) && !(impl(ghc <9.6) || impl(ghc >=9.7)) - build-depends: plutus-scripts-bench ^>= 1.0.4 + build-depends: plutus-scripts-bench ^>= 1.0.5 cpp-options: -DWITH_LIBRARY common maybe-unix diff --git a/wb_profiles.mk b/wb_profiles.mk index 20c9daba78b..b425dba9f8f 100644 --- a/wb_profiles.mk +++ b/wb_profiles.mk @@ -1,7 +1,7 @@ PROFILES_EMPTY := fast-solo fast fast-notracer fast-plutus ci-test ci-test-notracer ci-test-plutus ci-test-hydra trace-bench trace-bench-notracer trace-full default plutus plutus-secp-ecdsa plutus-secp-schnorr epoch-transition PROFILES_MINIATURE := ci-bench ci-bench-lmdb ci-bench-lsmt ci-bench-notracer ci-bench-drep ci-bench-plutus ci-bench-v11-plutus ci-bench-v11-plutusv3 ci-bench-plutus24 ci-bench-plutus-secp-ecdsa ci-bench-plutus-secp-schnorr ci-bench-plutusv3-blst ci-bench-plutusv3-ripemd ci-bench-plutusv3-ripemd-step2x 10 10-notracer 10-plutus 6-dense 6-dense-rtsprof 6-dense-1h 6-dense-1h-rtsprof 6-dense-1h-timeseries 6-dense-4h 6-dense-4h-rtsprof PROFILES_FORGE_STRESS := forge-stress-solo-xs forge-stress-solo forge-stress-plutus-solo forge-stress-pre-solo-xs forge-stress-pre-solo forge-stress-pre-solo-xl forge-stress forge-stress-notracer forge-stress-plutus forge-stress-large forge-stress-pre forge-stress-pre-rtsA4m forge-stress-pre-rtsA64m forge-stress-pre-rtsN3 forge-stress-pre-rtsA4mN3 forge-stress-pre-rtsA64mN3 forge-stress-pre-rtsxn forge-stress-pre-notracer forge-stress-pre-plutus forge-stress-pre-large forge-stress-pre-large-rtsqg1 forge-stress-pre-large-rtsN3 forge-stress-pre-large-rtsN4 forge-stress-pre-large-rtsqg1N4 -PROFILES_PLUTUSCALL := plutuscall-loop plutuscall-loop-memx2 plutuscall-secp-ecdsa plutuscall-secp-ecdsa-stepx2 plutuscall-secp-schnorr plutuscall-secp-schnorr-stepx2 plutuscall-volt-loop plutuscall-volt-blst plutuscall-volt-ripemd plutuscall-voltv11-ripemd +PROFILES_PLUTUSCALL := plutuscall-loop plutuscall-loop-memx2 plutuscall-secp-ecdsa plutuscall-secp-ecdsa-stepx2 plutuscall-secp-schnorr plutuscall-secp-schnorr-stepx2 plutuscall-volt-loop plutuscall-volt-blst plutuscall-volt-ripemd plutuscall-voltv11-ripemd plutuscall-voltv11-schnorrv3 plutuscall-voltv11-mscalmul plutuscall-voltv11-expmod PROFILES_MODEL := model-secp-ecdsa-stepx2 model-secp-ecdsa model-value model-value-test PROFILES_K3 := k3-3ep-5kTx-10000kU-1300kD-64kbs-fixed-loaded k3-3ep-9kTx-10000kU-1300kD-64kbs-5tps-fixed-loaded k3-3ep-18kTx-10000kU-1300kD-64kbs-10tps-fixed-loaded PROFILES_SCENARIOS := chainsync-early-byron chainsync-early-byron-notracer chainsync-early-alonzo chainsync-early-alonzo-notracer devops idle tracer-only