]> Untitled Git - bdk/commitdiff
Add more test to the database module
authorVladimir Fomene <vladimirfomene@gmail.com>
Wed, 7 Sep 2022 17:45:22 +0000 (20:45 +0300)
committerVladimir Fomene <vladimirfomene@gmail.com>
Tue, 13 Sep 2022 13:35:53 +0000 (16:35 +0300)
This PR aims to add more test to database
code so that we can catch bugs as soon
as they occur. Contributing to fixing
issue #699.

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

index e10ada1fa43f74a42d18a2424645a89b1d437cf3..f586ebeba820eaad612e3a76596bce7b4f7e72f5 100644 (file)
@@ -492,4 +492,44 @@ mod test {
     fn test_sync_time() {
         crate::database::test::test_sync_time(get_tree());
     }
+
+    #[test]
+    fn test_iter_raw_txs() {
+        crate::database::test::test_iter_raw_txs(get_tree());
+    }
+
+    #[test]
+    fn test_del_path_from_script_pubkey() {
+        crate::database::test::test_del_path_from_script_pubkey(get_tree());
+    }
+
+    #[test]
+    fn test_iter_script_pubkeys() {
+        crate::database::test::test_iter_script_pubkeys(get_tree());
+    }
+
+    #[test]
+    fn test_del_utxo() {
+        crate::database::test::test_del_utxo(get_tree());
+    }
+
+    #[test]
+    fn test_del_raw_tx() {
+        crate::database::test::test_del_raw_tx(get_tree());
+    }
+
+    #[test]
+    fn test_del_tx() {
+        crate::database::test::test_del_tx(get_tree());
+    }
+
+    #[test]
+    fn test_del_last_index() {
+        crate::database::test::test_del_last_index(get_tree());
+    }
+
+    #[test]
+    fn test_check_descriptor_checksum() {
+        crate::database::test::test_check_descriptor_checksum(get_tree());
+    }
 }
index eff5ecf148d60d070b63f43953a98ca69c83c25f..691e7eb16b8ba1c5a6bdf94d887b8c0481c46330 100644 (file)
@@ -647,4 +647,44 @@ mod test {
     fn test_sync_time() {
         crate::database::test::test_sync_time(get_tree());
     }
+
+    #[test]
+    fn test_iter_raw_txs() {
+        crate::database::test::test_iter_raw_txs(get_tree());
+    }
+
+    #[test]
+    fn test_del_path_from_script_pubkey() {
+        crate::database::test::test_del_path_from_script_pubkey(get_tree());
+    }
+
+    #[test]
+    fn test_iter_script_pubkeys() {
+        crate::database::test::test_iter_script_pubkeys(get_tree());
+    }
+
+    #[test]
+    fn test_del_utxo() {
+        crate::database::test::test_del_utxo(get_tree());
+    }
+
+    #[test]
+    fn test_del_raw_tx() {
+        crate::database::test::test_del_raw_tx(get_tree());
+    }
+
+    #[test]
+    fn test_del_tx() {
+        crate::database::test::test_del_tx(get_tree());
+    }
+
+    #[test]
+    fn test_del_last_index() {
+        crate::database::test::test_del_last_index(get_tree());
+    }
+
+    #[test]
+    fn test_check_descriptor_checksum() {
+        crate::database::test::test_check_descriptor_checksum(get_tree());
+    }
 }
index c7ff17951fcdb1ef40be60aa6f8fbdb846d42880..711dea7ef649a55713794ced6053a78e18f4591b 100644 (file)
@@ -217,6 +217,7 @@ pub mod test {
     use std::str::FromStr;
 
     use bitcoin::consensus::encode::deserialize;
+    use bitcoin::consensus::serialize;
     use bitcoin::hashes::hex::*;
     use bitcoin::*;
 
@@ -322,8 +323,24 @@ pub mod test {
     }
 
     pub fn test_raw_tx<D: Database>(mut tree: D) {
-        let hex_tx = Vec::<u8>::from_hex("0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000").unwrap();
-        let tx: Transaction = deserialize(&hex_tx).unwrap();
+        let hex_tx = Vec::<u8>::from_hex("02000000000101f58c18a90d7a76b30c7e47d4e817adfdd79a6a589a615ef36e360f913adce2cd0000000000feffffff0210270000000000001600145c9a1816d38db5cbdd4b067b689dc19eb7d930e2cf70aa2b080000001600140f48b63160043047f4f60f7f8f551f80458f693f024730440220413f42b7bc979945489a38f5221e5527d4b8e3aa63eae2099e01945896ad6c10022024ceec492d685c31d8adb64e935a06933877c5ae0e21f32efe029850914c5bad012102361caae96f0e9f3a453d354bb37a5c3244422fb22819bf0166c0647a38de39f21fca2300").unwrap();
+        let mut tx: Transaction = deserialize(&hex_tx).unwrap();
+
+        tree.set_raw_tx(&tx).unwrap();
+
+        let txid = tx.txid();
+
+        assert_eq!(tree.get_raw_tx(&txid).unwrap(), Some(tx.clone()));
+
+        // mutate transaction's witnesses
+        for tx_in in tx.input.iter_mut() {
+            tx_in.witness = Witness::new();
+        }
+
+        let updated_hex_tx = serialize(&tx);
+
+        // verify that mutation was successful
+        assert_ne!(hex_tx, updated_hex_tx);
 
         tree.set_raw_tx(&tx).unwrap();
 
@@ -441,5 +458,203 @@ pub mod test {
         assert!(tree.get_sync_time().unwrap().is_none());
     }
 
+    pub fn test_iter_raw_txs<D: Database>(mut db: D) {
+        let txs = db.iter_raw_txs().unwrap();
+        assert!(txs.is_empty());
+
+        let hex_tx = Vec::<u8>::from_hex("0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000").unwrap();
+        let first_tx: Transaction = deserialize(&hex_tx).unwrap();
+
+        let hex_tx = Vec::<u8>::from_hex("02000000000101f58c18a90d7a76b30c7e47d4e817adfdd79a6a589a615ef36e360f913adce2cd0000000000feffffff0210270000000000001600145c9a1816d38db5cbdd4b067b689dc19eb7d930e2cf70aa2b080000001600140f48b63160043047f4f60f7f8f551f80458f693f024730440220413f42b7bc979945489a38f5221e5527d4b8e3aa63eae2099e01945896ad6c10022024ceec492d685c31d8adb64e935a06933877c5ae0e21f32efe029850914c5bad012102361caae96f0e9f3a453d354bb37a5c3244422fb22819bf0166c0647a38de39f21fca2300").unwrap();
+        let second_tx: Transaction = deserialize(&hex_tx).unwrap();
+
+        db.set_raw_tx(&first_tx).unwrap();
+        db.set_raw_tx(&second_tx).unwrap();
+
+        let txs = db.iter_raw_txs().unwrap();
+
+        assert!(txs.contains(&first_tx));
+        assert!(txs.contains(&second_tx));
+        assert_eq!(txs.len(), 2);
+    }
+
+    pub fn test_del_path_from_script_pubkey<D: Database>(mut db: D) {
+        let keychain = KeychainKind::External;
+
+        let script = Script::from(
+            Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
+        );
+        let path = 42;
+
+        let res = db.del_path_from_script_pubkey(&script).unwrap();
+
+        assert!(res.is_none());
+
+        let _res = db.set_script_pubkey(&script, keychain, path);
+        let (chain, child) = db.del_path_from_script_pubkey(&script).unwrap().unwrap();
+
+        assert_eq!(chain, keychain);
+        assert_eq!(child, path);
+
+        let res = db.get_path_from_script_pubkey(&script).unwrap();
+        assert!(res.is_none());
+    }
+
+    pub fn test_iter_script_pubkeys<D: Database>(mut db: D) {
+        let keychain = KeychainKind::External;
+        let scripts = db.iter_script_pubkeys(Some(keychain)).unwrap();
+        assert!(scripts.is_empty());
+
+        let first_script = Script::from(
+            Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
+        );
+        let path = 42;
+
+        db.set_script_pubkey(&first_script, keychain, path).unwrap();
+
+        let second_script = Script::from(
+            Vec::<u8>::from_hex("00145c9a1816d38db5cbdd4b067b689dc19eb7d930e2").unwrap(),
+        );
+        let path = 57;
+
+        db.set_script_pubkey(&second_script, keychain, path)
+            .unwrap();
+        let scripts = db.iter_script_pubkeys(Some(keychain)).unwrap();
+
+        assert!(scripts.contains(&first_script));
+        assert!(scripts.contains(&second_script));
+        assert_eq!(scripts.len(), 2);
+    }
+
+    pub fn test_del_utxo<D: Database>(mut db: D) {
+        let outpoint = OutPoint::from_str(
+            "5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:0",
+        )
+        .unwrap();
+        let script = Script::from(
+            Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
+        );
+        let txout = TxOut {
+            value: 133742,
+            script_pubkey: script,
+        };
+        let utxo = LocalUtxo {
+            txout,
+            outpoint,
+            keychain: KeychainKind::External,
+            is_spent: true,
+        };
+
+        let res = db.del_utxo(&outpoint).unwrap();
+        assert!(res.is_none());
+
+        db.set_utxo(&utxo).unwrap();
+
+        let res = db.del_utxo(&outpoint).unwrap();
+
+        assert_eq!(res.unwrap(), utxo);
+
+        let res = db.get_utxo(&outpoint).unwrap();
+        assert!(res.is_none());
+    }
+
+    pub fn test_del_raw_tx<D: Database>(mut db: D) {
+        let hex_tx = Vec::<u8>::from_hex("02000000000101f58c18a90d7a76b30c7e47d4e817adfdd79a6a589a615ef36e360f913adce2cd0000000000feffffff0210270000000000001600145c9a1816d38db5cbdd4b067b689dc19eb7d930e2cf70aa2b080000001600140f48b63160043047f4f60f7f8f551f80458f693f024730440220413f42b7bc979945489a38f5221e5527d4b8e3aa63eae2099e01945896ad6c10022024ceec492d685c31d8adb64e935a06933877c5ae0e21f32efe029850914c5bad012102361caae96f0e9f3a453d354bb37a5c3244422fb22819bf0166c0647a38de39f21fca2300").unwrap();
+        let tx: Transaction = deserialize(&hex_tx).unwrap();
+
+        let res = db.del_raw_tx(&tx.txid()).unwrap();
+
+        assert!(res.is_none());
+
+        db.set_raw_tx(&tx).unwrap();
+
+        let res = db.del_raw_tx(&tx.txid()).unwrap();
+
+        assert_eq!(res.unwrap(), tx);
+
+        let res = db.get_raw_tx(&tx.txid()).unwrap();
+        assert!(res.is_none());
+    }
+
+    pub fn test_del_tx<D: Database>(mut db: D) {
+        let hex_tx = Vec::<u8>::from_hex("0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000").unwrap();
+        let tx: Transaction = deserialize(&hex_tx).unwrap();
+        let txid = tx.txid();
+        let mut tx_details = TransactionDetails {
+            transaction: Some(tx.clone()),
+            txid,
+            received: 1337,
+            sent: 420420,
+            fee: Some(140),
+            confirmation_time: Some(BlockTime {
+                timestamp: 123456,
+                height: 1000,
+            }),
+        };
+
+        let res = db.del_tx(&tx.txid(), true).unwrap();
+
+        assert!(res.is_none());
+
+        db.set_tx(&tx_details).unwrap();
+
+        let res = db.del_tx(&tx.txid(), false).unwrap();
+        tx_details.transaction = None;
+        assert_eq!(res.unwrap(), tx_details);
+
+        let res = db.get_tx(&tx.txid(), true).unwrap();
+        assert!(res.is_none());
+
+        let res = db.get_raw_tx(&tx.txid()).unwrap();
+        assert_eq!(res.unwrap(), tx);
+
+        db.set_tx(&tx_details).unwrap();
+        let res = db.del_tx(&tx.txid(), true).unwrap();
+        tx_details.transaction = Some(tx.clone());
+        assert_eq!(res.unwrap(), tx_details);
+
+        let res = db.get_tx(&tx.txid(), true).unwrap();
+        assert!(res.is_none());
+
+        let res = db.get_raw_tx(&tx.txid()).unwrap();
+        assert!(res.is_none());
+    }
+
+    pub fn test_del_last_index<D: Database>(mut db: D) {
+        let keychain = KeychainKind::External;
+
+        let _res = db.increment_last_index(keychain);
+
+        let res = db.get_last_index(keychain).unwrap().unwrap();
+
+        assert_eq!(res, 0);
+
+        let _res = db.increment_last_index(keychain);
+
+        let res = db.del_last_index(keychain).unwrap().unwrap();
+
+        assert_eq!(res, 1);
+
+        let res = db.get_last_index(keychain).unwrap();
+        assert!(res.is_none());
+    }
+
+    pub fn test_check_descriptor_checksum<D: Database>(mut db: D) {
+        // insert checksum associated to keychain
+        let checksum = "1cead456".as_bytes();
+        let keychain = KeychainKind::External;
+        let _res = db.check_descriptor_checksum(keychain, checksum);
+
+        // check if `check_descriptor_checksum` throws
+        // `Error::ChecksumMismatch` error if the
+        // function is passed a checksum that does
+        // not match the one initially inserted
+        let checksum = "1cead454".as_bytes();
+        let keychain = KeychainKind::External;
+        let res = db.check_descriptor_checksum(keychain, checksum);
+
+        assert!(res.is_err());
+    }
+
     // TODO: more tests...
 }
index a9cbe1a7e729685045c344b6b0c3e713ed686ee0..bec6dd48716df649f9f06c6ccf9d0c86cd27efba 100644 (file)
@@ -1038,4 +1038,44 @@ pub mod test {
     fn test_txs() {
         crate::database::test::test_list_transaction(get_database());
     }
+
+    #[test]
+    fn test_iter_raw_txs() {
+        crate::database::test::test_iter_raw_txs(get_database());
+    }
+
+    #[test]
+    fn test_del_path_from_script_pubkey() {
+        crate::database::test::test_del_path_from_script_pubkey(get_database());
+    }
+
+    #[test]
+    fn test_iter_script_pubkeys() {
+        crate::database::test::test_iter_script_pubkeys(get_database());
+    }
+
+    #[test]
+    fn test_del_utxo() {
+        crate::database::test::test_del_utxo(get_database());
+    }
+
+    #[test]
+    fn test_del_raw_tx() {
+        crate::database::test::test_del_raw_tx(get_database());
+    }
+
+    #[test]
+    fn test_del_tx() {
+        crate::database::test::test_del_tx(get_database());
+    }
+
+    #[test]
+    fn test_del_last_index() {
+        crate::database::test::test_del_last_index(get_database());
+    }
+
+    #[test]
+    fn test_check_descriptor_checksum() {
+        crate::database::test::test_check_descriptor_checksum(get_database());
+    }
 }