Skip to content

Fix/chain position ffi serialization#959

Closed
kumulynja wants to merge 6 commits intobitcoindevkit:masterfrom
kumulynja:fix/chain-position-ffi-serialization
Closed

Fix/chain position ffi serialization#959
kumulynja wants to merge 6 commits intobitcoindevkit:masterfrom
kumulynja:fix/chain-position-ffi-serialization

Conversation

@kumulynja
Copy link
Contributor

@kumulynja kumulynja commented Feb 23, 2026

Description

While using bdk-dart I encountered the following error after having broadcasted a transaction and wanting to list the transactions which resulted in app crashes:

unexpected enum: UniFfi::UnexpectedEnumCase    ParallelWaitError(2 errors): UniFfi::UnexpectedEnumCase    #0      FfiConverterChainPosition.read (package:bdk_dart/bdk.dart:5622:9)

ChainPosition was writing garbage bytes (0x00da7f10 in this specific case) instead of valid enum discriminants (1 or 2).

Tracked it down with Claude Code to the following cause in bdk-ffi:

The From implementation called .into() on a borrowed ChainPosition<&BdkConfirmationBlockTime>. This caused a lifetime mismatch with the From trait expecting an owned value, resulting in undefined behavior during FFI serialization.

Solution implemented in this PR:

Explicitly pattern match on the borrowed chain_position and construct the ChainPosition enum correctly, fixing the "invalid enum index" error when calling Wallet.transactions().

Tested successfully with bdk-dart and the crashing wallet.

Notes to the reviewers

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing
  • I've added a changelog in the next release tracking issue (see example)
  • I've linked the relevant upstream docs or specs above

Bugfixes:

  • This pull request breaks the existing API
  • I've added tests to reproduce the issue which are now passing
  • I'm linking the issue being fixed by this PR

kumulynja and others added 2 commits February 23, 2026 00:47
Fixed FFI serialization bug where ChainPosition was writing garbage
bytes (0x00da7f10) instead of valid enum discriminants (1 or 2).

The issue was in the From<BdkCanonicalTx> implementation which called
.into() on a borrowed ChainPosition<&BdkConfirmationBlockTime>. This
caused a lifetime mismatch with the From trait expecting an owned value,
resulting in undefined behavior during FFI serialization.

Now explicitly pattern match on the borrowed chain_position and construct
the ChainPosition enum correctly, fixing the "invalid enum index" error
when calling Wallet.transactions().

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@kumulynja kumulynja force-pushed the fix/chain-position-ffi-serialization branch from 7a51454 to 4f777ca Compare February 23, 2026 19:54
@kumulynja
Copy link
Contributor Author

I added test cases to bdk-ffi first, but they passed without the fix as well, since the bug appears in the uniffi serialization, not on Rust-level conversions. So I removed them again and it would be better to add tests for it in the languages of the bindings themselves.

@kumulynja
Copy link
Contributor Author

kumulynja commented Feb 23, 2026

I made some wrong conclusions, BdkConfirmationBlockTime is not borrowed, and the problem I encountered seems to be solved by the following: bitcoindevkit/bdk-dart#47. So closing the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants