Skip to content

Commit eaf2b96

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

File tree

5 files changed

+137
-13
lines changed

5 files changed

+137
-13
lines changed

src/builder.rs

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

552-
if !config.trusted_peers_0conf.is_empty() {
553-
// Manually accept inbound channels if we expect 0conf channel requests, avoid
554-
// generating the events otherwise.
555-
user_config.manually_accept_inbound_channels = true;
556-
}
557554
let channel_manager = {
558555
if let Ok(mut reader) =
559556
kv_store.read(CHANNEL_MANAGER_PERSISTENCE_NAMESPACE, CHANNEL_MANAGER_PERSISTENCE_KEY)

src/event.rs

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

66
use crate::payment_store::{
@@ -223,8 +223,9 @@ pub(crate) struct EventHandler<K: KVStore + Sync + Send, L: Deref>
223223
where
224224
L::Target: Logger,
225225
{
226-
wallet: Arc<Wallet<bdk::database::SqliteDatabase, L>>,
227226
event_queue: Arc<EventQueue<K, L>>,
227+
wallet: Arc<Wallet<bdk::database::SqliteDatabase, L>>,
228+
bump_tx_event_handler: Arc<BumpTransactionEventHandler>,
228229
channel_manager: Arc<ChannelManager<K>>,
229230
network_graph: Arc<NetworkGraph>,
230231
keys_manager: Arc<KeysManager>,
@@ -239,14 +240,16 @@ where
239240
L::Target: Logger,
240241
{
241242
pub fn new(
242-
wallet: Arc<Wallet<bdk::database::SqliteDatabase, L>>, event_queue: Arc<EventQueue<K, L>>,
243+
event_queue: Arc<EventQueue<K, L>>, wallet: Arc<Wallet<bdk::database::SqliteDatabase, L>>,
244+
bump_tx_event_handler: Arc<BumpTransactionEventHandler>,
243245
channel_manager: Arc<ChannelManager<K>>, network_graph: Arc<NetworkGraph>,
244246
keys_manager: Arc<KeysManager>, payment_store: Arc<PaymentStore<K, L>>,
245247
runtime: Arc<RwLock<Option<tokio::runtime::Runtime>>>, logger: L, config: Arc<Config>,
246248
) -> Self {
247249
Self {
248250
event_queue,
249251
wallet,
252+
bump_tx_event_handler,
250253
channel_manager,
251254
network_graph,
252255
keys_manager,
@@ -760,7 +763,9 @@ where
760763
}
761764
LdkEvent::DiscardFunding { .. } => {}
762765
LdkEvent::HTLCIntercepted { .. } => {}
763-
LdkEvent::BumpTransaction(_) => {}
766+
LdkEvent::BumpTransaction(bte) => {
767+
self.bump_tx_event_handler.handle_event(&bte);
768+
}
764769
}
765770
}
766771
}

src/lib.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,17 @@ use io::KVStore;
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, Scorer};
121+
use types::{
122+
BumpTransactionEventHandler, ChainMonitor, ChannelManager, KeysManager, NetworkGraph,
123+
PeerManager, Scorer,
124+
};
122125
pub use types::{ChannelDetails, ChannelId, 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::{PaymentHash, PaymentPreimage};
130134
use lightning::sign::EntropySource;
@@ -634,9 +638,17 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
634638
}
635639
});
636640

637-
let event_handler = Arc::new(EventHandler::new(
641+
let bump_tx_event_handler = Arc::new(BumpTransactionEventHandler::new(
638642
Arc::clone(&self.wallet),
643+
Arc::new(LdkWallet::new(Arc::clone(&self.wallet))),
644+
Arc::clone(&self.keys_manager),
645+
Arc::clone(&self.logger),
646+
));
647+
648+
let event_handler = Arc::new(EventHandler::new(
639649
Arc::clone(&self.event_queue),
650+
Arc::clone(&self.wallet),
651+
bump_tx_event_handler,
640652
Arc::clone(&self.channel_manager),
641653
Arc::clone(&self.network_graph),
642654
Arc::clone(&self.keys_manager),

src/types.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,18 @@ impl lightning::onion_message::MessageRouter for FakeMessageRouter {
105105
}
106106
}
107107

108+
pub(crate) type BumpTransactionEventHandler =
109+
lightning::events::bump_transaction::BumpTransactionEventHandler<
110+
Arc<Wallet<bdk::database::SqliteDatabase, Arc<FilesystemLogger>>>,
111+
Arc<
112+
lightning::events::bump_transaction::Wallet<
113+
Arc<Wallet<bdk::database::SqliteDatabase, Arc<FilesystemLogger>>>,
114+
>,
115+
>,
116+
Arc<WalletKeysManager<bdk::database::SqliteDatabase, Arc<FilesystemLogger>>>,
117+
Arc<FilesystemLogger>,
118+
>;
119+
108120
/// The global identifier of a channel.
109121
///
110122
/// Note that this will start out to be a temporary ID until channel funding negotiation is

src/wallet.rs

Lines changed: 99 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;
@@ -344,6 +348,100 @@ where
344348
}
345349
}
346350

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

0 commit comments

Comments
 (0)