Skip to content

Commit eb5198a

Browse files
committed
Avoid parsing PublicKeys when applying an unsigned chan update
`PublicKey` parsing is relatively expensive as we have to check if the point is actually on the curve. To avoid it, our `NetworkGraph` uses `NodeId`s which don't have the validity requirement. Sadly, we were always parsing the broadcasting node's `PublicKey` from the `node_id` in the network graph whenever we see an update for that channel, whether we have a corresponding signature or not. Here we fix this, only parsing the public key (and hashing the message) if we're going to check a signature.
1 parent 1434e9c commit eb5198a

File tree

2 files changed

+23
-8
lines changed

2 files changed

+23
-8
lines changed

lightning-background-processor/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2379,8 +2379,8 @@ mod tests {
23792379
42,
23802380
53,
23812381
features,
2382-
$nodes[0].node.get_our_node_id(),
2383-
$nodes[1].node.get_our_node_id(),
2382+
$nodes[0].node.get_our_node_id().into(),
2383+
$nodes[1].node.get_our_node_id().into(),
23842384
)
23852385
.expect("Failed to update channel from partial announcement");
23862386
let original_graph_description = $nodes[0].network_graph.to_string();

lightning/src/routing/gossip.rs

+21-6
Original file line numberDiff line numberDiff line change
@@ -2537,7 +2537,7 @@ where
25372537
}
25382538
};
25392539

2540-
let node_pubkey;
2540+
let mut node_pubkey = None;
25412541
{
25422542
let channels = self.channels.read().unwrap();
25432543
match channels.get(&msg.short_channel_id) {
@@ -2556,16 +2556,31 @@ where
25562556
} else {
25572557
channel.node_one.as_slice()
25582558
};
2559-
node_pubkey = PublicKey::from_slice(node_id).map_err(|_| LightningError {
2560-
err: "Couldn't parse source node pubkey".to_owned(),
2561-
action: ErrorAction::IgnoreAndLog(Level::Debug),
2562-
})?;
2559+
if sig.is_some() {
2560+
// PublicKey parsing isn't entirely trivial as it requires that we check
2561+
// that the provided point is on the curve. Thus, if we don't have a
2562+
// signature to verify, we want to skip the parsing step entirely.
2563+
// This represents a substantial speedup in applying RGS snapshots.
2564+
node_pubkey =
2565+
Some(PublicKey::from_slice(node_id).map_err(|_| LightningError {
2566+
err: "Couldn't parse source node pubkey".to_owned(),
2567+
action: ErrorAction::IgnoreAndLog(Level::Debug),
2568+
})?);
2569+
}
25632570
},
25642571
}
25652572
}
25662573

2567-
let msg_hash = hash_to_message!(&message_sha256d_hash(&msg)[..]);
25682574
if let Some(sig) = sig {
2575+
let msg_hash = hash_to_message!(&message_sha256d_hash(&msg)[..]);
2576+
let node_pubkey = if let Some(pubkey) = node_pubkey {
2577+
pubkey
2578+
} else {
2579+
debug_assert!(false, "node_pubkey should have been decoded above");
2580+
let err = "node_pubkey wasn't decoded but we need it to check a sig".to_owned();
2581+
let action = ErrorAction::IgnoreAndLog(Level::Error);
2582+
return Err(LightningError { err, action });
2583+
};
25692584
secp_verify_sig!(self.secp_ctx, &msg_hash, &sig, &node_pubkey, "channel_update");
25702585
}
25712586

0 commit comments

Comments
 (0)