data Phase : Type where EnteringRound Proposing Receiving AdvancingRound Locking Committing Voting : Phase
Furthermore, the local state stores a database of blocks and votes, an inbox for unread messages, and the current finalized chain.
record LocalState : Type where constructor ⦅_,_,_,_,_,_,_,_,_,_,_⦆ field r-vote : Round -- highest voted round -- r-lock : Round -- highest locked round r-cur : Round -- current round qc-high : QC -- highest quorum certificate tc-last : Maybe TC -- last round timeout certificate phase : Phase -- current phase db : Messages -- list of processed messages inbox : Messages -- messages received, but not yet processed finalChain : Chain -- the most recent committed chain timer : Maybe Time -- (optional) timer to fire timedOut? : Bool -- whether the timer has fired roundAdvanced? : Bool -- whether the round has advanced currentLeader = roundLeader r-cur nextLeader = roundLeader (1 + r-cur) timedOut : Time → Type timedOut t = Any (_≤ t) timerThe initial local state is the empty one:
initLocalState : LocalState initLocalState = record { r-vote = 0 -- ; r-lock = 0 ; r-cur = 1 ; qc-high = qc₀ ; tc-last = nothing ; phase = EnteringRound ; db = [] ; inbox = [] ; finalChain = [] ; timer = nothing ; timedOut? = false ; roundAdvanced? = true }
record Has∈ (A : Type) : Type₁ where field _∙∈_ : A → Messages → Type _∙∉_ = ¬_ ∘₂ _∙∈_ infix 100 _∙∈_ module _ ⦃ _ : _∙∈_ ⁇² ⦄ where _∙∈?_ : Decidable² _∙∈_ _∙∈?_ = dec² open Has∈ ⦃...⦄ public data AllMs {A} ⦃ _ : Has∈ A ⦄ (P : A → Type) (ms : Messages) : Type where mk : (∀ {a} → a ∙∈ ms → P a) → AllMs P ms
{- data _-block-∈-_ : Block → Messages → Type where initialBlock : b ∙blockId ≡ genesisId ────────────────────── b -block-∈- ms proposedBlock : b ∈ allBlocks ms ──────────────── b -block-∈- ms -- In the paper there's no other way of learning about a block. -- inQC : -- ∙ Any (qc qc∈-Message_) ms -- ∙ qc ∙blockId ≡ b ∙blockId -- ─────────────────────────── -- b block-∈ ms instance Has∈-Block = Has∈ Block ∋ λ where ._∙∈_ → _-block-∈-_ -} instance Has∈-Block = Has∈ Block ∋ λ where ._∙∈_ b ms → b ∈ allBlocks ms
We define different Predicates on chains wrt to lists of messages.
qcVoteShares : QC → VoteShares qcVoteShares qc = map (qc .payload signed-by_) (qc .shares)
instance Has∈-VS = Has∈ VoteShare ∋ λ where ._∙∈_ vs ms → Vote vs ∈ ms FormedVS : VoteShares → Messages → Type FormedVS vss ms = All (_∙∈ ms) vss FormedQC : QC → Messages → Type FormedQC qc = FormedVS (qcVoteShares qc) data _-qc-∈-_ (qc : QC) (ms : Messages) : Type where initialQC : qc ≡ qc₀ ──────────── qc -qc-∈- ms formedQC : FormedQC qc ms -- all voteshares come from ms ────────────── qc -qc-∈- ms receivedQC : Any (qc qc∈-Message_) ms ──────────────────────── qc -qc-∈- ms
_-te-∈-_ : TimeoutEvidence → Messages → Type te -te-∈- ms = ∃ λ mtc → Timeout (te , mtc) ∈ ms instance Has∈-TimeoutEvidence = Has∈ TimeoutEvidence ∋ λ where ._∙∈_ → _-te-∈-_ FormedTE : List TimeoutEvidence → Messages → Type FormedTE tes ms = All (_∙∈ ms) tes FormedTC : TC → Messages → Type FormedTC tc = FormedTE (tc .tes) data _-tc-∈-_ (tc : TC) (ms : Messages) : Type where formedTC : FormedTC tc ms ────────────────────── tc -tc-∈- ms receivedTC : Any (tc tc∈-Message_) ms ──────────────────────── tc -tc-∈- ms
data _-highest-qc-∈-_ : QC → Messages → Type where isHighest : ∙ qc ∙∈ ms ∙ (∀ qc′ → qc′ ∙∈ ms → qc′ ≤qc qc) ──────────────────────────────── qc -highest-qc-∈- ms
The following predicate indicates that the chain has been “seen” (i. e. it is in the database).
data _-chain-∈-_ : Chain → Messages → Type where [] : ──────────────────── genesis -chain-∈- ms _∷_⊣_ : ∙ b ∙∈ ms ∙ ch -chain-∈- ms ∙ b -connects-to- ch ───────────────────── (b ∷ ch) -chain-∈- ms -- TODO: refactor to this definition instead -- _-chain-∈-_ : Chain → Messages → Type -- ch -chain-∈- ms = All (_∙∈ ms) ch × ValidChain ch
A block is certified if there exists a qc for that block.
data _-certified-∈-_ (b : Block) (ms : Messages) : Type where certified : -- ∙ b ∙∈ ms ∙ qc ∙∈ ms ∙ qc ∙blockId ≡ b ∙blockId ∙ qc ∙round ≡ b ∙round ──────────────────────── b -certified-∈- ms
data _∶_final-∈_ : Block → Chain → Messages → Type where final∈ : ∙ b -certified-∈- ms ∙ b′ -certified-∈- ms ∙ (b′ ∷ b ∷ ch) ∙∈ ms ∙ b′ ∙round ≡ 1 + b ∙round ──────────────────────── b′ ∶ (b ∷ ch) final-∈ ms _∶_longer-final-∈_ : Block → Chain → LocalState → Type b ∶ ch longer-final-∈ ls = b ∶ ch final-∈ ls .db × length ch > length (ls .finalChain) data _longer-final-∈_ : Block → LocalState → Type where mk : ∀ {ch} → (b ∶ ch longer-final-∈ ls) ────────────────────────── b longer-final-∈ ls
ShouldVote : LocalState → Block → Type ShouldVote ls ⟨ qc , mtc , r , _ {-⊣ _-} ⟩ = r ≡ ls .r-cur × r > ls .r-vote × ( {-(1)-} r ≡ 1 + qc ∙round ⊎ {-(2)-} Any (λ tc → r ≡ 1 + tc ∙round × qc ∙round ≥ highestQC tc ∙round) mtc )
data _-connects-∈-_ (b : Block) (ms : Messages) : Type where mk : ∀ {ch : Chain} → ∙ ch -chain-∈- ms ∙ b -connects-to- ch ────────────────── b -connects-∈- ms ValidProposal : Messages → Block → Type ValidProposal ms b = AllBlock (λ b′ → b ∙round ≢ b′ ∙round) ms × b -connects-∈- ms -- this is also checked by Commit (longer-final-∈) ValidProposal⇒ValidBlock : ValidProposal ms b → ValidBlock b ValidProposal⇒ValidBlock (_ , mk _ (connects∶ _ _ vb)) = vb