diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 89f967c4f70..f87daf8ad85 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -64,7 +64,7 @@ use crate::ln::wire::Encode; use crate::offers::invoice::{BlindedPayInfo, Bolt12Invoice, DEFAULT_RELATIVE_EXPIRY, DerivedSigningPubkey, ExplicitSigningPubkey, InvoiceBuilder, UnsignedBolt12Invoice}; use crate::offers::invoice_error::InvoiceError; use crate::offers::invoice_request::{DerivedPayerId, InvoiceRequestBuilder}; -use crate::offers::offer::{Offer, OfferBuilder}; +use crate::offers::offer::{Offer, OfferBuilder, Amount}; use crate::offers::parse::Bolt12SemanticError; use crate::offers::refund::{Refund, RefundBuilder}; use crate::onion_message::async_payments::{AsyncPaymentsMessage, HeldHtlcAvailable, ReleaseHeldHtlc, AsyncPaymentsMessageHandler}; @@ -8816,6 +8816,26 @@ where None => builder, Some(payer_note) => builder.payer_note(payer_note), }; + + let total_liquidity: u64 = self.list_usable_channels().iter().map(|channel| channel.next_outbound_htlc_limit_msat).sum(); + let total_amount_msats = match amount_msats { + Some(amount_msats) => Some(amount_msats), + None => match offer.amount() { + Some(Amount::Bitcoin {amount_msats}) => Some(amount_msats), + _ => None, + }, + }; + + if let Some(amount) = total_amount_msats { + return if amount > total_liquidity { + log_error!(self.logger, "Insufficient liquidity for payment with payment id: {}", payment_id); + Err(Bolt12SemanticError::InsufficientLiquidity) + } else { + log_error!(self.logger, "Offer amount is missing for payment with id: {}", payment_id); + Err(Bolt12SemanticError::InvalidAmount) + } + } + let invoice_request = builder.build_and_sign()?; let context = OffersContext::OutboundPayment { payment_id }; diff --git a/lightning/src/offers/parse.rs b/lightning/src/offers/parse.rs index c48d745a9ff..00181d1ef27 100644 --- a/lightning/src/offers/parse.rs +++ b/lightning/src/offers/parse.rs @@ -193,6 +193,8 @@ pub enum Bolt12SemanticError { UnexpectedPaymentHash, /// A signature was expected but was missing. MissingSignature, + /// There is insufficient liquidity to complete the payment. + InsufficientLiquidity, } impl From for Bolt12ParseError {