mirror of
https://github.com/logos-blockchain/research.git
synced 2026-08-09 04:33:15 +00:00
90 lines
4.0 KiB
Python
90 lines
4.0 KiB
Python
|
|
"""What the DEPLOYED chain would read at the spec's own operating point — handoff E1/E2/E6.
|
||
|
|
|
||
|
|
The report measures the mechanism: it drives the estimator to exact `f`, so its numbers isolate
|
||
|
|
fork loss from every other effect. That is the right default for design questions and the wrong
|
||
|
|
one for "what will the deployed chain read", because the spec's estimator quantises the target
|
||
|
|
rate — `cryptarchia-total-stake-inference.md` carries `const PRECISION: u64 = 1e3`, so
|
||
|
|
`f_p = 0.033` at `f = 1/30` and the recursion drives density to a target ~1 % below `f`.
|
||
|
|
|
||
|
|
E1 pins the operating point from `analysis-block-times-blend-network.md`: `blending_delay` is a
|
||
|
|
FIXED per-hop dwell of 2 s (the `3d+5` max-delay arithmetic gives 11 s at d=2 and 14 s at d=3,
|
||
|
|
matching the prose), so the simulator's `Uniform(0, delta_max)` matches it in the mean at
|
||
|
|
`delta_max = 4` -> `D_vis ~ 8 s`, `rho ~ 0.27`.
|
||
|
|
|
||
|
|
Three arms, everything else identical:
|
||
|
|
|
||
|
|
exact f fixed_point=False the report's convention -> expect 1.000
|
||
|
|
spec fixed_point=True, 1e3 what the chain does today -> expect ~1.010
|
||
|
|
proposed fixed_point=True, 1e6 the report's recommendation -> expect ~1.00001
|
||
|
|
|
||
|
|
The point of running rather than quoting `theory.fixed_point_bias`: the closed form predicts the
|
||
|
|
offset in isolation, and this confirms it survives the full per-node dynamics at the deployment's
|
||
|
|
actual load, alongside the fork loss rather than instead of it.
|
||
|
|
|
||
|
|
Run: python scripts/spec_point.py (writes runs/spec_point.parquet)
|
||
|
|
"""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
import pandas as pd
|
||
|
|
from joblib import Parallel, delayed
|
||
|
|
|
||
|
|
from tsi_sim.config import SimConfig
|
||
|
|
from tsi_sim.engine import run_trajectory
|
||
|
|
from tsi_sim.theory import fixed_point_bias
|
||
|
|
|
||
|
|
HERE = Path(__file__).resolve().parent.parent
|
||
|
|
RUNS = HERE / "runs"
|
||
|
|
RUNS.mkdir(exist_ok=True)
|
||
|
|
|
||
|
|
EPOCHS = 20
|
||
|
|
REPS = 20
|
||
|
|
N_JOBS = 6
|
||
|
|
|
||
|
|
# The spec's operating point (E1), with the spec's own MAX_UNCLES rather than the report's U = 2.
|
||
|
|
SPEC_POINT = dict(n_nodes=1000, stake_dist="pareto", topology="blend", degree=6,
|
||
|
|
link_latency_mean=0.5, link_latency_dist="geo", blend_hops=3,
|
||
|
|
blend_delay_max=4.0, max_uncles=4, uncle_strategy="oldest",
|
||
|
|
window_absorption=10.0, k=2160, epochs=EPOCHS,
|
||
|
|
genesis_d_factor=0.5, early_stop=True)
|
||
|
|
|
||
|
|
ARMS = [("exact f (report convention)", False, 1_000_000),
|
||
|
|
("spec today (PRECISION = 1e3)", True, 1_000),
|
||
|
|
("recommended (PRECISION = 1e6)", True, 1_000_000)]
|
||
|
|
|
||
|
|
|
||
|
|
def _cell(label: str, fixed_point: bool, precision: int, rep: int) -> dict:
|
||
|
|
cfg = SimConfig(**SPEC_POINT, fixed_point=fixed_point, f_precision=precision, replicate=rep)
|
||
|
|
t = pd.DataFrame(run_trajectory(cfg))
|
||
|
|
t = t[t.epoch >= t.epoch.max() // 2]
|
||
|
|
return dict(arm=label, fixed_point=fixed_point, f_precision=precision, rep=rep,
|
||
|
|
mean_ratio=float(t.mean_ratio.mean()),
|
||
|
|
fork_rate=float(t.fork_rate.mean()),
|
||
|
|
p_ref=float(t.p_ref.mean()),
|
||
|
|
range_ratio=float(t.range_ratio.max()))
|
||
|
|
|
||
|
|
|
||
|
|
def main() -> None:
|
||
|
|
print("=== the spec's operating point: delta_max = 4, D_vis ~ 8 s, rho ~ 0.27, U = 4 ===")
|
||
|
|
jobs = [(lab, fp, pr, r) for lab, fp, pr in ARMS for r in range(REPS)]
|
||
|
|
df = pd.DataFrame(Parallel(n_jobs=N_JOBS, backend="loky", inner_max_num_threads=1)(
|
||
|
|
delayed(_cell)(lab, fp, pr, r) for lab, fp, pr, r in jobs))
|
||
|
|
df.to_parquet(RUNS / "spec_point.parquet", index=False)
|
||
|
|
|
||
|
|
f = SimConfig(**SPEC_POINT).f
|
||
|
|
print(f"\n{'arm':>32} {'D-hat/D':>18} {'predicted':>10} {'consensus':>10}")
|
||
|
|
for lab, fp, pr in ARMS:
|
||
|
|
g = df[df.arm == lab]
|
||
|
|
pred = fixed_point_bias(f, pr) if fp else 1.0
|
||
|
|
print(f"{lab:>32} {g.mean_ratio.mean():10.5f}+-{g.mean_ratio.sem():.5f} "
|
||
|
|
f"{pred:10.5f} {('exact' if g.range_ratio.max() == 0 else 'SPREAD'):>10}")
|
||
|
|
print(f"\nfork rate {df.fork_rate.mean():.3f}, p_ref {df.p_ref.mean():.4f}, "
|
||
|
|
f"{REPS} replicates, k = 2160")
|
||
|
|
print(f"wrote {RUNS}/spec_point.parquet")
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
main()
|