From cefa6eda83b42df98365daee248f58a6d810858e Mon Sep 17 00:00:00 2001 From: thunderbiscuit Date: Tue, 26 May 2026 19:01:58 -0400 Subject: [PATCH 1/3] test: add test databases --- .../lib/src/androidTest/assets/README.md | 10 ++++++++++ .../lib/src/androidTest/assets/db_v3.sqlite3 | Bin 0 -> 69632 bytes .../assets/old_databases/db_v032.sqlite3 | Bin 0 -> 86016 bytes .../assets/old_databases/db_v1.sqlite3 | Bin 0 -> 53248 bytes .../assets/old_databases/db_v2.sqlite3 | Bin 0 -> 61440 bytes 5 files changed, 10 insertions(+) create mode 100644 bdk-android/lib/src/androidTest/assets/db_v3.sqlite3 create mode 100644 bdk-android/lib/src/androidTest/assets/old_databases/db_v032.sqlite3 create mode 100644 bdk-android/lib/src/androidTest/assets/old_databases/db_v1.sqlite3 create mode 100644 bdk-android/lib/src/androidTest/assets/old_databases/db_v2.sqlite3 diff --git a/bdk-android/lib/src/androidTest/assets/README.md b/bdk-android/lib/src/androidTest/assets/README.md index 9d9331b7..60ce89e9 100644 --- a/bdk-android/lib/src/androidTest/assets/README.md +++ b/bdk-android/lib/src/androidTest/assets/README.md @@ -4,6 +4,7 @@ The wallet database `awesome_wallet_1.sqlite3` is used for testing. This wallet: +- Was created using bdk_wallet 2.X - Is a Regtest wallet - Was built using 2 descriptors - Has a transaction on address index 0 @@ -31,3 +32,12 @@ The wallet database `wallet_pre_v1.sqlite3` is used for testing. This wallet: - Has revealed the first 8 addresses on the external keychain (last revealed index is 7) - Has revealed the first address on the internal keychain (last revealed index is 0) - The descriptors are BIP86 descriptors with the MNEMONIC_AWESOME mnemonic + +## Old Databases + +The `old_databases` directory contains wallets created from different versions of BDK. These wallets: + +- Are Regtest wallets +- Have revealed 7 addresses (0-6) on the external keychain (next address to come up is index 7) +- Have revealed the first address (index 0) on the internal keychain (next address to come up is index 1) +- The wallets were created with BIP84 descriptors with the MNEMONIC_ALL mnemonic diff --git a/bdk-android/lib/src/androidTest/assets/db_v3.sqlite3 b/bdk-android/lib/src/androidTest/assets/db_v3.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..6f3d40de08b8d7f228b215661c87450c1e5253e8 GIT binary patch literal 69632 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 literal 0 HcmV?d00001 diff --git a/bdk-android/lib/src/androidTest/assets/old_databases/db_v2.sqlite3 b/bdk-android/lib/src/androidTest/assets/old_databases/db_v2.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..bc5618045cdd513500d5e09cb34b1a629fd57ec7 GIT binary patch literal 61440 zcmeI*%WvaE90zba=_ctTH6TzVDkN7uY>T=yj_t%jT8T7ux22Emrs=X>grc!Mc{FL# zb=)=!5>mn*kT~ zHELMZf<>FAT{&|aHcQ%-3u+abXVvC}P4n5Dp2_QCKC`~7ixYMfm&KvdE0&nopX9~; zhwOEdzLi1UT{qa>G=T5_0FHER*L7K2pXlG`_F;V< zYQ0j-$hNsjh$DMmtvHM^5FP!&S5^Bo?WH^6*unzed9U9Fr{#4y`xY9j8Ovmqa9X_{ zy!zNSxhyy>uhUjVuOdxK>;10n=Fy9a=}@bey($(fHX|F}wby~2>FIE6X^H=85Uiwb zmK(NL({6HRthU_^BQ@>`i8*~!&*}SF{m=_suVrq-R#ru$)-bDuGOd)#POo}H(bwHf zn&nr+*lg5UBiJAHl}5ebR8DFCr#JM?%+YRMyeAD6G_1Gm9((lA{WW%^K`^T`q1g7) zq+sqg+YjFE%4}N=hhvM2d`BJX=*GFz?Q1s`83S}$ZvK^itKtRQ)^A^rm1UFK`Jml{ ze1B}2cqaP!+uqzj5!fpl)yX+Zu|7ym9=KxlpXCPbzL` zI2k#I#>Rq?tx@40F5({HUMLjHEKE88i?m*4o8fkN%IlW)AhNyi^18)O-5Ki^Kc96= zHxfq!bvUX9{M}v0f_5+xtOWf48H@y%q*kMjJ9hc0sj-^)`K%^vKZt2+_ zahdIQUyQR;Y@qC&L#v`$CiM~>`W@8GuT$r;VORY#tv4Qg$$P^=JKOKyrdg(^#8c}g z17nr#ZdexUgq@k*Z=kE{%0ighO?C$NThvqRTd9HnItRPQ@;kb_;$GW(F%o5oDd9U# z_)GXh_=P2~KmY;|fB*y_009U<00Izz00ba#Qv}|Q1lOkB*^nxI&Za9Wb#Jyw2nCmT zH`i&EY;sl(z8MIvMBEHEi%4qTj!{0i=w9UY_R-$nR<5LF8jp7#pI(@m1J%e~ zrZV=%4sGmT?qohbKY1*-vIo`mizizuJvl5HrRV#}YED1hOf~l`McTKF^DUy)rH!Zi zt;4<2T72#Ol_k3#|D2wfjil&^00Izz00bZa0SG_<0uX?}Ef#P;|Bvhc zTin5D8U!E!0SG_<0uX=z1Rwwb2ta@d;Ql|t00Izz00bZa0SG_<0uX=z1R!wx1#tiW z_V+Pb2muH{00Izz00bZa0SG_<0uaFcf5ZR;AOHafKmY;|fB*y_009U<;PwmP{{QXo zW3&(g5P$##AOHafKmY;|fB*y_;NJfa2u=3@k7GclmQ#JN%zG6x>j5M(laxuZ4*{7x5$N0rlYC?^ti-Zu1#wnr1QjBz3 zR@0KI6y?wc&x(m86Goz_#1%zL$*PjF62!EUR$57=NSdZCEuKmmM#@Yp$&@6k34^4p zc+#SBD#@N4s8Pke{~r*}IpGKPh6Mr;fB*y_009U<00Izz00bZaf$I~{uVVrru)#{1 z{=e7%`27F%bt_7O00bZa0SG_<0uX=z1Rwwb2;5WweE$EY_6+I;0SG_<0uX=z1Rwwb N2tWV=5V$^pe*yf;ec=EA literal 0 HcmV?d00001 From 37e6117e1d7329fa9ccdb969527cfd4f64e0be03 Mon Sep 17 00:00:00 2001 From: thunderbiscuit Date: Wed, 27 May 2026 09:18:59 -0400 Subject: [PATCH 2/3] test: test database migration from v0, v1, v2 to v3 wallet --- .../DatabaseVersionCompatTest.kt | 228 ++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 bdk-android/lib/src/androidTest/kotlin/org/bitcoindevkit/DatabaseVersionCompatTest.kt diff --git a/bdk-android/lib/src/androidTest/kotlin/org/bitcoindevkit/DatabaseVersionCompatTest.kt b/bdk-android/lib/src/androidTest/kotlin/org/bitcoindevkit/DatabaseVersionCompatTest.kt new file mode 100644 index 00000000..4e7c1665 --- /dev/null +++ b/bdk-android/lib/src/androidTest/kotlin/org/bitcoindevkit/DatabaseVersionCompatTest.kt @@ -0,0 +1,228 @@ +package org.bitcoindevkit + +import android.database.sqlite.SQLiteDatabase +import androidx.test.platform.app.InstrumentationRegistry +import java.io.File +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +const val MNEMONIC_ALL = "all all all all all all all all all all all all" + +class DatabaseVersionCompatTest { + private val context = InstrumentationRegistry.getInstrumentation().targetContext + + private fun resolveAsset(dbFileName: String, subDir: String? = null): String { + val context = InstrumentationRegistry.getInstrumentation().targetContext + val assetPath = if (subDir != null) "$subDir/$dbFileName" else dbFileName + val destFile = File(context.getDatabasePath(dbFileName).path) + context.assets.open(assetPath).use { input -> + destFile.outputStream().use { output -> + input.copyTo(output) + } + } + return destFile.absolutePath + } + + val descriptorSecretKey: DescriptorSecretKey = DescriptorSecretKey( + NetworkKind.TEST, + Mnemonic.fromString(MNEMONIC_ALL), + null + ) + val descriptor: Descriptor = Descriptor.newBip84(descriptorSecretKey, KeychainKind.EXTERNAL, NetworkKind.TEST) + val changeDescriptor: Descriptor = Descriptor.newBip84(descriptorSecretKey, KeychainKind.INTERNAL, NetworkKind.TEST) + + // You can take a v1 Wallet database and use it to create a v3 Wallet. + @Test + fun loadV1WalletDBIntoV3Wallet() { + val dbV1 = Persister.newSqlite(resolveAsset("db_v1.sqlite3", "old_databases")) + + val wallet = Wallet.load( + descriptor = descriptor, + changeDescriptor = changeDescriptor, + persister = dbV1, + ) + + val addressInfo: AddressInfo = wallet.revealNextAddress(KeychainKind.EXTERNAL) + val changeAddressInfo: AddressInfo = wallet.revealNextAddress(KeychainKind.INTERNAL) + println("Address info: $addressInfo") + println("Change address info: $changeAddressInfo") + + assertEquals(addressInfo.index, 7u) + assertEquals(changeAddressInfo.index, 1u) + } + + // You can take a v2 Wallet database and use it to create a v3 Wallet. + @Test + fun loadV2WalletDBIntoV3Wallet() { + val dbV2 = Persister.newSqlite(resolveAsset("db_v2.sqlite3", "old_databases")) + + val wallet = Wallet.load( + descriptor = descriptor, + changeDescriptor = changeDescriptor, + persister = dbV2, + ) + + val addressInfo: AddressInfo = wallet.revealNextAddress(KeychainKind.EXTERNAL) + val changeAddressInfo: AddressInfo = wallet.revealNextAddress(KeychainKind.INTERNAL) + // println("Address info: $addressInfo") + // println("Change address info: $changeAddressInfo") + + assertEquals(addressInfo.index, 7u) + assertEquals(changeAddressInfo.index, 1u) + } + + // You can take a v1 Wallet database and use it to create a v3 Wallet, and the database migrates gracefully. + // The v3 database adds the bdk_descriptor_derived_spks and bdk_wallet_locked_outpoints tables. + @Test + fun v3WalletWillAddRequiredFieldsToV1DB() { + val dbPath = resolveAsset("db_v1.sqlite3", "old_databases") + val oldV1DB = Persister.newSqlite(dbPath) + + val tablesBefore: List = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READONLY).use { db -> + db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null).use { cursor -> + generateSequence { if (cursor.moveToNext()) cursor.getString(0) else null }.toList() + } + } + // println("V1 Database Tables: $tablesBefore") + // V1 Database Tables: [bdk_schemas, bdk_wallet, bdk_blocks, bdk_txs, bdk_txouts, bdk_anchors, bdk_descriptor_last_revealed] + + assertTrue(!tablesBefore.contains("bdk_descriptor_derived_spks")) + assertTrue(!tablesBefore.contains("bdk_wallet_locked_outpoints")) + + val wallet1 = Wallet.load( + descriptor = descriptor, + changeDescriptor = changeDescriptor, + persister = oldV1DB, + ) + + val addressInfoWallet1: AddressInfo = wallet1.revealNextAddress(KeychainKind.EXTERNAL) + val changeAddressInfoWallet1: AddressInfo = wallet1.revealNextAddress(KeychainKind.INTERNAL) + + assertEquals(addressInfoWallet1.index, 7u) + assertEquals(changeAddressInfoWallet1.index, 1u) + + wallet1.persist(oldV1DB) + + val tables: List = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READONLY).use { db -> + db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null).use { cursor -> + generateSequence { if (cursor.moveToNext()) cursor.getString(0) else null }.toList() + } + } + + // println("V3 Database Tables: $tables") + // V3 Database Tables: [bdk_schemas, bdk_wallet, bdk_blocks, bdk_txs, bdk_txouts, bdk_anchors, bdk_descriptor_last_revealed, bdk_wallet_locked_outpoints, bdk_descriptor_derived_spks] + + assertTrue(tables.contains("bdk_descriptor_derived_spks")) + assertTrue(tables.contains("bdk_wallet_locked_outpoints")) + } + + // You can take a v2 Wallet database and use it to create a v3 Wallet, and the database migrates gracefully. + // The v3 database adds the bdk_wallet_locked_outpoints table. + @Test + fun v3WalletWillAddRequiredFieldsToV2DB() { + val dbPath = resolveAsset("db_v2.sqlite3", "old_databases") + val oldV1DB = Persister.newSqlite(dbPath) + + val tablesBefore: List = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READONLY).use { db -> + db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null).use { cursor -> + generateSequence { if (cursor.moveToNext()) cursor.getString(0) else null }.toList() + } + } + println("V2 Database Tables: $tablesBefore") + // V2 Database Tables: [bdk_schemas, bdk_wallet, bdk_blocks, bdk_txs, bdk_txouts, bdk_anchors, bdk_descriptor_last_revealed, bdk_descriptor_derived_spks] + assertTrue(!tablesBefore.contains("bdk_wallet_locked_outpoints")) + + val wallet1 = Wallet.load( + descriptor = descriptor, + changeDescriptor = changeDescriptor, + persister = oldV1DB, + ) + + val addressInfoWallet1: AddressInfo = wallet1.revealNextAddress(KeychainKind.EXTERNAL) + val changeAddressInfoWallet1: AddressInfo = wallet1.revealNextAddress(KeychainKind.INTERNAL) + + assertEquals(addressInfoWallet1.index, 7u) + assertEquals(changeAddressInfoWallet1.index, 1u) + + wallet1.persist(oldV1DB) + + val tables: List = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READONLY).use { db -> + db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null).use { cursor -> + generateSequence { if (cursor.moveToNext()) cursor.getString(0) else null }.toList() + } + } + + println("V3 Database Tables: $tables") + // V3 Database Tables: [bdk_schemas, bdk_wallet, bdk_blocks, bdk_txs, bdk_txouts, bdk_anchors, bdk_descriptor_last_revealed, bdk_wallet_locked_outpoints, bdk_descriptor_derived_spks] + + assertTrue(tables.contains("bdk_wallet_locked_outpoints")) + } + + // The v3 wallet can load a v3 database + @Test + fun loadV3Wallet() { + val v3DB = Persister.newSqlite(resolveAsset("db_v3.sqlite3")) + + val wallet = Wallet.load( + descriptor = descriptor, + changeDescriptor = changeDescriptor, + persister = v3DB, + ) + + val addressInfo: AddressInfo = wallet.revealNextAddress(KeychainKind.EXTERNAL) + val changeAddressInfo: AddressInfo = wallet.revealNextAddress(KeychainKind.INTERNAL) + println("Address info: $addressInfo") + println("Change address info: $changeAddressInfo") + + assertEquals(addressInfo.index, 7u) + assertEquals(changeAddressInfo.index, 1u) + } + + // You can correctly migrate a v0.32 Wallet into a v3 Wallet + @Test + fun migrateToV3From032() { + val oldDB = Persister.newSqlite(resolveAsset("db_v032.sqlite3", "old_databases")) + val preV1Keychains: List = oldDB.getPreV1WalletKeychains() + + val externalPreV1Keychain = preV1Keychains.single { it.keychain == KeychainKind.EXTERNAL } + val internalPreV1Keychain = preV1Keychains.single { it.keychain == KeychainKind.INTERNAL } + + assertEquals(2, preV1Keychains.size) + assertEquals(KeychainKind.EXTERNAL, externalPreV1Keychain.keychain) + assertEquals(KeychainKind.INTERNAL, internalPreV1Keychain.keychain) + assertEquals(6u, externalPreV1Keychain.lastDerivationIndex) + assertEquals(0u, internalPreV1Keychain.lastDerivationIndex) + assertEquals("rn0zejch", externalPreV1Keychain.checksum) + assertEquals("j82ry8g0", internalPreV1Keychain.checksum) + + val newV3DBFilePath = context.getDatabasePath("new_v3_wallet.sqlite3") + newV3DBFilePath.parentFile?.mkdirs() + // This ensures local tests always create a new DB and don't reuse an old one leftover from prior tests + if (newV3DBFilePath.exists()) newV3DBFilePath.delete() + val newV3DB = Persister.newSqlite(newV3DBFilePath.absolutePath) + + val wallet = Wallet( + descriptor = descriptor, + changeDescriptor = changeDescriptor, + network = Network.REGTEST, + persister = newV3DB, + ) + + wallet.revealAddressesTo(KeychainKind.EXTERNAL, externalPreV1Keychain.lastDerivationIndex) + wallet.revealAddressesTo(KeychainKind.INTERNAL, internalPreV1Keychain.lastDerivationIndex) + wallet.persist(newV3DB) + + val reloadedWallet = Wallet.load( + descriptor = descriptor, + changeDescriptor = changeDescriptor, + persister = newV3DB, + ) + + val addressInfo: AddressInfo = reloadedWallet.revealNextAddress(KeychainKind.EXTERNAL) + val changeAddressInfo: AddressInfo = reloadedWallet.revealNextAddress(KeychainKind.INTERNAL) + + assertEquals(addressInfo.index, 7u) + assertEquals(changeAddressInfo.index, 1u) + } +} From 8f6a10bfdc99017cff64fda71cc7d65a748c21b1 Mon Sep 17 00:00:00 2001 From: thunderbiscuit Date: Wed, 27 May 2026 10:26:07 -0400 Subject: [PATCH 3/3] test: bump ci android API version to 34 --- .github/workflows/test-android.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-android.yaml b/.github/workflows/test-android.yaml index 5b335b3c..23b71358 100644 --- a/.github/workflows/test-android.yaml +++ b/.github/workflows/test-android.yaml @@ -83,7 +83,7 @@ jobs: - name: "Run Android connected tests" uses: reactivecircus/android-emulator-runner@v2 with: - api-level: 30 + api-level: 34 target: google_apis arch: x86_64 profile: Nexus 6