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

Eliminate Boolean properties #649

Merged
merged 10 commits into from
Jan 31, 2025
2 changes: 1 addition & 1 deletion src/Ledger/Conway/Conformance/Utxo.agda
Original file line number Diff line number Diff line change
@@ -88,7 +88,7 @@ data _⊢_⇀⦇_,UTXO⦈_ : UTxOEnv → UTxOState → Tx → UTxOState → Type
in
∙ txins ≢ ∅ ∙ txins ∪ refInputs ⊆ dom utxo
∙ txins ∩ refInputs ≡ ∅ ∙ L.inInterval slot txvldt
∙ L.feesOK pp tx utxo ≡ true ∙ L.consumed pp s txb ≡ L.produced pp s txb
∙ L.feesOK pp tx utxo ∙ L.consumed pp s txb ≡ L.produced pp s txb
∙ coin mint ≡ 0 ∙ txsize ≤ maxTxSize pp
∙ L.refScriptsSize utxo tx ≤ pp .maxRefScriptSizePerTx

8 changes: 6 additions & 2 deletions src/Ledger/Transaction.lagda
Original file line number Diff line number Diff line change
@@ -235,8 +235,12 @@ Ingredients of the transaction body introduced in the Conway era are the followi
\end{NoConway}

\begin{code}[hide]
isP2Script : Script → Bool
isP2Script = is-just ∘ isInj₂
isP2Script : Script → Type
isP2Script = From-inj₂

isP2Script? : ∀ {s} → isP2Script s ⁇
isP2Script? {inj₁ x} .dec = true because ofʸ (lift tt)
isP2Script? {inj₂ y} .dec = true because ofʸ y

instance
HasCoin-TxOut : HasCoin TxOut
60 changes: 28 additions & 32 deletions src/Ledger/Utxo.lagda
Original file line number Diff line number Diff line change
@@ -43,14 +43,24 @@ q *↓ n = ℤ.∣ ℚ.⌊ q ℚ.* (ℤ.+ n ℚ./ 1) ⌋ ∣
\begin{NoConway}
\begin{figure*}[h]
\begin{code}
isTwoPhaseScriptAddress : Tx → UTxO → Addr → Bool
isTwoPhaseScriptAddress : Tx → UTxO → Addr → Type
isTwoPhaseScriptAddress tx utxo a =
if isScriptAddr a then
(λ {p} → if lookupScriptHash (getScriptHash a p) tx utxo
then (λ {s} → isP2Script s)
else false)
else )
else
false
\end{code}
\begin{code}[hide]
isTwoPhaseScriptAddress? : ∀ {tx utxo a} → isTwoPhaseScriptAddress tx utxo a ⁇
isTwoPhaseScriptAddress? {tx} {utxo} {a} .dec
with decide (isScriptAddr a)
... | inj₂ _ = false because ofⁿ λ ()
... | inj₁ p
with decide (lookupScriptHash (getScriptHash a p) tx utxo)
... | inj₂ _ = false because ofⁿ λ ()
... | inj₁ s = isP2Script? {s} .dec
\end{code}
\begin{code}[hide]
opaque
@@ -61,8 +71,9 @@ opaque

getInputHashes : Tx → UTxO → ℙ DataHash
getInputHashes tx utxo = getDataHashes
(filterˢ (λ (a , _ ) → isTwoPhaseScriptAddress tx utxo a ≡ true)
(range (utxo ∣ txins)))
(filterˢ (λ (a , _ ) → isTwoPhaseScriptAddress tx utxo a)
⦃ λ {(a , _)} → isTwoPhaseScriptAddress? {tx} {utxo} {a} ⦄
Copy link
Collaborator

Choose a reason for hiding this comment

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

Here we have an interesting problem: this code belongs to the visible section of the PDF and we shouldn't show stuff like that because we'd have to explain what it means (and the meaning isn't particularly interesting). However, marking isTwoPhaseScriptAddress? as an instance isn't a good idea and wouldn't even work anyway.

I think the only reasonable solution here is to turn isTwoPhaseScriptAddress into a data type and then provide a instance for that type. As I see it, there are two options to do that:

  • either completely replace the function with a type whose constructors contain the same logic, or
  • provide a 'newtype' wrapper around isTwoPhaseScriptAddress, i.e. something of this form:
    data isTwoPhaseScriptAddress' : Tx → UTxO → Addr → Type where
      wrap : ∀ {tx utxo a} → isTwoPhaseScriptAddress tx utxo a → isTwoPhaseScriptAddress' tx utxo a
    

The second option has the upside that we can cheat a little and just hide this wrapper behind the curtain when rendering the PDF. We currently don't have the machinery to do that perfectly because we'd have to substitute isTwoPhaseScriptAddress' with isTwoPhaseScriptAddress in the line above when rendering the PDF, but we probably need a mechanism for that anyway. So I'm currently leaning more towards that option.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

How would we go about substituting isTwoPhaseScriptAddress' by its unprimed version in the pdf?

(range (utxo ∣ txins)))
where open Tx; open TxBody (tx .body)

totExUnits : Tx → ExUnits
@@ -377,37 +388,22 @@ instance
+ getCoin (UTxOState.deposits s)
+ UTxOState.donations s

-- Boolean implication
_=>ᵇ_ : Bool → Bool → Bool
a =>ᵇ b = if a then b else true

-- Boolean-valued inequalities on natural numbers
_≤ᵇ_ _≥ᵇ_ : ℕ → ℕ → Bool
m ≤ᵇ n = ¿ m ≤ n ¿ᵇ
_≥ᵇ_ = flip _≤ᵇ_

≟-∅ᵇ : {A : Type} ⦃ _ : DecEq A ⦄ → (X : ℙ A) → Bool
≟-∅ᵇ X = ¿ X ≡ ∅ ¿ᵇ

coinPolicies : ℙ ScriptHash
coinPolicies = policies (inject 1)

isAdaOnlyᵇ : Value → Bool
isAdaOnlyᵇ v = toBool (policies v ≡ᵉ coinPolicies)

-- TODO: this could be a regular property
-- TODO: using this in UTxO rule below
isAdaOnlyᵇ : Value → Type
isAdaOnlyᵇ v = policies v ≡ᵉ coinPolicies
\end{code}
\begin{code}

feesOK : PParams → Tx → UTxO → Bool
feesOK pp tx utxo = ( minfee pp utxo tx ≤ᵇ txfee ∧ not (≟-∅ᵇ (txrdmrs ˢ))
=>ᵇ ( allᵇ (λ (addr , _) → ¿ isVKeyAddr addr ¿) collateralRange
∧ isAdaOnlyᵇ bal
∧ (coin bal * 100) ≥ᵇ (txfee * pp .collateralPercentage)
∧ not (≟-∅ᵇ collateral)
)
)
feesOK : PParams → Tx → UTxO → Type
feesOK pp tx utxo = ( minfee pp utxo tx ≤ txfee × (txrdmrs ˢ ≢ ∅
→ ( All (λ (addr , _) → isVKeyAddr addr) collateralRange
× isAdaOnlyᵇ bal
× coin bal * 100 ≥ txfee * pp .collateralPercentage
× collateral ≢ ∅
)
)
)
where
open Tx tx; open TxBody body; open TxWitnesses wits; open PParams pp
collateralRange = range ((mapValues txOutHash utxo) ∣ collateral)
@@ -538,7 +534,7 @@ data _⊢_⇀⦇_,UTXO⦈_ where
in
∙ txins ≢ ∅ ∙ txins ∪ refInputs ⊆ dom utxo
∙ txins ∩ refInputs ≡ ∅ ∙ inInterval slot txvldt
∙ feesOK pp tx utxo ≡ true ∙ consumed pp s txb ≡ produced pp s txb
∙ feesOK pp tx utxo ∙ consumed pp s txb ≡ produced pp s txb
∙ coin mint ≡ 0 ∙ txsize ≤ maxTxSize pp
∙ refScriptsSize utxo tx ≤ pp .maxRefScriptSizePerTx

2 changes: 1 addition & 1 deletion src/Ledger/Utxo/Properties.lagda
Original file line number Diff line number Diff line change
@@ -92,7 +92,7 @@ instance
(inj₂ b₂') → case dec-de-morgan b₂' of λ where
(inj₁ a₂) → "¬ inInterval (UTxOEnv.slot Γ) (txvldt (Tx.body tx))"
(inj₂ b₂) → case dec-de-morgan b₂ of λ where
(inj₁ a₃) → "¬ feesOK pp tx utxo ≡ true"
(inj₁ a₃) → "¬ feesOK pp tx utxo"
(inj₂ b₃) → case dec-de-morgan b₃ of λ where
(inj₁ a₄) →
let