We can now provide smart constructors for using proof-by-reflection
without calling auto:
mkQC : ∀ (b : Block) pids
→ {_ : auto∶ Unique pids}
→ {_ : auto∶ IsMajority pids}
→ QC
mkQC b sh {x} {y} = record
{ payload = b ∙blockId , b ∙round
; shares = sh
; uniqueShares = toWitness x
; quorum = toWitness y
}
mkTC : ∀ (roundTC : Round) (tes : List TimeoutEvidence)
→ {_ : auto∶ IsMajority tes}
→ {_ : auto∶ Unique (map node tes)}
→ {_ : auto∶ All (λ te → te ∙round ≡ roundTC) tes}
→ {_ : auto∶ All (λ te → te ∙qcTE ∙round < roundTC) tes}
→ TC
mkTC r tes {x} {y} {z} {w} = record
{ roundTC = r
; tes = tes
; quorumTC = toWitness x
; uniqueTC = toWitness y
; allRound = toWitness z
; qcBound = toWitness w
}
module _ {ls : LocalState} (let L = currentLeader ls) p where
≪InitTC? :
{h : auto∶ ls .phase ≡ EnteringRound}
{_ : auto∶ ls .tc-last ≡ just tc}
→ p ⦂ t ⊢ ls — _ —→ _
≪InitTC? {h = x}{y} = InitTC (toWitness x) (toWitness y)
≪InitNoTC? :
{h : auto∶ ls .phase ≡ EnteringRound}
{_ : auto∶ ls .tc-last ≡ nothing}
→ p ⦂ t ⊢ ls — _ —→ _
≪InitNoTC? {h = x}{y} = InitNoTC (toWitness x) (toWitness y)
≪ProposeBlock? : ∀ txn →
let
b = mkBlockForState ls txn
m = Propose $ signData L b
in
{_ : auto∶ ls .phase ≡ Proposing}
{_ : auto∶ p ≡ L}
→ p ⦂ t ⊢ ls —[ m ]—→ propose ls
≪ProposeBlock? _ {x}{y} = ProposeBlock (toWitness x) (toWitness y)
≪ProposeBlockNoOp? :
{h : auto∶ ls .phase ≡ Proposing}
{_ : auto∶ p ≢ L}
→ p ⦂ t ⊢ ls ——→ propose ls
≪ProposeBlockNoOp? {h = x}{y} = ProposeBlockNoOp (toWitness x) (toWitness y)
≪RegisterProposal? : let m = Propose sb; b = sb .datum in
{m∈ : auto∶ m ∈ ls .inbox}
{_ : auto∶ ls .phase ≡ Receiving}
{_ : auto∶ ¬ timedOut ls t}
{_ : auto∶ sb .node ≡ roundLeader (b ∙round)}
{_ : auto∶ ValidProposal (ls .db) b}
→ p ⦂ t ⊢ ls ——→ registerProposal ls (toWitness m∈)
≪RegisterProposal? {m∈ = x}{y}{z}{w}{q} = RegisterProposal
(toWitness x) (toWitness y) (toWitness z) (toWitness w) (toWitness q)
≪RegisterVote? : ∀ (b : Block) p′ →
let
L′ = roundLeader (1 + r)
m = Vote $ signData p′ (b ∙blockId , r)
in
{m∈ : auto∶ m ∈ ls .inbox}
{_ : auto∶ ls .phase ≡ Receiving}
{_ : auto∶ ¬ timedOut ls t}
{_ : auto∶ b ∙∈ ls .db}
{_ : auto∶ m ∉ ls .db}
{_ : auto∶ L′ ≡ p}
→ p ⦂ t ⊢ ls ——→ registerVote ls (toWitness m∈)
≪RegisterVote? _ _ {x}{y}{z}{w}{q}{k} =
RegisterVote (toWitness x) (toWitness y) (toWitness z) (toWitness w)
(toWitness q) (toWitness k)
≪RegisterTimeout? : ∀ tm → let m = Timeout tm in
{m∈ : auto∶ m ∈ ls .inbox}
{_ : auto∶ ls .phase ≡ Receiving}
{_ : auto∶ ¬ timedOut ls t}
{_ : auto∶ m ∉ ls .db}
→ p ⦂ t ⊢ ls ——→ registerTimeout ls (toWitness m∈)
≪RegisterTimeout? _ {x}{y}{z}{w} =
RegisterTimeout (toWitness x) (toWitness y) (toWitness z) (toWitness w)
≪RegisterTC? : let m = TCFormed tc in
{m∈ : auto∶ m ∈ ls .inbox}
{_ : auto∶ ls .phase ≡ Receiving}
{_ : auto∶ ¬ timedOut ls t}
{_ : auto∶ m ∉ ls .db}
→ p ⦂ t ⊢ ls ——→ registerTimeout ls (toWitness m∈)
≪RegisterTC? {m∈ = x}{y}{z}{w} =
RegisterTC (toWitness x) (toWitness y) (toWitness z) (toWitness w)
≪EnoughTimeouts? : ∀ r →
let
m = Timeout $ signData p (ls .r-cur , ls .qc-high) , ls .tc-last
tms = filter (IsTimeoutForRound? r) (ls .db)
in
{_ : auto∶ ls .phase ≡ Receiving}
{_ : auto∶ ¬ timedOut ls t}
{_ : auto∶ IncludesHonest tms}
{_ : auto∶ r ≥ ls .r-cur}
→ p ⦂ t ⊢ ls —[ m ]—→ recordTimeout ls
≪EnoughTimeouts? _ {x}{y}{z}{w} =
EnoughTimeouts (toWitness x) (toWitness y) (toWitness z) (toWitness w)
≪TimerExpired? : let m = Timeout _ in
{h : auto∶ ls .phase ≡ Receiving}
{_ : auto∶ timedOut ls t}
→ p ⦂ t ⊢ ls —[ m ]—→ recordTimeout ls
≪TimerExpired? {h = x}{y} = TimerExpired (toWitness x) (toWitness y)
≪AdvanceRoundQC? : ∀ qc →
{_ : auto∶ ls .phase ≡ AdvancingRound}
{_ : auto∶ qc ∙∈ ls .db}
{_ : auto∶ qc ∙round ≥ ls .r-cur}
→ p ⦂ t ⊢ ls ——→ advanceRound (inj₁ qc) ls
≪AdvanceRoundQC? _ {x}{y}{z} =
AdvanceRoundQC (toWitness x) (toWitness y) (toWitness z)
≪AdvanceRoundTC? : ∀ tc →
{_ : auto∶ ls .phase ≡ AdvancingRound}
{_ : auto∶ tc ∙∈ ls .db}
{_ : auto∶ tc ∙round ≥ ls .r-cur}
→ p ⦂ t ⊢ ls ——→ advanceRound (inj₂ tc) ls
≪AdvanceRoundTC? _ {x}{y}{z} =
AdvanceRoundTC (toWitness x) (toWitness y) (toWitness z)
≪AdvanceRoundNoOp? :
{h : auto∶ ls .phase ≡ AdvancingRound}
{_ : auto∶ AllQC (λ qc → qc ∙round < ls .r-cur) (ls .db)}
{_ : auto∶ AllTC (λ tc → tc ∙round < ls .r-cur) (ls .db)}
→ p ⦂ t ⊢ ls ——→ record ls { phase = Locking }
≪AdvanceRoundNoOp? {h = x}{y}{z} =
AdvanceRoundNoOp (toWitness x) (toWitness y) (toWitness z)
≪Lock? :
{h : auto∶ ls .phase ≡ Locking}
{_ : auto∶ qc -highest-qc-∈- ls .db}
→ p ⦂ t ⊢ ls ——→ lock qc ls
≪Lock? {h = x}{y} = Lock (toWitness x) (toWitness y)
≪Commit? : ∀ b ch →
{_ : auto∶ ls .phase ≡ Committing}
{_ : auto∶ b ∶ ch longer-final-∈ ls}
→ p ⦂ t ⊢ ls ——→ commit ch ls
≪Commit? _ _ {x}{y} = Commit (toWitness x) (toWitness y)
≪CommitNoOp? :
{h : auto∶ ls .phase ≡ Committing}
{_ : auto∶ NoBlock (_longer-final-∈ ls) (ls .db)}
→ p ⦂ t ⊢ ls ——→ record ls {phase = Voting}
≪CommitNoOp? {h = x}{y} = CommitNoOp (toWitness x) (toWitness y)
≪VoteBlock? : ∀ b →
let
m = Vote $ signData p (b ∙blockId , b ∙round)
L′ = roundLeader (1 + ls .r-cur)
in
{_ : auto∶ ls .phase ≡ Voting}
{_ : auto∶ b ∙∈ ls .db}
{_ : auto∶ ShouldVote ls b}
→ p ⦂ t ⊢ ls —[ L′ ∣ m ⟩—→ voteProposal ls
≪VoteBlock? _ {x}{y}{z} = VoteBlock (toWitness x) (toWitness y) (toWitness z)
≪VoteBlockNoOp? :
{h : auto∶ ls .phase ≡ Voting}
{_ : auto∶ NoBlock (ShouldVote ls) (ls .db)}
→ p ⦂ t ⊢ ls ——→ shouldEnterRound ls
≪VoteBlockNoOp? {h = x}{y} = VoteBlockNoOp (toWitness x) (toWitness y)
module _ {s : GlobalState} (let t = s .currentTime) where
module _ p ⦃ _ : Honest p ⦄ (let ls = s @ p; L = currentLeader ls) where
_:InitTC? :
{h : auto∶ ls .phase ≡ EnteringRound}
{_ : auto∶ ls .tc-last ≡ just tc}
→ s —→ _
_:InitTC? {h = x}{y} = LocalStep $′ ≪InitTC? p {h = x}{y}
_:InitNoTC? :
{_ : auto∶ ls .phase ≡ EnteringRound}
{_ : auto∶ ls .tc-last ≡ nothing}
→ s —→ _
_:InitNoTC? {x}{y} = LocalStep $′ ≪InitNoTC? p {h = x}{y}
_:ProposeBlock?_ : ∀ txn →
{_ : auto∶ ls .phase ≡ Proposing}
{_ : auto∶ p ≡ L}
→ s —→ _
_:ProposeBlock?_ txn {x}{y} = LocalStep $′ ≪ProposeBlock? _ txn {x}{y}
_:ProposeBlockNoOp? :
{_ : auto∶ ls .phase ≡ Proposing}
{_ : auto∶ p ≢ L}
→ s —→ _
_:ProposeBlockNoOp? {x}{y} = LocalStep $′ ≪ProposeBlockNoOp? _ {h = x}{y}
_:RegisterProposal? : let m = _; b = sb .datum in
{m∈ : auto∶ m ∈ ls .inbox}
{_ : auto∶ ls .phase ≡ Receiving}
{_ : auto∶ ¬ timedOut ls t}
{_ : auto∶ sb .node ≡ roundLeader (b ∙round)}
{_ : auto∶ ValidProposal (ls .db) b}
→ s —→ _
_:RegisterProposal? {m∈ = x}{y}{z}{w}{q} = LocalStep $′
≪RegisterProposal? _ {m∈ = x}{y}{z}{w}{q}
_:RegisterVote?_ : ∀ b {p′} → let L′ = roundLeader (1 + r); m = _ in
{_ : auto∶ m ∈ ls .inbox}
{_ : auto∶ ls .phase ≡ Receiving}
{_ : auto∶ ¬ timedOut ls t}
{_ : auto∶ b ∙∈ ls .db}
{_ : auto∶ m ∉ ls .db}
{_ : auto∶ L′ ≡ p}
→ s —→ _
_:RegisterVote?_ b {p′}{x}{y}{z}{w}{q}{k} =
LocalStep $′ ≪RegisterVote? _ b p′ {x}{y}{z}{w}{q}{k}
_:RegisterTimeout?_ : ∀ tm → let m = Timeout tm in
{m∈ : auto∶ m ∈ ls .inbox}
{_ : auto∶ ls .phase ≡ Receiving}
{_ : auto∶ ¬ timedOut ls t}
{_ : auto∶ m ∉ ls .db}
→ s —→ _
_:RegisterTimeout?_ _ {x}{y}{z}{w} = LocalStep $′ ≪RegisterTimeout? _ _ {x}{y}{z}{w}
_:RegisterTC? : let m = TCFormed tc in
{m∈ : auto∶ m ∈ ls .inbox}
{_ : auto∶ ls .phase ≡ Receiving}
{_ : auto∶ ¬ timedOut ls t}
{_ : auto∶ m ∉ ls .db}
→ s —→ _
_:RegisterTC? {m∈ = x}{y}{z}{w} = LocalStep $′ ≪RegisterTC? _ {m∈ = x}{y}{z}{w}
_:EnoughTimeouts?_ : ∀ r → let tms = filter (IsTimeoutForRound? r) (ls .db) in
{_ : auto∶ ls .phase ≡ Receiving}
{_ : auto∶ ¬ timedOut ls t}
{_ : auto∶ IncludesHonest tms}
{_ : auto∶ r ≥ ls .r-cur}
→ s —→ _
_:EnoughTimeouts?_ _ {x}{y}{z}{w} = LocalStep $′ ≪EnoughTimeouts? _ _ {x}{y}{z}{w}
_:TimerExpired? :
{_ : auto∶ ls .phase ≡ Receiving}
{_ : auto∶ timedOut ls t}
→ s —→ _
_:TimerExpired? {x}{y} = LocalStep $′ ≪TimerExpired? _ {h = x}{y}
_:AdvanceRoundQC?_ : ∀ qc → let r = qc ∙round in
{_ : auto∶ ls .phase ≡ AdvancingRound}
{_ : auto∶ qc ∙∈ ls .db}
{_ : auto∶ r ≥ ls .r-cur}
→ s —→ _
_:AdvanceRoundQC?_ qc {x}{y}{z} = LocalStep $′ ≪AdvanceRoundQC? _ qc {x}{y}{z}
_:AdvanceRoundTC?_ : ∀ tc → let r = tc ∙round in
{_ : auto∶ ls .phase ≡ AdvancingRound}
{_ : auto∶ tc ∙∈ ls .db}
{_ : auto∶ r ≥ ls .r-cur}
→ s —→ _
_:AdvanceRoundTC?_ tc {x}{y}{z} = LocalStep $′ ≪AdvanceRoundTC? _ tc {x}{y}{z}
_:AdvanceRoundNoOp? :
{_ : auto∶ ls .phase ≡ AdvancingRound}
{_ : auto∶ AllQC (λ qc → qc ∙round < ls .r-cur) (ls .db)}
{_ : auto∶ AllTC (λ tc → tc ∙round < ls .r-cur) (ls .db)}
→ s —→ _
_:AdvanceRoundNoOp? {x}{y}{z} = LocalStep $′ ≪AdvanceRoundNoOp? _ {h = x}{y}{z}
_:Lock? :
{h : auto∶ ls .phase ≡ Locking}
{_ : auto∶ qc -highest-qc-∈- ls .db}
→ s —→ _
_:Lock? {h = x}{y} = LocalStep $′ ≪Lock? _ {h = x}{y}
_:Commit?_ : ∀ (bch : Chain) {b ch} → ⦃ bch ≡ b ∷ ch ⦄ →
{_ : auto∶ ls .phase ≡ Committing}
{_ : auto∶ b ∶ ch longer-final-∈ ls}
→ s —→ broadcast (s .currentTime) nothing (s @ p ≔ commit ch ls)
_:Commit?_ _ ⦃ refl ⦄ {x}{y} = LocalStep $′ ≪Commit? p _ _ {x}{y}
_:CommitNoOp? :
{_ : auto∶ ls .phase ≡ Committing}
{_ : auto∶ NoBlock (_longer-final-∈ ls) (ls .db)}
→ s —→ _
_:CommitNoOp? {x}{y} = LocalStep $′ ≪CommitNoOp? _ {h = x}{y}
_:VoteBlock?_ : ∀ b →
{_ : auto∶ ls .phase ≡ Voting}
{_ : auto∶ b ∙∈ ls .db}
{_ : auto∶ ShouldVote ls b}
→ s —→ _
_:VoteBlock?_ b {x}{y}{z} = LocalStep $′ ≪VoteBlock? _ b {x}{y}{z}
_:VoteBlockNoOp? :
{_ : auto∶ ls .phase ≡ Voting}
{_ : auto∶ NoBlock (ShouldVote ls) (ls .db)}
→ s —→ _
_:VoteBlockNoOp? {x}{y} = LocalStep $′ ≪VoteBlockNoOp? _ {h = x}{y}
module _ tpm {tpm∈ : auto∶ tpm ∈ s .networkBuffer} where
Deliver? : s —→ _
Deliver? = Deliver (toWitness tpm∈)
WaitUntil? : ∀ t →
{_ : auto∶ All (λ (t′ , _ , _) → t ≤ t′ + Δ) (s .networkBuffer) }
{_ : auto∶ currentTime s < t }
→ s —→ _
WaitUntil? t {x}{y} = WaitUntil t (toWitness x) (toWitness y)