To join net2040 with xOne, start xone --network net2040 with an empty datadir and the enode URL of one net2040 peer. The node syncs from genesis, recomputes every block, and serves JSON-RPC. This post follows the net2040 guide in xOneRS. It uses the Rust client. The xOneTS, xOnePy and xOneC repositories are private, so their links need access.

What is net2040?

net2040 is the public end-to-end devnet, with chain id 2040. Every fork is live within its first 21,600 blocks (chain spec). --network net2040 selects it (flags). The support matrix marks follow, sync modes, archive and RPC as working on net2040. Signing needs the owner's approval.

How do I get the binary?

Build xone from source or download the v0.1.0 release and check its SHA256SUMS. How to run and verify xOneRS has the commands and the version-stamp check. This post does not repeat them.

How do I find peers?

The repository commits no public net2040 bootnode list. The net2040 guide passes the enode URL of one peer with --bootnodes. That peer is a geth-XDC archive node. Use the enode URL of a net2040 peer you trust, in this form:

enode://<node-id>@<peer-host>:<peer-port>

--bootnodes takes a comma-separated list. On main, xone p2p check <enode-url> tells you why a peer works or not (troubleshooting). The node also keeps a table of peers that completed a handshake in <datadir>/peers.json, and dials them again at the next start (flags).

How do I start the node?

xone --network net2040 --datadir <datadir> \
     --bootnodes <enode-url> --port 30303 \
     --http --http.port 8545 --http.api eth,net,web3,XDPoS \
     --metrics --metrics.addr 127.0.0.1 --metrics.port 6060

The HTTP RPC listens on localhost by default. Allow outbound TCP and UDP on port 30303 (troubleshooting). The recorded node ran this command under a loop that starts it again 5 seconds after any exit.

How do I check that the node is in sync and correct?

Compare the head of your node with a reference node of the same network. In the guide, the reference is a geth-XDC archive node.

rpc() { curl -s -H 'content-type: application/json' \
  --data '{"jsonrpc":"2.0","id":1,"method":"'$2'","params":'$3'}' "$1"; }
rpc http://127.0.0.1:8545 eth_blockNumber '[]'
rpc <reference-rpc-url>   eth_blockNumber '[]'

The guide's run on 2026-11-12 printed local 759746 archive 759746 lag 0. It also compared eth_getBlockByNumber with [h, false] and XDPoS_getMasternodesByNumber between the two nodes, as whole JSON. Block 18,000 had hash 0x68e72f4b8a1b61aab2872966088a8383917721da51e27b3fc009fc56d5caf907 on both. The run guide has a diff script for this check.

More checks:

  • curl -i http://127.0.0.1:6060/readyz answers ready when the node is at a current head and not syncing. /livez and /metrics are on the same port.
  • On main, xone sync-status --count 3 --interval 10 shows a rising head or caught up. xone wait-ready --timeout 600 exits 0 when the RPC is up and not syncing. The v0.1.0 binary has neither command.
  • A block that differs from its header is refused, and the peer is set aside. Search the log for refused.

A full sync from genesis reached block 762,846 in about 95 minutes on the MDBX store. The datadir was 17 GB and peak memory was 7.07 GB.

How do I stop and resume?

Send SIGTERM. The node writes a state checkpoint and stops. The next start opens at the head it stopped at. In the recorded run, the node stopped in 4 seconds and wrote the checkpoint of block 762,849. It followed from that head after 120 seconds and imported the 38 blocks made in between. Use the same --datadir. A datadir that holds a chain is continued, never replaced.

How do I replace the binary?

Copy the new build next to the old one, move it over, and stop the process. The loop starts the new binary, which opens at the head:

cp <new-build> <bindir>/xone.new
mv <bindir>/xone.new <bindir>/xone
pkill -TERM -f '^<bindir>/xone '

A service manager can do the restart that the loop did. A newer datadir format under an older binary is refused. Upgrade and rollback has the rule and the backup step.

Which sync mode should I pick?

Pick full (the default) if you want every block executed on your own state. Pick snap for a start in seconds, and accept that history below a window is gone. Pick minimal if you have a snapshot file and a pin you trust. How sync works in xOne compares the modes. How to bootstrap from a snapshot covers export, pins and import.

REFERENCE TABLEScroll to explore all columns →
Mode Flag Measured on net2040 (2026-11-12 unless noted)
full --syncmode full About 95 minutes, 17 GB (run of 2026-11-11)
snap --syncmode snap 10 s to the tip, 72 MB datadir, 2 MB over snap/1 and xpre/1
fast --syncmode fast Alias of snap, as in geth-XDC: 12 s
minimal --minimal after xone snapshot import 7 s, snapshot of 4,956,408 bytes

Source: net2040 sync modes. Snap needs an empty datadir. Set --snap.pins <file> beyond test networks. Without it, two peers must serve the same switch header. If your only peers run geth-XDC, pass --snap.gap-rpc with an archive RPC that serves eth_getProof. Without that flag and without an xOne peer, the start fails with a typed error (flags).

REFERENCE TABLEScroll to explore all columns →
Client Default sync mode, as stated in its docs
geth snap is the default (sync modes, edited 2025-02-18)
Besu --sync-mode=SNAP for named networks (node sync)
ethrex --syncmode full|snap, default snap (sync modes)
xOneRS full

Which xOne clients run on net2040 today?

All four. The latest tracker comment on xOneRS#140 is from 2026-11-14 19:30 UTC, with the tip at block 841513. Lag is the blocks behind the reference archive node. The tracker prints a negative lag for a node that reported a higher head.

REFERENCE TABLEScroll to explore all columns →
Client full snap fast minimal archive
xOneRS lag 0 lag 0 lag 0 lag 0 lag 0
xOneTS lag 0 two nodes, both down -3 and -6 -3 and -6 syncing from genesis (head 185183)
xOnePy -6 -6 not built -6 -8
xOneC -8 -8 not built -8 -8

xOneTS also runs a validator on its own seat (lag -7). The xOneRS full node holds seat 0xa0ea since 2026-11-12 with 0 misses. The xOnePy snap node holds seat 0xc33a with 368 seals and 1 miss. The xOneC snap node holds seat 0x00ce with 962 seals and 0 misses. The tracker's xOneRS archive row says "state retained from block 825238 only". That text predates PR #416, which added --gcmode archive state for every block (README). For validator steps, see the validator guide.

Frequently asked questions

Is there an official net2040 bootnode list?

No list is committed in the xOneRS repository. The net2040 guide passes the enode URL of one geth-XDC archive peer with --bootnodes.

How long does a net2040 sync take?

A full sync reached block 762,846 in about 95 minutes in the recorded run. A snap node reached the tip in 10 seconds on 2026-11-12 and used a 72 MB datadir.

Does restarting lose progress?

No. SIGTERM writes a state checkpoint. The next start opens at the head the node stopped at.

Can I use --syncmode snap with a geth-XDC peer only?

The flags page describes it: set --snap.gap-rpc to an archive RPC that serves eth_getProof. Every proof is checked against the header, so the RPC is not trusted.

Sources