Skip to content

Cover linux/arm64 in the prebuilt seid install and upgrade steps - #64

Draft
monty-sei wants to merge 1 commit into
mainfrom
monty/arm64-prebuilt-binary-docs
Draft

Cover linux/arm64 in the prebuilt seid install and upgrade steps#64
monty-sei wants to merge 1 commit into
mainfrom
monty/arm64-prebuilt-binary-docs

Conversation

@monty-sei

Copy link
Copy Markdown
Collaborator

Draft on purpose. Do not merge until arm64 binaries are actually attached to a sei-chain release. These pages were reverted once before (#44) for documenting prebuilt binaries ahead of their existence, and #55 only restored them after v6.6.1 shipped. Same rule applies here.

What this changes

Three files, eight lines. The prebuilt binary tabs hardcode sei-chain_${VERSION#v}_linux_x86_64.tar.gz and state the builds are linux/amd64 only.

File Hunks
evm/installing-seid-cli.mdx intro sentence, download snippet, <Info> caveat
node/index.mdx intro sentence, download snippet, <Info> caveat
node/node-operators.mdx the Minor Updates and Major Updates snippets

The two in node-operators.mdx are the easy ones to miss. Without them an arm64 operator can install from the guide and then be unable to upgrade, because both update procedures would hand them an amd64 tarball.

The detail worth reviewing

The asset token is arm64, but uname -m on Linux reports aarch64. So substituting $(uname -m) directly appears to work (it is correct on amd64 by coincidence) and then 404s on every arm64 machine. The snippet maps explicitly instead:

case "$(uname -m)" in
  x86_64)        ARCH=x86_64 ;;
  aarch64|arm64) ARCH=arm64  ;;
  *) echo "unsupported architecture: $(uname -m)" >&2; exit 1 ;;
esac
FILE=sei-chain_${VERSION#v}_linux_${ARCH}.tar.gz

An unrecognised architecture stops rather than building a filename that cannot exist. Verified the mapping produces ..._linux_x86_64.tar.gz on x86_64 and ..._linux_arm64.tar.gz on both aarch64 and arm64.

Before this can merge

  • arm64 binaries are attached to a published sei-chain release
  • replace the <arm64-release-tag> placeholder in evm/installing-seid-cli.mdx and node/index.mdx with the first release that carries them
  • confirm the asset name matches what goreleaser actually produced (this assumes sei-chain_<version>_linux_arm64.tar.gz)
  • confirm the arm64 tarball is covered by checksums.txt, since sha256sum -c --ignore-missing exits 0 and prints nothing for a file that is present but unlisted

Out of scope

node/seictl.mdx also names x86_64 archives, but that is the seictl binary and a separate release pipeline. node/index.mdx line 195 ("Available architectures: linux/amd64 and linux/arm64") describes the Docker images and stays accurate. llms.txt and llms-full.txt are generated from the deployed site, so they should be regenerated after this deploys rather than hand-edited.

The prebuilt binary tabs hardcode the amd64 tarball name and state that the
builds are amd64 only. Once arm64 binaries are attached, an operator on Graviton
or Ampere following these pages downloads a 404 or, worse, installs an amd64
binary that will not run.

Derive the asset architecture from uname -m rather than substituting it directly.
The asset token is arm64 while uname -m reports aarch64 on Linux, so a naive
substitution works on amd64 by coincidence and fails everywhere else. An
unrecognised architecture now stops the pipeline instead of building a filename
that does not exist.

Both update procedures in node-operators.mdx get the same treatment. They were
easy to miss and leaving them would let arm64 operators install and then be
unable to upgrade.
@mintlify

mintlify Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
sei-docs 🟢 Ready View Preview Aug 17, 2026, 9:57 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

revofusion pushed a commit to revofusion/sei-chain that referenced this pull request Sep 13, 2026
Releases carry `linux/amd64` only. sei-protocol#3932 arch-split the musl link path,
which made an arm64 static build possible; this wires it through the
build script, the CI gate and goreleaser so the archive actually ships.

## Verified end to end

`goreleaser release --snapshot` on this branch:

```
• archiving  name=dist/sei-chain_..._linux_arm64.tar.gz
• archiving  name=dist/sei-chain_..._linux_x86_64.tar.gz

sei-chain_..._linux_arm64.tar.gz:  OK   -> ELF 64-bit LSB executable, ARM aarch64
sei-chain_..._linux_x86_64.tar.gz: OK   -> ELF 64-bit LSB executable, x86-64
```

Both archives are listed in `checksums.txt`, `sha256sum -c
--ignore-missing` reports OK for both, and each archive contains a
binary of the matching architecture. That last check matters because
`--ignore-missing` exits 0 silently for a file that is present but
unlisted, so an out of band upload would give operators a verification
step that verifies nothing.

## The toolchain pin is needed on both architectures

The gcc>=12 unwind b-tree that crashed the amd64 binary at the genesis
wasm store is not amd64 specific. `ATOMIC_FDE_FAST_PATH` is gated on
atomics support rather than a target allowlist, and an unpinned arm64
build SIGSEGVs on the **first** boot under `RAYON_NUM_THREADS=1`,
reproduced on native arm64 hardware. So the Alpine 3.15 gcc 10.3.1
libgcc is now vendored for both, each in its own subdirectory, with
provenance and checksums in the README.

With the pin applied, the arm64 binary carries zero b-tree symbols and
boots 8/8 clean at 4 CPUs.

## Build script

`build-static.sh` takes a target architecture and writes
`build/seid-<arch>`, so the two builds do not overwrite each other on
one runner. The libgcc directory and the checksums it verifies are both
derived from that one argument, so a build cannot verify one
architecture's archives while linking another's. It also asserts the ELF
machine of the output matches what was requested.

Two guards that were failing open are now closed:

- The `nm` b-tree assertion materialises the symbol table before
grepping. Reading `nm` through a pipe reported **grep's** exit status,
so a failing `nm` printed "pre-b-tree unwinder confirmed" and passed.
- `boot-smoke.sh` refuses a binary built for another architecture. It
previously reached `seid init`, died with an exec-format error, and
reported "did not reach the ABCI handshake", which reads as a crashing
binary rather than the wrong file being passed in.

## Where the arm64 binary gets booted

The release runner is amd64 and cannot execute the arm64 binary, so the
goreleaser hook boots only the amd64 one. The arm64 8-boot gauntlet runs
in the new `Linux ARM64 (static)` job on native `ubuntu-24.04-arm`
hardware.

The link between them is reproducibility: the static build produces a
byte-identical binary for a given commit (measured, identical `sha256`
across independent runs), so the binary CI boots is the one that ships.
The release job builds arm64 under emulation via binfmt, which costs
roughly 45 minutes and is why the boot gate lives on native hardware
instead.

## Notes for review

- No `uci` change needed. Docker and privileged runs already work on the
release runner, so binfmt registration is just another `before:` hook.
- The workflow file changes cannot be carried by the backport bot and
need a manual cherry-pick for release branches.
- Docs are drafted separately in sei-protocol/sei-docs#64, held in draft
until an arm64 tarball exists on a published release.

---------

Co-authored-by: Masih H. Derkani <m@derkani.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant