Source code on Githubopen import Data.List.Membership.Propositional.Properties using (∈-map⁻; ∈-map⁺; ∈-filter⁻)
open import Prelude.Init hiding (_∋_)
open import Prelude.General
open import Prelude.Lists
open import Prelude.DecEq
open import Prelude.ToN
open import Prelude.Membership
open import UTxO.Hashing
open import UTxO.Value
open import UTxO.Types hiding (I)
open import UTxO.TxUtilities
open import UTxO.Validity
open import StateMachine.Base
open InputInfo
module Bisimulation.Base
{S I : Set} {{_ : IsData S}} {{_ : IsData I}} {sm : StateMachine S I}
where
open CEM {sm = sm}
_—→[_]_ : S → I → (S × TxConstraints) → Set
s —→[ i ] (s′ , tx≡) = stepₛₘ s i ≡ just (s′ , tx≡)
infix 30 _—→[_∶-_]_
_—→[_∶-_]_ : ∀ {l} → ValidLedger l → (tx : Tx) → IsValidTx tx l → ValidLedger (tx ∷ l) → Set
vl —→[ tx ∶- vtx ] vl′ = vl′ ≡ vl ⊕ tx ∶- vtx
_~_ : ∀ {l} → ValidLedger l → S → Set
_~_ {l} _ s = (toData s) ♯ᵈ ∈ ( map (datumHash ∘ out)
∘ filter ((_≟ true) ∘ (_≥ᶜ threadₛₘ) ∘ value ∘ out)
∘ filter ((𝕍 ≟_) ∘ address ∘ out)
) (utxo l)
view-~ : ∀ {l} {s : S} {vl : ValidLedger l}
→ vl ~ s
→ ∃ λ prevTx → ∃ λ v → Σ (s —→ v ∈ outputs prevTx) λ prevOut∈ →
let
oRef = (prevTx ♯ₜₓ) indexed-at toℕ (L.Any.index prevOut∈)
out = record { address = 𝕍; datumHash = toData s ♯ᵈ; value = v }
u = record { prevTx = prevTx; out = out; outRef = oRef }
in ( u ∈ utxo l
× prevTx ∈ l
× oRef ∈ map outRef (utxo l)
× (getSpentOutputRef l oRef ≡ just out)
× ((v ≥ᶜ threadₛₘ) ≡ true)
)
view-~ {l} {s} vl~s
with ∈-map⁻ (datumHash ∘ out) vl~s
... | u@(record {prevTx = prevTx; out = record {value = v}}) , out∈ , refl
with ∈-filter⁻ ((_≟ true) ∘ (_≥ᶜ threadₛₘ) ∘ value ∘ out) {xs = filter _ (utxo l)} out∈
... | u∈′ , threadToken≡
with ∈-filter⁻ ((𝕍 ≟_) ∘ address ∘ out) {xs = utxo l} u∈′
... | u∈ , refl
with ∈utxo⇒outRef≡ {u = u} {l = l} u∈
... | prev∈ , prevOut∈ , refl
= prevTx , v , prevOut∈ , u∈ , prev∈ , ∈-map⁺ outRef u∈ , spent≡ , threadToken≡
where
oRef = (prevTx ♯ₜₓ) indexed-at toℕ (L.Any.index prevOut∈)
o = record { address = 𝕍; datumHash = toData s ♯ᵈ; value = v }
u′ = record { prevTx = prevTx; out = o; outRef = oRef }
spent≡ : getSpentOutputRef l oRef ≡ just o
spent≡ = utxo-getSpent {l = l} {u = u′} u∈
Satisfiable : ∀ {s l} {vl : ValidLedger l}
→ TxConstraints
→ vl ~ s
→ Set
Satisfiable {l = l} {vl} tx≡ vl~s
with view-~ {vl = vl} vl~s
... | _ , v , _
= (range≡ tx≡ >>=ₜ (_∋ length l) ≡ true)
× (spent≥ tx≡ >>=ₜ (v ≥ᶜ_) ≡ true)
× (∀ tx →
All {A = MonetaryPolicy}
(λ f → T (f (toPendingMPS l tx (f ♯))))
(maybe (map proj₁) [] (forge≡ tx≡)))
mkTx : ∀ {l} {s s′ : S} {i : I} {vl : ValidLedger l} {vl~s : vl ~ s}
→ (tx≡ : TxConstraints)
→ Satisfiable {vl = vl} tx≡ vl~s
→ Σ[ tx ∈ Tx ] (verifyTx l tx tx≡ ≡ true)
mkTx {l} {s} {s′} {i} {vl} {vl~s} tx≡ (r≡ , s≥ , _)
with view-~ {vl = vl} vl~s
... | prevTx , v , prevOut∈ , _ , _ , _ , getSpent≡ , _
= tx , verify≡
where
frg = maybe toValue $0 (forge≡ tx≡)
rng = M.fromMaybe (-∞ ⋯ +∞) (range≡ tx≡)
plc = maybe (map proj₁) [] (forge≡ tx≡)
i₀ = (prevTx ♯ₜₓ) indexed-at toℕ (L.Any.index prevOut∈) ←— (i , s)
tx = record { inputs = [ i₀ ]
; outputs = [ s′ —→ (frg +ᶜ v) ]
; policies = plc
; forge = frg
; range = rng
; datumWitnesses = [ toData s′ ♯ᵈ , toData s′ ] }
txi = mkTxInfo l tx
frgT : (forge≡ tx≡ >>=ₜ λ v → ⌊ TxInfo.forge txi ≟ toValue v ⌋) ≡ true
frgT with forge≡ tx≡
... | nothing = refl
... | just v rewrite ≟-refl (toValue v) = refl
rngT : (range≡ tx≡ >>=ₜ λ r → ⌊ TxInfo.range txi ≟ r ⌋) ≡ true
rngT with range≡ tx≡
... | nothing = refl
... | just v rewrite ≟-refl v = refl
v≡ : valueSpent txi ≡ v
v≡ rewrite sum-single {v = InputInfo.value (mkInputInfo l i₀)}
| getSpent≡
= refl
spT : (spent≥ tx≡ >>=ₜ (valueSpent txi ≥ᶜ_)) ≡ true
spT rewrite v≡ = s≥
verify≡ : verifyTx l tx tx≡ ≡ true
verify≡ rewrite frgT | rngT | spT = refl