Smart Constructors

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)