Skip to content

Commit 3bc7c2d

Browse files
committed
WIP: Impl Anchors
TODO: - Decide how to expose enforcing/non-enforcing anchors - check reserve for enforcing variant
1 parent 5b20403 commit 3bc7c2d

File tree

5 files changed

+130
-16
lines changed

5 files changed

+130
-16
lines changed

src/builder.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -591,12 +591,9 @@ fn build_with_store_internal<K: KVStore + Sync + Send + 'static>(
591591
// Initialize the ChannelManager
592592
let mut user_config = UserConfig::default();
593593
user_config.channel_handshake_limits.force_announced_channel_preference = false;
594+
user_config.manually_accept_inbound_channels = true;
595+
user_config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
594596

595-
if !config.trusted_peers_0conf.is_empty() {
596-
// Manually accept inbound channels if we expect 0conf channel requests, avoid
597-
// generating the events otherwise.
598-
user_config.manually_accept_inbound_channels = true;
599-
}
600597
let channel_manager = {
601598
if let Ok(res) = kv_store.read(
602599
CHANNEL_MANAGER_PERSISTENCE_PRIMARY_NAMESPACE,

src/event.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::types::{Sweeper, Wallet};
22
use crate::{
3-
hex_utils, ChannelManager, Config, Error, NetworkGraph, PeerInfo, PeerStore, UserChannelId,
3+
hex_utils, BumpTransactionEventHandler, ChannelManager, Config, Error, NetworkGraph, PeerInfo,
4+
PeerStore, UserChannelId,
45
};
56

67
use crate::payment_store::{
@@ -246,6 +247,7 @@ where
246247
{
247248
event_queue: Arc<EventQueue<K, L>>,
248249
wallet: Arc<Wallet>,
250+
bump_tx_event_handler: Arc<BumpTransactionEventHandler>,
249251
channel_manager: Arc<ChannelManager<K>>,
250252
output_sweeper: Arc<Sweeper<K>>,
251253
network_graph: Arc<NetworkGraph>,
@@ -263,13 +265,14 @@ where
263265
pub fn new(
264266
event_queue: Arc<EventQueue<K, L>>, wallet: Arc<Wallet>,
265267
channel_manager: Arc<ChannelManager<K>>, output_sweeper: Arc<Sweeper<K>>,
266-
network_graph: Arc<NetworkGraph>, payment_store: Arc<PaymentStore<K, L>>,
267-
peer_store: Arc<PeerStore<K, L>>, runtime: Arc<RwLock<Option<tokio::runtime::Runtime>>>,
268-
logger: L, config: Arc<Config>,
268+
bump_tx_event_handler: Arc<BumpTransactionEventHandler>, network_graph: Arc<NetworkGraph>,
269+
payment_store: Arc<PaymentStore<K, L>>, peer_store: Arc<PeerStore<K, L>>,
270+
runtime: Arc<RwLock<Option<tokio::runtime::Runtime>>>, logger: L, config: Arc<Config>,
269271
) -> Self {
270272
Self {
271273
event_queue,
272274
wallet,
275+
bump_tx_event_handler,
273276
channel_manager,
274277
output_sweeper,
275278
network_graph,
@@ -785,7 +788,9 @@ where
785788
}
786789
LdkEvent::DiscardFunding { .. } => {}
787790
LdkEvent::HTLCIntercepted { .. } => {}
788-
LdkEvent::BumpTransaction(_) => {}
791+
LdkEvent::BumpTransaction(bte) => {
792+
self.bump_tx_event_handler.handle_event(&bte);
793+
}
789794
LdkEvent::InvoiceRequestFailed { .. } => {}
790795
LdkEvent::ConnectionNeeded { .. } => {}
791796
}

src/lib.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,14 +119,15 @@ use payment_store::PaymentStore;
119119
pub use payment_store::{PaymentDetails, PaymentDirection, PaymentStatus};
120120
use peer_store::{PeerInfo, PeerStore};
121121
use types::{
122-
Broadcaster, ChainMonitor, ChannelManager, FeeEstimator, KeysManager, NetworkGraph,
123-
PeerManager, Router, Scorer, Sweeper, Wallet,
122+
Broadcaster, BumpTransactionEventHandler, ChainMonitor, ChannelManager, FeeEstimator,
123+
KeysManager, NetworkGraph, PeerManager, Router, Scorer, Sweeper, Wallet,
124124
};
125125
pub use types::{ChannelDetails, Network, PeerDetails, UserChannelId};
126126

127127
use logger::{log_error, log_info, log_trace, FilesystemLogger, Logger};
128128

129129
use lightning::chain::Confirm;
130+
use lightning::events::bump_transaction::Wallet as LdkWallet;
130131
use lightning::ln::channelmanager::{self, PaymentId, RecipientOnionFields, Retry};
131132
use lightning::ln::msgs::SocketAddress;
132133
use lightning::ln::{ChannelId, PaymentHash, PaymentPreimage};
@@ -691,11 +692,19 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
691692
}
692693
});
693694

695+
let bump_tx_event_handler = Arc::new(BumpTransactionEventHandler::new(
696+
Arc::clone(&self.tx_broadcaster),
697+
Arc::new(LdkWallet::new(Arc::clone(&self.wallet), Arc::clone(&self.logger))),
698+
Arc::clone(&self.keys_manager),
699+
Arc::clone(&self.logger),
700+
));
701+
694702
let event_handler = Arc::new(EventHandler::new(
695703
Arc::clone(&self.event_queue),
696704
Arc::clone(&self.wallet),
697705
Arc::clone(&self.channel_manager),
698706
Arc::clone(&self.output_sweeper),
707+
bump_tx_event_handler,
699708
Arc::clone(&self.network_graph),
700709
Arc::clone(&self.payment_store),
701710
Arc::clone(&self.peer_store),

src/types.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,14 @@ impl FromStr for Network {
191191
}
192192
}
193193

194+
pub(crate) type BumpTransactionEventHandler =
195+
lightning::events::bump_transaction::BumpTransactionEventHandler<
196+
Arc<Broadcaster>,
197+
Arc<lightning::events::bump_transaction::Wallet<Arc<Wallet>, Arc<FilesystemLogger>>>,
198+
Arc<KeysManager>,
199+
Arc<FilesystemLogger>,
200+
>;
201+
194202
/// A local, potentially user-provided, identifier of a channel.
195203
///
196204
/// By default, this will be randomly generated for the user to ensure local uniqueness.

src/wallet.rs

Lines changed: 99 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::Error;
44

55
use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
66

7+
use lightning::events::bump_transaction::{Utxo, WalletSource};
78
use lightning::ln::msgs::{DecodeError, UnsignedGossipMessage};
89
use lightning::ln::script::ShutdownScript;
910
use lightning::sign::{
@@ -19,8 +20,12 @@ use bdk::wallet::AddressIndex;
1920
use bdk::FeeRate;
2021
use bdk::{SignOptions, SyncOptions};
2122

23+
use bitcoin::address::{Payload, WitnessVersion};
2224
use bitcoin::bech32::u5;
2325
use bitcoin::blockdata::locktime::absolute::LockTime;
26+
use bitcoin::hash_types::WPubkeyHash;
27+
use bitcoin::hashes::Hash;
28+
use bitcoin::psbt::PartiallySignedTransaction;
2429
use bitcoin::secp256k1::ecdh::SharedSecret;
2530
use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature};
2631
use bitcoin::secp256k1::{PublicKey, Scalar, Secp256k1, Signing};
@@ -245,6 +250,97 @@ where
245250
}
246251
}
247252

253+
impl<D, B: Deref, E: Deref, L: Deref> WalletSource for Wallet<D, B, E, L>
254+
where
255+
D: BatchDatabase,
256+
B::Target: BroadcasterInterface,
257+
E::Target: FeeEstimator,
258+
L::Target: Logger,
259+
{
260+
fn list_confirmed_utxos(&self) -> Result<Vec<Utxo>, ()> {
261+
let locked_wallet = self.inner.lock().unwrap();
262+
let mut utxos = Vec::new();
263+
let txs = locked_wallet.list_transactions(true).map_err(|e| {
264+
log_error!(self.logger, "Failed to retrieve transactions from wallet: {}", e);
265+
})?;
266+
let unspent = locked_wallet.list_unspent().map_err(|e| {
267+
log_error!(self.logger, "Failed to retrieve unspent transactions from wallet: {}", e);
268+
})?;
269+
270+
for u in unspent {
271+
for t in &txs {
272+
if u.outpoint.txid == t.txid && t.confirmation_time.is_some() {
273+
let payload = Payload::from_script(&u.txout.script_pubkey).map_err(|e| {
274+
log_error!(self.logger, "Failed to retrieve script payload: {}", e);
275+
})?;
276+
277+
match payload {
278+
Payload::WitnessProgram(program) => {
279+
if program.version() == WitnessVersion::V0
280+
&& program.program().len() == 20
281+
{
282+
let wpkh = WPubkeyHash::from_slice(program.program().as_bytes())
283+
.map_err(|e| {
284+
log_error!(
285+
self.logger,
286+
"Failed to retrieve script payload: {}",
287+
e
288+
);
289+
})?;
290+
let utxo = Utxo::new_v0_p2wpkh(u.outpoint, u.txout.value, &wpkh);
291+
utxos.push(utxo);
292+
} else {
293+
log_error!(
294+
self.logger,
295+
"Unexpected program length: {}",
296+
program.program().len()
297+
);
298+
}
299+
}
300+
_ => {
301+
log_error!(
302+
self.logger,
303+
"Tried to use a non-witness script. This must never happen."
304+
);
305+
panic!("Tried to use a non-witness script. This must never happen.");
306+
}
307+
}
308+
}
309+
}
310+
}
311+
312+
Ok(utxos)
313+
}
314+
315+
fn get_change_script(&self) -> Result<ScriptBuf, ()> {
316+
let locked_wallet = self.inner.lock().unwrap();
317+
let address_info = locked_wallet.get_address(AddressIndex::New).map_err(|e| {
318+
log_error!(self.logger, "Failed to retrieve new address from wallet: {}", e);
319+
})?;
320+
321+
Ok(address_info.address.script_pubkey())
322+
}
323+
324+
fn sign_psbt(&self, mut psbt: PartiallySignedTransaction) -> Result<Transaction, ()> {
325+
let locked_wallet = self.inner.lock().unwrap();
326+
327+
match locked_wallet.sign(&mut psbt, SignOptions::default()) {
328+
Ok(finalized) => {
329+
if !finalized {
330+
log_error!(self.logger, "Failed to finalize PSBT.");
331+
return Err(());
332+
}
333+
}
334+
Err(err) => {
335+
log_error!(self.logger, "Failed to sign transaction: {}", err);
336+
return Err(());
337+
}
338+
}
339+
340+
Ok(psbt.extract_tx())
341+
}
342+
}
343+
248344
/// Similar to [`KeysManager`], but overrides the destination and shutdown scripts so they are
249345
/// directly spendable by the BDK wallet.
250346
pub struct WalletKeysManager<D, B: Deref, E: Deref, L: Deref>
@@ -398,11 +494,10 @@ where
398494
})?;
399495

400496
match address.payload {
401-
bitcoin::address::Payload::WitnessProgram(program) => {
402-
ShutdownScript::new_witness_program(&program).map_err(|e| {
497+
Payload::WitnessProgram(program) => ShutdownScript::new_witness_program(&program)
498+
.map_err(|e| {
403499
log_error!(self.logger, "Invalid shutdown script: {:?}", e);
404-
})
405-
}
500+
}),
406501
_ => {
407502
log_error!(
408503
self.logger,

0 commit comments

Comments
 (0)