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 #-}