Skip to content

Commit 3a1d74a

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 6e0799b commit 3a1d74a

File tree

6 files changed

+135
-36
lines changed

6 files changed

+135
-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: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use crate::util::ser::{VecWriter, Writeable, Writer};
2727
use crate::ln::peer_channel_encryptor::{PeerChannelEncryptor,NextNoiseStep};
2828
use crate::ln::wire;
2929
use crate::ln::wire::Encode;
30-
use crate::onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, SimpleArcOnionMessenger, SimpleRefOnionMessenger};
30+
use crate::onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, OffersMessage, OffersMessageHandler, SimpleArcOnionMessenger, SimpleRefOnionMessenger};
3131
use crate::routing::gossip::{NetworkGraph, P2PGossipSync, NodeId, NodeAlias};
3232
use crate::util::atomic_counter::AtomicCounter;
3333
use crate::util::logger::Logger;
@@ -102,6 +102,9 @@ impl OnionMessageHandler for IgnoringMessageHandler {
102102
InitFeatures::empty()
103103
}
104104
}
105+
impl OffersMessageHandler for IgnoringMessageHandler {
106+
fn handle_message(&self, _msg: OffersMessage) {}
107+
}
105108
impl CustomOnionMessageHandler for IgnoringMessageHandler {
106109
type CustomMessage = Infallible;
107110
fn handle_custom_message(&self, _msg: Infallible) {
@@ -575,7 +578,15 @@ impl Peer {
575578
/// issues such as overly long function definitions.
576579
///
577580
/// This is not exported to bindings users as `Arc`s don't make sense in bindings.
578-
pub type SimpleArcPeerManager<SD, M, T, F, C, L> = PeerManager<SD, Arc<SimpleArcChannelManager<M, T, F, L>>, Arc<P2PGossipSync<Arc<NetworkGraph<Arc<L>>>, Arc<C>, Arc<L>>>, Arc<SimpleArcOnionMessenger<L>>, Arc<L>, IgnoringMessageHandler, Arc<KeysManager>>;
581+
pub type SimpleArcPeerManager<SD, M, T, F, C, L> = PeerManager<
582+
SD,
583+
Arc<SimpleArcChannelManager<M, T, F, L>>,
584+
Arc<P2PGossipSync<Arc<NetworkGraph<Arc<L>>>, Arc<C>, Arc<L>>>,
585+
Arc<SimpleArcOnionMessenger<M, T, F, L>>,
586+
Arc<L>,
587+
IgnoringMessageHandler,
588+
Arc<KeysManager>
589+
>;
579590

580591
/// SimpleRefPeerManager is a type alias for a PeerManager reference, and is the reference
581592
/// counterpart to the SimpleArcPeerManager type alias. Use this type by default when you don't
@@ -585,7 +596,15 @@ pub type SimpleArcPeerManager<SD, M, T, F, C, L> = PeerManager<SD, Arc<SimpleArc
585596
/// helps with issues such as long function definitions.
586597
///
587598
/// This is not exported to bindings users as general type aliases don't make sense in bindings.
588-
pub type SimpleRefPeerManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, SD, M, T, F, C, L> = PeerManager<SD, SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'm, M, T, F, L>, &'f P2PGossipSync<&'g NetworkGraph<&'f L>, &'h C, &'f L>, &'i SimpleRefOnionMessenger<'j, 'k, L>, &'f L, IgnoringMessageHandler, &'c KeysManager>;
599+
pub type SimpleRefPeerManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, 'n, SD, M, T, F, C, L> = PeerManager<
600+
SD,
601+
&'n SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'm, M, T, F, L>,
602+
&'f P2PGossipSync<&'g NetworkGraph<&'f L>, &'h C, &'f L>,
603+
&'i SimpleRefOnionMessenger<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'm, 'n, M, T, F, L>,
604+
&'f L,
605+
IgnoringMessageHandler,
606+
&'c KeysManager
607+
>;
589608

590609

591610
/// A generic trait which is implemented for all [`PeerManager`]s. This makes bounding functions or

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: 56 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@ use bitcoin::secp256k1::{self, PublicKey, Scalar, Secp256k1, SecretKey};
1818
use crate::blinded_path::{BlindedPath, ForwardTlvs, ReceiveTlvs, utils};
1919
use crate::sign::{EntropySource, KeysManager, NodeSigner, Recipient};
2020
use crate::events::OnionMessageProvider;
21+
use crate::ln::channelmanager::{SimpleArcChannelManager, SimpleRefChannelManager};
2122
use crate::ln::features::{InitFeatures, NodeFeatures};
2223
use crate::ln::msgs::{self, OnionMessageHandler};
2324
use crate::ln::onion_utils;
2425
use crate::ln::peer_handler::IgnoringMessageHandler;
2526
pub use super::packet::{CustomOnionMessageContents, OnionMessageContents};
27+
use super::offers::OffersMessageHandler;
2628
use super::packet::{BIG_PACKET_HOP_DATA_LEN, ForwardControlTlvs, Packet, Payload, ReceiveControlTlvs, SMALL_PACKET_HOP_DATA_LEN};
2729
use crate::util::logger::Logger;
2830
use crate::util::ser::Writeable;
@@ -63,10 +65,11 @@ use crate::prelude::*;
6365
/// # let hop_node_id1 = PublicKey::from_secret_key(&secp_ctx, &node_secret);
6466
/// # let (hop_node_id2, hop_node_id3, hop_node_id4) = (hop_node_id1, hop_node_id1, hop_node_id1);
6567
/// # let destination_node_id = hop_node_id1;
66-
/// # let your_custom_message_handler = IgnoringMessageHandler {};
68+
/// # let custom_message_handler = IgnoringMessageHandler {};
69+
/// # let offers_message_handler = IgnoringMessageHandler {};
6770
/// // Create the onion messenger. This must use the same `keys_manager` as is passed to your
6871
/// // ChannelManager.
69-
/// let onion_messenger = OnionMessenger::new(&keys_manager, &keys_manager, logger, &your_custom_message_handler);
72+
/// let onion_messenger = OnionMessenger::new(&keys_manager, &keys_manager, logger, &offers_message_handler, &custom_message_handler);
7073
///
7174
/// # struct YourCustomMessage {}
7275
/// impl Writeable for YourCustomMessage {
@@ -103,20 +106,21 @@ use crate::prelude::*;
103106
///
104107
/// [offers]: <https://github.com/lightning/bolts/pull/798>
105108
/// [`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,
109+
pub struct OnionMessenger<ES: Deref, NS: Deref, L: Deref, OMH: Deref, CMH: Deref>
110+
where
111+
ES::Target: EntropySource,
112+
NS::Target: NodeSigner,
113+
L::Target: Logger,
114+
OMH::Target: OffersMessageHandler,
115+
CMH:: Target: CustomOnionMessageHandler,
111116
{
112117
entropy_source: ES,
113118
node_signer: NS,
114119
logger: L,
115120
pending_messages: Mutex<HashMap<PublicKey, VecDeque<msgs::OnionMessage>>>,
116121
secp_ctx: Secp256k1<secp256k1::All>,
122+
offers_handler: OMH,
117123
custom_handler: CMH,
118-
// Coming soon:
119-
// invoice_handler: InvoiceHandler,
120124
}
121125

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

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,
194+
impl<ES: Deref, NS: Deref, L: Deref, OMH: Deref, CMH: Deref> OnionMessenger<ES, NS, L, OMH, CMH>
195+
where
196+
ES::Target: EntropySource,
197+
NS::Target: NodeSigner,
198+
L::Target: Logger,
199+
OMH::Target: OffersMessageHandler,
200+
CMH::Target: CustomOnionMessageHandler,
195201
{
196202
/// Constructs a new `OnionMessenger` to send, forward, and delegate received onion messages to
197203
/// their respective handlers.
198-
pub fn new(entropy_source: ES, node_signer: NS, logger: L, custom_handler: CMH) -> Self {
204+
pub fn new(
205+
entropy_source: ES, node_signer: NS, logger: L, offers_handler: OMH, custom_handler: CMH
206+
) -> Self {
199207
let mut secp_ctx = Secp256k1::new();
200208
secp_ctx.seeded_randomize(&entropy_source.get_secure_random_bytes());
201209
OnionMessenger {
@@ -204,6 +212,7 @@ impl<ES: Deref, NS: Deref, L: Deref, CMH: Deref> OnionMessenger<ES, NS, L, CMH>
204212
pending_messages: Mutex::new(HashMap::new()),
205213
secp_ctx,
206214
logger,
215+
offers_handler,
207216
custom_handler,
208217
}
209218
}
@@ -298,11 +307,14 @@ fn outbound_buffer_full(peer_node_id: &PublicKey, buffer: &HashMap<PublicKey, Ve
298307
false
299308
}
300309

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,
305-
CMH::Target: CustomOnionMessageHandler + Sized,
310+
impl<ES: Deref, NS: Deref, L: Deref, OMH: Deref, CMH: Deref> OnionMessageHandler
311+
for OnionMessenger<ES, NS, L, OMH, CMH>
312+
where
313+
ES::Target: EntropySource,
314+
NS::Target: NodeSigner,
315+
L::Target: Logger,
316+
OMH::Target: OffersMessageHandler,
317+
CMH::Target: CustomOnionMessageHandler + Sized,
306318
{
307319
/// Handle an incoming onion message. Currently, if a message was destined for us we will log, but
308320
/// soon we'll delegate the onion message to a handler that can generate invoices or send
@@ -341,7 +353,7 @@ impl<ES: Deref, NS: Deref, L: Deref, CMH: Deref> OnionMessageHandler for OnionMe
341353
"Received an onion message with path_id {:02x?} and {} reply_path",
342354
path_id, if reply_path.is_some() { "a" } else { "no" });
343355
match message {
344-
OnionMessageContents::Offers(_msg) => todo!(),
356+
OnionMessageContents::Offers(msg) => self.offers_handler.handle_message(msg),
345357
OnionMessageContents::Custom(msg) => self.custom_handler.handle_custom_message(msg),
346358
}
347359
},
@@ -444,11 +456,14 @@ impl<ES: Deref, NS: Deref, L: Deref, CMH: Deref> OnionMessageHandler for OnionMe
444456
}
445457
}
446458

447-
impl<ES: Deref, NS: Deref, L: Deref, CMH: Deref> OnionMessageProvider for OnionMessenger<ES, NS, L, CMH>
448-
where ES::Target: EntropySource,
449-
NS::Target: NodeSigner,
450-
L::Target: Logger,
451-
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,
452467
{
453468
fn next_onion_message_for_peer(&self, peer_node_id: PublicKey) -> Option<msgs::OnionMessage> {
454469
let mut pending_msgs = self.pending_messages.lock().unwrap();
@@ -468,15 +483,28 @@ impl<ES: Deref, NS: Deref, L: Deref, CMH: Deref> OnionMessageProvider for OnionM
468483
///
469484
/// [`SimpleArcChannelManager`]: crate::ln::channelmanager::SimpleArcChannelManager
470485
/// [`SimpleArcPeerManager`]: crate::ln::peer_handler::SimpleArcPeerManager
471-
pub type SimpleArcOnionMessenger<L> = OnionMessenger<Arc<KeysManager>, Arc<KeysManager>, Arc<L>, IgnoringMessageHandler>;
486+
pub type SimpleArcOnionMessenger<M, T, F, L> = OnionMessenger<
487+
Arc<KeysManager>,
488+
Arc<KeysManager>,
489+
Arc<L>,
490+
Arc<SimpleArcChannelManager<M, T, F, L>>,
491+
IgnoringMessageHandler
492+
>;
493+
472494
/// Useful for simplifying the parameters of [`SimpleRefChannelManager`] and
473495
/// [`SimpleRefPeerManager`]. See their docs for more details.
474496
///
475497
/// This is not exported to bindings users as general type aliases don't make sense in bindings.
476498
///
477499
/// [`SimpleRefChannelManager`]: crate::ln::channelmanager::SimpleRefChannelManager
478500
/// [`SimpleRefPeerManager`]: crate::ln::peer_handler::SimpleRefPeerManager
479-
pub type SimpleRefOnionMessenger<'a, 'b, L> = OnionMessenger<&'a KeysManager, &'a KeysManager, &'b L, IgnoringMessageHandler>;
501+
pub type SimpleRefOnionMessenger<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, M, T, F, L> = OnionMessenger<
502+
&'c KeysManager,
503+
&'c KeysManager,
504+
&'g L,
505+
&'i SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, M, T, F, L>,
506+
IgnoringMessageHandler
507+
>;
480508

481509
/// Construct onion packet payloads and keys for sending an onion message along the given
482510
/// `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: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,18 @@
1010
//! Message handling for BOLT 12 Offers.
1111
1212
use core::convert::TryFrom;
13+
use core::ops::Deref;
14+
use crate::chain;
15+
use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator};
1316
use crate::io::{self, Read};
17+
use crate::ln::channelmanager::ChannelManager;
1418
use crate::ln::msgs::DecodeError;
1519
use crate::offers::invoice_request::InvoiceRequest;
1620
use crate::offers::invoice::Invoice;
1721
use crate::offers::parse::ParseError;
22+
use crate::routing::router::Router;
23+
use crate::sign::{EntropySource, NodeSigner, SignerProvider};
24+
use crate::util::logger::Logger;
1825
use crate::util::ser::{ReadableArgs, Writeable, Writer};
1926

2027
use crate::prelude::*;
@@ -24,6 +31,15 @@ const INVOICE_REQUEST_TLV_TYPE: u64 = 64;
2431
const INVOICE_TLV_TYPE: u64 = 66;
2532
const INVOICE_ERROR_TLV_TYPE: u64 = 68;
2633

34+
/// A handler for an [`OnionMessage`] containing a BOLT 12 Offers message as its payload.
35+
///
36+
/// [`OnionMessage`]: crate::ln::msgs::OnionMessage
37+
pub trait OffersMessageHandler {
38+
/// Handles the given message by either responding with an [`Invoice`], sending a payment, or
39+
/// replying with an error.
40+
fn handle_message(&self, message: OffersMessage);
41+
}
42+
2743
/// Possible BOLT 12 Offers messages sent and received via an [`OnionMessage`].
2844
///
2945
/// [`OnionMessage`]: crate::ln::msgs::OnionMessage
@@ -93,3 +109,20 @@ impl ReadableArgs<u64> for OffersMessage {
93109
}
94110
}
95111
}
112+
113+
impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref>
114+
OffersMessageHandler for ChannelManager<M, T, ES, NS, SP, F, R, L>
115+
where
116+
M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
117+
T::Target: BroadcasterInterface,
118+
ES::Target: EntropySource,
119+
NS::Target: NodeSigner,
120+
SP::Target: SignerProvider,
121+
F::Target: FeeEstimator,
122+
R::Target: Router,
123+
L::Target: Logger,
124+
{
125+
fn handle_message(&self, _message: OffersMessage) {
126+
todo!()
127+
}
128+
}

0 commit comments

Comments
 (0)