mirror of
https://github.com/logos-blockchain/research.git
synced 2026-08-07 11:43:20 +00:00
Review finding: the timing study and the neighbourhood-confidence numbers were produced by ad-hoc analysis, not by the simulator. timing_linkability, neighbourhood_confidence and mean_upstream_hops had no callers outside their own modules; min_blend_delay and release_mode were declared on SweepConfig, validated and keyed, but never read by sweep.py, so a YAML setting them was silently ignored; and propagation.py called mix_wait without the minimum, leaving the knob inert on the delay tables of 3.1-3.2. Section 6 promised every number was reproducible and data/README claimed to hold the evidence behind every number -- both were false for 3.11. Now wired end to end: release_designs() is a real sweep axis, the engine measures the timing attack per design and records it in traffic.parquet, and the deanon table carries the full attribution bracket (local confidence, attributable fractions, upstream hops, neighbourhood confidence). Added configs/timing.yaml and a make target. The committed sweep reproduces 3.11: MAP success 0.993/0.905/0.683 for clock and 0.989/0.832/0.550 for jitter across the swept rates, and the minimum interval changes nothing (0.993 vs 0.993). Evidence checked in under data/timing. Three regression tests pin the wiring so a measure cannot go back to living only in analysis. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
46 lines
2.9 KiB
Markdown
46 lines
2.9 KiB
Markdown
# Evidence of record
|
||
|
||
The sweep outputs behind every number in [the report](../README.md). The simulator does not commit
|
||
its own `runs/` directory — these are the copies of record, kept so that any figure or table can be
|
||
re-derived, or challenged, without re-running hours of compute.
|
||
|
||
Each run directory holds the three tables the simulator writes: `propagation.parquet`,
|
||
`adversary.parquet` and `deanon.parquet`.
|
||
|
||
| directory | config | sampling | backs |
|
||
|---|---|---|---|
|
||
| `default/` | `configs/default.yaml` | 1 000 rounds × 8 seeds = **8 000/cell** | §3.1–§3.5 — delay, observation, eclipse, deanonymization, delivery, coverage |
|
||
| `redundancy/` | `configs/redundancy.yaml` | 1 200 × 8 = **9 600/cell** | §3.8 — messaging redundancy R = 1…4 |
|
||
| `percolation/` | `configs/percolation.yaml` | 800 × 8 = **6 400/cell** | §3.5 — the churn threshold `u_c = 1 − 1/(degree − 1)` |
|
||
| `correlated-churn/` | `configs/correlated-churn.yaml` | 800 × 8 = **6 400/cell** | §3.9 — correlated AS/region outages vs uniform churn |
|
||
| `fullscale/` | `configs/fullscale.yaml` | 64 × 3 = **192/cell** | §5 — the 10⁶ scaling check (deliberately lighter; not a source of headline numbers) |
|
||
| `cover-traffic/` | `configs/cover-traffic.yaml` | 900 s timeline × 4 seeds | §3.10 — blending, mixing, and the emission-quota stake ceiling. Carries a fourth table, `traffic.parquet` |
|
||
| `timing/` | `configs/timing.yaml` | 120 s timeline × 3 seeds | §3.11 — the two release designs under a timing attack, and the minimum-interval control |
|
||
|
||
The linkability results (§3.6–§3.7) and both deanonymization rates are closed forms over these
|
||
tables rather than separate measurements, so they have no run of their own — `blend.linkability`
|
||
derives them and `make verify` checks them against Monte-Carlo.
|
||
|
||
## Regenerating the report's numbers
|
||
|
||
```
|
||
python report_numbers.py
|
||
```
|
||
|
||
prints every quoted value with its across-topology standard error, straight from the parquets here.
|
||
That is the fastest way to check a table in the report against its evidence. It takes optional
|
||
paths (`report_numbers.py <default> <redundancy> <percolation>`) if you want to point it at fresh
|
||
runs instead.
|
||
|
||
## Regenerating the data itself
|
||
|
||
From [`tools/simulators/blend`](../../../tools/simulators/blend): `make sweep`,
|
||
`make redundancy`, `make percolation`, `make correlated-churn`, `make sweep-fullscale`. Results
|
||
land in that simulator's `runs/<timestamp>_<label>/`. Note that the seed streams depend on the
|
||
configuration, so re-running reproduces the *statistics*, not bit-identical numbers, unless the
|
||
config is unchanged — in which case it does reproduce exactly.
|
||
|
||
Two runs from the same session are deliberately **not** kept: the smoke runs (throwaway, far too
|
||
noisy to interpret) and an earlier 144-rounds/cell redundancy grid that was superseded because its
|
||
sampling error produced a non-monotonic delivery curve — the reason `redundancy/` samples 9 600.
|