Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

"UniFFI API checksum mismatch" in LWK bindings on armeabi-v7a

オープン
#317 コメント 3 件 リアクション 0 件 担当者 1 名 GitHub で見る

@ardier16 がすでに取り組んでいます。

2026年10月19日 から。

評価

この issue はまだ評価されていません。

説明

bug status: confirmed
Title

Crash at login on 32-bit ARM (armeabi-v7a): "UniFFI API checksum mismatch" in LWK bindings

Summary

The app crashes immediately when logging in (PIN) on a 32-bit ARM device. The crash comes from the LWK UniFFI integrity check failing when LwkNetworkBackend calls lwk.Network.mainnet(). The same wallet type works on a 64-bit (arm64-v8a) device.

This looks like the known gobley 0.3.7 bug on 32-bit ARM Android (gobley/gobley#252). It was fixed in LWK on 2026-10-09 (Blockstream/lwk@22659e7), but that fix is still listed as "Unreleased" in LWK's changelog. Green currently depends on LWK 0.19.0.

Environment
  • App: Blockstream App (Green), com.greenaddress.greenbits_android_wallet, version [5.7.0] from Play Store
  • Device: Xiaomi Redmi A1 (MediaTek Helio A22), Android 12 Go edition
  • ABI: armeabi-v7a (ro.product.cpu.abilist = armeabi-v7a,armeabi
  • Works on: Xiaomi Redmi 12 (arm64-v8a)
Steps to reproduce
  1. Install the app on a 32-bit ARM (armeabi-v7a) device.
  2. Let the app be AOT-compiled (Play cloud profile at install, or background dexopt).
  3. Open or create a wallet with pin
  4. The app crashes.
Expected

Login succeeds.

Actual

Fatal crash:

java.lang.ExceptionInInitializerError
  at lwk.UniffiLib.<clinit>
  at lwk.Network$Companion.mainnet
  at com.blockstream.data.backend.lwk.LwkNetworkBackend.<init>
  at com.blockstream.data.gdk.GdkSession.initNetworkBackends
  at com.blockstream.data.gdk.GdkSession.connect
  at com.blockstream.data.gdk.GdkSession.loginWithLoginCredentials
  at com.blockstream.compose.models.login.LoginViewModel$loginWithPinOrMnemonic$1.invokeSuspend
  ...
Caused by: java.lang.RuntimeException: UniFFI API checksum mismatch: try cleaning and rebuilding your project
  at lwk.IntegrityCheckingUniffiLib.uniffiCheckApiChecksums
  at lwk.IntegrityCheckingUniffiLib.<clinit>

Full logcat
--------  5805  5805 E AndroidRuntime: FATAL EXCEPTION: main
--------  5805  5805 E AndroidRuntime: Process: com.greenaddress.greenbits_android_wallet, PID: 5805
--------  5805  5805 E AndroidRuntime: java.lang.ExceptionInInitializerError
--------  5805  5805 E AndroidRuntime:  at lwk.UniffiLib.<clinit>(r8-map-id-eba37adec517341ce9f8432a2a824f7221e62e373e383229433fbb9433ed751f:8)
--------  5805  5805 E AndroidRuntime:  at lwk.Network$Companion$mainnet$$inlined$uniffiRustCall$1.invoke(r8-map-id-eba37adec517341ce9f8432a2a824f7221e62e373e383229433fbb9433ed751f:4)
--------  5805  5805 E AndroidRuntime:  at lwk.Network$Companion$mainnet$$inlined$uniffiRustCall$1.invoke(r8-map-id-eba37adec517341ce9f8432a2a824f7221e62e373e383229433fbb9433ed751f:14)
--------  5805  5805 E AndroidRuntime:  at lwk.UniffiRustCallStatusHelper.withReference$lib(r8-map-id-eba37adec517341ce9f8432a2a824f7221e62e373e383229433fbb9433ed751f:9)
--------  5805  5805 E AndroidRuntime:  at lwk.Network$Companion.mainnet(r8-map-id-eba37adec517341ce9f8432a2a824f7221e62e373e383229433fbb9433ed751f:12)
--------  5805  5805 E AndroidRuntime:  at com.blockstream.data.backend.lwk.LwkNetworkBackend.<init>(r8-map-id-eba37adec517341ce9f8432a2a824f7221e62e373e383229433fbb9433ed751f:40)
--------  5805  5805 E AndroidRuntime:  at com.blockstream.data.gdk.GdkSession.initNetworkBackends(r8-map-id-eba37adec517341ce9f8432a2a824f7221e62e373e383229433fbb9433ed751f:220)
--------  5805  5805 E AndroidRuntime:  at com.blockstream.data.gdk.GdkSession.connect(r8-map-id-eba37adec517341ce9f8432a2a824f7221e62e373e383229433fbb9433ed751f:153)
--------  5805  5805 E AndroidRuntime:  at com.blockstream.data.gdk.GdkSession.loginWithLoginCredentials(r8-map-id-eba37adec517341ce9f8432a2a824f7221e62e373e383229433fbb9433ed751f:27)
--------  5805  5805 E AndroidRuntime:  at com.blockstream.data.gdk.GdkSession.loginWithLoginCredentials$default(r8-map-id-eba37adec517341ce9f8432a2a824f7221e62e373e383229433fbb9433ed751f:113)
--------  5805  5805 E AndroidRuntime:  at com.blockstream.data.gdk.GdkSession.loginWithWallet(r8-map-id-eba37adec517341ce9f8432a2a824f7221e62e373e383229433fbb9433ed751f:94)
--------  5805  5805 E AndroidRuntime:  at com.blockstream.compose.models.login.LoginViewModel$loginWithPinOrMnemonic$1.invokeSuspend(r8-map-id-eba37adec517341ce9f8432a2a824f7221e62e373e383229433fbb9433ed751f:126)
--------  5805  5805 E AndroidRuntime:  at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(r8-map-id-eba37adec517341ce9f8432a2a824f7221e62e373e383229433fbb9433ed751f:11)
--------  5805  5805 E AndroidRuntime:  at kotlinx.coroutines.DispatchedTask.run(r8-map-id-eba37adec517341ce9f8432a2a824f7221e62e373e383229433fbb9433ed751f:127)
--------  5805  5805 E AndroidRuntime:  at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(r8-map-id-eba37adec517341ce9f8432a2a824f7221e62e373e383229433fbb9433ed751f:1)
--------  5805  5805 E AndroidRuntime:  at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(r8-map-id-eba37adec517341ce9f8432a2a824f7221e62e373e383229433fbb9433ed751f:62)
--------  5805  5805 E AndroidRuntime:  at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(r8-map-id-eba37adec517341ce9f8432a2a824f7221e62e373e383229433fbb9433ed751f:29)
--------  5805  5805 E AndroidRuntime:  at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(r8-map-id-eba37adec517341ce9f8432a2a824f7221e62e373e383229433fbb9433ed751f:1)
--------  5805  5805 E AndroidRuntime:  Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@7dbae6d, Dispatchers.Main.immediate]
--------  5805  5805 E AndroidRuntime: Caused by: java.lang.RuntimeException: UniFFI API checksum mismatch: try cleaning and rebuilding your project
--------  5805  5805 E AndroidRuntime:  at ge.g(r8-map-id-eba37adec517341ce9f8432a2a824f7221e62e373e383229433fbb9433ed751f:3)
--------  5805  5805 E AndroidRuntime:  at lwk.IntegrityCheckingUniffiLib.uniffiCheckApiChecksums(r8-map-id-eba37adec517341ce9f8432a2a824f7221e62e373e383229433fbb9433ed751f:992)
--------  5805  5805 E AndroidRuntime:  at lwk.IntegrityCheckingUniffiLib.<clinit>(r8-map-id-eba37adec517341ce9f8432a2a824f7221e62e373e383229433fbb9433ed751f:22)
--------  5805  5805 E AndroidRuntime:  ... 18 more
Analysis
  • gradle/libs.versions.toml pins blockstream-lwk = "0.19.0".
  • LWK's Kotlin bindings are generated with gobley 0.3.7. It declares the u16 returns of the uniffi_lwk_checksum_* functions as Short with JNA direct mapping. Rust zero-extends the value. ART's compiled JNI stubs on 32-bit ARM don't re-extend small return values, so after AOT compilation the checksum read on armeabi-v7a is wrong and uniffiCheckApiChecksums throws. arm64 is unaffected.
  • LWK fixed this by generating the bindings with a patched gobley (lwk@22659e7, upstream PR gobley/gobley#297). The fix is not in 0.19.0 or 0.19.1.
  • glsdk (Greenlight) uses the same generator and recently added the same workaround in build/.tasks.yml. glsdk 0.3.0 may therefore also be affected on 32-bit ARM, for example in Lightning flows.
  • Ruled out: duplicate liblwk.so hidden by packaging.jniLibs.pickFirsts("**/*.so"). GDK 0.78.0 ships only libgreen_gdk_java.so and exports no UniFFI or LWK symbols. glsdk ships libglsdk.
Suggested fix
  • Bump LWK to the first release containing lwk@22659e7, and glsdk to a release built with the patched gobley.
  • Possible interim mitigation: android:vmSafeMode="true" in the manifest to prevent AOT compilation, at some performance cost. Dropping armeabi-v7a would instead lock out existing 32-bit users.
Verified workaround

Resetting the app to non-AOT code may avoid the crash without touching wallet data:

adb shell cmd package compile -m verify -f com.greenaddress.greenbits_android_wallet

Background dexopt will likely re-compile the app later, bringing the crash back.

主要言語
Kotlin
スター
274
フォーク
111
PR マージ指標
30日以内にマージされた PR はありません

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

Blockstream/green_android のほかの issue

Blockstream/green_android の issue をすべて見る

似ている issue

Kotlin の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。