Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ lightning-dns-resolver = { git = "https://github.com/lightningdevkit/rust-lightn
bdk_chain = { version = "0.23.0", default-features = false, features = ["std"] }
bdk_esplora = { version = "0.22.0", default-features = false, features = ["async-https-rustls", "tokio"]}
bdk_electrum = { version = "0.23.0", default-features = false, features = ["use-rustls-ring"]}
bdk_wallet = { version = "2.3.0", default-features = false, features = ["std", "keys-bip39"]}
bdk_wallet = { version = "3.0.0", default-features = false, features = ["std", "keys-bip39"]}

bitreq = { version = "0.3", default-features = false, features = ["async-https", "json-using-serde"] }
rustls = { version = "0.23", default-features = false }
Expand Down
158 changes: 25 additions & 133 deletions src/wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ use std::sync::{Arc, Mutex};
use bdk_chain::spk_client::{FullScanRequest, SyncRequest};
use bdk_wallet::descriptor::ExtendedDescriptor;
use bdk_wallet::error::{BuildFeeBumpError, CreateTxError};
use bdk_wallet::event::WalletEvent;
#[allow(deprecated)]
use bdk_wallet::SignOptions;
use bdk_wallet::{Balance, KeychainKind, PersistedWallet, Update};
use bdk_wallet::{Balance, KeychainKind, PersistedWallet, Update, WalletEvent};
use bitcoin::address::NetworkUnchecked;
use bitcoin::blockdata::constants::WITNESS_SCALE_FACTOR;
use bitcoin::blockdata::locktime::absolute::LockTime;
Expand Down Expand Up @@ -181,30 +180,13 @@ impl Wallet {
}

let mut locked_wallet = self.inner.lock().expect("lock");

let chain_tip1 = locked_wallet.latest_checkpoint().block_id();
let wallet_txs1 = locked_wallet
.transactions()
.map(|wtx| (wtx.tx_node.txid, (wtx.tx_node.tx.clone(), wtx.chain_position)))
.collect::<std::collections::BTreeMap<
Txid,
(Arc<Transaction>, bdk_chain::ChainPosition<bdk_chain::ConfirmationBlockTime>),
>>();

locked_wallet.apply_unconfirmed_txs(unconfirmed_txs);
locked_wallet.apply_evicted_txs(evicted_txids);

let chain_tip2 = locked_wallet.latest_checkpoint().block_id();
let wallet_txs2 = locked_wallet
.transactions()
.map(|wtx| (wtx.tx_node.txid, (wtx.tx_node.tx.clone(), wtx.chain_position)))
.collect::<std::collections::BTreeMap<
Txid,
(Arc<Transaction>, bdk_chain::ChainPosition<bdk_chain::ConfirmationBlockTime>),
>>();

let events =
wallet_events(&mut *locked_wallet, chain_tip1, chain_tip2, wallet_txs1, wallet_txs2);
let events = locked_wallet
.events_helper(|wallet| {
wallet.apply_unconfirmed_txs(unconfirmed_txs);
wallet.apply_evicted_txs(evicted_txids);
Ok::<(), std::convert::Infallible>(())
})
.expect("infallible");

self.update_payment_store(&mut *locked_wallet, events).map_err(|e| {
log_error!(self.logger, "Failed to update payment store: {}", e);
Expand Down Expand Up @@ -504,7 +486,7 @@ impl Wallet {
let mut locked_wallet = self.inner.lock().expect("lock");
let mut locked_persister = self.persister.lock().expect("lock");

locked_wallet.cancel_tx(tx);
reclaim_tx_outputs(&mut locked_wallet, tx);
locked_wallet.persist(&mut locked_persister).map_err(|e| {
log_error!(self.logger, "Failed to persist wallet: {}", e);
Error::PersistenceFailed
Expand Down Expand Up @@ -593,7 +575,7 @@ impl Wallet {
/// Builds a temporary drain transaction and returns the maximum amount that would be sent to
/// the drain output, along with the PSBT for further inspection.
///
/// The caller is responsible for cancelling the PSBT via `locked_wallet.cancel_tx()`.
/// The caller is responsible for reclaiming any used addresses from the PSBT.
fn get_max_drain_amount(
&self, locked_wallet: &mut PersistedWallet<KVStoreWalletPersister>,
drain_script: ScriptBuf, cur_anchor_reserve_sats: u64, fee_rate: FeeRate,
Expand Down Expand Up @@ -665,7 +647,7 @@ impl Wallet {
None,
)?;

locked_wallet.cancel_tx(&tmp_psbt.unsigned_tx);
reclaim_tx_outputs(&mut locked_wallet, &tmp_psbt.unsigned_tx);

Ok(max_amount)
}
Expand Down Expand Up @@ -695,7 +677,7 @@ impl Wallet {
Some(&shared_input),
)?;

locked_wallet.cancel_tx(&tmp_psbt.unsigned_tx);
reclaim_tx_outputs(&mut locked_wallet, &tmp_psbt.unsigned_tx);

Ok(splice_amount)
}
Expand Down Expand Up @@ -751,7 +733,7 @@ impl Wallet {
e
})?;

locked_wallet.cancel_tx(&tmp_psbt.unsigned_tx);
reclaim_tx_outputs(&mut locked_wallet, &tmp_psbt.unsigned_tx);

let mut tx_builder = locked_wallet.build_tx();
tx_builder
Expand Down Expand Up @@ -1427,6 +1409,18 @@ impl Wallet {
}
}

fn reclaim_tx_outputs(
locked_wallet: &mut PersistedWallet<KVStoreWalletPersister>, tx: &Transaction,
) {
for output in &tx.output {
if let Some((keychain, index)) =
locked_wallet.derivation_of_spk(output.script_pubkey.clone())
{
locked_wallet.unmark_used(keychain, index);
}
}
}

impl Listen for Wallet {
fn filtered_block_connected(
&self, _header: &bitcoin::block::Header,
Expand Down Expand Up @@ -1716,105 +1710,3 @@ impl ChangeDestinationSource for WalletKeysManager {
}
}
}

// FIXME/TODO: This is copied-over from bdk_wallet and only used to generate `WalletEvent`s after
// applying mempool transactions. We should drop this when BDK offers to generate events for
// mempool transactions natively.
pub(crate) fn wallet_events(
wallet: &mut bdk_wallet::Wallet, chain_tip1: bdk_chain::BlockId,
chain_tip2: bdk_chain::BlockId,
wallet_txs1: std::collections::BTreeMap<
Txid,
(Arc<Transaction>, bdk_chain::ChainPosition<bdk_chain::ConfirmationBlockTime>),
>,
wallet_txs2: std::collections::BTreeMap<
Txid,
(Arc<Transaction>, bdk_chain::ChainPosition<bdk_chain::ConfirmationBlockTime>),
>,
) -> Vec<WalletEvent> {
let mut events: Vec<WalletEvent> = Vec::new();

if chain_tip1 != chain_tip2 {
events.push(WalletEvent::ChainTipChanged { old_tip: chain_tip1, new_tip: chain_tip2 });
}

wallet_txs2.iter().for_each(|(txid2, (tx2, cp2))| {
if let Some((tx1, cp1)) = wallet_txs1.get(txid2) {
assert_eq!(tx1.compute_txid(), *txid2);
match (cp1, cp2) {
(
bdk_chain::ChainPosition::Unconfirmed { .. },
bdk_chain::ChainPosition::Confirmed { anchor, .. },
) => {
events.push(WalletEvent::TxConfirmed {
txid: *txid2,
tx: tx2.clone(),
block_time: *anchor,
old_block_time: None,
});
},
(
bdk_chain::ChainPosition::Confirmed { anchor, .. },
bdk_chain::ChainPosition::Unconfirmed { .. },
) => {
events.push(WalletEvent::TxUnconfirmed {
txid: *txid2,
tx: tx2.clone(),
old_block_time: Some(*anchor),
});
},
(
bdk_chain::ChainPosition::Confirmed { anchor: anchor1, .. },
bdk_chain::ChainPosition::Confirmed { anchor: anchor2, .. },
) => {
if *anchor1 != *anchor2 {
events.push(WalletEvent::TxConfirmed {
txid: *txid2,
tx: tx2.clone(),
block_time: *anchor2,
old_block_time: Some(*anchor1),
});
}
},
(
bdk_chain::ChainPosition::Unconfirmed { .. },
bdk_chain::ChainPosition::Unconfirmed { .. },
) => {
// do nothing if still unconfirmed
},
}
} else {
match cp2 {
bdk_chain::ChainPosition::Confirmed { anchor, .. } => {
events.push(WalletEvent::TxConfirmed {
txid: *txid2,
tx: tx2.clone(),
block_time: *anchor,
old_block_time: None,
});
},
bdk_chain::ChainPosition::Unconfirmed { .. } => {
events.push(WalletEvent::TxUnconfirmed {
txid: *txid2,
tx: tx2.clone(),
old_block_time: None,
});
},
}
}
});

// find tx that are no longer canonical
wallet_txs1.iter().for_each(|(txid1, (tx1, _))| {
if !wallet_txs2.contains_key(txid1) {
let conflicts = wallet.tx_graph().direct_conflicts(tx1).collect::<Vec<_>>();
if !conflicts.is_empty() {
events.push(WalletEvent::TxReplaced { txid: *txid1, tx: tx1.clone(), conflicts });
} else {
events.push(WalletEvent::TxDropped { txid: *txid1, tx: tx1.clone() });
}
}
});

events
}
9 changes: 9 additions & 0 deletions tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ macro_rules! expect_channel_pending_event {
}};
}

#[allow(unused_imports)]
pub(crate) use expect_channel_pending_event;

macro_rules! expect_channel_ready_event {
Expand All @@ -141,8 +142,10 @@ macro_rules! expect_channel_ready_event {
}};
}

#[allow(unused_imports)]
pub(crate) use expect_channel_ready_event;

#[allow(unused_macros)]
macro_rules! expect_channel_ready_events {
($node:expr, $counterparty_node_id_a:expr, $counterparty_node_id_b:expr) => {{
let mut ids = Vec::new();
Expand Down Expand Up @@ -177,6 +180,7 @@ macro_rules! expect_channel_ready_events {
}};
}

#[allow(unused_imports)]
pub(crate) use expect_channel_ready_events;

macro_rules! expect_splice_pending_event {
Expand All @@ -203,6 +207,7 @@ macro_rules! expect_splice_pending_event {
}};
}

#[allow(unused_imports)]
pub(crate) use expect_splice_pending_event;

macro_rules! expect_payment_received_event {
Expand Down Expand Up @@ -233,6 +238,7 @@ macro_rules! expect_payment_received_event {
}};
}

#[allow(unused_imports)]
pub(crate) use expect_payment_received_event;

macro_rules! expect_payment_claimable_event {
Expand Down Expand Up @@ -269,6 +275,7 @@ macro_rules! expect_payment_claimable_event {
}};
}

#[allow(unused_imports)]
pub(crate) use expect_payment_claimable_event;

macro_rules! expect_payment_successful_event {
Expand Down Expand Up @@ -299,6 +306,7 @@ macro_rules! expect_payment_successful_event {
}};
}

#[allow(unused_imports)]
pub(crate) use expect_payment_successful_event;

pub(crate) fn setup_bitcoind_and_electrsd() -> (BitcoinD, ElectrsD) {
Expand Down Expand Up @@ -464,6 +472,7 @@ macro_rules! setup_builder {
};
}

#[allow(unused_imports)]
pub(crate) use setup_builder;

#[cfg(any(cln_test, lnd_test, eclair_test))]
Expand Down
Loading