Skip to content

Commit 340cdd5

Browse files
committed
WIP: Impl Anchors
TODO: - Decide how to expose enforcing/non-enforcing anchors - check reserve for enforcing variant
1 parent 03dd0e1 commit 340cdd5

File tree

5 files changed

+137
-13
lines changed

5 files changed

+137
-13
lines changed

src/builder.rs

+2-5
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

+10-5
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

+14-2
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

+12
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

+99-1
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,100 @@ 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: &mut Transaction) -> Result<(), ()> {
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+
*tx = psbt.extract_tx();
443+
444+
Ok(())
445+
}
446+
}
447+
350448
/// Similar to [`KeysManager`], but overrides the destination and shutdown scripts so they are
351449
/// directly spendable by the BDK wallet.
352450
pub struct WalletKeysManager<D, L: Deref>

0 commit comments

Comments
 (0)