Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a data-backed ScriptContext #6171

Merged
merged 2 commits into from
Aug 9, 2024
Merged

Conversation

ana-pantilie
Copy link
Contributor

@ana-pantilie ana-pantilie commented Jun 4, 2024

Needs #6143
Fixes #6097

Adds a first version of a data-backed ScriptContext. For now, "data-backed" means that all the maps contained by the ScriptContext are represented as BuiltinData. The next step will be to make lists data-backed as well, hoping that reduces encoding/decoding time to be negligible.

The interface provided to users is the same as the regular ScriptContext, the difference is that they have to import i.e. PlutusLedgerAPI.Data.V1 instead of PlutusLedgerAPI.V1 to use the data version. The modules which don't have anything to do with maps are shared.
Note: this might have introduced some unnecessary duplication in the code, but it doesn't seem trivial to fix it without messing up the interface. For this first version, I think this is fine but let me know if there's something we can do to improve things!

Pre-submit checklist:

  • Branch
    • Tests are provided (if possible)
    • Commit sequence broadly makes sense
    • Key commits have useful messages
    • Changelog fragments have been written (if appropriate)
    • Relevant tickets are mentioned in commit messages
    • Formatting, PNG optimization, etc. are updated
  • PR
    • (For external contributions) Corresponding issue exists and is linked in the description
    • Targeting master unless this is a cherry-pick backport
    • Self-reviewed the diff
    • Useful pull request description
    • Reviewer requested

Copy link
Contributor Author

@ana-pantilie ana-pantilie left a comment

Choose a reason for hiding this comment

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

Consistently better performance results for the Data-backed version on the plutus-benchmark/script-contexts tests!

@@ -0,0 +1,2 @@
({cpu: 215441185
| mem: 798229})
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Non-data is:

({cpu: 291862695
| mem: 1092729})

Copy link
Contributor

Choose a reason for hiding this comment

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

26% less cpu, 27% less of mem!

@@ -0,0 +1 @@
(constr 0)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is correct.

TODO: write tests which check that the SOP and the Data versions eval to the same result

Copy link
Contributor

Choose a reason for hiding this comment

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

It would be ideal to simply share golden files for evaluation tests of the two flavors of ScriptContext.

@@ -0,0 +1,2 @@
({cpu: 68663201
| mem: 260597})
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Non-data version:

({cpu: 87564279
| mem: 338905})

@@ -0,0 +1 @@
(constr 0)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍

@@ -0,0 +1 @@
2829
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Non-data version: 3183

@@ -0,0 +1 @@
2765
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Non-data version: 3119

@@ -0,0 +1,2 @@
({cpu: 51650332
| mem: 118202})
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Non-data version:

({cpu: 67298332
| mem: 216002})

@@ -0,0 +1 @@
(constr 0)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍

@@ -0,0 +1,2 @@
({cpu: 18656100
| mem: 116700})
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Non-data version:

({cpu: 34304100
| mem: 214500})

@@ -0,0 +1 @@
(constr 0)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍

@ana-pantilie ana-pantilie marked this pull request as ready for review July 16, 2024 09:52
Comment on lines +91 to +93
-- Just using a bang pattern was not enough to stop GHC from getting
-- rid of the dead binding before we even hit the plugin, this works
-- for now!
Copy link
Contributor

Choose a reason for hiding this comment

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

Did you consider deriving NFData instances and using deepseq to deeply evaluate the script context?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is basically all copied over from PlutusBenchmark.ScriptContexts, and most of the documentation in the other modules is as well copied over from the non-data versions. Which reminds me that I need properly document things, but once I refactor and remove the duplication.

@ana-pantilie ana-pantilie requested a review from a team July 24, 2024 13:12
ready to be evaluated on-chain.
Called inside phase-1 validation (i.e., deserialisation error is a phase-1 error).
-}
deserialiseScript ::
Copy link
Member

Choose a reason for hiding this comment

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

I don't see why we need to redefine this. Can we not re-export the existing one?

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 I'd prefer for this module not to depend on the other one as that'll save us pretty little, but will make things quite more confusing.

Code duplication is quite unfortunate though, we'll now have to maintain twice more API modules and those are maintenance-hungry. Maybe we should eventually make the whole API type-class-based? Ledger-style.

Copy link
Member

Choose a reason for hiding this comment

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

Duplicating a function that uses map would be one thing, but duplicating something that doesn't use map at all makes little sense. Consider making PlutusLedgerApi.V1 agnostic of the choice of map/list, and making PlutusLedgerApi.V1.Term and PlutusLedgerApi.V1.Data for anything specific to a particular map/list.


import GHC.Generics (Generic)
import PlutusTx
import PlutusTx.AssocMap hiding (filter, mapMaybe)
Copy link
Member

Choose a reason for hiding this comment

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

Why is it still using AssocMap?

_ == _ = False

-- | A pending transaction. This is the view as seen by validator scripts, so some details are stripped out.
data TxInfo = TxInfo
Copy link
Member

Choose a reason for hiding this comment

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

This looks the same as the existing TxInfo, so why redefine it?

Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if it's the same, but it's definitely not gonna be, right? Because the lists will become Data-based as well. @ana-pantilie is that right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It uses different Map and Value types, so it's not the same TxInfo.

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.

I really do hope we'll eventually get to cleaning it all up instead of leaving this much code duplication lying around.

@@ -0,0 +1 @@
(constr 0)
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be ideal to simply share golden files for evaluation tests of the two flavors of ScriptContext.

@@ -0,0 +1,3 @@
### Added

- A first version of a data-backed `ScriptContext`. The ledger API is similar to the regular `ScriptContext`; one should import the `Data` versions of modules instead to use this version.
Copy link
Contributor

Choose a reason for hiding this comment

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

Please provide one example here.

ready to be evaluated on-chain.
Called inside phase-1 validation (i.e., deserialisation error is a phase-1 error).
-}
deserialiseScript ::
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 I'd prefer for this module not to depend on the other one as that'll save us pretty little, but will make things quite more confusing.

Code duplication is quite unfortunate though, we'll now have to maintain twice more API modules and those are maintenance-hungry. Maybe we should eventually make the whole API type-class-based? Ledger-style.

_ == _ = False

-- | A pending transaction. This is the view as seen by validator scripts, so some details are stripped out.
data TxInfo = TxInfo
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if it's the same, but it's definitely not gonna be, right? Because the lists will become Data-based as well. @ana-pantilie is that right?

Comment on lines +469 to +473
{-# INLINEABLE findContinuingOutputs #-}

{- | Find the indices of all the outputs that pay to the same script address we are
currently spending from, if any.
-}
Copy link
Contributor

Choose a reason for hiding this comment

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

ormolu idiocy at your service.

, P.UnsafeFromData k
, P.UnsafeFromData a
) => Pretty (Map k a) where
pretty = pretty . toList
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this needed now?

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 believe it's for the tests.

@ana-pantilie
Copy link
Contributor Author

Opened #6396 for addressing the code duplication concerns.

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.

This looks mergeable. I think we'd need a data-encoded list as well, since using regular lists in a data-encoded ScriptContext could be very bad for efficiency.

ready to be evaluated on-chain.
Called inside phase-1 validation (i.e., deserialisation error is a phase-1 error).
-}
deserialiseScript ::
Copy link
Member

Choose a reason for hiding this comment

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

Duplicating a function that uses map would be one thing, but duplicating something that doesn't use map at all makes little sense. Consider making PlutusLedgerApi.V1 agnostic of the choice of map/list, and making PlutusLedgerApi.V1.Term and PlutusLedgerApi.V1.Data for anything specific to a particular map/list.

@ana-pantilie ana-pantilie force-pushed the ana/data-value-ledger-api branch from 8913c56 to b98efe8 Compare August 9, 2024 13:17
@ana-pantilie ana-pantilie force-pushed the ana/data-value-ledger-api branch from b98efe8 to 4e46945 Compare August 9, 2024 13:30
@ana-pantilie ana-pantilie merged commit c32b03a into master Aug 9, 2024
6 checks passed
@ana-pantilie ana-pantilie deleted the ana/data-value-ledger-api branch August 9, 2024 14:37
@kwxm kwxm mentioned this pull request Aug 12, 2024
v0d1ch pushed a commit to v0d1ch/plutus that referenced this pull request Dec 6, 2024
* Add an initial data-backed ScriptContext and ledger API
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

A Data-encoded ScriptContext (for each Plutus version) is provided in the ledger api
4 participants