mirror of
https://github.com/logos-blockchain/research.git
synced 2026-08-07 11:43:20 +00:00
35 lines
1.6 KiB
Python
35 lines
1.6 KiB
Python
"""Early stop: converge-then-measure truncation that preserves equilibrium statistics."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pandas as pd
|
|
|
|
from tsi_sim.config import SimConfig
|
|
from tsi_sim.engine import ES_MEASURE, ES_MIN_EPOCH, run_trajectory
|
|
|
|
BASE = dict(n_nodes=300, 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=2, uncle_window=300, k=256, epochs=40, genesis_d_factor=0.5)
|
|
|
|
|
|
def test_early_stop_truncates_and_matches_full_run():
|
|
full = pd.DataFrame(run_trajectory(SimConfig(**BASE)))
|
|
es = pd.DataFrame(run_trajectory(SimConfig(**BASE, early_stop=True)))
|
|
# truncation happened, with room for the measurement budget
|
|
assert ES_MIN_EPOCH + 1 <= len(es) < len(full)
|
|
# bit-identical prefix (same RNG streams; early_stop is excluded from key())
|
|
n = len(es)
|
|
assert (full.head(n).mean_ratio.to_numpy() == es.mean_ratio.to_numpy()).all()
|
|
# equilibrium agrees: early-stop tail (measurement sample) vs full-run tail
|
|
es_tail = es.tail(ES_MEASURE).mean_ratio.mean()
|
|
full_tail = full[full.epoch >= 20].mean_ratio.mean()
|
|
assert abs(es_tail - full_tail) < 0.015
|
|
|
|
|
|
def test_sawtooth_never_stops_early():
|
|
cfg = SimConfig(**{**BASE, "epochs": 24}, early_stop=True,
|
|
adversary_frac=0.3, adversary_strategy="withhold",
|
|
adversary_period=6, adversary_withhold_epochs=3)
|
|
df = pd.DataFrame(run_trajectory(cfg))
|
|
assert len(df) == 24 # full budget: detector disabled for schedules
|