From: Matt Corallo Date: Wed, 23 Mar 2022 22:10:15 +0000 (+0000) Subject: Skip `channel_update` signature checks if we have a newer state X-Git-Tag: v0.0.106~10^2 X-Git-Url: http://git.bitcoin.ninja/?a=commitdiff_plain;h=63ca72e5b06e3dc826935541aab7b69f34e3310d;p=rust-lightning Skip `channel_update` signature checks if we have a newer state `channel_update` messages already have their signatures checked with the network graph write lock held, so there's no reason to check the signatures before doing other quicker checks first, including checking if we're already aware of a newer update for the channel. This reduces common-case CPU usage as `channel_update`s are sent rather liberally over the p2p network to gossip them. --- diff --git a/lightning/src/routing/network_graph.rs b/lightning/src/routing/network_graph.rs index 012357df3..13e6beedd 100644 --- a/lightning/src/routing/network_graph.rs +++ b/lightning/src/routing/network_graph.rs @@ -1376,8 +1376,8 @@ impl NetworkGraph { } } } - macro_rules! maybe_update_channel_info { - ( $target: expr, $src_node: expr) => { + macro_rules! check_update_latest { + ($target: expr) => { if let Some(existing_chan_info) = $target.as_ref() { // The timestamp field is somewhat of a misnomer - the BOLTs use it to // order updates to ensure you always have the latest one, only @@ -1394,7 +1394,11 @@ impl NetworkGraph { } else { chan_was_enabled = false; } + } + } + macro_rules! get_new_channel_info { + () => { { let last_update_message = if msg.excess_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY { full_msg.cloned() } else { None }; @@ -1410,29 +1414,31 @@ impl NetworkGraph { }, last_update_message }; - $target = Some(updated_channel_update_info); - } + Some(updated_channel_update_info) + } } } let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]); if msg.flags & 1 == 1 { dest_node_id = channel.node_one.clone(); + check_update_latest!(channel.two_to_one); if let Some((sig, ctx)) = sig_info { secp_verify_sig!(ctx, &msg_hash, &sig, &PublicKey::from_slice(channel.node_two.as_slice()).map_err(|_| LightningError{ err: "Couldn't parse source node pubkey".to_owned(), action: ErrorAction::IgnoreAndLog(Level::Debug) })?, "channel_update"); } - maybe_update_channel_info!(channel.two_to_one, channel.node_two); + channel.two_to_one = get_new_channel_info!(); } else { dest_node_id = channel.node_two.clone(); + check_update_latest!(channel.one_to_two); if let Some((sig, ctx)) = sig_info { secp_verify_sig!(ctx, &msg_hash, &sig, &PublicKey::from_slice(channel.node_one.as_slice()).map_err(|_| LightningError{ err: "Couldn't parse destination node pubkey".to_owned(), action: ErrorAction::IgnoreAndLog(Level::Debug) })?, "channel_update"); } - maybe_update_channel_info!(channel.one_to_two, channel.node_one); + channel.one_to_two = get_new_channel_info!(); } } }