forked from IntersectMBO/plutus
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add an initial data-backed
ScriptContext
(IntersectMBO#6171)
* Add an initial data-backed ScriptContext and ledger API
- Loading branch information
1 parent
ab9cc56
commit c32b03a
Showing
38 changed files
with
5,662 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
148 changes: 148 additions & 0 deletions
148
plutus-benchmark/script-contexts/src/PlutusBenchmark/Data/ScriptContexts.hs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
{-# LANGUAGE BangPatterns #-} | ||
{-# LANGUAGE DataKinds #-} | ||
{-# LANGUAGE OverloadedStrings #-} | ||
{-# LANGUAGE TemplateHaskell #-} | ||
|
||
module PlutusBenchmark.Data.ScriptContexts where | ||
|
||
import PlutusLedgerApi.Data.V3 (OutputDatum (NoOutputDatum), PubKeyHash (..), Redeemer (..), | ||
ScriptContext (..), ScriptInfo (SpendingScript), TxId (..), | ||
TxInfo (..), TxOut (..), TxOutRef (..), always) | ||
import PlutusLedgerApi.V1.Address | ||
import PlutusLedgerApi.V1.Data.Value | ||
import PlutusTx qualified | ||
import PlutusTx.Builtins qualified as PlutusTx | ||
import PlutusTx.Data.AssocMap qualified as Map | ||
import PlutusTx.Plugin () | ||
import PlutusTx.Prelude qualified as PlutusTx | ||
|
||
-- | A very crude deterministic generator for 'ScriptContext's with size | ||
-- approximately proportional to the input integer. | ||
mkScriptContext :: Int -> ScriptContext | ||
mkScriptContext i = | ||
ScriptContext | ||
(mkTxInfo i) | ||
(Redeemer (PlutusTx.toBuiltinData (1 :: Integer))) | ||
(SpendingScript (TxOutRef (TxId "") 0) Nothing) | ||
|
||
|
||
mkTxInfo :: Int -> TxInfo | ||
mkTxInfo i = TxInfo { | ||
txInfoInputs=mempty, | ||
txInfoReferenceInputs=mempty, | ||
txInfoOutputs=fmap mkTxOut [1..i], | ||
txInfoFee=10000, | ||
txInfoMint=mempty, | ||
txInfoTxCerts=mempty, | ||
txInfoWdrl=Map.empty, | ||
txInfoValidRange=always, | ||
txInfoSignatories=mempty, | ||
txInfoRedeemers=Map.empty, | ||
txInfoData=Map.empty, | ||
txInfoId=TxId "", | ||
txInfoVotes=Map.empty, | ||
txInfoProposalProcedures=mempty, | ||
txInfoCurrentTreasuryAmount=Nothing, | ||
txInfoTreasuryDonation=Nothing | ||
} | ||
|
||
mkTxOut :: Int -> TxOut | ||
mkTxOut i = TxOut { | ||
txOutAddress=pubKeyHashAddress (PubKeyHash ""), | ||
txOutValue=mkValue i, | ||
txOutDatum=NoOutputDatum, | ||
txOutReferenceScript=Nothing | ||
} | ||
|
||
mkValue :: Int -> Value | ||
mkValue i = assetClassValue (assetClass adaSymbol adaToken) (fromIntegral i) | ||
|
||
-- This example decodes the script context (which is O(size-of-context) work), and then also | ||
-- does some work that's roughly proportional to the size of the script context (counting the | ||
-- outputs). This should be a somewhat realistic example where a reasonable chunk of work is | ||
-- done in addition to decoding. | ||
{-# INLINABLE checkScriptContext1 #-} | ||
checkScriptContext1 :: PlutusTx.BuiltinData -> () | ||
checkScriptContext1 d = | ||
-- Bang pattern to ensure this is forced, probably not necesssary | ||
-- since we do use it later | ||
let !sc = PlutusTx.unsafeFromBuiltinData d | ||
ScriptContext txi _ _ = sc | ||
in | ||
if PlutusTx.length (txInfoOutputs txi) `PlutusTx.modInteger` 2 PlutusTx.== 0 | ||
then () | ||
else PlutusTx.traceError "Odd number of outputs" | ||
|
||
mkCheckScriptContext1Code :: ScriptContext -> PlutusTx.CompiledCode () | ||
mkCheckScriptContext1Code sc = | ||
let d = PlutusTx.toBuiltinData sc | ||
in | ||
$$(PlutusTx.compile [|| checkScriptContext1 ||]) | ||
`PlutusTx.unsafeApplyCode` | ||
PlutusTx.liftCodeDef d | ||
|
||
-- This example aims to *force* the decoding of the script context and then ignore it entirely. | ||
-- This corresponds to the unfortunate case where the decoding "wrapper" around a script forces | ||
-- all the decoding work to be done even if it isn't used. | ||
{-# INLINABLE checkScriptContext2 #-} | ||
checkScriptContext2 :: PlutusTx.BuiltinData -> () | ||
checkScriptContext2 d = | ||
let (sc :: ScriptContext) = PlutusTx.unsafeFromBuiltinData d | ||
-- 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! | ||
in case sc of | ||
!_ -> | ||
if 48 PlutusTx.* 9900 PlutusTx.== (475200 :: Integer) | ||
then () | ||
else PlutusTx.traceError "Got my sums wrong" | ||
|
||
mkCheckScriptContext2Code :: ScriptContext -> PlutusTx.CompiledCode () | ||
mkCheckScriptContext2Code sc = | ||
let d = PlutusTx.toBuiltinData sc | ||
in | ||
$$(PlutusTx.compile [|| checkScriptContext2 ||]) | ||
`PlutusTx.unsafeApplyCode` | ||
PlutusTx.liftCodeDef d | ||
|
||
{- Note [Redundant arguments to equality benchmarks] | ||
The arguments for the benchmarks are passed as terms created with `liftCodeDef`. | ||
But the benchmark still needs to _evaluate_ these terms, which adds overhead that | ||
distracts from the main point. | ||
We can't easily remove the overhead, but we can at least include it in both cases to | ||
make things fairer. Hence we include redundant arguments in the two cases to ensure | ||
the same work is done in both cases. There is a third case that is just this overhead | ||
for comparison. | ||
-} | ||
|
||
-- This example checks the script context for equality (with itself) when encoded as `Data`. | ||
-- That means it just takes a single builtin call, which is fast (so long as the builtin is | ||
-- costed cheaply). | ||
{-# INLINABLE scriptContextEqualityData #-} | ||
scriptContextEqualityData :: ScriptContext -> PlutusTx.BuiltinData -> () | ||
-- See Note [Redundant arguments to equality benchmarks] | ||
scriptContextEqualityData _ d = | ||
if PlutusTx.equalsData d d | ||
then () | ||
else PlutusTx.traceError "The argument is not equal to itself" | ||
|
||
mkScriptContextEqualityDataCode :: ScriptContext -> PlutusTx.CompiledCode () | ||
mkScriptContextEqualityDataCode sc = | ||
let d = PlutusTx.toBuiltinData sc | ||
in $$(PlutusTx.compile [|| scriptContextEqualityData ||]) | ||
`PlutusTx.unsafeApplyCode` PlutusTx.liftCodeDef sc | ||
`PlutusTx.unsafeApplyCode` PlutusTx.liftCodeDef d | ||
|
||
-- This example is just the overhead from the previous two | ||
-- See Note [Redundant arguments to equality benchmarks] | ||
{-# INLINABLE scriptContextEqualityOverhead #-} | ||
scriptContextEqualityOverhead :: ScriptContext -> PlutusTx.BuiltinData -> () | ||
scriptContextEqualityOverhead _ _ = () | ||
|
||
mkScriptContextEqualityOverheadCode :: ScriptContext -> PlutusTx.CompiledCode () | ||
mkScriptContextEqualityOverheadCode sc = | ||
let d = PlutusTx.toBuiltinData sc | ||
in $$(PlutusTx.compile [|| scriptContextEqualityOverhead ||]) | ||
`PlutusTx.unsafeApplyCode` PlutusTx.liftCodeDef sc | ||
`PlutusTx.unsafeApplyCode` PlutusTx.liftCodeDef d |
2 changes: 2 additions & 0 deletions
2
plutus-benchmark/script-contexts/test/Data/9.6/checkScriptContext1-20.budget.golden
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
({cpu: 215441185 | ||
| mem: 798229}) |
1 change: 1 addition & 0 deletions
1
plutus-benchmark/script-contexts/test/Data/9.6/checkScriptContext1-20.eval.golden
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
(constr 0) |
2 changes: 2 additions & 0 deletions
2
plutus-benchmark/script-contexts/test/Data/9.6/checkScriptContext1-4.budget.golden
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
({cpu: 68663201 | ||
| mem: 260597}) |
1 change: 1 addition & 0 deletions
1
plutus-benchmark/script-contexts/test/Data/9.6/checkScriptContext1-4.eval.golden
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
(constr 0) |
Oops, something went wrong.