From fdf1f5c18ecf83abbe33dedcff63fc632a40722e Mon Sep 17 00:00:00 2001 From: rajarshimaitra Date: Wed, 17 Aug 2022 16:36:07 +0530 Subject: [PATCH] Set the db sync height Previously we weren't setting the db sync height in populate_test_db macro even when current height is provided.. This creates a bug that get_funded_wallet will return 0 balance. This PR fixes the populate_test_db macro and updates tests which were previously dependent on the unsynced wallet behavior. --- src/database/memory.rs | 30 +++++++++++++++++++--- src/wallet/mod.rs | 58 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 81 insertions(+), 7 deletions(-) diff --git a/src/database/memory.rs b/src/database/memory.rs index 7d806eb4af..9b88105a46 100644 --- a/src/database/memory.rs +++ b/src/database/memory.rs @@ -486,7 +486,8 @@ macro_rules! populate_test_db { }}; ($db:expr, $tx_meta:expr, $current_height:expr, (@coinbase $is_coinbase:expr)$(,)?) => {{ use std::str::FromStr; - use $crate::database::BatchOperations; + use $crate::database::SyncTime; + use $crate::database::{BatchOperations, Database}; let mut db = $db; let tx_meta = $tx_meta; let current_height: Option = $current_height; @@ -512,13 +513,34 @@ macro_rules! populate_test_db { }; let txid = tx.txid(); - let confirmation_time = tx_meta + // Set Confirmation time only if current height is provided. Else None. + let confirmation_time = if let Some(height) = current_height { + tx_meta .min_confirmations .and_then(|v| if v == 0 { None } else { Some(v) }) .map(|conf| $crate::BlockTime { - height: current_height.unwrap().checked_sub(conf as u32).unwrap() + 1, + height: height.checked_sub(conf as u32).unwrap() + 1, timestamp: 0, - }); + }) + } else { + None + }; + + // Set the database sync_time. + // Check if the current_height is less than already known sync height, apply the max + // If any of them is None, the other will be applied instead. + // If both are None, this will not be set. + if let Some(height) = db.get_sync_time().unwrap() + .and_then(|sync_time| Some(sync_time.block_time.height)) + .max(current_height) { + let sync_time = SyncTime { + block_time: BlockTime { + height, + timestamp: 0 + } + }; + db.set_sync_time(sync_time).unwrap(); + } let tx_details = $crate::TransactionDetails { transaction: Some(tx.clone()), diff --git a/src/wallet/mod.rs b/src/wallet/mod.rs index f7f7dc5269..daee5de362 100644 --- a/src/wallet/mod.rs +++ b/src/wallet/mod.rs @@ -1926,6 +1926,12 @@ pub(crate) mod test { // OP_PUSH. const P2WPKH_FAKE_WITNESS_SIZE: usize = 106; + #[test] + fn test_get_funded_wallet_balance() { + let (wallet, _, _) = get_funded_wallet(get_test_wpkh()); + assert_eq!(wallet.get_balance().unwrap().confirmed, 50000); + } + #[test] fn test_cache_addresses_fixed() { let db = MemoryDatabase::new(); @@ -2173,7 +2179,22 @@ pub(crate) mod test { #[test] fn test_create_tx_default_locktime() { - let (wallet, _, _) = get_funded_wallet(get_test_wpkh()); + let descriptors = testutils!(@descriptors (get_test_wpkh())); + let wallet = Wallet::new( + &descriptors.0, + None, + Network::Regtest, + AnyDatabase::Memory(MemoryDatabase::new()), + ) + .unwrap(); + + let tx_meta = testutils! { + @tx ( (@external descriptors, 0) => 50_000 ) (@confirmations 1) + }; + + // Add the transaction to our db, but do not sync the db. + crate::populate_test_db!(wallet.database.borrow_mut(), tx_meta, None); + let addr = wallet.get_address(New).unwrap(); let mut builder = wallet.build_tx(); builder.add_recipient(addr.script_pubkey(), 25_000); @@ -2364,7 +2385,23 @@ pub(crate) mod test { #[test] fn test_create_tx_default_sequence() { - let (wallet, _, _) = get_funded_wallet(get_test_wpkh()); + let descriptors = testutils!(@descriptors (get_test_wpkh())); + let wallet = Wallet::new( + &descriptors.0, + None, + Network::Regtest, + AnyDatabase::Memory(MemoryDatabase::new()), + ) + .unwrap(); + + let tx_meta = testutils! { + @tx ( (@external descriptors, 0) => 50_000 ) (@confirmations 1) + }; + + // Add the transaction to our db, but do not sync the db. Unsynced db + // should trigger the default sequence value for a new transaction as 0xFFFFFFFF + crate::populate_test_db!(wallet.database.borrow_mut(), tx_meta, None); + let addr = wallet.get_address(New).unwrap(); let mut builder = wallet.build_tx(); builder.add_recipient(addr.script_pubkey(), 25_000); @@ -2862,7 +2899,22 @@ pub(crate) mod test { #[test] fn test_create_tx_policy_path_no_csv() { - let (wallet, _, _) = get_funded_wallet(get_test_a_or_b_plus_csv()); + let descriptors = testutils!(@descriptors (get_test_wpkh())); + let wallet = Wallet::new( + &descriptors.0, + None, + Network::Regtest, + AnyDatabase::Memory(MemoryDatabase::new()), + ) + .unwrap(); + + let tx_meta = testutils! { + @tx ( (@external descriptors, 0) => 50_000 ) (@confirmations 1) + }; + + // Add the transaction to our db, but do not sync the db. Unsynced db + // should trigger the default sequence value for a new transaction as 0xFFFFFFFF + crate::populate_test_db!(wallet.database.borrow_mut(), tx_meta, None); let external_policy = wallet.policies(KeychainKind::External).unwrap().unwrap(); let root_id = external_policy.id;