Skip to content

Commit 8830704

Browse files
Add more test to the database module
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.
1 parent e06c3f9 commit 8830704

File tree

4 files changed

+337
-2
lines changed

4 files changed

+337
-2
lines changed

src/database/keyvalue.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,4 +492,44 @@ mod test {
492492
fn test_sync_time() {
493493
crate::database::test::test_sync_time(get_tree());
494494
}
495+
496+
#[test]
497+
fn test_iter_raw_txs() {
498+
crate::database::test::test_iter_raw_txs(get_tree());
499+
}
500+
501+
#[test]
502+
fn test_del_path_from_script_pubkey() {
503+
crate::database::test::test_del_path_from_script_pubkey(get_tree());
504+
}
505+
506+
#[test]
507+
fn test_iter_script_pubkeys() {
508+
crate::database::test::test_iter_script_pubkeys(get_tree());
509+
}
510+
511+
#[test]
512+
fn test_del_utxo() {
513+
crate::database::test::test_del_utxo(get_tree());
514+
}
515+
516+
#[test]
517+
fn test_del_raw_tx() {
518+
crate::database::test::test_del_raw_tx(get_tree());
519+
}
520+
521+
#[test]
522+
fn test_del_tx() {
523+
crate::database::test::test_del_tx(get_tree());
524+
}
525+
526+
#[test]
527+
fn test_del_last_index() {
528+
crate::database::test::test_del_last_index(get_tree());
529+
}
530+
531+
#[test]
532+
fn test_check_descriptor_checksum() {
533+
crate::database::test::test_check_descriptor_checksum(get_tree());
534+
}
495535
}

src/database/memory.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,4 +647,44 @@ mod test {
647647
fn test_sync_time() {
648648
crate::database::test::test_sync_time(get_tree());
649649
}
650+
651+
#[test]
652+
fn test_iter_raw_txs() {
653+
crate::database::test::test_iter_raw_txs(get_tree());
654+
}
655+
656+
#[test]
657+
fn test_del_path_from_script_pubkey() {
658+
crate::database::test::test_del_path_from_script_pubkey(get_tree());
659+
}
660+
661+
#[test]
662+
fn test_iter_script_pubkeys() {
663+
crate::database::test::test_iter_script_pubkeys(get_tree());
664+
}
665+
666+
#[test]
667+
fn test_del_utxo() {
668+
crate::database::test::test_del_utxo(get_tree());
669+
}
670+
671+
#[test]
672+
fn test_del_raw_tx() {
673+
crate::database::test::test_del_raw_tx(get_tree());
674+
}
675+
676+
#[test]
677+
fn test_del_tx() {
678+
crate::database::test::test_del_tx(get_tree());
679+
}
680+
681+
#[test]
682+
fn test_del_last_index() {
683+
crate::database::test::test_del_last_index(get_tree());
684+
}
685+
686+
#[test]
687+
fn test_check_descriptor_checksum() {
688+
crate::database::test::test_check_descriptor_checksum(get_tree());
689+
}
650690
}

src/database/mod.rs

Lines changed: 217 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ pub mod test {
217217
use std::str::FromStr;
218218

219219
use bitcoin::consensus::encode::deserialize;
220+
use bitcoin::consensus::serialize;
220221
use bitcoin::hashes::hex::*;
221222
use bitcoin::*;
222223

@@ -322,8 +323,24 @@ pub mod test {
322323
}
323324

324325
pub fn test_raw_tx<D: Database>(mut tree: D) {
325-
let hex_tx = Vec::<u8>::from_hex("0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000").unwrap();
326-
let tx: Transaction = deserialize(&hex_tx).unwrap();
326+
let hex_tx = Vec::<u8>::from_hex("02000000000101f58c18a90d7a76b30c7e47d4e817adfdd79a6a589a615ef36e360f913adce2cd0000000000feffffff0210270000000000001600145c9a1816d38db5cbdd4b067b689dc19eb7d930e2cf70aa2b080000001600140f48b63160043047f4f60f7f8f551f80458f693f024730440220413f42b7bc979945489a38f5221e5527d4b8e3aa63eae2099e01945896ad6c10022024ceec492d685c31d8adb64e935a06933877c5ae0e21f32efe029850914c5bad012102361caae96f0e9f3a453d354bb37a5c3244422fb22819bf0166c0647a38de39f21fca2300").unwrap();
327+
let mut tx: Transaction = deserialize(&hex_tx).unwrap();
328+
329+
tree.set_raw_tx(&tx).unwrap();
330+
331+
let txid = tx.txid();
332+
333+
assert_eq!(tree.get_raw_tx(&txid).unwrap(), Some(tx.clone()));
334+
335+
// mutate transaction's witnesses
336+
for tx_in in tx.input.iter_mut() {
337+
tx_in.witness = Witness::new();
338+
}
339+
340+
let updated_hex_tx = serialize(&tx);
341+
342+
// verify that mutation was successful
343+
assert_ne!(hex_tx, updated_hex_tx);
327344

328345
tree.set_raw_tx(&tx).unwrap();
329346

@@ -441,5 +458,203 @@ pub mod test {
441458
assert!(tree.get_sync_time().unwrap().is_none());
442459
}
443460

461+
pub fn test_iter_raw_txs<D: Database>(mut db: D) {
462+
let txs = db.iter_raw_txs().unwrap();
463+
assert!(txs.is_empty());
464+
465+
let hex_tx = Vec::<u8>::from_hex("0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000").unwrap();
466+
let first_tx: Transaction = deserialize(&hex_tx).unwrap();
467+
468+
let hex_tx = Vec::<u8>::from_hex("02000000000101f58c18a90d7a76b30c7e47d4e817adfdd79a6a589a615ef36e360f913adce2cd0000000000feffffff0210270000000000001600145c9a1816d38db5cbdd4b067b689dc19eb7d930e2cf70aa2b080000001600140f48b63160043047f4f60f7f8f551f80458f693f024730440220413f42b7bc979945489a38f5221e5527d4b8e3aa63eae2099e01945896ad6c10022024ceec492d685c31d8adb64e935a06933877c5ae0e21f32efe029850914c5bad012102361caae96f0e9f3a453d354bb37a5c3244422fb22819bf0166c0647a38de39f21fca2300").unwrap();
469+
let second_tx: Transaction = deserialize(&hex_tx).unwrap();
470+
471+
db.set_raw_tx(&first_tx).unwrap();
472+
db.set_raw_tx(&second_tx).unwrap();
473+
474+
let txs = db.iter_raw_txs().unwrap();
475+
476+
assert!(txs.contains(&first_tx));
477+
assert!(txs.contains(&second_tx));
478+
assert_eq!(txs.len(), 2);
479+
}
480+
481+
pub fn test_del_path_from_script_pubkey<D: Database>(mut db: D) {
482+
let keychain = KeychainKind::External;
483+
484+
let script = Script::from(
485+
Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
486+
);
487+
let path = 42;
488+
489+
let res = db.del_path_from_script_pubkey(&script).unwrap();
490+
491+
assert!(res.is_none());
492+
493+
let _res = db.set_script_pubkey(&script, keychain, path);
494+
let (chain, child) = db.del_path_from_script_pubkey(&script).unwrap().unwrap();
495+
496+
assert_eq!(chain, keychain);
497+
assert_eq!(child, path);
498+
499+
let res = db.get_path_from_script_pubkey(&script).unwrap();
500+
assert!(res.is_none());
501+
}
502+
503+
pub fn test_iter_script_pubkeys<D: Database>(mut db: D) {
504+
let keychain = KeychainKind::External;
505+
let scripts = db.iter_script_pubkeys(Some(keychain)).unwrap();
506+
assert!(scripts.is_empty());
507+
508+
let first_script = Script::from(
509+
Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
510+
);
511+
let path = 42;
512+
513+
db.set_script_pubkey(&first_script, keychain, path).unwrap();
514+
515+
let second_script = Script::from(
516+
Vec::<u8>::from_hex("00145c9a1816d38db5cbdd4b067b689dc19eb7d930e2").unwrap(),
517+
);
518+
let path = 57;
519+
520+
db.set_script_pubkey(&second_script, keychain, path)
521+
.unwrap();
522+
let scripts = db.iter_script_pubkeys(Some(keychain)).unwrap();
523+
524+
assert!(scripts.contains(&first_script));
525+
assert!(scripts.contains(&second_script));
526+
assert_eq!(scripts.len(), 2);
527+
}
528+
529+
pub fn test_del_utxo<D: Database>(mut db: D) {
530+
let outpoint = OutPoint::from_str(
531+
"5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:0",
532+
)
533+
.unwrap();
534+
let script = Script::from(
535+
Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
536+
);
537+
let txout = TxOut {
538+
value: 133742,
539+
script_pubkey: script,
540+
};
541+
let utxo = LocalUtxo {
542+
txout,
543+
outpoint,
544+
keychain: KeychainKind::External,
545+
is_spent: true,
546+
};
547+
548+
let res = db.del_utxo(&outpoint).unwrap();
549+
assert!(res.is_none());
550+
551+
db.set_utxo(&utxo).unwrap();
552+
553+
let res = db.del_utxo(&outpoint).unwrap();
554+
555+
assert_eq!(res.unwrap(), utxo);
556+
557+
let res = db.get_utxo(&outpoint).unwrap();
558+
assert!(res.is_none());
559+
}
560+
561+
pub fn test_del_raw_tx<D: Database>(mut db: D) {
562+
let hex_tx = Vec::<u8>::from_hex("02000000000101f58c18a90d7a76b30c7e47d4e817adfdd79a6a589a615ef36e360f913adce2cd0000000000feffffff0210270000000000001600145c9a1816d38db5cbdd4b067b689dc19eb7d930e2cf70aa2b080000001600140f48b63160043047f4f60f7f8f551f80458f693f024730440220413f42b7bc979945489a38f5221e5527d4b8e3aa63eae2099e01945896ad6c10022024ceec492d685c31d8adb64e935a06933877c5ae0e21f32efe029850914c5bad012102361caae96f0e9f3a453d354bb37a5c3244422fb22819bf0166c0647a38de39f21fca2300").unwrap();
563+
let tx: Transaction = deserialize(&hex_tx).unwrap();
564+
565+
let res = db.del_raw_tx(&tx.txid()).unwrap();
566+
567+
assert!(res.is_none());
568+
569+
db.set_raw_tx(&tx).unwrap();
570+
571+
let res = db.del_raw_tx(&tx.txid()).unwrap();
572+
573+
assert_eq!(res.unwrap(), tx);
574+
575+
let res = db.get_raw_tx(&tx.txid()).unwrap();
576+
assert!(res.is_none());
577+
}
578+
579+
pub fn test_del_tx<D: Database>(mut db: D) {
580+
let hex_tx = Vec::<u8>::from_hex("0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000").unwrap();
581+
let tx: Transaction = deserialize(&hex_tx).unwrap();
582+
let txid = tx.txid();
583+
let mut tx_details = TransactionDetails {
584+
transaction: Some(tx.clone()),
585+
txid,
586+
received: 1337,
587+
sent: 420420,
588+
fee: Some(140),
589+
confirmation_time: Some(BlockTime {
590+
timestamp: 123456,
591+
height: 1000,
592+
}),
593+
};
594+
595+
let res = db.del_tx(&tx.txid(), true).unwrap();
596+
597+
assert!(res.is_none());
598+
599+
db.set_tx(&tx_details).unwrap();
600+
601+
let res = db.del_tx(&tx.txid(), false).unwrap();
602+
tx_details.transaction = None;
603+
assert_eq!(res.unwrap(), tx_details);
604+
605+
let res = db.get_tx(&tx.txid(), true).unwrap();
606+
assert!(res.is_none());
607+
608+
let res = db.get_raw_tx(&tx.txid()).unwrap();
609+
assert_eq!(res.unwrap(), tx);
610+
611+
db.set_tx(&tx_details).unwrap();
612+
let res = db.del_tx(&tx.txid(), true).unwrap();
613+
tx_details.transaction = Some(tx.clone());
614+
assert_eq!(res.unwrap(), tx_details);
615+
616+
let res = db.get_tx(&tx.txid(), true).unwrap();
617+
assert!(res.is_none());
618+
619+
let res = db.get_raw_tx(&tx.txid()).unwrap();
620+
assert!(res.is_none());
621+
}
622+
623+
pub fn test_del_last_index<D: Database>(mut db: D) {
624+
let keychain = KeychainKind::External;
625+
626+
let _res = db.increment_last_index(keychain);
627+
628+
let res = db.get_last_index(keychain).unwrap().unwrap();
629+
630+
assert_eq!(res, 0);
631+
632+
let _res = db.increment_last_index(keychain);
633+
634+
let res = db.del_last_index(keychain).unwrap().unwrap();
635+
636+
assert_eq!(res, 1);
637+
638+
let res = db.get_last_index(keychain).unwrap();
639+
assert!(res.is_none());
640+
}
641+
642+
pub fn test_check_descriptor_checksum<D: Database>(mut db: D) {
643+
// insert checksum associated to keychain
644+
let checksum = "1cead456".as_bytes();
645+
let keychain = KeychainKind::External;
646+
let _res = db.check_descriptor_checksum(keychain, checksum);
647+
648+
// check if `check_descriptor_checksum` throws
649+
// `Error::ChecksumMismatch` error if the
650+
// function is passed a checksum that does
651+
// not match the one initially inserted
652+
let checksum = "1cead454".as_bytes();
653+
let keychain = KeychainKind::External;
654+
let res = db.check_descriptor_checksum(keychain, checksum);
655+
656+
assert!(res.is_err());
657+
}
658+
444659
// TODO: more tests...
445660
}

src/database/sqlite.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,4 +1038,44 @@ pub mod test {
10381038
fn test_txs() {
10391039
crate::database::test::test_list_transaction(get_database());
10401040
}
1041+
1042+
#[test]
1043+
fn test_iter_raw_txs() {
1044+
crate::database::test::test_iter_raw_txs(get_database());
1045+
}
1046+
1047+
#[test]
1048+
fn test_del_path_from_script_pubkey() {
1049+
crate::database::test::test_del_path_from_script_pubkey(get_database());
1050+
}
1051+
1052+
#[test]
1053+
fn test_iter_script_pubkeys() {
1054+
crate::database::test::test_iter_script_pubkeys(get_database());
1055+
}
1056+
1057+
#[test]
1058+
fn test_del_utxo() {
1059+
crate::database::test::test_del_utxo(get_database());
1060+
}
1061+
1062+
#[test]
1063+
fn test_del_raw_tx() {
1064+
crate::database::test::test_del_raw_tx(get_database());
1065+
}
1066+
1067+
#[test]
1068+
fn test_del_tx() {
1069+
crate::database::test::test_del_tx(get_database());
1070+
}
1071+
1072+
#[test]
1073+
fn test_del_last_index() {
1074+
crate::database::test::test_del_last_index(get_database());
1075+
}
1076+
1077+
#[test]
1078+
fn test_check_descriptor_checksum() {
1079+
crate::database::test::test_check_descriptor_checksum(get_database());
1080+
}
10411081
}

0 commit comments

Comments
 (0)