Skip to content

Commit 4d1e44b

Browse files
committed
Avoid allocating when checking gossip message signatures
When we check gossip message signatures, there's no reason to serialize out the full gossip message before hashing, and it generates a lot of allocations during the initial startup when we fetch the full gossip from peers.
1 parent 10b3aef commit 4d1e44b

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed

lightning/src/routing/gossip.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use bitcoin::secp256k1::{PublicKey, Verification};
1616
use bitcoin::secp256k1::Secp256k1;
1717
use bitcoin::secp256k1;
1818

19+
use bitcoin::hashes::sha256::Hash as Sha256Hash;
1920
use bitcoin::hashes::sha256d::Hash as Sha256dHash;
2021
use bitcoin::hashes::Hash;
2122
use bitcoin::hashes::hex::FromHex;
@@ -412,11 +413,17 @@ macro_rules! get_pubkey_from_node_id {
412413
}
413414
}
414415

416+
fn message_sha256d_hash<M: Writeable>(msg: &M) -> [u8; 32] {
417+
let mut engine = Sha256Hash::engine();
418+
msg.write(&mut engine).expect("In-memory structs should not fail to serialize");
419+
Sha256dHash::from_engine(engine).into_inner()
420+
}
421+
415422
/// Verifies the signature of a [`NodeAnnouncement`].
416423
///
417424
/// Returns an error if it is invalid.
418425
pub fn verify_node_announcement<C: Verification>(msg: &NodeAnnouncement, secp_ctx: &Secp256k1<C>) -> Result<(), LightningError> {
419-
let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.contents.encode()[..])[..]);
426+
let msg_hash = hash_to_message!(&message_sha256d_hash(&msg.contents)[..]);
420427
secp_verify_sig!(secp_ctx, &msg_hash, &msg.signature, &get_pubkey_from_node_id!(msg.contents.node_id, "node_announcement"), "node_announcement");
421428

422429
Ok(())
@@ -426,7 +433,7 @@ pub fn verify_node_announcement<C: Verification>(msg: &NodeAnnouncement, secp_ct
426433
///
427434
/// Returns an error if one of the signatures is invalid.
428435
pub fn verify_channel_announcement<C: Verification>(msg: &ChannelAnnouncement, secp_ctx: &Secp256k1<C>) -> Result<(), LightningError> {
429-
let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.contents.encode()[..])[..]);
436+
let msg_hash = hash_to_message!(&message_sha256d_hash(&msg.contents)[..]);
430437
secp_verify_sig!(secp_ctx, &msg_hash, &msg.node_signature_1, &get_pubkey_from_node_id!(msg.contents.node_id_1, "channel_announcement"), "channel_announcement");
431438
secp_verify_sig!(secp_ctx, &msg_hash, &msg.node_signature_2, &get_pubkey_from_node_id!(msg.contents.node_id_2, "channel_announcement"), "channel_announcement");
432439
secp_verify_sig!(secp_ctx, &msg_hash, &msg.bitcoin_signature_1, &get_pubkey_from_node_id!(msg.contents.bitcoin_key_1, "channel_announcement"), "channel_announcement");
@@ -1969,7 +1976,7 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
19691976
} }
19701977
}
19711978

1972-
let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]);
1979+
let msg_hash = hash_to_message!(&message_sha256d_hash(&msg)[..]);
19731980
if msg.flags & 1 == 1 {
19741981
check_update_latest!(channel.two_to_one);
19751982
if let Some(sig) = sig {

0 commit comments

Comments
 (0)