Pin Rust toolchain to 1.96 via single-source rust-toolchain.toml
What changed, and why it matters
This commit is a build-maintenance change, not a security fix. It creates one central file (rust-toolchain.toml) that declares which Rust compiler version to use, and updates build scripts and Docker configuration to read from that file instead of hard-coding an older version. There is no change to wallet logic, cryptography, or user-facing behavior.
No security action required. Treat as routine build hygiene; verify that CI and reproducible builds still pass with Rust 1.96.1.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch pins the Rust toolchain to 1.96.1 in a new rust-toolchain.toml file and makes CI, Docker, F-Droid build, reproducibility checks, and a cargokit-patching script derive the Rust version from that single source. It removes the previous hard-coded 1.83.0 default in Dockerfile.builder and several scripts. No application code, FFI bindings, or cryptographic operations are modified.
Changed components
rust-toolchain.toml (new).github/workflows/build-builder-image.ymlDockerfile.builderscripts/fdroid-build.shscripts/pin-rust-toolchain.shscripts/repro/apk-repro-check.shscripts/repro/fdroid-repro-check.shInspect captured patch +24 / −9
diff --git a/.github/workflows/build-builder-image.yml b/.github/workflows/build-builder-image.yml
index ec2f2cd..e39497f 100644
--- a/.github/workflows/build-builder-image.yml
+++ b/.github/workflows/build-builder-image.yml
@@ -8,6 +8,7 @@ on:
- 'Dockerfile.builder'
- '.github/workflows/build-builder-image.yml'
- 'pubspec.yaml'
+ - 'rust-toolchain.toml'
workflow_dispatch:
env:
@@ -35,6 +36,13 @@ jobs:
echo "FLUTTER_VERSION=${FLUTTER_VERSION}" >> $GITHUB_OUTPUT
echo "Using Flutter version: ${FLUTTER_VERSION}"
+ - name: Extract Rust toolchain from rust-toolchain.toml
+ id: rust
+ run: |
+ RUST_VERSION=$(sed -n 's/^[[:space:]]*channel[[:space:]]*=[[:space:]]*"\([^"]*\)".*/\1/p' rust-toolchain.toml | head -1)
+ echo "RUST_VERSION=${RUST_VERSION}" >> $GITHUB_OUTPUT
+ echo "Using Rust toolchain: ${RUST_VERSION}"
+
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
@@ -66,6 +74,7 @@ jobs:
labels: ${{ steps.meta.outputs.labels }}
build-args: |
FLUTTER_VERSION=${{ steps.flutter.outputs.FLUTTER_VERSION }}
+ RUST_VERSION=${{ steps.rust.outputs.RUST_VERSION }}
cache-from: type=gha
cache-to: type=gha,mode=max
diff --git a/Dockerfile.builder b/Dockerfile.builder
index d69fb85..bd701e9 100644
--- a/Dockerfile.builder
+++ b/Dockerfile.builder
@@ -3,7 +3,8 @@ FROM debian:bullseye-20251117@sha256:ee239c601913c0d3962208299eef70dcffcb7aac178
ARG FLUTTER_VERSION
-ARG RUST_VERSION=1.83.0
+# Passed by build-builder-image.yml from rust-toolchain.toml (single source of truth).
+ARG RUST_VERSION
ARG ANDROID_CMDLINE_TOOLS_VERSION=11076708
ARG ANDROID_BUILD_TOOLS_VERSION=36.0.0
ARG ANDROID_PLATFORM_VERSION=36
diff --git a/rust-toolchain.toml b/rust-toolchain.toml
new file mode 100644
index 0000000..2d45363
--- /dev/null
+++ b/rust-toolchain.toml
@@ -0,0 +1,2 @@
+[toolchain]
+channel = "1.96.1"
diff --git a/scripts/fdroid-build.sh b/scripts/fdroid-build.sh
index 960ff31..99be65b 100755
--- a/scripts/fdroid-build.sh
+++ b/scripts/fdroid-build.sh
@@ -51,7 +51,8 @@ cp "/tmp/monero_c/monero_libwallet2_api_c/build/$ARCH/libwallet2_api_c.so" \
rm -rf /tmp/monero_c
cd /tmp/skylight
export SOURCE_DATE_EPOCH="$(git log -1 --format=%ct)"
-rustup default 1.83.0
+RUST_TOOLCHAIN=$(sed -n 's/^[[:space:]]*channel[[:space:]]*=[[:space:]]*"\([^"]*\)".*/\1/p' rust-toolchain.toml | head -1)
+rustup default "$RUST_TOOLCHAIN"
rustup target add "$RUST"
export PUB_CACHE=/tmp/skylight/.pub-cache
export CARGO_HOME=/tmp/skylight-cargo
diff --git a/scripts/pin-rust-toolchain.sh b/scripts/pin-rust-toolchain.sh
index abced5a..d2f5daa 100755
--- a/scripts/pin-rust-toolchain.sh
+++ b/scripts/pin-rust-toolchain.sh
@@ -9,18 +9,19 @@
# cargokit's config only allows the channel enum (stable/beta/nightly), not an exact
# version — so we patch the default in the package instead.
#
-# Two cargokit copies need patching, in different places:
-# - tor_ffi_plugin: a pub.dev/git dependency -> its cargokit lives in PUB_CACHE.
-# - openalias_ffi: an in-repo PATH plugin -> its cargokit lives in plugins/.
+# Both Rust plugins — tor_ffi_plugin and wallet_openalias — are git/pub
+# dependencies now, so their cargokit copies live in PUB_CACHE. We still scan the
+# in-repo plugins/ dir for any local path plugin, though there are none today.
#
-# Run AFTER `flutter pub get` (so the tor package is in PUB_CACHE) and BEFORE the
+# Run AFTER `flutter pub get` (so both packages are in PUB_CACHE) and BEFORE the
# flutter build. Idempotent; safe if the string is already pinned.
#
set -euo pipefail
-TOOLCHAIN="${1:-1.96.1}"
CACHE="${PUB_CACHE:-$HOME/.pub-cache}"
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
+# Single source of truth: rust-toolchain.toml (arg still overrides, for ad-hoc use).
+TOOLCHAIN="${1:-$(sed -n 's/^[[:space:]]*channel[[:space:]]*=[[:space:]]*"\([^"]*\)".*/\1/p' "$ROOT/rust-toolchain.toml" | head -1)}"
n=0
while IFS= read -r f; do
diff --git a/scripts/repro/apk-repro-check.sh b/scripts/repro/apk-repro-check.sh
index e9e2a72..a8fc152 100755
--- a/scripts/repro/apk-repro-check.sh
+++ b/scripts/repro/apk-repro-check.sh
@@ -85,7 +85,8 @@ docker run --rm \
cd "$app"
test -f "android/app/src/main/jniLibs/$ABI/libmonero_libwallet2_api_c.so"
: "${SOURCE_DATE_EPOCH:=1700000000}" # from host -e (.git not copied)
- rustup default 1.83.0 >/dev/null 2>&1 || true
+ RUST_TOOLCHAIN=$(sed -n 's/^[[:space:]]*channel[[:space:]]*=[[:space:]]*"\([^"]*\)".*/\1/p' rust-toolchain.toml | head -1)
+ rustup default "$RUST_TOOLCHAIN" >/dev/null 2>&1 || true
rustup target add "$RUST" >/dev/null 2>&1 || true
export PUB_CACHE="$app/.pub-cache"
echo "==> [$app] flutter pub get..."
diff --git a/scripts/repro/fdroid-repro-check.sh b/scripts/repro/fdroid-repro-check.sh
index 955e04e..ad0fdd4 100755
--- a/scripts/repro/fdroid-repro-check.sh
+++ b/scripts/repro/fdroid-repro-check.sh
@@ -71,7 +71,7 @@ cleanup() {
trap cleanup EXIT INT TERM
git add -u # tracked modifications (pubspec, scripts, ...)
-git add scripts/reproducible.patch scripts/pin-rust-toolchain.sh scripts/fdroid-build.sh scripts/build-moneroc.sh 2>/dev/null || true
+git add rust-toolchain.toml scripts/reproducible.patch scripts/pin-rust-toolchain.sh scripts/fdroid-build.sh scripts/build-moneroc.sh 2>/dev/null || true
TREE=$(git write-tree)
TMP_COMMIT=$(git commit-tree "$TREE" -p HEAD -m "repro test (throwaway)")
git branch -f "$TMP_BRANCH" "$TMP_COMMIT"
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.