Skip to content

Commit 389bda3

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 87226c6 commit 389bda3

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
@@ -4696,7 +4696,7 @@ where
46964696
}
46974697

46984698
#[cfg(async_payments)]
4699-
fn initiate_async_payment(
4699+
fn handle_static_invoice_received(
47004700
&self, invoice: &StaticInvoice, payment_id: PaymentId
47014701
) -> Result<(), Bolt12PaymentError> {
47024702
let mut res = Ok(());
@@ -4718,43 +4718,51 @@ where
47184718
return NotifyOption::DoPersist
47194719
}
47204720
};
4721-
4722-
let nonce = Nonce::from_entropy_source(&*self.entropy_source);
4723-
let hmac = payment_id.hmac_for_async_payment(nonce, &self.inbound_payment_key);
4724-
let reply_paths = match self.create_blinded_paths(
4725-
MessageContext::AsyncPayments(
4726-
AsyncPaymentsContext::OutboundPayment { payment_id, nonce, hmac }
4727-
)
4728-
) {
4729-
Ok(paths) => paths,
4730-
Err(()) => {
4731-
self.abandon_payment_with_reason(payment_id, PaymentFailureReason::BlindedPathCreationFailed);
4732-
res = Err(Bolt12PaymentError::BlindedPathCreationFailed);
4733-
return NotifyOption::DoPersist
4734-
}
4735-
};
4736-
4737-
let mut pending_async_payments_messages = self.pending_async_payments_messages.lock().unwrap();
4738-
const HTLC_AVAILABLE_LIMIT: usize = 10;
4739-
reply_paths
4740-
.iter()
4741-
.flat_map(|reply_path| invoice.message_paths().iter().map(move |invoice_path| (invoice_path, reply_path)))
4742-
.take(HTLC_AVAILABLE_LIMIT)
4743-
.for_each(|(invoice_path, reply_path)| {
4744-
let instructions = MessageSendInstructions::WithSpecifiedReplyPath {
4745-
destination: Destination::BlindedPath(invoice_path.clone()),
4746-
reply_path: reply_path.clone(),
4747-
};
4748-
let message = AsyncPaymentsMessage::HeldHtlcAvailable(HeldHtlcAvailable {});
4749-
pending_async_payments_messages.push((message, instructions));
4750-
});
4751-
47524721
NotifyOption::DoPersist
47534722
});
47544723

47554724
res
47564725
}
47574726

4727+
#[cfg(async_payments)]
4728+
fn initiate_async_payment(
4729+
&self, invoice: &StaticInvoice, payment_id: PaymentId
4730+
) -> Result<(), Bolt12PaymentError> {
4731+
4732+
self.handle_static_invoice_received(invoice, payment_id)?;
4733+
4734+
let nonce = Nonce::from_entropy_source(&*self.entropy_source);
4735+
let hmac = payment_id.hmac_for_async_payment(nonce, &self.inbound_payment_key);
4736+
let reply_paths = match self.create_blinded_paths(
4737+
MessageContext::AsyncPayments(
4738+
AsyncPaymentsContext::OutboundPayment { payment_id, nonce, hmac }
4739+
)
4740+
) {
4741+
Ok(paths) => paths,
4742+
Err(()) => {
4743+
self.abandon_payment_with_reason(payment_id, PaymentFailureReason::BlindedPathCreationFailed);
4744+
return Err(Bolt12PaymentError::BlindedPathCreationFailed);
4745+
}
4746+
};
4747+
4748+
let mut pending_async_payments_messages = self.pending_async_payments_messages.lock().unwrap();
4749+
const HTLC_AVAILABLE_LIMIT: usize = 10;
4750+
reply_paths
4751+
.iter()
4752+
.flat_map(|reply_path| invoice.message_paths().iter().map(move |invoice_path| (invoice_path, reply_path)))
4753+
.take(HTLC_AVAILABLE_LIMIT)
4754+
.for_each(|(invoice_path, reply_path)| {
4755+
let instructions = MessageSendInstructions::WithSpecifiedReplyPath {
4756+
destination: Destination::BlindedPath(invoice_path.clone()),
4757+
reply_path: reply_path.clone(),
4758+
};
4759+
let message = AsyncPaymentsMessage::HeldHtlcAvailable(HeldHtlcAvailable {});
4760+
pending_async_payments_messages.push((message, instructions));
4761+
});
4762+
4763+
Ok(())
4764+
}
4765+
47584766
#[cfg(async_payments)]
47594767
fn send_payment_for_static_invoice(
47604768
&self, payment_id: PaymentId

0 commit comments

Comments
 (0)