Skip to content

Commit 6fff3e5

Browse files
authored
Merge pull request #2666 from tnull/2023-10-observable-update
2 parents d7a6d0d + 1c35255 commit 6fff3e5

File tree

1 file changed

+34
-12
lines changed

1 file changed

+34
-12
lines changed

lightning/src/routing/gossip.rs

+34-12
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,9 @@ where U::Target: UtxoLookup, L::Target: Logger
341341

342342
impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
343343
/// Handles any network updates originating from [`Event`]s.
344+
//
345+
/// Note that this will skip applying any [`NetworkUpdate::ChannelUpdateMessage`] to avoid
346+
/// leaking possibly identifying information of the sender to the public network.
344347
///
345348
/// [`Event`]: crate::events::Event
346349
pub fn handle_network_update(&self, network_update: &NetworkUpdate) {
@@ -349,8 +352,7 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
349352
let short_channel_id = msg.contents.short_channel_id;
350353
let is_enabled = msg.contents.flags & (1 << 1) != (1 << 1);
351354
let status = if is_enabled { "enabled" } else { "disabled" };
352-
log_debug!(self.logger, "Updating channel with channel_update from a payment failure. Channel {} is {}.", short_channel_id, status);
353-
let _ = self.update_channel(msg);
355+
log_debug!(self.logger, "Skipping application of a channel update from a payment failure. Channel {} is {}.", short_channel_id, status);
354356
},
355357
NetworkUpdate::ChannelFailure { short_channel_id, is_permanent } => {
356358
if is_permanent {
@@ -1845,14 +1847,14 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
18451847
/// For an already known (from announcement) channel, update info about one of the directions
18461848
/// of the channel.
18471849
///
1848-
/// You probably don't want to call this directly, instead relying on a P2PGossipSync's
1849-
/// RoutingMessageHandler implementation to call it indirectly. This may be useful to accept
1850+
/// You probably don't want to call this directly, instead relying on a [`P2PGossipSync`]'s
1851+
/// [`RoutingMessageHandler`] implementation to call it indirectly. This may be useful to accept
18501852
/// routing messages from a source using a protocol other than the lightning P2P protocol.
18511853
///
18521854
/// If built with `no-std`, any updates with a timestamp more than two weeks in the past or
18531855
/// materially in the future will be rejected.
18541856
pub fn update_channel(&self, msg: &msgs::ChannelUpdate) -> Result<(), LightningError> {
1855-
self.update_channel_intern(&msg.contents, Some(&msg), Some(&msg.signature))
1857+
self.update_channel_internal(&msg.contents, Some(&msg), Some(&msg.signature), false)
18561858
}
18571859

18581860
/// For an already known (from announcement) channel, update info about one of the directions
@@ -1862,10 +1864,23 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
18621864
/// If built with `no-std`, any updates with a timestamp more than two weeks in the past or
18631865
/// materially in the future will be rejected.
18641866
pub fn update_channel_unsigned(&self, msg: &msgs::UnsignedChannelUpdate) -> Result<(), LightningError> {
1865-
self.update_channel_intern(msg, None, None)
1867+
self.update_channel_internal(msg, None, None, false)
18661868
}
18671869

1868-
fn update_channel_intern(&self, msg: &msgs::UnsignedChannelUpdate, full_msg: Option<&msgs::ChannelUpdate>, sig: Option<&secp256k1::ecdsa::Signature>) -> Result<(), LightningError> {
1870+
/// For an already known (from announcement) channel, verify the given [`ChannelUpdate`].
1871+
///
1872+
/// This checks whether the update currently is applicable by [`Self::update_channel`].
1873+
///
1874+
/// If built with `no-std`, any updates with a timestamp more than two weeks in the past or
1875+
/// materially in the future will be rejected.
1876+
pub fn verify_channel_update(&self, msg: &msgs::ChannelUpdate) -> Result<(), LightningError> {
1877+
self.update_channel_internal(&msg.contents, Some(&msg), Some(&msg.signature), true)
1878+
}
1879+
1880+
fn update_channel_internal(&self, msg: &msgs::UnsignedChannelUpdate,
1881+
full_msg: Option<&msgs::ChannelUpdate>, sig: Option<&secp256k1::ecdsa::Signature>,
1882+
only_verify: bool) -> Result<(), LightningError>
1883+
{
18691884
let chan_enabled = msg.flags & (1 << 1) != (1 << 1);
18701885

18711886
if msg.chain_hash != self.chain_hash {
@@ -1961,7 +1976,9 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
19611976
action: ErrorAction::IgnoreAndLog(Level::Debug)
19621977
})?, "channel_update");
19631978
}
1964-
channel.two_to_one = get_new_channel_info!();
1979+
if !only_verify {
1980+
channel.two_to_one = get_new_channel_info!();
1981+
}
19651982
} else {
19661983
check_update_latest!(channel.one_to_two);
19671984
if let Some(sig) = sig {
@@ -1970,7 +1987,9 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
19701987
action: ErrorAction::IgnoreAndLog(Level::Debug)
19711988
})?, "channel_update");
19721989
}
1973-
channel.one_to_two = get_new_channel_info!();
1990+
if !only_verify {
1991+
channel.one_to_two = get_new_channel_info!();
1992+
}
19741993
}
19751994
}
19761995
}
@@ -2411,6 +2430,7 @@ pub(crate) mod tests {
24112430
}
24122431

24132432
let valid_channel_update = get_signed_channel_update(|_| {}, node_1_privkey, &secp_ctx);
2433+
network_graph.verify_channel_update(&valid_channel_update).unwrap();
24142434
match gossip_sync.handle_channel_update(&valid_channel_update) {
24152435
Ok(res) => assert!(res),
24162436
_ => panic!(),
@@ -2513,7 +2533,8 @@ pub(crate) mod tests {
25132533

25142534
let short_channel_id;
25152535
{
2516-
// Announce a channel we will update
2536+
// Check we won't apply an update via `handle_network_update` for privacy reasons, but
2537+
// can continue fine if we manually apply it.
25172538
let valid_channel_announcement = get_signed_channel_announcement(|_| {}, node_1_privkey, node_2_privkey, &secp_ctx);
25182539
short_channel_id = valid_channel_announcement.contents.short_channel_id;
25192540
let chain_source: Option<&test_utils::TestChainSource> = None;
@@ -2524,10 +2545,11 @@ pub(crate) mod tests {
25242545
assert!(network_graph.read_only().channels().get(&short_channel_id).unwrap().one_to_two.is_none());
25252546

25262547
network_graph.handle_network_update(&NetworkUpdate::ChannelUpdateMessage {
2527-
msg: valid_channel_update,
2548+
msg: valid_channel_update.clone(),
25282549
});
25292550

2530-
assert!(network_graph.read_only().channels().get(&short_channel_id).unwrap().one_to_two.is_some());
2551+
assert!(network_graph.read_only().channels().get(&short_channel_id).unwrap().one_to_two.is_none());
2552+
network_graph.update_channel(&valid_channel_update).unwrap();
25312553
}
25322554

25332555
// Non-permanent failure doesn't touch the channel at all

0 commit comments

Comments
 (0)