Skip to content

Commit 15b482a

Browse files
committed
f Drop spending callback fn
.. and use `OutputSpender`/`ChangeDestinationSource`/`FeeEstimator` traits instead.
1 parent 808402d commit 15b482a

File tree

1 file changed

+81
-116
lines changed

1 file changed

+81
-116
lines changed

lightning/src/util/sweep.rs

Lines changed: 81 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@
88
//! [`SpendableOutputDescriptor`]s, i.e., persists them in a given [`KVStore`] and regularly retries
99
//! sweeping them.
1010
11-
use crate::chain::chaininterface::BroadcasterInterface;
11+
use crate::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
1212
use crate::chain::channelmonitor::ANTI_REORG_DELAY;
1313
use crate::chain::{self, BestBlock, Confirm, Filter, Listen, WatchedOutput};
1414
use crate::io;
1515
use crate::ln::msgs::DecodeError;
1616
use crate::ln::ChannelId;
17-
use crate::prelude::{Box, Vec};
18-
use crate::sign::SpendableOutputDescriptor;
17+
use crate::prelude::Vec;
18+
use crate::sign::{ChangeDestinationSource, OutputSpender, SpendableOutputDescriptor};
1919
use crate::sync::Mutex;
2020
use crate::util::logger::Logger;
2121
use crate::util::persist::{
@@ -26,6 +26,8 @@ use crate::util::ser::{Readable, ReadableArgs, Writeable};
2626
use crate::{impl_writeable_tlv_based, log_debug, log_error};
2727

2828
use bitcoin::blockdata::block::Header;
29+
use bitcoin::blockdata::locktime::absolute::LockTime;
30+
use bitcoin::secp256k1::Secp256k1;
2931
use bitcoin::{BlockHash, Transaction, Txid};
3032

3133
use core::ops::Deref;
@@ -307,121 +309,66 @@ impl_writeable_tlv_based_enum!(OutputSpendStatus,
307309
/// constructor.
308310
///
309311
/// [`Event::SpendableOutputs`]: crate::events::Event::SpendableOutputs
310-
pub struct OutputSweeper<B: Deref, F: Deref, K: Deref, L: Deref>
312+
pub struct OutputSweeper<B: Deref, D: Deref, E: Deref, F: Deref, K: Deref, L: Deref, O: Deref>
311313
where
312314
B::Target: BroadcasterInterface,
315+
D::Target: ChangeDestinationSource,
316+
E::Target: FeeEstimator,
313317
F::Target: Filter + Sync + Send,
314318
K::Target: KVStore,
315319
L::Target: Logger,
320+
O::Target: OutputSpender,
316321
{
317322
sweeper_state: Mutex<SweeperState>,
318323
broadcaster: B,
319-
kv_store: K,
324+
fee_estimator: E,
320325
chain_data_source: Option<F>,
326+
output_spender: O,
327+
change_destination_source: D,
328+
kv_store: K,
321329
logger: L,
322-
spend_outputs_callback: Box<
323-
dyn Fn(&[&SpendableOutputDescriptor]) -> Result<Transaction, ()> + Send + Sync + 'static,
324-
>,
325330
}
326331

327-
impl<B: Deref, F: Deref, K: Deref, L: Deref> OutputSweeper<B, F, K, L>
332+
impl<B: Deref, D: Deref, E: Deref, F: Deref, K: Deref, L: Deref, O: Deref>
333+
OutputSweeper<B, D, E, F, K, L, O>
328334
where
329335
B::Target: BroadcasterInterface,
336+
D::Target: ChangeDestinationSource,
337+
E::Target: FeeEstimator,
330338
F::Target: Filter + Sync + Send,
331339
K::Target: KVStore,
332340
L::Target: Logger,
341+
O::Target: OutputSpender,
333342
{
334343
/// Constructs a new [`OutputSweeper`].
335344
///
336345
/// If chain data is provided via the [`Confirm`] interface or via filtered blocks, users also
337346
/// need to register their [`Filter`] implementation via the given `chain_data_source`.
338-
///
339-
/// The given `spend_outputs_callback` is a function takes a list of
340-
/// [`SpendableOutputDescriptor`] and returns a fully signed ready-for-broadcast
341-
/// [`Transaction`]. Usually, this should retrieve a change address from the on-chain wallet
342-
/// and call [`KeysManager::spend_spendable_outputs`].
343-
///
344-
/// [`KeysManager::spend_spendable_outputs`]: crate::sign::KeysManager::spend_spendable_outputs
345-
///
346-
/// #### Example:
347-
/// ```
348-
/// # use bitcoin::key::Secp256k1;
349-
/// # use bitcoin::{Network, Script, ScriptBuf, Transaction, Txid};
350-
/// # use std::sync::Arc;
351-
/// # use lightning::sign::SpendableOutputDescriptor;
352-
/// # use lightning::sign::KeysManager;
353-
/// # use lightning::chain::chaininterface::{ConfirmationTarget, FeeEstimator, BroadcasterInterface};
354-
/// # use lightning::chain::{BestBlock, Filter, WatchedOutput};
355-
/// # use lightning::util::persist::KVStore;
356-
/// # use lightning::util::sweep::OutputSweeper;
357-
/// # use lightning::util::logger::{Logger, Record};
358-
/// # use lightning::io;
359-
/// # struct MyWallet {}
360-
/// # impl MyWallet {
361-
/// # fn get_new_address(&self) -> ScriptBuf { ScriptBuf::new() }
362-
/// # }
363-
/// # fn example<K: KVStore, E: FeeEstimator + Send + Sync + 'static, B: BroadcasterInterface,
364-
/// # F: Filter + Sync + Send, L: Logger>
365-
/// # (
366-
/// # store: Arc<K>, fee_estimator: Arc<E>, broadcaster: Arc<B>, chain_data_source: Arc<F>,
367-
/// # logger: Arc<L>
368-
/// # ) {
369-
/// # let wallet = Arc::new(MyWallet{});
370-
/// # let keys_manager = Arc::new(KeysManager::new(&[42u8; 32], 0, 0));
371-
/// # let best_block = BestBlock::from_network(Network::Regtest);
372-
/// let spend_wallet = Arc::clone(&wallet);
373-
/// let spend_keys_manager = Arc::clone(&keys_manager);
374-
/// let spend_fee_estimator = Arc::clone(&fee_estimator);
375-
/// let spend_outputs_callback = move |output_descriptors: &[&SpendableOutputDescriptor]| {
376-
/// let change_destination_script = spend_wallet.get_new_address();
377-
/// let fee_rate = spend_fee_estimator.get_est_sat_per_1000_weight(
378-
/// ConfirmationTarget::NonAnchorChannelFee
379-
/// );
380-
/// spend_keys_manager.spend_spendable_outputs(
381-
/// output_descriptors,
382-
/// Vec::new(),
383-
/// change_destination_script,
384-
/// fee_rate,
385-
/// None,
386-
/// &Secp256k1::new(),
387-
/// )
388-
/// };
389-
///
390-
/// let sweeper = OutputSweeper::new(broadcaster, store, best_block, Some(chain_data_source),
391-
/// logger, spend_outputs_callback
392-
/// );
393-
/// # }
394-
///```
395347
pub fn new(
396-
broadcaster: B, kv_store: K, best_block: BestBlock, chain_data_source: Option<F>,
397-
logger: L,
398-
spend_outputs_callback: impl Fn(&[&SpendableOutputDescriptor]) -> Result<Transaction, ()>
399-
+ Send
400-
+ Sync
401-
+ 'static,
348+
best_block: BestBlock, broadcaster: B, fee_estimator: E, chain_data_source: Option<F>,
349+
output_spender: O, change_destination_source: D, kv_store: K, logger: L,
402350
) -> Self {
403351
let outputs = Vec::new();
404352
Self::from_outputs(
405353
outputs,
406-
broadcaster,
407-
kv_store,
408354
best_block,
355+
broadcaster,
356+
fee_estimator,
409357
chain_data_source,
358+
output_spender,
359+
change_destination_source,
360+
kv_store,
410361
logger,
411-
spend_outputs_callback,
412362
)
413363
}
414364

415365
/// Constructs an [`OutputSweeper`] from the given list of [`TrackedSpendableOutput`]s.
416366
///
417367
/// See [`Self::new`] for more information regarding the remaining arguments.
418368
pub fn from_outputs(
419-
outputs: Vec<TrackedSpendableOutput>, broadcaster: B, kv_store: K, best_block: BestBlock,
420-
chain_data_source: Option<F>, logger: L,
421-
spend_outputs_callback: impl Fn(&[&SpendableOutputDescriptor]) -> Result<Transaction, ()>
422-
+ Send
423-
+ Sync
424-
+ 'static,
369+
outputs: Vec<TrackedSpendableOutput>, best_block: BestBlock, broadcaster: B,
370+
fee_estimator: E, chain_data_source: Option<F>, output_spender: O,
371+
change_destination_source: D, kv_store: K, logger: L,
425372
) -> Self {
426373
if let Some(filter) = chain_data_source.as_ref() {
427374
for output_info in &outputs {
@@ -431,14 +378,15 @@ where
431378
}
432379

433380
let sweeper_state = Mutex::new(SweeperState { outputs, best_block });
434-
let spend_outputs_callback = Box::new(spend_outputs_callback);
435381
Self {
436382
sweeper_state,
437383
broadcaster,
438-
kv_store,
384+
fee_estimator,
439385
chain_data_source,
386+
output_spender,
387+
change_destination_source,
388+
kv_store,
440389
logger,
441-
spend_outputs_callback,
442390
}
443391
}
444392

@@ -532,7 +480,7 @@ where
532480
return None;
533481
}
534482

535-
let spending_tx = match (self.spend_outputs_callback)(&respend_descriptors) {
483+
let spending_tx = match self.spend_outputs(&*sweeper_state, respend_descriptors) {
536484
Ok(spending_tx) => {
537485
log_debug!(
538486
self.logger,
@@ -600,14 +548,37 @@ where
600548
e
601549
})
602550
}
551+
552+
fn spend_outputs(
553+
&self, sweeper_state: &SweeperState, descriptors: Vec<&SpendableOutputDescriptor>,
554+
) -> Result<Transaction, ()> {
555+
let tx_feerate =
556+
self.fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::AnchorChannelFee);
557+
let change_destination_script =
558+
self.change_destination_source.get_change_destination_script()?;
559+
let cur_height = sweeper_state.best_block.height;
560+
let locktime = Some(LockTime::from_height(cur_height).unwrap_or(LockTime::ZERO));
561+
self.output_spender.spend_spendable_outputs(
562+
&descriptors,
563+
Vec::new(),
564+
change_destination_script,
565+
tx_feerate,
566+
locktime,
567+
&Secp256k1::new(),
568+
)
569+
}
603570
}
604571

605-
impl<B: Deref, F: Deref, K: Deref, L: Deref> Listen for OutputSweeper<B, F, K, L>
572+
impl<B: Deref, D: Deref, E: Deref, F: Deref, K: Deref, L: Deref, O: Deref> Listen
573+
for OutputSweeper<B, D, E, F, K, L, O>
606574
where
607575
B::Target: BroadcasterInterface,
576+
D::Target: ChangeDestinationSource,
577+
E::Target: FeeEstimator,
608578
F::Target: Filter + Sync + Send,
609579
K::Target: KVStore,
610580
L::Target: Logger,
581+
O::Target: OutputSpender,
611582
{
612583
fn filtered_block_connected(
613584
&self, header: &Header, txdata: &chain::transaction::TransactionData, height: u32,
@@ -649,12 +620,16 @@ where
649620
}
650621
}
651622

652-
impl<B: Deref, F: Deref, K: Deref, L: Deref> Confirm for OutputSweeper<B, F, K, L>
623+
impl<B: Deref, D: Deref, E: Deref, F: Deref, K: Deref, L: Deref, O: Deref> Confirm
624+
for OutputSweeper<B, D, E, F, K, L, O>
653625
where
654626
B::Target: BroadcasterInterface,
627+
D::Target: ChangeDestinationSource,
628+
E::Target: FeeEstimator,
655629
F::Target: Filter + Sync + Send,
656630
K::Target: KVStore,
657631
L::Target: Logger,
632+
O::Target: OutputSpender,
658633
{
659634
fn transactions_confirmed(
660635
&self, header: &Header, txdata: &chain::transaction::TransactionData, height: u32,
@@ -749,50 +724,40 @@ impl_writeable_tlv_based!(SweeperState, {
749724
(2, best_block, required),
750725
});
751726

752-
impl<B: Deref, F: Deref, K: Deref, L: Deref>
753-
ReadableArgs<(
754-
B,
755-
Option<F>,
756-
K,
757-
L,
758-
Box<
759-
dyn Fn(&[&SpendableOutputDescriptor]) -> Result<Transaction, ()>
760-
+ Send
761-
+ Sync
762-
+ 'static,
763-
>,
764-
)> for OutputSweeper<B, F, K, L>
727+
impl<B: Deref, D: Deref, E: Deref, F: Deref, K: Deref, L: Deref, O: Deref>
728+
ReadableArgs<(B, E, Option<F>, O, D, K, L)> for OutputSweeper<B, D, E, F, K, L, O>
765729
where
766730
B::Target: BroadcasterInterface,
731+
D::Target: ChangeDestinationSource,
732+
E::Target: FeeEstimator,
767733
F::Target: Filter + Sync + Send,
768734
K::Target: KVStore,
769735
L::Target: Logger,
736+
O::Target: OutputSpender,
770737
{
771738
#[inline]
772739
fn read<R: io::Read>(
773-
reader: &mut R,
774-
args: (
775-
B,
776-
Option<F>,
777-
K,
778-
L,
779-
Box<
780-
dyn Fn(&[&SpendableOutputDescriptor]) -> Result<Transaction, ()>
781-
+ Send
782-
+ Sync
783-
+ 'static,
784-
>,
785-
),
740+
reader: &mut R, args: (B, E, Option<F>, O, D, K, L),
786741
) -> Result<Self, DecodeError> {
787-
let (broadcaster, chain_data_source, kv_store, logger, spend_outputs_callback) = args;
742+
let (
743+
broadcaster,
744+
fee_estimator,
745+
chain_data_source,
746+
output_spender,
747+
change_destination_source,
748+
kv_store,
749+
logger,
750+
) = args;
788751
let sweeper_state = Readable::read(reader)?;
789752
Ok(Self {
790753
sweeper_state,
791754
broadcaster,
792-
kv_store,
755+
fee_estimator,
793756
chain_data_source,
757+
output_spender,
758+
change_destination_source,
759+
kv_store,
794760
logger,
795-
spend_outputs_callback,
796761
})
797762
}
798763
}

0 commit comments

Comments
 (0)