diff --git a/src/fiber/graph.rs b/src/fiber/graph.rs index 38621a96..edd96bb5 100644 --- a/src/fiber/graph.rs +++ b/src/fiber/graph.rs @@ -609,11 +609,19 @@ where ) -> Result, GraphError> { let started_time = std::time::Instant::now(); let nodes_len = self.nodes.len(); + let route_to_self = source == target; + let mut result = vec![]; let mut nodes_visited = 0; let mut edges_expanded = 0; let mut nodes_heap = NodeHeap::new(nodes_len); let mut distances = HashMap::::new(); + // a map from node_id to the selected channel outpoint + // suppose the scenario of A <-- channel_1 --> B <-- channel_2 --> A + // when we starting iterate channels from A, we may considerting channel_1 and channel_2, + // and we selected channel_1 according to weight + // in this case, `last_hop_channels` stores (B -> channel_1) so that we can skip channel_1 when we iterate channels from B + let mut last_hop_channels = HashMap::new(); if amount == 0 { return Err(GraphError::Amount( @@ -651,8 +659,7 @@ where next_hop: None, incoming_htlc_expiry: 0, }); - let route_to_self = source == target; - let mut last_hop_channels = HashMap::new(); + while let Some(cur_hop) = nodes_heap.pop() { nodes_visited += 1; @@ -682,11 +689,6 @@ where // if the amount to send is greater than the amount we have, skip this edge if let Some(max_fee_amount) = max_fee_amount { if amount_to_send > amount + max_fee_amount { - debug!( - "amount_to_send: {:?} is greater than sum_amount sum_amount: {:?}", - amount_to_send, - amount + max_fee_amount - ); continue; } } @@ -696,19 +698,9 @@ where || (channel_update.htlc_maximum_value != 0 && amount_to_send > channel_update.htlc_maximum_value) { - debug!( - "amount_to_send is greater than channel capacity: {:?} capacity: {:?}, htlc_max_value: {:?}", - amount_to_send, - channel_info.capacity(), - channel_update.htlc_maximum_value - ); continue; } if amount_to_send < channel_update.htlc_minimum_value { - debug!( - "amount_to_send is less than htlc_minimum_value: {:?} min_value: {:?}", - amount_to_send, channel_update.htlc_minimum_value - ); continue; } let incoming_htlc_expiry = cur_hop.incoming_htlc_expiry @@ -727,7 +719,6 @@ where ); if probability < DEFAULT_MIN_PROBABILITY { - debug!("probability is too low: {:?}", probability); continue; } let agg_weight = diff --git a/src/fiber/tests/graph.rs b/src/fiber/tests/graph.rs index c121ec0f..bb792cae 100644 --- a/src/fiber/tests/graph.rs +++ b/src/fiber/tests/graph.rs @@ -863,8 +863,77 @@ fn test_graph_payment_pay_self_with_one_node() { fn test_graph_build_route_with_double_edge_node() { let mut network = MockNetworkGraph::new(3); // Add edges with min_htlc_value set to 50 - network.add_edge_with_config(0, 2, Some(500), Some(500), Some(50), None, None, Some(100)); - network.add_edge_with_config(2, 0, Some(500), Some(300), Some(50), None, None, Some(200)); + // A <-> B, A is initiator, and A -> B with fee rate 5000, B -> A with fee rate 600000 + network.add_edge_with_config( + 0, + 2, + Some(500), + Some(5000), + Some(50), + None, + None, + Some(600000), + ); + // A -> B, B is initiator, B -> A with fee rate 100000, A -> B with fee rate 200 + network.add_edge_with_config( + 2, + 0, + Some(500), + Some(100000), + Some(50), + None, + None, + Some(200), + ); + + let node0 = network.keys[0]; + + // node0 is the source node + let command = SendPaymentCommand { + target_pubkey: Some(network.keys[0].into()), + amount: Some(100), + payment_hash: Some(Hash256::default()), + final_htlc_expiry_delta: Some(100), + invoice: None, + timeout: Some(10), + max_fee_amount: Some(1000), + max_parts: None, + keysend: Some(false), + udt_type_script: None, + allow_self_payment: true, + }; + let payment_data = SendPaymentData::new(command, node0.into()).unwrap(); + let route = network.graph.build_route(&payment_data); + assert!(route.is_ok()); +} + +#[test] +fn test_graph_build_route_with_other_node_maybe_better() { + let mut network = MockNetworkGraph::new(3); + // Add edges with min_htlc_value set to 50 + // A <-> B, A is initiator, and A -> B with fee rate 5000, B -> A with fee rate 600000 + network.add_edge_with_config( + 0, + 2, + Some(500), + Some(600000), + Some(50), + None, + None, + Some(600000), + ); + // A -> B, B is initiator, B -> A with fee rate 100000, A -> B with fee rate 200 + network.add_edge_with_config( + 2, + 0, + Some(500), + Some(100000), + Some(50), + None, + None, + Some(600000), + ); + // B <-> C, B is initiator network.add_edge_with_config(2, 3, Some(500), Some(2), Some(50), None, None, Some(1)); let node0 = network.keys[0];