Merge pull request #2227 from TheBlueMatt/2023-04-0.0.115-bindings
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Wed, 26 Apr 2023 17:50:17 +0000 (17:50 +0000)
committerGitHub <noreply@github.com>
Wed, 26 Apr 2023 17:50:17 +0000 (17:50 +0000)
0.0.115 Bindings Updates

25 files changed:
fuzz/src/chanmon_consistency.rs
fuzz/src/onion_message.rs
lightning-invoice/src/lib.rs
lightning-invoice/src/payment.rs
lightning-invoice/src/utils.rs
lightning-persister/src/lib.rs
lightning-rapid-gossip-sync/src/lib.rs
lightning/src/chain/channelmonitor.rs
lightning/src/ln/channel.rs
lightning/src/ln/channelmanager.rs
lightning/src/ln/mod.rs
lightning/src/ln/msgs.rs
lightning/src/ln/peer_handler.rs
lightning/src/ln/priv_short_conf_tests.rs
lightning/src/offers/invoice.rs
lightning/src/offers/invoice_request.rs
lightning/src/offers/offer.rs
lightning/src/offers/parse.rs
lightning/src/offers/refund.rs
lightning/src/onion_message/messenger.rs
lightning/src/onion_message/mod.rs
lightning/src/routing/gossip.rs
lightning/src/routing/scoring.rs
lightning/src/util/persist.rs
lightning/src/util/wakers.rs

index 0461c75772c7a39fa5176ca37bbc5f55878f4c7d..43495acaa684d0ed83c0bd5c431aa5f5ca677cbc 100644 (file)
@@ -41,7 +41,8 @@ use lightning::chain::keysinterface::{KeyMaterial, InMemorySigner, Recipient, En
 use lightning::events;
 use lightning::events::MessageSendEventsProvider;
 use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
-use lightning::ln::channelmanager::{ChainParameters, ChannelDetails, ChannelManager, PaymentSendFailure, ChannelManagerReadArgs, PaymentId, RecipientOnionFields};
+use lightning::ln::channelmanager::{ChainParameters, ChannelDetails, ChannelManager, PaymentSendFailure, ChannelManagerReadArgs, PaymentId};
+use lightning::ln::outbound_payment::RecipientOnionFields;
 use lightning::ln::channel::FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE;
 use lightning::ln::msgs::{self, CommitmentUpdate, ChannelMessageHandler, DecodeError, UpdateAddHTLC, Init};
 use lightning::ln::script::ShutdownScript;
index 9bbf8b9cdffa5010e6463ae96d5de071b19d8285..de84f049faa5811296fee1d05b7198af2b16179e 100644 (file)
@@ -11,7 +11,8 @@ use lightning::ln::script::ShutdownScript;
 use lightning::util::enforcing_trait_impls::EnforcingSigner;
 use lightning::util::logger::Logger;
 use lightning::util::ser::{Readable, Writeable, Writer};
-use lightning::onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, OnionMessenger};
+use lightning::onion_message::packet::CustomOnionMessageContents;
+use lightning::onion_message::messenger::{OnionMessenger, CustomOnionMessageHandler};
 
 use crate::utils::test_logger;
 
index 0923fcc1756d4fd05305ab53b2653d08539949f9..101051b5e7f23509325d42301a424d3045fc7589 100644 (file)
@@ -455,6 +455,15 @@ pub enum TaggedField {
 pub struct Sha256(/// This is not exported to bindings users as the native hash types are not currently mapped
        pub sha256::Hash);
 
+impl Sha256 {
+       /// Constructs a new [`Sha256`] from the given bytes, which are assumed to be the output of a
+       /// single sha256 hash.
+       #[cfg(c_bindings)]
+       pub fn from_bytes(bytes: &[u8; 32]) -> Self {
+               Self(sha256::Hash::from_slice(bytes).expect("from_slice only fails if len is not 32"))
+       }
+}
+
 /// Description string
 ///
 /// # Invariants
index 11757be2e3a2f8399661da3b9b81d51f8457d6a6..3089741351356450c0bbfe772bd2df179720ef2d 100644 (file)
@@ -17,7 +17,8 @@ use lightning::chain;
 use lightning::chain::chaininterface::{BroadcasterInterface, FeeEstimator};
 use lightning::chain::keysinterface::{NodeSigner, SignerProvider, EntropySource};
 use lightning::ln::PaymentHash;
-use lightning::ln::channelmanager::{ChannelManager, PaymentId, Retry, RetryableSendFailure, RecipientOnionFields};
+use lightning::ln::channelmanager::{ChannelManager, PaymentId};
+use lightning::ln::outbound_payment::{RecipientOnionFields, RetryableSendFailure, Retry};
 use lightning::routing::router::{PaymentParameters, RouteParameters, Router};
 use lightning::util::logger::Logger;
 
index 5f378ab6fbd1108601e63043d67f710b5d810e2a..2abe2313c735636f8f8be7e098e8b24e6abe99aa 100644 (file)
@@ -667,7 +667,8 @@ mod test {
        use lightning::chain::keysinterface::PhantomKeysManager;
        use lightning::events::{MessageSendEvent, MessageSendEventsProvider, Event};
        use lightning::ln::{PaymentPreimage, PaymentHash};
-       use lightning::ln::channelmanager::{PhantomRouteHints, MIN_FINAL_CLTV_EXPIRY_DELTA, PaymentId, RecipientOnionFields, Retry};
+       use lightning::ln::channelmanager::{PhantomRouteHints, MIN_FINAL_CLTV_EXPIRY_DELTA, PaymentId};
+       use lightning::ln::outbound_payment::{RecipientOnionFields, Retry};
        use lightning::ln::functional_test_utils::*;
        use lightning::ln::msgs::ChannelMessageHandler;
        use lightning::routing::router::{PaymentParameters, RouteParameters};
index e6687fef7b8a24a2e6e9cd2cefd8b73f77adbcb4..51d91e2442aab67bbbf28aaed31a6480e1d05291 100644 (file)
@@ -20,7 +20,7 @@ extern crate libc;
 use bitcoin::hash_types::{BlockHash, Txid};
 use bitcoin::hashes::hex::FromHex;
 use lightning::chain::channelmonitor::ChannelMonitor;
-use lightning::chain::keysinterface::{EntropySource, SignerProvider};
+use lightning::chain::keysinterface::{EntropySource, SignerProvider, WriteableEcdsaChannelSigner};
 use lightning::util::ser::{ReadableArgs, Writeable};
 use lightning::util::persist::KVStorePersister;
 use std::fs;
@@ -59,12 +59,11 @@ impl FilesystemPersister {
        }
 
        /// Read `ChannelMonitor`s from disk.
-       pub fn read_channelmonitors<ES: Deref, SP: Deref> (
-               &self, entropy_source: ES, signer_provider: SP
-       ) -> std::io::Result<Vec<(BlockHash, ChannelMonitor<<SP::Target as SignerProvider>::Signer>)>>
+       pub fn read_channelmonitors<ES: Deref, WES: WriteableEcdsaChannelSigner, SP: SignerProvider<Signer = WES> + Sized, SPD: Deref<Target=SP>> (
+               &self, entropy_source: ES, signer_provider: SPD
+       ) -> Result<Vec<(BlockHash, ChannelMonitor<WES>)>, std::io::Error>
                where
                        ES::Target: EntropySource + Sized,
-                       SP::Target: SignerProvider + Sized
        {
                let mut path = PathBuf::from(&self.path_to_channel_data);
                path.push("monitors");
@@ -105,7 +104,7 @@ impl FilesystemPersister {
 
                        let contents = fs::read(&file.path())?;
                        let mut buffer = Cursor::new(&contents);
-                       match <(BlockHash, ChannelMonitor<<SP::Target as SignerProvider>::Signer>)>::read(&mut buffer, (&*entropy_source, &*signer_provider)) {
+                       match <(BlockHash, ChannelMonitor<WES>)>::read(&mut buffer, (&*entropy_source, &*signer_provider)) {
                                Ok((blockhash, channel_monitor)) => {
                                        if channel_monitor.get_funding_txo().0.txid != txid || channel_monitor.get_funding_txo().0.index != index {
                                                return Err(std::io::Error::new(std::io::ErrorKind::InvalidData,
index c8f140cc18955d8225bbf300fcda2aee6ddae267..9e2b8334e648dfdb43fef1812cac0639f020a09e 100644 (file)
@@ -81,10 +81,10 @@ use lightning::io;
 use lightning::routing::gossip::NetworkGraph;
 use lightning::util::logger::Logger;
 
-pub use crate::error::GraphSyncError;
+use crate::error::GraphSyncError;
 
 /// Error types that these functions can return
-mod error;
+pub mod error;
 
 /// Core functionality of this crate
 mod processing;
index f2c6ea18249480d981337fd530bbf8874265af71..c0fbb6a980e4d446dc2aa42aae2d0f2bf0689729 100644 (file)
@@ -3772,8 +3772,8 @@ where
 
 const MAX_ALLOC_SIZE: usize = 64*1024;
 
-impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP)>
-               for (BlockHash, ChannelMonitor<SP::Signer>) {
+impl<'a, 'b, ES: EntropySource, SP: SignerProvider<Signer=Signer>, Signer: WriteableEcdsaChannelSigner> ReadableArgs<(&'a ES, &'b SP)>
+               for (BlockHash, ChannelMonitor<Signer>) {
        fn read<R: io::Read>(reader: &mut R, args: (&'a ES, &'b SP)) -> Result<Self, DecodeError> {
                macro_rules! unwrap_obj {
                        ($key: expr) => {
index 8b5e89d9441ace4510bddd65f877fc7355f94604..a45b91f6322623b52c46306fb671682baa71b5e1 100644 (file)
@@ -5539,7 +5539,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
                                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;
@@ -5573,7 +5573,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
                                .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()))?;
                        let our_bitcoin_sig = self.holder_signer.sign_channel_announcement_with_funding_key(&announcement, &self.secp_ctx)
                                .map_err(|_| ChannelError::Ignore("Signer rejected channel_announcement".to_owned()))?;
index 498813de7a11900e2dbdcffa9adf8de9fd037d6c..43a854b3df1534609447de967ddf6d3cb0c5974f 100644 (file)
@@ -77,7 +77,7 @@ use core::time::Duration;
 use core::ops::Deref;
 
 // Re-export this for use in the public API.
-pub use crate::ln::outbound_payment::{PaymentSendFailure, Retry, RetryableSendFailure, RecipientOnionFields};
+pub(crate) use crate::ln::outbound_payment::{PaymentSendFailure, Retry, RetryableSendFailure, RecipientOnionFields};
 
 // We hold various information about HTLC relay in the HTLC objects in Channel itself:
 //
@@ -2650,7 +2650,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,
index 340213c515070aa719de95cef2e062e5c82158bc..e60cbb585595039a06f81bcd0f0faae794388199 100644 (file)
@@ -32,7 +32,7 @@ pub mod channel;
 pub(crate) mod channel;
 
 pub(crate) mod onion_utils;
-mod outbound_payment;
+pub mod outbound_payment;
 pub mod wire;
 
 // Older rustc (which we support) refuses to let us call the get_payment_preimage_hash!() macro
index 4b2eb9674fa8acefa0afba97245ca4674d49e577..3dec35e9f06dc4c502266eb3465e81d19562054d 100644 (file)
@@ -658,16 +658,17 @@ impl Readable for NetAddress {
 }
 
 /// 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<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
                match self {
                        UnsignedGossipMessage::ChannelAnnouncement(ref msg) => msg.write(writer),
index 84870143008a3f19bd47fe2a303a897760bba516..6dcb6cbd865364a2310064dcfac92794021c9a6d 100644 (file)
@@ -27,7 +27,8 @@ use crate::util::ser::{VecWriter, Writeable, Writer};
 use crate::ln::peer_channel_encryptor::{PeerChannelEncryptor,NextNoiseStep};
 use crate::ln::wire;
 use crate::ln::wire::Encode;
-use crate::onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, SimpleArcOnionMessenger, SimpleRefOnionMessenger};
+use crate::onion_message::messenger::{CustomOnionMessageHandler, SimpleArcOnionMessenger, SimpleRefOnionMessenger};
+use crate::onion_message::packet::CustomOnionMessageContents;
 use crate::routing::gossip::{NetworkGraph, P2PGossipSync, NodeId, NodeAlias};
 use crate::util::atomic_counter::AtomicCounter;
 use crate::util::logger::Logger;
@@ -2160,7 +2161,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                        excess_data: Vec::new(),
                };
                let node_announce_sig = match self.node_signer.sign_gossip_message(
-                       msgs::UnsignedGossipMessage::NodeAnnouncement(&announcement)
+                       msgs::UnsignedGossipMessage::NodeAnnouncement(announcement.clone())
                ) {
                        Ok(sig) => sig,
                        Err(_) => {
index 7bb1fd44f2fe1f6d42698a222d47039f431d91be..97639b122cbfb7826da1a2212d6a2626eb2fdef5 100644 (file)
@@ -506,7 +506,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();
index 05b2b5d010ec7a8cf36306f95ce481d6c148dd58..7d24c2e46a994c54789d30b5dfdb495825e85f66 100644 (file)
@@ -134,6 +134,8 @@ pub(super) const SIGNATURE_TAG: &'static str = concat!("lightning", "invoice", "
 ///
 /// See [module-level documentation] for usage.
 ///
+/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
+///
 /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
 /// [`Refund`]: crate::offers::refund::Refund
 /// [module-level documentation]: self
@@ -145,12 +147,18 @@ pub struct InvoiceBuilder<'a, S: SigningPubkeyStrategy> {
 }
 
 /// Indicates how [`Invoice::signing_pubkey`] was set.
+///
+/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
 pub trait SigningPubkeyStrategy {}
 
 /// [`Invoice::signing_pubkey`] was explicitly set.
+///
+/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
 pub struct ExplicitSigningPubkey {}
 
 /// [`Invoice::signing_pubkey`] was derived.
+///
+/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
 pub struct DerivedSigningPubkey {}
 
 impl SigningPubkeyStrategy for ExplicitSigningPubkey {}
@@ -303,6 +311,8 @@ impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> {
        ///
        /// Successive calls to this method will add another address. Caller is responsible for not
        /// adding duplicate addresses and only calling if capable of receiving to P2TR addresses.
+       ///
+       /// This is not exported to bindings users as TweakedPublicKey isn't yet mapped.
        pub fn fallback_v1_p2tr_tweaked(mut self, output_key: &TweakedPublicKey) -> Self {
                let address = FallbackAddress {
                        version: WitnessVersion::V1.to_num(),
@@ -369,6 +379,8 @@ impl<'a> UnsignedInvoice<'a> {
        }
 
        /// Signs the invoice using the given function.
+       ///
+       /// This is not exported to bindings users as functions aren't currently mapped.
        pub fn sign<F, E>(self, sign: F) -> Result<Invoice, SignError<E>>
        where
                F: FnOnce(&Message) -> Result<Signature, E>
@@ -405,6 +417,8 @@ impl<'a> UnsignedInvoice<'a> {
 /// An invoice may be sent in response to an [`InvoiceRequest`] in the case of an offer or sent
 /// directly after scanning a refund. It includes all the information needed to pay a recipient.
 ///
+/// This is not exported to bindings users as its name conflicts with the BOLT 11 Invoice type.
+///
 /// [`Offer`]: crate::offers::offer::Offer
 /// [`Refund`]: crate::offers::refund::Refund
 /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
@@ -464,6 +478,8 @@ impl Invoice {
        ///
        /// Blinded paths provide recipient privacy by obfuscating its node id. Note, however, that this
        /// privacy is lost if a public node id is used for [`Invoice::signing_pubkey`].
+       ///
+       /// This is not exported to bindings users as a slice of tuples isn't exportable.
        pub fn payment_paths(&self) -> &[(BlindedPath, BlindedPayInfo)] {
                &self.contents.fields().payment_paths[..]
        }
@@ -504,6 +520,8 @@ impl Invoice {
 
        /// Fallback addresses for paying the invoice on-chain, in order of most-preferred to
        /// least-preferred.
+       ///
+       /// This is not exported to bindings users as Address is not yet mapped
        pub fn fallbacks(&self) -> Vec<Address> {
                let network = match self.network() {
                        None => return Vec::new(),
@@ -568,6 +586,8 @@ impl Invoice {
        }
 
        /// Signature of the invoice verified using [`Invoice::signing_pubkey`].
+       ///
+       /// This is not exported to bindings users as SIgnature is not yet mapped.
        pub fn signature(&self) -> Signature {
                self.signature
        }
index e8aeb2c827b68e03a6f24c804532d903b53893c3..7243b7b92b32b2904c3e3f7278d5a3ce5fe44b67 100644 (file)
@@ -84,6 +84,8 @@ pub(super) const IV_BYTES: &[u8; IV_LEN] = b"LDK Invreq ~~~~~";
 ///
 /// See [module-level documentation] for usage.
 ///
+/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
+///
 /// [module-level documentation]: self
 pub struct InvoiceRequestBuilder<'a, 'b, P: PayerIdStrategy, T: secp256k1::Signing> {
        offer: &'a Offer,
@@ -94,12 +96,18 @@ pub struct InvoiceRequestBuilder<'a, 'b, P: PayerIdStrategy, T: secp256k1::Signi
 }
 
 /// Indicates how [`InvoiceRequest::payer_id`] will be set.
+///
+/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
 pub trait PayerIdStrategy {}
 
 /// [`InvoiceRequest::payer_id`] will be explicitly set.
+///
+/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
 pub struct ExplicitPayerId {}
 
 /// [`InvoiceRequest::payer_id`] will be derived.
+///
+/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
 pub struct DerivedPayerId {}
 
 impl PayerIdStrategy for ExplicitPayerId {}
@@ -340,6 +348,8 @@ pub struct UnsignedInvoiceRequest<'a> {
 
 impl<'a> UnsignedInvoiceRequest<'a> {
        /// Signs the invoice request using the given function.
+       ///
+       /// This is not exported to bindings users as functions are not yet mapped.
        pub fn sign<F, E>(self, sign: F) -> Result<InvoiceRequest, SignError<E>>
        where
                F: FnOnce(&Message) -> Result<Signature, E>
@@ -454,6 +464,8 @@ impl InvoiceRequest {
 
        /// Signature of the invoice request using [`payer_id`].
        ///
+       /// This is not exported to bindings users as Signature is not yet mapped.
+       ///
        /// [`payer_id`]: Self::payer_id
        pub fn signature(&self) -> Signature {
                self.signature
@@ -465,6 +477,8 @@ impl InvoiceRequest {
        /// See [`InvoiceRequest::respond_with_no_std`] for further details where the aforementioned
        /// creation time is used for the `created_at` parameter.
        ///
+       /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
+       ///
        /// [`Duration`]: core::time::Duration
        #[cfg(feature = "std")]
        pub fn respond_with(
@@ -493,6 +507,8 @@ impl InvoiceRequest {
        ///
        /// Errors if the request contains unknown required features.
        ///
+       /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
+       ///
        /// [`Invoice::created_at`]: crate::offers::invoice::Invoice::created_at
        pub fn respond_with_no_std(
                &self, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, payment_hash: PaymentHash,
@@ -511,6 +527,8 @@ impl InvoiceRequest {
        ///
        /// See [`InvoiceRequest::respond_with`] for further details.
        ///
+       /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
+       ///
        /// [`Invoice`]: crate::offers::invoice::Invoice
        #[cfg(feature = "std")]
        pub fn verify_and_respond_using_derived_keys<T: secp256k1::Signing>(
@@ -532,6 +550,8 @@ impl InvoiceRequest {
        ///
        /// See [`InvoiceRequest::respond_with_no_std`] for further details.
        ///
+       /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
+       ///
        /// [`Invoice`]: crate::offers::invoice::Invoice
        pub fn verify_and_respond_using_derived_keys_no_std<T: secp256k1::Signing>(
                &self, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, payment_hash: PaymentHash,
@@ -554,6 +574,8 @@ impl InvoiceRequest {
        /// keys need to sign an [`Invoice`] for the request if they could be extracted from the
        /// metadata.
        ///
+       /// This is not exported to bindings users as KeyPair is not yet mapped.
+       ///
        /// [`Invoice`]: crate::offers::invoice::Invoice
        pub fn verify<T: secp256k1::Signing>(
                &self, key: &ExpandedKey, secp_ctx: &Secp256k1<T>
index 887318c0c0ea8dccffad71d61ecfdaaf045da6df..a49ed5ff69cde279e5a8f799523e2deb47fe0875 100644 (file)
@@ -98,6 +98,8 @@ pub(super) const IV_BYTES: &[u8; IV_LEN] = b"LDK Offer ~~~~~~";
 ///
 /// See [module-level documentation] for usage.
 ///
+/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
+///
 /// [module-level documentation]: self
 pub struct OfferBuilder<'a, M: MetadataStrategy, T: secp256k1::Signing> {
        offer: OfferContents,
@@ -106,12 +108,18 @@ pub struct OfferBuilder<'a, M: MetadataStrategy, T: secp256k1::Signing> {
 }
 
 /// Indicates how [`Offer::metadata`] may be set.
+///
+/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
 pub trait MetadataStrategy {}
 
 /// [`Offer::metadata`] may be explicitly set or left empty.
+///
+/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
 pub struct ExplicitMetadata {}
 
 /// [`Offer::metadata`] will be derived.
+///
+/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
 pub struct DerivedMetadata {}
 
 impl MetadataStrategy for ExplicitMetadata {}
@@ -448,6 +456,8 @@ impl Offer {
        ///
        /// Useful to protect the sender's privacy.
        ///
+       /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
+       ///
        /// [`InvoiceRequest::payer_id`]: crate::offers::invoice_request::InvoiceRequest::payer_id
        /// [`InvoiceRequest::metadata`]: crate::offers::invoice_request::InvoiceRequest::metadata
        /// [`Invoice::verify`]: crate::offers::invoice::Invoice::verify
@@ -470,6 +480,8 @@ impl Offer {
        ///
        /// Useful for recurring payments using the same `payer_id` with different invoices.
        ///
+       /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
+       ///
        /// [`InvoiceRequest::payer_id`]: crate::offers::invoice_request::InvoiceRequest::payer_id
        pub fn request_invoice_deriving_metadata<ES: Deref>(
                &self, payer_id: PublicKey, expanded_key: &ExpandedKey, entropy_source: ES
@@ -496,6 +508,8 @@ impl Offer {
        ///
        /// Errors if the offer contains unknown required features.
        ///
+       /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
+       ///
        /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
        pub fn request_invoice(
                &self, metadata: Vec<u8>, payer_id: PublicKey
@@ -691,6 +705,9 @@ pub enum Amount {
        /// An amount of currency specified using ISO 4712.
        Currency {
                /// The currency that the amount is denominated in.
+               ///
+               /// This is not exported to bindings users as bindings have troubles with type aliases to
+               /// byte arrays.
                iso4217_code: CurrencyCode,
                /// The amount in the currency unit adjusted by the ISO 4712 exponent (e.g., USD cents).
                amount: u64,
@@ -698,7 +715,7 @@ pub enum Amount {
 }
 
 /// 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)]
@@ -708,7 +725,8 @@ pub enum Quantity {
        ///
        /// May be used with `NonZeroU64::new(1)` but prefer to use [`Quantity::One`] if only one item
        /// is supported.
-       Bounded(NonZeroU64),
+       Bounded(/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
+               NonZeroU64),
        /// One or more items. Use when more than one item can be requested without any limit.
        Unbounded,
        /// Only one item. Use when only a single item can be requested.
index 3f1a9c887ec002315d56d766910b026e6d7efedc..022a7b4c8abe61d751983d937047166dd936e0f7 100644 (file)
@@ -116,6 +116,8 @@ impl<T: SeekReadable> TryFrom<Vec<u8>> for ParsedMessage<T> {
 }
 
 /// Error when parsing a bech32 encoded message using [`str::parse`].
+///
+/// This is not exported to bindings users as its name conflicts with the BOLT 11 ParseError type.
 #[derive(Debug, PartialEq)]
 pub enum ParseError {
        /// The bech32 encoding does not conform to the BOLT 12 requirements for continuing messages
@@ -125,7 +127,8 @@ pub enum ParseError {
        /// 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.
@@ -135,6 +138,8 @@ pub enum ParseError {
 }
 
 /// Error when interpreting a TLV stream as a specific type.
+///
+/// This is not exported to bindings users as its name conflicts with the BOLT 11 SemanticError type.
 #[derive(Debug, PartialEq)]
 pub enum SemanticError {
        /// The current [`std::time::SystemTime`] is past the offer or invoice's expiration.
index d5d80198ef29c8045f9097ddec5645fa1c47ffd7..6cbdd2da2bc091e70c731942970fabec55ba2026 100644 (file)
@@ -105,6 +105,8 @@ pub(super) const IV_BYTES: &[u8; IV_LEN] = b"LDK Refund ~~~~~";
 ///
 /// See [module-level documentation] for usage.
 ///
+/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
+///
 /// [module-level documentation]: self
 pub struct RefundBuilder<'a, T: secp256k1::Signing> {
        refund: RefundContents,
@@ -387,6 +389,8 @@ impl Refund {
        /// See [`Refund::respond_with_no_std`] for further details where the aforementioned creation
        /// time is used for the `created_at` parameter.
        ///
+       /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
+       ///
        /// [`Duration`]: core::time::Duration
        #[cfg(feature = "std")]
        pub fn respond_with(
@@ -419,6 +423,8 @@ impl Refund {
        ///
        /// Errors if the request contains unknown required features.
        ///
+       /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
+       ///
        /// [`Invoice::created_at`]: crate::offers::invoice::Invoice::created_at
        pub fn respond_with_no_std(
                &self, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, payment_hash: PaymentHash,
@@ -436,6 +442,8 @@ impl Refund {
        ///
        /// See [`Refund::respond_with`] for further details.
        ///
+       /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
+       ///
        /// [`Invoice`]: crate::offers::invoice::Invoice
        #[cfg(feature = "std")]
        pub fn respond_using_derived_keys<ES: Deref>(
@@ -459,6 +467,8 @@ impl Refund {
        ///
        /// See [`Refund::respond_with_no_std`] for further details.
        ///
+       /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
+       ///
        /// [`Invoice`]: crate::offers::invoice::Invoice
        pub fn respond_using_derived_keys_no_std<ES: Deref>(
                &self, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, payment_hash: PaymentHash,
index b50282433b18a128df1185711861a98ea0b44aa4..4cd167ecf3dd5cc39e8dd8d16e49956fea1a0e3e 100644 (file)
@@ -22,7 +22,7 @@ use crate::ln::features::{InitFeatures, NodeFeatures};
 use crate::ln::msgs::{self, OnionMessageHandler};
 use crate::ln::onion_utils;
 use crate::ln::peer_handler::IgnoringMessageHandler;
-pub use super::packet::{CustomOnionMessageContents, OnionMessageContents};
+pub(crate) use super::packet::{CustomOnionMessageContents, OnionMessageContents};
 use super::packet::{BIG_PACKET_HOP_DATA_LEN, ForwardControlTlvs, Packet, Payload, ReceiveControlTlvs, SMALL_PACKET_HOP_DATA_LEN};
 use crate::util::logger::Logger;
 use crate::util::ser::Writeable;
@@ -45,7 +45,8 @@ use crate::prelude::*;
 /// # use lightning::blinded_path::BlindedPath;
 /// # use lightning::chain::keysinterface::KeysManager;
 /// # use lightning::ln::peer_handler::IgnoringMessageHandler;
-/// # use lightning::onion_message::{CustomOnionMessageContents, Destination, OnionMessageContents, OnionMessenger};
+/// # use lightning::onion_message::messenger::{Destination, OnionMessenger};
+/// # use lightning::onion_message::packet::{CustomOnionMessageContents, OnionMessageContents};
 /// # use lightning::util::logger::{Logger, Record};
 /// # use lightning::util::ser::{Writeable, Writer};
 /// # use lightning::io;
index 713b83c62d67d3e0a2fdcc39fd5a004d8a744e6c..893a35532d865eeebd063952e05c4070afb70e1c 100644 (file)
 //! [offers]: <https://github.com/lightning/bolts/pull/798>
 //! [blinded paths]: crate::blinded_path::BlindedPath
 
-mod messenger;
-mod packet;
+pub mod messenger;
+pub mod packet;
 #[cfg(test)]
 mod functional_tests;
 
 // Re-export structs so they can be imported with just the `onion_message::` module prefix.
-pub use self::messenger::{CustomOnionMessageContents, CustomOnionMessageHandler, Destination, OnionMessageContents, OnionMessenger, SendError, SimpleArcOnionMessenger, SimpleRefOnionMessenger};
+pub(crate) use self::messenger::{CustomOnionMessageContents, CustomOnionMessageHandler, Destination, OnionMessageContents, OnionMessenger, SendError, SimpleArcOnionMessenger, SimpleRefOnionMessenger};
 pub(crate) use self::packet::{ControlTlvs, Packet};
index e5f5e63c93893b114137c888b941519e28e5488f..531be4c235028fd49452a9d2e80ffba031eb11ad 100644 (file)
@@ -829,7 +829,7 @@ pub struct 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)> {
                let (direction, source) = {
                        if target == &self.node_one {
                                (self.two_to_one.as_ref(), &self.node_two)
@@ -844,7 +844,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)> {
                let (direction, target) = {
                        if source == &self.node_one {
                                (self.one_to_two.as_ref(), &self.node_two)
index e60e4879b3d5e25ca121ed6d1a543b120317282f..f3a508ab6fc2d31cd3f6e236387312f69f33da60 100644 (file)
@@ -316,12 +316,44 @@ impl ReadableArgs<u64> for FixedPenaltyScorer {
 }
 
 #[cfg(not(feature = "no-std"))]
-type ConfiguredTime = std::time::Instant;
-#[cfg(feature = "no-std")]
-use crate::util::time::Eternity;
+/// [`Score`] implementation using channel success probability distributions.
+///
+/// Channels are tracked with upper and lower liquidity bounds - when an HTLC fails at a channel,
+/// we learn that the upper-bound on the available liquidity is lower than the amount of the HTLC.
+/// When a payment is forwarded through a channel (but fails later in the route), we learn the
+/// lower-bound on the channel's available liquidity must be at least the value of the HTLC.
+///
+/// These bounds are then used to determine a success probability using the formula from
+/// *Optimally Reliable & Cheap Payment Flows on the Lightning Network* by Rene Pickhardt
+/// and Stefan Richter [[1]] (i.e. `(upper_bound - payment_amount) / (upper_bound - lower_bound)`).
+///
+/// This probability is combined with the [`liquidity_penalty_multiplier_msat`] and
+/// [`liquidity_penalty_amount_multiplier_msat`] parameters to calculate a concrete penalty in
+/// milli-satoshis. The penalties, when added across all hops, have the property of being linear in
+/// terms of the entire path's success probability. This allows the router to directly compare
+/// penalties for different paths. See the documentation of those parameters for the exact formulas.
+///
+/// The liquidity bounds are decayed by halving them every [`liquidity_offset_half_life`].
+///
+/// Further, we track the history of our upper and lower liquidity bounds for each channel,
+/// allowing us to assign a second penalty (using [`historical_liquidity_penalty_multiplier_msat`]
+/// and [`historical_liquidity_penalty_amount_multiplier_msat`]) based on the same probability
+/// formula, but using the history of a channel rather than our latest estimates for the liquidity
+/// bounds.
+///
+/// # Note
+///
+/// Mixing the `no-std` feature between serialization and deserialization results in undefined
+/// behavior.
+///
+/// [1]: https://arxiv.org/abs/2107.05322
+/// [`liquidity_penalty_multiplier_msat`]: ProbabilisticScoringParameters::liquidity_penalty_multiplier_msat
+/// [`liquidity_penalty_amount_multiplier_msat`]: ProbabilisticScoringParameters::liquidity_penalty_amount_multiplier_msat
+/// [`liquidity_offset_half_life`]: ProbabilisticScoringParameters::liquidity_offset_half_life
+/// [`historical_liquidity_penalty_multiplier_msat`]: ProbabilisticScoringParameters::historical_liquidity_penalty_multiplier_msat
+/// [`historical_liquidity_penalty_amount_multiplier_msat`]: ProbabilisticScoringParameters::historical_liquidity_penalty_amount_multiplier_msat
+pub type ProbabilisticScorer<G, L> = ProbabilisticScorerUsingTime::<G, L, std::time::Instant>;
 #[cfg(feature = "no-std")]
-type ConfiguredTime = Eternity;
-
 /// [`Score`] implementation using channel success probability distributions.
 ///
 /// Channels are tracked with upper and lower liquidity bounds - when an HTLC fails at a channel,
@@ -358,7 +390,7 @@ type ConfiguredTime = Eternity;
 /// [`liquidity_offset_half_life`]: ProbabilisticScoringParameters::liquidity_offset_half_life
 /// [`historical_liquidity_penalty_multiplier_msat`]: ProbabilisticScoringParameters::historical_liquidity_penalty_multiplier_msat
 /// [`historical_liquidity_penalty_amount_multiplier_msat`]: ProbabilisticScoringParameters::historical_liquidity_penalty_amount_multiplier_msat
-pub type ProbabilisticScorer<G, L> = ProbabilisticScorerUsingTime::<G, L, ConfiguredTime>;
+pub type ProbabilisticScorer<G, L> = ProbabilisticScorerUsingTime::<G, L, crate::util::time::Eternity>;
 
 /// Probabilistic [`Score`] implementation.
 ///
index aa705f286736ada5cf8d12635fc91f0d459dd29c..0accd0cc12868dd52226dd84bccc2ea88c74ed31 100644 (file)
@@ -28,6 +28,7 @@ use super::{logger::Logger, ser::Writeable};
 /// Implementing `KVStorePersister` provides auto-implementations for [`Persister`]
 /// and [`Persist`] traits.  It uses "manager", "network_graph",
 /// and "monitors/{funding_txo_id}_{funding_txo_index}" for keys.
+/// (C-not exported)
 pub trait KVStorePersister {
        /// Persist the given writeable using the provided key
        fn persist<W: Writeable>(&self, key: &str, object: &W) -> io::Result<()>;
index 602c2ee04b7d0fb2b85554e8d5566aef8f3fd6d6..37c036da9594747ea81b142e151ff960c2892dad 100644 (file)
@@ -45,7 +45,7 @@ impl Notifier {
        pub(crate) fn notify(&self) {
                let mut lock = self.notify_pending.lock().unwrap();
                if let Some(future_state) = &lock.1 {
-                       if future_state.lock().unwrap().complete() {
+                       if complete_future(future_state) {
                                lock.1 = None;
                                return;
                        }
@@ -69,6 +69,7 @@ impl Notifier {
                } else {
                        let state = Arc::new(Mutex::new(FutureState {
                                callbacks: Vec::new(),
+                               callbacks_with_state: Vec::new(),
                                complete: lock.0,
                                callbacks_made: false,
                        }));
@@ -112,19 +113,24 @@ pub(crate) struct FutureState {
        // first bool - set to false if we're just calling a Waker, and true if we're calling an actual
        // user-provided function.
        callbacks: Vec<(bool, Box<dyn FutureCallback>)>,
+       callbacks_with_state: Vec<(bool, Box<dyn Fn(&Arc<Mutex<FutureState>>) -> () + Send>)>,
        complete: bool,
        callbacks_made: bool,
 }
 
-impl FutureState {
-       fn complete(&mut self) -> bool {
-               for (counts_as_call, callback) in self.callbacks.drain(..) {
-                       callback.call();
-                       self.callbacks_made |= counts_as_call;
-               }
-               self.complete = true;
-               self.callbacks_made
+fn complete_future(this: &Arc<Mutex<FutureState>>) -> bool {
+       let mut state_lock = this.lock().unwrap();
+       let state = &mut *state_lock;
+       for (counts_as_call, callback) in state.callbacks.drain(..) {
+               callback.call();
+               state.callbacks_made |= counts_as_call;
+       }
+       for (counts_as_call, callback) in state.callbacks_with_state.drain(..) {
+               (callback)(this);
+               state.callbacks_made |= counts_as_call;
        }
+       state.complete = true;
+       state.callbacks_made
 }
 
 /// A simple future which can complete once, and calls some callback(s) when it does so.
@@ -240,14 +246,13 @@ impl Sleeper {
                        for notifier_mtx in self.notifiers.iter() {
                                let cv_ref = Arc::clone(&cv);
                                let notified_fut_ref = Arc::clone(&notified_fut_mtx);
-                               let notifier_ref = Arc::clone(&notifier_mtx);
                                let mut notifier = notifier_mtx.lock().unwrap();
                                if notifier.complete {
-                                       *notified_fut_mtx.lock().unwrap() = Some(notifier_ref);
+                                       *notified_fut_mtx.lock().unwrap() = Some(Arc::clone(&notifier_mtx));
                                        break;
                                }
-                               notifier.callbacks.push((false, Box::new(move || {
-                                       *notified_fut_ref.lock().unwrap() = Some(Arc::clone(&notifier_ref));
+                               notifier.callbacks_with_state.push((false, Box::new(move |notifier_ref| {
+                                       *notified_fut_ref.lock().unwrap() = Some(Arc::clone(notifier_ref));
                                        cv_ref.notify_all();
                                })));
                        }
@@ -407,11 +412,50 @@ mod tests {
                }
        }
 
+       #[cfg(feature = "std")]
+       #[test]
+       fn test_state_drops() {
+               // Previously, there was a leak if a `Notifier` was `drop`ed without ever being notified
+               // but after having been slept-on. This tests for that leak.
+               use crate::sync::Arc;
+               use std::thread;
+
+               let notifier_a = Arc::new(Notifier::new());
+               let notifier_b = Arc::new(Notifier::new());
+
+               let thread_notifier_a = Arc::clone(&notifier_a);
+
+               let future_a = notifier_a.get_future();
+               let future_state_a = Arc::downgrade(&future_a.state);
+
+               let future_b = notifier_b.get_future();
+               let future_state_b = Arc::downgrade(&future_b.state);
+
+               let join_handle = thread::spawn(move || {
+                       // Let the other thread get to the wait point, then notify it.
+                       std::thread::sleep(Duration::from_millis(50));
+                       thread_notifier_a.notify();
+               });
+
+               // Wait on the other thread to finish its sleep, note that the leak only happened if we
+               // actually have to sleep here, not if we immediately return.
+               Sleeper::from_two_futures(future_a, future_b).wait();
+
+               join_handle.join().unwrap();
+
+               // then drop the notifiers and make sure the future states are gone.
+               mem::drop(notifier_a);
+               mem::drop(notifier_b);
+
+               assert!(future_state_a.upgrade().is_none() && future_state_b.upgrade().is_none());
+       }
+
        #[test]
        fn test_future_callbacks() {
                let future = Future {
                        state: Arc::new(Mutex::new(FutureState {
                                callbacks: Vec::new(),
+                               callbacks_with_state: Vec::new(),
                                complete: false,
                                callbacks_made: false,
                        }))
@@ -421,9 +465,9 @@ mod tests {
                future.register_callback(Box::new(move || assert!(!callback_ref.fetch_or(true, Ordering::SeqCst))));
 
                assert!(!callback.load(Ordering::SeqCst));
-               future.state.lock().unwrap().complete();
+               complete_future(&future.state);
                assert!(callback.load(Ordering::SeqCst));
-               future.state.lock().unwrap().complete();
+               complete_future(&future.state);
        }
 
        #[test]
@@ -431,11 +475,12 @@ mod tests {
                let future = Future {
                        state: Arc::new(Mutex::new(FutureState {
                                callbacks: Vec::new(),
+                               callbacks_with_state: Vec::new(),
                                complete: false,
                                callbacks_made: false,
                        }))
                };
-               future.state.lock().unwrap().complete();
+               complete_future(&future.state);
 
                let callback = Arc::new(AtomicBool::new(false));
                let callback_ref = Arc::clone(&callback);
@@ -469,6 +514,7 @@ mod tests {
                let mut future = Future {
                        state: Arc::new(Mutex::new(FutureState {
                                callbacks: Vec::new(),
+                               callbacks_with_state: Vec::new(),
                                complete: false,
                                callbacks_made: false,
                        }))
@@ -483,7 +529,7 @@ mod tests {
                assert_eq!(Pin::new(&mut second_future).poll(&mut Context::from_waker(&second_waker)), Poll::Pending);
                assert!(!second_woken.load(Ordering::SeqCst));
 
-               future.state.lock().unwrap().complete();
+               complete_future(&future.state);
                assert!(woken.load(Ordering::SeqCst));
                assert!(second_woken.load(Ordering::SeqCst));
                assert_eq!(Pin::new(&mut future).poll(&mut Context::from_waker(&waker)), Poll::Ready(()));