To verify an xOne release artifact, download the asset and SHA256SUMS from the same release page and run sha256sum -c. Then read the version stamp and compare its commit with the tag. The release page has no signature file today, so these checks find a damaged or wrong file. They do not prove who built it.
The release process post explains the stamp format and how a release is cut. The xOneRS run guide shows the first download steps. xOneTS, xOnePy and xOneC are private repositories. Their links need access.
How do I check the downloaded file against SHA256SUMS?
Download the asset and SHA256SUMS from the same release, then run sha256sum -c. A line that says OK means the file equals the one that was listed.
V=https://github.com/XDCIndia/xOneRS/releases/download/v0.1.0
curl -fLO $V/xone-v0.1.0-linux-amd64
curl -fLO $V/SHA256SUMS
sha256sum -c SHA256SUMS
The v0.1.0 SHA256SUMS of xOneRS has one line, for xone-v0.1.0-linux-amd64. The xOnePy release lists a wheel and a source archive for each package, so you may download only some of them. The GNU option --ignore-missing skips the files that you did not download.
How do I check the version stamp against the tag?
The commit in the stamp must equal the first 8 characters of the commit that the tag points to. Print the stamp, then ask git for the tag commit.
./xone-v0.1.0-linux-amd64 --version
git clone https://github.com/XDCIndia/xOneRS.git && cd xOneRS
git rev-parse 'v0.1.0^{commit}' | cut -c1-8
For the xOneRS v0.1.0 binary, the stamp says xOne/v0.1.0-9465ddb4-12112026/linux-x86_64/rustc1.94.0. The tag commit starts with 9465ddb4. The ^{commit} suffix matters: the xOneRS v0.1.0 tag is an annotated tag, and git rev-parse v0.1.0 alone prints the tag object, which starts with 7612a711.
To read the stamp without running the file, use strings. The qualification script does the same for a foreign architecture:
strings -a xone-v0.1.0-linux-amd64 | grep -m1 '^xOne'
The stamp must not contain unknown or -dirty. The older v0.1.0 page still shows the name xOne/. Code on main builds xOneRS/.
The date field is the part that differs between clients:
| Client | Date in the stamp | How to check it | -dirty marker |
|---|---|---|---|
| xOneRS | Commit date, in UTC | TZ=UTC git log -1 --format=%cd --date=format-local:%d%m%Y 'v0.1.0^{commit}' prints 12112026 for v0.1.0 |
Yes |
| xOneTS | UTC build date | The date is not a function of the tag. Compare it with the release date as a plausibility check. | Yes |
| xOnePy | UTC build date, written into the wheel by tools/build.py |
Install the wheel in a fresh venv, run xonepy --version, and compare as for xOneTS. |
Yes |
| xOneC | Commit date | git log -1 --date=format:%d%m%Y --format=%cd 'v0.1.0^{commit}' |
No |
Sources for the table: bin/xone/build.rs and ci/release.sh in xOneRS, and docs/process/release.md in the other three. xOneC reads the stamp at configure time. For xOneC, the rulebook says to make a fresh configure of a clean checkout of the tag, because the stamp cannot show a dirty tree.
A stamp that shows 00000000 for the commit and date is a failed build in xOneTS, xOnePy and xOneC.
What does ci/qualify-artifact.sh check?
It checks the packaged bytes of a release tarball, not the source. The script has two modes. qualify tests a tarball and records its digest in a ledger file. publish refuses any file whose digest is not in the ledger.
ci/qualify-artifact.sh qualify <ledger> <tarball>...
ci/qualify-artifact.sh publish <ledger> <file>...
For each tarball, qualify does these steps:
- It computes the SHA-256 of the tarball. If a
<tarball>.sha256file exists, the two must match. - It unpacks the tarball and requires an executable
xoneinside the folder of the tarball name. - It requires an ELF file for the architecture in the name,
x86_64oraarch64. - It runs
xone versionwhen the architecture equals the host. For the other architecture, it reads the stamp from the binary withstrings. The stamp must start withxOneRS/v. - It appends
<sha256> <file> <stamp>to the ledger.
The tarball name must be xone-<version>-linux-<arch>-musl.tar.gz. A rebuild between qualify and publish gives a new digest, so publish fails. The script does not compare the stamp with the tag. ci/release.sh does that. The script header lists what is not done yet (issue #62): the signing, recovery and precompile corpus per backend, failure injection, and the container digest.
ci/test-qualify.sh holds five failing-fixture cases: a good tarball is recorded, a binary without a stamp is refused with nothing recorded, a tarball that differs from its .sha256 is refused, a qualified digest is publishable, and a rebuilt file is refused. The CI check job runs it.
How do I check that a running node matches the release?
Use ops/tools/xone-release-check.py version. It compares the hash of the running executable, the hash of the installed binary, and web3_clientVersion.
ops/tools/xone-release-check.py version <unit> <installed-binary> <expected-version> --rpc <rpc-url>
Each check prints ok, STALE or incomplete. The command exits with 1 when any check is STALE. STALE means the process runs an older or replaced binary, or the RPC string does not contain the expected text. The RPC address defaults to http://127.0.0.1:8545. The images mode only prints a plan of unused xone Docker images. For upgrades, see the upgrade and rollback guide.
What does the release page lack today?
It has no signature file, and the assets differ from what the docs describe. The checks above can find a damaged download. They cannot show who built the file.
- No signature.
docs/ops/release.mddocuments a detachedSHA256SUMS.sig. The release key is an open owner decision: where the key lives, who may use it, rotation, and the key id to publish. - Fewer files. The release docs list a tarball per architecture, an SBOM, a provenance file,
SHA256SUMSand the signature. The v0.1.0 page of xOneRS has the binary andSHA256SUMS. The xOneTS and xOneC pages have a binary andSHA256SUMS. The xOnePy pages have wheels, source archives andSHA256SUMS. - Not a static build.
filereports the xOneRS v0.1.0 asset as a dynamically linked executable.ci/release.shon main refuses a binary that is not static. - No signature in the other clients' rules. The xOneTS, xOnePy and xOneC rulebooks write
SHA256SUMSand do not mention a signature.
On main, ops/xone-install.sh install checks a signature, the checksum and the stamp before it installs. It needs the signature files that the v0.1.0 page does not have. See releases for the list of tags.
Frequently asked questions
Does sha256sum -c prove that the file is genuine?
No. It shows that the file equals the line in SHA256SUMS. Both files come from the same release page, so the check finds a damaged download. The release page has no signature today.
Why does git rev-parse give another hash than the stamp?
The tag may be an annotated tag. For xOneRS v0.1.0, git rev-parse v0.1.0 prints the tag object. Use git rev-parse 'v0.1.0^{commit}' and compare its first 8 characters with the stamp.
Which date must the stamp show?
It depends on the client. xOneRS and xOneC use the commit date. xOneTS and xOnePy use the UTC build date. The format is DDMMYYYY.
Can I run ci/qualify-artifact.sh on the v0.1.0 download?
No. The script expects a tarball named xone-<version>-linux-<arch>-musl.tar.gz. The v0.1.0 page has a bare binary.
Sources
- xOneRS: ci/qualify-artifact.sh, ci/test-qualify.sh, ops/tools/xone-release-check.py, docs/ops/release.md, ci/release.sh, bin/xone/build.rs, ops/install.md, ops/xone-install.sh, docs/assurance/README.md
- xOneTS (private): docs/process/release.md
- xOnePy (private): docs/process/release.md
- xOneC (private): docs/process/release.md
- Release pages: xOneRS v0.1.0, xOneTS, xOnePy, xOneC
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/verify-release-artifact/index.md). GitHub may ask you to sign in. Report a correction opens a prefilled GitHub issue for this page.