Jolteon Global Step

PLAN : Allow Deliver global step to deliver many messages at once and advance the time there (advance by constant Δ or new constant δ s.t. δ < Δ).

State-updating functions

honestTPMessage : TPMessage  Maybe (HonestPid × Message)
honestTPMessage (_ , p , m) = case honest? p of λ where
    (yes hp)  just ((p  hp) , m)
    (no _)    nothing

-- Delivers a message to replicas' inboxes.
receiveMsg : StateMap  Maybe (HonestPid × Message)  StateMap
receiveMsg sm = M.maybe′  (p , m)  sm [ p ]%=′ receiveMessage m) sm

-- Deliver a message which is in transit:
--   · adds it to the corresponding inbox in a local state
--   · removes it from the network buffer
deliverMsg :  s {tpm}  tpm  s .networkBuffer  GlobalState
deliverMsg s {tpm} tpm∈ = record s
  { stateMap      = receiveMsg (s .stateMap) (honestTPMessage tpm)
  ; networkBuffer = s .networkBuffer L.Mem.─ tpm∈
  }

-- Takes a time and envelope and expand the broadcasted messages to n unicast messages.
-- This function broadcasts messages even to the sender (otherwise we would filter).
expandBroadcasts : Time  Envelope  TPMessages
expandBroadcasts t = expandEnv
  module _ where
  expandEnv : Envelope  TPMessages
  expandEnv = λ where
    [ m       L.map  p  (t , p , m)) allPids
    [ p  m   [ (t , p , m) ]

  expandEnv-content≡ :  env  All  (_ , _ , m)  m  env .content) (expandEnv env)
  expandEnv-content≡ = λ where
    [ m       L.All.tabulate λ x∈  let _ , _ , eq = L.Mem.∈-map⁻  p  (t , p , m)) x∈ in
                cong (proj₂  proj₂) eq
    [ p  m   refl  []

broadcast : Time  Maybe Envelope  Op₁ GlobalState
broadcast t me s = record s
  { networkBuffer = maybe  e  s .networkBuffer ++ expandBroadcasts t e) (s .networkBuffer) me
  ; history       = L.fromMaybe (M.map _∙message me) ++ s .history
  }

The (global) step relation

data _—→_ (s : GlobalState) : GlobalState  Type where

  -- An *honest* node performs a local step.
  LocalStep :  _ : Honest p   let ls = s  p; t = s .currentTime in
    (p  t  ls  menv —→ ls′)
    ────────────────────────────────────
    s —→ broadcast t menv (s  p  ls′)

  -- A *dishonest* node can:
  --   - Replay a message sent previously by an honest participant.
  --   - Broadcast any message signed by a dishonest participant.
  DishonestLocalStep : let m = env .content; t = s .currentTime in
     Dishonest p
     NoSignatureForging m s
      ─────────────────────────────
      s —→ broadcast t (just env) s

  -- *Deliver* a message in the network
  -- Since we may deliver any message on the network, this models
  -- non-determinism in the order that messages may arrive.
  Deliver :  {tpm}
    (tpm∈ : tpm  s .networkBuffer) 
    ───────────────────────────────
    s —→ deliverMsg s tpm∈

  -- We can always do nothing for a while, as long as we are
  -- still able to deliver messages in time.
  WaitUntil :  t 
     All  (t′ , _ , _)  t  t′ + Δ) (s .networkBuffer)
     currentTime s < t
      ─────────────────────────────────
      s —→ record s { currentTime = t }