Skip to content

Add get_pre_1_wallet_keychains migration helper#364

Merged
notmandatory merged 1 commit intobitcoindevkit:masterfrom
notmandatory:feat/sqlite_pre1_migration_helper
Feb 24, 2026
Merged

Add get_pre_1_wallet_keychains migration helper#364
notmandatory merged 1 commit intobitcoindevkit:masterfrom
notmandatory:feat/sqlite_pre1_migration_helper

Conversation

@notmandatory
Copy link
Member

@notmandatory notmandatory commented Jan 12, 2026

Description

Add wallet/migration module and get_pre_1_wallet_keychains() to help migrate users from a pre-1.0 bdk sqlite database. This new function returns the last revealed index and checksum value for each keychain it finds.

Notes to the reviewers

This PR replaces bitcoindevkit/bdk#2090 since make more sense to put it in the wallet where it will be easier to export the bindings.

Changelog notice

  • Add get_pre_1_wallet_keychains to assist migration from pre-1.0 bdk wallets.

Checklists

All Submissions:

New Features:

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

@notmandatory notmandatory added this to the Wallet 2.4.0 milestone Jan 12, 2026
@notmandatory notmandatory self-assigned this Jan 12, 2026
@notmandatory notmandatory added the new feature New feature or request label Jan 12, 2026
@codecov
Copy link

codecov bot commented Jan 12, 2026

Codecov Report

❌ Patch coverage is 90.27778% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.78%. Comparing base (e078db2) to head (80276fc).
⚠️ Report is 15 commits behind head on master.

Files with missing lines Patch % Lines
src/wallet/migration.rs 90.27% 7 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #364      +/-   ##
==========================================
+ Coverage   86.75%   86.78%   +0.02%     
==========================================
  Files          25       26       +1     
  Lines        8479     8551      +72     
==========================================
+ Hits         7356     7421      +65     
- Misses       1123     1130       +7     
Flag Coverage Δ
rust 86.78% <90.27%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@notmandatory notmandatory changed the base branch from master to release/2.x January 12, 2026 23:30
@notmandatory notmandatory changed the title feat[rusqlite]: add get_pre_1_wallet_keychains migration helper Add get_pre_1_wallet_keychains migration helper Jan 12, 2026
@notmandatory notmandatory changed the base branch from release/2.x to master January 12, 2026 23:38
@notmandatory notmandatory force-pushed the feat/sqlite_pre1_migration_helper branch from 4751fac to 366ca7a Compare January 12, 2026 23:40
@notmandatory notmandatory marked this pull request as ready for review January 12, 2026 23:41
Copy link
Member

@thunderbiscuit thunderbiscuit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested ACK 366ca7a.

@notmandatory notmandatory moved this to Needs Review in BDK Wallet Jan 13, 2026
@thunderbiscuit
Copy link
Member

Part of this PR (rather a sidequest to this PR) could include updating the Migrating from 0.X page on the book of bdk, since this approach is simpler and requires less code, and I think it could simply supercede what we have there (or at least be added as a secondary section/option).

Also would be great to add a small feature page on the Release Guide when we do push the 2.4 section of the Release Guide. I keep track of the features I think should be highlighted here.

@thunderbiscuit
Copy link
Member

Two things I'd like to clarify maybe:

  1. Can we confirm the versions of bdk this will work for, and add it to the docstrings?
  2. Was there a reason to return the descriptor checksum instead of the whole descriptor string?

@notmandatory
Copy link
Member Author

Two things I'd like to clarify maybe:

  1. Can we confirm the versions of bdk this will work for, and add it to the docstrings?

The only sqlite tables this function uses is last_derivation_indices and checksums which existed and haven't changed for any pre-1.0 version of bdk. So I'd prefer to leave it as-is and let folks know that this function works for any pre-1.0 version they're on.

  1. Was there a reason to return the descriptor checksum instead of the whole descriptor string?

Unfortunately pre-1.0 we did not persist the descriptor string in the sqlite db, all wallet constructors required you pass in your descriptor(s), see: pre-1.0 Wallet docs. All we have in the pre-1.0 sqlite db are the descriptor checksums.

// Create pre-1.0 bdk sqlite schema
conn.execute_batch(
"CREATE TABLE last_derivation_indices (keychain TEXT, value INTEGER);
CREATE UNIQUE INDEX idx_indices_keychain ON last_derivation_indices(keychain);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a nit, feel free to ignore:
Do we need to create an index on the keychain column?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed probably don't need it for this test, but I'll leave it since it's copy/paste from pre-1.0 schema sqlite.

@110CodingP
Copy link
Contributor

TACK 366ca7a

Tested by running the following in bdk_wallet@v0.30.2 and bdk_wallet@366ca7a respectively:

use bdk_wallet::rusqlite::{self, Connection};

fn main() -> rusqlite::Result<()> {
    let mut conn = Connection::open("/home/codingp110/pre-1_wallet/.bdk_db.sqlite")?;

    let external_checksum = "1cead456".as_bytes();
    let internal_checksum = "1cead454".as_bytes();

    let result = bdk_wallet::migration::get_pre_1_wallet_keychains(&mut conn)?;
    assert_eq!(result.len(), 2);
    assert_eq!(result[0].keychain, "External");
    assert_eq!(result[0].last_derivation_index, 1337);
    assert_eq!(result[0].checksum, external_checksum);
    assert_eq!(result[1].keychain, "Internal");
    assert_eq!(result[1].last_derivation_index, 68);
    assert_eq!(result[1].checksum, internal_checksum);
    println!("Successful");
    Ok(())
}

and

use bdk::database::SqliteDatabase;
use bdk::database::{BatchOperations, Database};
use bdk::KeychainKind;

fn main() {
    let mut db = SqliteDatabase::new(String::from("./.bdk_db.sqlite"));
    db.set_last_index(KeychainKind::External, 1337).unwrap();
    db.set_last_index(KeychainKind::Internal, 68).unwrap();
    db.check_descriptor_checksum(KeychainKind::External, "1cead456".as_bytes());
    db.check_descriptor_checksum(KeychainKind::Internal, "1cead454".as_bytes());
}

@notmandatory notmandatory force-pushed the feat/sqlite_pre1_migration_helper branch from 366ca7a to 80276fc Compare February 17, 2026 15:17
@notmandatory
Copy link
Member Author

Rebased on master branch.

@ValuedMammal
Copy link
Collaborator

Code review ACK

@notmandatory notmandatory merged commit c422104 into bitcoindevkit:master Feb 24, 2026
17 checks passed
@github-project-automation github-project-automation bot moved this from Needs Review to Done in BDK Wallet Feb 24, 2026
notmandatory added a commit that referenced this pull request Feb 24, 2026
f19c6fb feat[rusqlite]: add get_pre_1_wallet_keychains migration helper (Steve Myers)

Pull request description:

  ### Description

  Add `wallet/migration` module and `get_pre_1_wallet_keychains()` to help migrate users from a pre-1.0 bdk sqlite database. This new function returns the last revealed index and checksum value for each keychain it finds.

  ### Notes to the reviewers

  This is a backport to the `release/2.x` branch of #364.

  ### Changelog notice

  * Add `get_pre_1_wallet_keychains` to assist migration from pre-1.0 bdk wallets. (back ported from 3.x)

  ### Checklists

  #### All Submissions:

  * [x] I've signed all my commits
  * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
  * [x] I ran `just p` before pushing

  #### New Features:

  * [x] I've added tests for the new feature
  * [x] I've added docs for the new feature

ACKs for top commit:
  thunderbiscuit:
    Tested ACK f19c6fb.
  110CodingP:
    ACK [f19c6fb](f19c6fb)

Tree-SHA512: 48ec320871361bc041020efdbdcfbdf7acd9d80700c5b35c933868424edb3fef8bae3a39491c722f619aeefe36456b42ac78626a758847ff9de566baae2456b4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new feature New feature or request

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Add Utility Function to Pull Relevant Data From Old BDK Database Add helper methods to help migration from 0.X versions

4 participants