Skip to content

Commit 405dcec

Browse files
committed
WIP: Impl Anchors
TODO: - Decide how to expose enforcing/non-enforcing anchors - check reserve for enforcing variant
1 parent ca4e0da commit 405dcec

File tree

5 files changed

+136
-12
lines changed

5 files changed

+136
-12
lines changed

src/builder.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -550,12 +550,9 @@ fn build_with_store_internal<K: KVStore + Sync + Send + 'static>(
550550
// Initialize the ChannelManager
551551
let mut user_config = UserConfig::default();
552552
user_config.channel_handshake_limits.force_announced_channel_preference = false;
553+
user_config.manually_accept_inbound_channels = true;
554+
user_config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
553555

554-
if !config.trusted_peers_0conf.is_empty() {
555-
// Manually accept inbound channels if we expect 0conf channel requests, avoid
556-
// generating the events otherwise.
557-
user_config.manually_accept_inbound_channels = true;
558-
}
559556
let channel_manager = {
560557
if let Ok(res) = kv_store.read(
561558
CHANNEL_MANAGER_PERSISTENCE_PRIMARY_NAMESPACE,

src/event.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::{
2-
hex_utils, ChannelManager, Config, Error, KeysManager, NetworkGraph, UserChannelId, Wallet,
2+
hex_utils, BumpTransactionEventHandler, ChannelManager, Config, Error, KeysManager,
3+
NetworkGraph, UserChannelId, Wallet,
34
};
45

56
use crate::payment_store::{
@@ -242,8 +243,9 @@ pub(crate) struct EventHandler<K: KVStore + Sync + Send, L: Deref>
242243
where
243244
L::Target: Logger,
244245
{
245-
wallet: Arc<Wallet<bdk::database::SqliteDatabase, L>>,
246246
event_queue: Arc<EventQueue<K, L>>,
247+
wallet: Arc<Wallet<bdk::database::SqliteDatabase, L>>,
248+
bump_tx_event_handler: Arc<BumpTransactionEventHandler>,
247249
channel_manager: Arc<ChannelManager<K>>,
248250
network_graph: Arc<NetworkGraph>,
249251
keys_manager: Arc<KeysManager>,
@@ -258,14 +260,16 @@ where
258260
L::Target: Logger,
259261
{
260262
pub fn new(
261-
wallet: Arc<Wallet<bdk::database::SqliteDatabase, L>>, event_queue: Arc<EventQueue<K, L>>,
263+
event_queue: Arc<EventQueue<K, L>>, wallet: Arc<Wallet<bdk::database::SqliteDatabase, L>>,
264+
bump_tx_event_handler: Arc<BumpTransactionEventHandler>,
262265
channel_manager: Arc<ChannelManager<K>>, network_graph: Arc<NetworkGraph>,
263266
keys_manager: Arc<KeysManager>, payment_store: Arc<PaymentStore<K, L>>,
264267
runtime: Arc<RwLock<Option<tokio::runtime::Runtime>>>, logger: L, config: Arc<Config>,
265268
) -> Self {
266269
Self {
267270
event_queue,
268271
wallet,
272+
bump_tx_event_handler,
269273
channel_manager,
270274
network_graph,
271275
keys_manager,
@@ -780,7 +784,9 @@ where
780784
}
781785
LdkEvent::DiscardFunding { .. } => {}
782786
LdkEvent::HTLCIntercepted { .. } => {}
783-
LdkEvent::BumpTransaction(_) => {}
787+
LdkEvent::BumpTransaction(bte) => {
788+
self.bump_tx_event_handler.handle_event(&bte);
789+
}
784790
}
785791
}
786792
}

src/lib.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,17 @@ use gossip::GossipSource;
118118
use payment_store::PaymentStore;
119119
pub use payment_store::{PaymentDetails, PaymentDirection, PaymentStatus};
120120
use peer_store::{PeerInfo, PeerStore};
121-
use types::{ChainMonitor, ChannelManager, KeysManager, NetworkGraph, PeerManager, Router, Scorer};
121+
use types::{
122+
BumpTransactionEventHandler, ChainMonitor, ChannelManager, KeysManager, NetworkGraph,
123+
PeerManager, Router, Scorer,
124+
};
122125
pub use types::{ChannelDetails, PeerDetails, UserChannelId};
123126
use wallet::Wallet;
124127

125128
use logger::{log_error, log_info, log_trace, FilesystemLogger, Logger};
126129

127130
use lightning::chain::Confirm;
131+
use lightning::events::bump_transaction::Wallet as LdkWallet;
128132
use lightning::ln::channelmanager::{self, PaymentId, RecipientOnionFields, Retry};
129133
use lightning::ln::{ChannelId, PaymentHash, PaymentPreimage};
130134
use lightning::sign::EntropySource;
@@ -645,9 +649,17 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
645649
}
646650
});
647651

648-
let event_handler = Arc::new(EventHandler::new(
652+
let bump_tx_event_handler = Arc::new(BumpTransactionEventHandler::new(
649653
Arc::clone(&self.wallet),
654+
Arc::new(LdkWallet::new(Arc::clone(&self.wallet), Arc::clone(&self.logger))),
655+
Arc::clone(&self.keys_manager),
656+
Arc::clone(&self.logger),
657+
));
658+
659+
let event_handler = Arc::new(EventHandler::new(
650660
Arc::clone(&self.event_queue),
661+
Arc::clone(&self.wallet),
662+
bump_tx_event_handler,
651663
Arc::clone(&self.channel_manager),
652664
Arc::clone(&self.network_graph),
653665
Arc::clone(&self.keys_manager),

src/types.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,19 @@ impl lightning::onion_message::MessageRouter for FakeMessageRouter {
107107
}
108108
}
109109

110+
pub(crate) type BumpTransactionEventHandler =
111+
lightning::events::bump_transaction::BumpTransactionEventHandler<
112+
Arc<Wallet<bdk::database::SqliteDatabase, Arc<FilesystemLogger>>>,
113+
Arc<
114+
lightning::events::bump_transaction::Wallet<
115+
Arc<Wallet<bdk::database::SqliteDatabase, Arc<FilesystemLogger>>>,
116+
Arc<FilesystemLogger>,
117+
>,
118+
>,
119+
Arc<WalletKeysManager<bdk::database::SqliteDatabase, Arc<FilesystemLogger>>>,
120+
Arc<FilesystemLogger>,
121+
>;
122+
110123
/// A local, potentially user-provided, identifier of a channel.
111124
///
112125
/// By default, this will be randomly generated for the user to ensure local uniqueness.

src/wallet.rs

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use lightning::chain::chaininterface::{
66
BroadcasterInterface, ConfirmationTarget, FeeEstimator, FEERATE_FLOOR_SATS_PER_KW,
77
};
88

9+
use lightning::events::bump_transaction::{Utxo, WalletSource};
910
use lightning::ln::msgs::{DecodeError, UnsignedGossipMessage};
1011
use lightning::ln::script::ShutdownScript;
1112
use lightning::sign::{
@@ -21,10 +22,13 @@ use bdk::wallet::AddressIndex;
2122
use bdk::{FeeRate, SignOptions, SyncOptions};
2223

2324
use bitcoin::bech32::u5;
25+
use bitcoin::hashes::Hash;
2426
use bitcoin::secp256k1::ecdh::SharedSecret;
2527
use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature};
2628
use bitcoin::secp256k1::{PublicKey, Scalar, Secp256k1, Signing};
27-
use bitcoin::{LockTime, PackedLockTime, Script, Transaction, TxOut, Txid};
29+
use bitcoin::util::address::WitnessVersion;
30+
use bitcoin::util::psbt::PartiallySignedTransaction;
31+
use bitcoin::{LockTime, PackedLockTime, Script, Transaction, TxOut, Txid, WPubkeyHash};
2832

2933
use std::collections::HashMap;
3034
use std::ops::Deref;
@@ -347,6 +351,98 @@ where
347351
}
348352
}
349353

354+
impl<D, L: Deref> WalletSource for Wallet<D, L>
355+
where
356+
D: BatchDatabase,
357+
L::Target: Logger,
358+
{
359+
fn list_confirmed_utxos(&self) -> Result<Vec<Utxo>, ()> {
360+
let locked_wallet = self.inner.lock().unwrap();
361+
let mut utxos = Vec::new();
362+
let txs = locked_wallet.list_transactions(true).map_err(|e| {
363+
log_error!(self.logger, "Failed to retrieve transactions from wallet: {}", e);
364+
})?;
365+
let unspent = locked_wallet.list_unspent().map_err(|e| {
366+
log_error!(self.logger, "Failed to retrieve unspent transactions from wallet: {}", e);
367+
})?;
368+
369+
for u in unspent {
370+
for t in &txs {
371+
if u.outpoint.txid == t.txid && t.confirmation_time.is_some() {
372+
let payload =
373+
bitcoin::util::address::Payload::from_script(&u.txout.script_pubkey)
374+
.map_err(|e| {
375+
log_error!(self.logger, "Failed to retrieve script payload: {}", e);
376+
})?;
377+
378+
match payload {
379+
bitcoin::util::address::Payload::WitnessProgram { version, program } => {
380+
if version == WitnessVersion::V0 && program.len() == 20 {
381+
let wpkh = WPubkeyHash::from_slice(&program).map_err(|e| {
382+
log_error!(
383+
self.logger,
384+
"Failed to retrieve script payload: {}",
385+
e
386+
);
387+
})?;
388+
let utxo = Utxo::new_v0_p2wpkh(u.outpoint, u.txout.value, &wpkh);
389+
utxos.push(utxo);
390+
} else {
391+
log_error!(
392+
self.logger,
393+
"Unexpected program length: {}",
394+
program.len()
395+
);
396+
}
397+
}
398+
_ => {
399+
log_error!(
400+
self.logger,
401+
"Tried to use a non-witness script. This must never happen."
402+
);
403+
panic!("Tried to use a non-witness script. This must never happen.");
404+
}
405+
}
406+
}
407+
}
408+
}
409+
410+
Ok(utxos)
411+
}
412+
413+
fn get_change_script(&self) -> Result<Script, ()> {
414+
let locked_wallet = self.inner.lock().unwrap();
415+
let address_info = locked_wallet.get_address(AddressIndex::New).map_err(|e| {
416+
log_error!(self.logger, "Failed to retrieve new address from wallet: {}", e);
417+
})?;
418+
419+
Ok(address_info.address.script_pubkey())
420+
}
421+
422+
fn sign_tx(&self, tx: Transaction) -> Result<Transaction, ()> {
423+
let locked_wallet = self.inner.lock().unwrap();
424+
425+
let mut psbt = PartiallySignedTransaction::from_unsigned_tx(tx.clone()).map_err(|e| {
426+
log_error!(self.logger, "Failed to create PSBT: {}", e);
427+
})?;
428+
429+
match locked_wallet.sign(&mut psbt, SignOptions::default()) {
430+
Ok(finalized) => {
431+
if !finalized {
432+
log_error!(self.logger, "Failed to finalize PSBT.");
433+
return Err(());
434+
}
435+
}
436+
Err(err) => {
437+
log_error!(self.logger, "Failed to sign transaction: {}", err);
438+
return Err(());
439+
}
440+
}
441+
442+
Ok(psbt.extract_tx())
443+
}
444+
}
445+
350446
/// Similar to [`KeysManager`], but overrides the destination and shutdown scripts so they are
351447
/// directly spendable by the BDK wallet.
352448
pub struct WalletKeysManager<D, L: Deref>

0 commit comments

Comments
 (0)