"UniFFI API checksum mismatch" in LWK bindings on armeabi-v7a
@ardier16 がすでに取り組んでいます。
2026年10月19日 から。
評価
この issue はまだ評価されていません。
説明
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
- Install the app on a 32-bit ARM (armeabi-v7a) device.
- Let the app be AOT-compiled (Play cloud profile at install, or background dexopt).
- Open or create a wallet with pin
- 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.tomlpinsblockstream-lwk = "0.19.0".- LWK's Kotlin bindings are generated with gobley 0.3.7. It declares the
u16returns of theuniffi_lwk_checksum_*functions asShortwith 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 anduniffiCheckApiChecksumsthrows. 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.sohidden bypackaging.jniLibs.pickFirsts("**/*.so"). GDK 0.78.0 ships onlylibgreen_gdk_java.soand exports no UniFFI or LWK symbols. glsdk shipslibglsdk.
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. Droppingarmeabi-v7awould 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 はありません
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
Blockstream/green_android のほかの issue
-
難易度 1/5 1時間未満 初心者へのやさしさ 88/100
Blockstream/green_android#313 ·
-
難易度 3/5 1〜2日 初心者へのやさしさ 76/100
Blockstream/green_android#315 ·
-
難易度 4/5 3〜5日 初心者へのやさしさ 55/100
Blockstream/green_android#314 ·
-
Support scanning SeedQR recovery phrases再び着手できるかも @ardier16 が 58 日前に担当しましたが、オープン中のプルリクエストはありません。 オープンfeature request
Blockstream/green_android#311 · コメント 2 件 · 担当者 1 名 ·
-
UX: Use "Passphrase BIP39" as a universal untranslated label — don't translate it as "contraseña"再び着手できるかも @ardier16 が 58 日前に担当しましたが、オープン中のプルリクエストはありません。 オープンenhancement
Blockstream/green_android#310 · コメント 4 件 · 担当者 1 名 ·
Blockstream/green_android の issue をすべて見る
似ている issue
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
software-mansion/enriched-markdown#1084 ·
メンテナーはふだん 2 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
lysine-dev/okhttp#9814 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
getdictus/dictus-android#187 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 79/100
bryangerlach/rdgen#319 ·