Skip to content

Commit 7c02ca2

Browse files
committed
Refactor initiate_async_payment to improve separation of concerns
1. Previously, `initiate_async_payment` handled both the outbound payment state update (marking a static invoice as received) and the message queuing for async payments. This tightly coupled two distinct responsibilities within `ChannelManager`. 2. This refactor **separates concerns** by moving message queuing into a separate function, allowing `initiate_async_payment` to focus solely on updating `pending_outbound_payments`. This paves the way for moving message queuing to `flow.rs` in upcoming commits, ensuring `MessageRouter` logic remains independent of `ChannelManager`. 3. **This introduces a behavior change:** Since `pending_outbound_payments` is now handled separately, we drop PersistenceNotifierGuard before queuing messages. As a result, `NotifyOption` is no longer called for the message queuing process. 4. **Why is this safe?** Because `pending_async_payments_messages` is **not under `total_consistency_lock`**, meaning it does not require persistence notifications. This aligns with the lock order tree and maintains correct locking discipline. By making this change, we improve modularity, enforce a cleaner separation between `ChannelManager` and `MessageRouter`, and remove unnecessary persistence dependencies.
1 parent 4457ca0 commit 7c02ca2

File tree

1 file changed

+40
-32
lines changed

1 file changed

+40
-32
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4480,7 +4480,7 @@ where
44804480
}
44814481

44824482
#[cfg(async_payments)]
4483-
fn initiate_async_payment(
4483+
fn handle_static_invoice_received(
44844484
&self, invoice: &StaticInvoice, payment_id: PaymentId
44854485
) -> Result<(), Bolt12PaymentError> {
44864486
let mut res = Ok(());
@@ -4502,43 +4502,51 @@ where
45024502
return NotifyOption::DoPersist
45034503
}
45044504
};
4505-
4506-
let nonce = Nonce::from_entropy_source(&*self.entropy_source);
4507-
let hmac = payment_id.hmac_for_async_payment(nonce, &self.inbound_payment_key);
4508-
let reply_paths = match self.create_blinded_paths(
4509-
MessageContext::AsyncPayments(
4510-
AsyncPaymentsContext::OutboundPayment { payment_id, nonce, hmac }
4511-
)
4512-
) {
4513-
Ok(paths) => paths,
4514-
Err(()) => {
4515-
self.abandon_payment_with_reason(payment_id, PaymentFailureReason::BlindedPathCreationFailed);
4516-
res = Err(Bolt12PaymentError::BlindedPathCreationFailed);
4517-
return NotifyOption::DoPersist
4518-
}
4519-
};
4520-
4521-
let mut pending_async_payments_messages = self.pending_async_payments_messages.lock().unwrap();
4522-
const HTLC_AVAILABLE_LIMIT: usize = 10;
4523-
reply_paths
4524-
.iter()
4525-
.flat_map(|reply_path| invoice.message_paths().iter().map(move |invoice_path| (invoice_path, reply_path)))
4526-
.take(HTLC_AVAILABLE_LIMIT)
4527-
.for_each(|(invoice_path, reply_path)| {
4528-
let instructions = MessageSendInstructions::WithSpecifiedReplyPath {
4529-
destination: Destination::BlindedPath(invoice_path.clone()),
4530-
reply_path: reply_path.clone(),
4531-
};
4532-
let message = AsyncPaymentsMessage::HeldHtlcAvailable(HeldHtlcAvailable {});
4533-
pending_async_payments_messages.push((message, instructions));
4534-
});
4535-
45364505
NotifyOption::DoPersist
45374506
});
45384507

45394508
res
45404509
}
45414510

4511+
#[cfg(async_payments)]
4512+
fn initiate_async_payment(
4513+
&self, invoice: &StaticInvoice, payment_id: PaymentId
4514+
) -> Result<(), Bolt12PaymentError> {
4515+
4516+
self.handle_static_invoice_received(invoice, payment_id)?;
4517+
4518+
let nonce = Nonce::from_entropy_source(&*self.entropy_source);
4519+
let hmac = payment_id.hmac_for_async_payment(nonce, &self.inbound_payment_key);
4520+
let reply_paths = match self.create_blinded_paths(
4521+
MessageContext::AsyncPayments(
4522+
AsyncPaymentsContext::OutboundPayment { payment_id, nonce, hmac }
4523+
)
4524+
) {
4525+
Ok(paths) => paths,
4526+
Err(()) => {
4527+
self.abandon_payment_with_reason(payment_id, PaymentFailureReason::BlindedPathCreationFailed);
4528+
return Err(Bolt12PaymentError::BlindedPathCreationFailed);
4529+
}
4530+
};
4531+
4532+
let mut pending_async_payments_messages = self.pending_async_payments_messages.lock().unwrap();
4533+
const HTLC_AVAILABLE_LIMIT: usize = 10;
4534+
reply_paths
4535+
.iter()
4536+
.flat_map(|reply_path| invoice.message_paths().iter().map(move |invoice_path| (invoice_path, reply_path)))
4537+
.take(HTLC_AVAILABLE_LIMIT)
4538+
.for_each(|(invoice_path, reply_path)| {
4539+
let instructions = MessageSendInstructions::WithSpecifiedReplyPath {
4540+
destination: Destination::BlindedPath(invoice_path.clone()),
4541+
reply_path: reply_path.clone(),
4542+
};
4543+
let message = AsyncPaymentsMessage::HeldHtlcAvailable(HeldHtlcAvailable {});
4544+
pending_async_payments_messages.push((message, instructions));
4545+
});
4546+
4547+
Ok(())
4548+
}
4549+
45424550
#[cfg(async_payments)]
45434551
fn send_payment_for_static_invoice(
45444552
&self, payment_id: PaymentId

0 commit comments

Comments
 (0)