Skip to content

Score channels on payment (WIP) #625

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

25 changes: 25 additions & 0 deletions lightning/src/ln/functional_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3962,10 +3962,16 @@ fn test_manager_serialize_deserialize_events() {
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let fee_estimator: test_utils::TestFeeEstimator;
<<<<<<< HEAD
let logger: test_utils::TestLogger;
let new_chan_monitor: test_utils::TestChannelMonitor;
let keys_manager: test_utils::TestKeysInterface;
let nodes_0_deserialized: ChannelManager<EnforcingChannelKeys, &test_utils::TestChannelMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>;
=======
let new_chan_monitor: test_utils::TestChannelMonitor;
let keys_manager: test_utils::TestKeysInterface;
let nodes_0_deserialized: ChannelManager<EnforcingChannelKeys, &test_utils::TestChannelMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator>;
>>>>>>> 3f02a6c... Serialize ChannelManager events
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);

// Start creating a channel, but stop right before broadcasting the event message FundingBroadcastSafe
Expand Down Expand Up @@ -4010,26 +4016,45 @@ fn test_manager_serialize_deserialize_events() {
nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap().iter().next().unwrap().1.write_for_disk(&mut chan_0_monitor_serialized).unwrap();

fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 };
<<<<<<< HEAD
logger = test_utils::TestLogger::new();
new_chan_monitor = test_utils::TestChannelMonitor::new(nodes[0].chain_monitor.clone(), nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator);
nodes[0].chan_monitor = &new_chan_monitor;
let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..];
let (_, mut chan_0_monitor) = <(BlockHash, ChannelMonitor<EnforcingChannelKeys>)>::read(&mut chan_0_monitor_read).unwrap();
=======
new_chan_monitor = test_utils::TestChannelMonitor::new(nodes[0].chain_monitor.clone(), nodes[0].tx_broadcaster.clone(), Arc::new(test_utils::TestLogger::new()), &fee_estimator);
nodes[0].chan_monitor = &new_chan_monitor;
let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..];
let (_, mut chan_0_monitor) = <(BlockHash, ChannelMonitor<EnforcingChannelKeys>)>::read(&mut chan_0_monitor_read, Arc::new(test_utils::TestLogger::new())).unwrap();
>>>>>>> 3f02a6c... Serialize ChannelManager events
assert!(chan_0_monitor_read.is_empty());

let mut nodes_0_read = &nodes_0_serialized[..];
let config = UserConfig::default();
<<<<<<< HEAD
keys_manager = test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet);
let (_, nodes_0_deserialized_tmp) = {
let mut channel_monitors = HashMap::new();
channel_monitors.insert(chan_0_monitor.get_funding_txo(), &mut chan_0_monitor);
<(BlockHash, ChannelManager<EnforcingChannelKeys, &test_utils::TestChannelMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
=======
keys_manager = test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet, Arc::new(test_utils::TestLogger::new()));
let (_, nodes_0_deserialized_tmp) = {
let mut channel_monitors = HashMap::new();
channel_monitors.insert(chan_0_monitor.get_funding_txo(), &mut chan_0_monitor);
<(BlockHash, ChannelManager<EnforcingChannelKeys, &test_utils::TestChannelMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
>>>>>>> 3f02a6c... Serialize ChannelManager events
default_config: config,
keys_manager: &keys_manager,
fee_estimator: &fee_estimator,
monitor: nodes[0].chan_monitor,
tx_broadcaster: nodes[0].tx_broadcaster.clone(),
<<<<<<< HEAD
logger: &logger,
=======
logger: Arc::new(test_utils::TestLogger::new()),
>>>>>>> 3f02a6c... Serialize ChannelManager events
channel_monitors: &mut channel_monitors,
}).unwrap()
};
Expand Down
50 changes: 48 additions & 2 deletions lightning/src/routing/network_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use chain::chaininterface::{ChainError, ChainWatchInterface};
use ln::features::{ChannelFeatures, NodeFeatures};
use ln::msgs::{DecodeError,ErrorAction,LightningError,RoutingMessageHandler,NetAddress};
use ln::msgs;
use routing::router::{Route, RouteHop};
use util::ser::{Writeable, Readable, Writer};
use util::logger::Logger;

Expand Down Expand Up @@ -202,6 +203,36 @@ impl<C: Deref + Sync + Send, L: Deref + Sync + Send> RoutingMessageHandler for N
}
}

#[derive(PartialEq, Debug)]
/// Details about the quality of a channel stored in a field within a DirectionalChannelInfo
/// object. Updates on PaymentSent/Failed events.
pub struct ChannelScore {
/// Increments on detection of a PaymentSent event occuring
pub successes: u64,
/// Increments on detection of a PaymentFailed event occurring
pub failures: u64,
// Many more to come...
}

impl Readable for ChannelScore {
fn read<R: ::std::io::Read>(reader: &mut R) -> Result<ChannelScore, DecodeError> {
let successes: u64 = Readable::read(reader)?;
let failures: u64 = Readable::read(reader)?;
Ok(ChannelScore {
successes,
failures,
})
}
}

impl Writeable for ChannelScore {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
self.successes.write(writer)?;
self.failures.write(writer)?;
Ok(())
}
}

#[derive(PartialEq, Debug)]
/// Details about one direction of a channel. Received
/// within a channel update.
Expand All @@ -222,6 +253,9 @@ pub struct DirectionalChannelInfo {
/// Everything else is useful only for sending out for initial routing sync.
/// Not stored if contains excess data to prevent DoS.
pub last_update_message: Option<msgs::ChannelUpdate>,
/// Tracks a channel's performance over time. Gets updated on the detection of a
/// PaymentSent or PaymentFailed event
pub channel_score: ChannelScore,
}

impl std::fmt::Display for DirectionalChannelInfo {
Expand All @@ -237,7 +271,8 @@ impl_writeable!(DirectionalChannelInfo, 0, {
cltv_expiry_delta,
htlc_minimum_msat,
fees,
last_update_message
last_update_message,
channel_score
});

#[derive(PartialEq)]
Expand Down Expand Up @@ -506,6 +541,13 @@ impl NetworkGraph {
None
}

/// Updates directional channels within the network graph based on route and
/// whether or not the payment succeeded.
pub fn score_channels_on_route(&mut self, route: Route, payment_succeeded: bool) -> Result<bool, LightningError> {

Ok(true)
}

/// For an already known node (from channel announcements), update its stored properties from a given node announcement
/// Announcement signatures are checked here only if Secp256k1 object is provided.
fn update_node_from_announcement(&mut self, msg: &msgs::NodeAnnouncement, secp_ctx: Option<&Secp256k1<secp256k1::VerifyOnly>>) -> Result<bool, LightningError> {
Expand Down Expand Up @@ -677,7 +719,11 @@ impl NetworkGraph {
base_msat: msg.contents.fee_base_msat,
proportional_millionths: msg.contents.fee_proportional_millionths,
},
last_update_message
last_update_message,
channel_score: ChannelScore {
successes: 0,
failures: 0,
}
};
$target = Some(updated_channel_dir_info);
}
Expand Down