mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-02-25 15:20:24 +01:00
Merge pull request #2475 from alecchendev/2023-08-actually-fix-keysend
Fix keysend not being sent in `OutboundPayment::send_payment_internal`
This commit is contained in:
commit
100fdbb7e8
3 changed files with 58 additions and 69 deletions
|
@ -26,7 +26,7 @@ use crate::ln::channel::{DISCONNECT_PEER_AWAITING_RESPONSE_TICKS, ChannelError};
|
||||||
use crate::ln::{chan_utils, onion_utils};
|
use crate::ln::{chan_utils, onion_utils};
|
||||||
use crate::ln::chan_utils::{OFFERED_HTLC_SCRIPT_WEIGHT, htlc_success_tx_weight, htlc_timeout_tx_weight, HTLCOutputInCommitment};
|
use crate::ln::chan_utils::{OFFERED_HTLC_SCRIPT_WEIGHT, htlc_success_tx_weight, htlc_timeout_tx_weight, HTLCOutputInCommitment};
|
||||||
use crate::routing::gossip::{NetworkGraph, NetworkUpdate};
|
use crate::routing::gossip::{NetworkGraph, NetworkUpdate};
|
||||||
use crate::routing::router::{Path, PaymentParameters, Route, RouteHop, RouteParameters, find_route, get_route};
|
use crate::routing::router::{Path, PaymentParameters, Route, RouteHop, get_route};
|
||||||
use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, NodeFeatures};
|
use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, NodeFeatures};
|
||||||
use crate::ln::msgs;
|
use crate::ln::msgs;
|
||||||
use crate::ln::msgs::{ChannelMessageHandler, RoutingMessageHandler, ErrorAction};
|
use crate::ln::msgs::{ChannelMessageHandler, RoutingMessageHandler, ErrorAction};
|
||||||
|
@ -9408,73 +9408,6 @@ fn test_inconsistent_mpp_params() {
|
||||||
expect_payment_sent(&nodes[0], our_payment_preimage, Some(None), true);
|
expect_payment_sent(&nodes[0], our_payment_preimage, Some(None), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_keysend_payments_to_public_node() {
|
|
||||||
let chanmon_cfgs = create_chanmon_cfgs(2);
|
|
||||||
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
|
|
||||||
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
|
|
||||||
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
|
|
||||||
|
|
||||||
let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001);
|
|
||||||
let network_graph = nodes[0].network_graph.clone();
|
|
||||||
let payer_pubkey = nodes[0].node.get_our_node_id();
|
|
||||||
let payee_pubkey = nodes[1].node.get_our_node_id();
|
|
||||||
let route_params = RouteParameters {
|
|
||||||
payment_params: PaymentParameters::for_keysend(payee_pubkey, 40, false),
|
|
||||||
final_value_msat: 10000,
|
|
||||||
};
|
|
||||||
let scorer = test_utils::TestScorer::new();
|
|
||||||
let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
|
|
||||||
let route = find_route(&payer_pubkey, &route_params, &network_graph, None, nodes[0].logger, &scorer, &(), &random_seed_bytes).unwrap();
|
|
||||||
|
|
||||||
let test_preimage = PaymentPreimage([42; 32]);
|
|
||||||
let payment_hash = nodes[0].node.send_spontaneous_payment(&route, Some(test_preimage),
|
|
||||||
RecipientOnionFields::spontaneous_empty(), PaymentId(test_preimage.0)).unwrap();
|
|
||||||
check_added_monitors!(nodes[0], 1);
|
|
||||||
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
|
|
||||||
assert_eq!(events.len(), 1);
|
|
||||||
let event = events.pop().unwrap();
|
|
||||||
let path = vec![&nodes[1]];
|
|
||||||
pass_along_path(&nodes[0], &path, 10000, payment_hash, None, event, true, Some(test_preimage));
|
|
||||||
claim_payment(&nodes[0], &path, test_preimage);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_keysend_payments_to_private_node() {
|
|
||||||
let chanmon_cfgs = create_chanmon_cfgs(2);
|
|
||||||
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
|
|
||||||
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
|
|
||||||
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
|
|
||||||
|
|
||||||
let payer_pubkey = nodes[0].node.get_our_node_id();
|
|
||||||
let payee_pubkey = nodes[1].node.get_our_node_id();
|
|
||||||
|
|
||||||
let _chan = create_chan_between_nodes(&nodes[0], &nodes[1]);
|
|
||||||
let route_params = RouteParameters {
|
|
||||||
payment_params: PaymentParameters::for_keysend(payee_pubkey, 40, false),
|
|
||||||
final_value_msat: 10000,
|
|
||||||
};
|
|
||||||
let network_graph = nodes[0].network_graph.clone();
|
|
||||||
let first_hops = nodes[0].node.list_usable_channels();
|
|
||||||
let scorer = test_utils::TestScorer::new();
|
|
||||||
let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
|
|
||||||
let route = find_route(
|
|
||||||
&payer_pubkey, &route_params, &network_graph, Some(&first_hops.iter().collect::<Vec<_>>()),
|
|
||||||
nodes[0].logger, &scorer, &(), &random_seed_bytes
|
|
||||||
).unwrap();
|
|
||||||
|
|
||||||
let test_preimage = PaymentPreimage([42; 32]);
|
|
||||||
let payment_hash = nodes[0].node.send_spontaneous_payment(&route, Some(test_preimage),
|
|
||||||
RecipientOnionFields::spontaneous_empty(), PaymentId(test_preimage.0)).unwrap();
|
|
||||||
check_added_monitors!(nodes[0], 1);
|
|
||||||
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
|
|
||||||
assert_eq!(events.len(), 1);
|
|
||||||
let event = events.pop().unwrap();
|
|
||||||
let path = vec![&nodes[1]];
|
|
||||||
pass_along_path(&nodes[0], &path, 10000, payment_hash, None, event, true, Some(test_preimage));
|
|
||||||
claim_payment(&nodes[0], &path, test_preimage);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_double_partial_claim() {
|
fn test_double_partial_claim() {
|
||||||
// Test what happens if a node receives a payment, generates a PaymentClaimable event, the HTLCs
|
// Test what happens if a node receives a payment, generates a PaymentClaimable event, the HTLCs
|
||||||
|
|
|
@ -684,7 +684,7 @@ impl OutboundPayments {
|
||||||
Some(route_params.payment_params.clone()), entropy_source, best_block_height)
|
Some(route_params.payment_params.clone()), entropy_source, best_block_height)
|
||||||
.map_err(|_| RetryableSendFailure::DuplicatePayment)?;
|
.map_err(|_| RetryableSendFailure::DuplicatePayment)?;
|
||||||
|
|
||||||
let res = self.pay_route_internal(&route, payment_hash, recipient_onion, None, payment_id, None,
|
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);
|
onion_session_privs, node_signer, best_block_height, &send_payment_along_path);
|
||||||
log_info!(logger, "Result sending payment with id {}: {:?}", log_bytes!(payment_id.0), res);
|
log_info!(logger, "Result sending payment with id {}: {:?}", log_bytes!(payment_id.0), res);
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
|
|
|
@ -236,6 +236,62 @@ fn mpp_receive_timeout() {
|
||||||
do_mpp_receive_timeout(false);
|
do_mpp_receive_timeout(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_keysend_payments() {
|
||||||
|
do_test_keysend_payments(false, false);
|
||||||
|
do_test_keysend_payments(false, true);
|
||||||
|
do_test_keysend_payments(true, false);
|
||||||
|
do_test_keysend_payments(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_test_keysend_payments(public_node: bool, with_retry: bool) {
|
||||||
|
let chanmon_cfgs = create_chanmon_cfgs(2);
|
||||||
|
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
|
||||||
|
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
|
||||||
|
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
|
||||||
|
|
||||||
|
if public_node {
|
||||||
|
create_announced_chan_between_nodes(&nodes, 0, 1);
|
||||||
|
} else {
|
||||||
|
create_chan_between_nodes(&nodes[0], &nodes[1]);
|
||||||
|
}
|
||||||
|
let payer_pubkey = nodes[0].node.get_our_node_id();
|
||||||
|
let payee_pubkey = nodes[1].node.get_our_node_id();
|
||||||
|
let route_params = RouteParameters {
|
||||||
|
payment_params: PaymentParameters::for_keysend(payee_pubkey, 40, false),
|
||||||
|
final_value_msat: 10000,
|
||||||
|
};
|
||||||
|
|
||||||
|
let network_graph = nodes[0].network_graph.clone();
|
||||||
|
let channels = nodes[0].node.list_usable_channels();
|
||||||
|
let first_hops = channels.iter().collect::<Vec<_>>();
|
||||||
|
let first_hops = if public_node { None } else { Some(first_hops.as_slice()) };
|
||||||
|
|
||||||
|
let scorer = test_utils::TestScorer::new();
|
||||||
|
let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
|
||||||
|
let route = find_route(
|
||||||
|
&payer_pubkey, &route_params, &network_graph, first_hops,
|
||||||
|
nodes[0].logger, &scorer, &(), &random_seed_bytes
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
let test_preimage = PaymentPreimage([42; 32]);
|
||||||
|
let payment_hash = if with_retry {
|
||||||
|
nodes[0].node.send_spontaneous_payment_with_retry(Some(test_preimage),
|
||||||
|
RecipientOnionFields::spontaneous_empty(), PaymentId(test_preimage.0),
|
||||||
|
route_params, Retry::Attempts(1)).unwrap()
|
||||||
|
} else {
|
||||||
|
nodes[0].node.send_spontaneous_payment(&route, Some(test_preimage),
|
||||||
|
RecipientOnionFields::spontaneous_empty(), PaymentId(test_preimage.0)).unwrap()
|
||||||
|
};
|
||||||
|
check_added_monitors!(nodes[0], 1);
|
||||||
|
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
|
||||||
|
assert_eq!(events.len(), 1);
|
||||||
|
let event = events.pop().unwrap();
|
||||||
|
let path = vec![&nodes[1]];
|
||||||
|
pass_along_path(&nodes[0], &path, 10000, payment_hash, None, event, true, Some(test_preimage));
|
||||||
|
claim_payment(&nodes[0], &path, test_preimage);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_mpp_keysend() {
|
fn test_mpp_keysend() {
|
||||||
let mut mpp_keysend_config = test_default_channel_config();
|
let mut mpp_keysend_config = test_default_channel_config();
|
||||||
|
|
Loading…
Add table
Reference in a new issue