Merge bitcoindevkit/bdk#726: [bug-fix] Set the db sync height

08668ac46247d527cc53af5b6f359b1fa4e3b6aa Set the db sync height (rajarshimaitra)

Pull request description:

  <!-- You can erase any parts of this template not applicable to your Pull Request. -->

  ### Description

  Fixes #719

  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.

  ### Notes to the reviewers

  <!-- In this section you can include notes directed to the reviewers, like explaining why some parts
  of the PR were done in a specific way -->

  ### Checklists

  #### All Submissions:

  * [x] I've signed all my commits
  * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
  * [x] I ran `cargo fmt` and `cargo clippy` before committing

  #### Bugfixes:

  * [x] I've added tests to reproduce the issue which are now passing
  * [x] I'm linking the issue being fixed by this PR

ACKs for top commit:
  afilini:
    ACK 08668ac46247d527cc53af5b6f359b1fa4e3b6aa

Tree-SHA512: 1dcc968e4b3551e916b450c5ff2fab6636083f104cc982eb3f7602c624382434e0170d9f0c0a356e6c9c5f834eebe5cb1365b37ef73d7b4ef15d652a364dc2ab
This commit is contained in:
Alekos Filini 2022-08-29 10:24:33 +02:00
commit 2bff4e5e56
No known key found for this signature in database
GPG Key ID: 431401E4A4530061
2 changed files with 76 additions and 5 deletions

View File

@ -486,7 +486,8 @@ macro_rules! populate_test_db {
}}; }};
($db:expr, $tx_meta:expr, $current_height:expr, (@coinbase $is_coinbase:expr)$(,)?) => {{ ($db:expr, $tx_meta:expr, $current_height:expr, (@coinbase $is_coinbase:expr)$(,)?) => {{
use std::str::FromStr; use std::str::FromStr;
use $crate::database::BatchOperations; use $crate::database::SyncTime;
use $crate::database::{BatchOperations, Database};
let mut db = $db; let mut db = $db;
let tx_meta = $tx_meta; let tx_meta = $tx_meta;
let current_height: Option<u32> = $current_height; let current_height: Option<u32> = $current_height;
@ -512,14 +513,32 @@ macro_rules! populate_test_db {
}; };
let txid = tx.txid(); let txid = tx.txid();
// Set Confirmation time only if current height is provided.
// panics if `tx_meta.min_confirmation` is Some, and current_height is None.
let confirmation_time = tx_meta let confirmation_time = tx_meta
.min_confirmations .min_confirmations
.and_then(|v| if v == 0 { None } else { Some(v) }) .and_then(|v| if v == 0 { None } else { Some(v) })
.map(|conf| $crate::BlockTime { .map(|conf| $crate::BlockTime {
height: current_height.unwrap().checked_sub(conf as u32).unwrap() + 1, height: current_height.expect("Current height is needed for testing transaction with min-confirmation values").checked_sub(conf as u32).unwrap() + 1,
timestamp: 0, timestamp: 0,
}); });
// 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()
.map(|sync_time| 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 { let tx_details = $crate::TransactionDetails {
transaction: Some(tx.clone()), transaction: Some(tx.clone()),
txid, txid,

View File

@ -1926,6 +1926,12 @@ pub(crate) mod test {
// OP_PUSH. // OP_PUSH.
const P2WPKH_FAKE_WITNESS_SIZE: usize = 106; 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] #[test]
fn test_cache_addresses_fixed() { fn test_cache_addresses_fixed() {
let db = MemoryDatabase::new(); let db = MemoryDatabase::new();
@ -2173,7 +2179,22 @@ pub(crate) mod test {
#[test] #[test]
fn test_create_tx_default_locktime() { 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 )
};
// 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 addr = wallet.get_address(New).unwrap();
let mut builder = wallet.build_tx(); let mut builder = wallet.build_tx();
builder.add_recipient(addr.script_pubkey(), 25_000); builder.add_recipient(addr.script_pubkey(), 25_000);
@ -2364,7 +2385,23 @@ pub(crate) mod test {
#[test] #[test]
fn test_create_tx_default_sequence() { 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 )
};
// 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 addr = wallet.get_address(New).unwrap();
let mut builder = wallet.build_tx(); let mut builder = wallet.build_tx();
builder.add_recipient(addr.script_pubkey(), 25_000); builder.add_recipient(addr.script_pubkey(), 25_000);
@ -2862,7 +2899,22 @@ pub(crate) mod test {
#[test] #[test]
fn test_create_tx_policy_path_no_csv() { 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 )
};
// 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 external_policy = wallet.policies(KeychainKind::External).unwrap().unwrap();
let root_id = external_policy.id; let root_id = external_policy.id;