Add ScriptContext Builder testlib and refactor LinearVesting tests#7643
Add ScriptContext Builder testlib and refactor LinearVesting tests#7643
Conversation
| -- | Convert a hex encoded Haskell 'String' to a 'CurrencySymbol'. | ||
| currencySymbolFromHex :: String -> CurrencySymbol | ||
| currencySymbolFromHex hexStr = | ||
| case Base16.decode (BS8.pack hexStr) of |
There was a problem hiding this comment.
Change from #7562: Replaced stringToBuiltinByteStringHex (which isn't meant to be applied to a non-statically known argument) with Base16.decode from the base16-bytestring package. This removes custom hex-parsing code in favor of a well-tested library function.
| @@ -0,0 +1,632 @@ | |||
| {-# LANGUAGE BlockArguments #-} | |||
There was a problem hiding this comment.
Change from #7562: Removed 8 unused language pragmas that were present in the original (DataKinds, DeriveAnyClass, FlexibleInstances, MultiParamTypeClasses, ScopedTypeVariables, TemplateHaskell, TypeApplications, ViewPatterns). Only the three pragmas actually needed are kept.
| , txInfoReferenceInputsL | ||
| , txInfoSignatoriesL | ||
| ) | ||
| import PlutusLedgerApi.V3 |
There was a problem hiding this comment.
Change from #7562: Modernized imports from PlutusLedgerApi.V1 / PlutusLedgerApi.V1.Value to PlutusLedgerApi.V3. The original mixed V1 and V3 imports; this version imports consistently from V3 since the builder targets V3 script contexts.
| deriving stock (Generic) | ||
|
|
||
| -- | Create a 'Value' containing only ADA from a 'Lovelace' amount. | ||
| mkAdaValue :: Lovelace -> Value |
There was a problem hiding this comment.
Change from #7562: Changed mkAdaValue to take Lovelace instead of Integer. This leverages the Lovelace newtype for type safety and aligns with how fees and other ADA amounts are represented in the ledger API.
| mkAdaValue = singleton adaSymbol adaToken . getLovelace | ||
|
|
||
| -- | Add a minting entry to an existing 'ScriptContext'. | ||
| addMint :: ScriptContext -> Value -> BuiltinData -> ScriptContext |
There was a problem hiding this comment.
Change from #7562: Refactored field updates to use lens combinators (e.g. over txInfoMintL, set txInfoRedeemerL) instead of manual record updates with nested pattern matching. The lenses are TH-generated in the companion Lenses module. This makes the code more composable and less error-prone when the ledger types change.
| } | ||
|
|
||
| -- | Create a minimal 'ScriptContext' for a minting script. | ||
| mkMintingScriptWithPurpose :: Value -> BuiltinData -> ScriptContext |
There was a problem hiding this comment.
Change from #7562: Refactored mkMintingScriptWithPurpose (and the other mk*ScriptContext functions) to use a shared baseScriptContext helper with lens-based modifications, reducing code duplication across minting/spending/certifying/rewarding/proposing variants.
|
|
||
| -- | Set the transaction fee. | ||
| withFee :: Integer -> ScriptContextBuilder | ||
| withFee fee = ScriptContextBuilder \scb -> scb {scbFee = fee} |
There was a problem hiding this comment.
Change from #7562: Enabled BlockArguments and removed $ operators throughout in favor of block argument syntax (e.g. ScriptContextBuilder \scb -> ... instead of ScriptContextBuilder $ \scb -> ...). This follows the project's preferred style.
| instance PlutusTx.Eq.Eq ScriptPurpose where | ||
| a == b = PlutusTx.toBuiltinData a == PlutusTx.toBuiltinData b | ||
|
|
||
| -- | Convert a hex encoded Haskell 'String' to a 'CurrencySymbol'. |
There was a problem hiding this comment.
Change from #7562: Added Haddock documentation comments to all exported functions. The original had no doc comments; these explain each combinator's purpose and behavior.
|
|
||
| {-| Extract the single currency symbol from a 'Value'. Errors if the value | ||
| contains zero or more than one currency symbol. -} | ||
| singleCurrencySymbol :: Value -> CurrencySymbol |
There was a problem hiding this comment.
Change from #7562: Replaced uses of partial head (on the list of currency symbols in a Value) with a new singleCurrencySymbol function that pattern-matches and gives a clear error message if the value doesn't contain exactly one currency symbol. This eliminates a partial function and improves debuggability.
| , txInfoReferenceInputsL | ||
| , txInfoSignatoriesL | ||
| ) | ||
| import PlutusLedgerApi.V1.Address (toPubKeyHash, toScriptHash) |
There was a problem hiding this comment.
Change from #7562 (10): Replaced local isPubKeyAddress/isScriptAddress helpers (defined in where clauses of balanceWithChangeOutput, withInput, and withScriptInput) with toPubKeyHash/toScriptHash from PlutusLedgerApi.V1.Address. These existing API functions return Maybe PubKeyHash/Maybe ScriptHash, so the call sites use isJust . toPubKeyHash and isJust . toScriptHash.
| import PlutusTx qualified | ||
| import PlutusTx.AssocMap qualified as Map | ||
| import PlutusTx.Builtins.Internal (BuiltinByteString (..)) | ||
| import PlutusTx.Eq qualified |
There was a problem hiding this comment.
Change from #7562 (11): Replaced negateValue (which manually negated all quantities via nested Map.mapWithKey) with PlutusTx.negate from PlutusTx.Numeric. Value already has an AdditiveGroup instance (via deriving via (Additive Value) in PlutusLedgerApi.V1.Value), so PlutusTx.negate works directly. Removed the export and definition.
| } | ||
| where | ||
| finalState = runBuilder modify defaultScriptContextBuilderState | ||
|
|
There was a problem hiding this comment.
Change from #7562 (12): Exported currencySymbolFromHex and singleCurrencySymbol (previously internal) and relocated them to a dedicated Helpers section at the bottom of the module. These are test-specific utilities with no equivalent in the main ledger API.
Introduce a ScriptContext builder module in plutus-ledger-api testlib that provides composable combinators for constructing ScriptContext values in tests. This replaces hand-crafted script contexts with a declarative builder pattern using lenses. Key changes: - Add PlutusLedgerApi.Test.ScriptContextBuilder.Builder with combinators for minting, spending, certifying, rewarding, and proposing contexts - Add PlutusLedgerApi.Test.ScriptContextBuilder.Lenses with TH-generated lenses for all V3 ledger types - Refactor LinearVesting benchmark tests to use the new builder - Fix AsData destructSum-manual test to use manual IsData instances instead of asData, regenerating golden files Based on work from PR #7562. Co-authored-by: Philip DiSarro <philip-disarro@users.noreply.github.com>
- Replace local isPubKeyAddress/isScriptAddress with toPubKeyHash/toScriptHash from PlutusLedgerApi.V1.Address - Replace negateValue with PlutusTx.negate (Value has AdditiveGroup) - Export and relocate currencySymbolFromHex and singleCurrencySymbol to a dedicated Helpers section at the bottom of Builder.hs Co-authored-by: Philip DiSarro <philip-disarro@users.noreply.github.com>
62c1011 to
1d6054f
Compare
|
Why golden files changed ( The ScriptContext builder produces a more complete/populated
This makes the compiled UPLC constant larger, which is why |
zliu41
left a comment
There was a problem hiding this comment.
LGTM - this should be very useful for different purposes.
Summary
This is PR 1 of a split from @colll78's PR #7562. It lands the
ScriptContextBuilder module and associated test refactors.PlutusLedgerApi.Test.ScriptContextBuildertoplutus-ledger-apitestlib with composable combinators (mkMintingScriptContext,mkSpendingScriptContext,addMint,withFee, etc.) for constructingScriptContextvalues in testsTxInfo,TxOut,Value, etc.)destructSum-manualtest to use manualIsDatainstances instead ofasData, regenerating golden filesChanges from Philip's original code
Review comments on the diff annotate each change made to the original code from #7562.