From 47b358dee5686d82580179640830e25b25dad548 Mon Sep 17 00:00:00 2001 From: Florent Tapponnier Date: Thu, 21 May 2026 19:02:03 +0200 Subject: [PATCH] docs: Solana TX landing active bench V0-Lean Pre-registered methodology v1.1 + launch plan (5 services x us-east x 1h cadence, ~$159/mo). Required by Rule #1 to be merged before any sponsor contract. - methodology/solana-tx-landing-active.md: probe payload, submission flow, drop reasons, sponsor-proof guarantees, versioning - solana-landing-tiered-architecture.md: V0-Lean spec + escalation tiers (V0.5, V1, V2) - solana-landing-cost-model.md: probe cost formula + tip-floor analysis (note flagging arithmetic error in scenarios table) - solana-landing-deployment-checklist.md: 8-step Florent runbook (keypair, API keys, Railway env, sponsor outreach) - solana-landing-active-bench-plan.md: redirect to current docs --- docs/methodology/solana-tx-landing-active.md | 158 ++++++++++ docs/solana-landing-active-bench-plan.md | 31 ++ docs/solana-landing-cost-model.md | 158 ++++++++++ docs/solana-landing-deployment-checklist.md | 250 ++++++++++++++++ docs/solana-landing-tiered-architecture.md | 289 +++++++++++++++++++ 5 files changed, 886 insertions(+) create mode 100644 docs/methodology/solana-tx-landing-active.md create mode 100644 docs/solana-landing-active-bench-plan.md create mode 100644 docs/solana-landing-cost-model.md create mode 100644 docs/solana-landing-deployment-checklist.md create mode 100644 docs/solana-landing-tiered-architecture.md diff --git a/docs/methodology/solana-tx-landing-active.md b/docs/methodology/solana-tx-landing-active.md new file mode 100644 index 00000000..e0b360ad --- /dev/null +++ b/docs/methodology/solana-tx-landing-active.md @@ -0,0 +1,158 @@ +# Methodology — Solana TX Landing (Active Probing) + +> **Pre-registered methodology.** Pinned commit before any sponsor contract is signed. Changes ship as public PRs with a 14-day comment window. Disputes go through public GitHub issues. +> +> **Version :** v1.0 — first commit 2026-05-21. Bench № 016 (Solana TX Landing). +> **Replaces / extends :** the observational tip-wallet attribution methodology that ships with the same bench page (kept as the "Market Share" tab). + +--- + +## 1. Question we answer + +For each Solana transaction landing service, **how long does it take for a transaction submitted via that service to be confirmed on mainnet, and what fraction never confirms within a usable window** — measured from a single fixed geographic origin, on a uniform synthetic payload, at a uniform cadence. + +The bench does **not** answer "which service is best for your trading bot" — that requires modeling your own payload size, tip elasticity, and venue. The bench answers "what is the typical, comparable, reproducible time-to-land per service today." + +## 2. Scope (V0-Lean launch) + +| Dimension | Value | +|---|---| +| Services probed | 5 — Jito Block Engine, Helius Sender, Astralane Iris, Nozomi (Temporal), 0slot.trade | +| Region | 1 — Railway us-east (Newark / NY area) | +| Cadence | 1 cycle per hour | +| Duration | continuous, 24 / 7 | +| Window for headline metrics | rolling 7-day weekly leaderboard | +| Confirmation level | `confirmed` (1+ block confirmation) | + +Services and regions are added through the public escalation rules in [`solana-landing-tiered-architecture.md`](../solana-landing-tiered-architecture.md). Any expansion is a PR + 14-day window — never a silent change. + +## 3. Probe payload (exact) + +Every probe is a single Solana transaction containing three instructions, in this order : + +1. `ComputeBudgetProgram.SetComputeUnitLimit(50 000)` — caps compute units. +2. `ComputeBudgetProgram.SetComputeUnitPrice(50 000 micro-lamports)` — priority fee per CU. +3. `SystemProgram.Transfer(from = prober keypair, to = prober keypair, lamports = 1)` — the payload itself, self-transfer of 1 lamport. Solana requires non-zero state-touching for a tx to be valid; self-transfer is the minimum honest payload. +4. `SystemProgram.Transfer(from = prober keypair, to = , lamports = )` — the tip required by the landing service. +5. `MemoProgram.Memo("ocb---")` where `cycle_id` is a per-cycle 8-byte random hex generated once and shared across all per-service probes in the cycle. This lets us correlate the 5 simultaneous probes on-chain. + +The exact tip amount per service is published as part of this methodology and frozen unless a methodology PR amends it : + +| Service | Tip lamports | Source / justification | +|---|---:|---| +| Jito Block Engine | 10 000 | "Competitive" floor per docs.jito.wtf — above 1 000 doc minimum, below 50th-percentile observed real-traffic tip | +| Helius Sender | 10 000 | Same with `?swqos_only=true` (isolates Helius own path from Jito fan-out) | +| Astralane Iris | 500 000 | Mid-range net of refunds per astralane.gitbook.io | +| Nozomi (Temporal) | 1 000 000 | Hard floor per use.temporal.xyz/nozomi/tipping-and-faq | +| 0slot.trade | 1 000 000 | Hard floor per 0slot.trade | + +We do **not** vary tip amount across cycles. A "tip elasticity" experiment is a separate, sponsored methodology PR. + +## 4. Submission flow (per service, per cycle) + +1. Fetch a recent blockhash via the public mainnet RPC (`api.mainnet-beta.solana.com`) with `commitment = "processed"`. The same blockhash is used for all services in the same cycle so they share a chain-state reference point. `processed` is preferred over `confirmed` because the resulting blockhash is fresher (~400 ms vs ~6 s); the marginal fork risk is acceptable since landing services dedup on signature, not blockhash. +2. Build the transaction described in §3 for that service (the tip-transfer differs per service). +3. Sign with the region's persistent keypair. +4. Capture `submit_slot = getSlot(commitment="processed")` and `submit_wallclock = time.Now()`. +5. POST the base64-encoded signed transaction to the service's documented submission endpoint (exact URLs published in the harness source) with `skipPreflight = true`, `maxRetries = 0`, `encoding = "base64"`. Per-service auth headers / query params are applied as documented. +6. Capture the returned signature (or fail-fast on RPC error). +7. Poll `getSignatureStatuses` on the public mainnet RPC every 1 second. +8. On status reaching `confirmationStatus = "confirmed"` or `"finalized"`, record `land_slot` from the response context and `land_wallclock = time.Now()`. Classify as **landed**. +9. If 60 seconds elapse without a non-null `confirmationStatus`, abandon the poll. Classify as **dropped** with reason `timeout`. +10. If the original submission returned a transport error (HTTP timeout, DNS, EOF, connection refused), classify as **dropped** with reason `network_error`. If the upstream returned HTTP 419 / 429 or a JSON-RPC error containing "rate limit" / "too many requests", classify as `rate_limited`. If the submission was rejected with a structured RPC error (`InstructionError`, `BlockhashNotFound`, etc.) or the on-chain status comes back with an `Err`, classify as `invalid`. + +The 5 services for a given cycle are submitted **in parallel** (Go goroutines) so they sample the same congestion window. The order of `submit_slot` reads is arbitrary but all reads happen within 200 ms. + +## 5. Metrics (Prometheus, exposed at `:2112/metrics`) + +``` +solana_landing_probe_success_total{service, mode, region} counter +solana_landing_probe_dropped_total{service, mode, region, reason} counter + # reason: timeout | invalid | network_error | rate_limited + +solana_landing_probe_latency_slots{service, mode, region} gauge (last observed slot delta) +solana_landing_probe_latency_slots_histogram{service, mode, region} histogram + # buckets: 1, 2, 3, 5, 10, 20, 50, 100 + +solana_landing_probe_latency_ms{service, mode, region} gauge (last observed wall-clock ms) +solana_landing_probe_latency_ms_histogram{service, mode, region} histogram + # buckets: 100, 250, 500, 1000, 2000, 5000, 10000, 30000, 60000 + +solana_landing_probe_keypair_balance_sol{region} gauge +solana_landing_probe_keypair_low_balance_total{region} counter +solana_landing_probe_cycle_total{region} counter +solana_landing_probe_last_cycle_timestamp_seconds{region} gauge +solana_landing_probe_enabled{region} gauge + # 1 when prober configured + running, 0 in pure observational mode +``` + +The `rate_limited` reason groups responses where the upstream service returns HTTP 419 / 429 or a JSON-RPC error containing "rate limit" / "too many requests". Reported separately from `invalid` because rate-limiting is a quota/operational state, not a landing-quality signal. + +**Label semantics :** + +- `service` ∈ {jito, helius-sender, astralane, nozomi, 0slot} +- `mode` is set on `service = helius-sender` only and takes values `swqos_only` or `dual` (other services: `mode = "default"`) +- `region` ∈ {us-east} (V0-Lean); will expand under §7 + +**Headline metrics** displayed publicly on the bench page : + +- `landing_rate = success_total / (success_total + dropped_total{reason="timeout"})` over the last 7 days +- `p50_latency_ms` and `p99_latency_ms` over the last 7 days, per service, per region +- `p50_slot_delta` and `p99_slot_delta` over the last 7 days, per service, per region + +## 6. Jito control probe + +Three services (Helius default mode, Astralane Iris, Nozomi) submit a portion of their flow through Jito internally. Without controlling for this, their measured landing time conflates "this service's own path" with "Jito's auction outcome via this service". + +The Jito control probe is the standard Jito-direct probe **fired in the same cycle as the suspect services**, with the same tip floor (10 000 lamports) and same blockhash. If a suspect service consistently lands at the same `submit_slot + Δ` as the Jito control, the suspect service is interpreted as a Jito routing wrapper for that cycle. We do not currently publish a derived "service-net-of-Jito" metric, but the raw data supports such derivation. + +For Helius we additionally probe in `?swqos_only=true` mode in every cycle (see §3) to publish a clean Helius-only metric series. + +## 7. Versioning rules + +1. **Any** change to §3 (payload), §4 (submission flow), §5 (metric definitions), or the per-service URLs ships as a public PR against this file with a 14-day comment window before merge. +2. Adding a new service requires a PR that updates §2 + §3 + §5 and is announced on the OpenChainBench blog with a 14-day window. Removing a service same. +3. Tip-amount changes (§3) require a PR with a written explanation of why the new amount better reflects "competitive" floor. +4. Region additions and cadence changes are PR + 14-day window. +5. Metric removal or label rename is **prohibited within a version**. Such changes require a major version bump (v1 → v2) with a 30-day shadow-run period publishing both old and new metric families in parallel. + +## 8. Reproducibility + +The full harness source is published at `mobula-api/miniapps/solana-tx-landing/` (Go). Anyone with a funded Solana keypair (~1 SOL) can clone, set the `SOLANA_PROBE_KEYPAIR_BASE58` env var, run the binary, and reproduce all metrics. The bench does not rely on any internal Mobula service for measurement. + +Anyone replicating the bench from a different geographic origin will see different absolute latencies (since service POPs vary by region) but should see the same relative ranking trends over a 7-day window. Discrepancies of more than 1 percentile rank between independent replications should be filed as GitHub issues. + +## 9. Statistical power statement + +At V0-Lean cadence (1 / h × 1 region × 5 services) a single service accumulates 168 probes per rolling 7-day window. With this sample size : + +- `p50_latency_ms` standard error ≈ ±5 % at typical service variance +- `p99_latency_ms` standard error ≈ ±15 % (broad; published with confidence interval) +- Difference in `landing_rate` between two services detectable at 5 pp gap, p < 0.05, after ~18 days of data + +For sub-weekly resolution, cadence must increase. The escalation path is in [`solana-landing-tiered-architecture.md`](../solana-landing-tiered-architecture.md) §7. + +## 10. Limitations (explicit) + +- **Single-region**: latency reflects what a us-east client sees. Services with non-us-east-anchored POPs may rank differently from sgp or eu-west. +- **Synthetic payload**: a 1-lamport self-transfer + memo is the smallest valid mainnet tx. Real trading payloads (Jupiter swap, Raydium add-liquidity) are heavier and may behave differently in tip elasticity. The bench does not extrapolate. +- **Fixed tip per service**: the bench measures landing performance *at one tip level*. A service that lands at 99 % for 1 M lamports may land at 50 % for 100 k lamports. The bench does not characterize the tip elasticity curve in V0-Lean. +- **Fan-out attribution**: §6 partially handles Helius / Astralane / Nozomi fan-out via the Jito control probe, but does not produce a derived "service-net" published metric in V0-Lean. +- **Confirmation level**: we use `confirmed` (1+ confirmation). A service that lands at `processed` but never reaches `confirmed` would be undercounted. We do not currently publish a `processed` series. +- **Mainnet incidents**: when Solana mainnet halts or congests beyond 60-second confirmation, all services rank identically high in `dropped{reason=timeout}`. The bench page must surface a "chain health overlay" so readers can distinguish service problems from chain problems. +- **Geographic biases**: services with no us-east POP (none in the V0-Lean scope) are penalized vs services with one. We disclose POP locations in the bench page methodology block. + +## 11. Sponsor independence + +Sponsorship policy and the disclosure block live in [`solana-landing-tiered-architecture.md`](../solana-landing-tiered-architecture.md) §6. The contract template enforces : + +- Sponsors fund operations and receive newsletter visibility, case studies, integration support. Never leaderboard influence, advance results, or methodology changes. +- The non-suppression clause grants the sponsor a single remedy for unfavorable results : terminate the agreement and receive a pro-rata refund. Never edit, delay, or selectively publish. +- Methodology changes (this document) ship as PRs and are independent of sponsor contracts. + +## 12. Change log + +| Version | Date | Change | +|---|---|---| +| v1.0 | 2026-05-21 | Initial pre-registration. V0-Lean scope : 5 services × 1 region × 1 / h. | +| v1.1 | 2026-05-21 | Pre-launch reconciliation with implementation : metric names from `ocb_solana_landing_*` to `solana_landing_probe_*` (matches sibling OCB benches), `rate_limited` added as 4th drop reason, latency_ms histogram bucket list adjusted to include 250 ms and 30 s, blockhash commitment rationale clarified, memo format clarified (`ocb---` where cycle_id is itself the 8-byte random hex shared across all per-service probes in the cycle), `solana_landing_probe_enabled` gauge added so dashboards distinguish "prober disabled" from "prober stuck". | diff --git a/docs/solana-landing-active-bench-plan.md b/docs/solana-landing-active-bench-plan.md new file mode 100644 index 00000000..a01632d0 --- /dev/null +++ b/docs/solana-landing-active-bench-plan.md @@ -0,0 +1,31 @@ +# Solana TX Landing — Plan obsolète + +> ⚠️ **Ce document est obsolète depuis 2026-05-21.** +> +> Direction validée par Florent : ship **V0-Lean** (5 services × 1 région × 1 / heure × **$159/mo**) au lieu de l'ancien "Phase 0" à 8 services × 3 régions. +> +> Le plan courant est dans [`solana-landing-tiered-architecture.md`](./solana-landing-tiered-architecture.md). +> +> Le cost-model détaillé est dans [`solana-landing-cost-model.md`](./solana-landing-cost-model.md) — note de correction en tête du fichier. + +--- + +## Ce qui a changé + +| Avant (ce doc) | Après (tiered-architecture.md) | +|---|---| +| 8 services × 3 régions × 2 min | 5 services × 1 région × 60 min | +| Phase 0 = $1 452/mo (chiffre faux, vrai = $26 k/mo) | V0-Lean = $159/mo (calcul vérifié) | +| Services V0 : Jito + Helius + Nozomi + NextBlock | Services V0-Lean : Jito + Helius + Nozomi + Astralane + 0slot | +| Launch immédiat avec scope complet | Phasage : V0-Lean → V0-Daily → V1 → V2 sur signature sponsor | + +## Ce qui reste valide depuis ce doc + +- **Le Jito control probe** pour Helius/Nozomi/Astralane fan-out (gardé dans tiered-architecture §5). +- **Les 7 règles méthodologie sponsor-proof** (gardées dans tiered-architecture §6). +- **Le tier ladder Listed / Verified / Featured** pour le sponsoring (gardé). +- **L'ordre d'outreach sponsor** : Nozomi en premier (contact direct), 0slot ensuite via Discord. + +## Conservé pour archive + +Le contenu original n'est plus à jour mais reflète l'analyse initiale des 4 agents (provider matrix, architecture, cost model, sponsor bias). Si besoin de retrouver les détails par service (bloXroute, NextBlock, SVS qui sont reportés V1+), voir le rapport de l'agent provider matrix dans le transcript de la conversation du 2026-05-21. diff --git a/docs/solana-landing-cost-model.md b/docs/solana-landing-cost-model.md new file mode 100644 index 00000000..1d9620ed --- /dev/null +++ b/docs/solana-landing-cost-model.md @@ -0,0 +1,158 @@ +# Solana Tx-Landing Benchmark — Cost Model + +> ⚠️ **Correction 2026-05-21 :** la table de scénarios §3 contient une erreur d'arithmétique d'un facteur ~18× sur les coûts mensuels. Le coût réel d'un "Phase 0" tel que défini ici (8 svc × 3 reg × 2 min) est **~$26 140/mo** et non $1 452/mo. Voir la note de correction §3 corrigée. +> +> **Le plan courant n'utilise plus ce scope.** Le launch validé est V0-Lean (5 svc × 1 reg × 60 min × $159/mo) — voir [`solana-landing-tiered-architecture.md`](./solana-landing-tiered-architecture.md). Les sections §0 (assumptions), §1 (formule), §2 (statistical power), §4 (leviers), §5 (sensibilité), §6 (sponsorship) restent valides. Seul le tableau §3 (scenarios) est faux. + +--- + +> Active probing of 8 landing services × 3 regions, 24/7. Real signed mainnet txs. +> SOL price snapshot: **$86.20** (CoinGecko + Binance, 2026-05-21). Sensitivity from $80 to $300 shown in §5. + +--- + +## 0. Assumptions (explicit) + +| Variable | Value | Source / rationale | +|---|---|---| +| SOL price | $86.20 | CoinGecko `simple/price` 2026-05-21 | +| Solana base fee | 5,000 lamports/sig | Protocol constant | +| Priority fee CU price | 50,000 micro-lamports / CU | Median competitive level for trading txs | +| Compute units per probe | 50,000 CU | A minimal SOL self-transfer + tip transfer + memo | +| Priority fee per probe | 50,000 × 50,000 / 1e6 = **2,500 lamports** | CU price × CU | +| Probe fails ~ wasted tip | ~5% (we still pay tip on landing path; failed sends refund tip on some services) | Conservative | +| Services | 8 (Jito, Helius Sender, Nozomi, bloXroute, Astralane, 0slot, NextBlock, SVS) | Per spec | +| Regions | 3 (us-east, eu-west, sgp) | Per spec | +| Probe = 1 signed tx submitted to 1 service from 1 region | | | + +**Tip floor research (lamports per probe, "realistic competitive" = what you must pay to be representative of trading-bot traffic, not the doc-stated floor):** + +| Service | Doc floor | Competitive floor | Source | +|---|---:|---:|---| +| Jito Block Engine | 1,000 | **10,000** | [docs.jito.wtf](https://docs.jito.wtf/lowlatencytxnsend/) | +| Helius Sender | 1,000 | **10,000** | [helius.dev/docs](https://www.helius.dev/docs/sending-transactions/sender) | +| Nozomi (Temporal) | 1,000,000 | **1,000,000** | [use.temporal.xyz](https://use.temporal.xyz/nozomi/tipping-and-faq) | +| bloXroute Trader | 1,000,000 | **1,000,000** | [docs.bloxroute.com](https://docs.bloxroute.com/solana/trader-api/introduction/tip-and-tipping-addresses) | +| Astralane Iris | ~1,000,000 (refundable) | **500,000** (net of avg refund) | [astralane.gitbook.io](https://astralane.gitbook.io/docs/low-latency/submit-transactions/tip-refunds) | +| 0slot | 1,000,000 | **1,000,000** | [0slot.trade](https://0slot.trade/) | +| NextBlock | 1,000,000 | **1,000,000** | [docs.nextblock.io](https://docs.nextblock.io/) | +| SolanaVibeStation | 100,000 | **100,000** | [docs.solanavibestation.com](https://docs.solanavibestation.com/services/solana-node-services/lightspeed-transactions) | + +**Weighted-avg tip across 8 services** = (10k + 10k + 1M + 1M + 500k + 1M + 1M + 100k) / 8 = **577,500 lamports/probe**. + +--- + +## 1. Probe cost formula + +``` +cost_per_probe (lamports) = 5,000 (base) + 2,500 (priority) + service_tip +cost_per_probe (USD) = lamports × 1e-9 × SOL_USD +``` + +Per-probe USD cost at SOL = $86.20: + +| Service | Lamports | USD/probe | +|---|---:|---:| +| Jito | 17,500 | $0.00151 | +| Helius Sender | 17,500 | $0.00151 | +| SolanaVibeStation | 107,500 | $0.00927 | +| Astralane | 507,500 | $0.04374 | +| Nozomi | 1,007,500 | $0.08685 | +| bloXroute | 1,007,500 | $0.08685 | +| 0slot | 1,007,500 | $0.08685 | +| NextBlock | 1,007,500 | $0.08685 | +| **Sum / probe-set (all 8)** | **4,680,000** | **$0.4034** | + +A "probe-set" = 1 tx to each of the 8 services. Cost per probe-set per region = $0.4034. +A "full sweep" = 1 probe-set × 3 regions = **$1.210 / sweep**. + +--- + +## 2. Statistical power requirement + +Detecting a 5% absolute difference between two services at p₀ = 95% landing rate, α = 0.05, power = 0.80, two-proportion z-test: + +``` +n = (z_α/2 + z_β)² × [p1(1-p1) + p2(1-p2)] / (p1-p2)² +n = (1.96 + 0.84)² × [0.95·0.05 + 0.90·0.10] / 0.05² +n = 7.84 × 0.1375 / 0.0025 ≈ 431 probes per service per arm +``` + +So **~430 probes per service per region** to call a 5pp gap. To resolve the same gap **per hour** (e.g., detect a leader-rotation effect within a single hour window) you need ~430 probes/hour/service/region = **1 probe every 8.4 seconds per (service, region)**. That's the upper bound; weekly aggregation needs only ~2.5 probes/hour. + +For a 2pp gap (95% vs 93%) the requirement balloons to ~2,600/service/region — only Phase 1+ budgets reach this. + +--- + +## 3. Scenarios + +| | Probe interval | Sweeps/day | Daily probes (8 svc × 3 reg) | Daily USD | **Monthly USD** | Statistical resolution | +|---|---|---:|---:|---:|---:|---| +| **Micro** | 1 / 10 min | 144 | 3,456 | $9.69 | **$291** | Daily aggregation only; detects 5pp gaps over ~3 days | +| **Phase 0** | 1 / 2 min | 720 | 17,280 | $48.41 | **$1,452** | Detects 5pp gaps per service/region per **6h window**; daily leader-cycle resolution | +| **Phase 1** | 1 / 30 sec | 2,880 | 69,120 | $193.62 | **$5,809** | Detects 5pp gaps **per hour**; supports 2 tip tiers per service (low/high) → cost ×2 within budget by shrinking to 1/min | +| **Phase 2** | 1 / 10 sec | 8,640 | 207,360 | $580.86 | **$17,426** | 2pp gaps per hour, full leader-rotation (~4-slot) resolution; saturates statistical power for current scope | + +### Defending Phase 0 = $1.2k/mo + +Florent's number is **slightly conservative**: my model puts true Phase 0 at $1,452 at SOL=$86. At Florent's likely working assumption of SOL=$150 the same cadence costs **$2,527/mo** — so $1.2k/mo only holds at today's price OR with a slightly slower cadence (1 sweep per 2.5 min instead of 2 min, which still gives 6h 5pp resolution). The figure is defensible if disclosed with the SOL-price assumption. + +### What each phase unlocks + +- **Micro ($291):** dashboard demo + weekly methodology post. No intra-day signal. +- **Phase 0 ($1.2–1.5k):** public leaderboard with daily updates; can argue "service A beat service B today" within 6h windows. **Recommended launch tier.** +- **Phase 1 ($5.8k):** hourly leaderboard + tip-tier experiments (run each service at floor AND competitive, exposing whether bloXroute's higher mandatory tip actually buys landing). This is where the bench becomes a research product, not a dashboard. +- **Phase 2 ($17.4k):** diminishing returns on Solana alone. The marginal $ is better spent adding chains (Sui, Aptos, BSC priority lanes) or stake-weighted-QoS variants. + +--- + +## 4. Cost levers ranked by elasticity (signal-per-$) + +| Lever | Cost elasticity | Signal elasticity | Verdict | +|---|---|---|---| +| **Tip size on Nozomi/bX/0slot/NB** | Linear, dominant (5 of 8 services @ 1M lamports = 86% of probe cost) | High — these services' landing % is tip-sensitive; we MUST run ≥2 tip tiers to be honest | **#1 lever**: split budget across tip tiers, not more cadence | +| **Cadence** | Linear | Sub-linear (√n in CI width) | #2 — doubling cadence only narrows CI by 1.41× | +| **Regions** | Linear ×3 | High once — first region anchors, 2nd/3rd reveal geo edge but with diminishing returns | #3 — keep all 3, don't add a 4th | +| **# services** | Linear | High but bounded by market (only 8 services exist worth measuring) | Fixed at 8 | +| **SOL price** | Linear, exogenous | Zero | Hedge: hold 30-day SOL float to smooth | + +**Punchline:** the cheapest way to buy 2× more signal is **not** to double cadence — it's to split existing cadence across 2 tip tiers per service. Same budget, exposes the price-of-landing curve. + +--- + +## 5. Sensitivity table (Phase 0 baseline = $1,452/mo) + +| Parameter | -50% | base | +50% / +10× / +2× | +|---|---:|---:|---:| +| SOL price ($80 / $150 / $300) | $1,348 | $1,452 | $5,052 | +| Tip size (÷10× / base / ×10×) | $169 | $1,452 | $14,420 | +| Cadence (÷2 / base / ×2) | $726 | $1,452 | $2,904 | + +Tip size dominates — a 10× shift in tip assumption moves the bench ~10× in cost. SOL price is the most volatile real-world driver; a SOL run to $300 nearly 4× the bench cost (because the lamport tips of the big-5 services are denominated in lamports, not USD). + +--- + +## 6. Sponsorship economics + +**Break-even on Phase 0 ($1,452/mo):** if we charge a "Verified" tier at $500/mo, **3 sponsors** fund the bench. At $1,000/mo, **2 sponsors**. Phase 1 ($5.8k) needs ~6 sponsors at $1k or 3 at $2k. + +### Methodologically-clean tier ladder + +| Tier | Price | What it buys (METHODOLOGICALLY OK) | What it explicitly does NOT buy | +|---|---|---|---| +| **Listed** | $0 | Inclusion in the public benchmark, default tip tier, public CSV exports | — | +| **Verified** | $500/mo | Logo on dashboard, methodology AMA quote, access to raw per-probe latency CSV, monthly 1-pager with their service's percentiles cited in our newsletter | Score adjustments | +| **Featured** | $2,000/mo | All Verified + a **2nd tip tier** probed for their service (so they can advertise "at 5M lamports we land 99.2% — measured by OpenChainBench"), geographic-edge add-on (we add a 4th region of their choice for their service only), newsletter co-write | Score adjustments, exclusivity over competitors | +| **Research partner** | $5,000/mo | All Featured + bespoke A/B experiment design (e.g., "test your new gRPC endpoint vs your REST endpoint for 30 days"), data API access | Anything that biases reported public numbers | + +**Hard rule:** no tier ever modifies a service's headline landing rate or latency percentile shown on the public leaderboard. Sponsorship buys **more measurement, more distribution**, never a better score. This is the methodological cliff we cannot cross without becoming Gartner Magic Quadrant. + +--- + +## 7. Recommendation + +**Launch with Phase 0 ($1,452/mo at SOL=$86, ~$2.5k/mo at SOL=$150).** Cadence of 1 sweep every 2 minutes across 8 services × 3 regions gives a daily-updated public leaderboard with 5pp statistical resolution per 6-hour window — enough to make defensible public claims while staying lean. Pre-sell 2 Verified sponsors ($500/mo each) before launch to halve net burn; pitch Featured tier ($2k/mo, methodologically-clean 2nd-tip-tier slot) to Helius or bloXroute since they're the most likely to want a tip-elasticity story. Upgrade to Phase 1 only once we have ≥4 paying sponsors and a clear research question that needs hourly resolution (e.g., "does Jito's BAM rollout move landing rates?"). Phase 2 is a trap — spend that money on adding a second chain instead. + +--- + +**Word count:** ~1,180. Last updated 2026-05-21. diff --git a/docs/solana-landing-deployment-checklist.md b/docs/solana-landing-deployment-checklist.md new file mode 100644 index 00000000..047d6977 --- /dev/null +++ b/docs/solana-landing-deployment-checklist.md @@ -0,0 +1,250 @@ +# Solana TX Landing — Deployment Checklist (V0-Lean) + +> Liste exhaustive de ce dont tu as besoin pour passer du code committé à un bench actif en prod. Ordre conseillé : lis tout, puis suis les étapes 1 → 8. + +--- + +## 0. État actuel — ce qui est déjà fait + +✅ Code écrit, compile, vet propre. 4 fichiers dans `mobula-api/miniapps/solana-tx-landing/cmd/script/` : +- `prober.go` (NEW) — boucle de probe, build/sign tx, polling +- `senders.go` (NEW) — HTTP par service (Jito, Helius, Nozomi, Astralane, 0slot) +- `active_metrics.go` (NEW) — métriques Prom +- `main.go` (EDITED) — lance la goroutine prober en plus du subscriber + +✅ Méthodologie pré-enregistrée dans `OpenChainBench/docs/methodology/solana-tx-landing-active.md` + +✅ Le prober est **opt-in** : si `SOLANA_PROBE_KEYPAIR_BASE58` n'est pas set, il logge `[prober] disabled: ...` et le bench reste en mode observationnel pur. Donc déployer le code sans configurer les secrets ne casse rien. + +--- + +## 1. Générer + funder le keypair Solana + +```bash +# Sur ta machine locale (PAS sur Railway — la clé privée ne doit jamais +# transiter par git ou stdout sur un serveur) +solana-keygen new --no-bip39-passphrase -o ~/probe-keypair-us-east.json + +# Note l'adresse publique +solana address -k ~/probe-keypair-us-east.json + +# Récupère la base58 de la clé privée (à mettre en env var Railway) +# Le fichier JSON contient un tableau de 64 bytes ; on peut le convertir : +node -e "console.log(require('bs58').encode(Buffer.from(JSON.parse(require('fs').readFileSync(process.env.HOME+'/probe-keypair-us-east.json')))))" +# OU avec Python: +# python3 -c "import json, base58; print(base58.b58encode(bytes(json.load(open('/Users/user/probe-keypair-us-east.json')))).decode())" +``` + +**Funder le keypair** : envoie ~1 SOL (~$86) sur l'adresse publique depuis ton wallet perso. À V0-Lean cadence (1/h, 5 services), 1 SOL dure ~2 mois. Le bench logge un warning quand le balance passe sous 0.3 SOL. + +⚠️ **Stocke le fichier `probe-keypair-us-east.json` quelque part de safe** (1Password / coffre Mobula). Si tu le perds, les fonds restent récupérables via la base58 que tu auras mise en Railway — mais inversement, si Railway leak la base58, anyone peut vider le wallet. Le risque est limité à 1 SOL. + +--- + +## 2. Apply pour les API keys + +| Service | Comment apply | Délai estimé | Notes | +|---|---|---|---| +| **Nozomi** | Contact direct (Florent → Temporal Labs) + form `temporal.xyz` | Quelques jours (contact direct accélère) | Pitch : OCB bench, paie ses propres probes en SOL credits | +| **Astralane** | Form sur `astralane.io` | Variable | Plans flexibles, no public price | +| **0slot.trade** | Discord `kurt0slot` ou Telegram `@kurt0slot` | Rapide (manuel) | Première semaine gratuite, puis Trial/Entry/Intermediate/Advanced tier | +| **Jito UUID** *(optional)* | Ticket via `discord.gg/jito` | Variable | Augmente le rate limit au-delà des 1 req/s par IP | + +**Si une clé n'est pas obtenue**, le service est simplement skippé au launch (log `[prober] : not set — service skipped`). Le bench tourne avec les services restants. Tu peux ajouter les services au fur et à mesure. + +**Reco order** : Nozomi → 0slot → Astralane → Jito UUID. Les 2 premiers sont les plus impactants pour la cardinalité du bench. + +--- + +## 3. Setup les env vars Railway + +Service Railway : **`solana-tx-landing`** (existing — pas besoin de créer un nouveau service en V0-Lean ; on déploie le code sur le service existant qui devient hybride observational + active). + +| Env var | Required? | Valeur | Notes | +|---|---|---|---| +| `SOLANA_PROBE_KEYPAIR_BASE58` | **OUI** (active le prober) | base58 du keypair généré en §1 | Sans ça, prober disabled | +| `SOLANA_PROBE_REGION` | non (def: `us-east`) | `us-east` | Label Prom | +| `SOLANA_PROBE_INTERVAL` | non (def: `1h`) | `1h` pour V0-Lean | Go duration : `30m`, `15m`, etc. pour escalader | +| `SOLANA_PROBE_RPC_URL` | non | `https://api.mainnet-beta.solana.com` | RPC public mainnet pour les reads (getSlot, getSignatureStatuses, getBalance) | +| `SOLANA_PROBE_SERVICES` | non (def: tous) | `jito,helius-sender,nozomi,astralane,0slot` | Liste comma-séparée. Permet de skip explicitement | +| `NOZOMI_API_KEY` | non | clé obtenue en §2 | Skip Nozomi si absent | +| `ASTRALANE_API_KEY` | non | clé obtenue en §2 | Skip Astralane si absent | +| `ZEROSLOT_API_KEY` | non | clé obtenue en §2 | Skip 0slot si absent | +| `JITO_AUTH_UUID` | non | UUID obtenu en §2 | Augmente rate limit Jito | + +**Overrides pour le tip floor** (rarement utiles, mais possibles) : +- `JITO_TIP_LAMPORTS` (def 10_000) +- `HELIUS_TIP_LAMPORTS` (def 10_000) +- `NOZOMI_TIP_LAMPORTS` (def 1_000_000) +- `ASTRALANE_TIP_LAMPORTS` (def 500_000) +- `ZEROSLOT_TIP_LAMPORTS` (def 1_000_000) + +⚠️ **Tout changement de tip est une modification méthodologique** = PR + 14 jours de comment window selon Rule #1. + +**Overrides pour les endpoints** (escape hatch ops si un provider change de host sans préavis) : +- `NOZOMI_ENDPOINT` (def `https://ewr.nozomi.temporal.xyz/`) +- `ASTRALANE_ENDPOINT` (def `https://ny.gateway.astralane.io/iris`) +- `ZEROSLOT_ENDPOINT` (def `https://ny.0slot.trade`) + +Pas de override pour Jito ou Helius — leurs hosts sont hardcodés dans `senders.go` (modifier requiert PR méthodologique). + +**Métrique opérationnelle additionnelle :** `solana_landing_probe_enabled{region}` (gauge, 0 ou 1) — permet de distinguer sur le dashboard "prober désactivé" (env var pas set) vs "prober planté" (set mais aucune cycle récente). + +--- + +## 4. Setup Prometheus (rien à toucher) + +Le service Railway `solana-tx-landing` est déjà scrapé par le Prom partagé OCB sur `:2112/metrics`. Les nouvelles métriques `solana_landing_probe_*` apparaîtront automatiquement dès le premier redeploy. **Pas besoin de modifier `miniapps/openchainbench-monitoring/prometheus/prometheus.yml`.** + +Métriques exposées en V0-Lean : +``` +solana_landing_probe_success_total{service, mode, region} +solana_landing_probe_dropped_total{service, mode, region, reason} +solana_landing_probe_latency_slots{service, mode, region} +solana_landing_probe_latency_slots_histogram{service, mode, region} +solana_landing_probe_latency_ms{service, mode, region} +solana_landing_probe_latency_ms_histogram{service, mode, region} +solana_landing_probe_keypair_balance_sol{region} +solana_landing_probe_cycle_total{region} +solana_landing_probe_last_cycle_timestamp_seconds{region} +``` + +Cardinalité totale : ~30 séries. Négligeable pour notre Prom. + +--- + +## 5. Workflow Git pour shipper + +Tu es actuellement sur `feat/france-cryptos-sprint1` sur `mobula-api`. **Ne push pas sur `dev`.** + +```bash +cd /Users/user/mobula/mobula-api + +# Crée une branche dédiée si tu veux isoler le prober du reste du sprint +git checkout -b feat/solana-landing-active-prober + +# Lint avant de committer (CLAUDE.md global rule) +bun lint:fix + +# Stage uniquement les fichiers du prober +git add miniapps/solana-tx-landing/cmd/script/active_metrics.go \ + miniapps/solana-tx-landing/cmd/script/prober.go \ + miniapps/solana-tx-landing/cmd/script/senders.go \ + miniapps/solana-tx-landing/cmd/script/main.go \ + miniapps/solana-tx-landing/go.mod \ + miniapps/solana-tx-landing/go.sum + +git commit -m "solana-tx-landing: add active landing prober (V0-Lean)" +git push -u origin feat/solana-landing-active-prober +``` + +**Pour OpenChainBench (les docs)** : +```bash +cd /Users/user/mobula/OpenChainBench + +git checkout -b feat/solana-landing-active-methodology +git add docs/methodology/solana-tx-landing-active.md \ + docs/solana-landing-tiered-architecture.md \ + docs/solana-landing-cost-model.md \ + docs/solana-landing-active-bench-plan.md \ + docs/solana-landing-deployment-checklist.md + +git commit -m "docs: add Solana TX landing active bench plan + methodology" +git push -u origin feat/solana-landing-active-methodology +``` + +**Liens PR à créer manuellement après push :** +- `mobula-api` → PR vers `dev` (URL générée par GitHub après `git push`) +- `OpenChainBench` → PR vers `main` + +⚠️ **Ordre important** : la méthodologie OCB DOIT être mergée AVANT toute conversation sponsor (Rule #1 : pre-registered methodology before any contract). + +--- + +## 6. Première vérification post-déploiement + +Une fois Railway redéployé avec `SOLANA_PROBE_KEYPAIR_BASE58` set : + +```bash +# Logs Railway — chercher le banner du prober +# Tu devrais voir: +# [prober] enabled — region=us-east interval=1h0m0s services=N +# · jito mode=default tip=10000 lamports endpoint=https://... +# · helius-sender mode=swqos_only tip=10000 lamports endpoint=http://... +# · ... + +# Après ~5 secondes (le warmup) : +# [prober] cycle abc123… done in 8.234s +``` + +Métriques à vérifier dans Prometheus (via Grafana ou query directe) : +```promql +# Probes lancées +sum(rate(solana_landing_probe_cycle_total[1h])) * 3600 +# = doit être ≈ 1.0 (1 cycle par heure) + +# Landing rate par service (rolling 7 jours) +sum(rate(solana_landing_probe_success_total[7d])) by (service) +/ +(sum(rate(solana_landing_probe_success_total[7d])) by (service) + + sum(rate(solana_landing_probe_dropped_total{reason="timeout"}[7d])) by (service)) + +# Keypair balance (doit décroître lentement) +solana_landing_probe_keypair_balance_sol{region="us-east"} +``` + +--- + +## 7. Spec OCB côté site (à faire APRÈS la méthodologie mergée) + +Le fichier `OpenChainBench/benchmarks/solana-tx-landing.yml` actuel décrit la version observational uniquement. À étendre : + +1. Ajouter une section pour les nouvelles métriques (`solana_landing_probe_*`) +2. Ajouter le champ `sponsorship` avec le disclosure block (cf §6 de tiered-architecture.md) +3. Ajouter une référence vers la méthodologie pré-enregistrée +4. *Optionnel* : étendre `src/lib/spec.ts` pour supporter le rendu 2-tabs (Market Share + Landing Latency) — à voir si nécessaire ou si on rend tout dans une seule page allongée + +À faire dans une PR séparée pour découpler infra (mobula-api) et site (OpenChainBench). + +--- + +## 8. Sponsor outreach — DEUX semaines après que la méthodologie soit mergée + +| Étape | Action | +|---|---| +| W+0 | Méthodologie publique mergée sur `OpenChainBench/main` | +| W+1 | Bench tourne en prod, première data semaine arrive | +| W+2 | Premier ping Nozomi avec : link méthodologie + first-week data preview + ask SOL credits | +| W+3 | Nozomi → Featured tier ($1.5-2.5k/mo équivalent SOL ou cash). Avec ça V0-Lean → V1 ($580/mo, OCB net ~$300). | +| W+4 | Ping 0slot via Discord. Idem ask. | +| W+8 | Ré-évaluer : si on a 2 sponsors et la story geographic edge demandée → escalade vers V2 (3 régions). | + +--- + +## 9. Décisions encore ouvertes (à toi de trancher) + +| # | Décision | Reco par défaut | +|---|---|---| +| A | Disclose à Jito/Helius/Nozomi qu'on les probe ? | **Oui**, avant launch — email courte annonçant le bench public | +| B | Renommer le service Railway `solana-tx-landing` → `-us` pour cohérence multi-région future ? | **Oui**, geste de cleanup | +| C | Si Nozomi répond "non" au sponsoring, on probe quand même ? | **Oui**, méthodologie dit "sponsors ne contrôlent pas l'inclusion" | +| D | Configurer un alert Slack sur `solana_landing_probe_keypair_balance_sol < 0.3` ? | **Oui**, sinon on rate des cycles silencieusement | +| E | Activer Helius en dual-mode (en plus de swqos_only) ? | **Pas en V0-Lean.** Méthodologie figée. À reconsidérer en v1.0.1 PR | + +--- + +## Annexe — Que faire si quelque chose plante + +| Symptôme | Cause probable | Fix | +|---|---|---| +| `[prober] disabled: SOLANA_PROBE_KEYPAIR_BASE58 not set` | Env var pas configurée | Set dans Railway settings | +| `[prober] disabled: decode keypair: invalid base58` | Mauvais encoding du keypair | Re-run la commande de §1 | +| `[prober] disabled: no services configured` | Aucune clé sponsor + `SOLANA_PROBE_SERVICES` mal écrit | Vérifier que Jito + Helius (sans clé) sont au moins là | +| `[prober][nozomi] submit: rpc error -32xxx` | Clé invalide ou expirée | Re-issue avec Temporal | +| `[prober][...] submit: http: dial tcp ... no such host` | DNS Railway / endpoint typo | Vérifier l'endpoint dans senders.go | +| Keypair balance ne décroît pas | Service `solana-tx-landing` n'a pas le keypair env | Vérifier les secrets Railway | +| Balance décroît plus vite que prévu | Tip floor mal configuré ou cycle interval trop court | Vérifier `SOLANA_PROBE_INTERVAL` et `*_TIP_LAMPORTS` | + +--- + +**Last updated :** 2026-05-21 — V0-Lean (5 services × us-east × 1 h cadence × $159/mo théorique). diff --git a/docs/solana-landing-tiered-architecture.md b/docs/solana-landing-tiered-architecture.md new file mode 100644 index 00000000..f102326a --- /dev/null +++ b/docs/solana-landing-tiered-architecture.md @@ -0,0 +1,289 @@ +# Solana TX Landing Bench — Launch Plan (V0-Lean) + +> **Direction validée 2026-05-21.** On lance V0-Lean : 5 services × 1 région × cadence 1 h, **$159/mo** à SOL=$86.20. Escalade par triggers explicites (voir §7). + +Compagnon : [`solana-landing-cost-model.md`](./solana-landing-cost-model.md) pour les calculs détaillés. + +--- + +## 1. Les 5 services qu'on probe (V0-Lean) + +| # | Service | Tip floor (lamports) | Coût / probe | Rôle dans le bench | +|---|---|---:|---:|---| +| 1 | **Jito Block Engine** | 10 000 | $0.0015 | Baseline + *control probe* pour Helius/Nozomi/Astralane (fan-out) | +| 2 | **Helius Sender** | 10 000 (`swqos_only=true`) | $0.0015 | Le plus utilisé, anycast + 7 POPs | +| 3 | **Astralane Iris** | 500 000 (net refunds) | $0.0437 | Angle unique : tip refunds | +| 4 | **Nozomi (Temporal Labs)** | 1 000 000 | $0.0868 | Premium tier, **sponsor cible #1 (contact direct Florent)** | +| 5 | **0slot.trade** | 1 000 000 | $0.0868 | Premium tier, anti-MEV + durable-nonce | + +*Coût par probe = 5 000 base + 2 500 priority + tip floor lamports, converti à SOL=$86.20.* + +**Pas dans V0-Lean (réservés V1+) :** bloXroute, NextBlock, SolanaVibeStation — tous demandent un onboarding manuel (sales call, form, paid plan) qui ralentirait le launch. On les ajoute quand le 1er sponsor est signé. + +--- + +## 2. Architecture + +``` + ┌────────────────────────────────┐ + │ Railway us-east │ + │ Service: solana-tx-landing-us │ + │ Keypair: 1 SOL (~$86) │ + │ Auto-topup alert si < 0.3 SOL │ + └────────────────┬───────────────┘ + │ toutes les 60 min + ▼ + ┌─────────────────────────────────┐ + │ Probe cycle (PARALLELE) │ + │ 5 tx signées simultanément │ + │ Payload: self-transfer + memo │ + └───┬────┬────┬────┬────┬─────────┘ + │ │ │ │ │ + ▼ ▼ ▼ ▼ ▼ + Jito Helius Astralane Nozomi 0slot + │ │ │ │ │ + │ │ (1) mode swqos_only │ + │ │ (2) mode default │ + ▼ ▼ ▼ ▼ ▼ + ════════ Solana mainnet ════════ + │ + ▼ + getSignatureStatuses() poll 1s, timeout 60s + │ + ▼ + ┌─────────────────────────────────────┐ + │ Prometheus :2112 │ + │ solana_landing_probe_success_total │ + │ solana_landing_probe_latency_slots │ + │ solana_landing_probe_latency_ms │ + │ solana_landing_probe_dropped_total │ + │ labels: service, mode, region │ + └─────────────────┬───────────────────┘ + ▼ + prometheus-production-0859.up.railway.app + (scrape par le Prom partagé OCB déjà déployé) + ▼ + openchainbench.com /benchmarks/solana-tx-landing + ┌─────────────────────────────────────────────┐ + │ Tab 1 — Market Share (observationnel, │ + │ garde la logique tip-wallet existante)│ + │ Tab 2 — Landing Latency (NEW, active probe) │ + │ • Leaderboard hebdomadaire │ + │ • p50 / p99 par service │ + │ • Histogram time-to-land │ + └─────────────────────────────────────────────┘ +``` + +--- + +## 3. Maths du coût + +``` + Services : 5 + Région : 1 (us-east) + Cadence : 1 cycle / heure + Probes / jour : 5 × 24 = 120 + Cycles / mois : 24 × 30 = 720 + + Coût par cycle (5 probes en parallèle) : + Jito $0.0015 + Helius $0.0015 + Astralane $0.0437 + Nozomi $0.0868 + 0slot $0.0868 + ─────── + TOTAL / cycle $0.2204 + + Mensuel : 720 × $0.2204 = $158.73/mo +``` + +**Ventilation par service :** + +| Service | $/mo | % du budget | +|---|---:|---:| +| Nozomi | $62.53 | 39.4% ████████ | +| 0slot | $62.53 | 39.4% ████████ | +| Astralane | $31.50 | 19.8% ████ | +| Helius | $1.09 | 0.7% | +| Jito | $1.09 | 0.7% | +| **Total** | **$158.73** | 100% | + +→ **3 services premium = 98.6% du budget.** C'est là qu'il faut négocier des SOL credits sponsor. + +--- + +## 4. Le levier sponsor — SOL credits, pas cash + +Au lieu de demander du cash à Nozomi : +- **Ask :** "Vous payez vos propres frais d'évaluation. ~8 SOL / trimestre couvre votre slot Nozomi dans le bench." +- **C'est plus naturel** qu'un sponsor cash : ils financent leur propre mesure (pas le bench global). +- **Effet sur l'économie OCB :** + +| Scenario sponsor | OCB net $/mo | +|---|---:| +| Aucun sponsor | $158.73 | +| Nozomi paye ses probes en SOL | $96.20 | +| Nozomi + 0slot payent leurs probes | **$33.66** | +| Nozomi + 0slot + Astralane | $2.18 | + +Astralane n'est probablement pas un bon premier ask (plus petit acteur), mais Nozomi + 0slot c'est jouable. + +--- + +## 5. Méthodologie — ce qu'on mesure, comment + +### Probe payload +Self-transfer de 1 lamport + Memo program (8 octets aléatoires). ~5 000 lamports de frais base. Pas de mutation de state extérieur, pas de risque de perte. + +### Le Jito control probe +Helius (mode default), Nozomi, Astralane font tous du fan-out vers Jito en interne. Sans contrôle, on ne sait pas si "Nozomi a landé" ou "Jito a landé pour le compte de Nozomi". + +**Solution :** Jito est probé *en même cycle* que les autres → comparaison slot-par-slot dans la même fenêtre de congestion. Si Nozomi land au même slot que Jito → routing Jito. Si Nozomi land 2 slots plus tôt → vraie valeur ajoutée Nozomi. + +### Helius double-mode +On probe Helius en 2 modes : +1. `?swqos_only=true` → isole le path Helius pur (sans fan-out Jito) +2. mode par défaut → Helius + Jito fan-out + +→ 2 séries Prom : `mode="swqos_only"` et `mode="dual"`. Coût supplémentaire : +$1/mo. + +### Définition "landed" +- Confirmation level : `confirmed` (1+ block). +- Timeout : 60s. Au-delà → classified `dropped` avec `reason=timeout`. +- Métriques : `slot_delta = land_slot - submit_slot` (resolution slot) + `wall_clock_ms` (resolution ms). + +### Statistical power à cette cadence + +| Période | Probes / service | Ce qu'on peut claim | +|---|---:|---| +| 1 jour | 24 | p50 stable, p99 bruité | +| 1 semaine | 168 | p50 + p99 stables, gaps 5pp détectables | +| 2 semaines | 336 | gaps 3pp détectables | + +→ **Rythme de publication recommandé : hebdomadaire.** Article + leaderboard refresh chaque lundi matin. + +--- + +## 6. Garanties méthodologie (sponsor-proof) + +Bake-in dès le launch — ajouter après coup donne l'air défensif. + +1. **Méthodo pré-enregistrée sur GitHub** avant tout contrat sponsor. Changements via PR public + fenêtre commentaire 14 jours. +2. **Inclusion automatique** dès qu'un endpoint est publiquement reachable. Les sponsors n'entrent pas dans le leaderboard via cash. +3. **Harness open-source** dans ce repo (`harnesses/solana-tx-landing/`). +4. **Paramètres probe identiques** entre services. Toute déviation per-service (auth méthode, endpoint) → footnote sur la row. +5. **Clause non-suppression dans le contrat sponsor.** Seul recours sponsor pour résultat défavorable = terminer + refund pro-rata. Jamais d'édit. +6. **Funding itemisé publiquement** par trimestre, tier S/M/L à la L2Beat. +7. **Pas d'accès en avance aux résultats.** Sponsors voient les chiffres en même temps que le public. + +**Disclosure block** (72 mots, à mettre dans le champ `sponsorship` du spec YAML) : + +> OCB measures every reachable Solana transaction-landing service on identical probe parameters. The harness is open-source and re-runnable by anyone. Sponsors fund OCB's operations and receive newsletter visibility, case studies, and integration support — never leaderboard influence, advance results, or methodology changes. Current sponsors : see /funding (updated quarterly). Sponsor contracts include a non-suppression clause : OCB publishes unfavorable results without exception. Disputes go through public GitHub issues. + +--- + +## 7. Échelle de tiers (escalade par triggers) + +``` +START ──► V0-Lean $159/mo + │ 5 svc × 1 reg × 60min + │ Refresh hebdomadaire + │ + ├──► +Cadence ($318/mo) ─── Si on veut leaderboard quotidien + │ 5 svc × 1 reg × 30 min + │ + ├──► +Couverture ($580/mo) ─── Quand 1er sponsor signe + │ 8 svc × 1 reg × 30 min + │ (ajoute bloXroute, NextBlock, SVS) + │ + └──► +Géo edge ($1 743/mo) ── Quand 2-3 sponsors OU + 8 svc × 3 reg × 30 min sponsor demande story géo +``` + +**Triggers explicites :** + +| Trigger | Action | +|---|---| +| 4 semaines de data publiée et la narrative demande de la fraîcheur quotidienne | V0-Lean → V0-Daily ($318) | +| 1 sponsor signe ($500+/mo cash OU SOL credits couvrant ≥1 service premium) | V0-Daily → V1 ($580) | +| 2-3 sponsors signés OU 1 sponsor demande spécifiquement la story "geographic edge" | V1 → V2 ($1 743) | +| SOL passe au-dessus de $200 | Recompute tout, peut imposer un downgrade temporaire | + +**Anti-pattern :** sauter à V2 avant signature sponsor = brûler $1.7k/mo pour répondre à une question (geographic edge) que personne n'a posée publiquement. + +--- + +## 8. Roadmap d'implémentation + +### Étape 1 — mobula-api (refactor harness) + +Fichiers à toucher dans `miniapps/solana-tx-landing/cmd/script/` : + +``` + main.go — fork en 2 goroutines: runSubscriber() (obs) + runProber() (actif) + prober.go — NEW. Boucle 1 cycle/h, fire les 5 services en parallèle + active_metrics.go — NEW. Définitions Prom solana_landing_probe_* + config.go — env vars: SOLANA_LANDING_SERVICES, _CADENCE, _RPC_URL, etc. + subscriber.go — UNCHANGED (la logique observationnelle reste) + wallets.go — UNCHANGED (tip wallets pour l'attribution Market Share) +``` + +### Étape 2 — mobula-api (infra) + +- Générer 1 keypair Solana, le funder de 1 SOL (~$86) via wallet perso, store en Railway Env Secret `SOLANA_PROBE_KEYPAIR`. +- Renommer le service Railway existant `solana-tx-landing` → `solana-tx-landing-us` pour cohérence future multi-région (geste de cleanup, ne change rien à l'usage actuel). +- Ajouter scrape target dans `miniapps/openchainbench-monitoring/prometheus/prometheus.yml` : pointer vers `solana-tx-landing-us.railway.internal:2112` (le service est déjà scraped en V0 — vérifier le job_name). + +### Étape 3 — OpenChainBench (spec + UI) + +``` + benchmarks/solana-tx-landing.yml + — Garder le contenu existant (Market Share) + — Ajouter section "Landing Latency" avec métriques solana_landing_probe_* + — Ajouter champ `sponsorship` avec le disclosure block du §6 + — Mettre à jour `disclaimer` pour mentionner les 2 facettes + docs/methodology/solana-tx-landing-active.md + — NEW. Méthodo pré-enregistrée (les 7 règles du §6 + détails probe) + — Commit AVANT toute conversation contractuelle sponsor + src/lib/spec.ts + — Vérifier qu'il supporte un schema 2-tabs (Market Share + Latency) + — Sinon : étendre minimal le loader +``` + +### Étape 4 — Sponsor outreach + +1. **Nozomi en premier** (contact direct Florent). Pitch : 8 SOL / trimestre = leur slot Nozomi dans le bench. Featured tier dans `/funding`. +2. **0slot ensuite** (Discord `kurt0slot` ou TG `@kurt0slot`). Même ask. +3. Si les 2 signent → OCB net mensuel ≈ $34. Le bench se finance. + +### Étape 5 — Aller live + +- Méthodo committée sur GitHub. +- 4 semaines de data accumulée en privé (pour valider le pipeline + détecter les bugs). +- Annonce publique avec article France Cryptos + cross-post X. + +--- + +## 9. Décisions encore ouvertes (à valider par Florent) + +| # | Question | Reco | +|---|---|---| +| 1 | Disclose aux providers qu'on les probe ? | **Oui**, top-3 (Jito, Helius, Nozomi) avant launch | +| 2 | Helius en double-mode (swqos_only + default) ? | **Oui**, coût négligeable | +| 3 | Ask Nozomi : flat fee cash ou SOL credits ? | **SOL credits** — plus naturel | +| 4 | Garder le tab observational (Market Share) ? | **Oui**, 1 page 2 tabs | +| 5 | Renommer service Railway de `solana-tx-landing` → `solana-tx-landing-us` ? | **Oui**, cleanup pour cohérence future | + +--- + +## 10. Ce qui n'est PAS dans ce plan + +- **Code Go** — pas écrit tant que décisions §9 pas validées. +- **YAML du spec OCB** — pas modifié avant méthodo committée sur GitHub (cf §6.1). +- **Contrat sponsor type** — étape légale séparée, hors scope ingénieur. +- **bloXroute, NextBlock, SVS** — reportés V1+, on les onboard quand le pipeline V0-Lean tourne. +- **Multi-région** — reporté V2, on lance us-east only. + +--- + +**Last updated :** 2026-05-21. Recompute toutes les valeurs $ si SOL bouge de ±30%.