Issue #1015 asked whether xOneRS reports a new net2040 head later than geth-XDC on the same host; an earlier five-minute sample put xOneRS 0.28 to 0.58 s behind (block arrival). On 2026-11-15 we ran a new read-only sample on host B, where an xOneRS follower and the geth-XDC reference run side by side. Result: over 109 blocks in 10 minutes, xOneRS was later at the median by 0.071 s, inside the 0.1 s resolution, but its 90th percentile was 2.458 s and its worst block 8.4 s. The host was heavily loaded during the run, so the tail mixes the client with the host. On the way we found that the script that closed #1015 cannot show a leading peer (issue #1224), and that xOneRS sometimes answers null for the latest block (issue #1229).

How was it measured?

  • Two threads on the host, one per client, each calling eth_blockNumber on the local RPC every 0.1 s for 600 s, and keeping the time each block number was first seen. The resolution is 0.1 s.
  • Both clients use the same host clock, so clock offset cancels. The host clock was NTP-synchronised.
  • The xOneRS node runs build 8fe27572 of 2026-11-12, an older build than main.
  • Failed polls: none on either client. We discarded a first try at 0.05 s: it did not count failed polls, and the same node answered HTTP 429 to calls at a higher rate, so gaps could have inflated the lag.
  • Host load average (1 minute) after the run: 96.0 (it rose during the run; host B also runs other work).

What did the sample show?

REFERENCE TABLEScroll to explore all columns →
Value
Blocks seen by both 109
xOneRS later than geth-XDC, median 0.071 s
90th percentile 2.458 s
Largest gap (xOneRS later) 8.425 s
Largest lead (xOneRS earlier) -0.062 s
Blocks where xOneRS was later / earlier 90 / 19

With a 0.1 s poll, a difference under 0.1 s is within the measurement's resolution. This is one 10-minute sample on one host and one older build, not a benchmark.

Why can't measure-head-lag.sh answer this?

ops/bench/measure-head-lag.sh (PR #1128) polls xOneRS first and reads geth-XDC only after xOneRS shows a new block. If geth-XDC already had the block, the script's difference is just the time of that one read, a few milliseconds, and never negative. Our run of it gave 15 rows, all between 0.001 and 0.005 s, which says nothing about who was first. Issue #1224 asks it to poll both clients independently and report signed differences, as the sample above does.

What stopped the script?

After 15 rows it ended with a Python error: xOneRS had answered eth_getBlockByNumber("latest") with null. We then called it once every 0.1 s for 150 s: 1,476 answers had a block, 3 were null. "latest" should always name a block. Issue #1229 asks the node to resolve and read the head from one consistent view, as it already does for log queries (PR #1086). We did not test a main build.

Frequently asked questions

Is xOneRS slower than geth-XDC to show a new block?

In this sample, by 0.071 s at the median on one host and one older build. The receive and phase log lines of a main build can show where the time goes (log fields).

Why not use measure-head-lag.sh?

It reads the second client only after the first flips, so it cannot show the second client leading. Issue #1224 tracks the fix.

Can eth_getBlockByNumber("latest") return null on xOne?

On the build we tested, rarely: 3 of 1,479 calls. Issue #1229 tracks it.

Sources

  • Read-only sample on host B, 2026-11-15: eth_blockNumber every 0.1 s for 600 s on xOneRS and geth-XDC; eth_getBlockByNumber("latest") every 0.1 s for 150 s on xOneRS.
  • ops/bench/measure-head-lag.sh; issues #1015, #1224, #1229