{
let preimage = payment_preimage
.unwrap_or_else(|| PaymentPreimage(entropy_source.get_secure_random_bytes()));
- let payment_hash = PaymentHash(Sha256::hash(&preimage.0).into_inner());
+ let payment_hash = PaymentHash(Sha256::hash(&preimage.0).to_byte_array());
self.send_payment_internal(payment_id, payment_hash, recipient_onion, Some(preimage),
retry_strategy, route_params, router, first_hops, inflight_htlcs, entropy_source,
node_signer, best_block_height, logger, pending_events, send_payment_along_path)
{
let preimage = payment_preimage
.unwrap_or_else(|| PaymentPreimage(entropy_source.get_secure_random_bytes()));
- let payment_hash = PaymentHash(Sha256::hash(&preimage.0).into_inner());
+ let payment_hash = PaymentHash(Sha256::hash(&preimage.0).to_byte_array());
let onion_session_privs = self.add_new_pending_payment(payment_hash, recipient_onion.clone(),
payment_id, Some(preimage), &route, None, None, entropy_source, best_block_height)?;
}
}
- #[allow(unused)]
pub(super) fn send_payment_for_bolt12_invoice<R: Deref, ES: Deref, NS: Deref, IH, SP, L: Deref>(
&self, invoice: &Bolt12Invoice, payment_id: PaymentId, router: &R,
first_hops: Vec<ChannelDetails>, inflight_htlcs: IH, entropy_source: &ES, node_signer: &NS,
SP: Fn(SendAlongPathArgs) -> Result<(), APIError>,
{
let payment_hash = invoice.payment_hash();
- let mut max_total_routing_fee_msat = None;
+ let max_total_routing_fee_msat;
match self.pending_outbound_payments.lock().unwrap().entry(payment_id) {
hash_map::Entry::Occupied(entry) => match entry.get() {
PendingOutboundPayment::AwaitingInvoice { retry_strategy, max_total_routing_fee_msat: max_total_fee, .. } => {
hash_map::Entry::Vacant(_) => return Err(Bolt12PaymentError::UnexpectedInvoice),
};
- let route_params = RouteParameters {
- payment_params: PaymentParameters::from_bolt12_invoice(&invoice),
- final_value_msat: invoice.amount_msats(),
- max_total_routing_fee_msat,
- };
+ let pay_params = PaymentParameters::from_bolt12_invoice(&invoice);
+ let amount_msat = invoice.amount_msats();
+ let mut route_params = RouteParameters::from_payment_params_and_value(pay_params, amount_msat);
+ if let Some(max_fee_msat) = max_total_routing_fee_msat {
+ route_params.max_total_routing_fee_msat = Some(max_fee_msat);
+ }
self.find_route_and_send_payment(
payment_hash, payment_id, route_params, router, first_hops, &inflight_htlcs,
continue 'path_check;
}
}
+ for (i, hop) in path.hops.iter().enumerate() {
+ // Check for duplicate channel_id in the remaining hops of the path
+ if path.hops.iter().skip(i + 1).any(|other_hop| other_hop.short_channel_id == hop.short_channel_id) {
+ path_errs.push(Err(APIError::InvalidRoute{err: "Path went through the same channel twice".to_owned()}));
+ continue 'path_check;
+ }
+ }
total_value += path.final_value_msat();
path_errs.push(Ok(()));
}
let mut pending_events = pending_events.lock().unwrap();
if let hash_map::Entry::Occupied(mut payment) = outbounds.entry(payment_id) {
if !payment.get().is_fulfilled() {
- let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0).into_inner());
+ let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0).to_byte_array());
log_info!(logger, "Payment with id {} and hash {} sent!", payment_id, payment_hash);
let fee_paid_msat = payment.get().get_pending_fee_msat();
pending_events.push_back((events::Event::PaymentSent {
// TODO: We should have a second monitor event that informs us of payments
// irrevocably fulfilled.
if payment.get_mut().remove(&session_priv_bytes, Some(&path)) {
- let payment_hash = Some(PaymentHash(Sha256::hash(&payment_preimage.0).into_inner()));
+ let payment_hash = Some(PaymentHash(Sha256::hash(&payment_preimage.0).to_byte_array()));
pending_events.push_back((events::Event::PaymentPathSuccessful {
payment_id,
payment_hash,
let mut preimage = [0u8; 64];
preimage[..32].copy_from_slice(&probing_cookie_secret);
preimage[32..].copy_from_slice(&payment_id.0);
- PaymentHash(Sha256::hash(&preimage).into_inner())
+ PaymentHash(Sha256::hash(&preimage).to_byte_array())
}
impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
use crate::ln::features::{ChannelFeatures, NodeFeatures};
use crate::ln::msgs::{ErrorAction, LightningError};
use crate::ln::outbound_payment::{Bolt12PaymentError, OutboundPayments, Retry, RetryableSendFailure, StaleExpiration};
+ #[cfg(feature = "std")]
use crate::offers::invoice::DEFAULT_RELATIVE_EXPIRY;
use crate::offers::offer::OfferBuilder;
use crate::offers::test_utils::*;