From ad0a894e7dd64b2947b03ef00754aaeb5354b3b7 Mon Sep 17 00:00:00 2001 From: Florent Tapponnier Date: Sun, 24 May 2026 09:03:27 +0200 Subject: [PATCH 1/2] =?UTF-8?q?docs(solana-tx-landing):=20methodology=20v1?= =?UTF-8?q?.5=20=E2=80=94=20Nozomi=20batch-send=20+=20non-saturated=20tip?= =?UTF-8?q?=20wallet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit paired with mobula-api PRs #6463 (batch-send + tip wallet) + #6464 (HTTP fix). - YAML methodology source endpoints: Nozomi now described as binary batch-send (use.temporal.xyz/api/sendBatch, [u16_BE_len][tx_bytes], Content-Type: application/octet-stream). Other services unchanged (JSON-RPC sendTransaction with base64). - methodology doc v1.5 changelog row: documents the batch-send move, the tip wallet swap to nEFs3jph8... (non-saturated, per Jakob), and notes the main TEMPaMe... wallet remains as v1 anti-fingerprint fallback. Tip floor unchanged at 1M lamports. --- benchmarks/solana-tx-landing-latency.yml | 2 +- docs/methodology/solana-tx-landing-active.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/benchmarks/solana-tx-landing-latency.yml b/benchmarks/solana-tx-landing-latency.yml index d7989316..d546416f 100644 --- a/benchmarks/solana-tx-landing-latency.yml +++ b/benchmarks/solana-tx-landing-latency.yml @@ -84,7 +84,7 @@ abstract: | dual-mode arrives in v1.0.1 methodology PR. methodology: - - "Source endpoints (base64 sendTransaction, us-east Railway node): Jito `ny.mainnet.block-engine.jito.wtf/api/v1/transactions`. Helius Sender `ewr-sender.helius-rpc.com/fast?swqos_only=true` (requires skipPreflight + maxRetries=0). Nozomi `http://edge.nozomi.temporal.xyz/?c=` (geo-routed DNS, HTTP per Temporal Labs recommendation for server-to-server). Astralane `ny.gateway.astralane.io/iris?api-key=` (non-canonical 3-elem params, mevProtect=true). 0slot `ny.0slot.trade?api-key=`." + - "Source endpoints (us-east Railway node). Jito `ny.mainnet.block-engine.jito.wtf/api/v1/transactions` (JSON-RPC sendTransaction, base64). Helius Sender `ewr-sender.helius-rpc.com/fast?swqos_only=true` (JSON-RPC, requires skipPreflight + maxRetries=0). Nozomi `http://use.temporal.xyz/api/sendBatch?c=` (binary `[u16_BE_len][tx_bytes]` batch endpoint, HTTP per Temporal Labs recommendation for server-to-server). Astralane `ny.gateway.astralane.io/iris?api-key=` (JSON-RPC, non-canonical 3-elem params, mevProtect=true). 0slot `ny.0slot.trade?api-key=` (JSON-RPC)." - "Probe payload. 5 instructions in this exact order: SetComputeUnitLimit(50,000) + SetComputeUnitPrice(50,000 micro-lamports/CU) + SystemProgram.Transfer(payer→payer, 1 lamport) + SystemProgram.Transfer(payer→service tip wallet, floor lamports) + Memo(`ocb---`). cycle_id is an 8-byte random hex shared across the five parallel probes of one cycle, so the on-chain memos correlate." - "Tip floors (pre-registered, methodology PR + 14-day window to change). Jito 10,000 lamports. Helius Sender 10,000. Astralane 500,000 net of refunds. Nozomi 1,000,000. 0slot 1,000,000." - "Submission flow. One getLatestBlockhash(processed) shared across all five probes. One getSlot(processed) as submit_slot. For each service we subscribe to the signature via signatureSubscribe on the public WS BEFORE submission (otherwise a fast confirm could fire before we listen). Probes then fire in parallel goroutines, sign, POST. We block on the signatureNotification at commitment=confirmed; context.slot is land_slot; slot_delta = land_slot - submit_slot." diff --git a/docs/methodology/solana-tx-landing-active.md b/docs/methodology/solana-tx-landing-active.md index 0c8e465d..79c3d465 100644 --- a/docs/methodology/solana-tx-landing-active.md +++ b/docs/methodology/solana-tx-landing-active.md @@ -160,3 +160,4 @@ Sponsorship policy and the disclosure block live in [`solana-landing-tiered-arch | v1.2 | 2026-05-23 | `getSignatureStatuses` poll interval reduced from 1 s to 200 ms after the first 7 days of live data showed all services collapsing to identical 1.0 s p50. The 1 s poll was the measurement floor (Solana confirmed status arrives in ~400 ms-1 s), so 200 ms restores 5x the resolution. Bench page queries also switched from `histogram_quantile` on the latency_ms histogram to `quantile_over_time` on the latency_ms gauge, since the histogram bucket list only had ~3 buckets in the 1-5 s zone where probes actually land, collapsing p50 to bucket midpoints. | | v1.3 | 2026-05-23 | Primary observation path switched from HTTP polling to `signatureSubscribe` over the public mainnet WebSocket (`wss://api.mainnet-beta.solana.com`). The RPC pushes the notification at the instant the commitment level is reached, so resolution is RTT-bounded (~30-50 ms us-east → mainnet-beta) rather than poll-cadence-bounded. Subscription is registered BEFORE submission to prevent missing fast confirmations. HTTP polling at 200 ms remains an automatic fallback if the WebSocket connect fails. Validated locally against mainnet-beta with end-to-end slot and signature subscribe tests before deploy. | | v1.4 | 2026-05-23 | Nozomi endpoint switched from `https://ewr.nozomi.temporal.xyz/` (Newark, region-pinned) to `http://edge.nozomi.temporal.xyz/` (geo-routed DNS, HTTP). Reason: Railway us-east is Ashburn, the previous endpoint forced a cross-region hop adding ~30 ms RTT. The geo-routed DNS resolves to the POP closest to the caller. HTTP instead of HTTPS skips the TLS handshake on the hot path (Solana tx is already signed so plain-text body is not a confidentiality risk - the signature is public the moment the tx is on chain). Change requested by Jakob @ Temporal Labs on 2026-05-23 and applied to all probes from the same region. The same review pass is open for Jito / Helius / Astralane / 0slot - any service whose **publicly-documented** best-practice configuration differs from what we currently probe is invited to file an issue or PR. We do NOT accept private deals to alter the probe surface for any single service; we DO apply optimisations that the service publishes as their standard production recommendation. | +| v1.5 | 2026-05-24 | Two further Nozomi refinements per Jakob @ Temporal Labs follow-up. (a) Endpoint moved from `edge.nozomi.temporal.xyz` (JSON-RPC sendTransaction) to `http://use.temporal.xyz/api/sendBatch?c=` (binary `[u16_BE_len][tx_bytes]` framing, `Content-Type: application/octet-stream`). Per Jakob, this batch endpoint handles single-tx submissions and is the path most clients use. Implementation: single-tx wrap in the batch container. (b) Tip wallet switched from the saturated main wallet `TEMPaMeCRFAS9EKF53Jd6KpHxgL47uWLcpFArU1Fanq` to a non-saturated wallet `nEFs3jph8HJt7honu3k7XtGUufMnwAvSXmXcKSPxryP` recommended by Jakob; the main wallets receive heavy MEV-load traffic and clients typically rotate over less-busy alternates. The `TEMPaMe...` wallet remains in the Nozomi tip-wallet list as a fallback for the v1 anti-fingerprint randomisation feature. No change to tip floor (1 000 000 lamports). | From 8bb8beb40e8fab37beb129d946d82c49b29b806f Mon Sep 17 00:00:00 2001 From: Florent Tapponnier Date: Sun, 24 May 2026 09:04:15 +0200 Subject: [PATCH 2/2] fix(yaml): trim methodology[0] to fit 500 char cap --- benchmarks/solana-tx-landing-latency.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarks/solana-tx-landing-latency.yml b/benchmarks/solana-tx-landing-latency.yml index d546416f..67af1fa1 100644 --- a/benchmarks/solana-tx-landing-latency.yml +++ b/benchmarks/solana-tx-landing-latency.yml @@ -84,7 +84,7 @@ abstract: | dual-mode arrives in v1.0.1 methodology PR. methodology: - - "Source endpoints (us-east Railway node). Jito `ny.mainnet.block-engine.jito.wtf/api/v1/transactions` (JSON-RPC sendTransaction, base64). Helius Sender `ewr-sender.helius-rpc.com/fast?swqos_only=true` (JSON-RPC, requires skipPreflight + maxRetries=0). Nozomi `http://use.temporal.xyz/api/sendBatch?c=` (binary `[u16_BE_len][tx_bytes]` batch endpoint, HTTP per Temporal Labs recommendation for server-to-server). Astralane `ny.gateway.astralane.io/iris?api-key=` (JSON-RPC, non-canonical 3-elem params, mevProtect=true). 0slot `ny.0slot.trade?api-key=` (JSON-RPC)." + - "Source endpoints (us-east Railway, base64 JSON-RPC sendTransaction unless noted). Jito `ny.mainnet.block-engine.jito.wtf/api/v1/transactions`. Helius Sender `ewr-sender.helius-rpc.com/fast?swqos_only=true` (skipPreflight + maxRetries=0). Nozomi `http://use.temporal.xyz/api/sendBatch?c=` (binary `[u16_BE_len][tx_bytes]` batch endpoint, HTTP per Temporal Labs). Astralane `ny.gateway.astralane.io/iris?api-key=` (3-elem params, mevProtect=true). 0slot `ny.0slot.trade?api-key=`." - "Probe payload. 5 instructions in this exact order: SetComputeUnitLimit(50,000) + SetComputeUnitPrice(50,000 micro-lamports/CU) + SystemProgram.Transfer(payer→payer, 1 lamport) + SystemProgram.Transfer(payer→service tip wallet, floor lamports) + Memo(`ocb---`). cycle_id is an 8-byte random hex shared across the five parallel probes of one cycle, so the on-chain memos correlate." - "Tip floors (pre-registered, methodology PR + 14-day window to change). Jito 10,000 lamports. Helius Sender 10,000. Astralane 500,000 net of refunds. Nozomi 1,000,000. 0slot 1,000,000." - "Submission flow. One getLatestBlockhash(processed) shared across all five probes. One getSlot(processed) as submit_slot. For each service we subscribe to the signature via signatureSubscribe on the public WS BEFORE submission (otherwise a fast confirm could fire before we listen). Probes then fire in parallel goroutines, sign, POST. We block on the signatureNotification at commitment=confirmed; context.slot is land_slot; slot_delta = land_slot - submit_slot."