aere-research/formal-consensus/run_consensus_verification.py
Aere Network 4a0b48588c Initial public release
Aere Network public source. Everything here can be checked against the live
chain (chain id 2800, https://rpc.aere.network).

Scope note, stated up front rather than buried: consensus on chain 2800 is
classical secp256k1 ECDSA QBFT. The post-quantum work in this repository is at
the signature, precompile, account and transport layers. Nothing here makes the
consensus post-quantum, and no document in it should be read as claiming so.
2026-07-20 01:02:30 +03:00

90 lines
4.7 KiB
Python

#!/usr/bin/env python3
# -----------------------------------------------------------------------------
# run_consensus_verification.py
#
# One-command re-run of the AERE formal-verification suite (z3): the QBFT/Falcon
# CONSENSUS models AND the CONTRACT SMT models (fund-flow / registry / PQC-verifier
# invariants). Reports a single PASS/FAIL plus the verdict-line tally. Each model
# exits 0 only if every PROOF is PROVED and every NEGATIVE CONTROL fired, so a green
# run means the proofs are discharged AND demonstrably non-vacuous.
#
# python run_consensus_verification.py
#
# The verdict-line tally counts the per-check lines each model prints (one line per
# property, "[PROVED ] ..." / "[CEX-FOUND] ..." / "[FAILED ] ..."); it is a count
# of distinct property checks, not of SUMMARY echoes.
#
# (The quint/Apalache spec FalconQuorum.qnt is an OPTIONAL secondary cross-check;
# see CONSENSUS-VERIFICATION-2026-07-12.md for the `quint run` commands.)
# -----------------------------------------------------------------------------
import subprocess, sys, os, re
# --- QBFT / Falcon consensus models (unchanged) ---
CONSENSUS_MODELS = [
("QBFT/IBFT 2.0 SAFETY (agreement)", "qbft_safety_smt.py"),
("Falcon LOG-ONLY no-op", "falcon_logonly_noop_smt.py"),
("Falcon BLOCKING safety/liveness/N>=7", "falcon_blocking_smt.py"),
("PQC ACTIVATION transition safety (log-only->blocking + contract-anchored registry)", "qbft_pqc_activation_smt.py"),
("QBFT LIVENESS (partial synchrony)", "qbft_liveness_smt.py"),
("QBFT explicit-Prepare counting (2026-07-14 2nd-client bug+fix)", "qbft_prepare_counting_smt.py"),
("QBFT digest-keyed vote tally (2026-07-14 Finding-A shipped fix)", "qbft_digest_keyed_smt.py"),
("QBFT IBFT 2.0 locking, engine-role model (2026-07-14 Findings D/E)", "qbft_locking_smt.py"),
]
# --- CONTRACT SMT models: fund-flow + registry + PQC-verifier invariants (wired in
# this loop). Each proves a load-bearing safety invariant by asserting NOT-property
# under the real guards (UNSAT) with a firing negative control (guard removed -> SAT). ---
CONTRACT_MODELS = [
("ComputeMarketV3 ESCROW SOLVENCY (bal[T] >= totalLiabilities[T])", "computemarket_smt.py"),
("DestinationSettler NO-ARBITRARY-RECIPIENT + AT-MOST-ONCE + OUTPUT-MATCH", "destinationsettler_smt.py"),
("AccountMigrator ONLY-DESTINATION + ATOMICITY (no custody / no strand)", "migrator_smt.py"),
("PQ FinalityCertificate FAIL-CLOSED accept (quorum/root/size/domain/rotation)", "pqfinality_smt.py"),
("PQ AggregateVerifier FAIL-CLOSED t-of-n authorization (root/digest binding)", "pqaggregate_smt.py"),
("TrustRegistry + VerifiableCredential FAIL-CLOSED compliance trust", "credential_registry_smt.py"),
("RecoveryRegistry APPEND-ONLY + STRICT NONCE + FAIL-CLOSED (Falcon-512)", "recovery_registry_smt.py"),
("AP2MandateVerifier SPEND-AUTH cap + window + L3 executor gate", "ap2_mandate_smt.py"),
("ReputationRegistry8004 M1 author-gate + delta-clamp forward-safety", "reputation_gate_smt.py"),
("VectorStore VERSION-MONOTONICITY + APPEND-ONLY + one-shot receipt", "vectorstore_smt.py"),
("BitstringStatusList REVOCATION MONOTONICITY (terminal) + epoch + frame", "bitstring_status_smt.py"),
]
MODELS = CONSENSUS_MODELS + CONTRACT_MODELS
_TAG_RE = re.compile(r'^\[(PROVED|CEX-FOUND|FAILED)\s*\]')
here = os.path.dirname(os.path.abspath(__file__))
overall = True
summary = []
totals = {"PROVED": 0, "CEX-FOUND": 0, "FAILED": 0}
for label, fname in MODELS:
path = os.path.join(here, fname)
print("=" * 78)
print(f"### {label} [{fname}]")
print("=" * 78)
r = subprocess.run([sys.executable, path], capture_output=True, text=True)
sys.stdout.write(r.stdout)
if r.stderr:
sys.stderr.write(r.stderr)
for line in r.stdout.splitlines():
m = _TAG_RE.match(line)
if m:
totals[m.group(1)] += 1
ok = (r.returncode == 0)
overall = overall and ok
summary.append((label, fname, ok))
print()
print("#" * 78)
print("### AERE FORMAL-VERIFICATION SUITE -- OVERALL (consensus + contract models)")
print("#" * 78)
for label, fname, ok in summary:
print(f" {'PASS' if ok else 'FAIL'} {label:66} ({fname})")
print()
print(f" models run: {len(MODELS)} passed: {sum(1 for _,_,ok in summary if ok)}"
f" ({len(CONSENSUS_MODELS)} consensus + {len(CONTRACT_MODELS)} contract)")
print(f" verdict lines: {totals['PROVED']} PROVED {totals['CEX-FOUND']} CEX-FOUND "
f"{totals['FAILED']} FAILED")
print("RESULT:", "ALL MODELS PASS (proofs PROVED, negative controls fired)" if overall
else "FAILURE -- see model output above")
sys.exit(0 if overall else 1)