module Peras.Block where
PartyId = Nat
record Party : Set where constructor MkParty field pid : PartyId pkey : VerificationKey open Party public instance iPartyEq : Eq Party iPartyEq ._==_ x y = pid x == pid y && pkey x == pkey y
data Honesty : PartyId → Set where Honest : ∀ {p : PartyId} → Honesty p Corrupt : ∀ {p : PartyId} → Honesty p
PartyTup = ∃[ p ] (Honesty p) Parties = List PartyTup
Tx = ⊤
In addition to a Praos block, there is an optional field for the
included certificate. Note: What we name
Block
is actually a block Header, we use
BlockBody
to contain the payload.
A Peras Certificate represents an aggregated quorum of votes for a specific block at a specific round. Such a certificate is supposed to be self-contained and verifiable by any node.
record Block : Set record BlockBody : Set record Certificate : Set Payload = List Tx record Certificate where constructor MkCertificate pattern field round : RoundNumber blockRef : Hash Block roundNumber : Nat roundNumber = getRoundNumber round open Certificate public latestCert : Certificate → List Certificate → Certificate latestCert c = maximumBy c (comparing round) record Block where constructor MkBlock field slotNumber : SlotNumber creatorId : PartyId parentBlock : Hash Block certificate : Maybe Certificate leadershipProof : LeadershipProof signature : Signature bodyHash : Hash Payload slotNumber' : Nat slotNumber' = getSlotNumber slotNumber open Block public record BlockBody where constructor MkBlockBody field blockHash : Hash Payload payload : Payload open BlockBody public
instance iCertificateEq : Eq Certificate iCertificateEq ._==_ x y = round x == round y && blockRef x == blockRef y eqCertificate-sound : ∀ {c₁ c₂ : Certificate} → (c₁ == c₂) ≡ True → c₁ ≡ c₂ eqCertificate-sound {MkCertificate round₁ blockRef₁} {MkCertificate round₂ blockRef₂} x = let l = &&-leftTrue (getRoundNumber round₁ == getRoundNumber round₂) _ x r = &&-rightTrue _ (eqBS (hashBytes blockRef₁) (hashBytes blockRef₂)) x in cong₂ MkCertificate (cong MkRoundNumber (eqℕ-sound l)) (MkHash-inj (lem-eqBS r)) where eqℕ-sound : {n m : Nat} → (n == m) ≡ True → n ≡ m eqℕ-sound {zero} {zero} _ = refl eqℕ-sound {suc n} {suc m} prf = cong suc (eqℕ-sound prf) instance iBlockEq : Eq Block iBlockEq ._==_ x y = slotNumber x == slotNumber y && creatorId x == creatorId y && parentBlock x == parentBlock y && leadershipProof x == leadershipProof y && certificate x == certificate y && signature x == signature y && bodyHash x == bodyHash y -- FIXME: In principle, we only need to check equality of the signatures. instance iBlockBodyEq : Eq BlockBody iBlockBodyEq ._==_ x y = blockHash x == blockHash y && payload x == payload y module _ {a : Set} ⦃ _ : Hashable a ⦄ where open Hashable ⦃...⦄ tipHash : List a → Hash a tipHash [] = MkHash emptyBS tipHash (x ∷ _) = hash x private open Hashable instance hashBlock : Hashable Block hashBlock .hash = MkHash ∘ bytesS ∘ signature {-# COMPILE AGDA2HS tipHash #-} {-# COMPILE AGDA2HS iCertificateEq #-} {-# COMPILE AGDA2HS iBlockEq #-} {-# COMPILE AGDA2HS iBlockBodyEq #-} {-# COMPILE AGDA2HS hashBlock #-}