xOnePy is the Python client of the xOne family for the XDC Network. You install it with uv or from the v0.1.1 wheels, start it with xonepy, and check it with its version stamp, the board and a reference node. The xOnePy repository is private, so its links need access.
What is xOnePy?
xOnePy is an XDC execution client written in Python. It is one of four clients in the xOne rebuild, next to Rust, TypeScript and C++ (overview). This guide follows the CHANGELOG, docs/ops and the code on main.
- It is a typed uv workspace. The first release, v0.1.0, has 14 packages and a tool.
- It runs on CPython 3.13 with the GIL. Python 3.12 or newer is supported (CHANGELOG).
How do I install it?
Use uv and Python 3.12 or newer, or install the release wheels. Keep the virtual environment outside the checkout.
git clone https://github.com/XDCIndia/xOnePy.git
cd xOnePy
uv sync --frozen
uv run --frozen --no-sync xonepy --version
The v0.1.1 release holds one wheel and one source archive per package, and a SHA256SUMS file. Install the wheels in a fresh venv, then run xonepy --version. v0.1.1 fixed one defect: the wheels now carry the fork table and genesis files, so an installed wheel starts a node (#79, #80).
How do I follow net2040?
Start a read-only follower with the documented command. The owner of the node picks its name and its ports.
uv sync --frozen
uv run --frozen --no-sync xonepy --network net2040 --datadir <datadir> \
--port <p2p port> --http --http.addr 127.0.0.1 --http.port <rpc port> \
--http.api eth,net,web3,XDPoS --ws --ws.addr 127.0.0.1 --ws.port <ws port> \
--metrics --metrics.addr 127.0.0.1 --metrics.port <metrics port> \
--ethstats '<name>:<secret>@<board host>:<port>'
- Give the ethstats secret on the command line only. The node writes it nowhere. Log lines show
<redacted>. - net2040 has no built-in peer list. Add
--bootnodes <enode-url>. - Stop the node with
kill -TERM <pid>on its exact pid.
Source: net2040-py-node.md.
Which sync modes does it run?
xOnePy runs full, snap (alias fast), minimal and archive modes. --syncmode accepts full, snap and fast; --gcmode accepts full and archive. The sync modes post compares the four clients.
| Mode | Flag | Time to tip, net2040, 2026-11-12 | Datadir at tip | Peak RSS |
|---|---|---|---|---|
| snap | --syncmode snap on an empty datadir |
34.1 s | 20.7 MB | 103.7 MB |
| minimal | --minimal after snapshot import |
19.3 s | 14.4 MB | 95.7 MB |
- Snap: the node downloaded pivot 795514 with 9,532 accounts and 10,998 slots. It made 0 heal requests (sync modes record).
- Minimal: export on a snap node, then import on a new datadir, then start with
--minimal. Import needs a pins file.
xonepy snapshot export --network net2040 --datadir <datadir> --out <file>.xsnap
xonepy snapshot import --network net2040 --datadir <new datadir> --in <file>.xsnap --pins <pins file>
- Archive:
--gcmode archivekeeps the state of every block. It starts from an empty datadir only. It refuses--minimaland snap sync. The run at the tip is still listed as not covered. - Full: on 2026-11-12 the Python full node was about 778,000 blocks behind the tip. It cannot reach the tip while it executes the net2040 load-test blocks. Join net2040 with snap or minimal mode (CHANGELOG).
- Snap peers: v0.1.1 needs a peer that serves snap/1 and xpre/1, and only xOne nodes do. Unreleased code on
mainkeys the state by hash, so any snap/1 peer works.
How do I verify a node?
Check four things: the version stamp, the board, the head against a reference node, and the replay records. Each check has a documented source.
Version stamp.
xonepy --versionprintsxOnePy/v<semver>-<commit8>[-dirty]-<DDMMYYYY>/<os>-<arch>/cpython<ver>. A release wheel with00000000or-dirtyis a failed build. The RPC callweb3_clientVersionreturns the same value:curl -s -H 'Content-Type: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"web3_clientVersion"}' http://127.0.0.1:<rpc port>Board. The
clientVersionof the node on the net2040 board must equalxonepy --version. The board also shows the genesis hash andactive: true.Health.
/livezon the metrics port givesok./readyzgives 503 until the node has a head younger than 60 s.Head against a reference. Compare whole
eth_getBlockByNumberobjects, with and without transactions, andXDPoS_getMasternodesByNumber, against a read-only reference node. The sync record compares the pivot, the first executed block and head minus 10.
What do the replay records show?
docs/ops/RUNS.md lists own-state replays by python -m xonepy_replay run. The replay starts at genesis on its own state. It compares gasUsed, receiptsRoot, logsBloom, transactionsRoot and stateRoot for each block.
| Date | Network | Blocks | Transactions | V2 switches | Result | Commit |
|---|---|---|---|---|---|---|
| 2026-11-12 | net2040 | 1..21600 | 4,205,493 | 13 | 0 mismatches | d9be98e |
| 2026-11-13 | net2040 | 21601..60000 | 18,427,339 | 42 | 0 mismatches | 6e6e5d3 |
| 2026-11-12 | Apothem | 1801..432000 | 118,577 | 0 | 0 mismatches | 48c5d52 |
See the conformance replay gate for the method, and the release process for the stamp rules.
How fast is it?
Plain transfers run inside the budgets. Contract transactions do not. py-performance.md gives ranges, measured on a shared host at 1.3 to 1.6 load per core.
- Block 21,970 (5,032 transfers): 0.212-0.238 ms per transaction on the full path and 0.174-0.184 ms on the fast path. The budgets are 0.4 and 0.2.
- Recovery of 5,032 senders: 60-125 ms. The budget is 250 ms.
- Contract transactions: 61-63 ms each, about 12 Mgas/s. The follow budget is 2 ms.
What are the known gaps?
The CHANGELOG lists these gaps for v0.1.1.
- Contract-heavy blocks exceed the follow budget. Measure a contract-heavy Apothem block before any Apothem or mainnet follow claim.
- Not measured at the tip: restart to lag 0, memory growth over a 6 h follow, peers and ethstats during heavy blocks.
- Snap has no resume of an interrupted download or import. V1 pivots are refused. Apothem by snap was not run.
- The signer fence covers the quiet window only. Run one key on one host.
Frequently asked questions
Is the xOnePy repository public?
No. The repository is private, so you need access to clone it.
Which command prints the xOnePy version?
xonepy --version. The same stamp appears in web3_clientVersion, the P2P hello and the board clientVersion.
Can xOnePy reach the net2040 tip?
In snap mode, yes: the 2026-11-12 run reached the tip in 34.1 s. In full mode, no: the node was about 778,000 blocks behind on that date.
Which sync mode should I choose?
To join net2040, use snap on an empty datadir or minimal after a snapshot import. Archive mode needs a new datadir and a sync from genesis.
Sources
This article describes the source and evidence at its review date. Check the linked repository for current implementation and qualification status.
Explore the engineering evidenceEdit this page on GitHub opens the Markdown source (content/blog/run-xonepy/index.md). GitHub may ask you to sign in. Report a correction opens a prefilled GitHub issue for this page.