-
Notifications
You must be signed in to change notification settings - Fork 483
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
Conversation
a161078
to
db5cabb
Compare
There was a problem hiding this 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}) |
There was a problem hiding this comment.
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})
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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}) |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -0,0 +1 @@ | |||
2829 |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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}) |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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}) |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
-- 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! |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
ready to be evaluated on-chain. | ||
Called inside phase-1 validation (i.e., deserialisation error is a phase-1 error). | ||
-} | ||
deserialiseScript :: |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this 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) |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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 :: |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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?
{-# INLINEABLE findContinuingOutputs #-} | ||
|
||
{- | Find the indices of all the outputs that pay to the same script address we are | ||
currently spending from, if any. | ||
-} |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
Opened #6396 for addressing the code duplication concerns. |
There was a problem hiding this 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 :: |
There was a problem hiding this comment.
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.
8913c56
to
b98efe8
Compare
b98efe8
to
4e46945
Compare
* Add an initial data-backed ScriptContext and ledger API
Needs #6143
Fixes #6097
Adds a first version of a data-backed
ScriptContext
. For now, "data-backed" means that all the maps contained by theScriptContext
are represented asBuiltinData
. 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 ofPlutusLedgerAPI.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: