diff --git a/benchmarks/ckb-rpc.yml b/benchmarks/ckb-rpc.yml new file mode 100644 index 00000000..f8fbc0cd --- /dev/null +++ b/benchmarks/ckb-rpc.yml @@ -0,0 +1,112 @@ +# OpenChainBench. Bench No 219 + +slug: ckb-rpc +number: "219" +title: Fastest free Nervos CKB RPC, live no-key endpoint latency +seo_title: "Fastest free Nervos CKB RPC 2026" +seo_description: "{{best_name}} leads free Nervos CKB RPC at {{best_p50}} (get_tip_block_number p50, 24h). 2 providers measured every 60s from 3 regions." +subtitle: HTTP round-trip latency for get_tip_block_number against every available public Nervos CKB node, audited every 60 seconds from 3 regions. + +category: RPCs +status: live +metric: RPC latency +unit: ms +higher_is_better: false + +seo_intro: | + Nervos CKB (Common Knowledge Base) is a proof-of-work Layer 1 blockchain using the NC-MAX consensus protocol, a variant of Nakamoto consensus with improved selfish-mining resistance. CKB targets roughly one block every 10 seconds with probabilistic finality. Public JSON-RPC endpoints are available without an API key from the Nervos Foundation and CKBapp. Every provider was live-verified with consecutive get_tip_block_number probes at launch. + +abstract: | + Per-chain member of the RPC latency cluster, extended to Nervos CKB. + We measure the round-trip latency of a single JSON-RPC call + (get_tip_block_number) against every available public CKB node that + sustains continuous probing: 2 providers at launch, every 60 seconds, + from us-east, eu-west and Singapore. The harness classifies every + response (ok / http_err / jsonrpc_err / stale / timeout) with a + CKB-scaled staleness gap (30 blocks, around 5 min at 10 s/block). + The cross-chain view lives on the parent rpc-capabilities benchmark; + this page is the CKB-scoped answer with per-region breakdowns as a + first-class dimension. + +methodology: + - "Cadence: every 60 seconds per provider, from each of 3 probe regions (us-east Virginia, eu-west Amsterdam, sgp Singapore). Headline p50/p90/p99 aggregate across all 3 regions via Prometheus avg(quantile_over_time(...)); per-region breakdowns are first-class on this page via the region tabs." + - "Payload: {\"jsonrpc\":\"2.0\",\"id\":,\"method\":\"get_tip_block_number\",\"params\":[]}. Plain HTTP POST. The result field is a hex-encoded block number string (0x prefix)." + - "Latency: client-side round-trip delta in milliseconds, exposed as both a gauge and a histogram (buckets 50 ms to 10 s), so percentiles are computed via Prometheus quantile_over_time over the last 24 hours." + - "Call-result classification: ok (HTTP 200 + parsable hex block number), http_err, jsonrpc_err, stale (block more than 30 behind the cross-provider tip), timeout. Latency without reliability is a misleading ranking signal." + - "This page is part of the per-chain RPC cluster derived from the cross-chain rpc-capabilities benchmark; the identical harness, cadence and exclusion rules apply on every chain." + - "Chain scope: every query on this page is pinned to chain=ckb. Provider coverage at launch: 2 endpoints (Nervos Foundation, CKBapp)." + +findings: + - "{{best_name}} currently leads Nervos CKB RPC at {{best_p50}} (get_tip_block_number p50, 24h) across 2 measured providers." + +faq: + - q: "What is the fastest free Nervos CKB RPC right now?" + a: "{{best_name}} currently leads at {{best_p50}} (CKB block number p50 over the last 24h), measured against 2 providers probed every 60 seconds from us-east, eu-west and Singapore. The leaderboard re-sorts continuously against fresh Prometheus samples." + - q: "Which Nervos CKB RPC endpoints work without an API key?" + a: "2 endpoints sustain continuous keyless probing at launch: the Nervos Foundation node (mainnet.ckb.dev/rpc) and CKBapp (mainnet.ckbapp.dev/rpc). Every listed endpoint was live-verified with a get_tip_block_number call returning a parsable hex block number before inclusion." + - q: "Does the fastest CKB RPC change by region?" + a: "Often. Public infra concentrates in specific regions; a gateway that wins from Amsterdam can lose from Singapore by multiples. The region tabs at the top of the page re-scope every number to a single origin." + - q: "How is Nervos CKB RPC latency measured here, technically?" + a: "One get_tip_block_number JSON-RPC call every 60 seconds against each provider from each of 3 regions. Wall-clock round-trip is recorded at millisecond precision; p50/p90/p99 are computed via Prometheus quantile_over_time over 24 hours. Best-effort measurements; p50 is the median, p90 the 90th percentile and p99 the 99th percentile of latency samples collected over the last 24 hours." + +source: https://github.com/ChainBench/OpenChainBench/tree/main/harnesses/rpc-capabilities + +prometheus: + window: 24h + freshness_metric: rpc_latency_milliseconds + +rank_matrix_query: avg by (provider, region) (ocb:rpc_latency_milliseconds:p50_24h{chain="ckb"}) + +dimensions: + region: + - { value: all, label: All regions } + - { value: us-east, label: US-East } + - { value: eu-west, label: EU-West } + - { value: sgp, label: Singapore } + +providers: + - slug: ckb-dev + name: Nervos Foundation + tag: Nervos Foundation official CKB mainnet public RPC, keyless + formula: "50th percentile over 24h of client-side round-trip latency (ms) for a get_tip_block_number POST sent every 60s from 3 regions to mainnet.ckb.dev/rpc." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="ckb-dev", chain="ckb"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="ckb-dev", chain="ckb"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="ckb-dev", chain="ckb"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="ckb-dev", chain="ckb"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="ckb-dev", chain="ckb"}) / sum(ocb:rpc_call:rate_24h{provider="ckb-dev", chain="ckb"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="ckb-dev", chain="ckb"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="ckb-dev", chain="ckb"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="ckb-dev", chain="ckb", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="ckb-dev", chain="ckb", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="ckb-dev", chain="ckb", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="ckb-dev", chain="ckb", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="ckb-dev", chain="ckb", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="ckb-dev", chain="ckb", region="sgp"}[1h]) + + - slug: ckbapp + name: CKBapp + tag: CKBapp community CKB mainnet public RPC, keyless + formula: "50th percentile over 24h of client-side round-trip latency (ms) for a get_tip_block_number POST sent every 60s from 3 regions to mainnet.ckbapp.dev/rpc." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="ckbapp", chain="ckb"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="ckbapp", chain="ckb"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="ckbapp", chain="ckb"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="ckbapp", chain="ckb"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="ckbapp", chain="ckb"}) / sum(ocb:rpc_call:rate_24h{provider="ckbapp", chain="ckb"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="ckbapp", chain="ckb"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="ckbapp", chain="ckb"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="ckbapp", chain="ckb", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="ckbapp", chain="ckb", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="ckbapp", chain="ckb", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="ckbapp", chain="ckb", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="ckbapp", chain="ckb", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="ckbapp", chain="ckb", region="sgp"}[1h]) diff --git a/benchmarks/flow-rpc.yml b/benchmarks/flow-rpc.yml new file mode 100644 index 00000000..cf2cbc49 --- /dev/null +++ b/benchmarks/flow-rpc.yml @@ -0,0 +1,112 @@ +# OpenChainBench. Bench No 217 + +slug: flow-rpc +number: "217" +title: Fastest free Flow RPC, live no-key endpoint latency +seo_title: "Fastest free Flow RPC 2026" +seo_description: "{{best_name}} leads free Flow RPC at {{best_p50}} (Cadence REST /v1/blocks sealed height p50, 24h). 2 providers measured every 60s from 3 regions." +subtitle: HTTP round-trip latency for the Flow Cadence REST endpoint (GET /v1/blocks?height=sealed) against every available public Flow node, audited every 60 seconds from 3 regions. + +category: RPCs +status: live +metric: RPC latency +unit: ms +higher_is_better: false + +seo_intro: | + Flow is a proof-of-stake L1 blockchain developed by Dapper Labs using a multi-role node architecture (Collector, Consensus, Execution, Verification) and the Cadence smart contract language. The Cadence chain commits roughly one block every 1 to 2 seconds with immediate deterministic finality. Public REST access nodes are operated by the Flow Foundation and accept GET /v1/blocks?height=sealed without an API key. Every provider was live-verified with consecutive sealed-block REST probes at launch. + +abstract: | + Per-chain member of the RPC latency cluster, extended to Flow. + We measure the round-trip latency of a single REST GET to + /v1/blocks?height=sealed against every available public Flow node + that sustains continuous probing: 2 providers at launch, every + 60 seconds, from us-east, eu-west and Singapore. The harness + classifies every response (ok / http_err / stale / timeout) with + a Flow-scaled staleness gap (240 blocks, around 5 min). The + cross-chain view lives on the parent rpc-capabilities benchmark; + this page is the Flow-scoped answer with per-region breakdowns + as a first-class dimension. + +methodology: + - "Cadence: every 60 seconds per provider, from each of 3 probe regions (us-east Virginia, eu-west Amsterdam, sgp Singapore). Headline p50/p90/p99 aggregate across all 3 regions via Prometheus avg(quantile_over_time(...)); per-region breakdowns are first-class on this page via the region tabs." + - "Payload: HTTP GET to /v1/blocks?height=sealed with Accept: application/json. Pure REST endpoint, no API key. The response is a JSON array; [0].header.height is parsed as a decimal string." + - "Latency: client-side round-trip delta in milliseconds, exposed as both a gauge and a histogram (buckets 50 ms to 10 s), so percentiles are computed via Prometheus quantile_over_time over the last 24 hours." + - "Call-result classification: ok (HTTP 200 + parsable height), http_err, stale (block more than 240 behind the cross-provider tip), timeout. Latency without reliability is a misleading ranking signal." + - "This page is part of the per-chain RPC cluster derived from the cross-chain rpc-capabilities benchmark; the identical harness, cadence and exclusion rules apply on every chain." + - "Chain scope: every query on this page is pinned to chain=flow. Provider coverage at launch: 2 endpoints (Flow Foundation REST, Flow access node)." + +findings: + - "{{best_name}} currently leads Flow RPC at {{best_p50}} (Cadence REST /v1/blocks sealed height p50, 24h) across 2 measured providers." + +faq: + - q: "What is the fastest free Flow RPC right now?" + a: "{{best_name}} currently leads at {{best_p50}} (Flow sealed block height p50 over the last 24h), measured against 2 providers probed every 60 seconds from us-east, eu-west and Singapore. The leaderboard re-sorts continuously against fresh Prometheus samples." + - q: "Which Flow RPC endpoints work without an API key?" + a: "2 endpoints sustain continuous keyless probing at launch: the Flow Foundation REST node (rest-mainnet.onflow.org) and the Flow access node REST endpoint (access.mainnet.nodes.onflow.org). Every listed endpoint was live-verified with a GET /v1/blocks?height=sealed returning a parsable height before inclusion." + - q: "Does the fastest Flow RPC change by region?" + a: "Often. Public infra concentrates in specific regions; a gateway that wins from Amsterdam can lose from Singapore by multiples. The region tabs at the top of the page re-scope every number to a single origin." + - q: "How is Flow RPC latency measured here, technically?" + a: "One REST GET to /v1/blocks?height=sealed every 60 seconds against each provider from each of 3 regions. Wall-clock round-trip is recorded at millisecond precision; p50/p90/p99 are computed via Prometheus quantile_over_time over 24 hours. Best-effort measurements; p50 is the median, p90 the 90th percentile and p99 the 99th percentile of latency samples collected over the last 24 hours." + +source: https://github.com/ChainBench/OpenChainBench/tree/main/harnesses/rpc-capabilities + +prometheus: + window: 24h + freshness_metric: rpc_latency_milliseconds + +rank_matrix_query: avg by (provider, region) (ocb:rpc_latency_milliseconds:p50_24h{chain="flow"}) + +dimensions: + region: + - { value: all, label: All regions } + - { value: us-east, label: US-East } + - { value: eu-west, label: EU-West } + - { value: sgp, label: Singapore } + +providers: + - slug: onflow + name: Flow Foundation + tag: Flow Foundation official public REST node, keyless + formula: "50th percentile over 24h of client-side round-trip latency (ms) for a GET /v1/blocks?height=sealed sent every 60s from 3 regions to rest-mainnet.onflow.org." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="onflow", chain="flow"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="onflow", chain="flow"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="onflow", chain="flow"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="onflow", chain="flow"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="onflow", chain="flow"}) / sum(ocb:rpc_call:rate_24h{provider="onflow", chain="flow"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="onflow", chain="flow"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="onflow", chain="flow"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="onflow", chain="flow", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="onflow", chain="flow", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="onflow", chain="flow", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="onflow", chain="flow", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="onflow", chain="flow", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="onflow", chain="flow", region="sgp"}[1h]) + + - slug: flow-access + name: Flow Access Node + tag: Flow Foundation public access node REST API, keyless + formula: "50th percentile over 24h of client-side round-trip latency (ms) for a GET /v1/blocks?height=sealed sent every 60s from 3 regions to access.mainnet.nodes.onflow.org." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="flow-access", chain="flow"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="flow-access", chain="flow"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="flow-access", chain="flow"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="flow-access", chain="flow"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="flow-access", chain="flow"}) / sum(ocb:rpc_call:rate_24h{provider="flow-access", chain="flow"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="flow-access", chain="flow"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="flow-access", chain="flow"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="flow-access", chain="flow", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="flow-access", chain="flow", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="flow-access", chain="flow", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="flow-access", chain="flow", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="flow-access", chain="flow", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="flow-access", chain="flow", region="sgp"}[1h]) diff --git a/benchmarks/hedera-rpc.yml b/benchmarks/hedera-rpc.yml new file mode 100644 index 00000000..5369bc30 --- /dev/null +++ b/benchmarks/hedera-rpc.yml @@ -0,0 +1,112 @@ +# OpenChainBench. Bench No 218 + +slug: hedera-rpc +number: "218" +title: Fastest free Hedera RPC, live no-key endpoint latency +seo_title: "Fastest free Hedera RPC 2026" +seo_description: "{{best_name}} leads free Hedera RPC at {{best_p50}} (eth_getBlockByNumber EVM p50, 24h). 2 providers measured every 60s from 3 regions." +subtitle: HTTP round-trip latency for eth_getBlockByNumber against every available public Hedera EVM-compatible node, audited every 60 seconds from 3 regions. + +category: RPCs +status: live +metric: RPC latency +unit: ms +higher_is_better: false + +seo_intro: | + Hedera is a proof-of-stake public distributed ledger using the Hashgraph consensus algorithm (asynchronous Byzantine Fault Tolerant), targeting high throughput and deterministic finality in under 3 seconds. Hedera exposes an EVM-compatible JSON-RPC layer via Hashio, allowing standard eth_getBlockByNumber calls. Public EVM-compatible endpoints are available without an API key from Hashio (operated by the Hedera Foundation) and thirdweb. Every provider was live-verified with consecutive eth_getBlockByNumber probes at launch. + +abstract: | + Per-chain member of the RPC latency cluster, extended to Hedera. + We measure the round-trip latency of a single eth_getBlockByNumber + ("latest", false) call against every available public Hedera EVM + node that sustains continuous probing: 2 providers at launch, every + 60 seconds, from us-east, eu-west and Singapore. The harness + classifies every response (ok / http_err / jsonrpc_err / stale / + timeout) with a Hedera-scaled staleness gap (100 blocks, around + 5 min at 3 s/block). The cross-chain view lives on the parent + rpc-capabilities benchmark; this page is the Hedera-scoped answer + with per-region breakdowns as a first-class dimension. + +methodology: + - "Cadence: every 60 seconds per provider, from each of 3 probe regions (us-east Virginia, eu-west Amsterdam, sgp Singapore). Headline p50/p90/p99 aggregate across all 3 regions via Prometheus avg(quantile_over_time(...)); per-region breakdowns are first-class on this page via the region tabs." + - "Payload: {\"jsonrpc\":\"2.0\",\"id\":,\"method\":\"eth_getBlockByNumber\",\"params\":[\"latest\",false]}. Plain HTTP POST. Standard Ethereum JSON-RPC 2.0 — Hedera's Hashio layer is EVM-compatible." + - "Latency: client-side round-trip delta in milliseconds, exposed as both a gauge and a histogram (buckets 50 ms to 10 s), so percentiles are computed via Prometheus quantile_over_time over the last 24 hours." + - "Call-result classification: ok (HTTP 200 + parsable block number), http_err, jsonrpc_err, stale (block more than 100 behind the cross-provider tip), timeout. Latency without reliability is a misleading ranking signal." + - "This page is part of the per-chain RPC cluster derived from the cross-chain rpc-capabilities benchmark; the identical harness, cadence and exclusion rules apply on every chain." + - "Chain scope: every query on this page is pinned to chain=hedera. Provider coverage at launch: 2 endpoints (Hashio, thirdweb)." + +findings: + - "{{best_name}} currently leads Hedera RPC at {{best_p50}} (eth_getBlockByNumber p50, 24h) across 2 measured providers." + +faq: + - q: "What is the fastest free Hedera RPC right now?" + a: "{{best_name}} currently leads at {{best_p50}} (Hedera EVM block height p50 over the last 24h), measured against 2 providers probed every 60 seconds from us-east, eu-west and Singapore. The leaderboard re-sorts continuously against fresh Prometheus samples." + - q: "Which Hedera RPC endpoints work without an API key?" + a: "2 endpoints sustain continuous keyless probing at launch: Hashio (mainnet.hashio.io/api, operated by the Hedera Foundation) and thirdweb (295.rpc.thirdweb.com). Every listed endpoint was live-verified with an eth_getBlockByNumber call returning a parsable block number before inclusion." + - q: "Does the fastest Hedera RPC change by region?" + a: "Often. Public infra concentrates in specific regions; a gateway that wins from Amsterdam can lose from Singapore by multiples. The region tabs at the top of the page re-scope every number to a single origin." + - q: "How is Hedera RPC latency measured here, technically?" + a: "One eth_getBlockByNumber JSON-RPC call every 60 seconds against each provider from each of 3 regions. Wall-clock round-trip is recorded at millisecond precision; p50/p90/p99 are computed via Prometheus quantile_over_time over 24 hours. Best-effort measurements; p50 is the median, p90 the 90th percentile and p99 the 99th percentile of latency samples collected over the last 24 hours." + +source: https://github.com/ChainBench/OpenChainBench/tree/main/harnesses/rpc-capabilities + +prometheus: + window: 24h + freshness_metric: rpc_latency_milliseconds + +rank_matrix_query: avg by (provider, region) (ocb:rpc_latency_milliseconds:p50_24h{chain="hedera"}) + +dimensions: + region: + - { value: all, label: All regions } + - { value: us-east, label: US-East } + - { value: eu-west, label: EU-West } + - { value: sgp, label: Singapore } + +providers: + - slug: hashio + name: Hashio + tag: Hedera Foundation Hashio public EVM JSON-RPC endpoint, keyless + formula: "50th percentile over 24h of client-side round-trip latency (ms) for an eth_getBlockByNumber POST sent every 60s from 3 regions to mainnet.hashio.io/api." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="hashio", chain="hedera"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="hashio", chain="hedera"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="hashio", chain="hedera"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="hashio", chain="hedera"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="hashio", chain="hedera"}) / sum(ocb:rpc_call:rate_24h{provider="hashio", chain="hedera"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="hashio", chain="hedera"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="hashio", chain="hedera"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="hashio", chain="hedera", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="hashio", chain="hedera", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="hashio", chain="hedera", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="hashio", chain="hedera", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="hashio", chain="hedera", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="hashio", chain="hedera", region="sgp"}[1h]) + + - slug: thirdweb + name: thirdweb + tag: thirdweb public RPC for Hedera EVM (chain 295), no key required + formula: "50th percentile over 24h of client-side round-trip latency (ms) for an eth_getBlockByNumber POST sent every 60s from 3 regions to 295.rpc.thirdweb.com." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="thirdweb", chain="hedera"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="thirdweb", chain="hedera"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="thirdweb", chain="hedera"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="thirdweb", chain="hedera"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="thirdweb", chain="hedera"}) / sum(ocb:rpc_call:rate_24h{provider="thirdweb", chain="hedera"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="thirdweb", chain="hedera"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="thirdweb", chain="hedera"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="thirdweb", chain="hedera", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="thirdweb", chain="hedera", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="thirdweb", chain="hedera", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="thirdweb", chain="hedera", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="thirdweb", chain="hedera", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="thirdweb", chain="hedera", region="sgp"}[1h]) diff --git a/benchmarks/multiversx-rpc.yml b/benchmarks/multiversx-rpc.yml new file mode 100644 index 00000000..b8dcf82d --- /dev/null +++ b/benchmarks/multiversx-rpc.yml @@ -0,0 +1,112 @@ +# OpenChainBench. Bench No 220 + +slug: multiversx-rpc +number: "220" +title: Fastest free MultiversX RPC, live no-key endpoint latency +seo_title: "Fastest free MultiversX RPC 2026" +seo_description: "{{best_name}} leads free MultiversX RPC at {{best_p50}} (metachain erd_nonce p50, 24h). 2 providers measured every 60s from 3 regions." +subtitle: HTTP round-trip latency for GET /network/status/4294967295 (metachain nonce) against every available public MultiversX node, audited every 60 seconds from 3 regions. + +category: RPCs +status: live +metric: RPC latency +unit: ms +higher_is_better: false + +seo_intro: | + MultiversX (formerly Elrond) is a proof-of-stake L1 blockchain using Secure Proof of Stake (SPoS) with adaptive state sharding, supporting up to 15,000 TPS per shard. The metachain coordinates shard consensus and commits a nonce (block height) approximately every 6 seconds with immediate finality. Public gateway endpoints are available without an API key from the MultiversX Foundation. Every provider was live-verified with consecutive metachain status probes at launch. + +abstract: | + Per-chain member of the RPC latency cluster, extended to MultiversX. + We measure the round-trip latency of a single REST GET to + /network/status/4294967295 (metachain) against every available public + MultiversX node that sustains continuous probing: 2 providers at launch, + every 60 seconds, from us-east, eu-west and Singapore. The harness + classifies every response (ok / http_err / stale / timeout) with a + MultiversX-scaled staleness gap (50 nonces, around 5 min at 6 s/nonce). + The cross-chain view lives on the parent rpc-capabilities benchmark; + this page is the MultiversX-scoped answer with per-region breakdowns + as a first-class dimension. + +methodology: + - "Cadence: every 60 seconds per provider, from each of 3 probe regions (us-east Virginia, eu-west Amsterdam, sgp Singapore). Headline p50/p90/p99 aggregate across all 3 regions via Prometheus avg(quantile_over_time(...)); per-region breakdowns are first-class on this page via the region tabs." + - "Payload: HTTP GET to /network/status/4294967295 with Accept: application/json. The shard ID 4294967295 (0xFFFFFFFF) is the MultiversX metachain identifier. The response carries data.status.erd_nonce as a decimal uint64." + - "Latency: client-side round-trip delta in milliseconds, exposed as both a gauge and a histogram (buckets 50 ms to 10 s), so percentiles are computed via Prometheus quantile_over_time over the last 24 hours." + - "Call-result classification: ok (HTTP 200 + parsable erd_nonce), http_err, stale (nonce more than 50 behind the cross-provider tip), timeout. Latency without reliability is a misleading ranking signal." + - "This page is part of the per-chain RPC cluster derived from the cross-chain rpc-capabilities benchmark; the identical harness, cadence and exclusion rules apply on every chain." + - "Chain scope: every query on this page is pinned to chain=multiversx. Provider coverage at launch: 2 endpoints (MultiversX Gateway, MultiversX API)." + +findings: + - "{{best_name}} currently leads MultiversX RPC at {{best_p50}} (metachain erd_nonce p50, 24h) across 2 measured providers." + +faq: + - q: "What is the fastest free MultiversX RPC right now?" + a: "{{best_name}} currently leads at {{best_p50}} (MultiversX metachain nonce p50 over the last 24h), measured against 2 providers probed every 60 seconds from us-east, eu-west and Singapore. The leaderboard re-sorts continuously against fresh Prometheus samples." + - q: "Which MultiversX RPC endpoints work without an API key?" + a: "2 endpoints sustain continuous keyless probing at launch: the MultiversX Gateway (gateway.multiversx.com) and the MultiversX API (api.multiversx.com). Every listed endpoint was live-verified with a GET /network/status/4294967295 returning a parsable erd_nonce before inclusion." + - q: "Does the fastest MultiversX RPC change by region?" + a: "Often. Public infra concentrates in specific regions; a gateway that wins from Amsterdam can lose from Singapore by multiples. The region tabs at the top of the page re-scope every number to a single origin." + - q: "How is MultiversX RPC latency measured here, technically?" + a: "One GET /network/status/4294967295 REST call every 60 seconds against each provider from each of 3 regions. Wall-clock round-trip is recorded at millisecond precision; p50/p90/p99 are computed via Prometheus quantile_over_time over 24 hours. Best-effort measurements; p50 is the median, p90 the 90th percentile and p99 the 99th percentile of latency samples collected over the last 24 hours." + +source: https://github.com/ChainBench/OpenChainBench/tree/main/harnesses/rpc-capabilities + +prometheus: + window: 24h + freshness_metric: rpc_latency_milliseconds + +rank_matrix_query: avg by (provider, region) (ocb:rpc_latency_milliseconds:p50_24h{chain="multiversx"}) + +dimensions: + region: + - { value: all, label: All regions } + - { value: us-east, label: US-East } + - { value: eu-west, label: EU-West } + - { value: sgp, label: Singapore } + +providers: + - slug: mvx-gateway + name: MultiversX Gateway + tag: MultiversX Foundation official gateway, public REST endpoint, no key required + formula: "50th percentile over 24h of client-side round-trip latency (ms) for a GET /network/status/4294967295 sent every 60s from 3 regions to gateway.multiversx.com." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="mvx-gateway", chain="multiversx"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="mvx-gateway", chain="multiversx"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="mvx-gateway", chain="multiversx"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="mvx-gateway", chain="multiversx"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="mvx-gateway", chain="multiversx"}) / sum(ocb:rpc_call:rate_24h{provider="mvx-gateway", chain="multiversx"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="mvx-gateway", chain="multiversx"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="mvx-gateway", chain="multiversx"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="mvx-gateway", chain="multiversx", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="mvx-gateway", chain="multiversx", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="mvx-gateway", chain="multiversx", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="mvx-gateway", chain="multiversx", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="mvx-gateway", chain="multiversx", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="mvx-gateway", chain="multiversx", region="sgp"}[1h]) + + - slug: mvx-api + name: MultiversX API + tag: MultiversX Foundation official API endpoint, public REST, no key required + formula: "50th percentile over 24h of client-side round-trip latency (ms) for a GET /network/status/4294967295 sent every 60s from 3 regions to api.multiversx.com." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="mvx-api", chain="multiversx"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="mvx-api", chain="multiversx"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="mvx-api", chain="multiversx"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="mvx-api", chain="multiversx"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="mvx-api", chain="multiversx"}) / sum(ocb:rpc_call:rate_24h{provider="mvx-api", chain="multiversx"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="mvx-api", chain="multiversx"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="mvx-api", chain="multiversx"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="mvx-api", chain="multiversx", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="mvx-api", chain="multiversx", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="mvx-api", chain="multiversx", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="mvx-api", chain="multiversx", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="mvx-api", chain="multiversx", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="mvx-api", chain="multiversx", region="sgp"}[1h]) diff --git a/benchmarks/near-rpc.yml b/benchmarks/near-rpc.yml new file mode 100644 index 00000000..4065fae2 --- /dev/null +++ b/benchmarks/near-rpc.yml @@ -0,0 +1,157 @@ +# OpenChainBench. Bench No 216 + +slug: near-rpc +number: "216" +title: Fastest free NEAR RPC, live no-key endpoint latency +seo_title: "Fastest free NEAR Protocol RPC 2026" +seo_description: "{{best_name}} leads free NEAR RPC at {{best_p50}} (block/finality:final height p50, 24h). 4 providers measured every 60s from 3 regions." +subtitle: HTTP round-trip latency for block (finality=final) against every available public NEAR Protocol node, audited every 60 seconds from 3 regions. + +category: RPCs +status: live +metric: RPC latency +unit: ms +higher_is_better: false + +seo_intro: | + NEAR Protocol is a sharded Proof-of-Stake L1 blockchain using Nightshade sharding and Doomslug consensus, targeting roughly one block per second with near-instant practical finality. Public JSON-RPC endpoints are available without an API key from the NEAR Foundation, FastNEAR, Lava Network and dRPC. Every provider was live-verified with consecutive block/finality:final probes at launch. + +abstract: | + Per-chain member of the RPC latency cluster, extended to NEAR Protocol. + We measure the round-trip latency of a single JSON-RPC call (block with + finality=final) against every available public NEAR node that sustains + continuous probing: 4 providers at launch, every 60 seconds, from + us-east, eu-west and Singapore. The harness classifies every response + (ok / http_err / jsonrpc_err / stale / timeout) with a NEAR-scaled + staleness gap (300 blocks, around 5 min). The cross-chain view lives on + the parent rpc-capabilities benchmark; this page is the NEAR-scoped + answer with per-region breakdowns as a first-class dimension. + +methodology: + - "Cadence: every 60 seconds per provider, from each of 3 probe regions (us-east Virginia, eu-west Amsterdam, sgp Singapore). Headline p50/p90/p99 aggregate across all 3 regions via Prometheus avg(quantile_over_time(...)); per-region breakdowns are first-class on this page via the region tabs." + - "Payload: {\"jsonrpc\":\"2.0\",\"id\":,\"method\":\"block\",\"params\":{\"finality\":\"final\"}}. Plain HTTP POST. The response carries result.header.height as a decimal uint64." + - "Latency: client-side round-trip delta in milliseconds, exposed as both a gauge and a histogram (buckets 50 ms to 10 s), so percentiles are computed via Prometheus quantile_over_time over the last 24 hours." + - "Call-result classification: ok (HTTP 200 + parsable result.header.height), http_err, jsonrpc_err, stale (block more than 300 behind the cross-provider tip), timeout. Latency without reliability is a misleading ranking signal." + - "This page is part of the per-chain RPC cluster derived from the cross-chain rpc-capabilities benchmark; the identical harness, cadence and exclusion rules apply on every chain." + - "Chain scope: every query on this page is pinned to chain=near. Provider coverage at launch: 4 endpoints (NEAR Foundation, FastNEAR, Lava, dRPC)." + +findings: + - "{{best_name}} currently leads NEAR RPC at {{best_p50}} (block/finality:final height p50, 24h) across 4 measured providers." + +faq: + - q: "What is the fastest free NEAR Protocol RPC right now?" + a: "{{best_name}} currently leads at {{best_p50}} (NEAR block height p50 over the last 24h), measured against 4 providers probed every 60 seconds from us-east, eu-west and Singapore. The leaderboard re-sorts continuously against fresh Prometheus samples." + - q: "Which NEAR RPC endpoints work without an API key?" + a: "4 endpoints sustain continuous keyless probing at launch: NEAR Foundation (rpc.mainnet.near.org), FastNEAR (free.rpc.fastnear.com), Lava (near.lava.build) and dRPC (near.drpc.org). Every listed endpoint was live-verified with a block/finality:final call returning a parsable height before inclusion." + - q: "Does the fastest NEAR RPC change by region?" + a: "Often. Public infra concentrates in specific regions; a gateway that wins from Amsterdam can lose from Singapore by multiples. The region tabs at the top of the page re-scope every number to a single origin." + - q: "How is NEAR RPC latency measured here, technically?" + a: "One block/finality:final JSON-RPC call every 60 seconds against each provider from each of 3 regions. Wall-clock round-trip is recorded at millisecond precision; p50/p90/p99 are computed via Prometheus quantile_over_time over 24 hours. Best-effort measurements; p50 is the median, p90 the 90th percentile and p99 the 99th percentile of latency samples collected over the last 24 hours." + +source: https://github.com/ChainBench/OpenChainBench/tree/main/harnesses/rpc-capabilities + +prometheus: + window: 24h + freshness_metric: rpc_latency_milliseconds + +rank_matrix_query: avg by (provider, region) (ocb:rpc_latency_milliseconds:p50_24h{chain="near"}) + +dimensions: + region: + - { value: all, label: All regions } + - { value: us-east, label: US-East } + - { value: eu-west, label: EU-West } + - { value: sgp, label: Singapore } + +providers: + - slug: near-org + name: NEAR Foundation + tag: Official NEAR Foundation public mainnet RPC, keyless + formula: "50th percentile over 24h of client-side round-trip latency (ms) for a block/finality:final POST sent every 60s from 3 regions to rpc.mainnet.near.org." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="near-org", chain="near"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="near-org", chain="near"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="near-org", chain="near"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="near-org", chain="near"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="near-org", chain="near"}) / sum(ocb:rpc_call:rate_24h{provider="near-org", chain="near"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="near-org", chain="near"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="near-org", chain="near"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="near-org", chain="near", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="near-org", chain="near", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="near-org", chain="near", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="near-org", chain="near", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="near-org", chain="near", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="near-org", chain="near", region="sgp"}[1h]) + + - slug: fastnear + name: FastNEAR + tag: FastNEAR community RPC, free tier, no key required + formula: "50th percentile over 24h of client-side round-trip latency (ms) for a block/finality:final POST sent every 60s from 3 regions to free.rpc.fastnear.com." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="fastnear", chain="near"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="fastnear", chain="near"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="fastnear", chain="near"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="fastnear", chain="near"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="fastnear", chain="near"}) / sum(ocb:rpc_call:rate_24h{provider="fastnear", chain="near"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="fastnear", chain="near"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="fastnear", chain="near"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="fastnear", chain="near", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="fastnear", chain="near", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="fastnear", chain="near", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="fastnear", chain="near", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="fastnear", chain="near", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="fastnear", chain="near", region="sgp"}[1h]) + + - slug: lava + name: Lava + tag: Lava Network decentralised RPC, public NEAR endpoint, no key required + formula: "50th percentile over 24h of client-side round-trip latency (ms) for a block/finality:final POST sent every 60s from 3 regions to near.lava.build." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="lava", chain="near"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="lava", chain="near"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="lava", chain="near"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="lava", chain="near"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="lava", chain="near"}) / sum(ocb:rpc_call:rate_24h{provider="lava", chain="near"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="lava", chain="near"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="lava", chain="near"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="lava", chain="near", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="lava", chain="near", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="lava", chain="near", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="lava", chain="near", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="lava", chain="near", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="lava", chain="near", region="sgp"}[1h]) + + - slug: drpc + name: dRPC + tag: dRPC decentralised multi-chain RPC, public NEAR endpoint, no key required + formula: "50th percentile over 24h of client-side round-trip latency (ms) for a block/finality:final POST sent every 60s from 3 regions to near.drpc.org." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="drpc", chain="near"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="drpc", chain="near"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="drpc", chain="near"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="drpc", chain="near"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="drpc", chain="near"}) / sum(ocb:rpc_call:rate_24h{provider="drpc", chain="near"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="drpc", chain="near"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="drpc", chain="near"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="drpc", chain="near", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="drpc", chain="near", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="drpc", chain="near", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="drpc", chain="near", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="drpc", chain="near", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="drpc", chain="near", region="sgp"}[1h]) diff --git a/benchmarks/neo-rpc.yml b/benchmarks/neo-rpc.yml new file mode 100644 index 00000000..96cd042a --- /dev/null +++ b/benchmarks/neo-rpc.yml @@ -0,0 +1,135 @@ +# OpenChainBench. Bench No 221 + +slug: neo-rpc +number: "221" +title: Fastest free NEO N3 RPC, live no-key endpoint latency +seo_title: "Fastest free NEO N3 RPC 2026" +seo_description: "{{best_name}} leads free NEO N3 RPC at {{best_p50}} (getblockcount p50, 24h). 3 providers measured every 60s from 3 regions." +subtitle: HTTP round-trip latency for getblockcount against every available public NEO N3 node, audited every 60 seconds from 3 regions. + +category: RPCs +status: live +metric: RPC latency +unit: ms +higher_is_better: false + +seo_intro: | + NEO N3 is the third generation of the NEO blockchain, a delegated Byzantine Fault Tolerant (dBFT) proof-of-stake L1 blockchain targeting one block every 15 seconds with one-block deterministic finality. NEO N3 uses a dual-token model (NEO for governance/GAS generation, GAS for transaction fees) and supports smart contracts in multiple languages via the NeoVM. Public JSON-RPC endpoints are available without an API key from NSPCC and Neo Global Development. Every provider was live-verified with consecutive getblockcount probes at launch. + +abstract: | + Per-chain member of the RPC latency cluster, extended to NEO N3. + We measure the round-trip latency of a single JSON-RPC call + (getblockcount) against every available public NEO N3 node that + sustains continuous probing: 3 providers at launch, every 60 seconds, + from us-east, eu-west and Singapore. The harness classifies every + response (ok / http_err / jsonrpc_err / stale / timeout) with a + NEO-scaled staleness gap (20 blocks, around 5 min at 15 s/block). + The cross-chain view lives on the parent rpc-capabilities benchmark; + this page is the NEO N3-scoped answer with per-region breakdowns as + a first-class dimension. + +methodology: + - "Cadence: every 60 seconds per provider, from each of 3 probe regions (us-east Virginia, eu-west Amsterdam, sgp Singapore). Headline p50/p90/p99 aggregate across all 3 regions via Prometheus avg(quantile_over_time(...)); per-region breakdowns are first-class on this page via the region tabs." + - "Payload: {\"jsonrpc\":\"2.0\",\"id\":,\"method\":\"getblockcount\",\"params\":[]}. Plain HTTP POST. The result is a decimal integer (block count = current height + 1)." + - "Latency: client-side round-trip delta in milliseconds, exposed as both a gauge and a histogram (buckets 50 ms to 10 s), so percentiles are computed via Prometheus quantile_over_time over the last 24 hours." + - "Call-result classification: ok (HTTP 200 + parsable block count), http_err, jsonrpc_err, stale (block more than 20 behind the cross-provider tip), timeout. Latency without reliability is a misleading ranking signal." + - "This page is part of the per-chain RPC cluster derived from the cross-chain rpc-capabilities benchmark; the identical harness, cadence and exclusion rules apply on every chain." + - "Chain scope: every query on this page is pinned to chain=neo. Provider coverage at launch: 3 endpoints (NSPCC, NGD seed 1, NGD seed 2)." + +findings: + - "{{best_name}} currently leads NEO N3 RPC at {{best_p50}} (getblockcount p50, 24h) across 3 measured providers." + +faq: + - q: "What is the fastest free NEO N3 RPC right now?" + a: "{{best_name}} currently leads at {{best_p50}} (NEO N3 block count p50 over the last 24h), measured against 3 providers probed every 60 seconds from us-east, eu-west and Singapore. The leaderboard re-sorts continuously against fresh Prometheus samples." + - q: "Which NEO N3 RPC endpoints work without an API key?" + a: "3 endpoints sustain continuous keyless probing at launch: NSPCC (rpc10.n3.nspcc.ru:10331), NGD seed node 1 (n3seed1.ngd.network:10332) and NGD seed node 2 (n3seed2.ngd.network:10332). Every listed endpoint was live-verified with a getblockcount call returning a parsable block count before inclusion." + - q: "Does the fastest NEO N3 RPC change by region?" + a: "Often. Public infra concentrates in specific regions; NSPCC is Russia-hosted and NGD nodes are in Asia, so latency rankings shift significantly by origin. The region tabs at the top of the page re-scope every number to a single origin." + - q: "How is NEO N3 RPC latency measured here, technically?" + a: "One getblockcount JSON-RPC call every 60 seconds against each provider from each of 3 regions. Wall-clock round-trip is recorded at millisecond precision; p50/p90/p99 are computed via Prometheus quantile_over_time over 24 hours. Best-effort measurements; p50 is the median, p90 the 90th percentile and p99 the 99th percentile of latency samples collected over the last 24 hours." + +source: https://github.com/ChainBench/OpenChainBench/tree/main/harnesses/rpc-capabilities + +prometheus: + window: 24h + freshness_metric: rpc_latency_milliseconds + +rank_matrix_query: avg by (provider, region) (ocb:rpc_latency_milliseconds:p50_24h{chain="neo"}) + +dimensions: + region: + - { value: all, label: All regions } + - { value: us-east, label: US-East } + - { value: eu-west, label: EU-West } + - { value: sgp, label: Singapore } + +providers: + - slug: nspcc + name: NSPCC + tag: NSPCC NEO N3 public mainnet RPC node, keyless + formula: "50th percentile over 24h of client-side round-trip latency (ms) for a getblockcount POST sent every 60s from 3 regions to rpc10.n3.nspcc.ru:10331." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="nspcc", chain="neo"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="nspcc", chain="neo"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="nspcc", chain="neo"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="nspcc", chain="neo"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="nspcc", chain="neo"}) / sum(ocb:rpc_call:rate_24h{provider="nspcc", chain="neo"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="nspcc", chain="neo"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="nspcc", chain="neo"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="nspcc", chain="neo", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="nspcc", chain="neo", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="nspcc", chain="neo", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="nspcc", chain="neo", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="nspcc", chain="neo", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="nspcc", chain="neo", region="sgp"}[1h]) + + - slug: ngd + name: NGD + tag: Neo Global Development seed node 1, public mainnet RPC, no key required + formula: "50th percentile over 24h of client-side round-trip latency (ms) for a getblockcount POST sent every 60s from 3 regions to n3seed1.ngd.network:10332." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="ngd", chain="neo"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="ngd", chain="neo"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="ngd", chain="neo"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="ngd", chain="neo"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="ngd", chain="neo"}) / sum(ocb:rpc_call:rate_24h{provider="ngd", chain="neo"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="ngd", chain="neo"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="ngd", chain="neo"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="ngd", chain="neo", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="ngd", chain="neo", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="ngd", chain="neo", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="ngd", chain="neo", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="ngd", chain="neo", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="ngd", chain="neo", region="sgp"}[1h]) + + - slug: ngd2 + name: NGD (2) + tag: Neo Global Development seed node 2, public mainnet RPC, no key required + formula: "50th percentile over 24h of client-side round-trip latency (ms) for a getblockcount POST sent every 60s from 3 regions to n3seed2.ngd.network:10332." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="ngd2", chain="neo"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="ngd2", chain="neo"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="ngd2", chain="neo"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="ngd2", chain="neo"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="ngd2", chain="neo"}) / sum(ocb:rpc_call:rate_24h{provider="ngd2", chain="neo"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="ngd2", chain="neo"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="ngd2", chain="neo"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="ngd2", chain="neo", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="ngd2", chain="neo", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="ngd2", chain="neo", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="ngd2", chain="neo", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="ngd2", chain="neo", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="ngd2", chain="neo", region="sgp"}[1h]) diff --git a/harnesses/rpc-capabilities/cmd/script/config.go b/harnesses/rpc-capabilities/cmd/script/config.go index 01ab39f6..46762b62 100644 --- a/harnesses/rpc-capabilities/cmd/script/config.go +++ b/harnesses/rpc-capabilities/cmd/script/config.go @@ -1551,6 +1551,69 @@ func chains() []Chain { {Slug: "uniblock", Name: "Uniblock", URL: envDefault("RPC_URL_GRAM_UNIBLOCK", "https://api.uniblock.dev/uni/v1/json-rpc?chainId=toncoin")}, }, }, + // NEAR Protocol — JSON-RPC block/finality:final, ~1 block/s. 4 keyless providers. + { + Slug: "near", + Name: "NEAR Protocol", + Kind: "near", + Providers: []Provider{ + {Slug: "near-org", Name: "NEAR Foundation", URL: envDefault("RPC_URL_NEAR_NEARORG", "https://rpc.mainnet.near.org")}, + {Slug: "fastnear", Name: "FastNEAR", URL: envDefault("RPC_URL_NEAR_FASTNEAR", "https://free.rpc.fastnear.com")}, + {Slug: "lava", Name: "Lava", URL: envDefault("RPC_URL_NEAR_LAVA", "https://near.lava.build")}, + {Slug: "drpc", Name: "dRPC", URL: envDefault("RPC_URL_NEAR_DRPC", "https://near.drpc.org")}, + }, + }, + // Flow — Cadence REST GET /v1/blocks?height=sealed, ~1.25 s/block. 2 public REST nodes. + { + Slug: "flow", + Name: "Flow", + Kind: "flow", + Providers: []Provider{ + {Slug: "onflow", Name: "Flow Foundation", URL: envDefault("RPC_URL_FLOW_ONFLOW", "https://rest-mainnet.onflow.org")}, + {Slug: "flow-access", Name: "Flow Access Node", URL: envDefault("RPC_URL_FLOW_ACCESS", "https://access.mainnet.nodes.onflow.org")}, + }, + }, + // Hedera — EVM-compatible JSON-RPC (eth_getBlockByNumber), ~3 s/block. 2 keyless providers. + { + Slug: "hedera", + Name: "Hedera", + Kind: "hedera", + Providers: []Provider{ + {Slug: "hashio", Name: "Hashio", URL: envDefault("RPC_URL_HEDERA_HASHIO", "https://mainnet.hashio.io/api")}, + {Slug: "thirdweb", Name: "thirdweb", URL: envDefault("RPC_URL_HEDERA_THIRDWEB", "https://295.rpc.thirdweb.com")}, + }, + }, + // Nervos CKB — get_tip_block_number JSON-RPC (hex result), ~10 s/block. 2 keyless providers. + { + Slug: "ckb", + Name: "Nervos CKB", + Kind: "ckb", + Providers: []Provider{ + {Slug: "ckb-dev", Name: "Nervos Foundation", URL: envDefault("RPC_URL_CKB_CKBDEV", "https://mainnet.ckb.dev/rpc")}, + {Slug: "ckbapp", Name: "CKBapp", URL: envDefault("RPC_URL_CKB_CKBAPP", "https://mainnet.ckbapp.dev/rpc")}, + }, + }, + // MultiversX — REST GET /network/status/4294967295 erd_nonce, ~6 s/nonce. 2 keyless providers. + { + Slug: "multiversx", + Name: "MultiversX", + Kind: "multiversx", + Providers: []Provider{ + {Slug: "mvx-gateway", Name: "MultiversX Gateway", URL: envDefault("RPC_URL_MULTIVERSX_GATEWAY", "https://gateway.multiversx.com")}, + {Slug: "mvx-api", Name: "MultiversX API", URL: envDefault("RPC_URL_MULTIVERSX_API", "https://api.multiversx.com")}, + }, + }, + // NEO N3 — getblockcount JSON-RPC (decimal result), ~15 s/block. 3 keyless providers. + { + Slug: "neo", + Name: "NEO N3", + Kind: "neo", + Providers: []Provider{ + {Slug: "nspcc", Name: "NSPCC", URL: envDefault("RPC_URL_NEO_NSPCC", "https://rpc10.n3.nspcc.ru:10331")}, + {Slug: "ngd", Name: "NGD", URL: envDefault("RPC_URL_NEO_NGD", "https://n3seed1.ngd.network:10332")}, + {Slug: "ngd2", Name: "NGD (2)", URL: envDefault("RPC_URL_NEO_NGD2", "https://n3seed2.ngd.network:10332")}, + }, + }, } filter := strings.TrimSpace(os.Getenv("OCB_CHAINS")) diff --git a/harnesses/rpc-capabilities/cmd/script/probe.go b/harnesses/rpc-capabilities/cmd/script/probe.go index dfd931ee..b27424ac 100644 --- a/harnesses/rpc-capabilities/cmd/script/probe.go +++ b/harnesses/rpc-capabilities/cmd/script/probe.go @@ -64,6 +64,22 @@ const ( // gramStaleSeqnoGap: TON/Gram masterchain seqno advances every ~5 s, // so 60 seqnos ≈ 5 min. gramStaleSeqnoGap uint64 = 60 + // nearStaleBlockGap: NEAR commits ~1 block/s, so 300 blocks ≈ 5 min. + nearStaleBlockGap uint64 = 300 + // flowStaleBlockGap: Flow Cadence commits one block every ~1.25 s, + // so 240 blocks ≈ 5 min. + flowStaleBlockGap uint64 = 240 + // hederaStaleBlockGap: Hedera EVM blocks every ~3 s, so 100 blocks ≈ 5 min. + hederaStaleBlockGap uint64 = 100 + // ckbStaleBlockGap: Nervos CKB commits one block every ~10 s, + // so 30 blocks ≈ 5 min. + ckbStaleBlockGap uint64 = 30 + // multiversxStaleNonceGap: MultiversX meta-chain nonce advances every ~6 s, + // so 50 nonces ≈ 5 min. + multiversxStaleNonceGap uint64 = 50 + // neoStaleBlockGap: NEO N3 commits one block every ~15 s, + // so 20 blocks ≈ 5 min. + neoStaleBlockGap uint64 = 20 ) // chainTips tracks the highest block seen for each chain across all @@ -242,6 +258,16 @@ func probeOne(ctx context.Context, c Chain, p Provider) { block, result, latency, err = callAlgorandStatus(probeCtx, p.URL) case "gram": block, result, latency, err = callGramSeqno(probeCtx, p.URL) + case "near": + block, result, latency, err = callNearBlock(probeCtx, p.URL) + case "flow": + block, result, latency, err = callFlowBlock(probeCtx, p.URL) + case "ckb": + block, result, latency, err = callCkbTipBlockNumber(probeCtx, p.URL) + case "multiversx": + block, result, latency, err = callMultiversxNonce(probeCtx, p.URL) + case "neo": + block, result, latency, err = callNeoBlockCount(probeCtx, p.URL) default: block, hash, result, latency, err = callLatestBlock(probeCtx, p.URL) } @@ -271,6 +297,18 @@ func probeOne(ctx context.Context, c Chain, p Provider) { gap = algorandStaleRoundGap case "gram": gap = gramStaleSeqnoGap + case "near": + gap = nearStaleBlockGap + case "flow": + gap = flowStaleBlockGap + case "hedera": + gap = hederaStaleBlockGap + case "ckb": + gap = ckbStaleBlockGap + case "multiversx": + gap = multiversxStaleNonceGap + case "neo": + gap = neoStaleBlockGap } if tip > 0 && block+gap < tip { result = "stale" @@ -290,7 +328,8 @@ func probeOne(ctx context.Context, c Chain, p Provider) { // hash normalisation across Cosmos chains is validated). switch c.Kind { case "solana", "polkadot", "cosmos", "starknet", "stellar", - "sui", "aptos", "xrpl", "algorand", "gram": + "sui", "aptos", "xrpl", "algorand", "gram", + "near", "flow", "hedera", "ckb", "multiversx", "neo": // no consensus participation default: if result == "ok" || result == "stale" { @@ -940,3 +979,275 @@ func callGramSeqno(ctx context.Context, url string) (seqno uint64, result string } return mc.Last.Seqno, "ok", latencyMs, nil } + +// nearBlockHeader is the shape of result.header in a NEAR `block` JSON-RPC response. +type nearBlockHeader struct { + Height uint64 `json:"height"` +} + +type nearBlockResult struct { + Header nearBlockHeader `json:"header"` +} + +// callNearBlock probes a NEAR node via the `block` JSON-RPC method with finality=final. +// Staleness uses nearStaleBlockGap in probeOne. +func callNearBlock(ctx context.Context, url string) (height uint64, result string, latencyMs float64, err error) { + body := []byte(fmt.Sprintf( + `{"jsonrpc":"2.0","method":"block","params":{"finality":"final"},"id":%d}`, + time.Now().UnixNano(), + )) + req, _ := http.NewRequestWithContext(ctx, "POST", url, bytes.NewReader(body)) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("User-Agent", "OpenChainBench/1.0 (+https://openchainbench.com)") + client := &http.Client{Timeout: probeTimeout} + + start := time.Now() + resp, err := client.Do(req) + latencyMs = float64(time.Since(start).Nanoseconds()) / 1e6 + + if err != nil { + if ctx.Err() != nil || strings.Contains(err.Error(), "deadline exceeded") || strings.Contains(err.Error(), "Timeout") { + return 0, "timeout", latencyMs, err + } + return 0, "http_err", latencyMs, err + } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + _, _ = io.Copy(io.Discard, resp.Body) + return 0, "http_err", latencyMs, fmt.Errorf("status %d", resp.StatusCode) + } + + raw, err := io.ReadAll(resp.Body) + if err != nil { + return 0, "http_err", latencyMs, err + } + var r rpcBlockEnvelope + if err := json.Unmarshal(raw, &r); err != nil { + return 0, "http_err", latencyMs, err + } + if r.Error != nil { + return 0, "jsonrpc_err", latencyMs, fmt.Errorf("rpc -%d: %s", r.Error.Code, r.Error.Message) + } + if len(r.Result) == 0 || string(r.Result) == "null" { + return 0, "jsonrpc_err", latencyMs, fmt.Errorf("empty near result") + } + var blk nearBlockResult + if err := json.Unmarshal(r.Result, &blk); err != nil { + return 0, "jsonrpc_err", latencyMs, err + } + if blk.Header.Height == 0 { + return 0, "jsonrpc_err", latencyMs, fmt.Errorf("near block missing height") + } + return blk.Header.Height, "ok", latencyMs, nil +} + +// flowBlockEntry is the shape of one element in the array returned by +// GET /v1/blocks?height=sealed on the Flow Cadence REST API. +type flowBlockEntry struct { + Header struct { + Height string `json:"height"` + } `json:"header"` +} + +// callFlowBlock probes a Flow node via the Cadence REST endpoint GET /v1/blocks?height=sealed. +// The height field is a decimal string. Staleness uses flowStaleBlockGap in probeOne. +func callFlowBlock(ctx context.Context, url string) (height uint64, result string, latencyMs float64, err error) { + target := strings.TrimRight(url, "/") + "/v1/blocks?height=sealed" + req, _ := http.NewRequestWithContext(ctx, "GET", target, nil) + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", "OpenChainBench/1.0 (+https://openchainbench.com)") + client := &http.Client{Timeout: probeTimeout} + + start := time.Now() + resp, err := client.Do(req) + latencyMs = float64(time.Since(start).Nanoseconds()) / 1e6 + + if err != nil { + if ctx.Err() != nil || strings.Contains(err.Error(), "deadline exceeded") || strings.Contains(err.Error(), "Timeout") { + return 0, "timeout", latencyMs, err + } + return 0, "http_err", latencyMs, err + } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + _, _ = io.Copy(io.Discard, resp.Body) + return 0, "http_err", latencyMs, fmt.Errorf("status %d", resp.StatusCode) + } + + raw, err := io.ReadAll(resp.Body) + if err != nil { + return 0, "http_err", latencyMs, err + } + var blocks []flowBlockEntry + if err := json.Unmarshal(raw, &blocks); err != nil { + return 0, "http_err", latencyMs, err + } + if len(blocks) == 0 || blocks[0].Header.Height == "" { + return 0, "jsonrpc_err", latencyMs, fmt.Errorf("flow blocks response empty or missing height") + } + n, err := strconv.ParseUint(blocks[0].Header.Height, 10, 64) + if err != nil { + return 0, "jsonrpc_err", latencyMs, fmt.Errorf("non-numeric flow height: %s", blocks[0].Header.Height[:min(len(blocks[0].Header.Height), 40)]) + } + return n, "ok", latencyMs, nil +} + +// callCkbTipBlockNumber probes a Nervos CKB node via get_tip_block_number JSON-RPC. +// The result is a hex string ("0x..."). Staleness uses ckbStaleBlockGap in probeOne. +func callCkbTipBlockNumber(ctx context.Context, url string) (height uint64, result string, latencyMs float64, err error) { + body := []byte(fmt.Sprintf( + `{"jsonrpc":"2.0","method":"get_tip_block_number","params":[],"id":%d}`, + time.Now().UnixNano(), + )) + req, _ := http.NewRequestWithContext(ctx, "POST", url, bytes.NewReader(body)) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("User-Agent", "OpenChainBench/1.0 (+https://openchainbench.com)") + client := &http.Client{Timeout: probeTimeout} + + start := time.Now() + resp, err := client.Do(req) + latencyMs = float64(time.Since(start).Nanoseconds()) / 1e6 + + if err != nil { + if ctx.Err() != nil || strings.Contains(err.Error(), "deadline exceeded") || strings.Contains(err.Error(), "Timeout") { + return 0, "timeout", latencyMs, err + } + return 0, "http_err", latencyMs, err + } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + _, _ = io.Copy(io.Discard, resp.Body) + return 0, "http_err", latencyMs, fmt.Errorf("status %d", resp.StatusCode) + } + + raw, err := io.ReadAll(resp.Body) + if err != nil { + return 0, "http_err", latencyMs, err + } + var r rpcBlockEnvelope + if err := json.Unmarshal(raw, &r); err != nil { + return 0, "http_err", latencyMs, err + } + if r.Error != nil { + return 0, "jsonrpc_err", latencyMs, fmt.Errorf("rpc -%d: %s", r.Error.Code, r.Error.Message) + } + if len(r.Result) == 0 || string(r.Result) == "null" { + return 0, "jsonrpc_err", latencyMs, fmt.Errorf("empty ckb result") + } + var hexStr string + if err := json.Unmarshal(r.Result, &hexStr); err != nil { + return 0, "jsonrpc_err", latencyMs, err + } + n, err := strconv.ParseUint(strings.TrimPrefix(hexStr, "0x"), 16, 64) + if err != nil { + return 0, "jsonrpc_err", latencyMs, fmt.Errorf("non-hex ckb block number: %s", hexStr[:min(len(hexStr), 40)]) + } + return n, "ok", latencyMs, nil +} + +// multiversxNetworkStatus is the shape of GET /network/status/4294967295 on MultiversX gateway. +type multiversxNetworkStatus struct { + Data struct { + Status struct { + ErdNonce uint64 `json:"erd_nonce"` + } `json:"status"` + } `json:"data"` + Code string `json:"code"` +} + +// callMultiversxNonce probes a MultiversX node via GET /network/status/4294967295 (metachain). +// erd_nonce is the metachain block nonce (analogous to block height). +// Staleness uses multiversxStaleNonceGap in probeOne. +func callMultiversxNonce(ctx context.Context, url string) (nonce uint64, result string, latencyMs float64, err error) { + target := strings.TrimRight(url, "/") + "/network/status/4294967295" + req, _ := http.NewRequestWithContext(ctx, "GET", target, nil) + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", "OpenChainBench/1.0 (+https://openchainbench.com)") + client := &http.Client{Timeout: probeTimeout} + + start := time.Now() + resp, err := client.Do(req) + latencyMs = float64(time.Since(start).Nanoseconds()) / 1e6 + + if err != nil { + if ctx.Err() != nil || strings.Contains(err.Error(), "deadline exceeded") || strings.Contains(err.Error(), "Timeout") { + return 0, "timeout", latencyMs, err + } + return 0, "http_err", latencyMs, err + } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + _, _ = io.Copy(io.Discard, resp.Body) + return 0, "http_err", latencyMs, fmt.Errorf("status %d", resp.StatusCode) + } + + raw, err := io.ReadAll(resp.Body) + if err != nil { + return 0, "http_err", latencyMs, err + } + var st multiversxNetworkStatus + if err := json.Unmarshal(raw, &st); err != nil { + return 0, "http_err", latencyMs, err + } + if st.Code != "successful" { + return 0, "jsonrpc_err", latencyMs, fmt.Errorf("multiversx status code: %s", st.Code) + } + if st.Data.Status.ErdNonce == 0 { + return 0, "jsonrpc_err", latencyMs, fmt.Errorf("multiversx missing erd_nonce") + } + return st.Data.Status.ErdNonce, "ok", latencyMs, nil +} + +// callNeoBlockCount probes a NEO N3 node via getblockcount JSON-RPC. +// The result is a plain decimal integer. Staleness uses neoStaleBlockGap in probeOne. +func callNeoBlockCount(ctx context.Context, url string) (count uint64, result string, latencyMs float64, err error) { + body := []byte(fmt.Sprintf( + `{"jsonrpc":"2.0","method":"getblockcount","params":[],"id":%d}`, + time.Now().UnixNano(), + )) + req, _ := http.NewRequestWithContext(ctx, "POST", url, bytes.NewReader(body)) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("User-Agent", "OpenChainBench/1.0 (+https://openchainbench.com)") + client := &http.Client{Timeout: probeTimeout} + + start := time.Now() + resp, err := client.Do(req) + latencyMs = float64(time.Since(start).Nanoseconds()) / 1e6 + + if err != nil { + if ctx.Err() != nil || strings.Contains(err.Error(), "deadline exceeded") || strings.Contains(err.Error(), "Timeout") { + return 0, "timeout", latencyMs, err + } + return 0, "http_err", latencyMs, err + } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + _, _ = io.Copy(io.Discard, resp.Body) + return 0, "http_err", latencyMs, fmt.Errorf("status %d", resp.StatusCode) + } + + raw, err := io.ReadAll(resp.Body) + if err != nil { + return 0, "http_err", latencyMs, err + } + var r rpcBlockEnvelope + if err := json.Unmarshal(raw, &r); err != nil { + return 0, "http_err", latencyMs, err + } + if r.Error != nil { + return 0, "jsonrpc_err", latencyMs, fmt.Errorf("rpc -%d: %s", r.Error.Code, r.Error.Message) + } + if len(r.Result) == 0 || string(r.Result) == "null" { + return 0, "jsonrpc_err", latencyMs, fmt.Errorf("empty neo result") + } + var n uint64 + if err := json.Unmarshal(r.Result, &n); err != nil { + return 0, "jsonrpc_err", latencyMs, fmt.Errorf("non-numeric neo block count: %s", string(r.Result)[:min(len(r.Result), 40)]) + } + return n, "ok", latencyMs, nil +} diff --git a/public/logos/ckb.png b/public/logos/ckb.png new file mode 100644 index 00000000..625d1b97 Binary files /dev/null and b/public/logos/ckb.png differ diff --git a/public/logos/flow.png b/public/logos/flow.png new file mode 100644 index 00000000..e2ceba24 Binary files /dev/null and b/public/logos/flow.png differ diff --git a/public/logos/flow.svg b/public/logos/flow.svg new file mode 100644 index 00000000..12a0f6be --- /dev/null +++ b/public/logos/flow.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/logos/multiversx.png b/public/logos/multiversx.png new file mode 100644 index 00000000..538a0325 Binary files /dev/null and b/public/logos/multiversx.png differ diff --git a/public/logos/near.jpg b/public/logos/near.jpg new file mode 100644 index 00000000..44cb51c2 Binary files /dev/null and b/public/logos/near.jpg differ diff --git a/public/logos/neo.png b/public/logos/neo.png new file mode 100644 index 00000000..1968da6f Binary files /dev/null and b/public/logos/neo.png differ diff --git a/src/data/provider-registry.ts b/src/data/provider-registry.ts index 2b93f3c6..f42f255d 100644 --- a/src/data/provider-registry.ts +++ b/src/data/provider-registry.ts @@ -2285,6 +2285,85 @@ export const PROVIDER_REGISTRY: Record = { "Uniblock is a multi-chain RPC aggregator providing unified access to TON and other blockchains via a public JSON-RPC endpoint, no API key required.", twitter: "@UniblockDev", }, + // ─── NEAR Protocol providers (bench 216) ───────────────────────── + "near-org": { + url: "https://near.org", + description: + "Official NEAR Foundation public mainnet RPC endpoint (rpc.mainnet.near.org). Provides JSON-RPC access to the NEAR Protocol without an API key.", + twitter: "@NEARProtocol", + }, + fastnear: { + url: "https://fastnear.com", + description: + "FastNEAR is a high-performance NEAR Protocol RPC service offering a free public tier at free.rpc.fastnear.com, no API key required.", + twitter: "@fastnear", + }, + // ─── Flow providers (bench 217) ────────────────────────────────── + onflow: { + url: "https://flow.com", + description: + "Flow Foundation official public REST access node (rest-mainnet.onflow.org). Provides the Cadence REST API for block queries without an API key.", + twitter: "@flow_blockchain", + }, + "flow-access": { + url: "https://flow.com", + description: + "Flow Foundation public access node (access.mainnet.nodes.onflow.org) exposing the Cadence REST API for sealed block queries, no API key required.", + twitter: "@flow_blockchain", + parent: "onflow", + }, + // ─── Hedera providers (bench 218) ──────────────────────────────── + hashio: { + url: "https://swirldslabs.com/hashio", + description: + "Hashio is a free public EVM-compatible JSON-RPC gateway for Hedera Hashgraph, operated by Swirlds Labs. No API key required; supports standard Ethereum JSON-RPC 2.0 methods.", + twitter: "@SwirldsLabs", + }, + // ─── CKB providers (bench 219) ─────────────────────────────────── + "ckb-dev": { + url: "https://nervos.org", + description: + "Nervos Foundation official CKB mainnet public RPC node (mainnet.ckb.dev/rpc). Provides JSON-RPC access to the Nervos CKB Layer 1 without an API key.", + twitter: "@NervosNetwork", + }, + ckbapp: { + url: "https://ckbapp.dev", + description: + "CKBapp community-operated Nervos CKB mainnet public RPC node (mainnet.ckbapp.dev/rpc). Provides JSON-RPC access without an API key.", + }, + // ─── MultiversX providers (bench 220) ──────────────────────────── + "mvx-gateway": { + url: "https://multiversx.com", + description: + "MultiversX Foundation official gateway node (gateway.multiversx.com). Provides public REST API access to MultiversX blockchain data including metachain network status, no API key required.", + twitter: "@MultiversX", + }, + "mvx-api": { + url: "https://api.multiversx.com", + description: + "MultiversX Foundation official API service (api.multiversx.com). Exposes REST endpoints including network status for indexer and gateway queries without an API key.", + twitter: "@MultiversX", + parent: "mvx-gateway", + }, + // ─── NEO N3 providers (bench 221) ──────────────────────────────── + nspcc: { + url: "https://nspcc.ru", + description: + "NSPCC (Russian National Crypto Standard Committee) operates a public NEO N3 mainnet RPC node at rpc10.n3.nspcc.ru:10331. No API key required.", + }, + ngd: { + url: "https://neo.org", + description: + "Neo Global Development (NGD) operates public NEO N3 mainnet seed nodes (n3seed1.ngd.network:10332). No API key required.", + twitter: "@Neo_Blockchain", + }, + ngd2: { + url: "https://neo.org", + description: + "Neo Global Development (NGD) seed node 2 (n3seed2.ngd.network:10332) for NEO N3 mainnet. No API key required.", + twitter: "@Neo_Blockchain", + parent: "ngd", + }, }; /** diff --git a/src/lib/brand.ts b/src/lib/brand.ts index 58aa3de4..c6bd867e 100644 --- a/src/lib/brand.ts +++ b/src/lib/brand.ts @@ -107,6 +107,28 @@ const BRANDS: Record = { uniblock: { color: "#1FB6FF" }, // uniblock cyan nodely: { color: "#F9B72B" }, // nodely amber + // ─── Non-EVM L1s wave 2 (benches 216-221) ─── + near: { color: "#00C27E" }, // near green (official brand) + flow: { color: "#00EF8B" }, // flow green (primary brand) + hedera: { color: "#222222", dark: true }, // hedera dark (official brand) + ckb: { color: "#3CC68A" }, // nervos ckb teal + multiversx: { color: "#23F7DD" }, // multiversx teal/cyan + neo: { color: "#00AF92" }, // neo teal (brand kit) + + // ─── New providers (benches 216-221) ─── + fastnear: { color: "#00C27E" }, // fastnear inherits near green + hashio: { color: "#222222", dark: true }, // hashio inherits hedera dark + "ckb-dev": { color: "#3CC68A" }, // nervos foundation teal + ckbapp: { color: "#3CC68A" }, // ckbapp teal + "mvx-gateway": { color: "#23F7DD" }, // multiversx teal + "mvx-api": { color: "#23F7DD" }, // multiversx teal + nspcc: { color: "#1565C0", dark: true }, // nspcc deep blue + ngd: { color: "#00AF92" }, // ngd inherits neo teal + ngd2: { color: "#00AF92" }, // ngd2 inherits neo teal + onflow: { color: "#00EF8B" }, // onflow inherits flow green + "flow-access": { color: "#00EF8B" }, // flow access inherits flow green + "near-org": { color: "#00C27E" }, // near foundation inherits near green + // ─── Stellar ecosystem providers (bench № 210) ─── gateway: { color: "#00C2A8" }, // gateway.fm teal sorobanrpc: { color: "#7B4FBF" }, // sorobanrpc violet diff --git a/src/lib/chains.ts b/src/lib/chains.ts index 2b8891c4..bbf119d3 100644 --- a/src/lib/chains.ts +++ b/src/lib/chains.ts @@ -1123,6 +1123,60 @@ export const CHAINS: ChainEntry[] = [ description: "Polkadot parachain purpose-built for DePIN (Decentralised Physical Infrastructure Networks) with machine identity, machine staking, and role-based access control primitives for IoT and mobility networks.", }, + { + slug: "near", + label: "NEAR Protocol", + category: "L1", + nativeSymbol: "NEAR", + website: "https://near.org", + description: + "Sharded proof-of-stake L1 using Nightshade sharding and Doomslug consensus, targeting roughly one block per second with near-instant practical finality and human-readable account names.", + }, + { + slug: "flow", + label: "Flow", + category: "L1", + nativeSymbol: "FLOW", + website: "https://flow.com", + description: + "Proof-of-stake L1 developed by Dapper Labs using a multi-role node architecture (Collector, Consensus, Execution, Verification) and the Cadence resource-oriented smart contract language.", + }, + { + slug: "hedera", + label: "Hedera", + category: "L1", + nativeSymbol: "HBAR", + website: "https://hedera.com", + description: + "Enterprise-grade public distributed ledger governed by the Hedera Governing Council using the Hashgraph consensus algorithm, targeting high throughput with deterministic finality under 3 seconds.", + }, + { + slug: "ckb", + label: "Nervos CKB", + category: "L1", + nativeSymbol: "CKB", + website: "https://nervos.org", + description: + "Layer 1 proof-of-work blockchain using NC-MAX consensus (a selfish-mining-resistant Nakamoto variant) with a cell model for state storage and the RISC-V based CKB-VM for smart contract execution.", + }, + { + slug: "multiversx", + label: "MultiversX", + category: "L1", + nativeSymbol: "EGLD", + website: "https://multiversx.com", + description: + "Adaptive state-sharded proof-of-stake L1 using Secure Proof of Stake (SPoS) with a metachain coordinating shard consensus, targeting up to 15,000 TPS per shard with immediate deterministic finality.", + }, + { + slug: "neo", + label: "NEO N3", + category: "L1", + nativeSymbol: "NEO", + website: "https://neo.org", + description: + "Delegated Byzantine Fault Tolerant (dBFT) proof-of-stake L1 blockchain with one-block finality, a dual-token model (NEO for governance and GAS for fees), and the NeoVM supporting multiple smart contract languages.", + }, ]; export const CHAIN_BY_SLUG = new Map(CHAINS.map((c) => [c.slug, c])); diff --git a/src/lib/logo-manifest.ts b/src/lib/logo-manifest.ts index dbdad5ad..5039533c 100644 --- a/src/lib/logo-manifest.ts +++ b/src/lib/logo-manifest.ts @@ -183,6 +183,32 @@ const RAW: Record = { nownodes: "/logos/nownodes.svg", tatum: "/logos/tatum.svg", uniblock: "/logos/uniblock.svg", + // ─── Wave-2 non-EVM chains (benches 216-221) ─── + near: "/logos/near.jpg", + flow: "/logos/flow.png", + ckb: "/logos/ckb.png", + multiversx: "/logos/multiversx.png", + neo: "/logos/neo.png", + // ─── NEAR providers (bench 216) ─── + "near-org": "/logos/near.jpg", + fastnear: "/logos/near.jpg", + // lava already registered; drpc already registered + // ─── Flow providers (bench 217) ─── + onflow: "/logos/flow.png", + "flow-access": "/logos/flow.png", + // ─── Hedera providers (bench 218) ─── + hashio: "/logos/hedera.svg", + // thirdweb already registered + // ─── CKB providers (bench 219) ─── + "ckb-dev": "/logos/ckb.png", + ckbapp: "/logos/ckb.png", + // ─── MultiversX providers (bench 220) ─── + "mvx-gateway": "/logos/multiversx.png", + "mvx-api": "/logos/multiversx.png", + // ─── NEO providers (bench 221) ─── + nspcc: "/logos/neo.png", + ngd: "/logos/neo.png", + ngd2: "/logos/neo.png", infura: "/logos/infura.png", ankr: "/logos/ankr.png", chainstack: "/logos/chainstack.svg",