Skip to content

Conversation

@kwxm
Copy link
Contributor

@kwxm kwxm commented Jul 18, 2025

This fixes https://github.com/IntersectMBO/plutus-private/issues/1655 and https://github.com/IntersectMBO/plutus-private/issues/1656.

This will enable all builtins in PlutusV1 and PlutusV2 at PV11, and also sums of products. A protocol parameter update will also be required to update the cost model parameters before the new features become usable on the chain: the required parameters can be obtained using dump-cost-model-parameters (see PR #7171).

@kwxm kwxm requested review from effectfully and zliu41 July 18, 2025 06:30
@kwxm kwxm added Plutus Core Builtins Costing Anything relating to costs, fees, gas, etc. Plutus Ledger API labels Jul 18, 2025
@kwxm kwxm temporarily deployed to github-pages July 18, 2025 06:31 — with GitHub Actions Inactive
@github-actions
Copy link
Contributor

github-actions bot commented Jul 18, 2025

PR Preview Action v1.6.2

🚀 View preview at
https://IntersectMBO.github.io/plutus/pr-preview/pr-7223/

Built to branch gh-pages at 2025-07-23 21:19 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

where no new builtins are added. See Note [New builtins/language versions and
protocol versions]
-}
builtinsIntroducedIn :: PlutusLedgerLanguage -> Map.Map MajorProtocolVersion (Set.Set DefaultFun)
Copy link
Contributor Author

@kwxm kwxm Jul 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This (and other functions in this module) are used to perform validity checks during on-chain deserialisation, so it's important that they're efficient. I think that things like batch2 ++ batch3 ++ batch4 ++ batch5 ++ batch6 will be computed at compile time, but Set.fromList and Map.fromList won't, so this isn't as efficient as it could be. It seems that this problem can be solved using Template Haskell, and I plan to look into this in a later PR: see this issue.

Another possibility would be to cache the results: see this comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to rework these functions because the previous versions relied on assumptions that are no longer valid (specifically, the predicate in takeWhileAntitone must satisfy a certain property, and enabling new builtins in PlutusV1/V2 meant that this no longer held in the previous version of the function.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this cause any performance regression? Previously builtinsIntroducedIn was a top-level Map that can be cached, but it is now a function.

Copy link
Contributor Author

@kwxm kwxm Jul 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran the validation-decode benchmarks a few times and the results suggest that there's a slowdown of about 1.5-3% in deserialisation times. An earlier comment mentions this and some ways to deal with (like evaluate as much as possible at compile time) it and I plan to come back and look at it again in the near future.

Superficially this looks as if it could be more efficient than the previous version because that had to look at all (LL,PV) combinations and the new version only has to look at the PV values once we've callled the function to get everything for the relevant LL version. It does appear that it's not more efficient and I want to fix that. Also, the previous version no longer works because it assumes that if something's available in a praticular LL and PV then it's avaliable for all earlier LLs and PVs, and that no longer holds (we're enabling things in PV11 that aren't available in PV10, for example).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like you mentioned on Slack, this check can be significantly simplified from PV11. So perhaps you'd want to implement a separate check just for PV11?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that things like batch2 ++ batch3 ++ batch4 ++ batch5 ++ batch6 will be computed at compile time

You don't know that, unless you've checked it. These are not small definitions and they're not marked as INLINE, GHC can easily avoid inlining them, in which case fusion doesn't kick in, in which case they don't get computed statically.

Previously builtinsIntroducedIn was a top-level Map that can be cached, but it is now a function.

All we need to make it efficient again is just to put

      Map.fromList
      [ (alonzoPV, Set.fromList batch1)
      , (pv11PV,   Set.fromList (batch2 ++ batch3 ++ batch4 ++ batch5 ++ batch6))
      ]

etc into their own top-level definitions marked as OPAQUE.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests here are still not ideal (see this issue), so we should come back and take another look at them.

Copy link
Contributor Author

@kwxm kwxm Jul 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests needed substantial reworking because the previous versions relied on assumptions that are no longer true. What's really being tested in many tests is that functions like builtinsAvailableIn behave properly. These functions are used on the chain and it's important that they do what they're supposed to do, so I've tried to make the tests as comprehensive as possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes to builtinsAvailableIn and related functions will make the builtins pass the deserialisation checks, making the builtins usable in principle on the chain at PV11, except that the cost model parameters also need to be updated in order to make the builtins (and SoPs) affordable . The changes to these files enable the update to work properly.

@kwxm
Copy link
Contributor Author

kwxm commented Jul 18, 2025

/benchmark validation-full

@github-actions
Copy link
Contributor

Click here to check the status of your benchmark.

@github-actions
Copy link
Contributor

Comparing benchmark results of 'validation-full' on 'aeaafb922d' (base) and '3893622224' (PR)

Results table
Script aeaafb9 3893622 Change
auction_1-1 427.4 μs 430.9 μs +0.8%
auction_1-2 1.400 ms 1.406 ms +0.4%
auction_1-3 1.395 ms 1.410 ms +1.1%
auction_1-4 483.3 μs 480.0 μs -0.7%
auction_2-1 426.7 μs 429.8 μs +0.7%
auction_2-2 1.398 ms 1.414 ms +1.1%
auction_2-3 1.613 ms 1.610 ms -0.2%
auction_2-4 1.393 ms 1.393 ms 0.0%
auction_2-5 482.8 μs 479.0 μs -0.8%
crowdfunding-success-1 518.9 μs 519.3 μs +0.1%
crowdfunding-success-2 520.1 μs 520.1 μs 0.0%
crowdfunding-success-3 520.2 μs 518.9 μs -0.2%
currency-1 549.7 μs 552.0 μs +0.4%
escrow-redeem_1-1 767.6 μs 766.1 μs -0.2%
escrow-redeem_1-2 768.2 μs 765.2 μs -0.4%
escrow-redeem_2-1 826.5 μs 824.2 μs -0.3%
escrow-redeem_2-2 825.2 μs 823.5 μs -0.2%
escrow-redeem_2-3 825.8 μs 824.0 μs -0.2%
escrow-refund-1 567.7 μs 566.1 μs -0.3%
future-increase-margin-1 548.8 μs 552.3 μs +0.6%
future-increase-margin-2 960.0 μs 959.7 μs -0.0%
future-increase-margin-3 960.0 μs 959.8 μs -0.0%
future-increase-margin-4 1.430 ms 1.431 ms +0.1%
future-increase-margin-5 1.799 ms 1.803 ms +0.2%
future-pay-out-1 551.5 μs 546.0 μs -1.0%
future-pay-out-2 958.8 μs 960.9 μs +0.2%
future-pay-out-3 957.8 μs 960.6 μs +0.3%
future-pay-out-4 1.806 ms 1.800 ms -0.3%
future-settle-early-1 547.3 μs 553.2 μs +1.1%
future-settle-early-2 957.8 μs 961.2 μs +0.4%
future-settle-early-3 957.9 μs 960.7 μs +0.3%
future-settle-early-4 1.568 ms 1.565 ms -0.2%
game-sm-success_1-1 1.099 ms 1.099 ms 0.0%
game-sm-success_1-2 408.7 μs 406.9 μs -0.4%
game-sm-success_1-3 1.374 ms 1.374 ms 0.0%
game-sm-success_1-4 443.0 μs 443.2 μs +0.0%
game-sm-success_2-1 1.100 ms 1.114 ms +1.3%
game-sm-success_2-2 409.9 μs 407.8 μs -0.5%
game-sm-success_2-3 1.375 ms 1.377 ms +0.1%
game-sm-success_2-4 442.9 μs 443.6 μs +0.2%
game-sm-success_2-5 1.376 ms 1.375 ms -0.1%
game-sm-success_2-6 442.5 μs 443.6 μs +0.2%
multisig-sm-1 1.183 ms 1.187 ms +0.3%
multisig-sm-2 1.182 ms 1.192 ms +0.8%
multisig-sm-3 1.182 ms 1.184 ms +0.2%
multisig-sm-4 1.190 ms 1.203 ms +1.1%
multisig-sm-5 1.371 ms 1.367 ms -0.3%
multisig-sm-6 1.186 ms 1.190 ms +0.3%
multisig-sm-7 1.180 ms 1.179 ms -0.1%
multisig-sm-8 1.184 ms 1.199 ms +1.3%
multisig-sm-9 1.189 ms 1.202 ms +1.1%
multisig-sm-10 1.372 ms 1.370 ms -0.1%
ping-pong-1 982.7 μs 978.1 μs -0.5%
ping-pong-2 980.9 μs 978.0 μs -0.3%
ping-pong_2-1 846.8 μs 859.0 μs +1.4%
prism-1 374.0 μs 374.3 μs +0.1%
prism-2 1.117 ms 1.125 ms +0.7%
prism-3 676.1 μs 679.5 μs +0.5%
pubkey-1 353.6 μs 350.4 μs -0.9%
stablecoin_1-1 2.271 ms 2.269 ms -0.1%
stablecoin_1-2 406.5 μs 403.6 μs -0.7%
stablecoin_1-3 2.410 ms 2.408 ms -0.1%
stablecoin_1-4 419.7 μs 414.4 μs -1.3%
stablecoin_1-5 2.774 ms 2.782 ms +0.3%
stablecoin_1-6 468.9 μs 463.4 μs -1.2%
stablecoin_2-1 2.270 ms 2.265 ms -0.2%
stablecoin_2-2 406.5 μs 402.9 μs -0.9%
stablecoin_2-3 2.411 ms 2.408 ms -0.1%
stablecoin_2-4 419.9 μs 414.8 μs -1.2%
token-account-1 488.5 μs 488.9 μs +0.1%
token-account-2 609.9 μs 606.1 μs -0.6%
uniswap-1 702.8 μs 699.0 μs -0.5%
uniswap-2 524.0 μs 524.0 μs 0.0%
uniswap-3 2.898 ms 2.901 ms +0.1%
uniswap-4 565.5 μs 563.9 μs -0.3%
uniswap-5 2.203 ms 2.215 ms +0.5%
uniswap-6 551.1 μs 550.8 μs -0.1%
vesting-1 774.6 μs 776.7 μs +0.3%
aeaafb9 3893622 Change
TOTAL 79.31 ms 79.40 ms +0.1%

parameters and enable them all at PV11 and with a suitable parameter update.
However, if we do do this there's a theoretical risk of turning a phase 2
failure into a phase 1 failure: would that be problematic?
-}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way the three sets of cost model parameters are set up now means that the PlutusV1 parameters are a permutation of the PlutusV2 parameters (but the cost models they represent wll be exactly the same). This is unavoidable because the parameters for serialiseData were already present in the middle of the V2 parameters but had to be added to the end of the previous version of the V1 parameters (where serialiseData didn't exist). The parameters for the two integer/bytestring conversion functions are also in different places, but the V2 ones are in the correct place for the as-yet-unenacted parameter update that will enable them. It may just be easier to leave things as they are and not try to match the parameters up. See the discussion here.

@kwxm
Copy link
Contributor Author

kwxm commented Jul 18, 2025

/benchmark validation-decode

@github-actions
Copy link
Contributor

Click here to check the status of your benchmark.

@kwxm
Copy link
Contributor Author

kwxm commented Jul 18, 2025

^ Not sure if that's benchmarking what I want; I'll check later.

@github-actions
Copy link
Contributor

Comparing benchmark results of 'validation-decode' on 'aeaafb922d' (base) and '3893622224' (PR)

Results table
Script aeaafb9 3893622 Change
auction_1-1 190.3 μs 195.5 μs +2.7%
auction_1-2 526.7 μs 534.2 μs +1.4%
auction_1-3 530.7 μs 535.2 μs +0.8%
auction_1-4 192.3 μs 194.7 μs +1.2%
auction_2-1 192.7 μs 195.4 μs +1.4%
auction_2-2 529.1 μs 535.2 μs +1.2%
auction_2-3 527.1 μs 533.5 μs +1.2%
auction_2-4 530.3 μs 535.1 μs +0.9%
auction_2-5 190.8 μs 194.2 μs +1.8%
crowdfunding-success-1 233.1 μs 236.1 μs +1.3%
crowdfunding-success-2 231.4 μs 236.6 μs +2.2%
crowdfunding-success-3 233.7 μs 236.8 μs +1.3%
currency-1 230.5 μs 233.4 μs +1.3%
escrow-redeem_1-1 309.0 μs 311.6 μs +0.8%
escrow-redeem_1-2 307.7 μs 311.6 μs +1.3%
escrow-redeem_2-1 310.0 μs 312.0 μs +0.6%
escrow-redeem_2-2 310.6 μs 312.2 μs +0.5%
escrow-redeem_2-3 310.3 μs 312.2 μs +0.6%
escrow-refund-1 311.0 μs 312.1 μs +0.4%
future-increase-margin-1 237.5 μs 235.0 μs -1.1%
future-increase-margin-2 314.7 μs 317.3 μs +0.8%
future-increase-margin-3 314.3 μs 318.2 μs +1.2%
future-increase-margin-4 665.5 μs 672.5 μs +1.1%
future-increase-margin-5 660.4 μs 672.6 μs +1.8%
future-pay-out-1 227.4 μs 235.2 μs +3.4%
future-pay-out-2 313.2 μs 318.4 μs +1.7%
future-pay-out-3 313.5 μs 317.9 μs +1.4%
future-pay-out-4 663.4 μs 670.5 μs +1.1%
future-settle-early-1 230.5 μs 234.5 μs +1.7%
future-settle-early-2 315.3 μs 317.4 μs +0.7%
future-settle-early-3 314.2 μs 318.4 μs +1.3%
future-settle-early-4 662.2 μs 671.3 μs +1.4%
game-sm-success_1-1 510.2 μs 518.3 μs +1.6%
game-sm-success_1-2 160.4 μs 166.2 μs +3.6%
game-sm-success_1-3 510.1 μs 518.9 μs +1.7%
game-sm-success_1-4 160.6 μs 165.9 μs +3.3%
game-sm-success_2-1 508.5 μs 516.6 μs +1.6%
game-sm-success_2-2 162.6 μs 166.0 μs +2.1%
game-sm-success_2-3 510.8 μs 516.1 μs +1.0%
game-sm-success_2-4 163.2 μs 166.1 μs +1.8%
game-sm-success_2-5 510.8 μs 516.8 μs +1.2%
game-sm-success_2-6 164.0 μs 166.3 μs +1.4%
multisig-sm-1 566.9 μs 573.9 μs +1.2%
multisig-sm-2 564.3 μs 574.8 μs +1.9%
multisig-sm-3 566.3 μs 573.6 μs +1.3%
multisig-sm-4 564.8 μs 573.8 μs +1.6%
multisig-sm-5 562.7 μs 575.1 μs +2.2%
multisig-sm-6 566.4 μs 574.7 μs +1.5%
multisig-sm-7 566.4 μs 583.1 μs +2.9%
multisig-sm-8 566.4 μs 577.6 μs +2.0%
multisig-sm-9 563.1 μs 573.9 μs +1.9%
multisig-sm-10 565.7 μs 579.2 μs +2.4%
ping-pong-1 472.1 μs 488.1 μs +3.4%
ping-pong-2 480.4 μs 488.1 μs +1.6%
ping-pong_2-1 474.5 μs 487.9 μs +2.8%
prism-1 158.9 μs 162.2 μs +2.1%
prism-2 507.5 μs 509.2 μs +0.3%
prism-3 233.4 μs 235.6 μs +0.9%
pubkey-1 164.3 μs 166.1 μs +1.1%
stablecoin_1-1 853.8 μs 856.9 μs +0.4%
stablecoin_1-2 161.7 μs 166.6 μs +3.0%
stablecoin_1-3 853.2 μs 857.2 μs +0.5%
stablecoin_1-4 160.6 μs 166.3 μs +3.5%
stablecoin_1-5 851.4 μs 859.5 μs +1.0%
stablecoin_1-6 163.1 μs 166.3 μs +2.0%
stablecoin_2-1 855.3 μs 856.8 μs +0.2%
stablecoin_2-2 161.7 μs 165.9 μs +2.6%
stablecoin_2-3 855.1 μs 857.1 μs +0.2%
stablecoin_2-4 162.6 μs 166.2 μs +2.2%
token-account-1 229.5 μs 233.7 μs +1.8%
token-account-2 208.3 μs 213.7 μs +2.6%
uniswap-1 231.0 μs 236.3 μs +2.3%
uniswap-2 230.3 μs 234.2 μs +1.7%
uniswap-3 716.1 μs 720.8 μs +0.7%
uniswap-4 176.1 μs 179.1 μs +1.7%
uniswap-5 714.8 μs 720.9 μs +0.9%
uniswap-6 177.8 μs 179.0 μs +0.7%
vesting-1 315.1 μs 317.7 μs +0.8%
aeaafb9 3893622 Change
TOTAL 31.01 ms 31.44 ms +1.4%

@kwxm
Copy link
Contributor Author

kwxm commented Jul 18, 2025

/benchmark validation-decode

@github-actions
Copy link
Contributor

Click here to check the status of your benchmark.

@github-actions
Copy link
Contributor

Comparing benchmark results of 'validation-decode' on 'aeaafb922d' (base) and '3893622224' (PR)

Results table
Script aeaafb9 3893622 Change
auction_1-1 187.4 μs 195.4 μs +4.3%
auction_1-2 525.1 μs 548.8 μs +4.5%
auction_1-3 518.7 μs 548.6 μs +5.8%
auction_1-4 186.2 μs 195.2 μs +4.8%
auction_2-1 188.1 μs 195.2 μs +3.8%
auction_2-2 516.6 μs 535.6 μs +3.7%
auction_2-3 515.0 μs 547.6 μs +6.3%
auction_2-4 533.4 μs 535.6 μs +0.4%
auction_2-5 187.3 μs 195.3 μs +4.3%
crowdfunding-success-1 229.6 μs 236.4 μs +3.0%
crowdfunding-success-2 226.7 μs 235.8 μs +4.0%
crowdfunding-success-3 228.1 μs 235.6 μs +3.3%
currency-1 223.1 μs 234.1 μs +4.9%
escrow-redeem_1-1 305.6 μs 311.8 μs +2.0%
escrow-redeem_1-2 302.4 μs 312.2 μs +3.2%
escrow-redeem_2-1 303.7 μs 311.9 μs +2.7%
escrow-redeem_2-2 305.9 μs 311.3 μs +1.8%
escrow-redeem_2-3 305.9 μs 312.5 μs +2.2%
escrow-refund-1 304.9 μs 311.2 μs +2.1%
future-increase-margin-1 225.5 μs 234.1 μs +3.8%
future-increase-margin-2 307.0 μs 318.5 μs +3.7%
future-increase-margin-3 307.1 μs 317.3 μs +3.3%
future-increase-margin-4 649.5 μs 671.2 μs +3.3%
future-increase-margin-5 648.6 μs 669.7 μs +3.3%
future-pay-out-1 225.8 μs 235.5 μs +4.3%
future-pay-out-2 307.5 μs 318.8 μs +3.7%
future-pay-out-3 304.7 μs 319.1 μs +4.7%
future-pay-out-4 647.8 μs 683.3 μs +5.5%
future-settle-early-1 223.4 μs 232.8 μs +4.2%
future-settle-early-2 308.4 μs 316.4 μs +2.6%
future-settle-early-3 308.3 μs 318.8 μs +3.4%
future-settle-early-4 651.9 μs 667.9 μs +2.5%
game-sm-success_1-1 499.4 μs 516.6 μs +3.4%
game-sm-success_1-2 156.3 μs 165.1 μs +5.6%
game-sm-success_1-3 502.5 μs 518.0 μs +3.1%
game-sm-success_1-4 159.6 μs 165.0 μs +3.4%
game-sm-success_2-1 501.0 μs 515.0 μs +2.8%
game-sm-success_2-2 158.2 μs 165.1 μs +4.4%
game-sm-success_2-3 501.0 μs 515.8 μs +3.0%
game-sm-success_2-4 159.7 μs 166.0 μs +3.9%
game-sm-success_2-5 498.1 μs 524.6 μs +5.3%
game-sm-success_2-6 157.6 μs 165.6 μs +5.1%
multisig-sm-1 552.8 μs 571.7 μs +3.4%
multisig-sm-2 557.3 μs 572.8 μs +2.8%
multisig-sm-3 553.3 μs 574.0 μs +3.7%
multisig-sm-4 554.0 μs 573.9 μs +3.6%
multisig-sm-5 557.0 μs 586.2 μs +5.2%
multisig-sm-6 557.0 μs 572.0 μs +2.7%
multisig-sm-7 552.3 μs 572.9 μs +3.7%
multisig-sm-8 551.9 μs 573.8 μs +4.0%
multisig-sm-9 554.8 μs 573.6 μs +3.4%
multisig-sm-10 560.1 μs 574.5 μs +2.6%
ping-pong-1 462.9 μs 500.8 μs +8.2%
ping-pong-2 477.2 μs 491.6 μs +3.0%
ping-pong_2-1 468.2 μs 485.1 μs +3.6%
prism-1 153.0 μs 161.1 μs +5.3%
prism-2 492.7 μs 507.7 μs +3.0%
prism-3 226.6 μs 234.5 μs +3.5%
pubkey-1 157.6 μs 166.1 μs +5.4%
stablecoin_1-1 841.0 μs 861.1 μs +2.4%
stablecoin_1-2 159.4 μs 165.4 μs +3.8%
stablecoin_1-3 841.1 μs 853.8 μs +1.5%
stablecoin_1-4 160.1 μs 164.9 μs +3.0%
stablecoin_1-5 834.9 μs 872.2 μs +4.5%
stablecoin_1-6 159.4 μs 165.3 μs +3.7%
stablecoin_2-1 837.1 μs 855.3 μs +2.2%
stablecoin_2-2 159.2 μs 166.2 μs +4.4%
stablecoin_2-3 834.0 μs 855.4 μs +2.6%
stablecoin_2-4 159.2 μs 166.5 μs +4.6%
token-account-1 225.2 μs 232.6 μs +3.3%
token-account-2 204.2 μs 214.2 μs +4.9%
uniswap-1 228.2 μs 234.7 μs +2.8%
uniswap-2 226.0 μs 231.9 μs +2.6%
uniswap-3 698.9 μs 726.2 μs +3.9%
uniswap-4 172.4 μs 178.1 μs +3.3%
uniswap-5 698.8 μs 734.1 μs +5.1%
uniswap-6 174.3 μs 178.2 μs +2.2%
vesting-1 310.6 μs 318.0 μs +2.4%
aeaafb9 3893622 Change
TOTAL 30.42 ms 31.50 ms +3.6%

@kwxm
Copy link
Contributor Author

kwxm commented Jul 18, 2025

/benchmark validation-decode

@github-actions
Copy link
Contributor

Click here to check the status of your benchmark.

@github-actions
Copy link
Contributor

Comparing benchmark results of 'validation-decode' on 'aeaafb922d' (base) and '3893622224' (PR)

Results table
Script aeaafb9 3893622 Change
auction_1-1 190.0 μs 195.8 μs +3.1%
auction_1-2 536.5 μs 548.1 μs +2.2%
auction_1-3 524.6 μs 534.4 μs +1.9%
auction_1-4 188.7 μs 193.7 μs +2.6%
auction_2-1 189.5 μs 194.9 μs +2.8%
auction_2-2 532.3 μs 531.5 μs -0.2%
auction_2-3 520.7 μs 531.6 μs +2.1%
auction_2-4 538.2 μs 537.4 μs -0.1%
auction_2-5 189.3 μs 194.5 μs +2.7%
crowdfunding-success-1 229.8 μs 235.6 μs +2.5%
crowdfunding-success-2 230.3 μs 234.8 μs +2.0%
crowdfunding-success-3 232.8 μs 235.6 μs +1.2%
currency-1 229.3 μs 239.1 μs +4.3%
escrow-redeem_1-1 309.8 μs 310.7 μs +0.3%
escrow-redeem_1-2 308.9 μs 311.1 μs +0.7%
escrow-redeem_2-1 309.5 μs 310.6 μs +0.4%
escrow-redeem_2-2 310.5 μs 310.0 μs -0.2%
escrow-redeem_2-3 308.8 μs 309.6 μs +0.3%
escrow-refund-1 307.1 μs 312.2 μs +1.7%
future-increase-margin-1 225.3 μs 234.8 μs +4.2%
future-increase-margin-2 311.5 μs 317.3 μs +1.9%
future-increase-margin-3 312.5 μs 315.7 μs +1.0%
future-increase-margin-4 659.2 μs 667.1 μs +1.2%
future-increase-margin-5 658.0 μs 669.2 μs +1.7%
future-pay-out-1 229.1 μs 235.4 μs +2.7%
future-pay-out-2 309.4 μs 317.6 μs +2.7%
future-pay-out-3 312.6 μs 317.6 μs +1.6%
future-pay-out-4 674.6 μs 670.3 μs -0.6%
future-settle-early-1 232.0 μs 233.4 μs +0.6%
future-settle-early-2 311.8 μs 317.2 μs +1.7%
future-settle-early-3 309.6 μs 316.2 μs +2.1%
future-settle-early-4 658.2 μs 668.3 μs +1.5%
game-sm-success_1-1 510.5 μs 516.5 μs +1.2%
game-sm-success_1-2 158.9 μs 165.1 μs +3.9%
game-sm-success_1-3 504.2 μs 515.0 μs +2.1%
game-sm-success_1-4 158.7 μs 164.8 μs +3.8%
game-sm-success_2-1 502.5 μs 515.1 μs +2.5%
game-sm-success_2-2 161.0 μs 165.7 μs +2.9%
game-sm-success_2-3 506.2 μs 515.9 μs +1.9%
game-sm-success_2-4 161.6 μs 165.5 μs +2.4%
game-sm-success_2-5 520.7 μs 514.7 μs -1.2%
game-sm-success_2-6 162.1 μs 165.1 μs +1.9%
multisig-sm-1 563.4 μs 572.4 μs +1.6%
multisig-sm-2 563.0 μs 576.7 μs +2.4%
multisig-sm-3 569.5 μs 571.9 μs +0.4%
multisig-sm-4 564.0 μs 573.1 μs +1.6%
multisig-sm-5 578.0 μs 585.3 μs +1.3%
multisig-sm-6 562.3 μs 572.8 μs +1.9%
multisig-sm-7 557.9 μs 574.6 μs +3.0%
multisig-sm-8 574.6 μs 586.3 μs +2.0%
multisig-sm-9 562.7 μs 586.9 μs +4.3%
multisig-sm-10 562.6 μs 585.0 μs +4.0%
ping-pong-1 485.2 μs 498.6 μs +2.8%
ping-pong-2 474.8 μs 498.1 μs +4.9%
ping-pong_2-1 472.4 μs 486.4 μs +3.0%
prism-1 156.7 μs 161.2 μs +2.9%
prism-2 503.7 μs 506.7 μs +0.6%
prism-3 232.6 μs 234.6 μs +0.9%
pubkey-1 159.9 μs 166.0 μs +3.8%
stablecoin_1-1 848.2 μs 853.3 μs +0.6%
stablecoin_1-2 159.5 μs 165.3 μs +3.6%
stablecoin_1-3 847.3 μs 852.2 μs +0.6%
stablecoin_1-4 161.6 μs 165.3 μs +2.3%
stablecoin_1-5 848.6 μs 874.2 μs +3.0%
stablecoin_1-6 158.6 μs 165.3 μs +4.2%
stablecoin_2-1 845.8 μs 865.8 μs +2.4%
stablecoin_2-2 160.5 μs 165.5 μs +3.1%
stablecoin_2-3 850.1 μs 858.6 μs +1.0%
stablecoin_2-4 161.3 μs 165.2 μs +2.4%
token-account-1 230.1 μs 238.0 μs +3.4%
token-account-2 208.4 μs 212.7 μs +2.1%
uniswap-1 228.6 μs 236.9 μs +3.6%
uniswap-2 228.7 μs 232.5 μs +1.7%
uniswap-3 714.7 μs 719.7 μs +0.7%
uniswap-4 176.3 μs 178.4 μs +1.2%
uniswap-5 714.5 μs 720.9 μs +0.9%
uniswap-6 174.1 μs 177.6 μs +2.0%
vesting-1 314.1 μs 317.3 μs +1.0%
aeaafb9 3893622 Change
TOTAL 30.91 ms 31.46 ms +1.8%

@kwxm
Copy link
Contributor Author

kwxm commented Jul 18, 2025

/benchmark validation-decode

@github-actions
Copy link
Contributor

Click here to check the status of your benchmark.

@github-actions
Copy link
Contributor

Comparing benchmark results of 'validation-decode' on 'aeaafb922d' (base) and '3893622224' (PR)

Results table
Script aeaafb9 3893622 Change
auction_1-1 186.9 μs 195.1 μs +4.4%
auction_1-2 518.5 μs 548.4 μs +5.8%
auction_1-3 520.7 μs 537.4 μs +3.2%
auction_1-4 187.3 μs 193.7 μs +3.4%
auction_2-1 187.6 μs 194.6 μs +3.7%
auction_2-2 517.7 μs 532.5 μs +2.9%
auction_2-3 517.1 μs 531.1 μs +2.7%
auction_2-4 518.9 μs 533.9 μs +2.9%
auction_2-5 185.8 μs 194.7 μs +4.8%
crowdfunding-success-1 228.6 μs 234.4 μs +2.5%
crowdfunding-success-2 226.7 μs 234.2 μs +3.3%
crowdfunding-success-3 228.1 μs 234.5 μs +2.8%
currency-1 224.3 μs 234.7 μs +4.6%
escrow-redeem_1-1 304.7 μs 311.0 μs +2.1%
escrow-redeem_1-2 301.9 μs 311.0 μs +3.0%
escrow-redeem_2-1 306.1 μs 311.2 μs +1.7%
escrow-redeem_2-2 303.9 μs 312.2 μs +2.7%
escrow-redeem_2-3 302.4 μs 310.8 μs +2.8%
escrow-refund-1 301.5 μs 311.6 μs +3.3%
future-increase-margin-1 224.7 μs 233.8 μs +4.0%
future-increase-margin-2 305.1 μs 318.3 μs +4.3%
future-increase-margin-3 305.7 μs 317.9 μs +4.0%
future-increase-margin-4 656.5 μs 668.2 μs +1.8%
future-increase-margin-5 652.2 μs 678.6 μs +4.0%
future-pay-out-1 224.8 μs 233.0 μs +3.6%
future-pay-out-2 308.9 μs 317.1 μs +2.7%
future-pay-out-3 308.4 μs 317.4 μs +2.9%
future-pay-out-4 653.1 μs 665.8 μs +1.9%
future-settle-early-1 233.0 μs 239.4 μs +2.7%
future-settle-early-2 306.8 μs 317.5 μs +3.5%
future-settle-early-3 308.6 μs 318.0 μs +3.0%
future-settle-early-4 651.5 μs 667.2 μs +2.4%
game-sm-success_1-1 500.4 μs 527.9 μs +5.5%
game-sm-success_1-2 158.4 μs 165.3 μs +4.4%
game-sm-success_1-3 499.6 μs 520.0 μs +4.1%
game-sm-success_1-4 156.7 μs 165.9 μs +5.9%
game-sm-success_2-1 515.2 μs 520.5 μs +1.0%
game-sm-success_2-2 159.7 μs 164.9 μs +3.3%
game-sm-success_2-3 498.0 μs 514.9 μs +3.4%
game-sm-success_2-4 157.4 μs 165.3 μs +5.0%
game-sm-success_2-5 501.4 μs 515.7 μs +2.9%
game-sm-success_2-6 159.9 μs 165.5 μs +3.5%
multisig-sm-1 555.4 μs 572.3 μs +3.0%
multisig-sm-2 564.6 μs 572.3 μs +1.4%
multisig-sm-3 557.1 μs 572.2 μs +2.7%
multisig-sm-4 558.3 μs 578.0 μs +3.5%
multisig-sm-5 554.3 μs 577.9 μs +4.3%
multisig-sm-6 554.8 μs 586.9 μs +5.8%
multisig-sm-7 556.0 μs 570.1 μs +2.5%
multisig-sm-8 559.8 μs 571.0 μs +2.0%
multisig-sm-9 559.1 μs 572.9 μs +2.5%
multisig-sm-10 558.1 μs 570.4 μs +2.2%
ping-pong-1 468.9 μs 485.4 μs +3.5%
ping-pong-2 464.2 μs 484.3 μs +4.3%
ping-pong_2-1 471.3 μs 485.3 μs +3.0%
prism-1 156.9 μs 161.6 μs +3.0%
prism-2 494.9 μs 508.2 μs +2.7%
prism-3 230.5 μs 234.3 μs +1.6%
pubkey-1 160.6 μs 165.7 μs +3.2%
stablecoin_1-1 838.1 μs 853.0 μs +1.8%
stablecoin_1-2 158.5 μs 165.2 μs +4.2%
stablecoin_1-3 835.6 μs 855.6 μs +2.4%
stablecoin_1-4 158.8 μs 165.6 μs +4.3%
stablecoin_1-5 834.2 μs 873.8 μs +4.7%
stablecoin_1-6 157.9 μs 164.7 μs +4.3%
stablecoin_2-1 837.9 μs 853.9 μs +1.9%
stablecoin_2-2 159.3 μs 165.0 μs +3.6%
stablecoin_2-3 840.2 μs 851.2 μs +1.3%
stablecoin_2-4 157.9 μs 165.5 μs +4.8%
token-account-1 224.0 μs 236.4 μs +5.5%
token-account-2 204.2 μs 213.2 μs +4.4%
uniswap-1 229.1 μs 235.7 μs +2.9%
uniswap-2 223.0 μs 232.3 μs +4.2%
uniswap-3 705.0 μs 717.7 μs +1.8%
uniswap-4 174.4 μs 177.8 μs +1.9%
uniswap-5 705.8 μs 718.9 μs +1.9%
uniswap-6 174.1 μs 177.3 μs +1.8%
vesting-1 312.1 μs 316.5 μs +1.4%
aeaafb9 3893622 Change
TOTAL 30.47 ms 31.39 ms +3.0%

@@ -0,0 +1,7 @@
<!--
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uncomment the changelog

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops. Done.

-- decide what PVs the test should include. UPDATE THIS when we're expecting to
-- release new builtins in a forthcoming PV.
newestPV :: MajorProtocolVersion
newestPV = anonPV
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If new builtins are assigned to futurePV first, then changed to the appropriate PV when ready, then I don't see why we need this.

Copy link
Contributor Author

@kwxm kwxm Jul 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If new builtins are assigned to futurePV first, then changed to the appropriate PV when ready, then I don't see why we need this.

The preceding comment attempts to explain that. Some of the tests (here for instance) iterate over all of the deployed (or just-about-to-be-deployed) PVs and use newestPV to say where to stop. We can't use futurePV for that because it's maxBound. I added newestPV so that we wouldn't have to go through the tests and replace the actual most recent PV everywhere when we update it.

where no new builtins are added. See Note [New builtins/language versions and
protocol versions]
-}
builtinsIntroducedIn :: PlutusLedgerLanguage -> Map.Map MajorProtocolVersion (Set.Set DefaultFun)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this cause any performance regression? Previously builtinsIntroducedIn was a top-level Map that can be cached, but it is now a function.

-}
batch1 :: [DefaultFun]
batch1 =
[ AddInteger, SubtractInteger, MultiplyInteger, DivideInteger, QuotientInteger
Copy link
Member

@zliu41 zliu41 Jul 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's tedious to check the correctness of these batches manually. How about keeping the old version of builtinsIntroducedIn, and adding some property tests to verify that the old and new versions always agree (up to PV11)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what you mean. Do you want to keep both the old and the new versions? The batches were implcitly present in the previous version and here I've pulled them out to the top level to make things a bit more explicit and easier to relate to the specification; also, they're used in the tests so it helps to be able to export them. Of course, you should only ever add anything to the most recent batch (or add a new batch); maybe I should add a prominent comment to point that out.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean adding a test verifying that the new builtinsAvailableIn ll pv and the old builtinsAvailableIn ll pv always return the exact same set. This is especially important for pv=10. Or is this already covered in existing tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we'd have to keep the old builtinsAvailableIn function around specifically for the tests, even though it's not used? It gives incorrect results for PV11, so we'd have to modify it anyway: that's why I changed the implementation!

Copy link
Contributor Author

@kwxm kwxm Jul 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test should test that deserialisation succeeds or fails as expected for every single builtin in every LL/PV combination, and it's much more thorough than the previous version. It depends on batch1, batch2, etc being correct, but it's hard to see how to test the correctness of bultinsAvailableIn without using those since we don't have any independent descrioption of which builtins are available.

The batches in the new version start here and they're essentially just lifted from the previous version of builtinsAvailableIn, with batch4 having to be split into two to handle integerToByteString and byteStringToInteger in PlutusV2 at Plomin.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we'd have to keep the old builtinsAvailableIn function around specifically for the tests, even though it's not used?

Yeah, why not, we can move it to a test package. But if there's already a test that verifies that the new builtinsAvailableIn gives correct results for all ll/pv (especially PV10 and PV11), then we are good - that coverage is all we need.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. The old version works correctly up to PV10, so I can move it into the test code somewhere and add a test that the new implementation matches up to PV10 (but not PV11, where it breaks).

@kwxm kwxm temporarily deployed to github-pages July 21, 2025 05:49 — with GitHub Actions Inactive
| Ripemd_160'cpu'arguments'intercept
| Ripemd_160'cpu'arguments'slope
| Ripemd_160'memory'arguments
-- Not yet deployed
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't these also to be deployed in PV11? Why are they "Not yet deployed"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed that to "To be deployed in PV11", but I can take it out if you want. I may have copied it from the PlutusV3 parameters, where it marks the boundaries between the parameters for the things that are on the chain now and those that aren't.

A lot of the code in plutus-ledger-api is a bit weird because in a sort of in-between state where it's about stuff that's waiting to happen.

@kwxm kwxm temporarily deployed to github-pages July 23, 2025 02:05 — with GitHub Actions Inactive
@kwxm kwxm temporarily deployed to github-pages July 23, 2025 02:13 — with GitHub Actions Inactive
@kwxm kwxm temporarily deployed to github-pages July 23, 2025 02:19 — with GitHub Actions Inactive
@kwxm kwxm temporarily deployed to github-pages July 23, 2025 02:52 — with GitHub Actions Inactive
@kwxm kwxm temporarily deployed to github-pages July 23, 2025 03:24 — with GitHub Actions Inactive
Copy link
Member

@zliu41 zliu41 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great stuff. We can go ahead and merge it, then simplify the PV >= 11 logic in a separate PR.

pv11PV :: MajorProtocolVersion
pv11PV = MajorProtocolVersion 11

-- | The set of protocol versions that are "known", i.e. that have been released
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'm not quite sure what it means for a PV to be "released". It's probably more accurate to say: these are the PVs in which some Plutus primitives are enabled.

-- associate something with the wrong protocol version.
-- We're sometimes in an intermediate state where we've added new builtins but
-- not yet released them (but intend to). This is used by some of the tests to
-- decide what PVs the test should include. UPDATE THIS when we're expecting to
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than saying "UPDATE THIS" in a comment here - which is extremely easy to overlook - it would be nice to have a checklist somewhere, that documents everything we need to do when we are ready to release new builtins.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I have an issue to do that: thanks for reminding me. I'll put the issue in the current sprint so I can do it while the process is still fresh in my mind. I had in mind to write some kind of textual document, but maybe an issue template would be a better way to do it.

at the moment, it's tempting to insert the 4a parameter before the 4b
parameters and enable them all at PV11 and with a suitable parameter update.
However, if we do do this there's a theoretical risk of turning a phase 2
failure into a phase 1 failure: would that be problematic?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point - different node versions disagreeing on whether a failure is phase 1 or phase 2 can indeed be very problematic.

machineParametersFor ledgerLang majorPV =
MachineParameters
(if majorPV < futurePV
(if majorPV < pv11PV
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

import PlutusLedgerApi.V1 qualified as V1
import PlutusLedgerApi.V2 qualified as V2
import PlutusLedgerApi.V3 qualified as V3
-- import PlutusCore.Evaluation.Machine.ExBudgetingDefaults (defaultCostModelParamsForTesting)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove?

@kwxm kwxm temporarily deployed to github-pages July 23, 2025 21:16 — with GitHub Actions Inactive
@kwxm kwxm merged commit 58d77d2 into master Jul 24, 2025
8 checks passed
@kwxm kwxm deleted the kwxm/PV11/enable-all-builtins-2 branch July 24, 2025 01:11
Copy link
Contributor

@effectfully effectfully left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, there's no way I can make "I've spent hours reviewing Kenneth's PR and it turned out to be all good as expected" look good on a performance review, so here's a couple of comments that I had from a cursory reading.

where no new builtins are added. See Note [New builtins/language versions and
protocol versions]
-}
builtinsIntroducedIn :: PlutusLedgerLanguage -> Map.Map MajorProtocolVersion (Set.Set DefaultFun)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that things like batch2 ++ batch3 ++ batch4 ++ batch5 ++ batch6 will be computed at compile time

You don't know that, unless you've checked it. These are not small definitions and they're not marked as INLINE, GHC can easily avoid inlining them, in which case fusion doesn't kick in, in which case they don't get computed statically.

Previously builtinsIntroducedIn was a top-level Map that can be cached, but it is now a function.

All we need to make it efficient again is just to put

      Map.fromList
      [ (alonzoPV, Set.fromList batch1)
      , (pv11PV,   Set.fromList (batch2 ++ batch3 ++ batch4 ++ batch5 ++ batch6))
      ]

etc into their own top-level definitions marked as OPAQUE.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Builtins Costing Anything relating to costs, fees, gas, etc. Plutus Core Plutus Ledger API

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants