{-# OPTIONS --safe #-}
open import Prelude
open import Hash
open import Jolteon.Assumptions

module Jolteon.Properties.ValidQC ( : _) (open Assumptions ) where

open import Jolteon 
open import Jolteon.Properties.Core 
open import Jolteon.Properties.State 
open import Jolteon.Properties.Steps.Core 

-- ** monomorphic version
data ValidQC (qc : QC) : Type where
  isValidQC :
    (∀ {ch : Chain} 
       ValidChain ch
       ch ∙blockId  qc ∙blockId
        ─────────────────────────
        ch ∙round    qc ∙round   )
    ───────────────────────────────────────
    ValidQC qc

valid-qc₀ : ValidQC qc₀
valid-qc₀ = isValidQC λ where
  {[]}    _ refl  refl
  {_  _} _ id≡   ⊥-elim $ noHashCollision˘ id≡

ValidProposal⇒qcValid :
  ValidProposal ms b
  ────────────────────
  ValidQC (b .blockQC)
ValidProposal⇒qcValid (_ ,  mk {ch = ch} ch∈ (connects∶ id≡ r≡ _))
    using vchchain-∈⇒ValidChain ch∈
    = isValidQC  vch′ id≡′ 
       subst ((_≡ _)  _∙round )
             (uniqueChain vch vch′ (sym $ trans id≡′ id≡))
             (sym r≡))

b∈⇒qcValid :  {s}  Reachable s   _ : Honest p  
  let ls = s  p
      mᵖ = Propose $ b signed-by roundLeader (b ∙round)
  in
    mᵖ  ls .db
    ────────────────────
    ValidQC (b .blockQC)
b∈⇒qcValid {p}{b}{s} Rs  hp  m∈
  using srpsb∈⇒StepRegisterProposal Rs m∈
  with trE , srp▷traceRs▷ Rs srp
  = ValidProposal⇒qcValid vp
  where
  open TraceExtension trE

  vp : ValidProposal ((intState  p) .db) b
  vp = StepRegisterProposal⇒ValidProposal reachable′ srp▷