Skip to content

Commit 4a690a6

Browse files
committed
[Dijkstra] Fix collectP2ScriptsWithContext: TxLevel-indexed txInfo + split UTxO views
- Update collectP2ScriptsWithContext to take both utxoSpend₀ (initial snapshot) and utxoRefView (for reference lookups), preparing for batch-aware collection and single phase-2 eval. - Use txInfoForPurpose to construct validation context (TxLevel-indexed) instead of Conway's language-indexed txInfo. Dijkstra txInfo is indexed by TxLevel, not by Plutus language.
1 parent d9fd7b5 commit 4a690a6

File tree

3 files changed

+96
-71
lines changed

3 files changed

+96
-71
lines changed

src/Ledger/Dijkstra/Specification/Abstract.lagda.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module Ledger.Dijkstra.Specification.Abstract (txs : TransactionStructure) where
88
open import Ledger.Prelude
99
open TransactionStructure txs
1010
open import Ledger.Dijkstra.Specification.Certs govStructure
11+
open import Ledger.Dijkstra.Specification.Script.ScriptPurpose txs
1112
1213
1314
record indexOf : Type where
@@ -26,4 +27,5 @@ record AbstractFunctions : Type where
2627
indexOfImp : indexOf
2728
runPLCScript : CostModel → P2Script → ExUnits → List Data → Bool
2829
scriptSize : Script → ℕ
30+
valContext : TxInfo → ScriptPurpose → Data
2931
```
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
---
2+
source_branch: master
3+
source_path: src/Ledger/Dijkstra/Specification/Script/ScriptPurpose.lagda.md
4+
---
5+
6+
# Script Purpose {#sec:script-purpose}
7+
8+
<!--
9+
```agda
10+
{-# OPTIONS --safe #-}
11+
12+
open import Ledger.Dijkstra.Specification.Transaction
13+
14+
module Ledger.Dijkstra.Specification.Script.ScriptPurpose (txs : TransactionStructure) where
15+
16+
open import Ledger.Prelude
17+
open TransactionStructure txs
18+
open import Ledger.Dijkstra.Specification.Certs govStructure
19+
```
20+
-->
21+
22+
```agda
23+
data ScriptPurpose : Type where
24+
Cert : DCert → ScriptPurpose
25+
Rwrd : RewardAddress → ScriptPurpose
26+
Mint : ScriptHash → ScriptPurpose
27+
Spend : TxIn → ScriptPurpose
28+
Vote : GovVoter → ScriptPurpose
29+
Propose : GovProposal → ScriptPurpose
30+
Guard : Credential → ScriptPurpose
31+
```
32+
33+
Note that `Guard c` always indexes into *the current `tx`'s* `txGuards`:
34+
35+
+ if `tx : TopLevelTx`, it indexes into the top-level guard set's list-view;
36+
+ if `tx : SubLevelTx`, it indexes into the subTx's guard set's list-view.
37+
38+
```agda
39+
mutual
40+
record TxInfo : Type where
41+
inductive
42+
field
43+
realizedInputs : UTxO
44+
txOuts : Ix ⇀ TxOut
45+
txFee : Maybe Fees
46+
mint : Value
47+
txCerts : List DCert
48+
txWithdrawals : Withdrawals
49+
txVldt : Maybe Slot × Maybe Slot
50+
vkKey : ℙ KeyHash -- native/phase-1/timelock signers
51+
txGuards : ℙ Credential -- CIP-0112/0118 guards (required by tx body)
52+
txData : ℙ Datum
53+
txId : TxId
54+
txInfoSubTxs : Maybe (List SubTxInfo)
55+
56+
SubTxInfo : Type
57+
SubTxInfo = TxInfo
58+
59+
```

src/Ledger/Dijkstra/Specification/Script/Validation.lagda.md

Lines changed: 35 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,11 @@ module Ledger.Dijkstra.Specification.Script.Validation
1717
1818
open import Ledger.Prelude
1919
open import Ledger.Dijkstra.Specification.Certs govStructure
20-
```
21-
-->
2220
23-
```agda
24-
data ScriptPurpose : Type where
25-
Cert : DCert → ScriptPurpose
26-
Rwrd : RewardAddress → ScriptPurpose
27-
Mint : ScriptHash → ScriptPurpose
28-
Spend : TxIn → ScriptPurpose
29-
Vote : GovVoter → ScriptPurpose
30-
Propose : GovProposal → ScriptPurpose
31-
Guard : Credential → ScriptPurpose
21+
open import Ledger.Dijkstra.Specification.Abstract txs
22+
open import Ledger.Dijkstra.Specification.Script.ScriptPurpose txs
3223
```
33-
34-
Note that `Guard c` always indexes into *the current `tx`'s* `txGuards`:
35-
36-
+ if `tx : TopLevelTx`, it indexes into the top-level guard set's list-view;
37-
+ if `tx : SubLevelTx`, it indexes into the subTx's guard set's list-view.
24+
-->
3825

3926
<!--
4027
```agda
@@ -66,32 +53,11 @@ getDatum tx utxoSpend₀ (Spend txin) =
6653
case d of λ where
6754
(inj₁ d) → just d
6855
(inj₂ h) → lookupᵐ? (setToMap (mapˢ < hash , id > (DataOf tx))) h
69-
getDatum tx utxo _ = nothing
56+
getDatum tx utxoSpend₀ _ = nothing
7057
```
7158
-->
7259

7360
```agda
74-
mutual
75-
record TxInfo : Type where
76-
inductive
77-
field
78-
realizedInputs : UTxO
79-
txOuts : Ix ⇀ TxOut
80-
txFee : Maybe Fees
81-
mint : Value
82-
txCerts : List DCert
83-
txWithdrawals : Withdrawals
84-
txVldt : Maybe Slot × Maybe Slot
85-
vkKey : ℙ KeyHash -- native/phase-1/timelock signers
86-
txGuards : ℙ Credential -- CIP-0112/0118 guards (required by tx body)
87-
txData : ℙ Datum
88-
txId : TxId
89-
txInfoSubTxs : Maybe (List SubTxInfo)
90-
91-
SubTxInfo : Type
92-
SubTxInfo = TxInfo
93-
94-
9561
txInfo : (ℓ : TxLevel) → UTxO → Tx ℓ → TxInfo
9662
9763
txInfo TxLevelTop utxo tx =
@@ -125,7 +91,7 @@ txInfo TxLevelSub utxo tx =
12591
} where open Tx tx
12692
12793
txInfoForPurpose : (ℓ : TxLevel) → UTxO → Tx ℓ → ScriptPurpose → TxInfo
128-
-- SubTx scripts never get subTx infos (even if their ScriptPurpose is Guard).
94+
-- SubTx validation never populates txInfoSubTxs, regardless of purpose.
12995
txInfoForPurpose TxLevelSub utxo tx sp = txInfo TxLevelSub utxo tx
13096
-- Top-level scripts:
13197
-- - guard scripts see txInfoSubTxs
@@ -145,15 +111,13 @@ txInfoForPurpose TxLevelTop utxo tx sp with sp
145111
<!--
146112
```agda
147113
credsNeededMinusCollateral : {ℓ : TxLevel} → TxBody ℓ → ℙ (ScriptPurpose × Credential)
148-
credsNeededMinusCollateral txb = a ∪ b ∪ c ∪ d ∪ e
149-
where
150-
a b c d e : ℙ (ScriptPurpose × Credential)
151-
a = mapˢ (λ a → (Rwrd a , CredentialOf a)) (dom ∣ WithdrawalsOf txb ∣)
152-
b = mapPartial (λ c → (Cert c ,_) <$> cwitness c) (fromList (DCertsOf txb))
153-
c = mapˢ (λ x → (Mint x , ScriptObj x)) (policies (ValueOf txb))
154-
d = mapPartial (λ v → if isGovVoterCredential v then (λ {c} → just (Vote v , c)) else nothing)
114+
credsNeededMinusCollateral txb =
115+
mapˢ (λ a → (Rwrd a , CredentialOf a)) (dom ∣ WithdrawalsOf txb ∣)
116+
∪ mapPartial (λ c → (Cert c ,_) <$> cwitness c) (fromList (DCertsOf txb))
117+
∪ mapˢ (λ x → (Mint x , ScriptObj x)) (policies (ValueOf txb))
118+
∪ mapPartial (λ v → if isGovVoterCredential v then (λ {c} → just (Vote v , c)) else nothing)
155119
(fromList (map GovVoterOf (GovVotesOf txb)))
156-
e = mapPartial (λ p → if PolicyOf p then (λ {sh} → just (Propose p , ScriptObj sh)) else nothing)
120+
mapPartial (λ p → if PolicyOf p then (λ {sh} → just (Propose p , ScriptObj sh)) else nothing)
157121
(fromList (GovProposalsOf txb))
158122
159123
credsNeeded : (ℓ : TxLevel) → UTxO → (TxBody ℓ) → ℙ (ScriptPurpose × Credential)
@@ -165,9 +129,6 @@ credsNeeded TxLevelSub utxo txb = credsNeededMinusCollateral txb
165129
∪ mapˢ (λ (i , o) → (Spend i , payCred (proj₁ o))) ((utxo ∣ txIns) ˢ)
166130
where open TxBody txb
167131
168-
--valContext : TxInfo → ScriptPurpose → Data
169-
--valContext txinfo sp = toData (txinfo , sp)
170-
171132
txOutToDataHash : TxOut → Maybe DataHash
172133
txOutToDataHash (_ , _ , d , _) = d >>= isInj₂
173134
@@ -176,27 +137,30 @@ txOutToP2Script utxoSpend₀ utxoRefView tx (a , _) =
176137
do sh ← isScriptObj (payCred a)
177138
s ← lookupScriptHash sh tx utxoSpend₀ utxoRefView
178139
toP2Script s
179-
-- opaque
180-
-- collectP2ScriptsWithContext
181-
-- : PParams → (Tx ℓ) → UTxO
182-
-- → List (P2Script × List Data × ExUnits × CostModel)
183-
-- collectP2ScriptsWithContext pp tx utxo
184-
-- = setToList
185-
-- $ mapPartial (λ (sp , c) → if isScriptObj c
186-
-- then (λ {sh} → toScriptInput sp sh)
187-
-- else nothing)
188-
-- $ credsNeeded utxo (TxBodyOf tx)
189-
-- where
190-
-- toScriptInput
191-
-- : ScriptPurpose → ScriptHash
192-
-- → Maybe (P2Script × List Data × ExUnits × CostModel)
193-
-- toScriptInput sp sh =
194-
-- do s ← lookupScriptHash sh tx utxo
195-
-- p2s ← toP2Script s
196-
-- (rdmr , exunits) ← indexedRdmrs tx sp
197-
-- let data' = maybe [_] [] (getDatum tx utxo sp) ++ rdmr ∷ [ valContext (txInfo (language p2s) pp utxo tx) sp ]
198-
-- costModel = PParams.costmdls pp
199-
-- just (p2s , data' , exunits , costModel)
140+
141+
opaque
142+
collectP2ScriptsWithContext
143+
: {ℓ : TxLevel} → PParams → (Tx ℓ) → UTxO → UTxO
144+
→ List (P2Script × List Data × ExUnits × CostModel)
145+
collectP2ScriptsWithContext {ℓ} pp tx utxoSpend₀ utxoRefView
146+
= setToList $ mapPartial ( λ (sp , c) → if isScriptObj c
147+
then (λ {sh} → toScriptInput sp sh)
148+
else nothing )
149+
$ credsNeeded ℓ utxoSpend₀ (TxBodyOf tx)
150+
-- use initial utxo snapshot ^^here^^ to inspect `txIns` (collateral spend side)
151+
where
152+
toScriptInput
153+
: ScriptPurpose → ScriptHash
154+
→ Maybe (P2Script × List Data × ExUnits × CostModel)
155+
toScriptInput sp sh =
156+
do s ← lookupScriptHash sh tx utxoSpend₀ utxoRefView
157+
p2s ← toP2Script s
158+
(rdmr , exunits) ← indexedRdmrs tx sp
159+
let data' = maybe [_] [] (getDatum tx utxoSpend₀ sp)
160+
++ rdmr ∷ [ valContext (txInfoForPurpose ℓ utxoSpend₀ tx sp) sp ]
161+
-- use initial utxo snapshot ^^here^^ so spending
162+
-- inputs/realized inputs don't see prefix outputs
163+
just (p2s , data' , exunits , PParams.costmdls pp)
200164
201165
evalP2Scripts : List (P2Script × List Data × ExUnits × CostModel) → Bool
202166
evalP2Scripts = all (λ (s , d , eu , cm) → runPLCScript cm s eu d)

0 commit comments

Comments
 (0)