mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-03-10 13:35:38 +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::test_channel_signer::TestChannelSigner;
|
||||||
use lightning::util::logger::Logger;
|
use lightning::util::logger::Logger;
|
||||||
use lightning::util::ser::{Readable, Writeable, Writer};
|
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;
|
use crate::utils::test_logger;
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ struct TestCustomMessage {}
|
||||||
const CUSTOM_MESSAGE_TYPE: u64 = 4242;
|
const CUSTOM_MESSAGE_TYPE: u64 = 4242;
|
||||||
const CUSTOM_MESSAGE_CONTENTS: [u8; 32] = [42; 32];
|
const CUSTOM_MESSAGE_CONTENTS: [u8; 32] = [42; 32];
|
||||||
|
|
||||||
impl CustomOnionMessageContents for TestCustomMessage {
|
impl OnionMessageContents for TestCustomMessage {
|
||||||
fn tlv_type(&self) -> u64 {
|
fn tlv_type(&self) -> u64 {
|
||||||
CUSTOM_MESSAGE_TYPE
|
CUSTOM_MESSAGE_TYPE
|
||||||
}
|
}
|
||||||
|
@ -216,9 +216,9 @@ mod tests {
|
||||||
assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(),
|
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));
|
"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(),
|
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(),
|
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";
|
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::peer_channel_encryptor::{PeerChannelEncryptor,NextNoiseStep};
|
||||||
use crate::ln::wire;
|
use crate::ln::wire;
|
||||||
use crate::ln::wire::{Encode, Type};
|
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::routing::gossip::{NetworkGraph, P2PGossipSync, NodeId, NodeAlias};
|
||||||
use crate::util::atomic_counter::AtomicCounter;
|
use crate::util::atomic_counter::AtomicCounter;
|
||||||
use crate::util::logger::Logger;
|
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!(); }
|
fn tlv_type(&self) -> u64 { unreachable!(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ use crate::ln::msgs::{self, DecodeError, OnionMessageHandler};
|
||||||
use crate::sign::{NodeSigner, Recipient};
|
use crate::sign::{NodeSigner, Recipient};
|
||||||
use crate::util::ser::{FixedLengthReader, LengthReadable, Writeable, Writer};
|
use crate::util::ser::{FixedLengthReader, LengthReadable, Writeable, Writer};
|
||||||
use crate::util::test_utils;
|
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::network::constants::Network;
|
||||||
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
|
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_REQUEST_MESSAGE_CONTENTS: [u8; 32] = [42; 32];
|
||||||
const CUSTOM_RESPONSE_MESSAGE_CONTENTS: [u8; 32] = [43; 32];
|
const CUSTOM_RESPONSE_MESSAGE_CONTENTS: [u8; 32] = [43; 32];
|
||||||
|
|
||||||
impl CustomOnionMessageContents for TestCustomMessage {
|
impl OnionMessageContents for TestCustomMessage {
|
||||||
fn tlv_type(&self) -> u64 {
|
fn tlv_type(&self) -> u64 {
|
||||||
match self {
|
match self {
|
||||||
TestCustomMessage::Request => CUSTOM_REQUEST_MESSAGE_TYPE,
|
TestCustomMessage::Request => CUSTOM_REQUEST_MESSAGE_TYPE,
|
||||||
|
@ -196,7 +196,7 @@ fn pass_along_path(path: &Vec<MessengerNode>) {
|
||||||
#[test]
|
#[test]
|
||||||
fn one_hop() {
|
fn one_hop() {
|
||||||
let nodes = create_nodes(2);
|
let nodes = create_nodes(2);
|
||||||
let test_msg = ParsedOnionMessageContents::Custom(TestCustomMessage::Response);
|
let test_msg = TestCustomMessage::Response;
|
||||||
|
|
||||||
let path = OnionMessagePath {
|
let path = OnionMessagePath {
|
||||||
intermediate_nodes: vec![],
|
intermediate_nodes: vec![],
|
||||||
|
@ -210,7 +210,7 @@ fn one_hop() {
|
||||||
#[test]
|
#[test]
|
||||||
fn two_unblinded_hops() {
|
fn two_unblinded_hops() {
|
||||||
let nodes = create_nodes(3);
|
let nodes = create_nodes(3);
|
||||||
let test_msg = ParsedOnionMessageContents::Custom(TestCustomMessage::Response);
|
let test_msg = TestCustomMessage::Response;
|
||||||
|
|
||||||
let path = OnionMessagePath {
|
let path = OnionMessagePath {
|
||||||
intermediate_nodes: vec![nodes[1].get_node_pk()],
|
intermediate_nodes: vec![nodes[1].get_node_pk()],
|
||||||
|
@ -224,7 +224,7 @@ fn two_unblinded_hops() {
|
||||||
#[test]
|
#[test]
|
||||||
fn two_unblinded_two_blinded() {
|
fn two_unblinded_two_blinded() {
|
||||||
let nodes = create_nodes(5);
|
let nodes = create_nodes(5);
|
||||||
let test_msg = ParsedOnionMessageContents::Custom(TestCustomMessage::Response);
|
let test_msg = TestCustomMessage::Response;
|
||||||
|
|
||||||
let secp_ctx = Secp256k1::new();
|
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();
|
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]
|
#[test]
|
||||||
fn three_blinded_hops() {
|
fn three_blinded_hops() {
|
||||||
let nodes = create_nodes(4);
|
let nodes = create_nodes(4);
|
||||||
let test_msg = ParsedOnionMessageContents::Custom(TestCustomMessage::Response);
|
let test_msg = TestCustomMessage::Response;
|
||||||
|
|
||||||
let secp_ctx = Secp256k1::new();
|
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();
|
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() {
|
fn too_big_packet_error() {
|
||||||
// Make sure we error as expected if a packet is too big to send.
|
// Make sure we error as expected if a packet is too big to send.
|
||||||
let nodes = create_nodes(2);
|
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 hop_node_id = nodes[1].get_node_pk();
|
||||||
let hops = vec![hop_node_id; 400];
|
let hops = vec![hop_node_id; 400];
|
||||||
|
@ -285,7 +285,7 @@ fn we_are_intro_node() {
|
||||||
destination: Destination::BlindedPath(blinded_path),
|
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);
|
nodes[2].custom_message_handler.expect_message(TestCustomMessage::Response);
|
||||||
pass_along_path(&nodes);
|
pass_along_path(&nodes);
|
||||||
|
|
||||||
|
@ -295,7 +295,7 @@ fn we_are_intro_node() {
|
||||||
intermediate_nodes: vec![],
|
intermediate_nodes: vec![],
|
||||||
destination: Destination::BlindedPath(blinded_path),
|
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[1].custom_message_handler.expect_message(TestCustomMessage::Response);
|
||||||
nodes.remove(2);
|
nodes.remove(2);
|
||||||
pass_along_path(&nodes);
|
pass_along_path(&nodes);
|
||||||
|
@ -315,7 +315,7 @@ fn invalid_blinded_path_error() {
|
||||||
intermediate_nodes: vec![],
|
intermediate_nodes: vec![],
|
||||||
destination: Destination::BlindedPath(blinded_path),
|
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);
|
assert_eq!(err, SendError::TooFewBlindedHops);
|
||||||
|
|
||||||
// 1 hop
|
// 1 hop
|
||||||
|
@ -326,7 +326,7 @@ fn invalid_blinded_path_error() {
|
||||||
intermediate_nodes: vec![],
|
intermediate_nodes: vec![],
|
||||||
destination: Destination::BlindedPath(blinded_path),
|
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);
|
assert_eq!(err, SendError::TooFewBlindedHops);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,7 +342,7 @@ fn reply_path() {
|
||||||
destination: Destination::Node(nodes[3].get_node_pk()),
|
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();
|
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);
|
nodes[3].custom_message_handler.expect_message(TestCustomMessage::Request);
|
||||||
pass_along_path(&nodes);
|
pass_along_path(&nodes);
|
||||||
// Make sure the last node successfully decoded the reply path.
|
// 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();
|
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);
|
nodes[3].custom_message_handler.expect_message(TestCustomMessage::Request);
|
||||||
pass_along_path(&nodes);
|
pass_along_path(&nodes);
|
||||||
|
|
||||||
|
@ -373,7 +373,7 @@ fn invalid_custom_message_type() {
|
||||||
let nodes = create_nodes(2);
|
let nodes = create_nodes(2);
|
||||||
|
|
||||||
struct InvalidCustomMessage{}
|
struct InvalidCustomMessage{}
|
||||||
impl CustomOnionMessageContents for InvalidCustomMessage {
|
impl OnionMessageContents for InvalidCustomMessage {
|
||||||
fn tlv_type(&self) -> u64 {
|
fn tlv_type(&self) -> u64 {
|
||||||
// Onion message contents must have a TLV >= 64.
|
// Onion message contents must have a TLV >= 64.
|
||||||
63
|
63
|
||||||
|
@ -384,7 +384,7 @@ fn invalid_custom_message_type() {
|
||||||
fn write<W: Writer>(&self, _w: &mut W) -> Result<(), io::Error> { unreachable!() }
|
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 {
|
let path = OnionMessagePath {
|
||||||
intermediate_nodes: vec![],
|
intermediate_nodes: vec![],
|
||||||
destination: Destination::Node(nodes[1].get_node_pk()),
|
destination: Destination::Node(nodes[1].get_node_pk()),
|
||||||
|
@ -402,9 +402,9 @@ fn peer_buffer_full() {
|
||||||
destination: Destination::Node(nodes[1].get_node_pk()),
|
destination: Destination::Node(nodes[1].get_node_pk()),
|
||||||
};
|
};
|
||||||
for _ in 0..188 { // Based on MAX_PER_PEER_BUFFER_SIZE in OnionMessenger
|
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);
|
assert_eq!(err, SendError::BufferFull);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,7 +425,7 @@ fn many_hops() {
|
||||||
intermediate_nodes,
|
intermediate_nodes,
|
||||||
destination: Destination::Node(nodes[num_nodes-1].get_node_pk()),
|
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);
|
nodes[num_nodes-1].custom_message_handler.expect_message(TestCustomMessage::Response);
|
||||||
pass_along_path(&nodes);
|
pass_along_path(&nodes);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,8 @@ use crate::ln::features::{InitFeatures, NodeFeatures};
|
||||||
use crate::ln::msgs::{self, OnionMessage, OnionMessageHandler};
|
use crate::ln::msgs::{self, OnionMessage, OnionMessageHandler};
|
||||||
use crate::ln::onion_utils;
|
use crate::ln::onion_utils;
|
||||||
use crate::ln::peer_handler::IgnoringMessageHandler;
|
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::offers::OffersMessageHandler;
|
||||||
use super::packet::{BIG_PACKET_HOP_DATA_LEN, ForwardControlTlvs, Packet, Payload, ReceiveControlTlvs, SMALL_PACKET_HOP_DATA_LEN};
|
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::logger::Logger;
|
||||||
|
@ -60,7 +61,7 @@ use crate::prelude::*;
|
||||||
/// # use lightning::blinded_path::BlindedPath;
|
/// # use lightning::blinded_path::BlindedPath;
|
||||||
/// # use lightning::sign::KeysManager;
|
/// # use lightning::sign::KeysManager;
|
||||||
/// # use lightning::ln::peer_handler::IgnoringMessageHandler;
|
/// # 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::logger::{Logger, Record};
|
||||||
/// # use lightning::util::ser::{Writeable, Writer};
|
/// # use lightning::util::ser::{Writeable, Writer};
|
||||||
/// # use lightning::io;
|
/// # use lightning::io;
|
||||||
|
@ -101,7 +102,7 @@ use crate::prelude::*;
|
||||||
/// // Write your custom onion message to `w`
|
/// // Write your custom onion message to `w`
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// impl CustomOnionMessageContents for YourCustomMessage {
|
/// impl OnionMessageContents for YourCustomMessage {
|
||||||
/// fn tlv_type(&self) -> u64 {
|
/// fn tlv_type(&self) -> u64 {
|
||||||
/// # let your_custom_message_type = 42;
|
/// # let your_custom_message_type = 42;
|
||||||
/// your_custom_message_type
|
/// your_custom_message_type
|
||||||
|
@ -113,8 +114,7 @@ use crate::prelude::*;
|
||||||
/// destination: Destination::Node(destination_node_id),
|
/// destination: Destination::Node(destination_node_id),
|
||||||
/// };
|
/// };
|
||||||
/// let reply_path = None;
|
/// let reply_path = None;
|
||||||
/// # let your_custom_message = YourCustomMessage {};
|
/// # let message = YourCustomMessage {};
|
||||||
/// let message = ParsedOnionMessageContents::Custom(your_custom_message);
|
|
||||||
/// onion_messenger.send_onion_message(path, message, reply_path);
|
/// onion_messenger.send_onion_message(path, message, reply_path);
|
||||||
///
|
///
|
||||||
/// // Create a blinded path to yourself, for someone to send an onion message to.
|
/// // 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),
|
/// destination: Destination::BlindedPath(blinded_path),
|
||||||
/// };
|
/// };
|
||||||
/// let reply_path = None;
|
/// let reply_path = None;
|
||||||
/// # let your_custom_message = YourCustomMessage {};
|
/// # let message = YourCustomMessage {};
|
||||||
/// let message = ParsedOnionMessageContents::Custom(your_custom_message);
|
|
||||||
/// onion_messenger.send_onion_message(path, message, reply_path);
|
/// onion_messenger.send_onion_message(path, message, reply_path);
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
@ -244,7 +243,7 @@ pub enum SendError {
|
||||||
pub trait CustomOnionMessageHandler {
|
pub trait CustomOnionMessageHandler {
|
||||||
/// The message known to the handler. To support multiple message types, you may want to make this
|
/// 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.
|
/// 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.
|
/// 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>;
|
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)
|
/// A processed incoming onion message, containing either a Forward (another onion message)
|
||||||
/// or a Receive payload with decrypted contents.
|
/// 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
|
/// Forwarded onion, with the next node id and a new onion
|
||||||
Forward(PublicKey, OnionMessage),
|
Forward(PublicKey, OnionMessage),
|
||||||
/// Received onion message, with decrypted contents, path_id, and reply path
|
/// 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
|
/// Creates an [`OnionMessage`] with the given `contents` for sending to the destination of
|
||||||
/// `path`.
|
/// `path`.
|
||||||
///
|
///
|
||||||
/// Returns both the node id of the peer to send the message to and the message itself.
|
/// 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>,
|
entropy_source: &ES, node_signer: &NS, secp_ctx: &Secp256k1<secp256k1::All>,
|
||||||
path: OnionMessagePath, contents: ParsedOnionMessageContents<T>,
|
path: OnionMessagePath, contents: T, reply_path: Option<BlindedPath>,
|
||||||
reply_path: Option<BlindedPath>,
|
|
||||||
) -> Result<(PublicKey, OnionMessage), SendError>
|
) -> Result<(PublicKey, OnionMessage), SendError>
|
||||||
where
|
where
|
||||||
ES::Target: EntropySource,
|
ES::Target: EntropySource,
|
||||||
|
@ -361,7 +359,7 @@ where
|
||||||
onion_decode_ss, &msg.onion_routing_packet.hop_data[..], msg.onion_routing_packet.hmac,
|
onion_decode_ss, &msg.onion_routing_packet.hop_data[..], msg.onion_routing_packet.hmac,
|
||||||
(control_tlvs_ss, custom_handler.deref(), logger.deref())
|
(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,
|
message, control_tlvs: ReceiveControlTlvs::Unblinded(ReceiveTlvs { path_id }), reply_path,
|
||||||
}, None)) => {
|
}, None)) => {
|
||||||
Ok(PeeledOnion::Receive(message, path_id, reply_path))
|
Ok(PeeledOnion::Receive(message, path_id, reply_path))
|
||||||
|
@ -452,9 +450,8 @@ where
|
||||||
/// `path`.
|
/// `path`.
|
||||||
///
|
///
|
||||||
/// See [`OnionMessenger`] for example usage.
|
/// See [`OnionMessenger`] for example usage.
|
||||||
pub fn send_onion_message<T: CustomOnionMessageContents>(
|
pub fn send_onion_message<T: OnionMessageContents>(
|
||||||
&self, path: OnionMessagePath, contents: ParsedOnionMessageContents<T>,
|
&self, path: OnionMessagePath, contents: T, reply_path: Option<BlindedPath>
|
||||||
reply_path: Option<BlindedPath>
|
|
||||||
) -> Result<(), SendError> {
|
) -> Result<(), SendError> {
|
||||||
let (first_node_id, onion_msg) = create_onion_message(
|
let (first_node_id, onion_msg) = create_onion_message(
|
||||||
&self.entropy_source, &self.node_signer, &self.secp_ctx, path, contents, reply_path
|
&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>(
|
fn handle_onion_message_response<T: OnionMessageContents>(
|
||||||
&self, contents: ParsedOnionMessageContents<T>, destination: Destination,
|
&self, response: Option<T>, reply_path: Option<BlindedPath>, log_suffix: fmt::Arguments
|
||||||
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) {
|
let sender = match self.node_signer.get_node_id(Recipient::Node) {
|
||||||
Ok(node_id) => node_id,
|
Ok(node_id) => node_id,
|
||||||
|
@ -557,34 +570,27 @@ where
|
||||||
log_trace!(self.logger,
|
log_trace!(self.logger,
|
||||||
"Received an onion message with path_id {:02x?} and {} reply_path",
|
"Received an onion message with path_id {:02x?} and {} reply_path",
|
||||||
path_id, if reply_path.is_some() { "a" } else { "no" });
|
path_id, if reply_path.is_some() { "a" } else { "no" });
|
||||||
let response = match message {
|
|
||||||
|
match message {
|
||||||
ParsedOnionMessageContents::Offers(msg) => {
|
ParsedOnionMessageContents::Offers(msg) => {
|
||||||
self.offers_handler.handle_message(msg)
|
let response = self.offers_handler.handle_message(msg);
|
||||||
.map(|msg| ParsedOnionMessageContents::Offers(msg))
|
self.handle_onion_message_response(
|
||||||
},
|
response, reply_path, format_args!(
|
||||||
ParsedOnionMessageContents::Custom(msg) => {
|
"when responding to Offers onion message with path_id {:02x?}",
|
||||||
self.custom_handler.handle_custom_message(msg)
|
path_id
|
||||||
.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 => {
|
ParsedOnionMessageContents::Custom(msg) => {
|
||||||
log_trace!(
|
let response = self.custom_handler.handle_custom_message(msg);
|
||||||
self.logger,
|
self.handle_onion_message_response(
|
||||||
"Missing reply path when responding to onion message with path_id {:02x?}",
|
response, reply_path, format_args!(
|
||||||
|
"when responding to Custom onion message with path_id {:02x?}",
|
||||||
path_id
|
path_id
|
||||||
|
)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
Ok(PeeledOnion::Forward(next_node_id, onion_message)) => {
|
Ok(PeeledOnion::Forward(next_node_id, onion_message)) => {
|
||||||
let mut pending_per_peer_msgs = self.pending_messages.lock().unwrap();
|
let mut pending_per_peer_msgs = self.pending_messages.lock().unwrap();
|
||||||
|
@ -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
|
/// Construct onion packet payloads and keys for sending an onion message along the given
|
||||||
/// `unblinded_path` to the given `destination`.
|
/// `unblinded_path` to the given `destination`.
|
||||||
fn packet_payloads_and_keys<T: CustomOnionMessageContents, S: secp256k1::Signing + secp256k1::Verification>(
|
fn packet_payloads_and_keys<T: OnionMessageContents, S: secp256k1::Signing + secp256k1::Verification>(
|
||||||
secp_ctx: &Secp256k1<S>, unblinded_path: &[PublicKey], destination: Destination,
|
secp_ctx: &Secp256k1<S>, unblinded_path: &[PublicKey], destination: Destination, message: T,
|
||||||
message: ParsedOnionMessageContents<T>, mut reply_path: Option<BlindedPath>, session_priv: &SecretKey
|
mut reply_path: Option<BlindedPath>, session_priv: &SecretKey
|
||||||
) -> Result<(Vec<(Payload<T>, [u8; 32])>, Vec<onion_utils::OnionKeys>), secp256k1::Error> {
|
) -> Result<(Vec<(Payload<T>, [u8; 32])>, Vec<onion_utils::OnionKeys>), secp256k1::Error> {
|
||||||
let num_hops = unblinded_path.len() + destination.num_hops();
|
let num_hops = unblinded_path.len() + destination.num_hops();
|
||||||
let mut payloads = Vec::with_capacity(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
|
/// 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:
|
// Spec rationale:
|
||||||
// "`len` allows larger messages to be sent than the standard 1300 bytes allowed for an HTLC
|
// "`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
|
// onion, but this should be used sparingly as it is reduces anonymity set, hence the
|
||||||
|
|
|
@ -27,7 +27,7 @@ mod packet;
|
||||||
mod functional_tests;
|
mod functional_tests;
|
||||||
|
|
||||||
// Re-export structs so they can be imported with just the `onion_message::` module prefix.
|
// 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::offers::{OffersMessage, OffersMessageHandler};
|
||||||
pub use self::packet::Packet;
|
pub use self::packet::{Packet, ParsedOnionMessageContents};
|
||||||
pub(crate) use self::packet::ControlTlvs;
|
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_request::InvoiceRequest;
|
||||||
use crate::offers::invoice::Bolt12Invoice;
|
use crate::offers::invoice::Bolt12Invoice;
|
||||||
use crate::offers::parse::Bolt12ParseError;
|
use crate::offers::parse::Bolt12ParseError;
|
||||||
|
use crate::onion_message::OnionMessageContents;
|
||||||
use crate::util::logger::Logger;
|
use crate::util::logger::Logger;
|
||||||
use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer};
|
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> {
|
fn parse(tlv_type: u64, bytes: Vec<u8>) -> Result<Self, Bolt12ParseError> {
|
||||||
match tlv_type {
|
match tlv_type {
|
||||||
INVOICE_REQUEST_TLV_TYPE => Ok(Self::InvoiceRequest(InvoiceRequest::try_from(bytes)?)),
|
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 {
|
impl Writeable for OffersMessage {
|
||||||
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
|
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
|
||||||
match self {
|
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
|
/// 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
|
/// 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.
|
/// 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.
|
/// This payload is for an intermediate hop.
|
||||||
Forward(ForwardControlTlvs),
|
Forward(ForwardControlTlvs),
|
||||||
/// This payload is for the final hop.
|
/// This payload is for the final hop.
|
||||||
Receive {
|
Receive {
|
||||||
control_tlvs: ReceiveControlTlvs,
|
control_tlvs: ReceiveControlTlvs,
|
||||||
reply_path: Option<BlindedPath>,
|
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)]
|
#[derive(Debug)]
|
||||||
pub enum ParsedOnionMessageContents<T: CustomOnionMessageContents> {
|
pub enum ParsedOnionMessageContents<T: OnionMessageContents> {
|
||||||
/// A message related to BOLT 12 Offers.
|
/// A message related to BOLT 12 Offers.
|
||||||
Offers(OffersMessage),
|
Offers(OffersMessage),
|
||||||
/// A custom onion message specified by the user.
|
/// A custom onion message specified by the user.
|
||||||
Custom(T),
|
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.
|
/// 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
|
/// 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 {
|
match self {
|
||||||
&ParsedOnionMessageContents::Offers(ref msg) => msg.tlv_type(),
|
&ParsedOnionMessageContents::Offers(ref msg) => msg.tlv_type(),
|
||||||
&ParsedOnionMessageContents::Custom(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
|
/// 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> {
|
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
|
||||||
match self {
|
match self {
|
||||||
ParsedOnionMessageContents::Offers(msg) => Ok(msg.write(w)?),
|
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.
|
/// The contents of an onion message.
|
||||||
pub trait CustomOnionMessageContents: Writeable {
|
pub trait OnionMessageContents: Writeable {
|
||||||
/// Returns the TLV type identifying the message contents. MUST be >= 64.
|
/// Returns the TLV type identifying the message contents. MUST be >= 64.
|
||||||
fn tlv_type(&self) -> u64;
|
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.
|
// 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> {
|
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
|
||||||
match &self.0 {
|
match &self.0 {
|
||||||
Payload::Forward(ForwardControlTlvs::Blinded(encrypted_bytes)) => {
|
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.
|
// Uses the provided secret to simultaneously decode and decrypt the control TLVs and data TLV.
|
||||||
impl<H: CustomOnionMessageHandler + ?Sized, L: Logger + ?Sized>
|
impl<H: CustomOnionMessageHandler + ?Sized, L: Logger + ?Sized> ReadableArgs<(SharedSecret, &H, &L)>
|
||||||
ReadableArgs<(SharedSecret, &H, &L)> for Payload<<H as CustomOnionMessageHandler>::CustomMessage> {
|
for Payload<ParsedOnionMessageContents<<H as CustomOnionMessageHandler>::CustomMessage>> {
|
||||||
fn read<R: Read>(r: &mut R, args: (SharedSecret, &H, &L)) -> Result<Self, DecodeError> {
|
fn read<R: Read>(r: &mut R, args: (SharedSecret, &H, &L)) -> Result<Self, DecodeError> {
|
||||||
let (encrypted_tlvs_ss, handler, logger) = args;
|
let (encrypted_tlvs_ss, handler, logger) = args;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue