From 07a7e34f89323540f17abbf9a4b708d27f6bd18f Mon Sep 17 00:00:00 2001 From: Gleb Naumenko Date: Wed, 6 May 2020 19:04:44 -0400 Subject: [PATCH] Improve routing-related documentation --- ARCH.md | 16 +++--- lightning/src/ln/channelmanager.rs | 2 +- lightning/src/ln/mod.rs | 4 +- lightning/src/ln/peer_handler.rs | 2 +- lightning/src/routing/network_graph.rs | 73 +++++++++++++++++--------- lightning/src/routing/router.rs | 4 +- lightning/src/util/events.rs | 4 +- 7 files changed, 64 insertions(+), 41 deletions(-) diff --git a/ARCH.md b/ARCH.md index 237a8555..c4f94280 100644 --- a/ARCH.md +++ b/ARCH.md @@ -11,11 +11,11 @@ receive `ChannelMonitorUpdate`s from `ChannelManager` and persist them to disk b channel steps forward. There are two additional important structures that you may use either on the same device -as the `ChannelManager` or on a separate one. `Router` handles receiving channel and node -announcements and calculates routes for sending payments. `PeerManager` handles the -authenticated and encrypted communication protocol, monitoring for liveness of peers, -routing messages to `ChannelManager` and `Router` instances directly, and receiving -messages from them via the `EventsProvider` interface. +as the `ChannelManager` or on a separate one. `NetGraphMsgHandler` handles receiving channel +and node announcements, which are then used to calculate routes by `get_route` for sending payments. +`PeerManager` handles the authenticated and encrypted communication protocol, +monitoring for liveness of peers, routing messages to `ChannelManager` and `NetGraphMsgHandler` +instances directly, and receiving messages from them via the `EventsProvider` interface. These structs communicate with each other using a public API, so that you can easily add a proxy in between for special handling. Further, APIs for key generation, transaction @@ -56,7 +56,7 @@ At a high level, some of the common interfaces fit together as follows: | ----------------------- --------- | | | Event | (as RoutingMessageHandler) v --------- - \ ---------- - -----------------> | Router | - ---------- + \ -------------------- + -----------------> | NetGraphMsgHandler | + -------------------- ``` diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 8e7e3a05..5922ec28 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -4,7 +4,7 @@ //! responsible for tracking which channels are open, HTLCs are in flight and reestablishing those //! upon reconnect to the relevant peer(s). //! -//! It does not manage routing logic (see routing::router for that) nor does it manage constructing +//! It does not manage routing logic (see routing::router::get_route for that) nor does it manage constructing //! on-chain transactions (it only monitors the chain to watch for any force-closes that might //! imply it needs to fail HTLCs/payments/channels it manages). diff --git a/lightning/src/ln/mod.rs b/lightning/src/ln/mod.rs index 33f1c5bc..163799b0 100644 --- a/lightning/src/ln/mod.rs +++ b/lightning/src/ln/mod.rs @@ -1,13 +1,13 @@ //! High level lightning structs and impls live here. //! -//! You probably want to create a channelmanager::ChannelManager, and a router::Router first. +//! You probably want to create a channelmanager::ChannelManager, and a routing::NetGraphMsgHandler first. //! Then, you probably want to pass them both on to a peer_handler::PeerManager and use that to //! create/manage connections and call get_and_clear_pending_events after each action, handling //! them appropriately. //! //! When you want to open/close a channel or send a payment, call into your ChannelManager and when //! you want to learn things about the network topology (eg get a route for sending a payment), -//! call into your Router. +//! call into your NetGraphMsgHandler. pub mod channelmanager; pub mod channelmonitor; diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index de0d50c7..11c6c4d4 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -3,7 +3,7 @@ //! Instead of actually servicing sockets ourselves we require that you implement the //! SocketDescriptor interface and use that to receive actions which you should perform on the //! socket, and call into PeerManager with bytes read from the socket. The PeerManager will then -//! call into the provided message handlers (probably a ChannelManager and Router) with messages +//! call into the provided message handlers (probably a ChannelManager and NetGraphmsgHandler) with messages //! they should handle, and encoding/sending response messages. use bitcoin::secp256k1::key::{SecretKey,PublicKey}; diff --git a/lightning/src/routing/network_graph.rs b/lightning/src/routing/network_graph.rs index add57c25..faf2b5ff 100644 --- a/lightning/src/routing/network_graph.rs +++ b/lightning/src/routing/network_graph.rs @@ -23,7 +23,11 @@ use std::collections::BTreeMap; use std::collections::btree_map::Entry as BtreeEntry; use std; -/// Receives network updates from peers to track view of the network. +/// Receives and validates network updates from peers, +/// stores authentic and relevant data as a network graph. +/// This network graph is then used for routing payments. +/// Provides interface to help with initial routing sync by +/// serving historical announcements. pub struct NetGraphMsgHandler { secp_ctx: Secp256k1, /// Representation of the payment channel network @@ -35,7 +39,10 @@ pub struct NetGraphMsgHandler { impl NetGraphMsgHandler { /// Creates a new tracker of the actual state of the network of channels and nodes, - /// assuming fresh Network Graph + /// assuming a fresh network graph. + /// Chain monitor is used to make sure announced channels exist on-chain, + /// channel data is correct, and that the announcement is signed with + /// channel owners' keys. pub fn new(chain_monitor: Arc, logger: Arc) -> Self { NetGraphMsgHandler { secp_ctx: Secp256k1::verification_only(), @@ -61,7 +68,9 @@ impl NetGraphMsgHandler { } } - /// Get network addresses by node id + /// Get network addresses by node id. + /// Returns None if the requested node is completely unknown, + /// or if node announcement for the node was never received. pub fn get_addresses(&self, pubkey: &PublicKey) -> Option> { let network = self.network_graph.read().unwrap(); if let Some(node) = network.get_nodes().get(pubkey) { @@ -212,13 +221,15 @@ impl RoutingMessageHandler for NetGraphMsgHandler { } #[derive(PartialEq, Debug)] -/// Details regarding one direction of a channel +/// Details about one direction of a channel. Received +/// within a channel update. pub struct DirectionalChannelInfo { - /// When the last update to the channel direction was issued + /// When the last update to the channel direction was issued. + /// Value is opaque, as set in the announcement. pub last_update: u32, - /// Whether the channel can be currently used for payments + /// Whether the channel can be currently used for payments (in this one direction). pub enabled: bool, - /// The difference in CLTV values between the source and the destination node of the channel + /// The difference in CLTV values that you must have when routing through this channel. pub cltv_expiry_delta: u16, /// The minimum value, which must be relayed to the next hop via the channel pub htlc_minimum_msat: u64, @@ -245,7 +256,8 @@ impl_writeable!(DirectionalChannelInfo, 0, { }); #[derive(PartialEq)] -/// Details regarding a channel (both directions) +/// Details about a channel (both directions). +/// Received within a channel announcement. pub struct ChannelInfo { /// Protocol features of a channel communicated during its announcement pub features: ChannelFeatures, @@ -258,8 +270,9 @@ pub struct ChannelInfo { /// Details about the second direction of a channel pub two_to_one: Option, /// An initial announcement of the channel - //this is cached here so we can send out it later if required by initial routing sync - //keep an eye on this to see if the extra memory is a problem + /// Mostly redundant with the data we store in fields explicitly. + /// Everything else is useful only for sending out for initial routing sync. + /// Not stored if contains excess data to prevent DoS. pub announcement_message: Option, } @@ -284,9 +297,10 @@ impl_writeable!(ChannelInfo, 0, { /// Fees for routing via a given channel or a node #[derive(Eq, PartialEq, Copy, Clone, Debug)] pub struct RoutingFees { - /// Flat routing fee + /// Flat routing fee in satoshis pub base_msat: u32, - /// Liquidity-based routing fee + /// Liquidity-based routing fee in millionths of a routed amount. + /// In other words, 10000 is 1%. pub proportional_millionths: u32, } @@ -314,17 +328,21 @@ impl Writeable for RoutingFees { pub struct NodeAnnouncementInfo { /// Protocol features the node announced support for pub features: NodeFeatures, - /// When the last known update to the node state was issued + /// When the last known update to the node state was issued. + /// Value is opaque, as set in the announcement. pub last_update: u32, /// Color assigned to the node pub rgb: [u8; 3], - /// Moniker assigned to the node + /// Moniker assigned to the node. + /// May be invalid or malicious (eg control chars), + /// should not be exposed to the user. pub alias: [u8; 32], /// Internet-level addresses via which one can connect to the node pub addresses: Vec, /// An initial announcement of the node - // this is cached here so we can send out it later if required by initial routing sync - // keep an eye on this to see if the extra memory is a problem + /// Mostly redundant with the data we store in fields explicitly. + /// Everything else is useful only for sending out for initial routing sync. + /// Not stored if contains excess data to prevent DoS. pub announcement_message: Option } @@ -372,14 +390,17 @@ impl Readable for NodeAnnouncementInfo { } #[derive(PartialEq)] -/// Details regarding a node in the network +/// Details about a node in the network, known from the network announcement. pub struct NodeInfo { /// All valid channels a node has announced pub channels: Vec, - /// Lowest fees enabling routing via any of the known channels to a node + /// Lowest fees enabling routing via any of the known channels to a node. + /// The two fields (flat and proportional fee) are independent, + /// meaning they don't have to refer to the same channel. pub lowest_inbound_channel_fees: Option, - /// More information about a node from node_announcement - /// Optional because we may have a NodeInfo entry before having received the announcement + /// More information about a node from node_announcement. + /// Optional because we store a Node entry after learning about it from + /// a channel announcement, but before receiving a node announcement. pub announcement_info: Option } @@ -483,9 +504,9 @@ impl std::fmt::Display for NetworkGraph { } impl NetworkGraph { - /// Returns all known valid channels + /// Returns all known valid channels' short ids along with announced channel info. pub fn get_channels<'a>(&'a self) -> &'a BTreeMap { &self.channels } - /// Returns all known nodes + /// Returns all known nodes' public keys along with announced node info. pub fn get_nodes<'a>(&'a self) -> &'a BTreeMap { &self.nodes } /// For an already known node (from channel announcements), update its stored properties from a given node announcement @@ -520,9 +541,11 @@ impl NetworkGraph { } } - /// For a new or already known (from previous announcement) channel, store or update channel info, - /// after making sure it corresponds to a real transaction on-chain. + /// For a new or already known (from previous announcement) channel, store or update channel info. /// Also store nodes (if not stored yet) the channel is between, and make node aware of this channel. + /// Checking utxo on-chain is useful if we receive an update for already known channel id, + /// which is probably result of a reorg. In that case, we update channel info only if the + /// utxo was checked, otherwise stick to the existing update, to prevent DoS risks. /// Announcement signatures are checked here only if Secp256k1 object is provided. fn update_channel_from_announcement(&mut self, msg: &msgs::ChannelAnnouncement, checked_utxo: bool, secp_ctx: Option<&Secp256k1>) -> Result { if let Some(sig_verifier) = secp_ctx { @@ -621,7 +644,7 @@ impl NetworkGraph { } } - /// For an already known (from announcement) channel, update info regarding one of the directions of a channel. + /// For an already known (from announcement) channel, update info about one of the directions of a channel. /// Announcement signatures are checked here only if Secp256k1 object is provided. fn update_channel(&mut self, msg: &msgs::ChannelUpdate, secp_ctx: Option<&Secp256k1>) -> Result { let dest_node_id; diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index d593e8c2..524f015c 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -1,6 +1,6 @@ //! The top-level routing/network map tracking logic lives here. //! -//! You probably want to create a Router and use that as your RoutingMessageHandler and then +//! You probably want to create a NetGraphMsgHandler and use that as your RoutingMessageHandler and then //! interrogate it to get routes for your own payments. use bitcoin::secp256k1::key::PublicKey; @@ -151,7 +151,7 @@ struct DummyDirectionalChannelInfo { /// /// If some channels aren't announced, it may be useful to fill in a first_hops with the /// results from a local ChannelManager::list_usable_channels() call. If it is filled in, our -/// (this Router's) view of our local channels will be ignored, and only those in first_hops +/// view of our local channels (from net_graph_msg_handler) will be ignored, and only those in first_hops /// will be used. /// /// Panics if first_hops contains channels without short_channel_ids diff --git a/lightning/src/util/events.rs b/lightning/src/util/events.rs index 76ec2020..82c215a2 100644 --- a/lightning/src/util/events.rs +++ b/lightning/src/util/events.rs @@ -332,9 +332,9 @@ pub enum MessageSendEvent { action: msgs::ErrorAction }, /// When a payment fails we may receive updates back from the hop where it failed. In such - /// cases this event is generated so that we can inform the router of this information. + /// cases this event is generated so that we can inform the network graph of this information. PaymentFailureNetworkUpdate { - /// The channel/node update which should be sent to router + /// The channel/node update which should be sent to NetGraphMsgHandler update: msgs::HTLCFailChannelUpdate, } } -- 2.30.2