research/tools/simulators/tsi/tsi-sim-pernode/configs/window-uncles-anchor.yaml
Marcin Pawlowski 99ce8b76d0
Correct sec 6.12: the parent anchor does move the window floor
My sec 6.12 claim was "costs no honest recovery at any tested delay". That
measurement held max_uncles = 4 -- a slack cap, which hides the window entirely,
since with four uncle slots the queue drains faster than the window can bind.
Re-running the sec 3.4 absorption sweep at U = 1, where the window IS the binding
constraint, shows the cost is real:

  delta=4   knee W 5 -> 6    at W=10: 0.9982 -> 0.9981  (free)
  delta=8   knee W 6 -> 8    at W=10: 0.9963 -> 0.9930  (-0.0033)
  delta=16  knee W 20 -> 20  at W=10: 0.9658 -> 0.9326  (-0.0332)

The floor rises by one to two block-intervals, exactly what a parent gap running
one block-interval longer than the uncle gap predicts -- the prediction I wrote
into the plan and then failed to test, because the first study was configured
with a cap that masked it.

Both statements are true and the report now carries both: at the recommended
U = ceil(rho)+1 the anchor is free, and at U = 1 it costs measurably from
delta = 8 up. The consequence for sizing is that W should be measured against
the parent gap under the new rule -- W = 12 restores the margin W = 10 has
today, inside the spec's floor(0.6k) bound, so it needs no further spec change.
The delta = 16 row is U-limited rather than window-limited (rho ~ 0.87 against
U = 1, below the recommended cap), and is labelled as such.

The sec 8.5 spec-delta row and the sec 6 arc bullet carried the same overclaim and
are corrected too.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 18:27:08 +02:00

33 lines
2.3 KiB
YAML

# Does the parent anchor change the uncle cap rule U = ceil(rho) + 1? (§3.3, §3.5, §6.12)
#
# The cap is sized by the LOAD: one uncle slot drains one concurrent block per block interval,
# so U must cover rho with a margin. Anchoring the window to the uncle's parent does not change
# how fast the queue drains, but it does shrink the candidate pool — an orphan whose parent has
# aged past the window is no longer eligible — so the queue it drains is a slightly different
# one. This checks whether the smallest U reaching the 0.98 recovery bar moves.
#
# W is held at the recommended 10 block-intervals throughout, since the window's own floor is
# measured separately by absorption-window-anchor.yaml; here the window is meant to be slack so
# that U is the binding constraint.
# 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 — the deployment transport
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: [4.0, 8.0, 16.0, 24.0] # rho ~ 0.27 / 0.47 / 0.87 / 1.27
window_absorption: [10] # the recommended W; slack by design here
uncle_window_anchor: [uncle, parent] # spec rule vs the §6.12 proposal
max_uncles: [0, 1, 2, 3, 4] # 0 = baseline; find the smallest U clearing 0.98
uncle_strategy: [oldest] # spec Uncle Selection
init_dest: [common] # per-node initial D_est from agreement
replicates: 12
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