Skip to content

Express the wallet changeset over the FFI layer #756

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

rustaceanrob
Copy link
Collaborator

@rustaceanrob rustaceanrob commented May 7, 2025

Description

Builds on #754 to create a fully expressive and serializable ChangeSet type. The goal is for this to enable arbitrary persistence backends across the FFI layer. Ultimately that would close #739 and any further database requests that are outside the immediately supported options.

For context: The iterators in the BDK changesets are BTree based to be no_std compatible and have deterministic ordering of duplicate data across all targets. UniFFI exposes only two iterators across the boundary, Vec and HashMap, but I can try to lay out why I think using these is acceptable.

The goal here is to convert between bdk_wallet::ChangeSet and FFI ChangeSet, and the easiest way to go about that is to just make each field convertible. For the LocalChain::ChangeSet, I iterate over the BTreeMap, which will return the key-value pairs in order. That means the vector will be in order over the FFI layer. Everything else coming from BDK could be ordered by key, but is not required in my opinion to implement the persistence. For instance any mapping from DescriptorId to last revealed index is okay, as the DescirptorId do not necessarily have to be in any particular order. Same goes for Txid or Outpoint mapping to some value. While it is nice to be reproducible, these keys are suitable for a HashMap.

Can elaborate on the next call

Notes to the reviewers

In Swift, and key of a HashMap must implement Equitable and Hashable. We can export Eq and Hash from Rust for Objects, but not for Records from what I can tell. As a result, I made a kind-of-gross wrapper called HashableOutPoint that is an Object so it can be used as a key, but it is convertible to the underlying Record if required. Open to ideas on that one.

Also, I cannot for the life of me figure out the best way to go from a Descriptor<DescriptorPublicKey> into DescriptorPublicKey and vise versa without introducing an unwrap. Feels like we can improve that.

Changelog notice

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature

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

@rustaceanrob rustaceanrob force-pushed the use-hash-types-5-7 branch 6 times, most recently from 5c7d850 to 1af0175 Compare May 8, 2025 08:43
@rustaceanrob rustaceanrob marked this pull request as ready for review May 8, 2025 09:23
@rustaceanrob rustaceanrob force-pushed the use-hash-types-5-7 branch 2 times, most recently from 0896198 to a2027f3 Compare May 13, 2025 14:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Continued discussion on encrypting persisted data
1 participant