Skip to content

0.0.112 Bindings Branch #1810

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

18 changes: 8 additions & 10 deletions fuzz/src/onion_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -67,19 +68,16 @@ impl Writeable for TestCustomMessage {
}
}

impl MaybeReadableArgs<u64> for TestCustomMessage {
fn read<R: io::Read>(buffer: &mut R, _message_type: u64,) -> Result<Option<Self>, 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<R: io::Read>(&self, _message_type: u64, buffer: &mut R) -> Result<Option<Self::CustomMessage>, msgs::DecodeError> {
let mut buf = Vec::new();
buffer.read_to_end(&mut buf)?;
return Ok(Some(TestCustomMessage {}))
}
}

pub struct VecWriter(pub Vec<u8>);
Expand Down
4 changes: 2 additions & 2 deletions lightning-rapid-gossip-sync/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion lightning/src/ln/chan_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions lightning/src/ln/msgs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 = <onion_message::Packet as LengthReadable>::read(&mut packet_reader)?;
let onion_routing_packet = <onion_message::packet::Packet as LengthReadable>::read(&mut packet_reader)?;
Ok(Self {
blinding_point,
onion_routing_packet,
Expand Down
39 changes: 9 additions & 30 deletions lightning/src/ln/onion_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -589,31 +589,6 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(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]> {
Expand Down Expand Up @@ -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<Hop, OnionDecodeErr> {
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 {
Expand All @@ -677,12 +652,16 @@ pub(crate) fn decode_next_payment_hop(shared_secret: [u8; 32], hop_data: &[u8],
}
}

pub(crate) fn decode_next_hop<D: DecodeInput, R: ReadableArgs<D::Arg>, 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<T, R: ReadableArgs<T>, 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<T, R: ReadableArgs<T>, N: NextPacketBytes>(shared_secret: [u8; 32], hop_data: &[u8], hmac_bytes: [u8; 32], payment_hash: Option<PaymentHash>, 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::<Sha256>::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 {
Expand All @@ -693,7 +672,7 @@ pub(crate) fn decode_next_hop<D: DecodeInput, R: ReadableArgs<D::Arg>, 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
Expand Down
11 changes: 5 additions & 6 deletions lightning/src/ln/peer_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<u64> for Infallible {
fn read<R: io::Read>(_buffer: &mut R, _msg_type: u64) -> Result<Option<Self>, msgs::DecodeError> where Self: Sized {
fn read_custom_message<R: io::Read>(&self, _msg_type: u64, _buffer: &mut R) -> Result<Option<Infallible>, msgs::DecodeError> where Self: Sized {
Ok(None)
}
}
Expand Down
27 changes: 10 additions & 17 deletions lightning/src/onion_message/functional_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -54,8 +56,12 @@ impl Writeable for TestCustomMessage {
}
}

impl MaybeReadableArgs<u64> for TestCustomMessage {
fn read<R: io::Read>(buffer: &mut R, message_type: u64) -> Result<Option<Self>, 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<R: io::Read>(&self, message_type: u64, buffer: &mut R) -> Result<Option<Self::CustomMessage>, DecodeError> where Self: Sized {
if message_type == CUSTOM_MESSAGE_TYPE {
let mut buf = Vec::new();
buffer.read_to_end(&mut buf)?;
Expand All @@ -66,13 +72,6 @@ impl MaybeReadableArgs<u64> 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<MessengerNode> {
let mut nodes = Vec::new();
for i in 0..num_messengers {
Expand Down Expand Up @@ -233,12 +232,6 @@ fn invalid_custom_message_type() {
fn write<W: Writer>(&self, _w: &mut W) -> Result<(), io::Error> { unreachable!() }
}

impl MaybeReadableArgs<u64> for InvalidCustomMessage {
fn read<R: io::Read>(_buffer: &mut R, _message_type: u64) -> Result<Option<Self>, 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);
Expand Down
45 changes: 24 additions & 21 deletions lightning/src/onion_message/messenger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@ 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;
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::*;

Expand All @@ -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 {};
Expand Down Expand Up @@ -81,19 +84,11 @@ use crate::prelude::*;
/// your_custom_message_type
/// }
/// }
/// impl MaybeReadableArgs<u64> for YourCustomMessage {
/// fn read<R: io::Read>(r: &mut R, message_type: u64) -> Result<Option<Self>, 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;
Expand All @@ -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]: <https://github.com/lightning/bolts/pull/798>
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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<R: io::Read>(&self, message_type: u64, buffer: &mut R) -> Result<Option<Self::CustomMessage>, msgs::DecodeError>;
}

impl<Signer: Sign, K: Deref, L: Deref, CMH: Deref> OnionMessenger<Signer, K, L, CMH>
Expand All @@ -201,13 +198,19 @@ impl<Signer: Sign, K: Deref, L: Deref, CMH: Deref> OnionMessenger<Signer, K, L,

/// Send an onion message with contents `message` to `destination`, routing it through `intermediate_nodes`.
/// See [`OnionMessenger`] for example usage.
pub fn send_onion_message<T: CustomOnionMessageContents>(&self, intermediate_nodes: &[PublicKey], destination: Destination, message: OnionMessageContents<T>, reply_path: Option<BlindedRoute>) -> Result<(), SendError> {
pub(crate) fn send_onion_message<T: CustomOnionMessageContents>(&self, intermediate_nodes: &[PublicKey], destination: Destination, msg: OnionMessageContents<T>, reply_path: Option<BlindedRoute>) -> 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<T: CustomOnionMessageContents>(&self, intermediate_nodes: &[PublicKey], destination: Destination, msg: T, reply_path: Option<BlindedRoute>) -> 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();
Expand All @@ -222,7 +225,7 @@ impl<Signer: Sign, K: Deref, L: Deref, CMH: Deref> OnionMessenger<Signer, K, L,
}
};
let (packet_payloads, packet_keys) = packet_payloads_and_keys(
&self.secp_ctx, intermediate_nodes, destination, message, reply_path, &blinding_secret)
&self.secp_ctx, intermediate_nodes, destination, OnionMessageContents::Custom(msg), reply_path, &blinding_secret)
.map_err(|e| SendError::Secp256k1(e))?;

let prng_seed = self.keys_manager.get_secure_random_bytes();
Expand Down Expand Up @@ -279,7 +282,7 @@ fn outbound_buffer_full(peer_node_id: &PublicKey, buffer: &HashMap<PublicKey, Ve
impl<Signer: Sign, K: Deref, L: Deref, CMH: Deref> OnionMessageHandler for OnionMessenger<Signer, K, L, CMH>
where K::Target: KeysInterface<Signer = Signer>,
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
Expand Down Expand Up @@ -308,8 +311,8 @@ impl<Signer: Sign, K: Deref, L: Deref, CMH: Deref> 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::<<<CMH as Deref>::Target as CustomOnionMessageHandler>::CustomMessage> {
message, control_tlvs: ReceiveControlTlvs::Unblinded(ReceiveTlvs { path_id }), reply_path,
Expand Down
14 changes: 5 additions & 9 deletions lightning/src/onion_message/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,12 @@
//! information on its usage.
//!
//! [offers]: <https://github.com/lightning/bolts/pull/798>
//! [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;
Loading