Skip to content

Commit e137cfb

Browse files
committed
Send warning messages when appropriate in gossip handling pipeline
1 parent 1b3249a commit e137cfb

File tree

5 files changed

+52
-22
lines changed

5 files changed

+52
-22
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -613,8 +613,14 @@ impl MsgHandleErrInternal {
613613
Self {
614614
err: match err {
615615
ChannelError::Warn(msg) => LightningError {
616-
err: msg,
617-
action: msgs::ErrorAction::IgnoreError,
616+
err: msg.clone(),
617+
action: msgs::ErrorAction::SendWarningMessage {
618+
msg: msgs::WarningMessage {
619+
channel_id,
620+
data: msg
621+
},
622+
log_level: Level::Warn,
623+
},
618624
},
619625
ChannelError::Ignore(msg) => LightningError {
620626
err: msg,
@@ -1373,9 +1379,7 @@ macro_rules! convert_chan_err {
13731379
($self: ident, $err: expr, $short_to_id: expr, $channel: expr, $channel_id: expr) => {
13741380
match $err {
13751381
ChannelError::Warn(msg) => {
1376-
//TODO: Once warning messages are merged, we should send a `warning` message to our
1377-
//peer here.
1378-
(false, MsgHandleErrInternal::from_chan_no_close(ChannelError::Ignore(msg), $channel_id.clone()))
1382+
(false, MsgHandleErrInternal::from_chan_no_close(ChannelError::Warn(msg), $channel_id.clone()))
13791383
},
13801384
ChannelError::Ignore(msg) => {
13811385
(false, MsgHandleErrInternal::from_chan_no_close(ChannelError::Ignore(msg), $channel_id.clone()))

lightning/src/ln/functional_test_utils.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,22 @@ macro_rules! get_closing_signed_broadcast {
780780
}
781781
}
782782

783+
#[cfg(test)]
784+
macro_rules! check_warn_msg {
785+
($node: expr, $recipient_node_id: expr, $chan_id: expr) => {{
786+
let msg_events = $node.node.get_and_clear_pending_msg_events();
787+
assert_eq!(msg_events.len(), 1);
788+
match msg_events[0] {
789+
MessageSendEvent::HandleError { action: ErrorAction::SendWarningMessage { ref msg, log_level: _ }, node_id } => {
790+
assert_eq!(node_id, $recipient_node_id);
791+
assert_eq!(msg.channel_id, $chan_id);
792+
msg.data.clone()
793+
},
794+
_ => panic!("Unexpected event"),
795+
}
796+
}}
797+
}
798+
783799
/// Check that a channel's closing channel update has been broadcasted, and optionally
784800
/// check whether an error message event has occurred.
785801
#[macro_export]

lightning/src/ln/peer_handler.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,8 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref, CMH: Deref> P
918918
msgs::DecodeError::BadLengthDescriptor => return Err(PeerHandleError { no_connection_possible: false }),
919919
msgs::DecodeError::Io(_) => return Err(PeerHandleError { no_connection_possible: false }),
920920
msgs::DecodeError::UnsupportedCompression => {
921-
log_gossip!(self.logger, "We don't support zlib-compressed message fields, ignoring message");
921+
log_gossip!(self.logger, "We don't support zlib-compressed message fields, sending a warning and ignoring message");
922+
self.enqueue_message(peer, &msgs::WarningMessage { channel_id: [0; 32], data: "Unsupported message compression: zlib".to_owned() });
922923
continue;
923924
}
924925
}

lightning/src/ln/shutdown_tests.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -762,10 +762,8 @@ fn do_test_closing_signed_reinit_timeout(timeout_step: TimeoutStep) {
762762

763763
if timeout_step != TimeoutStep::AfterShutdown {
764764
nodes[1].node.handle_closing_signed(&nodes[0].node.get_our_node_id(), &node_0_closing_signed);
765-
// At this point nodes[1] should send back a warning message indicating it disagrees with the
766-
// given channel-closing fee. Currently we do not implement warning messages so instead we
767-
// remain silent here.
768-
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
765+
assert!(check_warn_msg!(nodes[1], nodes[0].node.get_our_node_id(), chan_id)
766+
.starts_with("Unable to come to consensus about closing feerate"));
769767

770768
// Now deliver a mutated closing_signed indicating a higher acceptable fee range, which
771769
// nodes[1] should happily accept and respond to.

lightning/src/routing/network_graph.rs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -294,10 +294,21 @@ where C::Target: chain::Access, L::Target: Logger
294294
}
295295

296296
macro_rules! secp_verify_sig {
297-
( $secp_ctx: expr, $msg: expr, $sig: expr, $pubkey: expr ) => {
297+
( $secp_ctx: expr, $msg: expr, $sig: expr, $pubkey: expr, $msg_type: expr ) => {
298298
match $secp_ctx.verify($msg, $sig, $pubkey) {
299299
Ok(_) => {},
300-
Err(_) => return Err(LightningError{err: "Invalid signature from remote node".to_owned(), action: ErrorAction::IgnoreError}),
300+
Err(_) => {
301+
return Err(LightningError {
302+
err: format!("Invalid signature on {} message", $msg_type),
303+
action: ErrorAction::SendWarningMessage {
304+
msg: msgs::WarningMessage {
305+
channel_id: [0; 32],
306+
data: format!("Invalid signature on {} message", $msg_type),
307+
},
308+
log_level: Level::Trace,
309+
},
310+
});
311+
},
301312
}
302313
};
303314
}
@@ -850,7 +861,7 @@ impl NetworkGraph {
850861
/// routing messages from a source using a protocol other than the lightning P2P protocol.
851862
pub fn update_node_from_announcement<T: secp256k1::Verification>(&self, msg: &msgs::NodeAnnouncement, secp_ctx: &Secp256k1<T>) -> Result<(), LightningError> {
852863
let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.contents.encode()[..])[..]);
853-
secp_verify_sig!(secp_ctx, &msg_hash, &msg.signature, &msg.contents.node_id);
864+
secp_verify_sig!(secp_ctx, &msg_hash, &msg.signature, &msg.contents.node_id, "node_announcement");
854865
self.update_node_from_announcement_intern(&msg.contents, Some(&msg))
855866
}
856867

@@ -910,10 +921,10 @@ impl NetworkGraph {
910921
C::Target: chain::Access,
911922
{
912923
let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.contents.encode()[..])[..]);
913-
secp_verify_sig!(secp_ctx, &msg_hash, &msg.node_signature_1, &msg.contents.node_id_1);
914-
secp_verify_sig!(secp_ctx, &msg_hash, &msg.node_signature_2, &msg.contents.node_id_2);
915-
secp_verify_sig!(secp_ctx, &msg_hash, &msg.bitcoin_signature_1, &msg.contents.bitcoin_key_1);
916-
secp_verify_sig!(secp_ctx, &msg_hash, &msg.bitcoin_signature_2, &msg.contents.bitcoin_key_2);
924+
secp_verify_sig!(secp_ctx, &msg_hash, &msg.node_signature_1, &msg.contents.node_id_1, "channel_announcement");
925+
secp_verify_sig!(secp_ctx, &msg_hash, &msg.node_signature_2, &msg.contents.node_id_2, "channel_announcement");
926+
secp_verify_sig!(secp_ctx, &msg_hash, &msg.bitcoin_signature_1, &msg.contents.bitcoin_key_1, "channel_announcement");
927+
secp_verify_sig!(secp_ctx, &msg_hash, &msg.bitcoin_signature_2, &msg.contents.bitcoin_key_2, "channel_announcement");
917928
self.update_channel_from_unsigned_announcement_intern(&msg.contents, Some(msg), chain_access)
918929
}
919930

@@ -1239,7 +1250,7 @@ impl NetworkGraph {
12391250
secp_verify_sig!(ctx, &msg_hash, &sig, &PublicKey::from_slice(channel.node_two.as_slice()).map_err(|_| LightningError{
12401251
err: "Couldn't parse source node pubkey".to_owned(),
12411252
action: ErrorAction::IgnoreAndLog(Level::Debug)
1242-
})?);
1253+
})?, "channel_update");
12431254
}
12441255
maybe_update_channel_info!(channel.two_to_one, channel.node_two);
12451256
} else {
@@ -1248,7 +1259,7 @@ impl NetworkGraph {
12481259
secp_verify_sig!(ctx, &msg_hash, &sig, &PublicKey::from_slice(channel.node_one.as_slice()).map_err(|_| LightningError{
12491260
err: "Couldn't parse destination node pubkey".to_owned(),
12501261
action: ErrorAction::IgnoreAndLog(Level::Debug)
1251-
})?);
1262+
})?, "channel_update");
12521263
}
12531264
maybe_update_channel_info!(channel.one_to_two, channel.node_one);
12541265
}
@@ -1522,7 +1533,7 @@ mod tests {
15221533
contents: valid_announcement.contents.clone()
15231534
}) {
15241535
Ok(_) => panic!(),
1525-
Err(e) => assert_eq!(e.err, "Invalid signature from remote node")
1536+
Err(e) => assert_eq!(e.err, "Invalid signature on node_announcement message")
15261537
};
15271538

15281539
let announcement_with_data = get_signed_node_announcement(|unsigned_announcement| {
@@ -1651,7 +1662,7 @@ mod tests {
16511662
invalid_sig_announcement.contents.excess_data = Vec::new();
16521663
match net_graph_msg_handler.handle_channel_announcement(&invalid_sig_announcement) {
16531664
Ok(_) => panic!(),
1654-
Err(e) => assert_eq!(e.err, "Invalid signature from remote node")
1665+
Err(e) => assert_eq!(e.err, "Invalid signature on channel_announcement message")
16551666
};
16561667

16571668
let channel_to_itself_announcement = get_signed_channel_announcement(|_| {}, node_1_privkey, node_1_privkey, &secp_ctx);
@@ -1760,7 +1771,7 @@ mod tests {
17601771
invalid_sig_channel_update.signature = secp_ctx.sign(&fake_msghash, node_1_privkey);
17611772
match net_graph_msg_handler.handle_channel_update(&invalid_sig_channel_update) {
17621773
Ok(_) => panic!(),
1763-
Err(e) => assert_eq!(e.err, "Invalid signature from remote node")
1774+
Err(e) => assert_eq!(e.err, "Invalid signature on channel_update message")
17641775
};
17651776
}
17661777

0 commit comments

Comments
 (0)