///
/// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
payment_id: PaymentId,
- /// The hash that was given to [`ChannelManager::send_payment`].
+ /// The hash that was given to [`ChannelManager::send_payment`]. `None` if the payment failed
+ /// before receiving an invoice when paying a BOLT12 [`Offer`].
///
/// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
- payment_hash: PaymentHash,
+ /// [`Offer`]: crate::offers::offer::Offer
+ payment_hash: Option<PaymentHash>,
/// The reason the payment failed. This is only `None` for events generated or serialized
/// by versions prior to 0.0.115.
reason: Option<PaymentFailureReason>,
},
&Event::PaymentFailed { ref payment_id, ref payment_hash, ref reason } => {
15u8.write(writer)?;
+ let (payment_hash, invoice_received) = match payment_hash {
+ Some(payment_hash) => (payment_hash, true),
+ None => (&PaymentHash([0; 32]), false),
+ };
write_tlv_fields!(writer, {
(0, payment_id, required),
(1, reason, option),
(2, payment_hash, required),
+ (3, invoice_received, required),
})
},
&Event::OpenChannelRequest { .. } => {
let mut payment_hash = PaymentHash([0; 32]);
let mut payment_id = PaymentId([0; 32]);
let mut reason = None;
+ let mut invoice_received: Option<bool> = None;
read_tlv_fields!(reader, {
(0, payment_id, required),
(1, reason, upgradable_option),
(2, payment_hash, required),
+ (3, invoice_received, option),
});
+ let payment_hash = match invoice_received {
+ Some(invoice_received) => invoice_received.then(|| payment_hash),
+ None => (payment_hash != PaymentHash([0; 32])).then(|| payment_hash),
+ };
Ok(Some(Event::PaymentFailed {
payment_id,
payment_hash,
assert_eq!(evs.len(), 1);
match evs[0] {
Event::PaymentFailed { payment_hash: ev_payment_hash, reason, .. } => {
- assert_eq!(ev_payment_hash, payment_hash);
+ assert_eq!(ev_payment_hash, Some(payment_hash));
// We have 1 retry attempt remaining, but we're out of blinded paths to try.
assert_eq!(reason, Some(PaymentFailureReason::RouteNotFound));
},
} else { panic!("Unexpected event!"); }
match events[2] {
Event::PaymentFailed { payment_hash, .. } => {
- assert_eq!(payment_hash, payment_hash_1);
+ assert_eq!(payment_hash, Some(payment_hash_1));
},
_ => panic!("Unexpected event"),
}
/// channel_manager.process_pending_events(&|event| {
/// match event {
/// Event::PaymentSent { payment_hash, .. } => println!("Paid {}", payment_hash),
-/// Event::PaymentFailed { payment_hash, .. } => println!("Failed paying {}", payment_hash),
+/// Event::PaymentFailed { payment_hash: Some(payment_hash), .. } =>
+/// println!("Failed paying {}", payment_hash),
/// // ...
/// # _ => {},
/// }
if !conditions.expected_mpp_parts_remain {
match &payment_failed_events[1] {
Event::PaymentFailed { ref payment_hash, ref payment_id, ref reason } => {
- assert_eq!(*payment_hash, expected_payment_hash, "unexpected second payment_hash");
+ assert_eq!(*payment_hash, Some(expected_payment_hash), "unexpected second payment_hash");
assert_eq!(*payment_id, expected_payment_id);
assert_eq!(reason.unwrap(), if expected_payment_failed_permanently {
PaymentFailureReason::RecipientRejected
if i == expected_paths.len() - 1 {
match events[1] {
Event::PaymentFailed { ref payment_hash, ref payment_id, ref reason } => {
- assert_eq!(*payment_hash, our_payment_hash, "unexpected second payment_hash");
+ assert_eq!(*payment_hash, Some(our_payment_hash), "unexpected second payment_hash");
assert_eq!(*payment_id, expected_payment_id);
assert_eq!(reason.unwrap(), expected_fail_reason);
}
)));
assert!(events.iter().any(|ev| matches!(
ev,
- Event::PaymentFailed { ref payment_hash, .. } if *payment_hash == fourth_payment_hash
+ Event::PaymentFailed { ref payment_hash, .. } if *payment_hash == Some(fourth_payment_hash)
)));
nodes[1].node.process_pending_htlc_forwards();
}
match events[1] {
Event::PaymentFailed { ref payment_hash, .. } => {
- assert_eq!(*payment_hash, first_payment_hash);
+ assert_eq!(*payment_hash, Some(first_payment_hash));
},
_ => panic!("Unexpected event"),
}
}
match events[3] {
Event::PaymentFailed { ref payment_hash, .. } => {
- assert_eq!(*payment_hash, second_payment_hash);
+ assert_eq!(*payment_hash, Some(second_payment_hash));
},
_ => panic!("Unexpected event"),
}
}
match events[5] {
Event::PaymentFailed { ref payment_hash, .. } => {
- assert_eq!(*payment_hash, third_payment_hash);
+ assert_eq!(*payment_hash, Some(third_payment_hash));
},
_ => panic!("Unexpected event"),
}
}
match events[1] {
Event::PaymentFailed { payment_hash, .. } => {
- assert_eq!(payment_hash, failed_payment_hash);
+ assert_eq!(payment_hash, Some(failed_payment_hash));
},
_ => panic!("Unexpected event"),
}
}
match events[3] {
Event::PaymentFailed { payment_hash, .. } => {
- assert_eq!(payment_hash, payment_hash_5);
+ assert_eq!(payment_hash, Some(payment_hash_5));
},
_ => panic!("Unexpected event"),
}
}
match &events[1] {
&Event::PaymentFailed { ref payment_hash, .. } => {
- assert_eq!(our_payment_hash.clone(), *payment_hash);
+ assert_eq!(Some(our_payment_hash), *payment_hash);
},
_ => panic!("Unexpected event"),
}
}
match &events[1] {
&Event::PaymentFailed { ref payment_hash, .. } => {
- assert_eq!(payment_hash_2.clone(), *payment_hash);
+ assert_eq!(Some(payment_hash_2), *payment_hash);
},
_ => panic!("Unexpected event"),
}
}
match events_5[1] {
Event::PaymentFailed { payment_hash, .. } => {
- assert_eq!(payment_hash, our_payment_hash);
+ assert_eq!(payment_hash, Some(our_payment_hash));
},
_ => panic!("Unexpected event"),
}
match get_event!(david, Event::PaymentFailed) {
Event::PaymentFailed {
payment_id: event_payment_id,
- payment_hash: event_payment_hash,
+ payment_hash: Some(event_payment_hash),
reason: Some(event_reason),
} => {
assert_eq!(event_payment_id, payment_id);
}
match events[1] {
Event::PaymentFailed { payment_hash: ev_payment_hash, payment_id: ev_payment_id, reason: ref ev_reason } => {
- assert_eq!(*payment_hash, ev_payment_hash);
+ assert_eq!(Some(*payment_hash), ev_payment_hash);
assert_eq!(payment_id, ev_payment_id);
assert_eq!(if expected_retryable {
PaymentFailureReason::RetriesExhausted
if let PendingOutboundPayment::Abandoned { payment_hash, reason, .. } = pmt {
pending_events.lock().unwrap().push_back((events::Event::PaymentFailed {
payment_id: *pmt_id,
- payment_hash: *payment_hash,
+ payment_hash: Some(*payment_hash),
reason: *reason,
}, None));
retain = false;
if $payment.get().remaining_parts() == 0 {
pending_events.lock().unwrap().push_back((events::Event::PaymentFailed {
payment_id,
- payment_hash,
+ payment_hash: Some(payment_hash),
reason: *reason,
}, None));
$payment.remove();
if !payment_is_probe {
full_failure_ev = Some(events::Event::PaymentFailed {
payment_id: *payment_id,
- payment_hash: *payment_hash,
+ payment_hash: Some(*payment_hash),
reason: *reason,
});
}
if payment.get().remaining_parts() == 0 {
pending_events.lock().unwrap().push_back((events::Event::PaymentFailed {
payment_id,
- payment_hash: *payment_hash,
+ payment_hash: Some(*payment_hash),
reason: *reason,
}, None));
payment.remove();
);
assert!(!outbound_payments.has_pending_payments());
- let payment_hash = invoice.payment_hash();
+ let payment_hash = Some(invoice.payment_hash());
let reason = Some(PaymentFailureReason::PaymentExpired);
assert!(!pending_events.lock().unwrap().is_empty());
);
assert!(!outbound_payments.has_pending_payments());
- let payment_hash = invoice.payment_hash();
+ let payment_hash = Some(invoice.payment_hash());
let reason = Some(PaymentFailureReason::RouteNotFound);
assert!(!pending_events.lock().unwrap().is_empty());
} else {
match events[1] {
Event::PaymentFailed { payment_hash: ev_payment_hash, .. } => {
- assert_eq!(payment_hash, ev_payment_hash);
+ assert_eq!(Some(payment_hash), ev_payment_hash);
},
_ => panic!("Unexpected event"),
}
assert_eq!(events.len(), 1);
match events[0] {
Event::PaymentFailed { payment_hash: ref ev_payment_hash, payment_id: ref ev_payment_id, reason: ref ev_reason } => {
- assert_eq!(payment_hash, *ev_payment_hash);
+ assert_eq!(Some(payment_hash), *ev_payment_hash);
assert_eq!(PaymentId(payment_hash.0), *ev_payment_id);
assert_eq!(PaymentFailureReason::RetriesExhausted, ev_reason.unwrap());
},
assert_eq!(events.len(), 1);
match events[0] {
Event::PaymentFailed { payment_hash: ref ev_payment_hash, payment_id: ref ev_payment_id, reason: ref ev_reason } => {
- assert_eq!(payment_hash, *ev_payment_hash);
+ assert_eq!(Some(payment_hash), *ev_payment_hash);
assert_eq!(PaymentId(payment_hash.0), *ev_payment_id);
assert_eq!(PaymentFailureReason::RetriesExhausted, ev_reason.unwrap());
},
assert_eq!(events.len(), 1);
match events[0] {
Event::PaymentFailed { payment_hash: ref ev_payment_hash, payment_id: ref ev_payment_id, reason: ref ev_reason } => {
- assert_eq!(payment_hash, *ev_payment_hash);
+ assert_eq!(Some(payment_hash), *ev_payment_hash);
assert_eq!(PaymentId(payment_hash.0), *ev_payment_id);
assert_eq!(PaymentFailureReason::RouteNotFound, ev_reason.unwrap());
},
}
match events[1] {
Event::PaymentFailed { payment_hash: ref ev_payment_hash, payment_id: ref ev_payment_id, reason: ref ev_reason } => {
- assert_eq!(payment_hash, *ev_payment_hash);
+ assert_eq!(Some(payment_hash), *ev_payment_hash);
assert_eq!(PaymentId(payment_hash.0), *ev_payment_id);
assert_eq!(PaymentFailureReason::RetriesExhausted, ev_reason.unwrap());
},