From dec090902cad7aa103af6f3491c5c3c42d17b214 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Tue, 1 Mar 2022 03:46:52 +0000 Subject: [PATCH 01/21] Make `as_directed_to` non-public ...as the bindings generation does not currently have the ability to map a reference to a `NodeId` inside a tuple. --- lightning/src/routing/gossip.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lightning/src/routing/gossip.rs b/lightning/src/routing/gossip.rs index bb14adefe07..d41866d2aa1 100644 --- a/lightning/src/routing/gossip.rs +++ b/lightning/src/routing/gossip.rs @@ -955,7 +955,7 @@ impl PartialEq for ChannelInfo { impl ChannelInfo { /// Returns a [`DirectedChannelInfo`] for the channel directed to the given `target` from a /// returned `source`, or `None` if `target` is not one of the channel's counterparties. - pub fn as_directed_to(&self, target: &NodeId) -> Option<(DirectedChannelInfo, &NodeId)> { + pub(crate) fn as_directed_to(&self, target: &NodeId) -> Option<(DirectedChannelInfo, &NodeId)> { if self.one_to_two.is_none() || self.two_to_one.is_none() { return None; } let (direction, source, outbound) = { if target == &self.node_one { From 292900fa06d9ee97b748be62b2b1cd045049fc89 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Tue, 29 Mar 2022 10:20:39 -0500 Subject: [PATCH 02/21] Restrict ChannelInfo::as_directed_from visibility Bindings can't handle references in return types, so reduce the visibility to pub(crate). --- lightning/src/routing/gossip.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lightning/src/routing/gossip.rs b/lightning/src/routing/gossip.rs index d41866d2aa1..c88252a15cd 100644 --- a/lightning/src/routing/gossip.rs +++ b/lightning/src/routing/gossip.rs @@ -972,7 +972,7 @@ impl ChannelInfo { /// Returns a [`DirectedChannelInfo`] for the channel directed from the given `source` to a /// returned `target`, or `None` if `source` is not one of the channel's counterparties. - pub fn as_directed_from(&self, source: &NodeId) -> Option<(DirectedChannelInfo, &NodeId)> { + pub(crate) fn as_directed_from(&self, source: &NodeId) -> Option<(DirectedChannelInfo, &NodeId)> { if self.one_to_two.is_none() || self.two_to_one.is_none() { return None; } let (direction, target, outbound) = { if source == &self.node_one { From c4de4c337d86a58e08391038a78f4a0ff3d7fca6 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 24 Dec 2022 04:16:48 +0000 Subject: [PATCH 03/21] Use an explicit `Sign` type on the `ChannelMonitor` read tuple The bindings currently get confused by the implicit `Sign` type, so we temporarily remove it on the `impl` here. --- lightning/src/chain/channelmonitor.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index 86f0d3de5ed..693e1dda5c7 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -4659,8 +4659,8 @@ where const MAX_ALLOC_SIZE: usize = 64*1024; -impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP)> - for (BlockHash, ChannelMonitor) { +impl<'a, 'b, ES: EntropySource, Signer: EcdsaChannelSigner, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP)> + for (BlockHash, ChannelMonitor) { fn read(reader: &mut R, args: (&'a ES, &'b SP)) -> Result { macro_rules! unwrap_obj { ($key: expr) => { From 74030c913062dba7fd7f41ac9492c0f8b9d572e2 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 22 Aug 2024 21:09:33 +0000 Subject: [PATCH 04/21] Export `outbound_payment` structs in their respective modules Re-exports in Rust make `use` statements a little shorter, but for otherwise don't materially change a crate's API. Sadly, the C bindings generator currently can't figure out re-exports, but it also exports everything into one global namespace, so it doesn't matter much anyway. --- fuzz/src/chanmon_consistency.rs | 4 ++-- fuzz/src/full_stack.rs | 3 ++- lightning/src/ln/bolt11_payment.rs | 5 +++-- lightning/src/ln/channelmanager.rs | 2 +- lightning/src/ln/invoice_utils.rs | 3 ++- lightning/src/ln/mod.rs | 2 +- 6 files changed, 11 insertions(+), 8 deletions(-) diff --git a/fuzz/src/chanmon_consistency.rs b/fuzz/src/chanmon_consistency.rs index 8929a579c74..98935c49bee 100644 --- a/fuzz/src/chanmon_consistency.rs +++ b/fuzz/src/chanmon_consistency.rs @@ -47,9 +47,9 @@ use lightning::events::MessageSendEventsProvider; use lightning::ln::channel::FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE; use lightning::ln::channel_state::ChannelDetails; use lightning::ln::channelmanager::{ - ChainParameters, ChannelManager, ChannelManagerReadArgs, PaymentId, PaymentSendFailure, - RecipientOnionFields, + ChainParameters, ChannelManager, ChannelManagerReadArgs, PaymentId, }; +use lightning::ln::outbound_payment::{RecipientOnionFields, PaymentSendFailure}; use lightning::ln::functional_test_utils::*; use lightning::ln::msgs::{ self, ChannelMessageHandler, CommitmentUpdate, DecodeError, Init, UpdateAddHTLC, diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index 90449248e32..bb193cac264 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -40,8 +40,9 @@ use lightning::chain::{BestBlock, ChannelMonitorUpdateStatus, Confirm, Listen}; use lightning::events::Event; use lightning::ln::channel_state::ChannelDetails; use lightning::ln::channelmanager::{ - ChainParameters, ChannelManager, InterceptId, PaymentId, RecipientOnionFields, Retry, + ChainParameters, ChannelManager, InterceptId, PaymentId, }; +use lightning::ln::outbound_payment::{RecipientOnionFields, Retry}; use lightning::ln::functional_test_utils::*; use lightning::ln::msgs::{self, DecodeError}; use lightning::ln::peer_handler::{ diff --git a/lightning/src/ln/bolt11_payment.rs b/lightning/src/ln/bolt11_payment.rs index d0655968a60..30d03f9f2bf 100644 --- a/lightning/src/ln/bolt11_payment.rs +++ b/lightning/src/ln/bolt11_payment.rs @@ -12,7 +12,7 @@ use bitcoin::hashes::Hash; use lightning_invoice::Bolt11Invoice; -use crate::ln::channelmanager::RecipientOnionFields; +use crate::ln::outbound_payment::RecipientOnionFields; use crate::ln::types::PaymentHash; use crate::routing::router::{PaymentParameters, RouteParameters}; @@ -161,7 +161,8 @@ mod tests { #[test] fn payment_metadata_end_to_end() { use crate::events::Event; - use crate::ln::channelmanager::{PaymentId, Retry}; + use crate::ln::channelmanager::PaymentId; + use crate::ln::outbound_payment::Retry; use crate::ln::functional_test_utils::*; use crate::ln::msgs::ChannelMessageHandler; diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index b3047930f61..09fc1e46007 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -111,7 +111,7 @@ use core::time::Duration; use core::ops::Deref; // Re-export this for use in the public API. -pub use crate::ln::outbound_payment::{Bolt12PaymentError, PaymentSendFailure, ProbeSendFailure, Retry, RetryableSendFailure, RecipientOnionFields}; +pub(crate) use crate::ln::outbound_payment::{Bolt12PaymentError, PaymentSendFailure, ProbeSendFailure, Retry, RetryableSendFailure, RecipientOnionFields}; use crate::ln::script::ShutdownScript; // We hold various information about HTLC relay in the HTLC objects in Channel itself: diff --git a/lightning/src/ln/invoice_utils.rs b/lightning/src/ln/invoice_utils.rs index 71686df59ce..79c6c96ca50 100644 --- a/lightning/src/ln/invoice_utils.rs +++ b/lightning/src/ln/invoice_utils.rs @@ -825,7 +825,8 @@ mod test { use crate::events::{MessageSendEvent, MessageSendEventsProvider}; use crate::ln::types::PaymentHash; use crate::ln::types::PaymentPreimage; - use crate::ln::channelmanager::{PhantomRouteHints, MIN_FINAL_CLTV_EXPIRY_DELTA, PaymentId, RecipientOnionFields, Retry}; + use crate::ln::channelmanager::{PhantomRouteHints, MIN_FINAL_CLTV_EXPIRY_DELTA, PaymentId}; + use crate::ln::outbound_payment::{RecipientOnionFields, Retry}; use crate::ln::functional_test_utils::*; use crate::ln::msgs::ChannelMessageHandler; use crate::routing::router::{PaymentParameters, RouteParameters}; diff --git a/lightning/src/ln/mod.rs b/lightning/src/ln/mod.rs index dceb52ab4ae..1a229159edd 100644 --- a/lightning/src/ln/mod.rs +++ b/lightning/src/ln/mod.rs @@ -49,7 +49,7 @@ pub mod channel; pub(crate) mod channel; pub(crate) mod onion_utils; -mod outbound_payment; +pub mod outbound_payment; pub mod wire; pub use onion_utils::create_payment_onion; From f40aa37ca8f6d25cb2131e0f4cece5a44da3f6c1 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sun, 5 Mar 2023 20:38:42 +0000 Subject: [PATCH 05/21] Avoid enums containing references with lifetimes Having struct fields with references to other structs is tough in our bindings logic, but even worse if the fields are in an enum. Its simplest to just take the clone penalty here. --- lightning/src/ln/channel.rs | 4 ++-- lightning/src/ln/channelmanager.rs | 2 +- lightning/src/ln/msgs.rs | 11 ++++++----- lightning/src/ln/offers_tests.rs | 2 +- lightning/src/ln/peer_handler.rs | 2 +- lightning/src/ln/priv_short_conf_tests.rs | 2 +- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index f21788e8bd2..f34e23dff81 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -7030,7 +7030,7 @@ impl Channel where return None; } }; - let our_node_sig = match node_signer.sign_gossip_message(msgs::UnsignedGossipMessage::ChannelAnnouncement(&announcement)) { + let our_node_sig = match node_signer.sign_gossip_message(msgs::UnsignedGossipMessage::ChannelAnnouncement(announcement.clone())) { Err(_) => { log_error!(logger, "Failed to generate node signature for channel_announcement. Channel will not be announced!"); return None; @@ -7076,7 +7076,7 @@ impl Channel where .map_err(|_| ChannelError::Ignore("Signer failed to retrieve own public key".to_owned()))?); let were_node_one = announcement.node_id_1 == our_node_key; - let our_node_sig = node_signer.sign_gossip_message(msgs::UnsignedGossipMessage::ChannelAnnouncement(&announcement)) + let our_node_sig = node_signer.sign_gossip_message(msgs::UnsignedGossipMessage::ChannelAnnouncement(announcement.clone())) .map_err(|_| ChannelError::Ignore("Failed to generate node signature for channel_announcement".to_owned()))?; match &self.context.holder_signer { ChannelSignerType::Ecdsa(ecdsa) => { diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 09fc1e46007..4333e7e50dc 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -4013,7 +4013,7 @@ where // If we returned an error and the `node_signer` cannot provide a signature for whatever // reason`, we wouldn't be able to receive inbound payments through the corresponding // channel. - let sig = self.node_signer.sign_gossip_message(msgs::UnsignedGossipMessage::ChannelUpdate(&unsigned)).unwrap(); + let sig = self.node_signer.sign_gossip_message(msgs::UnsignedGossipMessage::ChannelUpdate(unsigned.clone())).unwrap(); Ok(msgs::ChannelUpdate { signature: sig, diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index c176a8669d3..b821eb90c59 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -1165,16 +1165,17 @@ impl FromStr for SocketAddress { } /// Represents the set of gossip messages that require a signature from a node's identity key. -pub enum UnsignedGossipMessage<'a> { +#[derive(Clone)] +pub enum UnsignedGossipMessage { /// An unsigned channel announcement. - ChannelAnnouncement(&'a UnsignedChannelAnnouncement), + ChannelAnnouncement(UnsignedChannelAnnouncement), /// An unsigned channel update. - ChannelUpdate(&'a UnsignedChannelUpdate), + ChannelUpdate(UnsignedChannelUpdate), /// An unsigned node announcement. - NodeAnnouncement(&'a UnsignedNodeAnnouncement) + NodeAnnouncement(UnsignedNodeAnnouncement) } -impl<'a> Writeable for UnsignedGossipMessage<'a> { +impl Writeable for UnsignedGossipMessage { fn write(&self, writer: &mut W) -> Result<(), io::Error> { match self { UnsignedGossipMessage::ChannelAnnouncement(ref msg) => msg.write(writer), diff --git a/lightning/src/ln/offers_tests.rs b/lightning/src/ln/offers_tests.rs index 8bbf9a0ad7d..d0813bb43d9 100644 --- a/lightning/src/ln/offers_tests.rs +++ b/lightning/src/ln/offers_tests.rs @@ -126,7 +126,7 @@ fn announce_node_address<'a, 'b, 'c>( excess_data: Vec::new(), }; let signature = node.keys_manager.sign_gossip_message( - UnsignedGossipMessage::NodeAnnouncement(&announcement) + UnsignedGossipMessage::NodeAnnouncement(announcement.clone()) ).unwrap(); let msg = NodeAnnouncement { diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index 51695bba09a..b7c152b7798 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -2659,7 +2659,7 @@ impl sig, Err(_) => { diff --git a/lightning/src/ln/priv_short_conf_tests.rs b/lightning/src/ln/priv_short_conf_tests.rs index 83ff296e177..3883731ba06 100644 --- a/lightning/src/ln/priv_short_conf_tests.rs +++ b/lightning/src/ln/priv_short_conf_tests.rs @@ -517,7 +517,7 @@ fn test_scid_alias_returned() { fee_proportional_millionths: last_hop[0].counterparty.forwarding_info.as_ref().unwrap().fee_proportional_millionths, excess_data: Vec::new(), }; - let signature = nodes[1].keys_manager.sign_gossip_message(msgs::UnsignedGossipMessage::ChannelUpdate(&contents)).unwrap(); + let signature = nodes[1].keys_manager.sign_gossip_message(msgs::UnsignedGossipMessage::ChannelUpdate(contents.clone())).unwrap(); let msg = msgs::ChannelUpdate { signature, contents }; let mut err_data = Vec::new(); From 18f1e34fb6dc5ee8e86e0ea56f969df807b399e7 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 11 May 2024 20:05:15 +0000 Subject: [PATCH 06/21] Mark a few offers fields no-export as we have no mapping for them --- lightning/src/offers/parse.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lightning/src/offers/parse.rs b/lightning/src/offers/parse.rs index 8b9f64d8b39..1d08542468d 100644 --- a/lightning/src/offers/parse.rs +++ b/lightning/src/offers/parse.rs @@ -123,7 +123,8 @@ pub enum Bolt12ParseError { /// being parsed. InvalidBech32Hrp, /// The string could not be bech32 decoded. - Bech32(bech32::Error), + Bech32(/// This is not exported to bindings users as the details don't matter much + bech32::Error), /// The bech32 decoded string could not be decoded as the expected message type. Decode(DecodeError), /// The parsed message has invalid semantics. From 810e88c5cd50f1cf683a67470782b6aadbdc4e0c Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 11 May 2024 20:05:26 +0000 Subject: [PATCH 07/21] Use `[u8; 3]` not `CurrencyCode` to skip type aliases to primitives --- lightning/src/offers/offer.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lightning/src/offers/offer.rs b/lightning/src/offers/offer.rs index 27a79166bc3..8c22236e4e8 100644 --- a/lightning/src/offers/offer.rs +++ b/lightning/src/offers/offer.rs @@ -1023,14 +1023,14 @@ pub enum Amount { /// An amount of currency specified using ISO 4712. Currency { /// The currency that the amount is denominated in. - iso4217_code: CurrencyCode, + iso4217_code: [u8; 3], /// The amount in the currency unit adjusted by the ISO 4712 exponent (e.g., USD cents). amount: u64, }, } /// An ISO 4712 three-letter currency code (e.g., USD). -pub type CurrencyCode = [u8; 3]; +pub(crate) type CurrencyCode = [u8; 3]; /// Quantity of items supported by an [`Offer`]. #[derive(Clone, Copy, Debug, PartialEq)] From bda3c463611b4a9d8ffb3a88a80cf4e119a85e9e Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 21 Oct 2023 02:28:53 +0000 Subject: [PATCH 08/21] Hard-code scorer parameters to `ProbabilisticScoringFeeParameters` The scorer currently relies on an associated type for the fee parameters. This isn't supportable at all in bindings, and for lack of a better option we simply hard-code the parameter for all scorers to `ProbabilisticScoringFeeParameters`. --- lightning-background-processor/src/lib.rs | 6 ++-- lightning/src/ln/channelmanager.rs | 4 --- lightning/src/routing/router.rs | 40 +++++++++++++---------- lightning/src/routing/scoring.rs | 16 ++++++--- lightning/src/util/test_utils.rs | 5 ++- 5 files changed, 38 insertions(+), 33 deletions(-) diff --git a/lightning-background-processor/src/lib.rs b/lightning-background-processor/src/lib.rs index bbe1545d044..410f28a2e19 100644 --- a/lightning-background-processor/src/lib.rs +++ b/lightning-background-processor/src/lib.rs @@ -1141,8 +1141,6 @@ mod tests { Arc, Arc, Arc>, - (), - TestScorer, >, >, Arc, @@ -1404,10 +1402,10 @@ mod tests { } impl ScoreLookUp for TestScorer { + #[cfg(not(c_bindings))] type ScoreParams = (); fn channel_penalty_msat( - &self, _candidate: &CandidateRouteHop, _usage: ChannelUsage, - _score_params: &Self::ScoreParams, + &self, _candidate: &CandidateRouteHop, _usage: ChannelUsage, _score_params: &lightning::routing::scoring::ProbabilisticScoringFeeParameters ) -> u64 { unimplemented!(); } diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 4333e7e50dc..6bcf3099b6d 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -1165,8 +1165,6 @@ pub type SimpleArcChannelManager = ChannelManager< Arc, Arc, Arc>>, Arc>>>, - ProbabilisticScoringFeeParameters, - ProbabilisticScorer>>, Arc>, >>, Arc >; @@ -1196,8 +1194,6 @@ pub type SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, M, T, F, L> = &'g L, &'c KeysManager, &'h RwLock, &'g L>>, - ProbabilisticScoringFeeParameters, - ProbabilisticScorer<&'f NetworkGraph<&'g L>, &'g L> >, &'g L >; diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index a25609c89bb..969b60f39e2 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -45,32 +45,32 @@ pub use lightning_types::routing::{RouteHint, RouteHintHop}; /// /// Implements [`MessageRouter`] by delegating to [`DefaultMessageRouter`]. See those docs for /// privacy implications. -pub struct DefaultRouter>, L: Deref, ES: Deref, S: Deref, SP: Sized, Sc: ScoreLookUp> where +pub struct DefaultRouter>, L: Deref, ES: Deref, S: Deref> where L::Target: Logger, - S::Target: for <'a> LockableScore<'a, ScoreLookUp = Sc>, + S::Target: for <'a> LockableScore<'a>, ES::Target: EntropySource, { network_graph: G, logger: L, entropy_source: ES, scorer: S, - score_params: SP, + score_params: crate::routing::scoring::ProbabilisticScoringFeeParameters, } -impl>, L: Deref, ES: Deref, S: Deref, SP: Sized, Sc: ScoreLookUp> DefaultRouter where +impl>, L: Deref, ES: Deref, S: Deref> DefaultRouter where L::Target: Logger, - S::Target: for <'a> LockableScore<'a, ScoreLookUp = Sc>, + S::Target: for <'a> LockableScore<'a>, ES::Target: EntropySource, { /// Creates a new router. - pub fn new(network_graph: G, logger: L, entropy_source: ES, scorer: S, score_params: SP) -> Self { + pub fn new(network_graph: G, logger: L, entropy_source: ES, scorer: S, score_params: crate::routing::scoring::ProbabilisticScoringFeeParameters) -> Self { Self { network_graph, logger, entropy_source, scorer, score_params } } } -impl>, L: Deref, ES: Deref, S: Deref, SP: Sized, Sc: ScoreLookUp> Router for DefaultRouter where +impl>, L: Deref, ES: Deref, S: Deref> Router for DefaultRouter where L::Target: Logger, - S::Target: for <'a> LockableScore<'a, ScoreLookUp = Sc>, + S::Target: for <'a> LockableScore<'a>, ES::Target: EntropySource, { fn find_route( @@ -183,9 +183,9 @@ impl>, L: Deref, ES: Deref, S: Deref, SP: Size } } -impl< G: Deref>, L: Deref, ES: Deref, S: Deref, SP: Sized, Sc: ScoreLookUp> MessageRouter for DefaultRouter where +impl< G: Deref>, L: Deref, ES: Deref, S: Deref> MessageRouter for DefaultRouter where L::Target: Logger, - S::Target: for <'a> LockableScore<'a, ScoreLookUp = Sc>, + S::Target: for <'a> LockableScore<'a>, ES::Target: EntropySource, { fn find_path( @@ -270,8 +270,9 @@ impl<'a, S: Deref> ScorerAccountingForInFlightHtlcs<'a, S> where S::Target: Scor } impl<'a, S: Deref> ScoreLookUp for ScorerAccountingForInFlightHtlcs<'a, S> where S::Target: ScoreLookUp { + #[cfg(not(c_bindings))] type ScoreParams = ::ScoreParams; - fn channel_penalty_msat(&self, candidate: &CandidateRouteHop, usage: ChannelUsage, score_params: &Self::ScoreParams) -> u64 { + fn channel_penalty_msat(&self, candidate: &CandidateRouteHop, usage: ChannelUsage, score_params: &crate::routing::scoring::ProbabilisticScoringFeeParameters) -> u64 { let target = match candidate.target() { Some(target) => target, None => return self.scorer.channel_penalty_msat(candidate, usage, score_params), @@ -2079,7 +2080,7 @@ fn sort_first_hop_channels( pub fn find_route( our_node_pubkey: &PublicKey, route_params: &RouteParameters, network_graph: &NetworkGraph, first_hops: Option<&[&ChannelDetails]>, logger: L, - scorer: &S, score_params: &S::ScoreParams, random_seed_bytes: &[u8; 32] + scorer: &S, score_params: &crate::routing::scoring::ProbabilisticScoringFeeParameters, random_seed_bytes: &[u8; 32] ) -> Result where L::Target: Logger, GL::Target: Logger { let graph_lock = network_graph.read_only(); @@ -2091,7 +2092,7 @@ where L::Target: Logger, GL::Target: Logger { pub(crate) fn get_route( our_node_pubkey: &PublicKey, route_params: &RouteParameters, network_graph: &ReadOnlyNetworkGraph, - first_hops: Option<&[&ChannelDetails]>, logger: L, scorer: &S, score_params: &S::ScoreParams, + first_hops: Option<&[&ChannelDetails]>, logger: L, scorer: &S, score_params: &crate::routing::scoring::ProbabilisticScoringFeeParameters, _random_seed_bytes: &[u8; 32] ) -> Result where L::Target: Logger { @@ -3509,9 +3510,10 @@ fn build_route_from_hops_internal( } impl ScoreLookUp for HopScorer { + #[cfg(not(c_bindings))] type ScoreParams = (); fn channel_penalty_msat(&self, candidate: &CandidateRouteHop, - _usage: ChannelUsage, _score_params: &Self::ScoreParams) -> u64 + _usage: ChannelUsage, _score_params: &crate::routing::scoring::ProbabilisticScoringFeeParameters) -> u64 { let mut cur_id = self.our_node_id; for i in 0..self.hop_ids.len() { @@ -7010,8 +7012,9 @@ mod tests { fn write(&self, _w: &mut W) -> Result<(), crate::io::Error> { unimplemented!() } } impl ScoreLookUp for BadChannelScorer { + #[cfg(not(c_bindings))] type ScoreParams = (); - fn channel_penalty_msat(&self, candidate: &CandidateRouteHop, _: ChannelUsage, _score_params:&Self::ScoreParams) -> u64 { + fn channel_penalty_msat(&self, candidate: &CandidateRouteHop, _: ChannelUsage, _score_params: &crate::routing::scoring::ProbabilisticScoringFeeParameters) -> u64 { if candidate.short_channel_id() == Some(self.short_channel_id) { u64::max_value() } else { 0 } } } @@ -7026,8 +7029,9 @@ mod tests { } impl ScoreLookUp for BadNodeScorer { + #[cfg(not(c_bindings))] type ScoreParams = (); - fn channel_penalty_msat(&self, candidate: &CandidateRouteHop, _: ChannelUsage, _score_params:&Self::ScoreParams) -> u64 { + fn channel_penalty_msat(&self, candidate: &CandidateRouteHop, _: ChannelUsage, _score_params: &crate::routing::scoring::ProbabilisticScoringFeeParameters) -> u64 { if candidate.target() == Some(self.node_id) { u64::max_value() } else { 0 } } } @@ -8817,7 +8821,7 @@ pub(crate) mod bench_utils { } pub(crate) fn generate_test_routes(graph: &NetworkGraph<&TestLogger>, scorer: &mut S, - score_params: &S::ScoreParams, features: Bolt11InvoiceFeatures, mut seed: u64, + score_params: &crate::routing::scoring::ProbabilisticScoringFeeParameters, features: Bolt11InvoiceFeatures, mut seed: u64, starting_amount: u64, route_count: usize, ) -> Vec<(ChannelDetails, PaymentParameters, u64)> { let payer = payer_pubkey(); @@ -8947,7 +8951,7 @@ pub mod benches { fn generate_routes( bench: &mut Criterion, graph: &NetworkGraph<&TestLogger>, mut scorer: S, - score_params: &S::ScoreParams, features: Bolt11InvoiceFeatures, starting_amount: u64, + score_params: &crate::routing::scoring::ProbabilisticScoringFeeParameters, features: Bolt11InvoiceFeatures, starting_amount: u64, bench_name: &'static str, ) { // First, get 100 (source, destination) pairs for which route-getting actually succeeds... diff --git a/lightning/src/routing/scoring.rs b/lightning/src/routing/scoring.rs index 61b0086ebc6..42ce01a034c 100644 --- a/lightning/src/routing/scoring.rs +++ b/lightning/src/routing/scoring.rs @@ -88,9 +88,13 @@ macro_rules! define_score { ($($supertrait: path)*) => { /// /// Scoring is in terms of fees willing to be paid in order to avoid routing through a channel. pub trait ScoreLookUp { + #[cfg(not(c_bindings))] /// A configurable type which should contain various passed-in parameters for configuring the scorer, /// on a per-routefinding-call basis through to the scorer methods, /// which are used to determine the parameters for the suitability of channels for use. + /// + /// Note that due to limitations in many other languages' generics features, language bindings + /// use [`ProbabilisticScoringFeeParameters`] for the parameters on all scorers. type ScoreParams; /// Returns the fee in msats willing to be paid to avoid routing `send_amt_msat` through the /// given channel in the direction from `source` to `target`. @@ -101,7 +105,7 @@ pub trait ScoreLookUp { /// [`u64::max_value`] is given to indicate sufficient capacity for the invoice's full amount. /// Thus, implementations should be overflow-safe. fn channel_penalty_msat( - &self, candidate: &CandidateRouteHop, usage: ChannelUsage, score_params: &Self::ScoreParams + &self, candidate: &CandidateRouteHop, usage: ChannelUsage, score_params: &ProbabilisticScoringFeeParameters ) -> u64; } @@ -139,9 +143,10 @@ impl Score for T {} #[cfg(not(c_bindings))] impl> ScoreLookUp for T { + #[cfg(not(c_bindings))] type ScoreParams = S::ScoreParams; fn channel_penalty_msat( - &self, candidate: &CandidateRouteHop, usage: ChannelUsage, score_params: &Self::ScoreParams + &self, candidate: &CandidateRouteHop, usage: ChannelUsage, score_params: &ProbabilisticScoringFeeParameters ) -> u64 { self.deref().channel_penalty_msat(candidate, usage, score_params) } @@ -322,8 +327,9 @@ impl<'a, T: 'a + Score> Deref for MultiThreadedScoreLockRead<'a, T> { #[cfg(c_bindings)] impl<'a, T: Score> ScoreLookUp for MultiThreadedScoreLockRead<'a, T> { + #[cfg(not(c_bindings))] type ScoreParams = T::ScoreParams; - fn channel_penalty_msat(&self, candidate:&CandidateRouteHop, usage: ChannelUsage, score_params: &Self::ScoreParams + fn channel_penalty_msat(&self, candidate:&CandidateRouteHop, usage: ChannelUsage, score_params: &ProbabilisticScoringFeeParameters ) -> u64 { self.0.channel_penalty_msat(candidate, usage, score_params) } @@ -404,8 +410,9 @@ impl FixedPenaltyScorer { } impl ScoreLookUp for FixedPenaltyScorer { + #[cfg(not(c_bindings))] type ScoreParams = (); - fn channel_penalty_msat(&self, _: &CandidateRouteHop, _: ChannelUsage, _score_params: &Self::ScoreParams) -> u64 { + fn channel_penalty_msat(&self, _: &CandidateRouteHop, _: ChannelUsage, _score_params: &ProbabilisticScoringFeeParameters) -> u64 { self.penalty_msat } } @@ -1315,6 +1322,7 @@ DirectedChannelLiquidity { } impl>, L: Deref> ScoreLookUp for ProbabilisticScorer where L::Target: Logger { + #[cfg(not(c_bindings))] type ScoreParams = ProbabilisticScoringFeeParameters; fn channel_penalty_msat( &self, candidate: &CandidateRouteHop, usage: ChannelUsage, score_params: &ProbabilisticScoringFeeParameters diff --git a/lightning/src/util/test_utils.rs b/lightning/src/util/test_utils.rs index 7252162e269..5f8f27bde3b 100644 --- a/lightning/src/util/test_utils.rs +++ b/lightning/src/util/test_utils.rs @@ -121,8 +121,6 @@ pub struct TestRouter<'a> { &'a TestLogger, Arc, &'a RwLock, - (), - TestScorer, >, pub network_graph: Arc>, pub next_routes: Mutex>)>>, @@ -1493,9 +1491,10 @@ impl crate::util::ser::Writeable for TestScorer { } impl ScoreLookUp for TestScorer { + #[cfg(not(c_bindings))] type ScoreParams = (); fn channel_penalty_msat( - &self, candidate: &CandidateRouteHop, usage: ChannelUsage, _score_params: &Self::ScoreParams + &self, candidate: &CandidateRouteHop, usage: ChannelUsage, _score_params: &crate::routing::scoring::ProbabilisticScoringFeeParameters ) -> u64 { let short_channel_id = match candidate.globally_unique_short_channel_id() { Some(scid) => scid, From 1ac1fe820517bb72f8b645989619e1018a91116d Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Wed, 19 Jul 2023 20:09:23 +0000 Subject: [PATCH 09/21] Mark several types no-export which should be exported eventually --- lightning-types/src/features.rs | 2 ++ lightning/src/events/bump_transaction.rs | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/lightning-types/src/features.rs b/lightning-types/src/features.rs index 7ce87e0263e..d39f7331c6e 100644 --- a/lightning-types/src/features.rs +++ b/lightning-types/src/features.rs @@ -602,6 +602,7 @@ pub struct Features { mark: PhantomData, } +/// This is not exported to bindings users but probably should be. impl> core::ops::BitOrAssign for Features { fn bitor_assign(&mut self, rhs: Rhs) { let total_feature_len = cmp::max(self.flags.len(), rhs.borrow().flags.len()); @@ -612,6 +613,7 @@ impl> core::ops::BitOrAssign for Feat } } +/// This is not exported to bindings users but probably should be. impl core::ops::BitOr for Features { type Output = Self; diff --git a/lightning/src/events/bump_transaction.rs b/lightning/src/events/bump_transaction.rs index 3acb2145e5b..0850615446a 100644 --- a/lightning/src/events/bump_transaction.rs +++ b/lightning/src/events/bump_transaction.rs @@ -275,6 +275,8 @@ impl Utxo { } /// Returns a `Utxo` with the `satisfaction_weight` estimate for a P2WPKH nested in P2SH output. + /// + /// This is not exported to bindings users as WPubkeyHash is not yet exported pub fn new_nested_p2wpkh(outpoint: OutPoint, value: Amount, pubkey_hash: &WPubkeyHash) -> Self { let script_sig_size = 1 /* script_sig length */ + 1 /* OP_0 */ + @@ -291,6 +293,8 @@ impl Utxo { } /// Returns a `Utxo` with the `satisfaction_weight` estimate for a SegWit v0 P2WPKH output. + /// + /// This is not exported to bindings users as WPubkeyHash is not yet exported pub fn new_v0_p2wpkh(outpoint: OutPoint, value: Amount, pubkey_hash: &WPubkeyHash) -> Self { Self { outpoint, From e55b8e4d5bc678382ec0b9b4777879e3302908ed Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 28 Sep 2023 03:03:38 +0000 Subject: [PATCH 10/21] `crate`-only several BOLT12 methods that require unbounded generics These are not expressible in C/most languages, and thus must be hidden. --- lightning/src/offers/invoice.rs | 4 +++- lightning/src/offers/invoice_request.rs | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lightning/src/offers/invoice.rs b/lightning/src/offers/invoice.rs index 865939b078e..9e0fa2d4b37 100644 --- a/lightning/src/offers/invoice.rs +++ b/lightning/src/offers/invoice.rs @@ -516,7 +516,9 @@ macro_rules! unsigned_invoice_sign_method { ($self: ident, $self_type: ty $(, $s /// Signs the [`TaggedHash`] of the invoice using the given function. /// /// Note: The hash computation may have included unknown, odd TLV records. - pub fn sign( + /// + /// This is not exported to bindings users as functions aren't currently mapped. + pub(crate) fn sign( $($self_mut)* $self: $self_type, sign: F ) -> Result { let pubkey = $self.contents.fields().signing_pubkey; diff --git a/lightning/src/offers/invoice_request.rs b/lightning/src/offers/invoice_request.rs index fa3d9161b82..62cf5653ff7 100644 --- a/lightning/src/offers/invoice_request.rs +++ b/lightning/src/offers/invoice_request.rs @@ -545,7 +545,9 @@ macro_rules! unsigned_invoice_request_sign_method { ( /// Signs the [`TaggedHash`] of the invoice request using the given function. /// /// Note: The hash computation may have included unknown, odd TLV records. - pub fn sign( + /// + /// This is not exported to bindings users as functions are not yet mapped. + pub(crate) fn sign( $($self_mut)* $self: $self_type, sign: F ) -> Result { let pubkey = $self.contents.payer_id; From 5f526f820e2621607e993dcd5507904e549ba672 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sun, 31 Jan 2021 20:12:50 -0500 Subject: [PATCH 11/21] Make ChannelMonitor always clonable Rather than `ChannelMonitor` only being clonable when the signer is clonable, we require all signers to be clonable and then make all `ChannelMonitor`s clonable. --- lightning/src/chain/channelmonitor.rs | 2 +- lightning/src/sign/ecdsa.rs | 2 +- lightning/src/sign/mod.rs | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index 693e1dda5c7..464ad50407f 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -850,7 +850,7 @@ pub struct ChannelMonitor { pub(super) inner: Mutex>, } -impl Clone for ChannelMonitor where Signer: Clone { +impl Clone for ChannelMonitor { fn clone(&self) -> Self { let inner = self.inner.lock().unwrap().clone(); ChannelMonitor::from_impl(inner) diff --git a/lightning/src/sign/ecdsa.rs b/lightning/src/sign/ecdsa.rs index ecdd45aa3f5..c6df3344cfa 100644 --- a/lightning/src/sign/ecdsa.rs +++ b/lightning/src/sign/ecdsa.rs @@ -24,7 +24,7 @@ use crate::sign::{ChannelSigner, HTLCDescriptor}; /// policies in order to be secure. Please refer to the [VLS Policy /// Controls](https://gitlab.com/lightning-signer/validating-lightning-signer/-/blob/main/docs/policy-controls.md) /// for an example of such policies. -pub trait EcdsaChannelSigner: ChannelSigner { +pub trait EcdsaChannelSigner: ChannelSigner + Clone { /// Create a signature for a counterparty's commitment transaction and associated HTLC transactions. /// /// Note that if signing fails or is rejected, the channel will be force-closed. diff --git a/lightning/src/sign/mod.rs b/lightning/src/sign/mod.rs index 0d3ec9efa41..c0fd5b73bb9 100644 --- a/lightning/src/sign/mod.rs +++ b/lightning/src/sign/mod.rs @@ -2500,11 +2500,11 @@ impl EntropySource for RandomBytes { } } -// Ensure that EcdsaChannelSigner can have a vtable -#[test] +// Ensure that EcdsaChannelSigner can have a vtable - not required in bindings +/*#[test] pub fn dyn_sign() { let _signer: Box; -} +}*/ #[cfg(ldk_bench)] pub mod benches { From 2459a77de4f61d808e51f76a8a738411725555b1 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 24 Sep 2021 18:44:32 +0000 Subject: [PATCH 12/21] Make the custom message traits cloneable as they're deep in nested structs --- lightning/src/ln/wire.rs | 14 +++++++------- lightning/src/onion_message/functional_tests.rs | 2 +- lightning/src/onion_message/messenger.rs | 4 ++-- lightning/src/onion_message/packet.rs | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lightning/src/ln/wire.rs b/lightning/src/ln/wire.rs index 4cf5e21c173..a29ced36a2b 100644 --- a/lightning/src/ln/wire.rs +++ b/lightning/src/ln/wire.rs @@ -45,9 +45,9 @@ impl TestEq for T {} /// A Lightning message returned by [`read`] when decoding bytes received over the wire. Each /// variant contains a message from [`msgs`] or otherwise the message type if unknown. #[allow(missing_docs)] -#[derive(Debug)] +#[derive(Clone, Debug)] #[cfg_attr(test, derive(PartialEq))] -pub(crate) enum Message where T: core::fmt::Debug + Type + TestEq { +pub(crate) enum Message where T: Clone + core::fmt::Debug + Type + TestEq { Init(msgs::Init), Error(msgs::ErrorMessage), Warning(msgs::WarningMessage), @@ -419,13 +419,13 @@ pub(crate) use self::encode::Encode; /// Defines a type identifier for sending messages over the wire. /// /// Messages implementing this trait specify a type and must be [`Writeable`]. -pub trait Type: core::fmt::Debug + Writeable { +pub trait Type: core::fmt::Debug + Writeable + Clone { /// Returns the type identifying the message payload. fn type_id(&self) -> u16; } #[cfg(test)] -pub trait Type: core::fmt::Debug + Writeable + PartialEq { +pub trait Type: core::fmt::Debug + Writeable + Clone + PartialEq { fn type_id(&self) -> u16; } @@ -435,12 +435,12 @@ impl Type for () { } #[cfg(test)] -impl Type for T where T: Encode { +impl Type for T where T: Encode { fn type_id(&self) -> u16 { T::TYPE } } #[cfg(not(test))] -impl Type for T where T: Encode { +impl Type for T where T: Encode { fn type_id(&self) -> u16 { T::TYPE } } @@ -786,7 +786,7 @@ mod tests { } } - #[derive(Eq, PartialEq, Debug)] + #[derive(Clone, Eq, PartialEq, Debug)] struct TestCustomMessage {} const CUSTOM_MESSAGE_TYPE : u16 = 9000; diff --git a/lightning/src/onion_message/functional_tests.rs b/lightning/src/onion_message/functional_tests.rs index 56c54005739..463b9fea569 100644 --- a/lightning/src/onion_message/functional_tests.rs +++ b/lightning/src/onion_message/functional_tests.rs @@ -654,7 +654,7 @@ fn reply_path() { fn invalid_custom_message_type() { let nodes = create_nodes(2); - #[derive(Debug)] + #[derive(Debug, Clone)] struct InvalidCustomMessage{} impl OnionMessageContents for InvalidCustomMessage { fn tlv_type(&self) -> u64 { diff --git a/lightning/src/onion_message/messenger.rs b/lightning/src/onion_message/messenger.rs index f40a59f2c0c..395c4a12613 100644 --- a/lightning/src/onion_message/messenger.rs +++ b/lightning/src/onion_message/messenger.rs @@ -200,8 +200,8 @@ for OnionMessenger where /// &keys_manager, &keys_manager, logger, &node_id_lookup, message_router, /// &offers_message_handler, &async_payments_message_handler, &custom_message_handler /// ); - -/// # #[derive(Debug)] +/// +/// # #[derive(Debug, Clone)] /// # struct YourCustomMessage {} /// impl Writeable for YourCustomMessage { /// fn write(&self, w: &mut W) -> Result<(), io::Error> { diff --git a/lightning/src/onion_message/packet.rs b/lightning/src/onion_message/packet.rs index f65ed0d53ed..f2cf3f00dc0 100644 --- a/lightning/src/onion_message/packet.rs +++ b/lightning/src/onion_message/packet.rs @@ -180,7 +180,7 @@ impl Writeable for ParsedOnionMessageContents { } /// The contents of an onion message. -pub trait OnionMessageContents: Writeable + core::fmt::Debug { +pub trait OnionMessageContents: Writeable + core::fmt::Debug + Clone { /// Returns the TLV type identifying the message contents. MUST be >= 64. fn tlv_type(&self) -> u64; From 2dac3f8322a3b145212b819a054cc78c1adad562 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 28 Sep 2023 03:05:09 +0000 Subject: [PATCH 13/21] Avoid slices without inner references As we cannot express slices without inner references in bindings wrappers. --- lightning/src/blinded_path/payment.rs | 8 ++++---- lightning/src/ln/channelmanager.rs | 8 ++++---- lightning/src/routing/gossip.rs | 2 +- lightning/src/routing/router.rs | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lightning/src/blinded_path/payment.rs b/lightning/src/blinded_path/payment.rs index f741cead26d..320547962ce 100644 --- a/lightning/src/blinded_path/payment.rs +++ b/lightning/src/blinded_path/payment.rs @@ -90,7 +90,7 @@ impl BlindedPaymentPath { // be in relation to a specific channel. let htlc_maximum_msat = u64::max_value(); Self::new( - &[], payee_node_id, payee_tlvs, htlc_maximum_msat, min_final_cltv_expiry_delta, + Vec::new(), payee_node_id, payee_tlvs, htlc_maximum_msat, min_final_cltv_expiry_delta, entropy_source, secp_ctx ) } @@ -103,7 +103,7 @@ impl BlindedPaymentPath { /// * any unknown features are required in the provided [`ForwardTlvs`] // TODO: make all payloads the same size with padding + add dummy hops pub fn new( - intermediate_nodes: &[PaymentForwardNode], payee_node_id: PublicKey, + intermediate_nodes: Vec, payee_node_id: PublicKey, payee_tlvs: ReceiveTlvs, htlc_maximum_msat: u64, min_final_cltv_expiry_delta: u16, entropy_source: ES, secp_ctx: &Secp256k1, ) -> Result where ES::Target: EntropySource { @@ -114,14 +114,14 @@ impl BlindedPaymentPath { let blinding_secret = SecretKey::from_slice(&blinding_secret_bytes[..]).expect("RNG is busted"); let blinded_payinfo = compute_payinfo( - intermediate_nodes, &payee_tlvs, htlc_maximum_msat, min_final_cltv_expiry_delta + &intermediate_nodes, &payee_tlvs, htlc_maximum_msat, min_final_cltv_expiry_delta )?; Ok(Self { inner_path: BlindedPath { introduction_node, blinding_point: PublicKey::from_secret_key(secp_ctx, &blinding_secret), blinded_hops: blinded_hops( - secp_ctx, intermediate_nodes, payee_node_id, payee_tlvs, &blinding_secret + secp_ctx, &intermediate_nodes, payee_node_id, payee_tlvs, &blinding_secret ).map_err(|_| ())?, }, payinfo: blinded_payinfo diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 6bcf3099b6d..2a16a30182f 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -4818,7 +4818,7 @@ where /// [`ChannelUnavailable`]: APIError::ChannelUnavailable /// [`APIMisuseError`]: APIError::APIMisuseError pub fn update_partial_channel_config( - &self, counterparty_node_id: &PublicKey, channel_ids: &[ChannelId], config_update: &ChannelConfigUpdate, + &self, counterparty_node_id: &PublicKey, channel_ids: Vec, config_update: &ChannelConfigUpdate, ) -> Result<(), APIError> { if config_update.cltv_expiry_delta.map(|delta| delta < MIN_CLTV_EXPIRY_DELTA).unwrap_or(false) { return Err(APIError::APIMisuseError { @@ -4833,14 +4833,14 @@ where let mut peer_state_lock = peer_state_mutex.lock().unwrap(); let peer_state = &mut *peer_state_lock; - for channel_id in channel_ids { + for channel_id in channel_ids.iter() { if !peer_state.has_channel(channel_id) { return Err(APIError::ChannelUnavailable { err: format!("Channel with id {} not found for the passed counterparty node_id {}", channel_id, counterparty_node_id), }); }; } - for channel_id in channel_ids { + for channel_id in channel_ids.iter() { if let Some(channel_phase) = peer_state.channel_by_id.get_mut(channel_id) { let mut config = channel_phase.context().config(); config.apply(config_update); @@ -4895,7 +4895,7 @@ where /// [`ChannelUnavailable`]: APIError::ChannelUnavailable /// [`APIMisuseError`]: APIError::APIMisuseError pub fn update_channel_config( - &self, counterparty_node_id: &PublicKey, channel_ids: &[ChannelId], config: &ChannelConfig, + &self, counterparty_node_id: &PublicKey, channel_ids: Vec, config: &ChannelConfig, ) -> Result<(), APIError> { return self.update_partial_channel_config(counterparty_node_id, channel_ids, &(*config).into()); } diff --git a/lightning/src/routing/gossip.rs b/lightning/src/routing/gossip.rs index c88252a15cd..e90ed1608e0 100644 --- a/lightning/src/routing/gossip.rs +++ b/lightning/src/routing/gossip.rs @@ -91,7 +91,7 @@ impl NodeId { } /// Get the public key as an array from this NodeId - pub fn as_array(&self) -> &[u8; PUBLIC_KEY_SIZE] { + pub fn as_array(&self) -> &[u8; 33] { &self.0 } diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index 969b60f39e2..47db2f3ec66 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -160,7 +160,7 @@ impl>, L: Deref, ES: Deref, S: Deref> Router f }) .map(|forward_node| { BlindedPaymentPath::new( - &[forward_node], recipient, tlvs.clone(), u64::MAX, MIN_FINAL_CLTV_EXPIRY_DELTA, + vec![forward_node], recipient, tlvs.clone(), u64::MAX, MIN_FINAL_CLTV_EXPIRY_DELTA, &*self.entropy_source, secp_ctx ) }) @@ -172,7 +172,7 @@ impl>, L: Deref, ES: Deref, S: Deref> Router f _ => { if network_graph.nodes().contains_key(&NodeId::from_pubkey(&recipient)) { BlindedPaymentPath::new( - &[], recipient, tlvs, u64::MAX, MIN_FINAL_CLTV_EXPIRY_DELTA, &*self.entropy_source, + Vec::new(), recipient, tlvs, u64::MAX, MIN_FINAL_CLTV_EXPIRY_DELTA, &*self.entropy_source, secp_ctx ).map(|path| vec![path]) } else { From a7a2860cd9373e228915c2b65381cfb308df929f Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 17 Aug 2024 23:53:16 +0000 Subject: [PATCH 14/21] Avoid options holding references in the public API --- lightning/src/ln/channelmanager.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 2a16a30182f..eccffa5d39b 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -4234,10 +4234,10 @@ where /// whether or not the payment was successful. /// /// [timer tick]: Self::timer_tick_occurred - pub fn send_payment_for_bolt12_invoice( - &self, invoice: &Bolt12Invoice, context: Option<&OffersContext>, + pub(crate) fn send_payment_for_bolt12_invoice( + &self, invoice: &Bolt12Invoice, context: Option, ) -> Result<(), Bolt12PaymentError> { - match self.verify_bolt12_invoice(invoice, context) { + match self.verify_bolt12_invoice(invoice, context.as_ref()) { Ok(payment_id) => self.send_payment_for_verified_bolt12_invoice(invoice, payment_id), Err(()) => Err(Bolt12PaymentError::UnexpectedInvoice), } From 5ba0359b139ae06b3d941af2f10f5381ede680e9 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 11 May 2024 16:12:39 +0000 Subject: [PATCH 15/21] Hide `Direction::select_node_id` due to lifetimes --- lightning/src/blinded_path/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lightning/src/blinded_path/mod.rs b/lightning/src/blinded_path/mod.rs index 168bc7174d6..fd1846492a1 100644 --- a/lightning/src/blinded_path/mod.rs +++ b/lightning/src/blinded_path/mod.rs @@ -185,7 +185,7 @@ impl_writeable!(BlindedHop, { impl Direction { /// Returns the [`NodeId`] from the inputs corresponding to the direction. - pub fn select_node_id(&self, node_a: NodeId, node_b: NodeId) -> NodeId { + pub(crate) fn select_node_id(&self, node_a: NodeId, node_b: NodeId) -> NodeId { match self { Direction::NodeOne => core::cmp::min(node_a, node_b), Direction::NodeTwo => core::cmp::max(node_a, node_b), @@ -193,7 +193,7 @@ impl Direction { } /// Returns the [`PublicKey`] from the inputs corresponding to the direction. - pub fn select_pubkey<'a>(&self, node_a: &'a PublicKey, node_b: &'a PublicKey) -> &'a PublicKey { + pub(crate) fn select_pubkey<'a>(&self, node_a: &'a PublicKey, node_b: &'a PublicKey) -> &'a PublicKey { let (node_one, node_two) = if NodeId::from_pubkey(node_a) < NodeId::from_pubkey(node_b) { (node_a, node_b) } else { From 8c05cdabeb5ffe232206426578ba49be03d01d3a Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 11 May 2024 16:13:02 +0000 Subject: [PATCH 16/21] Drop `SerialId` type as bindings don't support primitive aliasing --- lightning/src/ln/interactivetxs.rs | 2 +- lightning/src/ln/msgs.rs | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/lightning/src/ln/interactivetxs.rs b/lightning/src/ln/interactivetxs.rs index deec638f7f1..64cd1d5792a 100644 --- a/lightning/src/ln/interactivetxs.rs +++ b/lightning/src/ln/interactivetxs.rs @@ -22,8 +22,8 @@ use crate::chain::chaininterface::fee_for_weight; use crate::events::bump_transaction::{BASE_INPUT_WEIGHT, EMPTY_SCRIPT_SIG_WEIGHT}; use crate::ln::channel::TOTAL_BITCOIN_SUPPLY_SATOSHIS; use crate::ln::msgs; -use crate::ln::msgs::SerialId; use crate::ln::types::ChannelId; +type SerialId = u64; use crate::sign::{EntropySource, P2TR_KEY_PATH_WITNESS_WEIGHT, P2WPKH_WITNESS_WEIGHT}; use crate::util::ser::TransactionU16LenLimited; diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index b821eb90c59..4fc00dff91b 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -441,10 +441,6 @@ pub struct ChannelReady { pub short_channel_id_alias: Option, } -/// A randomly chosen number that is used to identify inputs within an interactive transaction -/// construction. -pub type SerialId = u64; - /// An `stfu` (quiescence) message to be sent by or received from the stfu initiator. /// // TODO(splicing): Add spec link for `stfu`; still in draft, using from https://github.com/lightning/bolts/pull/1160 @@ -512,7 +508,7 @@ pub struct TxAddInput { pub channel_id: ChannelId, /// A randomly chosen unique identifier for this input, which is even for initiators and odd for /// non-initiators. - pub serial_id: SerialId, + pub serial_id: u64, /// Serialized transaction that contains the output this input spends to verify that it is non /// malleable. pub prevtx: TransactionU16LenLimited, @@ -533,7 +529,7 @@ pub struct TxAddOutput { pub channel_id: ChannelId, /// A randomly chosen unique identifier for this output, which is even for initiators and odd for /// non-initiators. - pub serial_id: SerialId, + pub serial_id: u64, /// The satoshi value of the output pub sats: u64, /// The scriptPubKey for the output @@ -548,7 +544,7 @@ pub struct TxRemoveInput { /// The channel ID pub channel_id: ChannelId, /// The serial ID of the input to be removed - pub serial_id: SerialId, + pub serial_id: u64, } /// A tx_remove_output message for removing an output during interactive transaction construction. @@ -559,7 +555,7 @@ pub struct TxRemoveOutput { /// The channel ID pub channel_id: ChannelId, /// The serial ID of the output to be removed - pub serial_id: SerialId, + pub serial_id: u64, } /// A tx_complete message signalling the conclusion of a peer's transaction contributions during From 640d4421de413cbbc933cabacbc7f51ebdd47c62 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Wed, 5 Jun 2024 14:41:03 +0000 Subject: [PATCH 17/21] Minimal updates to `lightning-transaction-sync` for bindings Bindings don't accept dyn traits, but instead map any traits to a single dynamic struct. Thus, we can always take a specific trait to accept any implementation, which we do here. --- lightning-transaction-sync/src/electrum.rs | 2 ++ lightning-transaction-sync/src/error.rs | 2 ++ lightning-transaction-sync/src/esplora.rs | 2 ++ lightning-transaction-sync/src/lib.rs | 6 +++--- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lightning-transaction-sync/src/electrum.rs b/lightning-transaction-sync/src/electrum.rs index 015cb42c639..2fb54a26682 100644 --- a/lightning-transaction-sync/src/electrum.rs +++ b/lightning-transaction-sync/src/electrum.rs @@ -1,3 +1,5 @@ +//! Chain sync using the electrum protocol + use crate::common::{ConfirmedTx, FilterQueue, SyncState}; use crate::error::{InternalError, TxSyncError}; diff --git a/lightning-transaction-sync/src/error.rs b/lightning-transaction-sync/src/error.rs index be59cb026b4..bdfe17ecc3f 100644 --- a/lightning-transaction-sync/src/error.rs +++ b/lightning-transaction-sync/src/error.rs @@ -1,3 +1,5 @@ +//! Common error types + use std::fmt; #[derive(Debug)] diff --git a/lightning-transaction-sync/src/esplora.rs b/lightning-transaction-sync/src/esplora.rs index 564d7f1773a..e2eb9673dd6 100644 --- a/lightning-transaction-sync/src/esplora.rs +++ b/lightning-transaction-sync/src/esplora.rs @@ -1,3 +1,5 @@ +//! Chain sync using the Esplora API + use crate::common::{ConfirmedTx, FilterQueue, SyncState}; use crate::error::{InternalError, TxSyncError}; diff --git a/lightning-transaction-sync/src/lib.rs b/lightning-transaction-sync/src/lib.rs index 96e0c0dfe9c..164c968348b 100644 --- a/lightning-transaction-sync/src/lib.rs +++ b/lightning-transaction-sync/src/lib.rs @@ -69,15 +69,15 @@ extern crate bdk_macros; #[cfg(any(feature = "esplora-blocking", feature = "esplora-async"))] -mod esplora; +pub mod esplora; #[cfg(any(feature = "electrum"))] -mod electrum; +pub mod electrum; #[cfg(any(feature = "esplora-blocking", feature = "esplora-async", feature = "electrum"))] mod common; #[cfg(any(feature = "esplora-blocking", feature = "esplora-async", feature = "electrum"))] -mod error; +pub mod error; #[cfg(any(feature = "esplora-blocking", feature = "esplora-async", feature = "electrum"))] pub use error::TxSyncError; From 28aca7d1b285a801d23d5a96ed9241bf0006fd19 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Tue, 20 Aug 2024 14:32:44 +0000 Subject: [PATCH 18/21] Require an OM in BP as this should generally be true and its easier to map --- lightning-background-processor/src/lib.rs | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/lightning-background-processor/src/lib.rs b/lightning-background-processor/src/lib.rs index 410f28a2e19..9fa8437b770 100644 --- a/lightning-background-processor/src/lib.rs +++ b/lightning-background-processor/src/lib.rs @@ -925,7 +925,7 @@ impl BackgroundProcessor { SC: for<'b> WriteableScore<'b>, >( persister: PS, event_handler: EH, chain_monitor: M, channel_manager: CM, - onion_messenger: Option, gossip_sync: GossipSync, peer_manager: PM, + onion_messenger: OM, gossip_sync: GossipSync, peer_manager: PM, logger: L, scorer: Option, ) -> Self where @@ -962,34 +962,27 @@ impl BackgroundProcessor { } event_handler.handle_event(event) }; + let om_opt = Some(&*onion_messenger); define_run_body!( persister, chain_monitor, chain_monitor.process_pending_events(&event_handler), channel_manager, channel_manager.get_cm().process_pending_events(&event_handler), - onion_messenger, - if let Some(om) = &onion_messenger { - om.get_om().process_pending_events(&event_handler) - }, + om_opt, + onion_messenger.get_om().process_pending_events(&event_handler), peer_manager, gossip_sync, logger, scorer, stop_thread.load(Ordering::Acquire), { - let sleeper = if let Some(om) = onion_messenger.as_ref() { + let sleeper = Sleeper::from_three_futures( &channel_manager.get_cm().get_event_or_persistence_needed_future(), &chain_monitor.get_update_future(), - &om.get_om().get_update_future(), - ) - } else { - Sleeper::from_two_futures( - &channel_manager.get_cm().get_event_or_persistence_needed_future(), - &chain_monitor.get_update_future(), - ) - }; + &onion_messenger.get_om().get_update_future(), + ); sleeper.wait_timeout(Duration::from_millis(100)); }, |_| Instant::now(), From 3f1a9b1c934ef4f616b99148564c8e5c99f7e35c Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 24 Aug 2024 20:37:31 +0000 Subject: [PATCH 19/21] Avoid returning references in `NodeAnnouncementInfo` accessors --- lightning/src/routing/gossip.rs | 17 +++++++++-------- lightning/src/routing/router.rs | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/lightning/src/routing/gossip.rs b/lightning/src/routing/gossip.rs index e90ed1608e0..0d465d53a78 100644 --- a/lightning/src/routing/gossip.rs +++ b/lightning/src/routing/gossip.rs @@ -1252,9 +1252,10 @@ pub enum NodeAnnouncementInfo { } impl NodeAnnouncementInfo { - /// Protocol features the node announced support for - pub fn features(&self) -> &NodeFeatures { + pub fn features(&self) -> NodeFeatures { self.features_ref().clone() } + + pub(crate) fn features_ref(&self) -> &NodeFeatures { match self { NodeAnnouncementInfo::Relayed(relayed) => { &relayed.contents.features @@ -1294,7 +1295,7 @@ impl NodeAnnouncementInfo { /// Moniker assigned to the node. /// /// May be invalid or malicious (eg control chars), should not be exposed to the user. - pub fn alias(&self) -> &NodeAlias { + pub fn alias(&self) -> NodeAlias { match self { NodeAnnouncementInfo::Relayed(relayed) => { &relayed.contents.alias @@ -1302,11 +1303,11 @@ impl NodeAnnouncementInfo { NodeAnnouncementInfo::Local(local) => { &local.alias } - } + }.clone() } /// Internet-level addresses via which one can connect to the node - pub fn addresses(&self) -> &[SocketAddress] { + pub fn addresses(&self) -> Vec { match self { NodeAnnouncementInfo::Relayed(relayed) => { &relayed.contents.addresses @@ -1314,13 +1315,13 @@ impl NodeAnnouncementInfo { NodeAnnouncementInfo::Local(local) => { &local.addresses } - } + }.to_vec() } /// An initial announcement of the node /// /// Not stored if contains excess data to prevent DoS. - pub fn announcement_message(&self) -> Option<&NodeAnnouncement> { + pub fn announcement_message(&self) -> Option { match self { NodeAnnouncementInfo::Relayed(announcement) => { Some(announcement) @@ -1328,7 +1329,7 @@ impl NodeAnnouncementInfo { NodeAnnouncementInfo::Local(_) => { None } - } + }.cloned() } } diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index 47db2f3ec66..da898f06e81 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -2717,7 +2717,7 @@ where L::Target: Logger { } let features = if let Some(node_info) = $node.announcement_info.as_ref() { - &node_info.features() + node_info.features_ref() } else { &default_node_features }; From d23d57d9bd11f4f955e4b726efc9d5b1bc005aca Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 26 Aug 2024 18:28:50 +0000 Subject: [PATCH 20/21] Use `[u8; 32]` rather than `Hmac` for simplicity Mapping an `Hmac` would require somewhat custom logic as we'd have to behave differently based on generic parameters, so its simplest to just swap it to a `[u8; 32]` instead. --- lightning/src/blinded_path/message.rs | 2 +- lightning/src/ln/channelmanager.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lightning/src/blinded_path/message.rs b/lightning/src/blinded_path/message.rs index e3899b50edb..0651877750c 100644 --- a/lightning/src/blinded_path/message.rs +++ b/lightning/src/blinded_path/message.rs @@ -334,7 +334,7 @@ pub enum OffersContext { /// used with an [`InvoiceError`]. /// /// [`InvoiceError`]: crate::offers::invoice_error::InvoiceError - hmac: Option>, + hmac: Option<[u8; 32]>, }, /// Context used by a [`BlindedMessagePath`] as a reply path for a [`Bolt12Invoice`]. /// diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index eccffa5d39b..cc84185e14c 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -9081,7 +9081,7 @@ where let invoice_request = builder.build_and_sign()?; let hmac = payment_id.hmac_for_offer_payment(nonce, expanded_key); - let context = OffersContext::OutboundPayment { payment_id, nonce, hmac: Some(hmac) }; + let context = OffersContext::OutboundPayment { payment_id, nonce, hmac: Some(hmac.to_byte_array()) }; let reply_paths = self.create_blinded_paths(context) .map_err(|_| Bolt12SemanticError::MissingPaths)?; @@ -10956,7 +10956,7 @@ where match context { Some(OffersContext::OutboundPayment { payment_id, nonce, hmac: Some(hmac) }) => { - if let Ok(()) = payment_id.verify(hmac, nonce, expanded_key) { + if let Ok(()) = payment_id.verify(bitcoin::hashes::hmac::Hmac::from_byte_array(hmac), nonce, expanded_key) { self.abandon_payment_with_reason( payment_id, PaymentFailureReason::InvoiceRequestRejected, ); From c85a315866ed0282993544e127ed7c61193332ae Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 26 Aug 2024 18:31:24 +0000 Subject: [PATCH 21/21] Use inline bounds for secp contexts, rather than `where` clauses The bindings really should support this, but currently they don't and its late enough in the release cycle I don't want to try to fix that. --- lightning/src/blinded_path/message.rs | 3 +-- lightning/src/blinded_path/payment.rs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lightning/src/blinded_path/message.rs b/lightning/src/blinded_path/message.rs index 0651877750c..e4aed2a547c 100644 --- a/lightning/src/blinded_path/message.rs +++ b/lightning/src/blinded_path/message.rs @@ -142,13 +142,12 @@ impl BlindedMessagePath { /// introduction node. /// /// Will only modify `self` when returning `Ok`. - pub fn advance_path_by_one( + pub fn advance_path_by_one( &mut self, node_signer: &NS, node_id_lookup: &NL, secp_ctx: &Secp256k1 ) -> Result<(), ()> where NS::Target: NodeSigner, NL::Target: NodeIdLookUp, - T: secp256k1::Signing + secp256k1::Verification, { let control_tlvs_ss = node_signer.ecdh(Recipient::Node, &self.0.blinding_point, None)?; let rho = onion_utils::gen_rho_from_shared_secret(&control_tlvs_ss.secret_bytes()); diff --git a/lightning/src/blinded_path/payment.rs b/lightning/src/blinded_path/payment.rs index 320547962ce..c84e5926a92 100644 --- a/lightning/src/blinded_path/payment.rs +++ b/lightning/src/blinded_path/payment.rs @@ -157,13 +157,12 @@ impl BlindedPaymentPath { /// introduction node. /// /// Will only modify `self` when returning `Ok`. - pub fn advance_path_by_one( + pub fn advance_path_by_one( &mut self, node_signer: &NS, node_id_lookup: &NL, secp_ctx: &Secp256k1 ) -> Result<(), ()> where NS::Target: NodeSigner, NL::Target: NodeIdLookUp, - T: secp256k1::Signing + secp256k1::Verification, { let control_tlvs_ss = node_signer.ecdh(Recipient::Node, &self.inner_path.blinding_point, None)?; let rho = onion_utils::gen_rho_from_shared_secret(&control_tlvs_ss.secret_bytes());