8
8
//! [`SpendableOutputDescriptor`]s, i.e., persists them in a given [`KVStore`] and regularly retries
9
9
//! sweeping them.
10
10
11
- use crate :: chain:: chaininterface:: BroadcasterInterface ;
11
+ use crate :: chain:: chaininterface:: { BroadcasterInterface , ConfirmationTarget , FeeEstimator } ;
12
12
use crate :: chain:: channelmonitor:: ANTI_REORG_DELAY ;
13
13
use crate :: chain:: { self , BestBlock , Confirm , Filter , Listen , WatchedOutput } ;
14
14
use crate :: io;
15
15
use crate :: ln:: msgs:: DecodeError ;
16
16
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 } ;
19
19
use crate :: sync:: Mutex ;
20
20
use crate :: util:: logger:: Logger ;
21
21
use crate :: util:: persist:: {
@@ -26,6 +26,8 @@ use crate::util::ser::{Readable, ReadableArgs, Writeable};
26
26
use crate :: { impl_writeable_tlv_based, log_debug, log_error} ;
27
27
28
28
use bitcoin:: blockdata:: block:: Header ;
29
+ use bitcoin:: blockdata:: locktime:: absolute:: LockTime ;
30
+ use bitcoin:: secp256k1:: Secp256k1 ;
29
31
use bitcoin:: { BlockHash , Transaction , Txid } ;
30
32
31
33
use core:: ops:: Deref ;
@@ -307,121 +309,66 @@ impl_writeable_tlv_based_enum!(OutputSpendStatus,
307
309
/// constructor.
308
310
///
309
311
/// [`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 >
311
313
where
312
314
B :: Target : BroadcasterInterface ,
315
+ D :: Target : ChangeDestinationSource ,
316
+ E :: Target : FeeEstimator ,
313
317
F :: Target : Filter + Sync + Send ,
314
318
K :: Target : KVStore ,
315
319
L :: Target : Logger ,
320
+ O :: Target : OutputSpender ,
316
321
{
317
322
sweeper_state : Mutex < SweeperState > ,
318
323
broadcaster : B ,
319
- kv_store : K ,
324
+ fee_estimator : E ,
320
325
chain_data_source : Option < F > ,
326
+ output_spender : O ,
327
+ change_destination_source : D ,
328
+ kv_store : K ,
321
329
logger : L ,
322
- spend_outputs_callback : Box <
323
- dyn Fn ( & [ & SpendableOutputDescriptor ] ) -> Result < Transaction , ( ) > + Send + Sync + ' static ,
324
- > ,
325
330
}
326
331
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 >
328
334
where
329
335
B :: Target : BroadcasterInterface ,
336
+ D :: Target : ChangeDestinationSource ,
337
+ E :: Target : FeeEstimator ,
330
338
F :: Target : Filter + Sync + Send ,
331
339
K :: Target : KVStore ,
332
340
L :: Target : Logger ,
341
+ O :: Target : OutputSpender ,
333
342
{
334
343
/// Constructs a new [`OutputSweeper`].
335
344
///
336
345
/// If chain data is provided via the [`Confirm`] interface or via filtered blocks, users also
337
346
/// 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
- ///```
395
347
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 ,
402
350
) -> Self {
403
351
let outputs = Vec :: new ( ) ;
404
352
Self :: from_outputs (
405
353
outputs,
406
- broadcaster,
407
- kv_store,
408
354
best_block,
355
+ broadcaster,
356
+ fee_estimator,
409
357
chain_data_source,
358
+ output_spender,
359
+ change_destination_source,
360
+ kv_store,
410
361
logger,
411
- spend_outputs_callback,
412
362
)
413
363
}
414
364
415
365
/// Constructs an [`OutputSweeper`] from the given list of [`TrackedSpendableOutput`]s.
416
366
///
417
367
/// See [`Self::new`] for more information regarding the remaining arguments.
418
368
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 ,
425
372
) -> Self {
426
373
if let Some ( filter) = chain_data_source. as_ref ( ) {
427
374
for output_info in & outputs {
@@ -431,14 +378,15 @@ where
431
378
}
432
379
433
380
let sweeper_state = Mutex :: new ( SweeperState { outputs, best_block } ) ;
434
- let spend_outputs_callback = Box :: new ( spend_outputs_callback) ;
435
381
Self {
436
382
sweeper_state,
437
383
broadcaster,
438
- kv_store ,
384
+ fee_estimator ,
439
385
chain_data_source,
386
+ output_spender,
387
+ change_destination_source,
388
+ kv_store,
440
389
logger,
441
- spend_outputs_callback,
442
390
}
443
391
}
444
392
@@ -532,7 +480,7 @@ where
532
480
return None ;
533
481
}
534
482
535
- let spending_tx = match ( self . spend_outputs_callback ) ( & respend_descriptors) {
483
+ let spending_tx = match self . spend_outputs ( & * sweeper_state , respend_descriptors) {
536
484
Ok ( spending_tx) => {
537
485
log_debug ! (
538
486
self . logger,
@@ -600,14 +548,37 @@ where
600
548
e
601
549
} )
602
550
}
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
+ }
603
570
}
604
571
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 >
606
574
where
607
575
B :: Target : BroadcasterInterface ,
576
+ D :: Target : ChangeDestinationSource ,
577
+ E :: Target : FeeEstimator ,
608
578
F :: Target : Filter + Sync + Send ,
609
579
K :: Target : KVStore ,
610
580
L :: Target : Logger ,
581
+ O :: Target : OutputSpender ,
611
582
{
612
583
fn filtered_block_connected (
613
584
& self , header : & Header , txdata : & chain:: transaction:: TransactionData , height : u32 ,
@@ -649,12 +620,16 @@ where
649
620
}
650
621
}
651
622
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 >
653
625
where
654
626
B :: Target : BroadcasterInterface ,
627
+ D :: Target : ChangeDestinationSource ,
628
+ E :: Target : FeeEstimator ,
655
629
F :: Target : Filter + Sync + Send ,
656
630
K :: Target : KVStore ,
657
631
L :: Target : Logger ,
632
+ O :: Target : OutputSpender ,
658
633
{
659
634
fn transactions_confirmed (
660
635
& self , header : & Header , txdata : & chain:: transaction:: TransactionData , height : u32 ,
@@ -749,50 +724,40 @@ impl_writeable_tlv_based!(SweeperState, {
749
724
( 2 , best_block, required) ,
750
725
} ) ;
751
726
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 >
765
729
where
766
730
B :: Target : BroadcasterInterface ,
731
+ D :: Target : ChangeDestinationSource ,
732
+ E :: Target : FeeEstimator ,
767
733
F :: Target : Filter + Sync + Send ,
768
734
K :: Target : KVStore ,
769
735
L :: Target : Logger ,
736
+ O :: Target : OutputSpender ,
770
737
{
771
738
#[ inline]
772
739
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 ) ,
786
741
) -> 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;
788
751
let sweeper_state = Readable :: read ( reader) ?;
789
752
Ok ( Self {
790
753
sweeper_state,
791
754
broadcaster,
792
- kv_store ,
755
+ fee_estimator ,
793
756
chain_data_source,
757
+ output_spender,
758
+ change_destination_source,
759
+ kv_store,
794
760
logger,
795
- spend_outputs_callback,
796
761
} )
797
762
}
798
763
}
0 commit comments