Skip to content

Commit 22b2d98

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 cbfd41b commit 22b2d98

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

lightning/src/routing/gossip.rs

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

19-
use bitcoin::hashes::sha256d::Hash as Sha256dHash;
19+
use bitcoin::hashes::sha256::Hash as Sha256Hash;
2020
use bitcoin::hashes::Hash;
2121
use bitcoin::hashes::hex::FromHex;
2222

@@ -412,11 +412,17 @@ macro_rules! get_pubkey_from_node_id {
412412
}
413413
}
414414

415+
fn message_sha256d_hash<M: Writeable>(msg: &M) -> [u8; 32] {
416+
let mut engine = Sha256Hash::engine();
417+
msg.write(&mut engine).expect("In-memory structs should not fail to serialize");
418+
Sha256Hash::hash(&Sha256Hash::from_engine(engine)[..]).into_inner()
419+
}
420+
415421
/// Verifies the signature of a [`NodeAnnouncement`].
416422
///
417423
/// Returns an error if it is invalid.
418424
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()[..])[..]);
425+
let msg_hash = hash_to_message!(&message_sha256d_hash(&msg.contents)[..]);
420426
secp_verify_sig!(secp_ctx, &msg_hash, &msg.signature, &get_pubkey_from_node_id!(msg.contents.node_id, "node_announcement"), "node_announcement");
421427

422428
Ok(())
@@ -426,7 +432,7 @@ pub fn verify_node_announcement<C: Verification>(msg: &NodeAnnouncement, secp_ct
426432
///
427433
/// Returns an error if one of the signatures is invalid.
428434
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()[..])[..]);
435+
let msg_hash = hash_to_message!(&message_sha256d_hash(&msg.contents)[..]);
430436
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");
431437
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");
432438
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 +1975,7 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
19691975
} }
19701976
}
19711977

1972-
let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]);
1978+
let msg_hash = hash_to_message!(&message_sha256d_hash(&msg)[..]);
19731979
if msg.flags & 1 == 1 {
19741980
check_update_latest!(channel.two_to_one);
19751981
if let Some(sig) = sig {

0 commit comments

Comments
 (0)