From e3da5c8fca007d118cbb272f14510327f5620dac Mon Sep 17 00:00:00 2001 From: Marcin Pawlowski Date: Wed, 5 Aug 2026 17:25:27 +0200 Subject: [PATCH] Audit sec 8.5 against spec 1.2.1: fix the window rationale and the open-task claim Full pass over every spec claim the report makes, against the uncle-references RFC at 521f20dd (v1.2.1, 2026-08-05). Thirteen claims check out verbatim, including the two that carry recommendations: PRECISION = 1e3 with f_p = truncate(f * PRECISION) confirms row 14's premise exactly, and "carry no fork-choice weight and grant no reward, a proposer has no incentive to deviate" confirms the uncle-reward row and implication (ii). MAX_UNCLES = 4, w_u = W/f, W <= floor(0.6k), T = 6k/f, epoch = 10*floor(k/f), the counting rules, duplicate handling and counting-only status all hold. Two claims did not. The W row rebutted "a larger window would gain little". That sentence is gone: the rationale was rewritten in the same revision that introduced W, and now justifies the UPPER bound W <= floor(0.6k) on two grounds (the candidate is still in the proposer's block tree; referencing blocks stay in the window's own epoch) while asserting of the value only that it "comfortably captures the forks worth referencing". Rebutting deleted text is worse than useless here, because the new bound is 1296 slots at k = 2160 -- so this report's own 450-600 widening near rho ~ 1 is already permitted and needs no spec change, which is a better outcome than the tension the row used to claim. What the spec still does not give is a LOWER bound, which is what the 7/f floor supplies. The intro said the spec flags w_u and MAX_UNCLES as "provisional", leaving their tuning "as an open task of [Analysis] Total Stake Inference". The word provisional appears in no spec document at any revision. The open task is real but different: analysis-total-stake-inference.md records that its analysis covers the design WITHOUT uncle references and that re-analyzing with uncle-inclusive block counts "is an open task" -- which is what this report does, so the claim gets stronger by being stated accurately. Also pins the revision audited, and notes that these rules live on the in-flight RFC rather than the released logos-lips copy, which is still 1.1.0 with no uncle references at all. Co-Authored-By: Claude Opus 5 (1M context) --- reports/tsi/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/reports/tsi/README.md b/reports/tsi/README.md index 5b93c80..388a17f 100644 --- a/reports/tsi/README.md +++ b/reports/tsi/README.md @@ -860,14 +860,14 @@ The whole recipe coheres: accurate to the true stake (the ~1 % rounding removed) ### 8.5 Recommendation vs the current spec -The deltas this report recommends, in one place (this is a parameter-selection report meant to inform the spec — and the spec explicitly flags `w_u` and `MAX_UNCLES` as *provisional*, leaving their tuning "as an open task of [Analysis] Total Stake Inference", i.e. this report): +The deltas this report recommends, in one place. This is a parameter-selection report meant to inform the spec, and it answers an open task the spec states: `analysis-total-stake-inference.md` records that its analysis "covers the total stake inference design **without** uncle references … the results below apply to the design without uncle references", and that "re-analyzing the algorithm with the block count that includes referenced uncles is an open task." That re-analysis is what this report is. Everything below is measured against the spec at revision **1.2.1** (`cryptarchia-v1-protocol.md`); the uncle-reference rules it audits live on the in-flight uncle-references RFC rather than in the released `logos-lips` copy, which is still at 1.1.0 and has no uncle references at all — so a reader comparing against a released spec will not find them. | parameter | current spec / default | recommended | why | |---|---|---|---| | uncle counting | per-block (double-counts multi-winner slots) | **per occupied slot** | lands the estimate at exactly `D`, not `c(f)·D` ([§2.1](#s2-1)) — the density-bug fix | | on-chain `f` precision | 10⁻³ (`f_p = 0.033`) | **10⁻⁶** (`0.033333`) | removes the residual ≈ 1 % `f/f_p` offset ([§2.2](#s2-2)) | -| uncle window `W` | `w_u` (the spec's window symbol; this report's window is `W`, and its `w_u` is the uncle *reward* below) = 300 slots (provisional) | **10/f = 300 slots** (confirms the default), widen to 450–600 near `ρ ≈ 1` | ≥ 7/f floor set by block *spacing*, not network delay — which revises the spec's rationale: its "300 slots comfortably captures forks" premise is only a ~1.5× margin over the 7/f floor, and "a larger window would gain little" fails near `ρ ≈ 1`, where W = 600 recovers ≈ 0.99 vs ≈ 0.96 at W = 300 (N = 1 000); buffers fork bursts ([§3.4](#s3-4)) | -| uncle cap `U` | `MAX_UNCLES` = 4 (provisional) | **`⌈ρ⌉ + 1`** = 2 at the Blend target — well inside the spec's cap of 4 | the load-plus-margin rule ([§3.3](#s3-3)); 4 leaves headroom for heavier loads | +| uncle window `W` | `W` = 10 block-intervals, so `w_u = W/f` = 300 slots, bounded `1 ≤ W ≤ ⌊0.6k⌋` | **10/f = 300 slots** (confirms the default), widen to 450–600 near `ρ ≈ 1` | the floor is ≥ 7/f, set by block *spacing* rather than network delay — which supplies what the spec's rationale leaves out. The spec justifies the *upper* bound (a candidate within `w_u` is still in the proposer's block tree, and referencing blocks stay in the same epoch as the window they count) and asserts of the value itself only that this window "comfortably captures the forks worth referencing"; it states no lower bound, and 300 slots is only a ~1.5× margin over the measured one. The `⌊0.6k⌋` ceiling is 1296 slots at k = 2160, so the 450–600 widening recommended near `ρ ≈ 1` — where W = 600 recovers ≈ 0.99 against ≈ 0.96 at W = 300 (N = 1 000) — is well inside what the spec already permits, and needs no spec change ([§3.4](#s3-4)) | +| uncle cap `U` | `MAX_UNCLES` = 4 | **`⌈ρ⌉ + 1`** = 2 at the Blend target — well inside the spec's cap of 4 | the load-plus-margin rule ([§3.3](#s3-3)); 4 leaves headroom for heavier loads | | peering degree | (operator choice) | **≥ 6, scaled with N** | keeps `ρ` and reorg depth bounded at scale ([§3.7](#s3-7), [§6.10](#s6-10)) | | uncle rewards | none (spec: uncle grants no block reward) | **soft inclusion, `w_u + w_n < 1`** | fork-safe fairness + anti-hiding ([§6.7](#s6-7)–[§6.8](#s6-8)) | | operating point | set by the Blend privacy budget | **`ρ = f·D_vis < 1`** | accuracy, weak grinding, shallow reorgs — one rule ([§6.3](#s6-3), [§6.10](#s6-10)) |