Move the public path for `channel_state` types to their new path
[rust-lightning] / lightning / src / routing / router.rs
index 08759ad4440b7e9b300ba66b70f48abaaf4e2fdf..56643c082eb5b54ace172b90f5faab58cda78afd 100644 (file)
 use bitcoin::secp256k1::{PublicKey, Secp256k1, self};
 
 use crate::blinded_path::{BlindedHop, BlindedPath, Direction, IntroductionNode};
-use crate::blinded_path::payment::{ForwardNode, ForwardTlvs, PaymentConstraints, PaymentRelay, ReceiveTlvs};
+use crate::blinded_path::message;
+use crate::blinded_path::payment::{ForwardTlvs, PaymentConstraints, PaymentRelay, ReceiveTlvs, self};
 use crate::ln::{PaymentHash, PaymentPreimage};
-use crate::ln::channelmanager::{ChannelDetails, PaymentId, MIN_FINAL_CLTV_EXPIRY_DELTA, RecipientOnionFields};
+use crate::ln::channel_state::ChannelDetails;
+use crate::ln::channelmanager::{PaymentId, MIN_FINAL_CLTV_EXPIRY_DELTA, RecipientOnionFields};
 use crate::ln::features::{BlindedHopFeatures, Bolt11InvoiceFeatures, Bolt12InvoiceFeatures, ChannelFeatures, NodeFeatures};
 use crate::ln::msgs::{DecodeError, ErrorAction, LightningError, MAX_VALUE_MSAT};
 use crate::ln::onion_utils;
@@ -122,7 +124,7 @@ impl<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, ES: Deref, S: Deref,
                                        max_cltv_expiry: tlvs.payment_constraints.max_cltv_expiry + cltv_expiry_delta,
                                        htlc_minimum_msat: details.inbound_htlc_minimum_msat.unwrap_or(0),
                                };
-                               Some(ForwardNode {
+                               Some(payment::ForwardNode {
                                        tlvs: ForwardTlvs {
                                                short_channel_id,
                                                payment_relay,
@@ -171,7 +173,7 @@ impl< G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, ES: Deref, S: Deref,
        fn create_blinded_paths<
                T: secp256k1::Signing + secp256k1::Verification
        > (
-               &self, recipient: PublicKey, peers: Vec<PublicKey>, secp_ctx: &Secp256k1<T>,
+               &self, recipient: PublicKey, peers: Vec<message::ForwardNode>, secp_ctx: &Secp256k1<T>,
        ) -> Result<Vec<BlindedPath>, ()> {
                self.message_router.create_blinded_paths(recipient, peers, secp_ctx)
        }
@@ -2013,13 +2015,29 @@ where L::Target: Logger {
 
        let max_total_routing_fee_msat = route_params.max_total_routing_fee_msat.unwrap_or(u64::max_value());
 
+       let first_hop_count = first_hops.map(|hops| hops.len()).unwrap_or(0);
        log_trace!(logger, "Searching for a route from payer {} to {} {} MPP and {} first hops {}overriding the network graph of {} nodes and {} channels with a fee limit of {} msat",
                our_node_pubkey, LoggedPayeePubkey(payment_params.payee.node_id()),
                if allow_mpp { "with" } else { "without" },
-               first_hops.map(|hops| hops.len()).unwrap_or(0), if first_hops.is_some() { "" } else { "not " },
+               first_hop_count, if first_hops.is_some() { "" } else { "not " },
                network_graph.nodes().len(), network_graph.channels().len(),
                max_total_routing_fee_msat);
 
+       if first_hop_count < 10 {
+               if let Some(hops) = first_hops {
+                       for hop in hops {
+                               log_trace!(
+                                       logger,
+                                       " First hop through {}/{} can send between {}msat and {}msat (inclusive).",
+                                       hop.counterparty.node_id,
+                                       hop.get_outbound_payment_scid().unwrap_or(0),
+                                       hop.next_outbound_htlc_minimum_msat,
+                                       hop.next_outbound_htlc_limit_msat
+                               );
+                       }
+               }
+       }
+
        // Step (1).
        // Prepare the data we'll use for payee-to-payer search by
        // inserting first hops suggested by the caller as targets.
@@ -2226,14 +2244,9 @@ where L::Target: Logger {
                                        // around again with a higher amount.
                                        if !contributes_sufficient_value {
                                                if should_log_candidate {
-                                                       log_trace!(logger, "Ignoring {} due to insufficient value contribution.", LoggedCandidateHop(&$candidate));
-
-                                                       if let Some(details) = first_hop_details {
-                                                               log_trace!(logger,
-                                                                       "First hop candidate next_outbound_htlc_limit_msat: {}",
-                                                                       details.next_outbound_htlc_limit_msat,
-                                                               );
-                                                       }
+                                                       log_trace!(logger, "Ignoring {} due to insufficient value contribution (channel max {:?}).",
+                                                               LoggedCandidateHop(&$candidate),
+                                                               effective_capacity);
                                                }
                                                num_ignored_value_contribution += 1;
                                        } else if exceeds_max_path_length {
@@ -2262,15 +2275,8 @@ where L::Target: Logger {
                                        } else if may_overpay_to_meet_path_minimum_msat {
                                                if should_log_candidate {
                                                        log_trace!(logger,
-                                                               "Ignoring {} to avoid overpaying to meet htlc_minimum_msat limit.",
-                                                               LoggedCandidateHop(&$candidate));
-
-                                                       if let Some(details) = first_hop_details {
-                                                               log_trace!(logger,
-                                                                       "First hop candidate next_outbound_htlc_minimum_msat: {}",
-                                                                       details.next_outbound_htlc_minimum_msat,
-                                                               );
-                                                       }
+                                                               "Ignoring {} to avoid overpaying to meet htlc_minimum_msat limit ({}).",
+                                                               LoggedCandidateHop(&$candidate), $candidate.htlc_minimum_msat());
                                                }
                                                num_ignored_avoid_overpayment += 1;
                                                hit_minimum_limit = true;
@@ -3316,6 +3322,7 @@ mod tests {
        use crate::routing::test_utils::{add_channel, add_or_update_node, build_graph, build_line_graph, id_to_feature_flags, get_nodes, update_channel};
        use crate::chain::transaction::OutPoint;
        use crate::sign::EntropySource;
+       use crate::ln::channel_state::{ChannelCounterparty, ChannelDetails, ChannelShutdownState};
        use crate::ln::types::ChannelId;
        use crate::ln::features::{BlindedHopFeatures, ChannelFeatures, InitFeatures, NodeFeatures};
        use crate::ln::msgs::{ErrorAction, LightningError, UnsignedChannelUpdate, MAX_VALUE_MSAT};
@@ -3328,8 +3335,9 @@ mod tests {
        #[cfg(c_bindings)]
        use crate::util::ser::Writer;
 
+       use bitcoin::amount::Amount;
        use bitcoin::hashes::Hash;
-       use bitcoin::network::constants::Network;
+       use bitcoin::network::Network;
        use bitcoin::blockdata::constants::ChainHash;
        use bitcoin::blockdata::script::Builder;
        use bitcoin::blockdata::opcodes;
@@ -3343,10 +3351,10 @@ mod tests {
        use crate::sync::Arc;
 
        fn get_channel_details(short_channel_id: Option<u64>, node_id: PublicKey,
-                       features: InitFeatures, outbound_capacity_msat: u64) -> channelmanager::ChannelDetails {
-               channelmanager::ChannelDetails {
+                       features: InitFeatures, outbound_capacity_msat: u64) -> ChannelDetails {
+               ChannelDetails {
                        channel_id: ChannelId::new_zero(),
-                       counterparty: channelmanager::ChannelCounterparty {
+                       counterparty: ChannelCounterparty {
                                features,
                                node_id,
                                unspendable_punishment_reserve: 0,
@@ -3376,7 +3384,7 @@ mod tests {
                        inbound_htlc_maximum_msat: None,
                        config: None,
                        feerate_sat_per_1000_weight: None,
-                       channel_shutdown_state: Some(channelmanager::ChannelShutdownState::NotShuttingDown),
+                       channel_shutdown_state: Some(ChannelShutdownState::NotShuttingDown),
                        pending_inbound_htlcs: Vec::new(),
                        pending_outbound_htlcs: Vec::new(),
                }
@@ -4887,10 +4895,10 @@ mod tests {
                .push_slice(&PublicKey::from_secret_key(&secp_ctx, &privkeys[0]).serialize())
                .push_slice(&PublicKey::from_secret_key(&secp_ctx, &privkeys[2]).serialize())
                .push_opcode(opcodes::all::OP_PUSHNUM_2)
-               .push_opcode(opcodes::all::OP_CHECKMULTISIG).into_script().to_v0_p2wsh();
+               .push_opcode(opcodes::all::OP_CHECKMULTISIG).into_script().to_p2wsh();
 
                *chain_monitor.utxo_ret.lock().unwrap() =
-                       UtxoResult::Sync(Ok(TxOut { value: 15, script_pubkey: good_script.clone() }));
+                       UtxoResult::Sync(Ok(TxOut { value: Amount::from_sat(15), script_pubkey: good_script.clone() }));
                gossip_sync.add_utxo_lookup(Some(chain_monitor));
 
                add_channel(&gossip_sync, &secp_ctx, &privkeys[0], &privkeys[2], ChannelFeatures::from_le_bytes(id_to_feature_flags(3)), 333);
@@ -5503,6 +5511,18 @@ mod tests {
                        fee_proportional_millionths: 0,
                        excess_data: Vec::new()
                });
+               update_channel(&gossip_sync, &secp_ctx, &privkeys[3], UnsignedChannelUpdate {
+                       chain_hash: ChainHash::using_genesis_block(Network::Testnet),
+                       short_channel_id: 5,
+                       timestamp: 2,
+                       flags: 3, // disable direction 1
+                       cltv_expiry_delta: 0,
+                       htlc_minimum_msat: 0,
+                       htlc_maximum_msat: 200_000,
+                       fee_base_msat: 0,
+                       fee_proportional_millionths: 0,
+                       excess_data: Vec::new()
+               });
 
                // Path via {node7, node2, node4} is channels {12, 13, 6, 11}.
                // Add 100 sats to the capacities of {12, 13}, because these channels
@@ -5680,6 +5700,18 @@ mod tests {
                        fee_proportional_millionths: 0,
                        excess_data: Vec::new()
                });
+               update_channel(&gossip_sync, &secp_ctx, &privkeys[3], UnsignedChannelUpdate {
+                       chain_hash: ChainHash::using_genesis_block(Network::Testnet),
+                       short_channel_id: 5,
+                       timestamp: 2,
+                       flags: 3, // disable direction 1
+                       cltv_expiry_delta: 0,
+                       htlc_minimum_msat: 0,
+                       htlc_maximum_msat: 200_000,
+                       fee_base_msat: 0,
+                       fee_proportional_millionths: 0,
+                       excess_data: Vec::new()
+               });
 
                // Path via {node7, node2, node4} is channels {12, 13, 6, 11}.
                // Add 100 sats to the capacities of {12, 13}, because these channels
@@ -5853,6 +5885,18 @@ mod tests {
                        fee_proportional_millionths: 0,
                        excess_data: Vec::new()
                });
+               update_channel(&gossip_sync, &secp_ctx, &privkeys[3], UnsignedChannelUpdate {
+                       chain_hash: ChainHash::using_genesis_block(Network::Testnet),
+                       short_channel_id: 5,
+                       timestamp: 2,
+                       flags: 3, // Disable direction 1
+                       cltv_expiry_delta: 0,
+                       htlc_minimum_msat: 0,
+                       htlc_maximum_msat: 100_000,
+                       fee_base_msat: 0,
+                       fee_proportional_millionths: 0,
+                       excess_data: Vec::new()
+               });
 
                // Path via {node7, node2, node4} is channels {12, 13, 6, 11}.
                // All channels should be 100 sats capacity. But for the fee experiment,
@@ -6245,92 +6289,104 @@ mod tests {
                let payment_params = PaymentParameters::from_node_id(nodes[6], 42);
 
                add_channel(&gossip_sync, &secp_ctx, &our_privkey, &privkeys[1], ChannelFeatures::from_le_bytes(id_to_feature_flags(6)), 6);
-               update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
-                       chain_hash: ChainHash::using_genesis_block(Network::Testnet),
-                       short_channel_id: 6,
-                       timestamp: 1,
-                       flags: 0,
-                       cltv_expiry_delta: (6 << 4) | 0,
-                       htlc_minimum_msat: 0,
-                       htlc_maximum_msat: MAX_VALUE_MSAT,
-                       fee_base_msat: 0,
-                       fee_proportional_millionths: 0,
-                       excess_data: Vec::new()
-               });
+               for (key, flags) in [(&our_privkey, 0), (&privkeys[1], 3)] {
+                       update_channel(&gossip_sync, &secp_ctx, key, UnsignedChannelUpdate {
+                               chain_hash: ChainHash::using_genesis_block(Network::Testnet),
+                               short_channel_id: 6,
+                               timestamp: 1,
+                               flags,
+                               cltv_expiry_delta: (6 << 4) | 0,
+                               htlc_minimum_msat: 0,
+                               htlc_maximum_msat: MAX_VALUE_MSAT,
+                               fee_base_msat: 0,
+                               fee_proportional_millionths: 0,
+                               excess_data: Vec::new()
+                       });
+               }
                add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[1], NodeFeatures::from_le_bytes(id_to_feature_flags(1)), 0);
 
                add_channel(&gossip_sync, &secp_ctx, &privkeys[1], &privkeys[4], ChannelFeatures::from_le_bytes(id_to_feature_flags(5)), 5);
-               update_channel(&gossip_sync, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
-                       chain_hash: ChainHash::using_genesis_block(Network::Testnet),
-                       short_channel_id: 5,
-                       timestamp: 1,
-                       flags: 0,
-                       cltv_expiry_delta: (5 << 4) | 0,
-                       htlc_minimum_msat: 0,
-                       htlc_maximum_msat: MAX_VALUE_MSAT,
-                       fee_base_msat: 100,
-                       fee_proportional_millionths: 0,
-                       excess_data: Vec::new()
-               });
+               for (key, flags) in [(&privkeys[1], 0), (&privkeys[4], 3)] {
+                       update_channel(&gossip_sync, &secp_ctx, key, UnsignedChannelUpdate {
+                               chain_hash: ChainHash::using_genesis_block(Network::Testnet),
+                               short_channel_id: 5,
+                               timestamp: 1,
+                               flags,
+                               cltv_expiry_delta: (5 << 4) | 0,
+                               htlc_minimum_msat: 0,
+                               htlc_maximum_msat: MAX_VALUE_MSAT,
+                               fee_base_msat: 100,
+                               fee_proportional_millionths: 0,
+                               excess_data: Vec::new()
+                       });
+               }
                add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[4], NodeFeatures::from_le_bytes(id_to_feature_flags(4)), 0);
 
                add_channel(&gossip_sync, &secp_ctx, &privkeys[4], &privkeys[3], ChannelFeatures::from_le_bytes(id_to_feature_flags(4)), 4);
-               update_channel(&gossip_sync, &secp_ctx, &privkeys[4], UnsignedChannelUpdate {
-                       chain_hash: ChainHash::using_genesis_block(Network::Testnet),
-                       short_channel_id: 4,
-                       timestamp: 1,
-                       flags: 0,
-                       cltv_expiry_delta: (4 << 4) | 0,
-                       htlc_minimum_msat: 0,
-                       htlc_maximum_msat: MAX_VALUE_MSAT,
-                       fee_base_msat: 0,
-                       fee_proportional_millionths: 0,
-                       excess_data: Vec::new()
-               });
+               for (key, flags) in [(&privkeys[4], 0), (&privkeys[3], 3)] {
+                       update_channel(&gossip_sync, &secp_ctx, key, UnsignedChannelUpdate {
+                               chain_hash: ChainHash::using_genesis_block(Network::Testnet),
+                               short_channel_id: 4,
+                               timestamp: 1,
+                               flags,
+                               cltv_expiry_delta: (4 << 4) | 0,
+                               htlc_minimum_msat: 0,
+                               htlc_maximum_msat: MAX_VALUE_MSAT,
+                               fee_base_msat: 0,
+                               fee_proportional_millionths: 0,
+                               excess_data: Vec::new()
+                       });
+               }
                add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[3], NodeFeatures::from_le_bytes(id_to_feature_flags(3)), 0);
 
                add_channel(&gossip_sync, &secp_ctx, &privkeys[3], &privkeys[2], ChannelFeatures::from_le_bytes(id_to_feature_flags(3)), 3);
-               update_channel(&gossip_sync, &secp_ctx, &privkeys[3], UnsignedChannelUpdate {
-                       chain_hash: ChainHash::using_genesis_block(Network::Testnet),
-                       short_channel_id: 3,
-                       timestamp: 1,
-                       flags: 0,
-                       cltv_expiry_delta: (3 << 4) | 0,
-                       htlc_minimum_msat: 0,
-                       htlc_maximum_msat: MAX_VALUE_MSAT,
-                       fee_base_msat: 0,
-                       fee_proportional_millionths: 0,
-                       excess_data: Vec::new()
-               });
+               for (key, flags) in [(&privkeys[3], 0), (&privkeys[2], 3)] {
+                       update_channel(&gossip_sync, &secp_ctx, key, UnsignedChannelUpdate {
+                               chain_hash: ChainHash::using_genesis_block(Network::Testnet),
+                               short_channel_id: 3,
+                               timestamp: 1,
+                               flags,
+                               cltv_expiry_delta: (3 << 4) | 0,
+                               htlc_minimum_msat: 0,
+                               htlc_maximum_msat: MAX_VALUE_MSAT,
+                               fee_base_msat: 0,
+                               fee_proportional_millionths: 0,
+                               excess_data: Vec::new()
+                       });
+               }
                add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[2], NodeFeatures::from_le_bytes(id_to_feature_flags(2)), 0);
 
                add_channel(&gossip_sync, &secp_ctx, &privkeys[2], &privkeys[4], ChannelFeatures::from_le_bytes(id_to_feature_flags(2)), 2);
-               update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
-                       chain_hash: ChainHash::using_genesis_block(Network::Testnet),
-                       short_channel_id: 2,
-                       timestamp: 1,
-                       flags: 0,
-                       cltv_expiry_delta: (2 << 4) | 0,
-                       htlc_minimum_msat: 0,
-                       htlc_maximum_msat: MAX_VALUE_MSAT,
-                       fee_base_msat: 0,
-                       fee_proportional_millionths: 0,
-                       excess_data: Vec::new()
-               });
+               for (key, flags) in [(&privkeys[2], 0), (&privkeys[4], 3)] {
+                       update_channel(&gossip_sync, &secp_ctx, key, UnsignedChannelUpdate {
+                               chain_hash: ChainHash::using_genesis_block(Network::Testnet),
+                               short_channel_id: 2,
+                               timestamp: 1,
+                               flags,
+                               cltv_expiry_delta: (2 << 4) | 0,
+                               htlc_minimum_msat: 0,
+                               htlc_maximum_msat: MAX_VALUE_MSAT,
+                               fee_base_msat: 0,
+                               fee_proportional_millionths: 0,
+                               excess_data: Vec::new()
+                       });
+               }
 
                add_channel(&gossip_sync, &secp_ctx, &privkeys[4], &privkeys[6], ChannelFeatures::from_le_bytes(id_to_feature_flags(1)), 1);
-               update_channel(&gossip_sync, &secp_ctx, &privkeys[4], UnsignedChannelUpdate {
-                       chain_hash: ChainHash::using_genesis_block(Network::Testnet),
-                       short_channel_id: 1,
-                       timestamp: 1,
-                       flags: 0,
-                       cltv_expiry_delta: (1 << 4) | 0,
-                       htlc_minimum_msat: 100,
-                       htlc_maximum_msat: MAX_VALUE_MSAT,
-                       fee_base_msat: 0,
-                       fee_proportional_millionths: 0,
-                       excess_data: Vec::new()
-               });
+               for (key, flags) in [(&privkeys[4], 0), (&privkeys[6], 3)] {
+                       update_channel(&gossip_sync, &secp_ctx, key, UnsignedChannelUpdate {
+                               chain_hash: ChainHash::using_genesis_block(Network::Testnet),
+                               short_channel_id: 1,
+                               timestamp: 1,
+                               flags,
+                               cltv_expiry_delta: (1 << 4) | 0,
+                               htlc_minimum_msat: 100,
+                               htlc_maximum_msat: MAX_VALUE_MSAT,
+                               fee_base_msat: 0,
+                               fee_proportional_millionths: 0,
+                               excess_data: Vec::new()
+                       });
+               }
                add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[6], NodeFeatures::from_le_bytes(id_to_feature_flags(6)), 0);
 
                {
@@ -8450,8 +8506,9 @@ pub(crate) mod bench_utils {
        use crate::chain::transaction::OutPoint;
        use crate::routing::scoring::ScoreUpdate;
        use crate::sign::KeysManager;
+       use crate::ln::channel_state::{ChannelCounterparty, ChannelShutdownState};
+       use crate::ln::channelmanager;
        use crate::ln::types::ChannelId;
-       use crate::ln::channelmanager::{self, ChannelCounterparty};
        use crate::util::config::UserConfig;
        use crate::util::test_utils::TestLogger;
 
@@ -8536,7 +8593,7 @@ pub(crate) mod bench_utils {
                        inbound_htlc_maximum_msat: None,
                        config: None,
                        feerate_sat_per_1000_weight: None,
-                       channel_shutdown_state: Some(channelmanager::ChannelShutdownState::NotShuttingDown),
+                       channel_shutdown_state: Some(ChannelShutdownState::NotShuttingDown),
                        pending_inbound_htlcs: Vec::new(),
                        pending_outbound_htlcs: Vec::new(),
                }