Skip to content

Commit

Permalink
Add more test to the database module
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
vladimirfomene committed Sep 7, 2022
1 parent 06310f1 commit d8f5026
Show file tree
Hide file tree
Showing 4 changed files with 314 additions and 2 deletions.
40 changes: 40 additions & 0 deletions src/database/keyvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}
40 changes: 40 additions & 0 deletions src/database/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}
196 changes: 194 additions & 2 deletions src/database/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;

Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -441,5 +458,180 @@ 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!(path, child);
}

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);
}

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);
}

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_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_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);
}

pub fn test_check_descriptor_checksum<D: Database>(mut db: D) {
let checksum = "1cead456".as_bytes();
let keychain = KeychainKind::External;
let _res = db.check_descriptor_checksum(keychain, checksum);

let checksum = "1cead454".as_bytes();
let keychain = KeychainKind::External;
let res = db.check_descriptor_checksum(keychain, checksum);

assert!(res.is_err());
}

// TODO: more tests...
}
40 changes: 40 additions & 0 deletions src/database/sqlite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1036,4 +1036,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());
}
}

0 comments on commit d8f5026

Please sign in to comment.