Skip to content

Commit 253ceed

Browse files
committed
Add PaymentId to logging Records
While `PaymentHash`es are great for searching logs, in the case of BOLT 12 the hash isn't selected until well into the payment process. Thus, its important that we allow for filtering by `PaymentId` as well to ensure payment-related logs are always reliably searchable.
1 parent 5e64c40 commit 253ceed

4 files changed

Lines changed: 73 additions & 44 deletions

File tree

lightning/src/ln/channelmanager.rs

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5192,6 +5192,13 @@ where
51925192
let prng_seed = self.entropy_source.get_secure_random_bytes();
51935193
let session_priv = SecretKey::from_slice(&session_priv_bytes[..]).expect("RNG is busted");
51945194

5195+
let logger = WithContext::for_payment(
5196+
&self.logger,
5197+
path.hops.first().map(|hop| hop.pubkey),
5198+
None,
5199+
Some(*payment_hash),
5200+
payment_id,
5201+
);
51955202
let (onion_packet, htlc_msat, htlc_cltv) = onion_utils::create_payment_onion(
51965203
&self.secp_ctx,
51975204
&path,
@@ -5205,8 +5212,6 @@ where
52055212
prng_seed,
52065213
)
52075214
.map_err(|e| {
5208-
let first_hop_key = Some(path.hops.first().unwrap().pubkey);
5209-
let logger = WithContext::from(&self.logger, first_hop_key, None, Some(*payment_hash));
52105215
log_error!(logger, "Failed to build an onion for path");
52115216
e
52125217
})?;
@@ -5217,9 +5222,6 @@ where
52175222

52185223
let (counterparty_node_id, id) = match first_chan {
52195224
None => {
5220-
let first_hop_key = Some(path.hops.first().unwrap().pubkey);
5221-
let logger =
5222-
WithContext::from(&self.logger, first_hop_key, None, Some(*payment_hash));
52235225
log_error!(logger, "Failed to find first-hop for payment hash {payment_hash}");
52245226
return Err(APIError::ChannelUnavailable {
52255227
err: "No channel available with first hop!".to_owned(),
@@ -5228,12 +5230,9 @@ where
52285230
Some((cp_id, chan_id)) => (cp_id, chan_id),
52295231
};
52305232

5231-
let logger = WithContext::from(
5232-
&self.logger,
5233-
Some(counterparty_node_id),
5234-
Some(id),
5235-
Some(*payment_hash),
5236-
);
5233+
// Add the channel id to the logger that already has the rest filled in.
5234+
let logger_ref = &logger;
5235+
let logger = WithContext::from(&logger_ref, None, Some(id), None);
52375236
log_trace!(
52385237
logger,
52395238
"Attempting to send payment along path with next hop {first_chan_scid}"
@@ -5256,11 +5255,6 @@ where
52565255
});
52575256
}
52585257
let funding_txo = chan.funding.get_funding_txo().unwrap();
5259-
let logger = WithChannelContext::from(
5260-
&self.logger,
5261-
&chan.context,
5262-
Some(*payment_hash),
5263-
);
52645258
let htlc_source = HTLCSource::OutboundRoute {
52655259
path: path.clone(),
52665260
session_priv: session_priv.clone(),
@@ -5354,7 +5348,8 @@ where
53545348
});
53555349
if route.route_params.is_none() { route.route_params = Some(route_params.clone()); }
53565350
let router = FixedRouter::new(route);
5357-
let logger = WithContext::from(&self.logger, None, None, Some(payment_hash));
5351+
let logger =
5352+
WithContext::for_payment(&self.logger, None, None, Some(payment_hash), payment_id);
53585353
self.pending_outbound_payments
53595354
.send_payment(payment_hash, recipient_onion, payment_id, Retry::Attempts(0),
53605355
route_params, &&router, self.list_usable_channels(), || self.compute_inflight_htlcs(),
@@ -5419,7 +5414,7 @@ where
54195414
best_block_height,
54205415
&self.pending_events,
54215416
|args| self.send_payment_along_path(args),
5422-
&WithContext::from(&self.logger, None, None, Some(payment_hash)),
5417+
&WithContext::for_payment(&self.logger, None, None, Some(payment_hash), payment_id),
54235418
)
54245419
}
54255420

@@ -5504,6 +5499,7 @@ where
55045499
) -> Result<(), Bolt11PaymentError> {
55055500
let best_block_height = self.best_block.read().unwrap().height;
55065501
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
5502+
let payment_hash = invoice.payment_hash();
55075503
self.pending_outbound_payments.pay_for_bolt11_invoice(
55085504
invoice,
55095505
payment_id,
@@ -5518,7 +5514,7 @@ where
55185514
best_block_height,
55195515
&self.pending_events,
55205516
|args| self.send_payment_along_path(args),
5521-
&WithContext::from(&self.logger, None, None, Some(invoice.payment_hash())),
5517+
&WithContext::for_payment(&self.logger, None, None, Some(payment_hash), payment_id),
55225518
)
55235519
}
55245520

@@ -5571,7 +5567,7 @@ where
55715567
best_block_height,
55725568
&self.pending_events,
55735569
|args| self.send_payment_along_path(args),
5574-
&WithContext::from(&self.logger, None, None, None),
5570+
&WithContext::for_payment(&self.logger, None, None, None, payment_id),
55755571
)
55765572
}
55775573

@@ -5628,6 +5624,7 @@ where
56285624
) -> Result<(), Bolt12PaymentError> {
56295625
let mut res = Ok(());
56305626
PersistenceNotifierGuard::optionally_notify(self, || {
5627+
let logger = WithContext::for_payment(&self.logger, None, None, None, payment_id);
56315628
let best_block_height = self.best_block.read().unwrap().height;
56325629
let features = self.bolt12_invoice_features();
56335630
let outbound_pmts_res = self.pending_outbound_payments.static_invoice_received(
@@ -5660,7 +5657,7 @@ where
56605657
self.send_payment_for_static_invoice_no_persist(payment_id, channels, true)
56615658
{
56625659
log_trace!(
5663-
self.logger,
5660+
logger,
56645661
"Failed to send held HTLC with payment id {}: {:?}",
56655662
payment_id,
56665663
e
@@ -5752,7 +5749,7 @@ where
57525749
best_block_height,
57535750
&self.pending_events,
57545751
|args| self.send_payment_along_path(args),
5755-
&WithContext::from(&self.logger, None, None, None),
5752+
&WithContext::for_payment(&self.logger, None, None, None, payment_id),
57565753
)
57575754
}
57585755

@@ -5846,7 +5843,7 @@ where
58465843
best_block_height,
58475844
&self.pending_events,
58485845
|args| self.send_payment_along_path(args),
5849-
&WithContext::from(&self.logger, None, None, payment_hash),
5846+
&WithContext::for_payment(&self.logger, None, None, payment_hash, payment_id),
58505847
)
58515848
}
58525849

@@ -8652,7 +8649,13 @@ where
86528649
// being fully configured. See the docs for `ChannelManagerReadArgs` for more.
86538650
match source {
86548651
HTLCSource::OutboundRoute { ref path, ref session_priv, ref payment_id, .. } => {
8655-
let logger = WithContext::from(&self.logger, None, None, Some(*payment_hash));
8652+
let logger = WithContext::for_payment(
8653+
&self.logger,
8654+
path.hops.first().map(|hop| hop.pubkey),
8655+
None,
8656+
Some(*payment_hash),
8657+
*payment_id,
8658+
);
86568659
self.pending_outbound_payments.fail_htlc(
86578660
source,
86588661
payment_hash,
@@ -9346,6 +9349,13 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
93469349
counterparty_node_id: path.hops[0].pubkey,
93479350
})
93489351
};
9352+
let logger = WithContext::for_payment(
9353+
&self.logger,
9354+
path.hops.first().map(|hop| hop.pubkey),
9355+
None,
9356+
Some(payment_preimage.into()),
9357+
payment_id,
9358+
);
93499359
self.pending_outbound_payments.claim_htlc(
93509360
payment_id,
93519361
payment_preimage,
@@ -9355,7 +9365,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
93559365
from_onchain,
93569366
&mut ev_completion_action,
93579367
&self.pending_events,
9358-
&WithContext::from(&self.logger, None, None, Some(payment_preimage.into())),
9368+
&logger,
93599369
);
93609370
// If an event was generated, `claim_htlc` set `ev_completion_action` to None, if
93619371
// not, we should go ahead and run it now (as the claim was duplicative), at least
@@ -16118,8 +16128,8 @@ where
1611816128
Err(()) => return None,
1611916129
};
1612016130

16121-
let logger = WithContext::from(
16122-
&self.logger, None, None, Some(invoice.payment_hash()),
16131+
let logger = WithContext::for_payment(
16132+
&self.logger, None, None, Some(invoice.payment_hash()), payment_id,
1612316133
);
1612416134

1612516135
if self.config.read().unwrap().manually_handle_bolt12_invoices {

lightning/src/ln/outbound_payment.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1365,6 +1365,9 @@ impl OutboundPayments {
13651365
}
13661366
core::mem::drop(outbounds);
13671367
if let Some((payment_hash, payment_id, route_params)) = retry_id_route_params {
1368+
let logger =
1369+
WithContext::for_payment(&logger, None, None, Some(payment_hash), payment_id);
1370+
let logger = &logger;
13681371
self.find_route_and_send_payment(
13691372
payment_hash,
13701373
payment_id,
@@ -1810,7 +1813,7 @@ impl OutboundPayments {
18101813
#[rustfmt::skip]
18111814
pub(super) fn send_probe<ES: Deref, NS: Deref, F>(
18121815
&self, path: Path, probing_cookie_secret: [u8; 32], entropy_source: &ES, node_signer: &NS,
1813-
best_block_height: u32, send_payment_along_path: F
1816+
best_block_height: u32, send_payment_along_path: F,
18141817
) -> Result<(PaymentHash, PaymentId), ProbeSendFailure>
18151818
where
18161819
ES::Target: EntropySource,

lightning/src/util/logger.rs

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use core::fmt::Display;
2121
use core::fmt::Write;
2222
use core::ops::Deref;
2323

24+
use crate::ln::channelmanager::PaymentId;
2425
use crate::ln::types::ChannelId;
2526
#[cfg(c_bindings)]
2627
use crate::prelude::*; // Needed for String
@@ -124,12 +125,18 @@ pub struct Record<$($args)?> {
124125
pub file: &'static str,
125126
/// The line containing the message.
126127
pub line: u32,
127-
/// The payment hash. Since payment_hash is not repeated in the message body, include it in the log output so
128-
/// entries remain clear.
128+
/// The payment hash.
129129
///
130-
/// Note that this is only filled in for logs pertaining to a specific payment, and will be
131-
/// `None` for logs which are not directly related to a payment.
130+
/// Since payment_hash is generally not repeated in the message body, you should ensure you log
131+
/// it so that entries remain clear.
132+
///
133+
/// Note that payments don't always have a [`PaymentHash`] immediately - when paying BOLT 12
134+
/// offers the [`PaymentHash`] is only selected a ways into the payment process. Thus, when
135+
/// searching your logs for specific payments you should also search for the relevant
136+
/// [`Self::payment_id`].
132137
pub payment_hash: Option<PaymentHash>,
138+
/// The payment id if the log pertained to a payment with an ID.
139+
pub payment_id: Option<PaymentId>,
133140
}
134141

135142
impl<$($args)?> Record<$($args)?> {
@@ -138,22 +145,22 @@ impl<$($args)?> Record<$($args)?> {
138145
/// This is not exported to bindings users as fmt can't be used in C
139146
#[inline]
140147
pub fn new<$($nonstruct_args)?>(
141-
level: Level, peer_id: Option<PublicKey>, channel_id: Option<ChannelId>,
142-
args: fmt::Arguments<'a>, module_path: &'static str, file: &'static str, line: u32,
143-
payment_hash: Option<PaymentHash>
148+
level: Level, args: fmt::Arguments<'a>, module_path: &'static str, file: &'static str,
149+
line: u32,
144150
) -> Record<$($args)?> {
145151
Record {
146152
level,
147-
peer_id,
148-
channel_id,
153+
peer_id: None,
154+
channel_id: None,
149155
#[cfg(not(c_bindings))]
150156
args,
151157
#[cfg(c_bindings)]
152158
args: format!("{}", args),
153159
module_path,
154160
file,
155161
line,
156-
payment_hash,
162+
payment_hash: None,
163+
payment_id: None,
157164
}
158165
}
159166
}
@@ -295,14 +302,11 @@ pub struct WithContext<'a, L: Deref>
295302
where
296303
L::Target: Logger,
297304
{
298-
/// The logger to delegate to after adding context to the record.
299305
logger: &'a L,
300-
/// The node id of the peer pertaining to the logged record.
301306
peer_id: Option<PublicKey>,
302-
/// The channel id of the channel pertaining to the logged record.
303307
channel_id: Option<ChannelId>,
304-
/// The payment hash of the payment pertaining to the logged record.
305308
payment_hash: Option<PaymentHash>,
309+
payment_id: Option<PaymentId>,
306310
}
307311

308312
impl<'a, L: Deref> Logger for WithContext<'a, L>
@@ -319,6 +323,9 @@ where
319323
if self.payment_hash.is_some() {
320324
record.payment_hash = self.payment_hash;
321325
}
326+
if self.payment_id.is_some() {
327+
record.payment_id = self.payment_id;
328+
}
322329
self.logger.log(record)
323330
}
324331
}
@@ -332,7 +339,16 @@ where
332339
logger: &'a L, peer_id: Option<PublicKey>, channel_id: Option<ChannelId>,
333340
payment_hash: Option<PaymentHash>,
334341
) -> Self {
335-
WithContext { logger, peer_id, channel_id, payment_hash }
342+
WithContext { logger, peer_id, channel_id, payment_hash, payment_id: None }
343+
}
344+
345+
/// Wraps the given logger, providing additional context to any logged records.
346+
pub fn for_payment(
347+
logger: &'a L, peer_id: Option<PublicKey>, channel_id: Option<ChannelId>,
348+
payment_hash: Option<PaymentHash>, payment_id: PaymentId,
349+
) -> Self {
350+
let payment_id = Some(payment_id);
351+
WithContext { logger, peer_id, channel_id, payment_hash, payment_id }
336352
}
337353
}
338354

lightning/src/util/macro_logger.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ macro_rules! log_spendable {
175175
#[macro_export]
176176
macro_rules! log_given_level {
177177
($logger: expr, $lvl:expr, $($arg:tt)+) => (
178-
$logger.log($crate::util::logger::Record::new($lvl, None, None, format_args!($($arg)+), module_path!(), file!(), line!(), None))
178+
$logger.log($crate::util::logger::Record::new($lvl, format_args!($($arg)+), module_path!(), file!(), line!()))
179179
);
180180
}
181181

0 commit comments

Comments
 (0)