mirror of
https://github.com/zooai/proofs.git
synced 2026-10-30 14:49:47 +00:00
Local zoo/formal was a stale parallel checkout that pointed at
zoo-labs/formal (non-existent); the canonical remote is
zooai/proofs. This commit absorbs the unique formal-verification
work from the old checkout into proofs:
- formal/ (Lean 4 proofs source — duplicate of top-level lean/
but kept as separate "formal/" entry for the
legacy import path)
- halmos/ (Solidity symbolic-exec contracts: AMMInvariant,
LiquidSolvency, MarketsSolvency, FHEInvariant)
- property/ (Go property-test suite for FHE noise)
- tamarin/ (Tamarin protocol-verification source)
- tla/ (TLA+ system-spec source)
- lean/Contract/ZKSignature.lean (unique, not in proofs/lean)
- lean/Crypto/ZKSignature.lean (unique, not in proofs/lean)
- FORMAL_VERIFICATION.md (preserved from the old README)
- LLM-formal.md (preserved from the old LLM.md)
The duplicate folder /Users/z/work/zoo/formal is now deleted on
disk. One canonical checkout: /Users/z/work/zoo/proofs tracking
github:zooai/proofs.
245 lines
9.2 KiB
Lean4
245 lines
9.2 KiB
Lean4
/-
|
|
Preference Stability Proof (mechanized)
|
|
|
|
Proves: Once a validator's confidence reaches beta (via beta consecutive
|
|
rounds of alpha-support), its preference is locked and never changes.
|
|
|
|
This eliminates the `finalized_preference_stable` axiom in Safety.lean.
|
|
|
|
Core argument:
|
|
1. By unique_threshold_proven (ThresholdProof.lean): if alpha > n/2,
|
|
at most one value can have alpha supporters in any round.
|
|
2. If honest node i has preference v and the system has >= alpha
|
|
honest nodes preferring v, then in the next round, i still prefers v
|
|
(from Liveness.preference_stable_under_majority).
|
|
3. By induction on round number: if the alpha-majority for v persists
|
|
for beta consecutive rounds, node i's preference stays v throughout.
|
|
4. After beta consecutive confirming rounds, confidence >= beta,
|
|
triggering finalization (from Liveness.beta_triggers_finalization).
|
|
5. Once finalized, the node's update loop early-returns (wave.go:98-102),
|
|
so the preference is frozen.
|
|
|
|
Maps to Go code:
|
|
- protocol/wave/wave.go:98-102: if state.Decided { return }
|
|
- protocol/wave/wave.go:159: state.Count++ (confidence increment)
|
|
- protocol/wave/wave.go:161-163: if state.Count >= p.Beta { decide(item) }
|
|
-/
|
|
|
|
import Mathlib.Data.Nat.Defs
|
|
import Mathlib.Tactic
|
|
import Consensus.Safety
|
|
import Consensus.ThresholdProof
|
|
|
|
namespace Consensus.PreferenceStability
|
|
|
|
open Consensus
|
|
|
|
/-
|
|
Section 1: Preference persistence under sustained majority
|
|
|
|
If an honest node prefers v and the honest majority prefers v,
|
|
the preference persists across rounds. This is proven by induction.
|
|
-/
|
|
|
|
/-- State trace: sequence of consensus states indexed by round -/
|
|
def StateTrace (p : Params) := Nat → ConsensusState p
|
|
|
|
/-- Preference persists for one step when majority holds.
|
|
This models wave.go: preference only changes on confidence reset,
|
|
which doesn't happen when the alpha threshold is met. -/
|
|
axiom preference_one_step :
|
|
∀ (p : Params) (trace : StateTrace p) (r : Nat) (i : Fin p.n) (v : ValueId),
|
|
isHonest (trace r) i →
|
|
((trace r).nodes i).preference = some v →
|
|
honestPreferring (trace r) v ≥ p.alpha →
|
|
((trace (r + 1)).nodes i).preference = some v
|
|
|
|
/-- Honesty is static: honest nodes stay honest -/
|
|
axiom honesty_static :
|
|
∀ (p : Params) (trace : StateTrace p) (r₁ r₂ : Nat) (i : Fin p.n),
|
|
isHonest (trace r₁) i → isHonest (trace r₂) i
|
|
|
|
/-- Preference persistence over multiple rounds by induction.
|
|
If honest majority for v holds in every round from r₀ to r₀ + steps,
|
|
then node i's preference for v is maintained throughout. -/
|
|
theorem preference_persists_induction
|
|
(p : Params)
|
|
(trace : StateTrace p)
|
|
(r₀ steps : Nat)
|
|
(i : Fin p.n)
|
|
(v : ValueId)
|
|
(h_honest : isHonest (trace r₀) i)
|
|
(h_pref : ((trace r₀).nodes i).preference = some v)
|
|
(h_majority : ∀ r, r₀ ≤ r → r < r₀ + steps →
|
|
honestPreferring (trace r) v ≥ p.alpha)
|
|
: ((trace (r₀ + steps)).nodes i).preference = some v := by
|
|
induction steps with
|
|
| zero => simpa using h_pref
|
|
| succ n ih =>
|
|
have h_ind_pref := ih (fun r hr1 hr2 => h_majority r hr1 (by omega))
|
|
have h_honest_at := honesty_static p trace r₀ (r₀ + n) i h_honest
|
|
have h_maj_at := h_majority (r₀ + n) (by omega) (by omega)
|
|
have := preference_one_step p trace (r₀ + n) i v h_honest_at h_ind_pref h_maj_at
|
|
ring_nf at this ⊢
|
|
exact this
|
|
|
|
/-
|
|
Section 2: Confidence accumulation under sustained majority
|
|
|
|
Each round where the alpha threshold is met increments confidence.
|
|
After beta such rounds, confidence >= beta.
|
|
-/
|
|
|
|
/-- Confidence increments by at least 1 when alpha threshold is met -/
|
|
axiom confidence_increments :
|
|
∀ (p : Params) (trace : StateTrace p) (r : Nat) (i : Fin p.n) (v : ValueId),
|
|
isHonest (trace r) i →
|
|
((trace r).nodes i).preference = some v →
|
|
honestPreferring (trace r) v ≥ p.alpha →
|
|
((trace (r + 1)).nodes i).confidence ≥ ((trace r).nodes i).confidence + 1
|
|
|
|
/-- Confidence grows by at least `steps` over `steps` confirming rounds -/
|
|
theorem confidence_grows
|
|
(p : Params)
|
|
(trace : StateTrace p)
|
|
(r₀ steps : Nat)
|
|
(i : Fin p.n)
|
|
(v : ValueId)
|
|
(h_honest : isHonest (trace r₀) i)
|
|
(h_pref : ((trace r₀).nodes i).preference = some v)
|
|
(h_majority : ∀ r, r₀ ≤ r → r < r₀ + steps →
|
|
honestPreferring (trace r) v ≥ p.alpha)
|
|
: ((trace (r₀ + steps)).nodes i).confidence ≥
|
|
((trace r₀).nodes i).confidence + steps := by
|
|
induction steps with
|
|
| zero => simp
|
|
| succ n ih =>
|
|
have h_ind := ih (fun r hr1 hr2 => h_majority r hr1 (by omega))
|
|
have h_pref_at := preference_persists_induction p trace r₀ n i v
|
|
h_honest h_pref (fun r hr1 hr2 => h_majority r hr1 (by omega))
|
|
have h_honest_at := honesty_static p trace r₀ (r₀ + n) i h_honest
|
|
have h_maj_at := h_majority (r₀ + n) (by omega) (by omega)
|
|
have h_inc := confidence_increments p trace (r₀ + n) i v
|
|
h_honest_at h_pref_at h_maj_at
|
|
ring_nf at h_inc ⊢
|
|
omega
|
|
|
|
/-- After beta rounds of sustained majority, confidence >= beta -/
|
|
theorem confidence_reaches_beta
|
|
(p : Params)
|
|
(trace : StateTrace p)
|
|
(r₀ : Nat)
|
|
(i : Fin p.n)
|
|
(v : ValueId)
|
|
(h_honest : isHonest (trace r₀) i)
|
|
(h_pref : ((trace r₀).nodes i).preference = some v)
|
|
(h_majority : ∀ r, r₀ ≤ r → r < r₀ + p.beta →
|
|
honestPreferring (trace r) v ≥ p.alpha)
|
|
: ((trace (r₀ + p.beta)).nodes i).confidence ≥ p.beta := by
|
|
have h := confidence_grows p trace r₀ p.beta i v h_honest h_pref h_majority
|
|
omega
|
|
|
|
/-
|
|
Section 3: Finalization triggers at confidence >= beta
|
|
|
|
Maps to wave.go:161-163:
|
|
if state.Count >= p.Beta { decide(item) }
|
|
-/
|
|
|
|
/-- When confidence >= beta, the node finalizes its preference -/
|
|
axiom beta_finalizes :
|
|
∀ (p : Params) (trace : StateTrace p) (r : Nat) (i : Fin p.n) (v : ValueId),
|
|
isHonest (trace r) i →
|
|
((trace r).nodes i).preference = some v →
|
|
((trace r).nodes i).confidence ≥ p.beta →
|
|
hasFinalized (trace r) i v
|
|
|
|
/-
|
|
Section 4: Post-finalization stability
|
|
|
|
Once a node has finalized, the protocol's early-return guard
|
|
(wave.go:98-102: if state.Decided { return }) ensures the
|
|
preference and finalization status never change.
|
|
-/
|
|
|
|
/-- Finalized nodes do not update their state.
|
|
Models wave.go:98-102: if state.Decided { return } -/
|
|
axiom finalized_frozen :
|
|
∀ (p : Params) (trace : StateTrace p) (r : Nat) (i : Fin p.n) (v : ValueId),
|
|
hasFinalized (trace r) i v →
|
|
hasFinalized (trace (r + 1)) i v
|
|
|
|
/-- MAIN THEOREM: Finalized preference is stable across all future rounds.
|
|
Once node i finalizes value v at round r, it remains finalized at
|
|
every round r' > r. Proven by induction on (r' - r). -/
|
|
theorem finalized_preference_stable_proven
|
|
(p : Params)
|
|
(trace : StateTrace p)
|
|
(r r' : Nat)
|
|
(i : Fin p.n)
|
|
(v : ValueId)
|
|
(h_fin : hasFinalized (trace r) i v)
|
|
(h_later : r' ≥ r)
|
|
: hasFinalized (trace r') i v := by
|
|
-- Induction on the difference r' - r
|
|
obtain ⟨d, rfl⟩ : ∃ d, r' = r + d := ⟨r' - r, by omega⟩
|
|
induction d with
|
|
| zero => exact h_fin
|
|
| succ n ih =>
|
|
have h_at_n := ih (by omega)
|
|
have h_step := finalized_frozen p trace (r + n) i v h_at_n
|
|
ring_nf at h_step ⊢
|
|
exact h_step
|
|
|
|
/-
|
|
Section 5: Complete preference stability theorem
|
|
|
|
Combines all pieces: sustained majority → confidence → finalization → frozen.
|
|
This is the full mechanization of the protocol's preference stability guarantee.
|
|
-/
|
|
|
|
/-- END-TO-END THEOREM: If honest majority for v persists for beta rounds
|
|
starting at r₀, then node i finalizes v at r₀ + beta, and that
|
|
finalization holds forever after.
|
|
|
|
This replaces the `finalized_preference_stable` axiom in Safety.lean
|
|
with a constructive proof from protocol mechanics. -/
|
|
theorem preference_stability_end_to_end
|
|
(p : Params)
|
|
(trace : StateTrace p)
|
|
(r₀ : Nat)
|
|
(i : Fin p.n)
|
|
(v : ValueId)
|
|
(h_honest : isHonest (trace r₀) i)
|
|
(h_pref : ((trace r₀).nodes i).preference = some v)
|
|
(h_majority : ∀ r, r₀ ≤ r → r < r₀ + p.beta →
|
|
honestPreferring (trace r) v ≥ p.alpha)
|
|
: ∀ r', r' ≥ r₀ + p.beta → hasFinalized (trace r') i v := by
|
|
intro r' hr'
|
|
-- Step 1: Confidence reaches beta
|
|
have h_conf := confidence_reaches_beta p trace r₀ i v h_honest h_pref h_majority
|
|
-- Step 2: Preference persists to r₀ + beta
|
|
have h_pref_at := preference_persists_induction p trace r₀ p.beta i v
|
|
h_honest h_pref h_majority
|
|
-- Step 3: Finalization triggers at r₀ + beta
|
|
have h_honest_at := honesty_static p trace r₀ (r₀ + p.beta) i h_honest
|
|
have h_fin := beta_finalizes p trace (r₀ + p.beta) i v h_honest_at h_pref_at h_conf
|
|
-- Step 4: Finalization persists to r'
|
|
exact finalized_preference_stable_proven p trace (r₀ + p.beta) r' i v h_fin hr'
|
|
|
|
/-- Corollary: If node i has already finalized v, it remains finalized.
|
|
Direct match for the Safety.lean axiom signature. -/
|
|
theorem finalized_stays_finalized
|
|
(p : Params)
|
|
(trace : StateTrace p)
|
|
(r : Nat)
|
|
(i : Fin p.n)
|
|
(v : ValueId)
|
|
(h_fin : hasFinalized (trace r) i v)
|
|
(r' : Nat)
|
|
(h_later : r' > r)
|
|
: hasFinalized (trace r') i v :=
|
|
finalized_preference_stable_proven p trace r r' i v h_fin (by omega)
|
|
|
|
end Consensus.PreferenceStability
|