mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-03-09 21:23:34 +01:00
Generalize CustomOnionMessageContents trait
Rename CustomOnionMessageContents to OnionMessageContents and use it as a trait bound on messages passed to OnionMessenger methods. This allows using the trait in an upcoming commit as a bound on the contents of PendingOnionMessage. Also, make ParsedOnionMessageContent implement OnionMessageContents so that Payload can be bounded by OnionMessageContents directly, but used when either reading a ParsedOnionMessageContent or writing a specific type of OnionMessageContents (e.g., OffersMessage).
This commit is contained in:
parent
94573dda33
commit
840efd5334
7 changed files with 104 additions and 94 deletions
|
@ -14,7 +14,7 @@ use lightning::offers::invoice_request::UnsignedInvoiceRequest;
|
|||
use lightning::util::test_channel_signer::TestChannelSigner;
|
||||
use lightning::util::logger::Logger;
|
||||
use lightning::util::ser::{Readable, Writeable, Writer};
|
||||
use lightning::onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, Destination, MessageRouter, OffersMessage, OffersMessageHandler, OnionMessagePath, OnionMessenger};
|
||||
use lightning::onion_message::{CustomOnionMessageHandler, Destination, MessageRouter, OffersMessage, OffersMessageHandler, OnionMessageContents, OnionMessagePath, OnionMessenger};
|
||||
|
||||
use crate::utils::test_logger;
|
||||
|
||||
|
@ -84,7 +84,7 @@ struct TestCustomMessage {}
|
|||
const CUSTOM_MESSAGE_TYPE: u64 = 4242;
|
||||
const CUSTOM_MESSAGE_CONTENTS: [u8; 32] = [42; 32];
|
||||
|
||||
impl CustomOnionMessageContents for TestCustomMessage {
|
||||
impl OnionMessageContents for TestCustomMessage {
|
||||
fn tlv_type(&self) -> u64 {
|
||||
CUSTOM_MESSAGE_TYPE
|
||||
}
|
||||
|
@ -216,9 +216,9 @@ mod tests {
|
|||
assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(),
|
||||
"Received an onion message with path_id None and a reply_path".to_string())), Some(&1));
|
||||
assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(),
|
||||
"Sending onion message when responding to onion message with path_id None".to_string())), Some(&1));
|
||||
"Sending onion message when responding to Custom onion message with path_id None".to_string())), Some(&1));
|
||||
assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(),
|
||||
"Failed sending onion message when responding to onion message with path_id None: TooFewBlindedHops".to_string())), Some(&1));
|
||||
"Failed sending onion message when responding to Custom onion message with path_id None: TooFewBlindedHops".to_string())), Some(&1));
|
||||
}
|
||||
|
||||
let two_unblinded_hops_om = "020000000000000000000000000000000000000000000000000000000000000e01055600020000000000000000000000000000000000000000000000000000000000000e0135043304210202020202020202020202020202020202020202020202020202020202020202026d000000000000000000000000000000eb0000000000000000000000000000000000000000000000000000000000000036041096000000000000000000000000000000fd1092202a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000";
|
||||
|
|
|
@ -29,7 +29,7 @@ use crate::util::ser::{VecWriter, Writeable, Writer};
|
|||
use crate::ln::peer_channel_encryptor::{PeerChannelEncryptor,NextNoiseStep};
|
||||
use crate::ln::wire;
|
||||
use crate::ln::wire::{Encode, Type};
|
||||
use crate::onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, OffersMessage, OffersMessageHandler, SimpleArcOnionMessenger, SimpleRefOnionMessenger};
|
||||
use crate::onion_message::{CustomOnionMessageHandler, OffersMessage, OffersMessageHandler, OnionMessageContents, SimpleArcOnionMessenger, SimpleRefOnionMessenger};
|
||||
use crate::routing::gossip::{NetworkGraph, P2PGossipSync, NodeId, NodeAlias};
|
||||
use crate::util::atomic_counter::AtomicCounter;
|
||||
use crate::util::logger::Logger;
|
||||
|
@ -131,7 +131,7 @@ impl CustomOnionMessageHandler for IgnoringMessageHandler {
|
|||
}
|
||||
}
|
||||
|
||||
impl CustomOnionMessageContents for Infallible {
|
||||
impl OnionMessageContents for Infallible {
|
||||
fn tlv_type(&self) -> u64 { unreachable!(); }
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ use crate::ln::msgs::{self, DecodeError, OnionMessageHandler};
|
|||
use crate::sign::{NodeSigner, Recipient};
|
||||
use crate::util::ser::{FixedLengthReader, LengthReadable, Writeable, Writer};
|
||||
use crate::util::test_utils;
|
||||
use super::{CustomOnionMessageContents, CustomOnionMessageHandler, Destination, MessageRouter, OffersMessage, OffersMessageHandler, ParsedOnionMessageContents, OnionMessagePath, OnionMessenger, SendError};
|
||||
use super::{CustomOnionMessageHandler, Destination, MessageRouter, OffersMessage, OffersMessageHandler, OnionMessageContents, OnionMessagePath, OnionMessenger, SendError};
|
||||
|
||||
use bitcoin::network::constants::Network;
|
||||
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
|
||||
|
@ -77,7 +77,7 @@ const CUSTOM_RESPONSE_MESSAGE_TYPE: u64 = 4343;
|
|||
const CUSTOM_REQUEST_MESSAGE_CONTENTS: [u8; 32] = [42; 32];
|
||||
const CUSTOM_RESPONSE_MESSAGE_CONTENTS: [u8; 32] = [43; 32];
|
||||
|
||||
impl CustomOnionMessageContents for TestCustomMessage {
|
||||
impl OnionMessageContents for TestCustomMessage {
|
||||
fn tlv_type(&self) -> u64 {
|
||||
match self {
|
||||
TestCustomMessage::Request => CUSTOM_REQUEST_MESSAGE_TYPE,
|
||||
|
@ -196,7 +196,7 @@ fn pass_along_path(path: &Vec<MessengerNode>) {
|
|||
#[test]
|
||||
fn one_hop() {
|
||||
let nodes = create_nodes(2);
|
||||
let test_msg = ParsedOnionMessageContents::Custom(TestCustomMessage::Response);
|
||||
let test_msg = TestCustomMessage::Response;
|
||||
|
||||
let path = OnionMessagePath {
|
||||
intermediate_nodes: vec![],
|
||||
|
@ -210,7 +210,7 @@ fn one_hop() {
|
|||
#[test]
|
||||
fn two_unblinded_hops() {
|
||||
let nodes = create_nodes(3);
|
||||
let test_msg = ParsedOnionMessageContents::Custom(TestCustomMessage::Response);
|
||||
let test_msg = TestCustomMessage::Response;
|
||||
|
||||
let path = OnionMessagePath {
|
||||
intermediate_nodes: vec![nodes[1].get_node_pk()],
|
||||
|
@ -224,7 +224,7 @@ fn two_unblinded_hops() {
|
|||
#[test]
|
||||
fn two_unblinded_two_blinded() {
|
||||
let nodes = create_nodes(5);
|
||||
let test_msg = ParsedOnionMessageContents::Custom(TestCustomMessage::Response);
|
||||
let test_msg = TestCustomMessage::Response;
|
||||
|
||||
let secp_ctx = Secp256k1::new();
|
||||
let blinded_path = BlindedPath::new_for_message(&[nodes[3].get_node_pk(), nodes[4].get_node_pk()], &*nodes[4].keys_manager, &secp_ctx).unwrap();
|
||||
|
@ -241,7 +241,7 @@ fn two_unblinded_two_blinded() {
|
|||
#[test]
|
||||
fn three_blinded_hops() {
|
||||
let nodes = create_nodes(4);
|
||||
let test_msg = ParsedOnionMessageContents::Custom(TestCustomMessage::Response);
|
||||
let test_msg = TestCustomMessage::Response;
|
||||
|
||||
let secp_ctx = Secp256k1::new();
|
||||
let blinded_path = BlindedPath::new_for_message(&[nodes[1].get_node_pk(), nodes[2].get_node_pk(), nodes[3].get_node_pk()], &*nodes[3].keys_manager, &secp_ctx).unwrap();
|
||||
|
@ -259,7 +259,7 @@ fn three_blinded_hops() {
|
|||
fn too_big_packet_error() {
|
||||
// Make sure we error as expected if a packet is too big to send.
|
||||
let nodes = create_nodes(2);
|
||||
let test_msg = ParsedOnionMessageContents::Custom(TestCustomMessage::Response);
|
||||
let test_msg = TestCustomMessage::Response;
|
||||
|
||||
let hop_node_id = nodes[1].get_node_pk();
|
||||
let hops = vec![hop_node_id; 400];
|
||||
|
@ -285,7 +285,7 @@ fn we_are_intro_node() {
|
|||
destination: Destination::BlindedPath(blinded_path),
|
||||
};
|
||||
|
||||
nodes[0].messenger.send_onion_message(path, ParsedOnionMessageContents::Custom(test_msg.clone()), None).unwrap();
|
||||
nodes[0].messenger.send_onion_message(path, test_msg.clone(), None).unwrap();
|
||||
nodes[2].custom_message_handler.expect_message(TestCustomMessage::Response);
|
||||
pass_along_path(&nodes);
|
||||
|
||||
|
@ -295,7 +295,7 @@ fn we_are_intro_node() {
|
|||
intermediate_nodes: vec![],
|
||||
destination: Destination::BlindedPath(blinded_path),
|
||||
};
|
||||
nodes[0].messenger.send_onion_message(path, ParsedOnionMessageContents::Custom(test_msg), None).unwrap();
|
||||
nodes[0].messenger.send_onion_message(path, test_msg, None).unwrap();
|
||||
nodes[1].custom_message_handler.expect_message(TestCustomMessage::Response);
|
||||
nodes.remove(2);
|
||||
pass_along_path(&nodes);
|
||||
|
@ -315,7 +315,7 @@ fn invalid_blinded_path_error() {
|
|||
intermediate_nodes: vec![],
|
||||
destination: Destination::BlindedPath(blinded_path),
|
||||
};
|
||||
let err = nodes[0].messenger.send_onion_message(path, ParsedOnionMessageContents::Custom(test_msg.clone()), None).unwrap_err();
|
||||
let err = nodes[0].messenger.send_onion_message(path, test_msg.clone(), None).unwrap_err();
|
||||
assert_eq!(err, SendError::TooFewBlindedHops);
|
||||
|
||||
// 1 hop
|
||||
|
@ -326,7 +326,7 @@ fn invalid_blinded_path_error() {
|
|||
intermediate_nodes: vec![],
|
||||
destination: Destination::BlindedPath(blinded_path),
|
||||
};
|
||||
let err = nodes[0].messenger.send_onion_message(path, ParsedOnionMessageContents::Custom(test_msg), None).unwrap_err();
|
||||
let err = nodes[0].messenger.send_onion_message(path, test_msg, None).unwrap_err();
|
||||
assert_eq!(err, SendError::TooFewBlindedHops);
|
||||
}
|
||||
|
||||
|
@ -342,7 +342,7 @@ fn reply_path() {
|
|||
destination: Destination::Node(nodes[3].get_node_pk()),
|
||||
};
|
||||
let reply_path = BlindedPath::new_for_message(&[nodes[2].get_node_pk(), nodes[1].get_node_pk(), nodes[0].get_node_pk()], &*nodes[0].keys_manager, &secp_ctx).unwrap();
|
||||
nodes[0].messenger.send_onion_message(path, ParsedOnionMessageContents::Custom(test_msg.clone()), Some(reply_path)).unwrap();
|
||||
nodes[0].messenger.send_onion_message(path, test_msg.clone(), Some(reply_path)).unwrap();
|
||||
nodes[3].custom_message_handler.expect_message(TestCustomMessage::Request);
|
||||
pass_along_path(&nodes);
|
||||
// Make sure the last node successfully decoded the reply path.
|
||||
|
@ -358,7 +358,7 @@ fn reply_path() {
|
|||
};
|
||||
let reply_path = BlindedPath::new_for_message(&[nodes[2].get_node_pk(), nodes[1].get_node_pk(), nodes[0].get_node_pk()], &*nodes[0].keys_manager, &secp_ctx).unwrap();
|
||||
|
||||
nodes[0].messenger.send_onion_message(path, ParsedOnionMessageContents::Custom(test_msg), Some(reply_path)).unwrap();
|
||||
nodes[0].messenger.send_onion_message(path, test_msg, Some(reply_path)).unwrap();
|
||||
nodes[3].custom_message_handler.expect_message(TestCustomMessage::Request);
|
||||
pass_along_path(&nodes);
|
||||
|
||||
|
@ -373,7 +373,7 @@ fn invalid_custom_message_type() {
|
|||
let nodes = create_nodes(2);
|
||||
|
||||
struct InvalidCustomMessage{}
|
||||
impl CustomOnionMessageContents for InvalidCustomMessage {
|
||||
impl OnionMessageContents for InvalidCustomMessage {
|
||||
fn tlv_type(&self) -> u64 {
|
||||
// Onion message contents must have a TLV >= 64.
|
||||
63
|
||||
|
@ -384,7 +384,7 @@ fn invalid_custom_message_type() {
|
|||
fn write<W: Writer>(&self, _w: &mut W) -> Result<(), io::Error> { unreachable!() }
|
||||
}
|
||||
|
||||
let test_msg = ParsedOnionMessageContents::Custom(InvalidCustomMessage {});
|
||||
let test_msg = InvalidCustomMessage {};
|
||||
let path = OnionMessagePath {
|
||||
intermediate_nodes: vec![],
|
||||
destination: Destination::Node(nodes[1].get_node_pk()),
|
||||
|
@ -402,9 +402,9 @@ fn peer_buffer_full() {
|
|||
destination: Destination::Node(nodes[1].get_node_pk()),
|
||||
};
|
||||
for _ in 0..188 { // Based on MAX_PER_PEER_BUFFER_SIZE in OnionMessenger
|
||||
nodes[0].messenger.send_onion_message(path.clone(), ParsedOnionMessageContents::Custom(test_msg.clone()), None).unwrap();
|
||||
nodes[0].messenger.send_onion_message(path.clone(), test_msg.clone(), None).unwrap();
|
||||
}
|
||||
let err = nodes[0].messenger.send_onion_message(path, ParsedOnionMessageContents::Custom(test_msg), None).unwrap_err();
|
||||
let err = nodes[0].messenger.send_onion_message(path, test_msg, None).unwrap_err();
|
||||
assert_eq!(err, SendError::BufferFull);
|
||||
}
|
||||
|
||||
|
@ -425,7 +425,7 @@ fn many_hops() {
|
|||
intermediate_nodes,
|
||||
destination: Destination::Node(nodes[num_nodes-1].get_node_pk()),
|
||||
};
|
||||
nodes[0].messenger.send_onion_message(path, ParsedOnionMessageContents::Custom(test_msg), None).unwrap();
|
||||
nodes[0].messenger.send_onion_message(path, test_msg, None).unwrap();
|
||||
nodes[num_nodes-1].custom_message_handler.expect_message(TestCustomMessage::Response);
|
||||
pass_along_path(&nodes);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,8 @@ use crate::ln::features::{InitFeatures, NodeFeatures};
|
|||
use crate::ln::msgs::{self, OnionMessage, OnionMessageHandler};
|
||||
use crate::ln::onion_utils;
|
||||
use crate::ln::peer_handler::IgnoringMessageHandler;
|
||||
pub use super::packet::{CustomOnionMessageContents, ParsedOnionMessageContents};
|
||||
pub use super::packet::OnionMessageContents;
|
||||
use super::packet::ParsedOnionMessageContents;
|
||||
use super::offers::OffersMessageHandler;
|
||||
use super::packet::{BIG_PACKET_HOP_DATA_LEN, ForwardControlTlvs, Packet, Payload, ReceiveControlTlvs, SMALL_PACKET_HOP_DATA_LEN};
|
||||
use crate::util::logger::Logger;
|
||||
|
@ -60,7 +61,7 @@ use crate::prelude::*;
|
|||
/// # use lightning::blinded_path::BlindedPath;
|
||||
/// # use lightning::sign::KeysManager;
|
||||
/// # use lightning::ln::peer_handler::IgnoringMessageHandler;
|
||||
/// # use lightning::onion_message::{CustomOnionMessageContents, Destination, MessageRouter, ParsedOnionMessageContents, OnionMessagePath, OnionMessenger};
|
||||
/// # use lightning::onion_message::{OnionMessageContents, Destination, MessageRouter, OnionMessagePath, OnionMessenger};
|
||||
/// # use lightning::util::logger::{Logger, Record};
|
||||
/// # use lightning::util::ser::{Writeable, Writer};
|
||||
/// # use lightning::io;
|
||||
|
@ -101,7 +102,7 @@ use crate::prelude::*;
|
|||
/// // Write your custom onion message to `w`
|
||||
/// }
|
||||
/// }
|
||||
/// impl CustomOnionMessageContents for YourCustomMessage {
|
||||
/// impl OnionMessageContents for YourCustomMessage {
|
||||
/// fn tlv_type(&self) -> u64 {
|
||||
/// # let your_custom_message_type = 42;
|
||||
/// your_custom_message_type
|
||||
|
@ -113,8 +114,7 @@ use crate::prelude::*;
|
|||
/// destination: Destination::Node(destination_node_id),
|
||||
/// };
|
||||
/// let reply_path = None;
|
||||
/// # let your_custom_message = YourCustomMessage {};
|
||||
/// let message = ParsedOnionMessageContents::Custom(your_custom_message);
|
||||
/// # let message = YourCustomMessage {};
|
||||
/// onion_messenger.send_onion_message(path, message, reply_path);
|
||||
///
|
||||
/// // Create a blinded path to yourself, for someone to send an onion message to.
|
||||
|
@ -128,8 +128,7 @@ use crate::prelude::*;
|
|||
/// destination: Destination::BlindedPath(blinded_path),
|
||||
/// };
|
||||
/// let reply_path = None;
|
||||
/// # let your_custom_message = YourCustomMessage {};
|
||||
/// let message = ParsedOnionMessageContents::Custom(your_custom_message);
|
||||
/// # let message = YourCustomMessage {};
|
||||
/// onion_messenger.send_onion_message(path, message, reply_path);
|
||||
/// ```
|
||||
///
|
||||
|
@ -244,7 +243,7 @@ pub enum SendError {
|
|||
pub trait CustomOnionMessageHandler {
|
||||
/// The message known to the handler. To support multiple message types, you may want to make this
|
||||
/// an enum with a variant for each supported message.
|
||||
type CustomMessage: CustomOnionMessageContents;
|
||||
type CustomMessage: OnionMessageContents;
|
||||
|
||||
/// Called with the custom message that was received, returning a response to send, if any.
|
||||
fn handle_custom_message(&self, msg: Self::CustomMessage) -> Option<Self::CustomMessage>;
|
||||
|
@ -256,21 +255,20 @@ pub trait CustomOnionMessageHandler {
|
|||
|
||||
/// A processed incoming onion message, containing either a Forward (another onion message)
|
||||
/// or a Receive payload with decrypted contents.
|
||||
pub enum PeeledOnion<CM: CustomOnionMessageContents> {
|
||||
pub enum PeeledOnion<T: OnionMessageContents> {
|
||||
/// Forwarded onion, with the next node id and a new onion
|
||||
Forward(PublicKey, OnionMessage),
|
||||
/// Received onion message, with decrypted contents, path_id, and reply path
|
||||
Receive(ParsedOnionMessageContents<CM>, Option<[u8; 32]>, Option<BlindedPath>)
|
||||
Receive(ParsedOnionMessageContents<T>, Option<[u8; 32]>, Option<BlindedPath>)
|
||||
}
|
||||
|
||||
/// Creates an [`OnionMessage`] with the given `contents` for sending to the destination of
|
||||
/// `path`.
|
||||
///
|
||||
/// Returns both the node id of the peer to send the message to and the message itself.
|
||||
pub fn create_onion_message<ES: Deref, NS: Deref, T: CustomOnionMessageContents>(
|
||||
pub fn create_onion_message<ES: Deref, NS: Deref, T: OnionMessageContents>(
|
||||
entropy_source: &ES, node_signer: &NS, secp_ctx: &Secp256k1<secp256k1::All>,
|
||||
path: OnionMessagePath, contents: ParsedOnionMessageContents<T>,
|
||||
reply_path: Option<BlindedPath>,
|
||||
path: OnionMessagePath, contents: T, reply_path: Option<BlindedPath>,
|
||||
) -> Result<(PublicKey, OnionMessage), SendError>
|
||||
where
|
||||
ES::Target: EntropySource,
|
||||
|
@ -361,7 +359,7 @@ where
|
|||
onion_decode_ss, &msg.onion_routing_packet.hop_data[..], msg.onion_routing_packet.hmac,
|
||||
(control_tlvs_ss, custom_handler.deref(), logger.deref())
|
||||
) {
|
||||
Ok((Payload::Receive::<<<CMH as Deref>::Target as CustomOnionMessageHandler>::CustomMessage> {
|
||||
Ok((Payload::Receive::<ParsedOnionMessageContents<<<CMH as Deref>::Target as CustomOnionMessageHandler>::CustomMessage>> {
|
||||
message, control_tlvs: ReceiveControlTlvs::Unblinded(ReceiveTlvs { path_id }), reply_path,
|
||||
}, None)) => {
|
||||
Ok(PeeledOnion::Receive(message, path_id, reply_path))
|
||||
|
@ -452,9 +450,8 @@ where
|
|||
/// `path`.
|
||||
///
|
||||
/// See [`OnionMessenger`] for example usage.
|
||||
pub fn send_onion_message<T: CustomOnionMessageContents>(
|
||||
&self, path: OnionMessagePath, contents: ParsedOnionMessageContents<T>,
|
||||
reply_path: Option<BlindedPath>
|
||||
pub fn send_onion_message<T: OnionMessageContents>(
|
||||
&self, path: OnionMessagePath, contents: T, reply_path: Option<BlindedPath>
|
||||
) -> Result<(), SendError> {
|
||||
let (first_node_id, onion_msg) = create_onion_message(
|
||||
&self.entropy_source, &self.node_signer, &self.secp_ctx, path, contents, reply_path
|
||||
|
@ -471,9 +468,25 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
fn find_path_and_enqueue_onion_message<T: CustomOnionMessageContents>(
|
||||
&self, contents: ParsedOnionMessageContents<T>, destination: Destination,
|
||||
log_suffix: fmt::Arguments
|
||||
fn handle_onion_message_response<T: OnionMessageContents>(
|
||||
&self, response: Option<T>, reply_path: Option<BlindedPath>, log_suffix: fmt::Arguments
|
||||
) {
|
||||
if let Some(response) = response {
|
||||
match reply_path {
|
||||
Some(reply_path) => {
|
||||
self.find_path_and_enqueue_onion_message(
|
||||
response, Destination::BlindedPath(reply_path), log_suffix
|
||||
);
|
||||
},
|
||||
None => {
|
||||
log_trace!(self.logger, "Missing reply path {}", log_suffix);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn find_path_and_enqueue_onion_message<T: OnionMessageContents>(
|
||||
&self, contents: T, destination: Destination, log_suffix: fmt::Arguments
|
||||
) {
|
||||
let sender = match self.node_signer.get_node_id(Recipient::Node) {
|
||||
Ok(node_id) => node_id,
|
||||
|
@ -557,33 +570,26 @@ where
|
|||
log_trace!(self.logger,
|
||||
"Received an onion message with path_id {:02x?} and {} reply_path",
|
||||
path_id, if reply_path.is_some() { "a" } else { "no" });
|
||||
let response = match message {
|
||||
|
||||
match message {
|
||||
ParsedOnionMessageContents::Offers(msg) => {
|
||||
self.offers_handler.handle_message(msg)
|
||||
.map(|msg| ParsedOnionMessageContents::Offers(msg))
|
||||
let response = self.offers_handler.handle_message(msg);
|
||||
self.handle_onion_message_response(
|
||||
response, reply_path, format_args!(
|
||||
"when responding to Offers onion message with path_id {:02x?}",
|
||||
path_id
|
||||
)
|
||||
);
|
||||
},
|
||||
ParsedOnionMessageContents::Custom(msg) => {
|
||||
self.custom_handler.handle_custom_message(msg)
|
||||
.map(|msg| ParsedOnionMessageContents::Custom(msg))
|
||||
},
|
||||
};
|
||||
if let Some(response) = response {
|
||||
match reply_path {
|
||||
Some(reply_path) => {
|
||||
self.find_path_and_enqueue_onion_message(
|
||||
response, Destination::BlindedPath(reply_path), format_args!(
|
||||
"when responding to onion message with path_id {:02x?}", path_id
|
||||
)
|
||||
);
|
||||
},
|
||||
None => {
|
||||
log_trace!(
|
||||
self.logger,
|
||||
"Missing reply path when responding to onion message with path_id {:02x?}",
|
||||
let response = self.custom_handler.handle_custom_message(msg);
|
||||
self.handle_onion_message_response(
|
||||
response, reply_path, format_args!(
|
||||
"when responding to Custom onion message with path_id {:02x?}",
|
||||
path_id
|
||||
);
|
||||
},
|
||||
}
|
||||
)
|
||||
);
|
||||
},
|
||||
}
|
||||
},
|
||||
Ok(PeeledOnion::Forward(next_node_id, onion_message)) => {
|
||||
|
@ -683,9 +689,9 @@ pub type SimpleRefOnionMessenger<'a, 'b, 'c, L> = OnionMessenger<
|
|||
|
||||
/// Construct onion packet payloads and keys for sending an onion message along the given
|
||||
/// `unblinded_path` to the given `destination`.
|
||||
fn packet_payloads_and_keys<T: CustomOnionMessageContents, S: secp256k1::Signing + secp256k1::Verification>(
|
||||
secp_ctx: &Secp256k1<S>, unblinded_path: &[PublicKey], destination: Destination,
|
||||
message: ParsedOnionMessageContents<T>, mut reply_path: Option<BlindedPath>, session_priv: &SecretKey
|
||||
fn packet_payloads_and_keys<T: OnionMessageContents, S: secp256k1::Signing + secp256k1::Verification>(
|
||||
secp_ctx: &Secp256k1<S>, unblinded_path: &[PublicKey], destination: Destination, message: T,
|
||||
mut reply_path: Option<BlindedPath>, session_priv: &SecretKey
|
||||
) -> Result<(Vec<(Payload<T>, [u8; 32])>, Vec<onion_utils::OnionKeys>), secp256k1::Error> {
|
||||
let num_hops = unblinded_path.len() + destination.num_hops();
|
||||
let mut payloads = Vec::with_capacity(num_hops);
|
||||
|
@ -761,7 +767,7 @@ fn packet_payloads_and_keys<T: CustomOnionMessageContents, S: secp256k1::Signing
|
|||
}
|
||||
|
||||
/// Errors if the serialized payload size exceeds onion_message::BIG_PACKET_HOP_DATA_LEN
|
||||
fn construct_onion_message_packet<T: CustomOnionMessageContents>(payloads: Vec<(Payload<T>, [u8; 32])>, onion_keys: Vec<onion_utils::OnionKeys>, prng_seed: [u8; 32]) -> Result<Packet, ()> {
|
||||
fn construct_onion_message_packet<T: OnionMessageContents>(payloads: Vec<(Payload<T>, [u8; 32])>, onion_keys: Vec<onion_utils::OnionKeys>, prng_seed: [u8; 32]) -> Result<Packet, ()> {
|
||||
// Spec rationale:
|
||||
// "`len` allows larger messages to be sent than the standard 1300 bytes allowed for an HTLC
|
||||
// onion, but this should be used sparingly as it is reduces anonymity set, hence the
|
||||
|
|
|
@ -27,7 +27,7 @@ mod packet;
|
|||
mod functional_tests;
|
||||
|
||||
// Re-export structs so they can be imported with just the `onion_message::` module prefix.
|
||||
pub use self::messenger::{CustomOnionMessageContents, CustomOnionMessageHandler, DefaultMessageRouter, Destination, MessageRouter, ParsedOnionMessageContents, OnionMessagePath, OnionMessenger, PeeledOnion, SendError, SimpleArcOnionMessenger, SimpleRefOnionMessenger};
|
||||
pub use self::messenger::{CustomOnionMessageHandler, DefaultMessageRouter, Destination, MessageRouter, OnionMessageContents, OnionMessagePath, OnionMessenger, PeeledOnion, SendError, SimpleArcOnionMessenger, SimpleRefOnionMessenger};
|
||||
pub use self::offers::{OffersMessage, OffersMessageHandler};
|
||||
pub use self::packet::Packet;
|
||||
pub use self::packet::{Packet, ParsedOnionMessageContents};
|
||||
pub(crate) use self::packet::ControlTlvs;
|
||||
|
|
|
@ -16,6 +16,7 @@ use crate::offers::invoice_error::InvoiceError;
|
|||
use crate::offers::invoice_request::InvoiceRequest;
|
||||
use crate::offers::invoice::Bolt12Invoice;
|
||||
use crate::offers::parse::Bolt12ParseError;
|
||||
use crate::onion_message::OnionMessageContents;
|
||||
use crate::util::logger::Logger;
|
||||
use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer};
|
||||
|
||||
|
@ -63,15 +64,6 @@ impl OffersMessage {
|
|||
}
|
||||
}
|
||||
|
||||
/// The TLV record type for the message as used in an `onionmsg_tlv` TLV stream.
|
||||
pub fn tlv_type(&self) -> u64 {
|
||||
match self {
|
||||
OffersMessage::InvoiceRequest(_) => INVOICE_REQUEST_TLV_TYPE,
|
||||
OffersMessage::Invoice(_) => INVOICE_TLV_TYPE,
|
||||
OffersMessage::InvoiceError(_) => INVOICE_ERROR_TLV_TYPE,
|
||||
}
|
||||
}
|
||||
|
||||
fn parse(tlv_type: u64, bytes: Vec<u8>) -> Result<Self, Bolt12ParseError> {
|
||||
match tlv_type {
|
||||
INVOICE_REQUEST_TLV_TYPE => Ok(Self::InvoiceRequest(InvoiceRequest::try_from(bytes)?)),
|
||||
|
@ -81,6 +73,16 @@ impl OffersMessage {
|
|||
}
|
||||
}
|
||||
|
||||
impl OnionMessageContents for OffersMessage {
|
||||
fn tlv_type(&self) -> u64 {
|
||||
match self {
|
||||
OffersMessage::InvoiceRequest(_) => INVOICE_REQUEST_TLV_TYPE,
|
||||
OffersMessage::Invoice(_) => INVOICE_TLV_TYPE,
|
||||
OffersMessage::InvoiceError(_) => INVOICE_ERROR_TLV_TYPE,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Writeable for OffersMessage {
|
||||
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
|
||||
match self {
|
||||
|
|
|
@ -103,31 +103,33 @@ impl LengthReadable for Packet {
|
|||
/// Onion message payloads contain "control" TLVs and "data" TLVs. Control TLVs are used to route
|
||||
/// the onion message from hop to hop and for path verification, whereas data TLVs contain the onion
|
||||
/// message content itself, such as an invoice request.
|
||||
pub(super) enum Payload<T: CustomOnionMessageContents> {
|
||||
pub(super) enum Payload<T: OnionMessageContents> {
|
||||
/// This payload is for an intermediate hop.
|
||||
Forward(ForwardControlTlvs),
|
||||
/// This payload is for the final hop.
|
||||
Receive {
|
||||
control_tlvs: ReceiveControlTlvs,
|
||||
reply_path: Option<BlindedPath>,
|
||||
message: ParsedOnionMessageContents<T>,
|
||||
message: T,
|
||||
}
|
||||
}
|
||||
|
||||
/// The contents of an onion message as read from the wire.
|
||||
/// The contents of an [`OnionMessage`] as read from the wire.
|
||||
///
|
||||
/// [`OnionMessage`]: crate::ln::msgs::OnionMessage
|
||||
#[derive(Debug)]
|
||||
pub enum ParsedOnionMessageContents<T: CustomOnionMessageContents> {
|
||||
pub enum ParsedOnionMessageContents<T: OnionMessageContents> {
|
||||
/// A message related to BOLT 12 Offers.
|
||||
Offers(OffersMessage),
|
||||
/// A custom onion message specified by the user.
|
||||
Custom(T),
|
||||
}
|
||||
|
||||
impl<T: CustomOnionMessageContents> ParsedOnionMessageContents<T> {
|
||||
impl<T: OnionMessageContents> OnionMessageContents for ParsedOnionMessageContents<T> {
|
||||
/// Returns the type that was used to decode the message payload.
|
||||
///
|
||||
/// This is not exported to bindings users as methods on non-cloneable enums are not currently exportable
|
||||
pub fn tlv_type(&self) -> u64 {
|
||||
fn tlv_type(&self) -> u64 {
|
||||
match self {
|
||||
&ParsedOnionMessageContents::Offers(ref msg) => msg.tlv_type(),
|
||||
&ParsedOnionMessageContents::Custom(ref msg) => msg.tlv_type(),
|
||||
|
@ -136,7 +138,7 @@ impl<T: CustomOnionMessageContents> ParsedOnionMessageContents<T> {
|
|||
}
|
||||
|
||||
/// This is not exported to bindings users as methods on non-cloneable enums are not currently exportable
|
||||
impl<T: CustomOnionMessageContents> Writeable for ParsedOnionMessageContents<T> {
|
||||
impl<T: OnionMessageContents> Writeable for ParsedOnionMessageContents<T> {
|
||||
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
|
||||
match self {
|
||||
ParsedOnionMessageContents::Offers(msg) => Ok(msg.write(w)?),
|
||||
|
@ -145,8 +147,8 @@ impl<T: CustomOnionMessageContents> Writeable for ParsedOnionMessageContents<T>
|
|||
}
|
||||
}
|
||||
|
||||
/// The contents of a custom onion message.
|
||||
pub trait CustomOnionMessageContents: Writeable {
|
||||
/// The contents of an onion message.
|
||||
pub trait OnionMessageContents: Writeable {
|
||||
/// Returns the TLV type identifying the message contents. MUST be >= 64.
|
||||
fn tlv_type(&self) -> u64;
|
||||
}
|
||||
|
@ -172,7 +174,7 @@ pub(super) enum ReceiveControlTlvs {
|
|||
}
|
||||
|
||||
// Uses the provided secret to simultaneously encode and encrypt the unblinded control TLVs.
|
||||
impl<T: CustomOnionMessageContents> Writeable for (Payload<T>, [u8; 32]) {
|
||||
impl<T: OnionMessageContents> Writeable for (Payload<T>, [u8; 32]) {
|
||||
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
|
||||
match &self.0 {
|
||||
Payload::Forward(ForwardControlTlvs::Blinded(encrypted_bytes)) => {
|
||||
|
@ -211,8 +213,8 @@ impl<T: CustomOnionMessageContents> Writeable for (Payload<T>, [u8; 32]) {
|
|||
}
|
||||
|
||||
// Uses the provided secret to simultaneously decode and decrypt the control TLVs and data TLV.
|
||||
impl<H: CustomOnionMessageHandler + ?Sized, L: Logger + ?Sized>
|
||||
ReadableArgs<(SharedSecret, &H, &L)> for Payload<<H as CustomOnionMessageHandler>::CustomMessage> {
|
||||
impl<H: CustomOnionMessageHandler + ?Sized, L: Logger + ?Sized> ReadableArgs<(SharedSecret, &H, &L)>
|
||||
for Payload<ParsedOnionMessageContents<<H as CustomOnionMessageHandler>::CustomMessage>> {
|
||||
fn read<R: Read>(r: &mut R, args: (SharedSecret, &H, &L)) -> Result<Self, DecodeError> {
|
||||
let (encrypted_tlvs_ss, handler, logger) = args;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue