This is an update to the old issue
Hey @0xh3rman and team — thanks for the detailed response back in March, and for the work you put
into the reproducible/ scripts and documenting the R8 pg-map-id issue. We can see you've been
actively thinking about this.
We've now re-run the verification against v2.68 on the new gemwalletcom/wallet monorepo. Good news
on a few fronts, and one remaining item we wanted to flag.
What's now clean:
- We're now building against the googleRelease flavor (via bundletool + split APKs), so the flavor
mismatch from the earlier test is resolved.
- The massive res/ diff from v1.3.97 is gone. resources.arsc still differs in binary, but aapt2
dump resources shows semantically identical resource tables across all splits.
- AndroidManifest.xml differs only in Play-injected stamp metadata (com.android.stamp.,
com.android.vending.derived.), which we filter out.
- stamp-cert-sha256 and splits0.xml locale alias differences are expected Play/bundletool
artifacts.
What's still differing:
The one real remaining issue is lib/arm64-v8a/libgemstone.so. It differs in hash, binary size, and
ELF section layout between the Play Store APK and our local build. The exported symbol list (nm -D)
is identical — the public ABI matches — but the internal binary does not.
official libgemstone.so: 28,351,496 bytes
built libgemstone.so: 28,465,232 bytes
.text size: official 0x1266360, built 0x128ef54
RELACOUNT: official 30534, built 29166
This is likely related to the fact that libgemstone is now built from Rust source via cargo ndk as
part of the Android build, and the repo currently has no rust-toolchain.toml pinning the Rust
version for Android. The core/Dockerfile pins rust-1.94.1 but that image is for the server binary,
not the Android CI runners. The Android CI workflow appears to use whatever stable Rust is active
on the runner at the time, which makes bit-for-bit reproducibility of the native library hard to
achieve.
We also saw classes*.dex and baseline.prof* differ on one of our build machines but not the other —
consistent with the R8 pg-map-id non-determinism you mentioned. We noted your R8 patch in the old
repo; it looks like that tooling was removed in the monorepo migration (reproducible/ is now a
placeholder). If you're planning a Nix-based replacement, a rust-toolchain.toml for the Android
target alongside it would go a long way toward locking down libgemstone.so as well.
Appreciate the transparency and the continued effort here — you're clearly closer than most. Happy
to share our full build script and comparison artifacts if it helps.
This is an update to the old issue
Hey @0xh3rman and team — thanks for the detailed response back in March, and for the work you put
into the reproducible/ scripts and documenting the R8 pg-map-id issue. We can see you've been
actively thinking about this.
We've now re-run the verification against v2.68 on the new gemwalletcom/wallet monorepo. Good news
on a few fronts, and one remaining item we wanted to flag.
What's now clean:
mismatch from the earlier test is resolved.
dump resources shows semantically identical resource tables across all splits.
com.android.vending.derived.), which we filter out.
artifacts.
What's still differing:
The one real remaining issue is lib/arm64-v8a/libgemstone.so. It differs in hash, binary size, and
ELF section layout between the Play Store APK and our local build. The exported symbol list (nm -D)
is identical — the public ABI matches — but the internal binary does not.
official libgemstone.so: 28,351,496 bytes
built libgemstone.so: 28,465,232 bytes
.text size: official 0x1266360, built 0x128ef54
RELACOUNT: official 30534, built 29166
This is likely related to the fact that libgemstone is now built from Rust source via cargo ndk as
part of the Android build, and the repo currently has no rust-toolchain.toml pinning the Rust
version for Android. The core/Dockerfile pins rust-1.94.1 but that image is for the server binary,
not the Android CI runners. The Android CI workflow appears to use whatever stable Rust is active
on the runner at the time, which makes bit-for-bit reproducibility of the native library hard to
achieve.
We also saw classes*.dex and baseline.prof* differ on one of our build machines but not the other —
consistent with the R8 pg-map-id non-determinism you mentioned. We noted your R8 patch in the old
repo; it looks like that tooling was removed in the monorepo migration (reproducible/ is now a
placeholder). If you're planning a Nix-based replacement, a rust-toolchain.toml for the Android
target alongside it would go a long way toward locking down libgemstone.so as well.
Appreciate the transparency and the continued effort here — you're clearly closer than most. Happy
to share our full build script and comparison artifacts if it helps.