]> Untitled Git - bdk/commitdiff
feat(chain,wallet)!: publicize `.init_sqlite_tables` changeset methods
author志宇 <hello@evanlinjin.me>
Sun, 11 Aug 2024 08:50:54 +0000 (08:50 +0000)
committer志宇 <hello@evanlinjin.me>
Thu, 15 Aug 2024 04:12:39 +0000 (04:12 +0000)
Changeset methods `.persist_to_sqlite` and `from_sqlite` no longer
internally call `.init_sqlite_tables`. Instead, it is up to the caller
to call `.init_sqlite_tables` beforehand.

This allows us to utilize `WalletPersister::initialize`, instead of
calling `.init_sqlite_tables` every time we persist/load.

crates/chain/src/rusqlite_impl.rs
crates/wallet/src/wallet/changeset.rs
crates/wallet/src/wallet/persisted.rs
crates/wallet/tests/wallet.rs

index a52c491c626a8ad6ea96aabc3f85fc19edb62500..d8ef65c42b04a702fecd5c64c63791519b096987 100644 (file)
@@ -225,7 +225,7 @@ where
     pub const ANCHORS_TABLE_NAME: &'static str = "bdk_anchors";
 
     /// Initialize sqlite tables.
-    fn init_sqlite_tables(db_tx: &rusqlite::Transaction) -> rusqlite::Result<()> {
+    pub fn init_sqlite_tables(db_tx: &rusqlite::Transaction) -> rusqlite::Result<()> {
         let schema_v0: &[&str] = &[
             // full transactions
             &format!(
@@ -264,9 +264,9 @@ where
     }
 
     /// Construct a [`TxGraph`] from an sqlite database.
+    ///
+    /// Remember to call [`Self::init_sqlite_tables`] beforehand.
     pub fn from_sqlite(db_tx: &rusqlite::Transaction) -> rusqlite::Result<Self> {
-        Self::init_sqlite_tables(db_tx)?;
-
         let mut changeset = Self::default();
 
         let mut statement = db_tx.prepare(&format!(
@@ -332,9 +332,9 @@ where
     }
 
     /// Persist `changeset` to the sqlite database.
+    ///
+    /// Remember to call [`Self::init_sqlite_tables`] beforehand.
     pub fn persist_to_sqlite(&self, db_tx: &rusqlite::Transaction) -> rusqlite::Result<()> {
-        Self::init_sqlite_tables(db_tx)?;
-
         let mut statement = db_tx.prepare_cached(&format!(
             "INSERT INTO {}(txid, raw_tx) VALUES(:txid, :raw_tx) ON CONFLICT(txid) DO UPDATE SET raw_tx=:raw_tx",
             Self::TXS_TABLE_NAME,
@@ -396,7 +396,7 @@ impl local_chain::ChangeSet {
     pub const BLOCKS_TABLE_NAME: &'static str = "bdk_blocks";
 
     /// Initialize sqlite tables for persisting [`local_chain::LocalChain`].
-    fn init_sqlite_tables(db_tx: &rusqlite::Transaction) -> rusqlite::Result<()> {
+    pub fn init_sqlite_tables(db_tx: &rusqlite::Transaction) -> rusqlite::Result<()> {
         let schema_v0: &[&str] = &[
             // blocks
             &format!(
@@ -411,9 +411,9 @@ impl local_chain::ChangeSet {
     }
 
     /// Construct a [`LocalChain`](local_chain::LocalChain) from sqlite database.
+    ///
+    /// Remember to call [`Self::init_sqlite_tables`] beforehand.
     pub fn from_sqlite(db_tx: &rusqlite::Transaction) -> rusqlite::Result<Self> {
-        Self::init_sqlite_tables(db_tx)?;
-
         let mut changeset = Self::default();
 
         let mut statement = db_tx.prepare(&format!(
@@ -435,9 +435,9 @@ impl local_chain::ChangeSet {
     }
 
     /// Persist `changeset` to the sqlite database.
+    ///
+    /// Remember to call [`Self::init_sqlite_tables`] beforehand.
     pub fn persist_to_sqlite(&self, db_tx: &rusqlite::Transaction) -> rusqlite::Result<()> {
-        Self::init_sqlite_tables(db_tx)?;
-
         let mut replace_statement = db_tx.prepare_cached(&format!(
             "REPLACE INTO {}(block_height, block_hash) VALUES(:block_height, :block_hash)",
             Self::BLOCKS_TABLE_NAME,
@@ -471,7 +471,7 @@ impl keychain_txout::ChangeSet {
 
     /// Initialize sqlite tables for persisting
     /// [`KeychainTxOutIndex`](keychain_txout::KeychainTxOutIndex).
-    fn init_sqlite_tables(db_tx: &rusqlite::Transaction) -> rusqlite::Result<()> {
+    pub fn init_sqlite_tables(db_tx: &rusqlite::Transaction) -> rusqlite::Result<()> {
         let schema_v0: &[&str] = &[
             // last revealed
             &format!(
@@ -487,9 +487,9 @@ impl keychain_txout::ChangeSet {
 
     /// Construct [`KeychainTxOutIndex`](keychain_txout::KeychainTxOutIndex) from sqlite database
     /// and given parameters.
+    ///
+    /// Remember to call [`Self::init_sqlite_tables`] beforehand.
     pub fn from_sqlite(db_tx: &rusqlite::Transaction) -> rusqlite::Result<Self> {
-        Self::init_sqlite_tables(db_tx)?;
-
         let mut changeset = Self::default();
 
         let mut statement = db_tx.prepare(&format!(
@@ -511,9 +511,9 @@ impl keychain_txout::ChangeSet {
     }
 
     /// Persist `changeset` to the sqlite database.
+    ///
+    /// Remember to call [`Self::init_sqlite_tables`] beforehand.
     pub fn persist_to_sqlite(&self, db_tx: &rusqlite::Transaction) -> rusqlite::Result<()> {
-        Self::init_sqlite_tables(db_tx)?;
-
         let mut statement = db_tx.prepare_cached(&format!(
             "REPLACE INTO {}(descriptor_id, last_revealed) VALUES(:descriptor_id, :last_revealed)",
             Self::LAST_REVEALED_TABLE_NAME,
index 5f3b9b3dc1c877d99432617ea06c4176c3279f9f..2d4b700ed19e6053f66ddfe8fd19f382bc2755b6 100644 (file)
@@ -72,10 +72,8 @@ impl ChangeSet {
     /// Name of table to store wallet descriptors and network.
     pub const WALLET_TABLE_NAME: &'static str = "bdk_wallet";
 
-    /// Initialize sqlite tables for wallet schema & table.
-    fn init_wallet_sqlite_tables(
-        db_tx: &chain::rusqlite::Transaction,
-    ) -> chain::rusqlite::Result<()> {
+    /// Initialize sqlite tables for wallet tables.
+    pub fn init_sqlite_tables(db_tx: &chain::rusqlite::Transaction) -> chain::rusqlite::Result<()> {
         let schema_v0: &[&str] = &[&format!(
             "CREATE TABLE {} ( \
                 id INTEGER PRIMARY KEY NOT NULL CHECK (id = 0), \
@@ -85,12 +83,17 @@ impl ChangeSet {
                 ) STRICT;",
             Self::WALLET_TABLE_NAME,
         )];
-        crate::rusqlite_impl::migrate_schema(db_tx, Self::WALLET_SCHEMA_NAME, &[schema_v0])
+        crate::rusqlite_impl::migrate_schema(db_tx, Self::WALLET_SCHEMA_NAME, &[schema_v0])?;
+
+        bdk_chain::local_chain::ChangeSet::init_sqlite_tables(db_tx)?;
+        bdk_chain::tx_graph::ChangeSet::<ConfirmationBlockTime>::init_sqlite_tables(db_tx)?;
+        bdk_chain::keychain_txout::ChangeSet::init_sqlite_tables(db_tx)?;
+
+        Ok(())
     }
 
     /// Recover a [`ChangeSet`] from sqlite database.
     pub fn from_sqlite(db_tx: &chain::rusqlite::Transaction) -> chain::rusqlite::Result<Self> {
-        Self::init_wallet_sqlite_tables(db_tx)?;
         use chain::rusqlite::OptionalExtension;
         use chain::Impl;
 
@@ -129,7 +132,6 @@ impl ChangeSet {
         &self,
         db_tx: &chain::rusqlite::Transaction,
     ) -> chain::rusqlite::Result<()> {
-        Self::init_wallet_sqlite_tables(db_tx)?;
         use chain::rusqlite::named_params;
         use chain::Impl;
 
index a7181a3c08a4e3748e93860192d69ef1e7722000..bef34a1f359a682daf324456084afb8e5a348cb4 100644 (file)
@@ -237,6 +237,7 @@ impl<'c> WalletPersister for bdk_chain::rusqlite::Transaction<'c> {
     type Error = bdk_chain::rusqlite::Error;
 
     fn initialize(persister: &mut Self) -> Result<ChangeSet, Self::Error> {
+        ChangeSet::init_sqlite_tables(&*persister)?;
         ChangeSet::from_sqlite(persister)
     }
 
@@ -251,6 +252,7 @@ impl WalletPersister for bdk_chain::rusqlite::Connection {
 
     fn initialize(persister: &mut Self) -> Result<ChangeSet, Self::Error> {
         let db_tx = persister.transaction()?;
+        ChangeSet::init_sqlite_tables(&db_tx)?;
         let changeset = ChangeSet::from_sqlite(&db_tx)?;
         db_tx.commit()?;
         Ok(changeset)
@@ -299,7 +301,9 @@ impl WalletPersister for bdk_file_store::Store<ChangeSet> {
     }
 
     fn persist(persister: &mut Self, changeset: &ChangeSet) -> Result<(), Self::Error> {
-        persister.append_changeset(changeset).map_err(FileStoreError::Write)
+        persister
+            .append_changeset(changeset)
+            .map_err(FileStoreError::Write)
     }
 }
 
index 32b7a0f77d51e23b0b957e7abaa29375d87969d5..53edd821584a2da56321eaa7934a05cb03abdc03 100644 (file)
@@ -249,7 +249,11 @@ fn wallet_load_checks() -> anyhow::Result<()> {
 
     run(
         "store.db",
-        |path| Ok(bdk_file_store::Store::<ChangeSet>::create_new(DB_MAGIC, path)?),
+        |path| {
+            Ok(bdk_file_store::Store::<ChangeSet>::create_new(
+                DB_MAGIC, path,
+            )?)
+        },
         |path| Ok(bdk_file_store::Store::<ChangeSet>::open(DB_MAGIC, path)?),
     )?;
     run(