mirror of
https://github.com/logos-blockchain/research.git
synced 2026-08-07 19:53:10 +00:00
Open item 11 listed "a random (rather than oldest-first) uncle-selection draw" as an untested spec sensitivity. The spec does not leave it open: Uncle Selection in cryptarchia-v1-protocol.md has the proposer take the oldest candidates first, deterministically, because an uncle expires w_u slots after its own slot. That is exactly what every result in the report already uses, so the item is a conformance match, not a gap -- and the simulator comment calling uncle_random_p "the spec's unbiased coin" cites text the spec no longer has. What is genuinely open is deviation FROM that rule: selection is proposer-local and the uncles field is never validated. configs/uncle-selection.yaml measures the cost. A proposer that includes each candidate on a fair coin instead loses up to 0.10 in D-hat/D, and 0.063 at the recommended W = 10 once rho ~ 1 (0.902 vs 0.965, t = -8.6). At the design point the margin survives but is spent: 0.980 vs 0.997 against a 0.98 bar. The loss does not close as W grows, because a coin wastes opportunities rather than queue capacity and a well-sized window is precisely what keeps the queue short enough for that to bite. This matters for the sec 8.5 reward recommendation: the spec argues a proposer has no incentive to deviate BECAUSE uncles grant no reward, and paying them removes that argument. Also adds adversary_selection=whale (the largest holders at matched stake, for the untested concentration case). The marker is appended to key() only when non-default so every historical run's seed stays byte-identical, guarded by a test alongside the paired_streams one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
42 lines
3.2 KiB
YAML
42 lines
3.2 KiB
YAML
# Does the SPEC's uncle-selection rule move the window floor? (§3.4, §8.3 item 11)
|
|
#
|
|
# Every window result in the report fills uncle slots OLDEST-FIRST, and the ~7/f floor is derived
|
|
# from exactly that: an orphan queue drained one per block interval. The spec selects with an
|
|
# unbiased per-candidate coin instead (uncle_random_p = 0.5). §3.4 argues a coin drains a queued
|
|
# orphan no faster than oldest-first, so the floor under it can only be the same or higher, and
|
|
# reads the margined W = 10/f as covering the difference. That argument has never been measured.
|
|
#
|
|
# This sweeps the window absorption parameter under BOTH selection rules at the two delays that
|
|
# bracket the design regime (rho ~ 0.6 and rho ~ 1), and asks one question: does the recovery knee
|
|
# move, and does W_abs = 10 still clear?
|
|
#
|
|
# UNPAIRED by construction: uncle_strategy is part of the RNG identity, so the two arms draw
|
|
# independent stake, graph and lottery streams — and unlike the countable-vs-old comparison there
|
|
# is no way to share them, because the coin arm consumes draws the oldest-first arm does not.
|
|
# Note the §9 negative-control idiom is NOT available here: SweepConfig.expand() collapses U=0
|
|
# across uncle_strategy (with no uncle slots the two arms would be the identical run), so there is
|
|
# no U=0 gap to read a noise floor off. Resolution comes from the replicate SEM within each cell
|
|
# instead, which is why this runs 10 replicates against absorption-window.yaml's 5. U=0 is still
|
|
# carried as the recovery baseline the knee is measured against.
|
|
# Latency is in SLOTS (1 slot = 1 s).
|
|
n_nodes: [1000] # network size
|
|
stake_dist: [pareto] # heavy-tailed (realistic) stake distribution
|
|
topology: [blend] # Blend mixnet (delay stresses the window)
|
|
degree: [6] # peering degree of the d-regular graph
|
|
link_latency_mean: [0.5] # natural geographic transport (sub-slot)
|
|
link_latency_dist: [geo] # real-world geographic band mixture
|
|
blend_hops: [3] # fixed hop count; delay is the swept knob
|
|
blend_delay_max: [8.0, 16.0] # design point (rho ~ 0.6) and the boundary (rho ~ 1)
|
|
window_absorption: [1, 2, 3, 5, 7, 10] # W: window in expected block-intervals
|
|
max_uncles: [0, 1] # 0 = negative control (rule never invoked), 1 = U
|
|
uncle_strategy: [oldest, random] # THE comparison: FIFO fill vs the spec's coin
|
|
init_dest: [common] # per-node initial D_est from agreement
|
|
replicates: 10 # 2x absorption-window.yaml: the arms are unpaired
|
|
base: # per-run settings shared by every cell
|
|
k: 2160 # true security parameter
|
|
epochs: 20 # equilibrium within ~2 epochs; burn 50%
|
|
f: 0.03333333333333333 # slot activation coefficient (1/30)
|
|
genesis_d_factor: 0.5 # start near true stake (cheap epoch 0)
|
|
early_stop: true
|
|
uncle_random_p: 0.5 # the spec's unbiased coin (only read by `random`)
|