diff --git a/fuzz/src/chanmon_consistency.rs b/fuzz/src/chanmon_consistency.rs index 0461c75772c..43495acaa68 100644 --- a/fuzz/src/chanmon_consistency.rs +++ b/fuzz/src/chanmon_consistency.rs @@ -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; diff --git a/fuzz/src/onion_message.rs b/fuzz/src/onion_message.rs index 9bbf8b9cdff..de84f049faa 100644 --- a/fuzz/src/onion_message.rs +++ b/fuzz/src/onion_message.rs @@ -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; diff --git a/lightning-invoice/src/lib.rs b/lightning-invoice/src/lib.rs index 0923fcc1756..101051b5e7f 100644 --- a/lightning-invoice/src/lib.rs +++ b/lightning-invoice/src/lib.rs @@ -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 diff --git a/lightning-invoice/src/payment.rs b/lightning-invoice/src/payment.rs index 11757be2e3a..30897413513 100644 --- a/lightning-invoice/src/payment.rs +++ b/lightning-invoice/src/payment.rs @@ -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; diff --git a/lightning-invoice/src/utils.rs b/lightning-invoice/src/utils.rs index 5f378ab6fbd..2abe2313c73 100644 --- a/lightning-invoice/src/utils.rs +++ b/lightning-invoice/src/utils.rs @@ -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}; diff --git a/lightning-persister/src/lib.rs b/lightning-persister/src/lib.rs index e6687fef7b8..51d91e2442a 100644 --- a/lightning-persister/src/lib.rs +++ b/lightning-persister/src/lib.rs @@ -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 ( - &self, entropy_source: ES, signer_provider: SP - ) -> std::io::Result::Signer>)>> + pub fn read_channelmonitors + Sized, SPD: Deref> ( + &self, entropy_source: ES, signer_provider: SPD + ) -> Result)>, 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<::Signer>)>::read(&mut buffer, (&*entropy_source, &*signer_provider)) { + match <(BlockHash, ChannelMonitor)>::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, diff --git a/lightning-rapid-gossip-sync/src/lib.rs b/lightning-rapid-gossip-sync/src/lib.rs index c8f140cc189..9e2b8334e64 100644 --- a/lightning-rapid-gossip-sync/src/lib.rs +++ b/lightning-rapid-gossip-sync/src/lib.rs @@ -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; diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index f2c6ea18249..c0fbb6a980e 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -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) { +impl<'a, 'b, ES: EntropySource, SP: SignerProvider, Signer: WriteableEcdsaChannelSigner> 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) => { diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 8b5e89d9441..a45b91f6322 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -5539,7 +5539,7 @@ impl Channel { 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 Channel { .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()))?; diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 498813de7a1..43a854b3df1 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -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, diff --git a/lightning/src/ln/mod.rs b/lightning/src/ln/mod.rs index 340213c5150..e60cbb58559 100644 --- a/lightning/src/ln/mod.rs +++ b/lightning/src/ln/mod.rs @@ -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 diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index 4b2eb9674fa..3dec35e9f06 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -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(&self, writer: &mut W) -> Result<(), io::Error> { match self { UnsignedGossipMessage::ChannelAnnouncement(ref msg) => msg.write(writer), diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index 84870143008..6dcb6cbd865 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -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 sig, Err(_) => { diff --git a/lightning/src/ln/priv_short_conf_tests.rs b/lightning/src/ln/priv_short_conf_tests.rs index 7bb1fd44f2f..97639b122cb 100644 --- a/lightning/src/ln/priv_short_conf_tests.rs +++ b/lightning/src/ln/priv_short_conf_tests.rs @@ -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(); diff --git a/lightning/src/offers/invoice.rs b/lightning/src/offers/invoice.rs index 05b2b5d010e..7d24c2e46a9 100644 --- a/lightning/src/offers/invoice.rs +++ b/lightning/src/offers/invoice.rs @@ -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(self, sign: F) -> Result> where F: FnOnce(&Message) -> Result @@ -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
{ 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 } diff --git a/lightning/src/offers/invoice_request.rs b/lightning/src/offers/invoice_request.rs index e8aeb2c827b..7243b7b92b3 100644 --- a/lightning/src/offers/invoice_request.rs +++ b/lightning/src/offers/invoice_request.rs @@ -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(self, sign: F) -> Result> where F: FnOnce(&Message) -> Result @@ -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( @@ -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( &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( &self, key: &ExpandedKey, secp_ctx: &Secp256k1 diff --git a/lightning/src/offers/offer.rs b/lightning/src/offers/offer.rs index 887318c0c0e..a49ed5ff69c 100644 --- a/lightning/src/offers/offer.rs +++ b/lightning/src/offers/offer.rs @@ -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( &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, 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. diff --git a/lightning/src/offers/parse.rs b/lightning/src/offers/parse.rs index 3f1a9c887ec..022a7b4c8ab 100644 --- a/lightning/src/offers/parse.rs +++ b/lightning/src/offers/parse.rs @@ -116,6 +116,8 @@ impl TryFrom> for ParsedMessage { } /// 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. diff --git a/lightning/src/offers/refund.rs b/lightning/src/offers/refund.rs index d5d80198ef2..6cbdd2da2bc 100644 --- a/lightning/src/offers/refund.rs +++ b/lightning/src/offers/refund.rs @@ -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( @@ -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( &self, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, payment_hash: PaymentHash, diff --git a/lightning/src/onion_message/messenger.rs b/lightning/src/onion_message/messenger.rs index b50282433b1..4cd167ecf3d 100644 --- a/lightning/src/onion_message/messenger.rs +++ b/lightning/src/onion_message/messenger.rs @@ -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; diff --git a/lightning/src/onion_message/mod.rs b/lightning/src/onion_message/mod.rs index 713b83c62d6..893a35532d8 100644 --- a/lightning/src/onion_message/mod.rs +++ b/lightning/src/onion_message/mod.rs @@ -20,11 +20,11 @@ //! [offers]: //! [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}; diff --git a/lightning/src/routing/gossip.rs b/lightning/src/routing/gossip.rs index e5f5e63c938..531be4c2350 100644 --- a/lightning/src/routing/gossip.rs +++ b/lightning/src/routing/gossip.rs @@ -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) diff --git a/lightning/src/routing/scoring.rs b/lightning/src/routing/scoring.rs index e60e4879b3d..f3a508ab6fc 100644 --- a/lightning/src/routing/scoring.rs +++ b/lightning/src/routing/scoring.rs @@ -316,12 +316,44 @@ impl ReadableArgs 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 = ProbabilisticScorerUsingTime::; #[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 = ProbabilisticScorerUsingTime::; +pub type ProbabilisticScorer = ProbabilisticScorerUsingTime::; /// Probabilistic [`Score`] implementation. /// diff --git a/lightning/src/util/persist.rs b/lightning/src/util/persist.rs index aa705f28673..0accd0cc128 100644 --- a/lightning/src/util/persist.rs +++ b/lightning/src/util/persist.rs @@ -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(&self, key: &str, object: &W) -> io::Result<()>; diff --git a/lightning/src/util/wakers.rs b/lightning/src/util/wakers.rs index 602c2ee04b7..37c036da959 100644 --- a/lightning/src/util/wakers.rs +++ b/lightning/src/util/wakers.rs @@ -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)>, + callbacks_with_state: Vec<(bool, Box>) -> () + 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>) -> 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(¬ified_fut_mtx); - let notifier_ref = Arc::clone(¬ifier_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(¬ifier_mtx)); break; } - notifier.callbacks.push((false, Box::new(move || { - *notified_fut_ref.lock().unwrap() = Some(Arc::clone(¬ifier_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(¬ifier_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(()));