mirror of
https://github.com/logos-blockchain/research.git
synced 2026-08-10 21:23:12 +00:00
4 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
86058fb3f0
|
Re-run §6.8's selfish uncle-margin sweep; close the coalition-sizing item
The last study still carrying pre-fix numbers. It was the most contaminated of
them — 2 of 8 replicates at alpha=0.3 and 1 of 8 at alpha=0.4 were running
majority coalitions — so it needed re-running before its levels could be quoted.
Every conclusion reproduces:
- alpha=0.3, delta=8: D-hat/D 0.757/0.769/0.775/0.766 across U=1..4 (was
0.729/0.755/0.738/0.758). Still flat in U — raising the cap does not buy the
estimate back, which is the section's point.
- No attacked cell reaches the 0.98 bar at any cap or either window.
- The honest baseline still reproduces §3.4 exactly: U=1 clears at delta=8;
delta=16 needs U=2 at W=10, or W=20 at U=1.
- The structural decomposition holds: countable share falls 97% -> 77% -> 54%
with alpha while referenced-of-countable stays high (70-92%), so the loss is
the first-fork restriction and not a drained queue.
§8.3 item 20 closes: every adversary study with the default selection has now
been re-measured, no conclusion was overturned, and the one materially resized
number was the parent anchor's cost under suppression (0.021 -> 0.006). What
replaces it is a residual worth stating rather than an open task — a Pareto draw
can leave adversary_frac unreachable outright, which now warns and leaves that
replicate with a weaker adversary than its label. That biases an attacked arm
toward the honest baseline, so it is conservative, but a sweep quoting levels
should report how many of its replicates warned.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
097543a5f9
|
Re-measure the W pairing paired, and correct my own severity numbers
The W = 12 pairing is now measured the way a ~0.001 claim has to be: every
integer W from 8 to 15, 32 replicates, and paired_streams so the whole grid runs
on common random numbers (_base_key excludes both uncle_window_anchor and
window_absorption, so a replicate draws one stake vector, one graph and one
lottery for every cell). The earlier unpaired sweep reported +0.0008 against a
standard error of 0.0009 — it could not resolve its own headline.
Paired against today's recipe (uncle-anchored, W = 10):
parent W=10 -0.0056 +- 0.0005 t = -10.4
parent W=11 -0.0024 +- 0.0005 t = -4.5
parent W=12 +0.00004 +- 0.00050 t = 0.1 <- parity
parent W=14 +0.0016 +- 0.0004 t = 3.5
W = 12 is the smallest window reaching parity, and the parity is exact rather
than marginal: W = 11, one interval short, is still resolvably worse. p_ref
agrees at the same window (0.938 vs 0.939) instead of lagging to W = 15 as the
unpaired edition had it. Also states what the sweep makes visible: widening
today's uncle-anchored rule buys +0.0018 on its own, so W = 12 makes the swap
cost-neutral against the CURRENT recipe rather than optimal in absolute terms.
CORRECTIONS to the previous commit, which measured contamination on the wrong
RNG stream. The engine draws stake from seedseq_for(config).spawn(...)[0]; I
used rng_for(config), the root. Both are valid stake draws, neither is the same
vector. Redone properly:
- The capstone draw was NOT contaminated: 0 of 8 replicates over 1.25x its
label, worst 0.369 against 0.30, no majority. My "2 of 8, one a 61%
majority" was wrong and is withdrawn from §8.4 and §9.
- The finding that survives is sharper: on that same mild overshoot the spec's
rule moved 0.001 and the parent-anchored variant moved 0.016. A rule leaning
harder on the reference window is far more sensitive to an oversized
suppressing coalition.
- Genuinely contaminated: §6.12's 12-replicate W sweep (2 majorities, worst
0.720) and §6.8's selfish margin at a=0.3 and a=0.4 (2 and 1 majorities).
§6.5's variants and §6.8's a=0.2 arm are clean; §8.3 item 20 narrowed to the
one sweep that still needs re-running.
- The general severity is worse than first stated, not better: at the report's
geometry a nominal 0.3 realised a majority in 12% of replicates.
Two more defects found on the way:
- stake_for(config) added, because scripts used rng_for and the engine uses
the spawned child — so every script that rebuilt a tree was analysing a
different network than the trajectory it was compared against. All scripts
and tests now use it.
- A coalition member could receive a private block BEFORE its parent: the
arrival was clamped against the PRODUCER's view of the parent and applied to
the whole coalition, so a member still awaiting a public parent got the child
first. Now clamped per member. Caught by the existing arrival-order test once
the stake derivation was corrected.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
5a8cc4437a
|
Item 5 resolved: the uncle cap is not the binding constraint under a private chain
With the SM1 adversary in the engine, the question item 5 could not ask is now a measurement. It asked whether the honest-load cap needs margin when the attack inflates orphaning, on the theory that owed uncles would defer past W. They do not. Sweeping U x W x alpha against the attack (512 runs, N=1000, k=256, 8 reps): at the design point and alpha = 0.3, D-hat/D reads 0.729/0.755/0.738/0.758 for U = 1/2/3/4 -- flat within noise -- and no attacked cell reaches the 0.98 bar at any cap or either window. The honest baseline in the same sweep reproduces sec 3.4 exactly (U=1 clears at delta=8; delta=16 needs U=2 at W=10 or W=20 at U=1), which is a useful check that the engine adversary has not disturbed the honest regime. Splitting the honest orphans by WHY they went unreferenced explains it. Neither existing metric separates the two causes -- p_ref mixes them, and deep_ref_share is 0 by construction here because the proposer's candidate filter drops deep-fork blocks before any reference to one is proposed -- so the script walks the tree. Countable share (first block of its fork): 97% honest, 76-81% at alpha=0.2, 59-72% at alpha=0.3. Referenced OF those: 90-93% honest, 84-93% and 80-88% under attack. The queue drains at essentially the honest rate whatever the cap; what collapses is eligibility. An override discards a CHAIN and only its first block has a parent on the surviving chain, so 20-40% of the honest work destroyed is unreferenceable by construction. U governs drain capacity for candidates that exist; it cannot manufacture eligibility. So U = ceil(rho) + 1 stands unchanged and needs no adversarial margin -- and the one place the cap does matter is the honest-load reason it was sized for (U=1 -> 2 lifts the referenced-of-countable rate from 84% to 93% at alpha = 0.2, then U=4 adds nothing). This is the fig36 first-fork ceiling reached from an independent direction: a per-node network simulation with real delays and a real queue, versus a stationary MDP. Two models sharing no code, agreeing on direction and rough size, is the strongest available evidence that the ceiling is a property of the counting rule rather than of either model. Recorded in sec 6.6 and sec 6.8, with the sec 6.8 structural argument corrected: it holds for orphans that are referenceable, but a private chain buries most of them out of reach. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
3708d03e22
|
Private-chain (SM1) adversary in the per-node engine
Sec 6.8 recorded that "the per-node engine has no private-chain strategy", which is why every selfish result came from the global race model with uncle recovery as a free knob eta -- and why open item 5 (does the uncle cap need margin under attack-inflated orphaning?) could not be sized: a knob has no queue to overflow. adversary_strategy="selfish" adds it. The coalition mines one shared private chain and releases under the classic SM1 rules in (a, h) form: adopt when the public chain wins, match at equal length, override at a one-block lead, else wait. Only VISIBILITY is modelled -- the coalition's mining needs no special case, because a member's fork choice already builds on the private tip whenever it leads (that tip has the greatest height among blocks the member can see) and falls back to the public chain exactly when the public chain overtakes, which is the adopt branch. So the private chain forms, extends and is abandoned emergently, and the code that had to be written is the arrival matrix. Design notes worth keeping: - Private blocks reuse the sentinel `withhold` already had (never-arrives), so the existing exclusions from canonical-tip selection apply unchanged; release flips it back and gossips DIRECTLY from the producer, bypassing Blend, since an adversary has no privacy budget to respect and wants the race won. - A private chain breaks the windowed horizon's premise (a hidden block is old enough to look fully-propagated while no honest node has it, and it becomes visible LATER, which the one-way frontier pointer cannot revisit), so selfish forces the exact full scan and full matrix. - Blocks still hidden at epoch end are abandoned and hidden from the coalition too, or the canonical-tip search would crown a chain no honest node saw. Validated against Eyal-Sirer at sub-slot latency: revenue share 0.0356 vs an exact 0.0356 at alpha = 0.1, and above the closed form at higher alpha by just the margin the alpha_eff fork-amplification correction predicts (0.498 vs 0.484 at alpha = 0.4, with fork rate 0.38). Adds p_ref_honest: the reference rate over orphans produced OUTSIDE the coalition. Under a private-chain attack this diverges sharply from p_ref, and only the honest one measures the repair the report credits to uncle counting -- an attacker's own discarded blocks are its loss to bear. test_fork unpacks fork_stats positionally, so its three call sites take the new fifth value. 247 tests pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |