Skip to content

Commit f521e4c

Browse files
committed
OffersMessageHandler trait for OnionMessenger
Add a trait for handling BOLT 12 Offers messages to OnionMessenger and a skeleton implementation of it for ChannelManager. This allows users to either provide their own custom handling Offers messages or rely on a version provided by LDK using stateless verification.
1 parent cff88aa commit f521e4c

File tree

7 files changed

+94
-36
lines changed

7 files changed

+94
-36
lines changed

fuzz/src/onion_message.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use lightning::ln::script::ShutdownScript;
1111
use lightning::util::enforcing_trait_impls::EnforcingSigner;
1212
use lightning::util::logger::Logger;
1313
use lightning::util::ser::{Readable, Writeable, Writer};
14-
use lightning::onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, OnionMessenger};
14+
use lightning::onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, OffersMessage, OffersMessageHandler, OnionMessenger};
1515

1616
use crate::utils::test_logger;
1717

@@ -29,8 +29,11 @@ pub fn do_test<L: Logger>(data: &[u8], logger: &L) {
2929
node_secret: secret,
3030
counter: AtomicU64::new(0),
3131
};
32+
let offers_msg_handler = TestOffersMessageHandler {};
3233
let custom_msg_handler = TestCustomMessageHandler {};
33-
let onion_messenger = OnionMessenger::new(&keys_manager, &keys_manager, logger, &custom_msg_handler);
34+
let onion_messenger = OnionMessenger::new(
35+
&keys_manager, &keys_manager, logger, &offers_msg_handler, &custom_msg_handler
36+
);
3437
let mut pk = [2; 33]; pk[1] = 0xff;
3538
let peer_node_id_not_used = PublicKey::from_slice(&pk).unwrap();
3639
onion_messenger.handle_onion_message(&peer_node_id_not_used, &msg);
@@ -50,6 +53,12 @@ pub extern "C" fn onion_message_run(data: *const u8, datalen: usize) {
5053
do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, &logger);
5154
}
5255

56+
struct TestOffersMessageHandler {}
57+
58+
impl OffersMessageHandler for TestOffersMessageHandler {
59+
fn handle_message(&self, _message: OffersMessage) {}
60+
}
61+
5362
struct TestCustomMessage {}
5463

5564
const CUSTOM_MESSAGE_TYPE: u64 = 4242;

lightning/src/ln/peer_handler.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use crate::util::ser::{VecWriter, Writeable, Writer};
2828
use crate::ln::peer_channel_encryptor::{PeerChannelEncryptor,NextNoiseStep};
2929
use crate::ln::wire;
3030
use crate::ln::wire::{Encode, Type};
31-
use crate::onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, SimpleArcOnionMessenger, SimpleRefOnionMessenger};
31+
use crate::onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, OffersMessage, OffersMessageHandler, SimpleArcOnionMessenger, SimpleRefOnionMessenger};
3232
use crate::routing::gossip::{NetworkGraph, P2PGossipSync, NodeId, NodeAlias};
3333
use crate::util::atomic_counter::AtomicCounter;
3434
use crate::util::logger::Logger;
@@ -118,6 +118,9 @@ impl OnionMessageHandler for IgnoringMessageHandler {
118118
InitFeatures::empty()
119119
}
120120
}
121+
impl OffersMessageHandler for IgnoringMessageHandler {
122+
fn handle_message(&self, _msg: OffersMessage) {}
123+
}
121124
impl CustomOnionMessageHandler for IgnoringMessageHandler {
122125
type CustomMessage = Infallible;
123126
fn handle_custom_message(&self, _msg: Infallible) {

lightning/src/onion_message/functional_tests.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::blinded_path::BlindedPath;
1313
use crate::sign::{NodeSigner, Recipient};
1414
use crate::ln::features::InitFeatures;
1515
use crate::ln::msgs::{self, DecodeError, OnionMessageHandler};
16-
use super::{CustomOnionMessageContents, CustomOnionMessageHandler, Destination, OnionMessageContents, OnionMessenger, SendError};
16+
use super::{CustomOnionMessageContents, CustomOnionMessageHandler, Destination, OffersMessage, OffersMessageHandler, OnionMessageContents, OnionMessenger, SendError};
1717
use crate::util::ser::{Writeable, Writer};
1818
use crate::util::test_utils;
1919

@@ -27,7 +27,7 @@ use crate::sync::Arc;
2727

2828
struct MessengerNode {
2929
keys_manager: Arc<test_utils::TestKeysInterface>,
30-
messenger: OnionMessenger<Arc<test_utils::TestKeysInterface>, Arc<test_utils::TestKeysInterface>, Arc<test_utils::TestLogger>, Arc<TestCustomMessageHandler>>,
30+
messenger: OnionMessenger<Arc<test_utils::TestKeysInterface>, Arc<test_utils::TestKeysInterface>, Arc<test_utils::TestLogger>, Arc<TestOffersMessageHandler>, Arc<TestCustomMessageHandler>>,
3131
custom_message_handler: Arc<TestCustomMessageHandler>,
3232
logger: Arc<test_utils::TestLogger>,
3333
}
@@ -38,6 +38,14 @@ impl MessengerNode {
3838
}
3939
}
4040

41+
struct TestOffersMessageHandler {}
42+
43+
impl OffersMessageHandler for TestOffersMessageHandler {
44+
fn handle_message(&self, _message: OffersMessage) {
45+
todo!()
46+
}
47+
}
48+
4149
#[derive(Clone)]
4250
struct TestCustomMessage {}
4351

@@ -98,10 +106,11 @@ fn create_nodes(num_messengers: u8) -> Vec<MessengerNode> {
98106
let logger = Arc::new(test_utils::TestLogger::with_id(format!("node {}", i)));
99107
let seed = [i as u8; 32];
100108
let keys_manager = Arc::new(test_utils::TestKeysInterface::new(&seed, Network::Testnet));
109+
let offers_message_handler = Arc::new(TestOffersMessageHandler {});
101110
let custom_message_handler = Arc::new(TestCustomMessageHandler::new());
102111
nodes.push(MessengerNode {
103112
keys_manager: keys_manager.clone(),
104-
messenger: OnionMessenger::new(keys_manager.clone(), keys_manager.clone(), logger.clone(), custom_message_handler.clone()),
113+
messenger: OnionMessenger::new(keys_manager.clone(), keys_manager, logger.clone(), offers_message_handler, custom_message_handler.clone()),
105114
custom_message_handler,
106115
logger,
107116
});

lightning/src/onion_message/messenger.rs

Lines changed: 55 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use crate::ln::msgs::{self, OnionMessageHandler};
2323
use crate::ln::onion_utils;
2424
use crate::ln::peer_handler::IgnoringMessageHandler;
2525
pub use super::packet::{CustomOnionMessageContents, OnionMessageContents};
26+
use super::offers::OffersMessageHandler;
2627
use super::packet::{BIG_PACKET_HOP_DATA_LEN, ForwardControlTlvs, Packet, Payload, ReceiveControlTlvs, SMALL_PACKET_HOP_DATA_LEN};
2728
use crate::util::logger::Logger;
2829
use crate::util::ser::Writeable;
@@ -63,10 +64,11 @@ use crate::prelude::*;
6364
/// # let hop_node_id1 = PublicKey::from_secret_key(&secp_ctx, &node_secret);
6465
/// # let (hop_node_id2, hop_node_id3, hop_node_id4) = (hop_node_id1, hop_node_id1, hop_node_id1);
6566
/// # let destination_node_id = hop_node_id1;
66-
/// # let your_custom_message_handler = IgnoringMessageHandler {};
67+
/// # let custom_message_handler = IgnoringMessageHandler {};
68+
/// # let offers_message_handler = IgnoringMessageHandler {};
6769
/// // Create the onion messenger. This must use the same `keys_manager` as is passed to your
6870
/// // ChannelManager.
69-
/// let onion_messenger = OnionMessenger::new(&keys_manager, &keys_manager, logger, &your_custom_message_handler);
71+
/// let onion_messenger = OnionMessenger::new(&keys_manager, &keys_manager, logger, &offers_message_handler, &custom_message_handler);
7072
///
7173
/// # struct YourCustomMessage {}
7274
/// impl Writeable for YourCustomMessage {
@@ -103,20 +105,21 @@ use crate::prelude::*;
103105
///
104106
/// [offers]: <https://github.com/lightning/bolts/pull/798>
105107
/// [`OnionMessenger`]: crate::onion_message::OnionMessenger
106-
pub struct OnionMessenger<ES: Deref, NS: Deref, L: Deref, CMH: Deref>
107-
where ES::Target: EntropySource,
108-
NS::Target: NodeSigner,
109-
L::Target: Logger,
110-
CMH:: Target: CustomOnionMessageHandler,
108+
pub struct OnionMessenger<ES: Deref, NS: Deref, L: Deref, OMH: Deref, CMH: Deref>
109+
where
110+
ES::Target: EntropySource,
111+
NS::Target: NodeSigner,
112+
L::Target: Logger,
113+
OMH::Target: OffersMessageHandler,
114+
CMH:: Target: CustomOnionMessageHandler,
111115
{
112116
entropy_source: ES,
113117
node_signer: NS,
114118
logger: L,
115119
pending_messages: Mutex<HashMap<PublicKey, VecDeque<msgs::OnionMessage>>>,
116120
secp_ctx: Secp256k1<secp256k1::All>,
121+
offers_handler: OMH,
117122
custom_handler: CMH,
118-
// Coming soon:
119-
// invoice_handler: InvoiceHandler,
120123
}
121124

122125
/// The destination of an onion message.
@@ -187,15 +190,19 @@ pub trait CustomOnionMessageHandler {
187190
fn read_custom_message<R: io::Read>(&self, message_type: u64, buffer: &mut R) -> Result<Option<Self::CustomMessage>, msgs::DecodeError>;
188191
}
189192

190-
impl<ES: Deref, NS: Deref, L: Deref, CMH: Deref> OnionMessenger<ES, NS, L, CMH>
191-
where ES::Target: EntropySource,
192-
NS::Target: NodeSigner,
193-
L::Target: Logger,
194-
CMH::Target: CustomOnionMessageHandler,
193+
impl<ES: Deref, NS: Deref, L: Deref, OMH: Deref, CMH: Deref> OnionMessenger<ES, NS, L, OMH, CMH>
194+
where
195+
ES::Target: EntropySource,
196+
NS::Target: NodeSigner,
197+
L::Target: Logger,
198+
OMH::Target: OffersMessageHandler,
199+
CMH::Target: CustomOnionMessageHandler,
195200
{
196201
/// Constructs a new `OnionMessenger` to send, forward, and delegate received onion messages to
197202
/// their respective handlers.
198-
pub fn new(entropy_source: ES, node_signer: NS, logger: L, custom_handler: CMH) -> Self {
203+
pub fn new(
204+
entropy_source: ES, node_signer: NS, logger: L, offers_handler: OMH, custom_handler: CMH
205+
) -> Self {
199206
let mut secp_ctx = Secp256k1::new();
200207
secp_ctx.seeded_randomize(&entropy_source.get_secure_random_bytes());
201208
OnionMessenger {
@@ -204,6 +211,7 @@ impl<ES: Deref, NS: Deref, L: Deref, CMH: Deref> OnionMessenger<ES, NS, L, CMH>
204211
pending_messages: Mutex::new(HashMap::new()),
205212
secp_ctx,
206213
logger,
214+
offers_handler,
207215
custom_handler,
208216
}
209217
}
@@ -298,11 +306,14 @@ fn outbound_buffer_full(peer_node_id: &PublicKey, buffer: &HashMap<PublicKey, Ve
298306
false
299307
}
300308

301-
impl<ES: Deref, NS: Deref, L: Deref, CMH: Deref> OnionMessageHandler for OnionMessenger<ES, NS, L, CMH>
302-
where ES::Target: EntropySource,
303-
NS::Target: NodeSigner,
304-
L::Target: Logger + Sized,
305-
CMH::Target: CustomOnionMessageHandler + Sized,
309+
impl<ES: Deref, NS: Deref, L: Deref, OMH: Deref, CMH: Deref> OnionMessageHandler
310+
for OnionMessenger<ES, NS, L, OMH, CMH>
311+
where
312+
ES::Target: EntropySource,
313+
NS::Target: NodeSigner,
314+
L::Target: Logger,
315+
OMH::Target: OffersMessageHandler,
316+
CMH::Target: CustomOnionMessageHandler + Sized,
306317
{
307318
/// Handle an incoming onion message. Currently, if a message was destined for us we will log, but
308319
/// soon we'll delegate the onion message to a handler that can generate invoices or send
@@ -342,7 +353,7 @@ impl<ES: Deref, NS: Deref, L: Deref, CMH: Deref> OnionMessageHandler for OnionMe
342353
"Received an onion message with path_id {:02x?} and {} reply_path",
343354
path_id, if reply_path.is_some() { "a" } else { "no" });
344355
match message {
345-
OnionMessageContents::Offers(_msg) => todo!(),
356+
OnionMessageContents::Offers(msg) => self.offers_handler.handle_message(msg),
346357
OnionMessageContents::Custom(msg) => self.custom_handler.handle_custom_message(msg),
347358
}
348359
},
@@ -445,11 +456,14 @@ impl<ES: Deref, NS: Deref, L: Deref, CMH: Deref> OnionMessageHandler for OnionMe
445456
}
446457
}
447458

448-
impl<ES: Deref, NS: Deref, L: Deref, CMH: Deref> OnionMessageProvider for OnionMessenger<ES, NS, L, CMH>
449-
where ES::Target: EntropySource,
450-
NS::Target: NodeSigner,
451-
L::Target: Logger,
452-
CMH::Target: CustomOnionMessageHandler,
459+
impl<ES: Deref, NS: Deref, L: Deref, OMH: Deref, CMH: Deref> OnionMessageProvider
460+
for OnionMessenger<ES, NS, L, OMH, CMH>
461+
where
462+
ES::Target: EntropySource,
463+
NS::Target: NodeSigner,
464+
L::Target: Logger,
465+
OMH::Target: OffersMessageHandler,
466+
CMH::Target: CustomOnionMessageHandler,
453467
{
454468
fn next_onion_message_for_peer(&self, peer_node_id: PublicKey) -> Option<msgs::OnionMessage> {
455469
let mut pending_msgs = self.pending_messages.lock().unwrap();
@@ -469,15 +483,28 @@ impl<ES: Deref, NS: Deref, L: Deref, CMH: Deref> OnionMessageProvider for OnionM
469483
///
470484
/// [`SimpleArcChannelManager`]: crate::ln::channelmanager::SimpleArcChannelManager
471485
/// [`SimpleArcPeerManager`]: crate::ln::peer_handler::SimpleArcPeerManager
472-
pub type SimpleArcOnionMessenger<L> = OnionMessenger<Arc<KeysManager>, Arc<KeysManager>, Arc<L>, IgnoringMessageHandler>;
486+
pub type SimpleArcOnionMessenger<L> = OnionMessenger<
487+
Arc<KeysManager>,
488+
Arc<KeysManager>,
489+
Arc<L>,
490+
IgnoringMessageHandler,
491+
IgnoringMessageHandler
492+
>;
493+
473494
/// Useful for simplifying the parameters of [`SimpleRefChannelManager`] and
474495
/// [`SimpleRefPeerManager`]. See their docs for more details.
475496
///
476497
/// This is not exported to bindings users as general type aliases don't make sense in bindings.
477498
///
478499
/// [`SimpleRefChannelManager`]: crate::ln::channelmanager::SimpleRefChannelManager
479500
/// [`SimpleRefPeerManager`]: crate::ln::peer_handler::SimpleRefPeerManager
480-
pub type SimpleRefOnionMessenger<'a, 'b, L> = OnionMessenger<&'a KeysManager, &'a KeysManager, &'b L, IgnoringMessageHandler>;
501+
pub type SimpleRefOnionMessenger<'a, 'b, L> = OnionMessenger<
502+
&'a KeysManager,
503+
&'a KeysManager,
504+
&'b L,
505+
IgnoringMessageHandler,
506+
IgnoringMessageHandler
507+
>;
481508

482509
/// Construct onion packet payloads and keys for sending an onion message along the given
483510
/// `unblinded_path` to the given `destination`.

lightning/src/onion_message/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,5 @@ mod functional_tests;
2828

2929
// Re-export structs so they can be imported with just the `onion_message::` module prefix.
3030
pub use self::messenger::{CustomOnionMessageContents, CustomOnionMessageHandler, Destination, OnionMessageContents, OnionMessenger, SendError, SimpleArcOnionMessenger, SimpleRefOnionMessenger};
31+
pub use self::offers::{OffersMessage, OffersMessageHandler};
3132
pub(crate) use self::packet::{ControlTlvs, Packet};

lightning/src/onion_message/offers.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ const INVOICE_REQUEST_TLV_TYPE: u64 = 64;
2626
const INVOICE_TLV_TYPE: u64 = 66;
2727
const INVOICE_ERROR_TLV_TYPE: u64 = 68;
2828

29+
/// A handler for an [`OnionMessage`] containing a BOLT 12 Offers message as its payload.
30+
///
31+
/// [`OnionMessage`]: crate::ln::msgs::OnionMessage
32+
pub trait OffersMessageHandler {
33+
/// Handles the given message by either responding with an [`Invoice`], sending a payment, or
34+
/// replying with an error.
35+
fn handle_message(&self, message: OffersMessage);
36+
}
37+
2938
/// Possible BOLT 12 Offers messages sent and received via an [`OnionMessage`].
3039
///
3140
/// [`OnionMessage`]: crate::ln::msgs::OnionMessage
@@ -82,7 +91,7 @@ impl Writeable for OffersMessage {
8291
}
8392
}
8493

85-
impl<L: Logger> ReadableArgs<(u64, &L)> for OffersMessage {
94+
impl<L: Logger + ?Sized> ReadableArgs<(u64, &L)> for OffersMessage {
8695
fn read<R: Read>(r: &mut R, read_args: (u64, &L)) -> Result<Self, DecodeError> {
8796
let (tlv_type, logger) = read_args;
8897
if tlv_type == INVOICE_ERROR_TLV_TYPE {

lightning/src/onion_message/packet.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ impl<T: CustomOnionMessageContents> Writeable for (Payload<T>, [u8; 32]) {
203203
}
204204

205205
// Uses the provided secret to simultaneously decode and decrypt the control TLVs and data TLV.
206-
impl<H: CustomOnionMessageHandler, L: Logger>
206+
impl<H: CustomOnionMessageHandler, L: Logger + ?Sized>
207207
ReadableArgs<(SharedSecret, &H, &L)> for Payload<<H as CustomOnionMessageHandler>::CustomMessage> {
208208
fn read<R: Read>(r: &mut R, args: (SharedSecret, &H, &L)) -> Result<Self, DecodeError> {
209209
let (encrypted_tlvs_ss, handler, logger) = args;

0 commit comments

Comments
 (0)