Skip to content

Commit e8f154d

Browse files
AsyncPaymentsMessageHandler trait for OnionMessenger
Add a trait for handling async payments messages to OnionMessenger. This allows users to either provide their own custom handling for async payments messages or rely on a version provided by LDK.
1 parent 445ec8d commit e8f154d

File tree

7 files changed

+136
-25
lines changed

7 files changed

+136
-25
lines changed

fuzz/src/onion_message.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ use lightning::ln::msgs::{self, DecodeError, OnionMessageHandler};
1212
use lightning::ln::script::ShutdownScript;
1313
use lightning::offers::invoice::UnsignedBolt12Invoice;
1414
use lightning::offers::invoice_request::UnsignedInvoiceRequest;
15+
use lightning::onion_message::async_payments::{
16+
AsyncPaymentsMessage, AsyncPaymentsMessageHandler, HeldHtlcAvailable, ReleaseHeldHtlc,
17+
};
1518
use lightning::onion_message::messenger::{
1619
CustomOnionMessageHandler, Destination, MessageRouter, OnionMessagePath, OnionMessenger,
1720
PendingOnionMessage, Responder, ResponseInstruction,
@@ -39,6 +42,7 @@ pub fn do_test<L: Logger>(data: &[u8], logger: &L) {
3942
let node_id_lookup = EmptyNodeIdLookUp {};
4043
let message_router = TestMessageRouter {};
4144
let offers_msg_handler = TestOffersMessageHandler {};
45+
let async_payments_msg_handler = TestAsyncPaymentsMessageHandler {};
4246
let custom_msg_handler = TestCustomMessageHandler {};
4347
let onion_messenger = OnionMessenger::new(
4448
&keys_manager,
@@ -47,6 +51,7 @@ pub fn do_test<L: Logger>(data: &[u8], logger: &L) {
4751
&node_id_lookup,
4852
&message_router,
4953
&offers_msg_handler,
54+
&async_payments_msg_handler,
5055
&custom_msg_handler,
5156
);
5257

@@ -105,6 +110,17 @@ impl OffersMessageHandler for TestOffersMessageHandler {
105110
}
106111
}
107112

113+
struct TestAsyncPaymentsMessageHandler {}
114+
115+
impl AsyncPaymentsMessageHandler for TestAsyncPaymentsMessageHandler {
116+
fn held_htlc_available(
117+
&self, _message: HeldHtlcAvailable, _responder: Option<Responder>,
118+
) -> ResponseInstruction<ReleaseHeldHtlc> {
119+
ResponseInstruction::NoResponse
120+
}
121+
fn release_held_htlc(&self, _message: ReleaseHeldHtlc) {}
122+
}
123+
108124
#[derive(Debug)]
109125
struct TestCustomMessage {}
110126

lightning-background-processor/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ use core::task;
568568
/// # type NetworkGraph = lightning::routing::gossip::NetworkGraph<Arc<Logger>>;
569569
/// # type P2PGossipSync<UL> = lightning::routing::gossip::P2PGossipSync<Arc<NetworkGraph>, Arc<UL>, Arc<Logger>>;
570570
/// # type ChannelManager<B, F, FE> = lightning::ln::channelmanager::SimpleArcChannelManager<ChainMonitor<B, F, FE>, B, FE, Logger>;
571-
/// # type OnionMessenger<B, F, FE> = lightning::onion_message::messenger::OnionMessenger<Arc<lightning::sign::KeysManager>, Arc<lightning::sign::KeysManager>, Arc<Logger>, Arc<ChannelManager<B, F, FE>>, Arc<lightning::onion_message::messenger::DefaultMessageRouter<Arc<NetworkGraph>, Arc<Logger>, Arc<lightning::sign::KeysManager>>>, Arc<ChannelManager<B, F, FE>>, lightning::ln::peer_handler::IgnoringMessageHandler>;
571+
/// # type OnionMessenger<B, F, FE> = lightning::onion_message::messenger::OnionMessenger<Arc<lightning::sign::KeysManager>, Arc<lightning::sign::KeysManager>, Arc<Logger>, Arc<ChannelManager<B, F, FE>>, Arc<lightning::onion_message::messenger::DefaultMessageRouter<Arc<NetworkGraph>, Arc<Logger>, Arc<lightning::sign::KeysManager>>>, Arc<ChannelManager<B, F, FE>>, lightning::ln::peer_handler::IgnoringMessageHandler, lightning::ln::peer_handler::IgnoringMessageHandler>;
572572
/// # type Scorer = RwLock<lightning::routing::scoring::ProbabilisticScorer<Arc<NetworkGraph>, Arc<Logger>>>;
573573
/// # type PeerManager<B, F, FE, UL> = lightning::ln::peer_handler::SimpleArcPeerManager<SocketDescriptor, ChainMonitor<B, F, FE>, B, FE, Arc<UL>, Logger>;
574574
/// #
@@ -996,7 +996,7 @@ mod tests {
996996
type PGS = Arc<P2PGossipSync<Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>>;
997997
type RGS = Arc<RapidGossipSync<Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, Arc<test_utils::TestLogger>>>;
998998

999-
type OM = OnionMessenger<Arc<KeysManager>, Arc<KeysManager>, Arc<test_utils::TestLogger>, Arc<ChannelManager>, Arc<DefaultMessageRouter<Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, Arc<test_utils::TestLogger>, Arc<KeysManager>>>, IgnoringMessageHandler, IgnoringMessageHandler>;
999+
type OM = OnionMessenger<Arc<KeysManager>, Arc<KeysManager>, Arc<test_utils::TestLogger>, Arc<ChannelManager>, Arc<DefaultMessageRouter<Arc<NetworkGraph<Arc<test_utils::TestLogger>>>, Arc<test_utils::TestLogger>, Arc<KeysManager>>>, IgnoringMessageHandler, IgnoringMessageHandler, IgnoringMessageHandler>;
10001000

10011001
struct Node {
10021002
node: Arc<ChannelManager>,
@@ -1291,7 +1291,7 @@ mod tests {
12911291
let best_block = BestBlock::from_network(network);
12921292
let params = ChainParameters { network, best_block };
12931293
let manager = Arc::new(ChannelManager::new(fee_estimator.clone(), chain_monitor.clone(), tx_broadcaster.clone(), router.clone(), logger.clone(), keys_manager.clone(), keys_manager.clone(), keys_manager.clone(), UserConfig::default(), params, genesis_block.header.time));
1294-
let messenger = Arc::new(OnionMessenger::new(keys_manager.clone(), keys_manager.clone(), logger.clone(), manager.clone(), msg_router.clone(), IgnoringMessageHandler {}, IgnoringMessageHandler {}));
1294+
let messenger = Arc::new(OnionMessenger::new(keys_manager.clone(), keys_manager.clone(), logger.clone(), manager.clone(), msg_router.clone(), IgnoringMessageHandler {}, IgnoringMessageHandler {}, IgnoringMessageHandler {}));
12951295
let wallet = Arc::new(TestWallet {});
12961296
let sweeper = Arc::new(OutputSweeper::new(best_block, Arc::clone(&tx_broadcaster), Arc::clone(&fee_estimator),
12971297
None::<Arc<dyn Filter + Sync + Send>>, Arc::clone(&keys_manager), wallet, Arc::clone(&kv_store), Arc::clone(&logger)));

lightning/src/ln/functional_test_utils.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ type TestOnionMessenger<'chan_man, 'node_cfg, 'chan_mon_cfg> = OnionMessenger<
421421
&'node_cfg test_utils::TestMessageRouter<'chan_mon_cfg>,
422422
&'chan_man TestChannelManager<'node_cfg, 'chan_mon_cfg>,
423423
IgnoringMessageHandler,
424+
IgnoringMessageHandler,
424425
>;
425426

426427
/// For use with [`OnionMessenger`] otherwise `test_restored_packages_retry` will fail. This is
@@ -3228,7 +3229,7 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
32283229
let dedicated_entropy = DedicatedEntropy(RandomBytes::new([i as u8; 32]));
32293230
let onion_messenger = OnionMessenger::new(
32303231
dedicated_entropy, cfgs[i].keys_manager, cfgs[i].logger, &chan_mgrs[i],
3231-
&cfgs[i].message_router, &chan_mgrs[i], IgnoringMessageHandler {},
3232+
&cfgs[i].message_router, &chan_mgrs[i], IgnoringMessageHandler {}, IgnoringMessageHandler {},
32323233
);
32333234
let gossip_sync = P2PGossipSync::new(cfgs[i].network_graph.as_ref(), None, cfgs[i].logger);
32343235
let wallet_source = Arc::new(test_utils::TestWalletSource::new(SecretKey::from_slice(&[i as u8 + 1; 32]).unwrap()));

lightning/src/ln/peer_handler.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use crate::util::ser::{VecWriter, Writeable, Writer};
2828
use crate::ln::peer_channel_encryptor::{PeerChannelEncryptor, NextNoiseStep, MessageBuf, MSG_BUF_ALLOC_SIZE};
2929
use crate::ln::wire;
3030
use crate::ln::wire::{Encode, Type};
31+
use crate::onion_message::async_payments::{AsyncPaymentsMessageHandler, HeldHtlcAvailable, ReleaseHeldHtlc};
3132
use crate::onion_message::messenger::{CustomOnionMessageHandler, PendingOnionMessage, Responder, ResponseInstruction};
3233
use crate::onion_message::offers::{OffersMessage, OffersMessageHandler};
3334
use crate::onion_message::packet::OnionMessageContents;
@@ -148,6 +149,14 @@ impl OffersMessageHandler for IgnoringMessageHandler {
148149
ResponseInstruction::NoResponse
149150
}
150151
}
152+
impl AsyncPaymentsMessageHandler for IgnoringMessageHandler {
153+
fn held_htlc_available(
154+
&self, _message: HeldHtlcAvailable, _responder: Option<Responder>,
155+
) -> ResponseInstruction<ReleaseHeldHtlc> {
156+
ResponseInstruction::NoResponse
157+
}
158+
fn release_held_htlc(&self, _message: ReleaseHeldHtlc) {}
159+
}
151160
impl CustomOnionMessageHandler for IgnoringMessageHandler {
152161
type CustomMessage = Infallible;
153162
fn handle_custom_message(&self, _message: Self::CustomMessage, _responder: Option<Responder>) -> ResponseInstruction<Self::CustomMessage> {

lightning/src/onion_message/async_payments.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,55 @@
1111
1212
use crate::io;
1313
use crate::ln::msgs::DecodeError;
14+
use crate::onion_message::messenger::PendingOnionMessage;
15+
use crate::onion_message::messenger::{Responder, ResponseInstruction};
1416
use crate::onion_message::packet::OnionMessageContents;
17+
use crate::prelude::*;
1518
use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer};
1619

1720
// TLV record types for the `onionmsg_tlv` TLV stream as defined in BOLT 4.
1821
const HELD_HTLC_AVAILABLE_TLV_TYPE: u64 = 72;
1922
const RELEASE_HELD_HTLC_TLV_TYPE: u64 = 74;
2023

24+
/// A handler for an [`OnionMessage`] containing an async payments message as its payload.
25+
///
26+
/// [`OnionMessage`]: crate::ln::msgs::OnionMessage
27+
pub trait AsyncPaymentsMessageHandler {
28+
/// Handle a [`HeldHtlcAvailable`] message. A [`ReleaseHeldHtlc`] should be returned to release
29+
/// the held funds.
30+
fn held_htlc_available(
31+
&self, message: HeldHtlcAvailable, responder: Option<Responder>,
32+
) -> ResponseInstruction<ReleaseHeldHtlc>;
33+
34+
/// Handle a [`ReleaseHeldHtlc`] message. If authentication of the message succeeds, an HTLC
35+
/// should be released to the corresponding payee.
36+
fn release_held_htlc(&self, message: ReleaseHeldHtlc);
37+
38+
/// Release any [`AsyncPaymentsMessage`]s that need to be sent.
39+
///
40+
/// Typically, this is used for messages initiating an async payment flow rather than in response
41+
/// to another message.
42+
#[cfg(not(c_bindings))]
43+
fn release_pending_messages(&self) -> Vec<PendingOnionMessage<AsyncPaymentsMessage>> {
44+
vec![]
45+
}
46+
47+
/// Release any [`AsyncPaymentsMessage`]s that need to be sent.
48+
///
49+
/// Typically, this is used for messages initiating a payment flow rather than in response to
50+
/// another message.
51+
#[cfg(c_bindings)]
52+
fn release_pending_messages(
53+
&self,
54+
) -> Vec<(
55+
AsyncPaymentsMessage,
56+
crate::onion_message::messenger::Destination,
57+
Option<crate::blinded_path::BlindedPath>,
58+
)> {
59+
vec![]
60+
}
61+
}
62+
2163
/// Possible async payment messages sent and received via an [`OnionMessage`].
2264
///
2365
/// [`OnionMessage`]: crate::ln::msgs::OnionMessage

lightning/src/onion_message/functional_tests.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use crate::routing::test_utils::{add_channel, add_or_update_node};
1919
use crate::sign::{NodeSigner, Recipient};
2020
use crate::util::ser::{FixedLengthReader, LengthReadable, Writeable, Writer};
2121
use crate::util::test_utils;
22+
use super::async_payments::{AsyncPaymentsMessageHandler, HeldHtlcAvailable, ReleaseHeldHtlc};
2223
use super::messenger::{CustomOnionMessageHandler, DefaultMessageRouter, Destination, OnionMessagePath, OnionMessenger, PendingOnionMessage, Responder, ResponseInstruction, SendError, SendSuccess};
2324
use super::offers::{OffersMessage, OffersMessageHandler};
2425
use super::packet::{OnionMessageContents, Packet};
@@ -50,6 +51,7 @@ struct MessengerNode {
5051
Arc<test_utils::TestKeysInterface>
5152
>>,
5253
Arc<TestOffersMessageHandler>,
54+
Arc<TestAsyncPaymentsMessageHandler>,
5355
Arc<TestCustomMessageHandler>
5456
>,
5557
custom_message_handler: Arc<TestCustomMessageHandler>,
@@ -79,6 +81,17 @@ impl OffersMessageHandler for TestOffersMessageHandler {
7981
}
8082
}
8183

84+
struct TestAsyncPaymentsMessageHandler {}
85+
86+
impl AsyncPaymentsMessageHandler for TestAsyncPaymentsMessageHandler {
87+
fn held_htlc_available(
88+
&self, _message: HeldHtlcAvailable, _responder: Option<Responder>,
89+
) -> ResponseInstruction<ReleaseHeldHtlc> {
90+
ResponseInstruction::NoResponse
91+
}
92+
fn release_held_htlc(&self, _message: ReleaseHeldHtlc) {}
93+
}
94+
8295
#[derive(Clone, Debug, PartialEq)]
8396
enum TestCustomMessage {
8497
Ping,
@@ -249,18 +262,19 @@ fn create_nodes_using_cfgs(cfgs: Vec<MessengerCfg>) -> Vec<MessengerNode> {
249262
DefaultMessageRouter::new(network_graph.clone(), entropy_source.clone())
250263
);
251264
let offers_message_handler = Arc::new(TestOffersMessageHandler {});
265+
let async_payments_message_handler = Arc::new(TestAsyncPaymentsMessageHandler {});
252266
let custom_message_handler = Arc::new(TestCustomMessageHandler::new());
253267
let messenger = if cfg.intercept_offline_peer_oms {
254268
OnionMessenger::new_with_offline_peer_interception(
255269
entropy_source.clone(), node_signer.clone(), logger.clone(),
256270
node_id_lookup, message_router, offers_message_handler,
257-
custom_message_handler.clone()
271+
async_payments_message_handler, custom_message_handler.clone()
258272
)
259273
} else {
260274
OnionMessenger::new(
261275
entropy_source.clone(), node_signer.clone(), logger.clone(),
262276
node_id_lookup, message_router, offers_message_handler,
263-
custom_message_handler.clone()
277+
async_payments_message_handler, custom_message_handler.clone()
264278
)
265279
};
266280
nodes.push(MessengerNode {

0 commit comments

Comments
 (0)