]> Untitled Git - bdk/commitdiff
[database] Wrap `BlockTime` in another struct to allow adding more
authorAlekos Filini <alekos.filini@gmail.com>
Thu, 4 Nov 2021 15:38:38 +0000 (15:38 +0000)
committerAlekos Filini <alekos.filini@gmail.com>
Wed, 10 Nov 2021 11:30:42 +0000 (12:30 +0100)
fields in the future

src/database/any.rs
src/database/keyvalue.rs
src/database/memory.rs
src/database/mod.rs
src/database/sqlite.rs
src/wallet/mod.rs

index a608daca354d9c64e3832d2260d7a59de1dabd18..8b626e4b71a6bbb83d532b357fbf65c512bc3028 100644 (file)
@@ -144,8 +144,8 @@ impl BatchOperations for AnyDatabase {
     fn set_last_index(&mut self, keychain: KeychainKind, value: u32) -> Result<(), Error> {
         impl_inner_method!(AnyDatabase, self, set_last_index, keychain, value)
     }
-    fn set_last_sync_time(&mut self, last_sync_time: BlockTime) -> Result<(), Error> {
-        impl_inner_method!(AnyDatabase, self, set_last_sync_time, last_sync_time)
+    fn set_sync_time(&mut self, sync_time: SyncTime) -> Result<(), Error> {
+        impl_inner_method!(AnyDatabase, self, set_sync_time, sync_time)
     }
 
     fn del_script_pubkey_from_path(
@@ -183,8 +183,8 @@ impl BatchOperations for AnyDatabase {
     fn del_last_index(&mut self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
         impl_inner_method!(AnyDatabase, self, del_last_index, keychain)
     }
-    fn del_last_sync_time(&mut self) -> Result<Option<BlockTime>, Error> {
-        impl_inner_method!(AnyDatabase, self, del_last_sync_time)
+    fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error> {
+        impl_inner_method!(AnyDatabase, self, del_sync_time)
     }
 }
 
@@ -247,8 +247,8 @@ impl Database for AnyDatabase {
     fn get_last_index(&self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
         impl_inner_method!(AnyDatabase, self, get_last_index, keychain)
     }
-    fn get_last_sync_time(&self) -> Result<Option<BlockTime>, Error> {
-        impl_inner_method!(AnyDatabase, self, get_last_sync_time)
+    fn get_sync_time(&self) -> Result<Option<SyncTime>, Error> {
+        impl_inner_method!(AnyDatabase, self, get_sync_time)
     }
 
     fn increment_last_index(&mut self, keychain: KeychainKind) -> Result<u32, Error> {
@@ -281,8 +281,8 @@ impl BatchOperations for AnyBatch {
     fn set_last_index(&mut self, keychain: KeychainKind, value: u32) -> Result<(), Error> {
         impl_inner_method!(AnyBatch, self, set_last_index, keychain, value)
     }
-    fn set_last_sync_time(&mut self, last_sync_time: BlockTime) -> Result<(), Error> {
-        impl_inner_method!(AnyBatch, self, set_last_sync_time, last_sync_time)
+    fn set_sync_time(&mut self, sync_time: SyncTime) -> Result<(), Error> {
+        impl_inner_method!(AnyBatch, self, set_sync_time, sync_time)
     }
 
     fn del_script_pubkey_from_path(
@@ -314,8 +314,8 @@ impl BatchOperations for AnyBatch {
     fn del_last_index(&mut self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
         impl_inner_method!(AnyBatch, self, del_last_index, keychain)
     }
-    fn del_last_sync_time(&mut self) -> Result<Option<BlockTime>, Error> {
-        impl_inner_method!(AnyBatch, self, del_last_sync_time)
+    fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error> {
+        impl_inner_method!(AnyBatch, self, del_sync_time)
     }
 }
 
index 976c3856b5c4ee0f7f33c320b357c6d769dc0517..07499e9f19399b84dab676837ec1bf5d9b1d16ac 100644 (file)
@@ -18,7 +18,7 @@ use bitcoin::hash_types::Txid;
 use bitcoin::{OutPoint, Script, Transaction};
 
 use crate::database::memory::MapKey;
-use crate::database::{BatchDatabase, BatchOperations, Database};
+use crate::database::{BatchDatabase, BatchOperations, Database, SyncTime};
 use crate::error::Error;
 use crate::types::*;
 
@@ -82,9 +82,9 @@ macro_rules! impl_batch_operations {
             Ok(())
         }
 
-        fn set_last_sync_time(&mut self, ct: BlockTime) -> Result<(), Error> {
-            let key = MapKey::LastSyncTime.as_map_key();
-            self.insert(key, serde_json::to_vec(&ct)?)$($after_insert)*;
+        fn set_sync_time(&mut self, data: SyncTime) -> Result<(), Error> {
+            let key = MapKey::SyncTime.as_map_key();
+            self.insert(key, serde_json::to_vec(&data)?)$($after_insert)*;
 
             Ok(())
         }
@@ -176,8 +176,8 @@ macro_rules! impl_batch_operations {
             }
         }
 
-        fn del_last_sync_time(&mut self) -> Result<Option<BlockTime>, Error> {
-            let key = MapKey::LastSyncTime.as_map_key();
+        fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error> {
+            let key = MapKey::SyncTime.as_map_key();
             let res = self.remove(key);
             let res = $process_delete!(res);
 
@@ -357,8 +357,8 @@ impl Database for Tree {
             .transpose()
     }
 
-    fn get_last_sync_time(&self) -> Result<Option<BlockTime>, Error> {
-        let key = MapKey::LastSyncTime.as_map_key();
+    fn get_sync_time(&self) -> Result<Option<SyncTime>, Error> {
+        let key = MapKey::SyncTime.as_map_key();
         Ok(self
             .get(key)?
             .map(|b| serde_json::from_slice(&b))
@@ -495,7 +495,7 @@ mod test {
     }
 
     #[test]
-    fn test_last_sync_time() {
-        crate::database::test::test_last_sync_time(get_tree());
+    fn test_sync_time() {
+        crate::database::test::test_sync_time(get_tree());
     }
 }
index 35b3283a4eca06a06ed91e8590d339eff1a298a3..e828dc9df44c7b4eef93456f7d83d0a47cb47508 100644 (file)
@@ -22,7 +22,7 @@ use bitcoin::consensus::encode::{deserialize, serialize};
 use bitcoin::hash_types::Txid;
 use bitcoin::{OutPoint, Script, Transaction};
 
-use crate::database::{BatchDatabase, BatchOperations, ConfigurableDatabase, Database};
+use crate::database::{BatchDatabase, BatchOperations, ConfigurableDatabase, Database, SyncTime};
 use crate::error::Error;
 use crate::types::*;
 
@@ -42,7 +42,7 @@ pub(crate) enum MapKey<'a> {
     RawTx(Option<&'a Txid>),
     Transaction(Option<&'a Txid>),
     LastIndex(KeychainKind),
-    LastSyncTime,
+    SyncTime,
     DescriptorChecksum(KeychainKind),
 }
 
@@ -61,7 +61,7 @@ impl MapKey<'_> {
             MapKey::RawTx(_) => b"r".to_vec(),
             MapKey::Transaction(_) => b"t".to_vec(),
             MapKey::LastIndex(st) => [b"c", st.as_ref()].concat(),
-            MapKey::LastSyncTime => b"l".to_vec(),
+            MapKey::SyncTime => b"l".to_vec(),
             MapKey::DescriptorChecksum(st) => [b"d", st.as_ref()].concat(),
         }
     }
@@ -183,9 +183,9 @@ impl BatchOperations for MemoryDatabase {
 
         Ok(())
     }
-    fn set_last_sync_time(&mut self, ct: BlockTime) -> Result<(), Error> {
-        let key = MapKey::LastSyncTime.as_map_key();
-        self.map.insert(key, Box::new(ct));
+    fn set_sync_time(&mut self, data: SyncTime) -> Result<(), Error> {
+        let key = MapKey::SyncTime.as_map_key();
+        self.map.insert(key, Box::new(data));
 
         Ok(())
     }
@@ -279,8 +279,8 @@ impl BatchOperations for MemoryDatabase {
             Some(b) => Ok(Some(*b.downcast_ref().unwrap())),
         }
     }
-    fn del_last_sync_time(&mut self) -> Result<Option<BlockTime>, Error> {
-        let key = MapKey::LastSyncTime.as_map_key();
+    fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error> {
+        let key = MapKey::SyncTime.as_map_key();
         let res = self.map.remove(&key);
         self.deleted_keys.push(key);
 
@@ -423,8 +423,8 @@ impl Database for MemoryDatabase {
         Ok(self.map.get(&key).map(|b| *b.downcast_ref().unwrap()))
     }
 
-    fn get_last_sync_time(&self) -> Result<Option<BlockTime>, Error> {
-        let key = MapKey::LastSyncTime.as_map_key();
+    fn get_sync_time(&self) -> Result<Option<SyncTime>, Error> {
+        let key = MapKey::SyncTime.as_map_key();
         Ok(self
             .map
             .get(&key)
@@ -503,12 +503,10 @@ macro_rules! populate_test_db {
         };
 
         let txid = tx.txid();
-        let confirmation_time = tx_meta
-            .min_confirmations
-            .map(|conf| $crate::BlockTime {
-                height: current_height.unwrap().checked_sub(conf as u32).unwrap(),
-                timestamp: 0,
-            });
+        let confirmation_time = tx_meta.min_confirmations.map(|conf| $crate::BlockTime {
+            height: current_height.unwrap().checked_sub(conf as u32).unwrap(),
+            timestamp: 0,
+        });
 
         let tx_details = $crate::TransactionDetails {
             transaction: Some(tx.clone()),
@@ -616,7 +614,7 @@ mod test {
     }
 
     #[test]
-    fn test_last_sync_time() {
-        crate::database::test::test_last_sync_time(get_tree());
+    fn test_sync_time() {
+        crate::database::test::test_sync_time(get_tree());
     }
 }
index a73d45b9a1ddb4580e067a0e6c7d0084a7c29424..e160b7422be040bcaa922ca876e5b456d80d7e16 100644 (file)
@@ -24,6 +24,8 @@
 //!
 //! [`Wallet`]: crate::wallet::Wallet
 
+use serde::{Deserialize, Serialize};
+
 use bitcoin::hash_types::Txid;
 use bitcoin::{OutPoint, Script, Transaction, TxOut};
 
@@ -44,6 +46,15 @@ pub use sqlite::SqliteDatabase;
 pub mod memory;
 pub use memory::MemoryDatabase;
 
+/// Blockchain state at the time of syncing
+///
+/// Contains only the block time and height at the moment
+#[derive(Clone, Debug, Serialize, Deserialize)]
+pub struct SyncTime {
+    /// Block timestamp and height at the time of sync
+    pub block_time: BlockTime,
+}
+
 /// Trait for operations that can be batched
 ///
 /// This trait defines the list of operations that must be implemented on the [`Database`] type and
@@ -64,8 +75,8 @@ pub trait BatchOperations {
     fn set_tx(&mut self, transaction: &TransactionDetails) -> Result<(), Error>;
     /// Store the last derivation index for a given keychain.
     fn set_last_index(&mut self, keychain: KeychainKind, value: u32) -> Result<(), Error>;
-    /// Store the sync time in terms of block height and timestamp
-    fn set_last_sync_time(&mut self, last_sync_time: BlockTime) -> Result<(), Error>;
+    /// Store the sync time
+    fn set_sync_time(&mut self, sync_time: SyncTime) -> Result<(), Error>;
 
     /// Delete a script_pubkey given the keychain and its child number.
     fn del_script_pubkey_from_path(
@@ -91,10 +102,10 @@ pub trait BatchOperations {
     ) -> Result<Option<TransactionDetails>, Error>;
     /// Delete the last derivation index for a keychain.
     fn del_last_index(&mut self, keychain: KeychainKind) -> Result<Option<u32>, Error>;
-    /// Reset the last sync time to `None`
+    /// Reset the sync time to `None`
     ///
     /// Returns the removed value
-    fn del_last_sync_time(&mut self) -> Result<Option<BlockTime>, Error>;
+    fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error>;
 }
 
 /// Trait for reading data from a database
@@ -140,8 +151,8 @@ pub trait Database: BatchOperations {
     fn get_tx(&self, txid: &Txid, include_raw: bool) -> Result<Option<TransactionDetails>, Error>;
     /// Return the last defivation index for a keychain.
     fn get_last_index(&self, keychain: KeychainKind) -> Result<Option<u32>, Error>;
-    /// Return the last sync time, if present
-    fn get_last_sync_time(&self) -> Result<Option<BlockTime>, Error>;
+    /// Return the sync time, if present
+    fn get_sync_time(&self) -> Result<Option<SyncTime>, Error>;
 
     /// Increment the last derivation index for a keychain and return it
     ///
@@ -385,22 +396,24 @@ pub mod test {
         );
     }
 
-    pub fn test_last_sync_time<D: Database>(mut tree: D) {
-        assert!(tree.get_last_sync_time().unwrap().is_none());
+    pub fn test_sync_time<D: Database>(mut tree: D) {
+        assert!(tree.get_sync_time().unwrap().is_none());
 
-        tree.set_last_sync_time(BlockTime {
-            height: 100,
-            timestamp: 1000,
+        tree.set_sync_time(SyncTime {
+            block_time: BlockTime {
+                height: 100,
+                timestamp: 1000,
+            },
         })
         .unwrap();
 
-        let extracted = tree.get_last_sync_time().unwrap();
+        let extracted = tree.get_sync_time().unwrap();
         assert!(extracted.is_some());
-        assert_eq!(extracted.as_ref().unwrap().height, 100);
-        assert_eq!(extracted.as_ref().unwrap().timestamp, 1000);
+        assert_eq!(extracted.as_ref().unwrap().block_time.height, 100);
+        assert_eq!(extracted.as_ref().unwrap().block_time.timestamp, 1000);
 
-        tree.del_last_sync_time().unwrap();
-        assert!(tree.get_last_sync_time().unwrap().is_none());
+        tree.del_sync_time().unwrap();
+        assert!(tree.get_sync_time().unwrap().is_none());
     }
 
     // TODO: more tests...
index 6394f7447a9cdf540d13ea64ffaf4bd7104686de..597ef65488ef4d9da4535624f11ec0bfa3f8a2c8 100644 (file)
@@ -13,7 +13,7 @@ use bitcoin::consensus::encode::{deserialize, serialize};
 use bitcoin::hash_types::Txid;
 use bitcoin::{OutPoint, Script, Transaction, TxOut};
 
-use crate::database::{BatchDatabase, BatchOperations, Database};
+use crate::database::{BatchDatabase, BatchOperations, Database, SyncTime};
 use crate::error::Error;
 use crate::types::*;
 
@@ -35,7 +35,7 @@ static MIGRATIONS: &[&str] = &[
     "CREATE UNIQUE INDEX idx_indices_keychain ON last_derivation_indices(keychain);",
     "CREATE TABLE checksums (keychain TEXT, checksum BLOB);",
     "CREATE INDEX idx_checksums_keychain ON checksums(keychain);",
-    "CREATE TABLE last_sync_time (id INTEGER PRIMARY KEY, height INTEGER, timestamp INTEGER);"
+    "CREATE TABLE sync_time (id INTEGER PRIMARY KEY, height INTEGER, timestamp INTEGER);"
 ];
 
 /// Sqlite database stored on filesystem
@@ -206,14 +206,14 @@ impl SqliteDatabase {
         Ok(())
     }
 
-    fn update_last_sync_time(&self, ct: BlockTime) -> Result<i64, Error> {
+    fn update_sync_time(&self, data: SyncTime) -> Result<i64, Error> {
         let mut statement = self.connection.prepare_cached(
-            "INSERT INTO last_sync_time (id, height, timestamp) VALUES (0, :height, :timestamp) ON CONFLICT(id) DO UPDATE SET height=:height, timestamp=:timestamp WHERE id = 0",
+            "INSERT INTO sync_time (id, height, timestamp) VALUES (0, :height, :timestamp) ON CONFLICT(id) DO UPDATE SET height=:height, timestamp=:timestamp WHERE id = 0",
         )?;
 
         statement.execute(named_params! {
-            ":height": ct.height,
-            ":timestamp": ct.timestamp,
+            ":height": data.block_time.height,
+            ":timestamp": data.block_time.timestamp,
         })?;
 
         Ok(self.connection.last_insert_rowid())
@@ -501,18 +501,22 @@ impl SqliteDatabase {
         }
     }
 
-    fn select_last_sync_time(&self) -> Result<Option<BlockTime>, Error> {
+    fn select_sync_time(&self) -> Result<Option<SyncTime>, Error> {
         let mut statement = self
             .connection
-            .prepare_cached("SELECT height, timestamp FROM last_sync_time WHERE id = 0")?;
-        let mut rows = statement.query_map([], |row| {
-            Ok(BlockTime {
-                height: row.get(0)?,
-                timestamp: row.get(1)?,
-            })
-        })?;
+            .prepare_cached("SELECT height, timestamp FROM sync_time WHERE id = 0")?;
+        let mut rows = statement.query([])?;
 
-        Ok(rows.next().transpose()?)
+        if let Some(row) = rows.next()? {
+            Ok(Some(SyncTime {
+                block_time: BlockTime {
+                    height: row.get(0)?,
+                    timestamp: row.get(1)?,
+                },
+            }))
+        } else {
+            Ok(None)
+        }
     }
 
     fn select_checksum_by_keychain(&self, keychain: String) -> Result<Option<Vec<u8>>, Error> {
@@ -592,10 +596,10 @@ impl SqliteDatabase {
         Ok(())
     }
 
-    fn delete_last_sync_time(&self) -> Result<(), Error> {
+    fn delete_sync_time(&self) -> Result<(), Error> {
         let mut statement = self
             .connection
-            .prepare_cached("DELETE FROM last_sync_time WHERE id = 0")?;
+            .prepare_cached("DELETE FROM sync_time WHERE id = 0")?;
         statement.execute([])?;
         Ok(())
     }
@@ -658,8 +662,8 @@ impl BatchOperations for SqliteDatabase {
         Ok(())
     }
 
-    fn set_last_sync_time(&mut self, ct: BlockTime) -> Result<(), Error> {
-        self.update_last_sync_time(ct)?;
+    fn set_sync_time(&mut self, ct: SyncTime) -> Result<(), Error> {
+        self.update_sync_time(ct)?;
         Ok(())
     }
 
@@ -749,10 +753,10 @@ impl BatchOperations for SqliteDatabase {
         }
     }
 
-    fn del_last_sync_time(&mut self) -> Result<Option<BlockTime>, Error> {
-        match self.select_last_sync_time()? {
+    fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error> {
+        match self.select_sync_time()? {
             Some(value) => {
-                self.delete_last_sync_time()?;
+                self.delete_sync_time()?;
 
                 Ok(Some(value))
             }
@@ -870,8 +874,8 @@ impl Database for SqliteDatabase {
         Ok(value)
     }
 
-    fn get_last_sync_time(&self) -> Result<Option<BlockTime>, Error> {
-        self.select_last_sync_time()
+    fn get_sync_time(&self) -> Result<Option<SyncTime>, Error> {
+        self.select_sync_time()
     }
 
     fn increment_last_index(&mut self, keychain: KeychainKind) -> Result<u32, Error> {
@@ -1023,7 +1027,7 @@ pub mod test {
     }
 
     #[test]
-    fn test_last_sync_time() {
-        crate::database::test::test_last_sync_time(get_database());
+    fn test_sync_time() {
+        crate::database::test::test_sync_time(get_database());
     }
 }
index 5ae46e992120078a8b909e7aa709fb36f41f507f..d5a6cb30e2a011077b6edd0edd3f5d7abdb49217 100644 (file)
@@ -57,7 +57,7 @@ use utils::{check_nlocktime, check_nsequence_rbf, After, Older, SecpCtx, DUST_LI
 
 use crate::blockchain::{Blockchain, Progress};
 use crate::database::memory::MemoryDatabase;
-use crate::database::{BatchDatabase, BatchOperations, DatabaseUtils};
+use crate::database::{BatchDatabase, BatchOperations, DatabaseUtils, SyncTime};
 use crate::descriptor::derived::AsDerived;
 use crate::descriptor::policy::BuildSatisfaction;
 use crate::descriptor::{
@@ -1554,14 +1554,14 @@ where
             }
         }
 
-        let last_sync_time = BlockTime {
-            height: maybe_await!(self.client.get_height())?,
-            timestamp: time::get_timestamp(),
+        let sync_time = SyncTime {
+            block_time: BlockTime {
+                height: maybe_await!(self.client.get_height())?,
+                timestamp: time::get_timestamp(),
+            },
         };
-        debug!("Saving `last_sync_time` = {:?}", last_sync_time);
-        self.database
-            .borrow_mut()
-            .set_last_sync_time(last_sync_time)?;
+        debug!("Saving `sync_time` = {:?}", sync_time);
+        self.database.borrow_mut().set_sync_time(sync_time)?;
 
         Ok(())
     }