Skip to content

Commit

Permalink
Merge branch 'master' into william/367-ga-deps-match-propls
Browse files Browse the repository at this point in the history
  • Loading branch information
williamdemeo committed Apr 27, 2024
2 parents 4a5abc2 + ed315b0 commit 1b29fc3
Show file tree
Hide file tree
Showing 6 changed files with 254 additions and 24 deletions.
8 changes: 5 additions & 3 deletions src/Axiom/Set/Map/Dec.agda
Expand Up @@ -17,6 +17,8 @@ open import Axiom.Set.Rel th using (dom; dom∈)
open import Axiom.Set.Map th
open import Data.Product.Properties using (×-≡,≡→≡; ×-≡,≡←≡)

open import Interface.IsCommutativeMonoid

open Equivalence

private variable A B C D : Type
Expand Down Expand Up @@ -50,12 +52,12 @@ module Lookupᵐᵈ (sp-∈ : spec-∈ A) where
helper _ _ | _ , _ , refl | _ , _ , refl | yes _ | yes _
with refl trans (sym eq) eq' = refl

module _ ⦃ M : Monoid 0ℓ 0ℓ ⦄ ⦃ _ : DecEq A ⦄ where
module _ {V : Type} ⦃ mon : IsCommutativeMonoid' 0ℓ 0ℓ V ⦄ ⦃ _ : DecEq A ⦄ where
infixr 6 _∪⁺_
open Monoid M renaming (Carrier to V)
open IsCommutativeMonoid' mon

_∪⁺_ : Map A V Map A V Map A V
_∪⁺_ = unionWith (fold id id __)
_∪⁺_ = unionWith (fold id id __)

aggregate₊ : FinSet (A × V) Map A V
aggregate₊ (_ , l , _) = foldl (λ m x m ∪⁺ ❴ x ❵ᵐ) ∅ᵐ l
Expand Down
30 changes: 29 additions & 1 deletion src/Ledger/Gov.lagda
Expand Up @@ -118,10 +118,38 @@ enactable e aidPairs = λ (aidNew , as) → case getHashES e (GovActionState.act

allEnactable : EnactState → GovState → Set
allEnactable e aid×states = All (enactable e (getAidPairsList aid×states)) aid×states

hasParentE : EnactState → GovActionID → GovAction → Set
hasParentE e aid a = case getHashES e a of λ where
nothing → ⊤
(just id) → id ≡ aid

hasParent : EnactState → GovState → (a : GovAction) → NeedsHash a → Set
hasParent e s a aid with getHash aid
... | just aid' = hasParentE e aid' a ⊎ Any (λ x → proj₁ x ≡ aid') s
... | nothing = ⊤
\end{code}
\begin{code}[hide]
open Equivalence

hasParentE? : ∀ e aid a → Dec (hasParentE e aid a)
hasParentE? e aid a with getHashES e a
... | nothing = yes _
... | (just id) = id ≟ aid

hasParent? : ∀ e s a aid → Dec (hasParent e s a aid)
hasParent? e s a aid with getHash aid
... | just aid' = hasParentE? e aid' a ⊎-dec any? (λ x → proj₁ x ≟ aid') s
... | nothing = yes tt

-- newtype to make the instance resolution work
data hasParent' : EnactState → GovState → (a : GovAction) → NeedsHash a → Set where
HasParent' : ∀ {x y z w} → hasParent x y z w → hasParent' x y z w

instance
hasParent?' : ∀ {x y z w} → hasParent' x y z w ⁇
hasParent?' = ⁇ map′ HasParent' (λ where (HasParent' x) → x) (hasParent? _ _ _ _)

[_connects_to_?] : ∀ l aidNew aidOld → Dec (l connects aidNew to aidOld)
[ [] connects aidNew to aidOld ?] = aidNew ≟ aidOld

Expand Down Expand Up @@ -226,7 +254,7 @@ data _⊢_⇀⦇_,GOV'⦈_ where
∙ (∀ {new rem q} → a ≡ NewCommittee new rem q
→ ∀[ e ∈ range new ] epoch < e × dom new ∩ rem ≡ᵉ ∅)
∙ validHFAction prop s enactState
allEnactable enactState s'
hasParent enactState s a prev
───────────────────────────────────────
(Γ , k) ⊢ s ⇀⦇ inj₂ prop ,GOV'⦈ s'

Expand Down
12 changes: 6 additions & 6 deletions src/Ledger/Gov/Properties.agda
Expand Up @@ -125,23 +125,23 @@ instance
× d ≡ govActionDeposit
× validHFAction prop s enactState
× (∃[ u ] a ≡ ChangePParams u ⊎ ∃[ w ] a ≡ TreasuryWdrl w p ≡ ppolicy)
× allEnactable' enactState (addAction s (govActionLifetime +ᵉ epoch) (txid , k) addr a prev) ¿
× hasParent' enactState s a prev ¿
,′ isNewCommittee a

computeProof = case H of λ where
(yes (wf , dep , vHFA , pol , AllEnactable' en) , yes (new , rem , q , refl))
(yes (wf , dep , vHFA , pol , HasParent' en) , yes (new , rem , q , refl))
case ¿ ∀[ e ∈ range new ] epoch < e × dom new ∩ rem ≡ᵉ ∅ ¿ of λ where
(yes newOk) success (_ , GOV-Propose (wf , dep , pol , (λ where refl newOk) , vHFA , en))
(no ¬p) failure (genErrors ¬p)
(yes (wf , dep , vHFA , pol , AllEnactable' en) , no notNewComm) success
(yes (wf , dep , vHFA , pol , HasParent' en) , no notNewComm) success
(-, GOV-Propose (wf , dep , pol , (λ isNewComm ⊥-elim (notNewComm (-, -, -, isNewComm))) , vHFA , en))
(no ¬p , _) failure (genErrors ¬p)

completeness : s' Γ ⊢ s ⇀⦇ inj₂ prop ,GOV'⦈ s' map proj₁ computeProof ≡ success s'
completeness s' (GOV-Propose (wf , dep , pol , newOk , vHFA , en)) with H
... | (no ¬p , _) = ⊥-elim (¬p (wf , dep , vHFA , pol , AllEnactable' en))
... | (yes (_ , _ , _ , _ , AllEnactable' _) , no notNewComm) = refl
... | (yes (_ , _ , _ , _ , AllEnactable' _) , yes (new , rem , q , refl))
... | (no ¬p , _) = ⊥-elim (¬p (wf , dep , vHFA , pol , HasParent' en))
... | (yes (_ , _ , _ , _ , HasParent' _) , no notNewComm) = refl
... | (yes (_ , _ , _ , _ , HasParent' _) , yes (new , rem , q , refl))
rewrite dec-yes ¿ ∀[ e ∈ range new ] epoch < e × dom new ∩ rem ≡ᵉ ∅ ¿ (newOk refl) .proj₂ = refl

computeProof : (sig : GovVote ⊎ GovProposal) _
Expand Down
2 changes: 2 additions & 0 deletions src/Ledger/PDF.lagda
Expand Up @@ -56,6 +56,8 @@ open import Ledger.Ratify

open import Ledger.Chain

open import Ledger.Properties

open import Ledger.EssentialAgda
open import Ledger.PDF.ConwayBootstrapEnact
\end{code}
Expand Down
183 changes: 183 additions & 0 deletions src/Ledger/Properties.agda
@@ -0,0 +1,183 @@
{-# OPTIONS --safe #-}

open import Ledger.Prelude
open import Ledger.Abstract
open import Ledger.Transaction

module Ledger.Properties
(txs : _) (open TransactionStructure txs)
(abs : AbstractFunctions txs) (open AbstractFunctions abs)
where

open import Ledger.Chain txs abs
open import Ledger.Utxo txs abs
open import Ledger.Epoch txs abs
open import Ledger.Ledger txs abs
open import Ledger.Enact govStructure
open import Ledger.Gov txs

isCredDeposit : DepositPurpose Set
isCredDeposit (CredentialDeposit x) =
isCredDeposit _ =

instance
isCredDeposit? : isCredDeposit ⁇¹
isCredDeposit? {CredentialDeposit x} = ⁇ (yes tt)
isCredDeposit? {PoolDeposit x} = ⁇ (no λ ())
isCredDeposit? {DRepDeposit x} = ⁇ (no λ ())
isCredDeposit? {GovActionDeposit x} = ⁇ (no λ ())

isGADeposit : DepositPurpose Set
isGADeposit (GovActionDeposit x) =
isGADeposit _ =

instance
isGADeposit? : isGADeposit ⁇¹
isGADeposit? {CredentialDeposit x} = ⁇ (no λ ())
isGADeposit? {PoolDeposit x} = ⁇ (no λ ())
isGADeposit? {DRepDeposit x} = ⁇ (no λ ())
isGADeposit? {GovActionDeposit x} = ⁇ (yes tt)

getLState : NewEpochState LState
getLState = EpochState.ls ∘ NewEpochState.epochState

getRewards : NewEpochState Credential ⇀ Coin
getRewards = DState.rewards ∘ CertState.dState ∘ LState.certState ∘ getLState

allDReps : NewEpochState Credential ⇀ Epoch
allDReps = GState.dreps ∘ CertState.gState ∘ LState.certState ∘ getLState

activeDReps : Epoch NewEpochState ℙ Credential
activeDReps currentEpoch s = dom (filterᵐ (λ (_ , e) currentEpoch ≤ e) (allDReps s))

getGovState : NewEpochState GovState
getGovState = LState.govSt ∘ getLState

instance
_ : IsSet Block Tx
_ = record { toSet = fromList ∘ Block.ts }

_ : IsSet TxBody GovProposal
_ = record { toSet = fromList ∘ TxBody.txprop }

validBlockIn : ChainState Block Set
validBlockIn s b = ∃[ s' ] _ ⊢ s ⇀⦇ b ,CHAIN⦈ s'

validBlock : Block Set
validBlock b = ∃[ s ] validBlockIn s b

-- Transaction validity is complicated. In the truest sense, a
-- transaction is valid if it is part of a valid block,
-- i.e. `validTxIn₁`. However, a transaction can also be seen as valid
-- if it could be applied at a certain slot (with no knowledge of an
-- actual block). This is closer to how the mempool sees transaction
-- validity and is expressed by `validTxIn₂`.

-- Note that these two are not equivalent and in fact there is no
-- implication between the two in either direction. `2 => 1` would
-- require one to come up with a block, which we can't, but `1 => 2`
-- is also not true, since the transaction might depend on a previous
-- transaction in the same block. Maybe this means that `validTxIn₂`
-- should be changed so that it allows for applying a list of
-- transactions before the final transaction? However, the downside
-- then becomes that the transaction isn't applied to the given state
-- but to some intermediate one. Maybe we'll gain some insight on this
-- matter once we have proven more theorems.

validTxIn₁ : ChainState Tx Set
validTxIn₁ s tx = ∃[ b ] tx ∈ b × validBlockIn s b

module _ (s : ChainState) (slot : Slot) where

open ChainState s; open NewEpochState newEpochState
open EpochState epochState; open EnactState es

private
ledgerEnv = ⟦ slot , constitution .proj₁ .proj₂ , pparams .proj₁ , es ⟧ˡᵉ

validTxIn₂ : Tx Set
validTxIn₂ tx = ∃[ ls' ] ledgerEnv ⊢ ls ⇀⦇ tx ,LEDGER⦈ ls'

validTx₁ : Tx Set
validTx₁ tx = ∃[ s ] validTxIn₁ s tx

ChainInvariant : {a} (ChainState Set a) Set a
ChainInvariant P = b s s' _ ⊢ s ⇀⦇ b ,CHAIN⦈ s' P s P s'

module _ (s : ChainState) where
open ChainState s; open NewEpochState newEpochState; open EpochState epochState
open LState ls
open EnactState es renaming (pparams to pparams')
open CertState certState; open DState dState
pparams = pparams' .proj₁
open PParams pparams
open Tx; open TxBody

-- Transaction properties

module _ {slot} {tx} (let txb = body tx) (valid : validTxIn₂ s slot tx)
(indexedSum-∪⁺-hom : {A V : Set} ⦃ _ : DecEq A ⦄ ⦃ _ : DecEq V ⦄ ⦃ mon : IsCommutativeMonoid' 0ℓ 0ℓ V ⦄
(d₁ d₂ : A ⇀ V) indexedSumᵛ' id (d₁ ∪⁺ d₂) ≡ indexedSumᵛ' id d₁ ◇ indexedSumᵛ' id d₂)
(indexedSum-⊆ : {A : Set} ⦃ _ : DecEq A ⦄ (d d' : A ⇀ ℕ) d ˢ ⊆ d' ˢ
indexedSumᵛ' id d ≤ indexedSumᵛ' id d') -- technically we could use an ordered monoid instead of ℕ
where
open import Ledger.Utxow txs abs
open import Ledger.Utxo.Properties txs abs

propose-minSpend : noRefundCert (txcerts txb)
coin (consumed pparams utxoSt txb) ≥ length (txprop txb) * govActionDeposit
propose-minSpend noRef = case valid of λ where
(_ , LEDGER-V (_ , (UTXOW-inductive⋯ _ _ _ _ _ _ _ x) , _ , _))
gmsc {indexedSum-∪⁺-hom} {indexedSum-⊆} x noRef
(_ , LEDGER-I (_ , (UTXOW-inductive⋯ _ _ _ _ _ _ _ x)))
gmsc {indexedSum-∪⁺-hom} {indexedSum-⊆} x noRef

-- propose-ChangePP-hasGroup : {up prop}
-- → prop ∈ txb → prop .GovProposal.action ≡ ChangePParams up → updateGroups up ≢ ∅
-- propose-ChangePP-hasGroup = {!!}

-- Block properties

module _ {b} (valid : validBlockIn s b) (let open Block b) where
isNewEpochBlock : Set
isNewEpochBlock = epoch slot ≡ sucᵉ lastEpoch

newChainState : ChainState
newChainState = proj₁ valid

getEnactState : ChainState EnactState
getEnactState = EpochState.es ∘ NewEpochState.epochState ∘ ChainState.newEpochState

-- enact-change⇒newEpoch : es ≢ getEnactState newChainState isNewEpochBlock
-- enact-change⇒newEpoch = {!!}

-- Invariant properties

action-deposits≡actions-prop : Set
action-deposits≡actions-prop = filterˢ isGADeposit (dom (UTxOState.deposits utxoSt))
≡ fromList (map (λ where (id , _) GovActionDeposit id) govSt)

dom-rwds≡credDeposits : Set
dom-rwds≡credDeposits = filterˢ isCredDeposit (dom (UTxOState.deposits utxoSt))
≡ mapˢ CredentialDeposit (dom rewards)

pp-wellFormed : Set
pp-wellFormed = paramsWellFormed pparams

-- action-deposits≡actions-inv : ChainInvariant action-deposits≡actions-prop
-- action-deposits≡actions-inv = {!!}

-- dom-rwds≡credDeposits-inv : ChainInvariant dom-rwds≡credDeposits
-- dom-rwds≡credDeposits-inv = {!!}

-- pp-wellFormed-inv : ChainInvariant pp-wellFormed
-- pp-wellFormed-inv = {!!}

-- Epoch boundary properties

-- module _ {Γ es e es'} (step : Γ ⊢ es ⇀⦇ e ,NEWEPOCH⦈ es') where
-- dom-rwds-const : dom (getRewards es) ≡ dom (getRewards es')
-- dom-rwds-const = {!!}

-- prop≡∅⇒activeDReps-const : getGovState es ≡ [] → activeDReps e es ≡ᵉ activeDReps (sucᵉ e) es'
-- prop≡∅⇒activeDReps-const = {!!}
43 changes: 29 additions & 14 deletions src/Ledger/Ratify.lagda
Expand Up @@ -301,8 +301,8 @@ restrictedDists coins rank dists = dists
actualVotes : RatifyEnv → PParams → CCData → GovAction
→ (GovRole × Credential ⇀ Vote) → (VDeleg ⇀ Vote)
actualVotes Γ pparams cc ga votes
= mapKeys (credVoter CC) (actualCCVotes cc) ∪ˡ actualPDRepVotes ga
∪ˡ actualDRepVotes ∪ˡ actualSPOVotes ga
= mapKeys (credVoter CC) actualCCVotes ∪ˡ actualPDRepVotes ga
∪ˡ actualDRepVotes ∪ˡ actualSPOVotes ga
where
\end{code}
\begin{code}[hide]
Expand All @@ -317,25 +317,40 @@ actualVotes Γ pparams cc ga votes
activeDReps = dom (filter (λ (_ , e) → currentEpoch ≤ e) dreps)
spos = filterˢ IsSPO (dom (stakeDistr stakeDistrs))

activeCC : CCData → ℙ Credential
activeCC (just (cc , _)) = dom (filter (λ (_ , x) → Is-just x) (ccHotKeys ∣ dom cc))
activeCC nothing = ∅
getCCHotCred : Credential × Epoch → Maybe Credential
getCCHotCred (c , e) = case ¿ currentEpoch ≤ e ¿ᵇ , lookupᵐ? ccHotKeys c of
\end{code}
\begin{code}[hide]
λ where
\end{code}
\begin{code}
(true , just (just c')) → just c'
_ → nothing -- expired, no hot key or resigned

actualCCVote : Credential → Epoch → Vote
actualCCVote c e = case ¿ currentEpoch ≤ e ¿ᵇ , lookupᵐ? ccHotKeys c of
actualCCVote c e = case getCCHotCred (c , e) of
\end{code}
\begin{code}[hide]
λ where
\end{code}
\begin{code}
(just c') → maybe id Vote.no (lookupᵐ? votes (CC , c'))
_ → Vote.abstain

activeCC : (Credential ⇀ Epoch) → ℙ Credential
activeCC m = mapPartial getCCHotCred (m ˢ)

actualCCVotes : Credential ⇀ Vote
actualCCVotes = case cc of
\end{code}
\begin{code}[hide]
λ where
\end{code}
\begin{code}
(true , just (just c')) → maybe id Vote.no (lookupᵐ? votes (CC , c'))
_ → Vote.abstain -- expired, no hot key or resigned

actualCCVotes : CCData → Credential ⇀ Vote
actualCCVotes nothing = ∅
actualCCVotes (just (cc , q)) = if ccMinSize ≤ lengthˢ (activeCC (just (cc , q)))
then mapWithKey actualCCVote cc
else constMap (dom cc) Vote.no
nothing → ∅
(just (m , q)) → if ccMinSize ≤ lengthˢ (activeCC m)
then mapWithKey actualCCVote m
else constMap (dom m) Vote.no

actualPDRepVotes : GovAction → VDeleg ⇀ Vote
actualPDRepVotes NoConfidence
Expand Down

0 comments on commit 1b29fc3

Please sign in to comment.