From: Matt Corallo <649246+TheBlueMatt@users.noreply.github.com> Date: Thu, 27 Oct 2022 23:16:03 +0000 (+0000) Subject: Merge pull request #1810 from TheBlueMatt/2022-10-112-bindings-base X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=fe1be693cf6317ae4b35ee3f1fe11896df64c9fa;hp=42ab358b4644e31dc6054ad2555128b1b35c1c9e;p=rust-lightning Merge pull request #1810 from TheBlueMatt/2022-10-112-bindings-base 0.0.112 Bindings Branch --- diff --git a/fuzz/src/onion_message.rs b/fuzz/src/onion_message.rs index 5318c0c9..6f5c945c 100644 --- a/fuzz/src/onion_message.rs +++ b/fuzz/src/onion_message.rs @@ -10,8 +10,9 @@ use lightning::ln::msgs::{self, DecodeError, OnionMessageHandler}; use lightning::ln::script::ShutdownScript; use lightning::util::enforcing_trait_impls::EnforcingSigner; use lightning::util::logger::Logger; -use lightning::util::ser::{MaybeReadableArgs, Readable, Writeable, Writer}; -use lightning::onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, OnionMessenger}; +use lightning::util::ser::{Readable, Writeable, Writer}; +use lightning::onion_message::packet::CustomOnionMessageContents; +use lightning::onion_message::messenger::{OnionMessenger, CustomOnionMessageHandler}; use crate::utils::test_logger; @@ -67,19 +68,16 @@ impl Writeable for TestCustomMessage { } } -impl MaybeReadableArgs for TestCustomMessage { - fn read(buffer: &mut R, _message_type: u64,) -> Result, DecodeError> where Self: Sized { - let mut buf = Vec::new(); - buffer.read_to_end(&mut buf)?; - return Ok(Some(TestCustomMessage {})) - } -} - struct TestCustomMessageHandler {} impl CustomOnionMessageHandler for TestCustomMessageHandler { type CustomMessage = TestCustomMessage; fn handle_custom_message(&self, _msg: Self::CustomMessage) {} + fn read_custom_message(&self, _message_type: u64, buffer: &mut R) -> Result, msgs::DecodeError> { + let mut buf = Vec::new(); + buffer.read_to_end(&mut buf)?; + return Ok(Some(TestCustomMessage {})) + } } pub struct VecWriter(pub Vec); diff --git a/lightning-rapid-gossip-sync/src/lib.rs b/lightning-rapid-gossip-sync/src/lib.rs index 06ce7eb2..b347f69c 100644 --- a/lightning-rapid-gossip-sync/src/lib.rs +++ b/lightning-rapid-gossip-sync/src/lib.rs @@ -79,10 +79,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/ln/chan_utils.rs b/lightning/src/ln/chan_utils.rs index a8c9dcc8..3f52bd48 100644 --- a/lightning/src/ln/chan_utils.rs +++ b/lightning/src/ln/chan_utils.rs @@ -737,7 +737,7 @@ pub(crate) fn get_anchor_output<'a>(commitment_tx: &'a Transaction, funding_pubk } /// Returns the witness required to satisfy and spend an anchor input. -pub fn build_anchor_input_witness(funding_key: &PublicKey, funding_sig: &Signature) -> Witness { +pub(crate) fn build_anchor_input_witness(funding_key: &PublicKey, funding_sig: &Signature) -> Witness { let anchor_redeem_script = chan_utils::get_anchor_redeemscript(funding_key); let mut funding_sig = funding_sig.serialize_der().to_vec(); funding_sig.push(EcdsaSighashType::All as u8); diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index 8b5a6ac6..f6bfc799 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -310,7 +310,7 @@ pub struct UpdateAddHTLC { pub struct OnionMessage { /// Used in decrypting the onion packet's payload. pub blinding_point: PublicKey, - pub(crate) onion_routing_packet: onion_message::Packet, + pub(crate) onion_routing_packet: onion_message::packet::Packet, } /// An update_fulfill_htlc message to be sent or received from a peer @@ -1422,7 +1422,7 @@ impl Readable for OnionMessage { let blinding_point: PublicKey = Readable::read(r)?; let len: u16 = Readable::read(r)?; let mut packet_reader = FixedLengthReader::new(r, len as u64); - let onion_routing_packet: onion_message::Packet = ::read(&mut packet_reader)?; + let onion_routing_packet = ::read(&mut packet_reader)?; Ok(Self { blinding_point, onion_routing_packet, diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs index 598edcf0..95331395 100644 --- a/lightning/src/ln/onion_utils.rs +++ b/lightning/src/ln/onion_utils.rs @@ -589,31 +589,6 @@ pub(super) fn process_onion_failure(secp_ctx: & } else { unreachable!(); } } -/// An input used when decoding an onion packet. -pub(crate) trait DecodeInput { - type Arg; - /// If Some, this is the input when checking the hmac of the onion packet. - fn payment_hash(&self) -> Option<&PaymentHash>; - /// Read argument when decrypting our hop payload. - fn read_arg(self) -> Self::Arg; -} - -impl DecodeInput for PaymentHash { - type Arg = (); - fn payment_hash(&self) -> Option<&PaymentHash> { - Some(self) - } - fn read_arg(self) -> Self::Arg { () } -} - -impl DecodeInput for SharedSecret { - type Arg = SharedSecret; - fn payment_hash(&self) -> Option<&PaymentHash> { - None - } - fn read_arg(self) -> Self::Arg { self } -} - /// Allows `decode_next_hop` to return the next hop packet bytes for either payments or onion /// message forwards. pub(crate) trait NextPacketBytes: AsMut<[u8]> { @@ -664,7 +639,7 @@ pub(crate) enum OnionDecodeErr { } pub(crate) fn decode_next_payment_hop(shared_secret: [u8; 32], hop_data: &[u8], hmac_bytes: [u8; 32], payment_hash: PaymentHash) -> Result { - match decode_next_hop(shared_secret, hop_data, hmac_bytes, payment_hash) { + match decode_next_hop(shared_secret, hop_data, hmac_bytes, Some(payment_hash), ()) { Ok((next_hop_data, None)) => Ok(Hop::Receive(next_hop_data)), Ok((next_hop_data, Some((next_hop_hmac, FixedSizeOnionPacket(new_packet_bytes))))) => { Ok(Hop::Forward { @@ -677,12 +652,16 @@ pub(crate) fn decode_next_payment_hop(shared_secret: [u8; 32], hop_data: &[u8], } } -pub(crate) fn decode_next_hop, N: NextPacketBytes>(shared_secret: [u8; 32], hop_data: &[u8], hmac_bytes: [u8; 32], decode_input: D) -> Result<(R, Option<([u8; 32], N)>), OnionDecodeErr> { +pub(crate) fn decode_next_untagged_hop, N: NextPacketBytes>(shared_secret: [u8; 32], hop_data: &[u8], hmac_bytes: [u8; 32], read_args: T) -> Result<(R, Option<([u8; 32], N)>), OnionDecodeErr> { + decode_next_hop(shared_secret, hop_data, hmac_bytes, None, read_args) +} + +fn decode_next_hop, N: NextPacketBytes>(shared_secret: [u8; 32], hop_data: &[u8], hmac_bytes: [u8; 32], payment_hash: Option, read_args: T) -> Result<(R, Option<([u8; 32], N)>), OnionDecodeErr> { let (rho, mu) = gen_rho_mu_from_shared_secret(&shared_secret); let mut hmac = HmacEngine::::new(&mu); hmac.input(hop_data); - if let Some(payment_hash) = decode_input.payment_hash() { - hmac.input(&payment_hash.0[..]); + if let Some(tag) = payment_hash { + hmac.input(&tag.0[..]); } if !fixed_time_eq(&Hmac::from_engine(hmac).into_inner(), &hmac_bytes) { return Err(OnionDecodeErr::Malformed { @@ -693,7 +672,7 @@ pub(crate) fn decode_next_hop, N: NextPa let mut chacha = ChaCha20::new(&rho, &[0u8; 8]); let mut chacha_stream = ChaChaReader { chacha: &mut chacha, read: Cursor::new(&hop_data[..]) }; - match R::read(&mut chacha_stream, decode_input.read_arg()) { + match R::read(&mut chacha_stream, read_args) { Err(err) => { let error_code = match err { msgs::DecodeError::UnknownVersion => 0x4000 | 1, // unknown realm byte diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index 228c2491..a65ed063 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -21,11 +21,12 @@ use crate::ln::features::{InitFeatures, NodeFeatures}; use crate::ln::msgs; use crate::ln::msgs::{ChannelMessageHandler, LightningError, NetAddress, OnionMessageHandler, RoutingMessageHandler}; use crate::ln::channelmanager::{SimpleArcChannelManager, SimpleRefChannelManager}; -use crate::util::ser::{MaybeReadableArgs, VecWriter, Writeable, Writer}; +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}; use crate::util::atomic_counter::AtomicCounter; use crate::util::crypto::sign; @@ -97,13 +98,11 @@ impl OnionMessageHandler for IgnoringMessageHandler { } impl CustomOnionMessageHandler for IgnoringMessageHandler { type CustomMessage = Infallible; - fn handle_custom_message(&self, _msg: Self::CustomMessage) { + fn handle_custom_message(&self, _msg: Infallible) { // Since we always return `None` in the read the handle method should never be called. unreachable!(); } -} -impl MaybeReadableArgs for Infallible { - fn read(_buffer: &mut R, _msg_type: u64) -> Result, msgs::DecodeError> where Self: Sized { + fn read_custom_message(&self, _msg_type: u64, _buffer: &mut R) -> Result, msgs::DecodeError> where Self: Sized { Ok(None) } } diff --git a/lightning/src/onion_message/functional_tests.rs b/lightning/src/onion_message/functional_tests.rs index 5c623cf2..efa6507b 100644 --- a/lightning/src/onion_message/functional_tests.rs +++ b/lightning/src/onion_message/functional_tests.rs @@ -12,9 +12,11 @@ use crate::chain::keysinterface::{KeysInterface, Recipient}; use crate::ln::features::InitFeatures; use crate::ln::msgs::{self, DecodeError, OnionMessageHandler}; -use super::{BlindedRoute, CustomOnionMessageContents, CustomOnionMessageHandler, Destination, OnionMessageContents, OnionMessenger, SendError}; +use super::blinded_route::BlindedRoute; +use super::messenger::{CustomOnionMessageHandler, Destination, OnionMessenger, SendError}; +use super::packet::{CustomOnionMessageContents, OnionMessageContents}; use crate::util::enforcing_trait_impls::EnforcingSigner; -use crate::util::ser::{MaybeReadableArgs, Writeable, Writer}; +use crate::util::ser::{ Writeable, Writer}; use crate::util::test_utils; use bitcoin::network::constants::Network; @@ -54,8 +56,12 @@ impl Writeable for TestCustomMessage { } } -impl MaybeReadableArgs for TestCustomMessage { - fn read(buffer: &mut R, message_type: u64) -> Result, DecodeError> where Self: Sized { +struct TestCustomMessageHandler {} + +impl CustomOnionMessageHandler for TestCustomMessageHandler { + type CustomMessage = TestCustomMessage; + fn handle_custom_message(&self, _msg: Self::CustomMessage) {} + fn read_custom_message(&self, message_type: u64, buffer: &mut R) -> Result, DecodeError> where Self: Sized { if message_type == CUSTOM_MESSAGE_TYPE { let mut buf = Vec::new(); buffer.read_to_end(&mut buf)?; @@ -66,13 +72,6 @@ impl MaybeReadableArgs for TestCustomMessage { } } -struct TestCustomMessageHandler {} - -impl CustomOnionMessageHandler for TestCustomMessageHandler { - type CustomMessage = TestCustomMessage; - fn handle_custom_message(&self, _msg: Self::CustomMessage) {} -} - fn create_nodes(num_messengers: u8) -> Vec { let mut nodes = Vec::new(); for i in 0..num_messengers { @@ -233,12 +232,6 @@ fn invalid_custom_message_type() { fn write(&self, _w: &mut W) -> Result<(), io::Error> { unreachable!() } } - impl MaybeReadableArgs for InvalidCustomMessage { - fn read(_buffer: &mut R, _message_type: u64) -> Result, DecodeError> where Self: Sized { - unreachable!() - } - } - let test_msg = OnionMessageContents::Custom(InvalidCustomMessage {}); let err = nodes[0].messenger.send_onion_message(&[], Destination::Node(nodes[1].get_node_pk()), test_msg, None).unwrap_err(); assert_eq!(err, SendError::InvalidMessage); diff --git a/lightning/src/onion_message/messenger.rs b/lightning/src/onion_message/messenger.rs index ff20f19a..6284c47c 100644 --- a/lightning/src/onion_message/messenger.rs +++ b/lightning/src/onion_message/messenger.rs @@ -21,7 +21,7 @@ use crate::ln::msgs::{self, OnionMessageHandler}; use crate::ln::onion_utils; use crate::ln::peer_handler::IgnoringMessageHandler; use super::blinded_route::{BlindedRoute, ForwardTlvs, ReceiveTlvs}; -pub use super::packet::{CustomOnionMessageContents, OnionMessageContents}; +use super::packet::{CustomOnionMessageContents, OnionMessageContents}; use super::packet::{BIG_PACKET_HOP_DATA_LEN, ForwardControlTlvs, Packet, Payload, ReceiveControlTlvs, SMALL_PACKET_HOP_DATA_LEN}; use super::utils; use crate::util::events::OnionMessageProvider; @@ -29,6 +29,7 @@ use crate::util::logger::Logger; use crate::util::ser::Writeable; use core::ops::Deref; +use crate::io; use crate::sync::{Arc, Mutex}; use crate::prelude::*; @@ -45,9 +46,11 @@ use crate::prelude::*; /// # use lightning::chain::keysinterface::{InMemorySigner, KeysManager, KeysInterface}; /// # use lightning::ln::msgs::DecodeError; /// # use lightning::ln::peer_handler::IgnoringMessageHandler; -/// # use lightning::onion_message::{BlindedRoute, CustomOnionMessageContents, Destination, OnionMessageContents, OnionMessenger}; +/// # use lightning::onion_message::messenger::{Destination, OnionMessenger}; +/// # use lightning::onion_message::packet::CustomOnionMessageContents; +/// # use lightning::onion_message::blinded_route::BlindedRoute; /// # use lightning::util::logger::{Logger, Record}; -/// # use lightning::util::ser::{MaybeReadableArgs, Writeable, Writer}; +/// # use lightning::util::ser::{Writeable, Writer}; /// # use lightning::io; /// # use std::sync::Arc; /// # struct FakeLogger {}; @@ -81,19 +84,11 @@ use crate::prelude::*; /// your_custom_message_type /// } /// } -/// impl MaybeReadableArgs for YourCustomMessage { -/// fn read(r: &mut R, message_type: u64) -> Result, DecodeError> { -/// # unreachable!() -/// // Read your custom onion message of type `message_type` from `r`, or return `None` -/// // if the message type is unknown -/// } -/// } /// // Send a custom onion message to a node id. /// let intermediate_hops = [hop_node_id1, hop_node_id2]; /// let reply_path = None; /// # let your_custom_message = YourCustomMessage {}; -/// let message = OnionMessageContents::Custom(your_custom_message); -/// onion_messenger.send_onion_message(&intermediate_hops, Destination::Node(destination_node_id), message, reply_path); +/// onion_messenger.send_custom_onion_message(&intermediate_hops, Destination::Node(destination_node_id), your_custom_message, reply_path); /// /// // Create a blinded route to yourself, for someone to send an onion message to. /// # let your_node_id = hop_node_id1; @@ -104,8 +99,7 @@ use crate::prelude::*; /// # let intermediate_hops = [hop_node_id1, hop_node_id2]; /// let reply_path = None; /// # let your_custom_message = YourCustomMessage {}; -/// let message = OnionMessageContents::Custom(your_custom_message); -/// onion_messenger.send_onion_message(&intermediate_hops, Destination::BlindedRoute(blinded_route), message, reply_path); +/// onion_messenger.send_custom_onion_message(&intermediate_hops, Destination::BlindedRoute(blinded_route), your_custom_message, reply_path); /// ``` /// /// [offers]: @@ -143,7 +137,7 @@ impl Destination { /// Errors that may occur when [sending an onion message]. /// -/// [sending an onion message]: OnionMessenger::send_onion_message +/// [sending an onion message]: OnionMessenger::send_custom_onion_message #[derive(Debug, PartialEq, Eq)] pub enum SendError { /// Errored computing onion message packet keys. @@ -178,6 +172,9 @@ pub trait CustomOnionMessageHandler { type CustomMessage: CustomOnionMessageContents; /// Called with the custom message that was received. fn handle_custom_message(&self, msg: Self::CustomMessage); + /// Read a custom message of type `message_type` from `buffer`, returning `Ok(None)` if the + /// message type is unknown. + fn read_custom_message(&self, message_type: u64, buffer: &mut R) -> Result, msgs::DecodeError>; } impl OnionMessenger @@ -201,13 +198,19 @@ impl OnionMessenger(&self, intermediate_nodes: &[PublicKey], destination: Destination, message: OnionMessageContents, reply_path: Option) -> Result<(), SendError> { + pub(crate) fn send_onion_message(&self, intermediate_nodes: &[PublicKey], destination: Destination, msg: OnionMessageContents, reply_path: Option) -> Result<(), SendError> { + let OnionMessageContents::Custom(message) = msg; + self.send_custom_onion_message(intermediate_nodes, destination, message, reply_path) + } + + /// Send an onion message with contents `message` to `destination`, routing it through `intermediate_nodes`. + /// See [`OnionMessenger`] for example usage. + pub fn send_custom_onion_message(&self, intermediate_nodes: &[PublicKey], destination: Destination, msg: T, reply_path: Option) -> Result<(), SendError> { if let Destination::BlindedRoute(BlindedRoute { ref blinded_hops, .. }) = destination { if blinded_hops.len() < 2 { return Err(SendError::TooFewBlindedHops); } } - let OnionMessageContents::Custom(ref msg) = message; if msg.tlv_type() < 64 { return Err(SendError::InvalidMessage) } let blinding_secret_bytes = self.keys_manager.get_secure_random_bytes(); @@ -222,7 +225,7 @@ impl OnionMessenger OnionMessageHandler for OnionMessenger where K::Target: KeysInterface, L::Target: Logger, - CMH::Target: CustomOnionMessageHandler, + CMH::Target: CustomOnionMessageHandler + Sized, { /// Handle an incoming onion message. Currently, if a message was destined for us we will log, but /// soon we'll delegate the onion message to a handler that can generate invoices or send @@ -308,8 +311,8 @@ impl OnionMessageHandler for Onion } } }; - match onion_utils::decode_next_hop(onion_decode_ss, &msg.onion_routing_packet.hop_data[..], - msg.onion_routing_packet.hmac, control_tlvs_ss) + match onion_utils::decode_next_untagged_hop(onion_decode_ss, &msg.onion_routing_packet.hop_data[..], + msg.onion_routing_packet.hmac, (control_tlvs_ss, &*self.custom_handler)) { Ok((Payload::Receive::<<::Target as CustomOnionMessageHandler>::CustomMessage> { message, control_tlvs: ReceiveControlTlvs::Unblinded(ReceiveTlvs { path_id }), reply_path, diff --git a/lightning/src/onion_message/mod.rs b/lightning/src/onion_message/mod.rs index 3c522e30..1830d3ba 100644 --- a/lightning/src/onion_message/mod.rs +++ b/lightning/src/onion_message/mod.rs @@ -18,16 +18,12 @@ //! information on its usage. //! //! [offers]: -//! [blinded routes]: crate::onion_message::BlindedRoute +//! [blinded routes]: crate::onion_message::blinded_route::BlindedRoute +//! [`OnionMessenger`]: crate::onion_message::messenger::OnionMessenger -mod blinded_route; -mod messenger; -mod packet; +pub mod blinded_route; +pub mod messenger; +pub mod packet; mod utils; #[cfg(test)] mod functional_tests; - -// Re-export structs so they can be imported with just the `onion_message::` module prefix. -pub use self::blinded_route::{BlindedRoute, BlindedHop}; -pub use self::messenger::{CustomOnionMessageContents, CustomOnionMessageHandler, Destination, OnionMessageContents, OnionMessenger, SendError, SimpleArcOnionMessenger, SimpleRefOnionMessenger}; -pub(crate) use self::packet::Packet; diff --git a/lightning/src/onion_message/packet.rs b/lightning/src/onion_message/packet.rs index da8dd561..3bc42f50 100644 --- a/lightning/src/onion_message/packet.rs +++ b/lightning/src/onion_message/packet.rs @@ -15,8 +15,9 @@ use bitcoin::secp256k1::ecdh::SharedSecret; use crate::ln::msgs::DecodeError; use crate::ln::onion_utils; use super::blinded_route::{BlindedRoute, ForwardTlvs, ReceiveTlvs}; +use super::messenger::CustomOnionMessageHandler; use crate::util::chacha20poly1305rfc::{ChaChaPolyReadAdapter, ChaChaPolyWriteAdapter}; -use crate::util::ser::{BigSize, FixedLengthReader, LengthRead, LengthReadable, LengthReadableArgs, MaybeReadableArgs, Readable, ReadableArgs, Writeable, Writer}; +use crate::util::ser::{BigSize, FixedLengthReader, LengthRead, LengthReadable, LengthReadableArgs, Readable, ReadableArgs, Writeable, Writer}; use core::cmp; use crate::io::{self, Read}; @@ -106,7 +107,7 @@ pub(super) enum Payload { #[derive(Debug)] /// The contents of an onion message. In the context of offers, this would be the invoice, invoice /// request, or invoice error. -pub enum OnionMessageContents where T: CustomOnionMessageContents { +pub(crate) enum OnionMessageContents { // Coming soon: // Invoice, // InvoiceRequest, @@ -115,7 +116,7 @@ pub enum OnionMessageContents where T: CustomOnionMessageContents { Custom(T), } -impl OnionMessageContents where T: CustomOnionMessageContents { +impl OnionMessageContents { /// Returns the type that was used to decode the message payload. pub fn tlv_type(&self) -> u64 { match self { @@ -132,9 +133,8 @@ impl Writeable for OnionMessageContents { } } -/// The contents of a custom onion message. Must implement `MaybeReadableArgs` where the `u64` -/// is the custom TLV type attempting to be read, and return `Ok(None)` if the TLV type is unknown. -pub trait CustomOnionMessageContents: Writeable + MaybeReadableArgs { +/// The contents of a custom onion message. +pub trait CustomOnionMessageContents: Writeable { /// Returns the TLV type identifying the message contents. MUST be >= 64. fn tlv_type(&self) -> u64; } @@ -198,8 +198,10 @@ impl Writeable for (Payload, [u8; 32]) { } // Uses the provided secret to simultaneously decode and decrypt the control TLVs and data TLV. -impl ReadableArgs for Payload { - fn read(r: &mut R, encrypted_tlvs_ss: SharedSecret) -> Result { +impl ReadableArgs<(SharedSecret, &H)> for Payload<::CustomMessage> { + fn read(r: &mut R, args: (SharedSecret, &H)) -> Result { + let (encrypted_tlvs_ss, handler) = args; + let v: BigSize = Readable::read(r)?; let mut rd = FixedLengthReader::new(r, v.0); let mut reply_path: Option = None; @@ -216,7 +218,7 @@ impl ReadableArgs for Payload { if message_type.is_some() { return Err(DecodeError::InvalidValue) } message_type = Some(msg_type); - match T::read(msg_reader, msg_type) { + match handler.read_custom_message(msg_type, msg_reader) { Ok(Some(msg)) => { message = Some(msg); Ok(true) diff --git a/lightning/src/routing/gossip.rs b/lightning/src/routing/gossip.rs index 1706e069..975f1f9f 100644 --- a/lightning/src/routing/gossip.rs +++ b/lightning/src/routing/gossip.rs @@ -740,7 +740,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) @@ -755,7 +755,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 1c13771b..57e22d45 100644 --- a/lightning/src/routing/scoring.rs +++ b/lightning/src/routing/scoring.rs @@ -317,12 +317,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, @@ -359,7 +391,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 9e81a340..849854a6 100644 --- a/lightning/src/util/persist.rs +++ b/lightning/src/util/persist.rs @@ -20,6 +20,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/ser.rs b/lightning/src/util/ser.rs index 1bf30fa9..5ff6dc86 100644 --- a/lightning/src/util/ser.rs +++ b/lightning/src/util/ser.rs @@ -269,15 +269,6 @@ impl MaybeReadable for T { } } -/// A trait that various rust-lightning types implement allowing them to (maybe) be read in from a -/// Read, given some additional set of arguments which is required to deserialize. -/// -/// (C-not exported) as we only export serialization to/from byte arrays instead -pub trait MaybeReadableArgs

{ - /// Reads a Self in from the given Read - fn read(reader: &mut R, params: P) -> Result, DecodeError> where Self: Sized; -} - pub(crate) struct OptionDeserWrapper(pub Option); impl Readable for OptionDeserWrapper { #[inline]