use crate::events::{self, PaymentFailureReason};
use crate::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
use crate::ln::channelmanager::{ChannelDetails, EventCompletionAction, HTLCSource, IDEMPOTENCY_TIMEOUT_TICKS, PaymentId};
-use crate::ln::onion_utils::HTLCFailReason;
+use crate::ln::onion_utils::{DecodedOnionFailure, HTLCFailReason};
use crate::routing::router::{InFlightHtlcs, Path, PaymentParameters, Route, RouteParameters, Router};
use crate::util::errors::APIError;
use crate::util::logger::Logger;
{
#[cfg(feature = "std")] {
if has_expired(&route_params) {
+ log_error!(logger, "Payment with id {} and hash {} had expired before we started paying",
+ payment_id, payment_hash);
return Err(RetryableSendFailure::PaymentExpired)
}
}
&node_signer.get_node_id(Recipient::Node).unwrap(), &route_params,
Some(&first_hops.iter().collect::<Vec<_>>()), inflight_htlcs(),
payment_hash, payment_id,
- ).map_err(|_| RetryableSendFailure::RouteNotFound)?;
+ ).map_err(|_| {
+ log_error!(logger, "Failed to find route for payment with id {} and hash {}",
+ payment_id, payment_hash);
+ RetryableSendFailure::RouteNotFound
+ })?;
let onion_session_privs = self.add_new_pending_payment(payment_hash,
recipient_onion.clone(), payment_id, keysend_preimage, &route, Some(retry_strategy),
Some(route_params.payment_params.clone()), entropy_source, best_block_height)
- .map_err(|_| RetryableSendFailure::DuplicatePayment)?;
+ .map_err(|_| {
+ log_error!(logger, "Payment with id {} is already pending. New payment had payment hash {}",
+ payment_id, payment_hash);
+ RetryableSendFailure::DuplicatePayment
+ })?;
let res = self.pay_route_internal(&route, payment_hash, recipient_onion, keysend_preimage, payment_id, None,
onion_session_privs, node_signer, best_block_height, &send_payment_along_path);
- log_info!(logger, "Result sending payment with id {}: {:?}", &payment_id, res);
+ log_info!(logger, "Sending payment with id {} and hash {} returned {:?}",
+ payment_id, payment_hash, res);
if let Err(e) = res {
self.handle_pay_route_err(e, payment_id, payment_hash, route, route_params, router, first_hops, &inflight_htlcs, entropy_source, node_signer, best_block_height, logger, pending_events, &send_payment_along_path);
}
}))
}
- let route = Route { paths: vec![path], payment_params: None };
+ let route = Route { paths: vec![path], route_params: None };
let onion_session_privs = self.add_new_pending_payment(payment_hash,
RecipientOnionFields::spontaneous_empty(), payment_id, None, &route, None, None,
entropy_source, best_block_height)?;
results,
payment_id,
failed_paths_retry: if pending_amt_unsent != 0 {
- if let Some(payment_params) = &route.payment_params {
+ if let Some(payment_params) = route.route_params.as_ref().map(|p| p.payment_params.clone()) {
Some(RouteParameters {
- payment_params: payment_params.clone(),
+ payment_params: payment_params,
final_value_msat: pending_amt_unsent,
})
} else { None }
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());
+ 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 {
payment_id: Some(payment_id),
pending_events: &Mutex<VecDeque<(events::Event, Option<EventCompletionAction>)>>, logger: &L,
) -> bool where L::Target: Logger {
#[cfg(test)]
- let (network_update, short_channel_id, payment_retryable, onion_error_code, onion_error_data) = onion_error.decode_onion_failure(secp_ctx, logger, &source);
+ let DecodedOnionFailure {
+ network_update, short_channel_id, payment_retryable, onion_error_code, onion_error_data
+ } = onion_error.decode_onion_failure(secp_ctx, logger, &source);
#[cfg(not(test))]
- let (network_update, short_channel_id, payment_retryable, _, _) = onion_error.decode_onion_failure(secp_ctx, logger, &source);
+ let DecodedOnionFailure { network_update, short_channel_id, payment_retryable } =
+ onion_error.decode_onion_failure(secp_ctx, logger, &source);
let payment_is_probe = payment_is_probe(payment_hash, &payment_id, probing_cookie_secret);
let mut session_priv_bytes = [0; 32];
use crate::ln::outbound_payment::{OutboundPayments, Retry, RetryableSendFailure};
use crate::routing::gossip::NetworkGraph;
use crate::routing::router::{InFlightHtlcs, Path, PaymentParameters, Route, RouteHop, RouteParameters};
- use crate::sync::{Arc, Mutex};
+ use crate::sync::{Arc, Mutex, RwLock};
use crate::util::errors::APIError;
use crate::util::test_utils;
let outbound_payments = OutboundPayments::new();
let logger = test_utils::TestLogger::new();
let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &logger));
- let scorer = Mutex::new(test_utils::TestScorer::new());
+ let scorer = RwLock::new(test_utils::TestScorer::new());
let router = test_utils::TestRouter::new(network_graph, &scorer);
let secp_ctx = Secp256k1::new();
let keys_manager = test_utils::TestKeysInterface::new(&[0; 32], Network::Testnet);
PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()),
0
).with_expiry_time(past_expiry_time);
- let expired_route_params = RouteParameters {
- payment_params,
- final_value_msat: 0,
- };
+ let expired_route_params = RouteParameters::from_payment_params_and_value(payment_params, 0);
let pending_events = Mutex::new(VecDeque::new());
if on_retry {
outbound_payments.add_new_pending_payment(PaymentHash([0; 32]), RecipientOnionFields::spontaneous_empty(),
- PaymentId([0; 32]), None, &Route { paths: vec![], payment_params: None },
+ PaymentId([0; 32]), None, &Route { paths: vec![], route_params: None },
Some(Retry::Attempts(1)), Some(expired_route_params.payment_params.clone()),
&&keys_manager, 0).unwrap();
outbound_payments.retry_payment_internal(
let outbound_payments = OutboundPayments::new();
let logger = test_utils::TestLogger::new();
let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &logger));
- let scorer = Mutex::new(test_utils::TestScorer::new());
+ let scorer = RwLock::new(test_utils::TestScorer::new());
let router = test_utils::TestRouter::new(network_graph, &scorer);
let secp_ctx = Secp256k1::new();
let keys_manager = test_utils::TestKeysInterface::new(&[0; 32], Network::Testnet);
let payment_params = PaymentParameters::from_node_id(
PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()), 0);
- let route_params = RouteParameters {
- payment_params,
- final_value_msat: 0,
- };
+ let route_params = RouteParameters::from_payment_params_and_value(payment_params, 0);
router.expect_find_route(route_params.clone(),
Err(LightningError { err: String::new(), action: ErrorAction::IgnoreError }));
let pending_events = Mutex::new(VecDeque::new());
if on_retry {
outbound_payments.add_new_pending_payment(PaymentHash([0; 32]), RecipientOnionFields::spontaneous_empty(),
- PaymentId([0; 32]), None, &Route { paths: vec![], payment_params: None },
+ PaymentId([0; 32]), None, &Route { paths: vec![], route_params: None },
Some(Retry::Attempts(1)), Some(route_params.payment_params.clone()),
&&keys_manager, 0).unwrap();
outbound_payments.retry_payment_internal(
let outbound_payments = OutboundPayments::new();
let logger = test_utils::TestLogger::new();
let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &logger));
- let scorer = Mutex::new(test_utils::TestScorer::new());
+ let scorer = RwLock::new(test_utils::TestScorer::new());
let router = test_utils::TestRouter::new(network_graph, &scorer);
let secp_ctx = Secp256k1::new();
let keys_manager = test_utils::TestKeysInterface::new(&[0; 32], Network::Testnet);
let sender_pk = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
let receiver_pk = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[43; 32]).unwrap());
let payment_params = PaymentParameters::from_node_id(sender_pk, 0);
- let route_params = RouteParameters {
- payment_params: payment_params.clone(),
- final_value_msat: 0,
- };
+ let route_params = RouteParameters::from_payment_params_and_value(payment_params.clone(), 0);
let failed_scid = 42;
let route = Route {
paths: vec![Path { hops: vec![RouteHop {
fee_msat: 0,
cltv_expiry_delta: 0,
}], blinded_tail: None }],
- payment_params: Some(payment_params),
+ route_params: Some(route_params.clone()),
};
router.expect_find_route(route_params.clone(), Ok(route.clone()));
let mut route_params_w_failed_scid = route_params.clone();