From 7f7d9e3d4d370adcd205b9f43942d3c36f820fd0 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 23 Jul 2021 20:13:50 +0000 Subject: [PATCH] Send our peers our supported gossip encoding types --- fuzz/src/chanmon_consistency.rs | 16 ++-- lightning-background-processor/src/lib.rs | 4 +- lightning/src/ln/chanmon_update_fail_tests.rs | 36 ++++----- lightning/src/ln/channelmanager.rs | 8 +- lightning/src/ln/functional_test_utils.rs | 8 +- lightning/src/ln/functional_tests.rs | 40 +++++----- lightning/src/ln/msgs.rs | 80 ++++++++++++++++--- lightning/src/ln/payment_tests.rs | 4 +- lightning/src/ln/peer_handler.rs | 6 +- lightning/src/ln/shutdown_tests.rs | 8 +- lightning/src/ln/wire.rs | 3 +- lightning/src/routing/network_graph.rs | 6 +- 12 files changed, 138 insertions(+), 81 deletions(-) diff --git a/fuzz/src/chanmon_consistency.rs b/fuzz/src/chanmon_consistency.rs index b1b8dfebb..279dc9261 100644 --- a/fuzz/src/chanmon_consistency.rs +++ b/fuzz/src/chanmon_consistency.rs @@ -915,15 +915,15 @@ pub fn do_test(data: &[u8], underlying_out: Out) { }, 0x0e => { if chan_a_disconnected { - nodes[0].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known() }); - nodes[1].peer_connected(&nodes[0].get_our_node_id(), &Init { features: InitFeatures::known() }); + nodes[0].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); + nodes[1].peer_connected(&nodes[0].get_our_node_id(), &Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); chan_a_disconnected = false; } }, 0x0f => { if chan_b_disconnected { - nodes[1].peer_connected(&nodes[2].get_our_node_id(), &Init { features: InitFeatures::known() }); - nodes[2].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known() }); + nodes[1].peer_connected(&nodes[2].get_our_node_id(), &Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); + nodes[2].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); chan_b_disconnected = false; } }, @@ -1118,13 +1118,13 @@ pub fn do_test(data: &[u8], underlying_out: Out) { // Next, make sure peers are all connected to each other if chan_a_disconnected { - nodes[0].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known() }); - nodes[1].peer_connected(&nodes[0].get_our_node_id(), &Init { features: InitFeatures::known() }); + nodes[0].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); + nodes[1].peer_connected(&nodes[0].get_our_node_id(), &Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); chan_a_disconnected = false; } if chan_b_disconnected { - nodes[1].peer_connected(&nodes[2].get_our_node_id(), &Init { features: InitFeatures::known() }); - nodes[2].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known() }); + nodes[1].peer_connected(&nodes[2].get_our_node_id(), &Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); + nodes[2].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); chan_b_disconnected = false; } diff --git a/lightning-background-processor/src/lib.rs b/lightning-background-processor/src/lib.rs index 39ecc316a..03576ed96 100644 --- a/lightning-background-processor/src/lib.rs +++ b/lightning-background-processor/src/lib.rs @@ -397,8 +397,8 @@ mod tests { for i in 0..num_nodes { for j in (i+1)..num_nodes { - nodes[i].node.peer_connected(&nodes[j].node.get_our_node_id(), &Init { features: InitFeatures::known() }); - nodes[j].node.peer_connected(&nodes[i].node.get_our_node_id(), &Init { features: InitFeatures::known() }); + nodes[i].node.peer_connected(&nodes[j].node.get_our_node_id(), &Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); + nodes[j].node.peer_connected(&nodes[i].node.get_our_node_id(), &Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); } } diff --git a/lightning/src/ln/chanmon_update_fail_tests.rs b/lightning/src/ln/chanmon_update_fail_tests.rs index cb39b64a4..aea171c1c 100644 --- a/lightning/src/ln/chanmon_update_fail_tests.rs +++ b/lightning/src/ln/chanmon_update_fail_tests.rs @@ -337,10 +337,10 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) { nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false); nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false); - nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]); assert_eq!(reestablish_1.len(), 1); - nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]); assert_eq!(reestablish_2.len(), 1); @@ -359,10 +359,10 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) { assert!(nodes[0].node.get_and_clear_pending_events().is_empty()); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); - nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]); assert_eq!(reestablish_1.len(), 1); - nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]); assert_eq!(reestablish_2.len(), 1); @@ -1111,8 +1111,8 @@ fn test_monitor_update_fail_reestablish() { commitment_signed_dance!(nodes[1], nodes[2], updates.commitment_signed, false); chanmon_cfgs[1].persister.set_update_ret(Err(ChannelMonitorUpdateErr::TemporaryFailure)); - nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); - nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); + nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let as_reestablish = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id()); let bs_reestablish = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id()); @@ -1130,8 +1130,8 @@ fn test_monitor_update_fail_reestablish() { nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false); nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false); - nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); - nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); + nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); assert!(as_reestablish == get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id())); assert!(bs_reestablish == get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id())); @@ -1303,8 +1303,8 @@ fn claim_while_disconnected_monitor_update_fail() { assert!(nodes[1].node.claim_funds(payment_preimage_1)); check_added_monitors!(nodes[1], 1); - nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); - nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); + nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let as_reconnect = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id()); let bs_reconnect = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id()); @@ -1430,8 +1430,8 @@ fn monitor_failed_no_reestablish_response() { nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false); nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false); - nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); - nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); + nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let as_reconnect = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id()); let bs_reconnect = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id()); @@ -1995,9 +1995,9 @@ fn test_pending_update_fee_ack_on_reconnect() { nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false); nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false); - nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known() }); + nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); let as_connect_msg = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id()); - nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known() }); + nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); let bs_connect_msg = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id()); nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &as_connect_msg); @@ -2077,9 +2077,9 @@ fn do_update_fee_resend_test(deliver_update: bool, parallel_updates: bool) { nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false); nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false); - nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known() }); + nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); let as_connect_msg = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id()); - nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known() }); + nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); let bs_connect_msg = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id()); nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &as_connect_msg); @@ -2241,10 +2241,10 @@ fn do_channel_holding_cell_serialize(disconnect: bool, reload_a: bool) { nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false); // Now reconnect the two - nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]); assert_eq!(reestablish_1.len(), 1); - nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]); assert_eq!(reestablish_2.len(), 1); diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 0eaf244d0..d13bcac71 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -6494,8 +6494,8 @@ mod tests { let payer_pubkey = nodes[0].node.get_our_node_id(); let payee_pubkey = nodes[1].node.get_our_node_id(); - nodes[0].node.peer_connected(&payee_pubkey, &msgs::Init { features: InitFeatures::known() }); - nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known() }); + nodes[0].node.peer_connected(&payee_pubkey, &msgs::Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); + nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); let _chan = create_chan_between_nodes(&nodes[0], &nodes[1], InitFeatures::known(), InitFeatures::known()); let params = RouteParameters { @@ -6537,8 +6537,8 @@ mod tests { let payer_pubkey = nodes[0].node.get_our_node_id(); let payee_pubkey = nodes[1].node.get_our_node_id(); - nodes[0].node.peer_connected(&payee_pubkey, &msgs::Init { features: InitFeatures::known() }); - nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known() }); + nodes[0].node.peer_connected(&payee_pubkey, &msgs::Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); + nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); let _chan = create_chan_between_nodes(&nodes[0], &nodes[1], InitFeatures::known(), InitFeatures::known()); let params = RouteParameters { diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index 01f9db534..e710438e6 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -1638,8 +1638,8 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec(node_a: &Node<'a, 'b, 'c>, node_b: &Node<'a, 'b, 'c>, send_funding_locked: (bool, bool), pending_htlc_adds: (i64, i64), pending_htlc_claims: (usize, usize), pending_htlc_fails: (usize, usize), pending_cell_htlc_claims: (usize, usize), pending_cell_htlc_fails: (usize, usize), pending_raa: (bool, bool)) { - node_a.node.peer_connected(&node_b.node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + node_a.node.peer_connected(&node_b.node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let reestablish_1 = get_chan_reestablish_msgs!(node_a, node_b); - node_b.node.peer_connected(&node_a.node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + node_b.node.peer_connected(&node_a.node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let reestablish_2 = get_chan_reestablish_msgs!(node_b, node_a); if send_funding_locked.0 { diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index 48d56b43b..bc00ee021 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -3977,10 +3977,10 @@ fn test_drop_messages_peer_disconnect_dual_htlc() { nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false); nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false); - nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]); assert_eq!(reestablish_1.len(), 1); - nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]); assert_eq!(reestablish_2.len(), 1); @@ -4249,9 +4249,9 @@ fn test_no_txn_manager_serialize_deserialize() { assert_eq!(nodes[0].node.list_channels().len(), 1); check_added_monitors!(nodes[0], 1); - nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]); - nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]); nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]); @@ -4369,9 +4369,9 @@ fn test_manager_serialize_deserialize_events() { assert_eq!(nodes[0].node.list_channels().len(), 1); check_added_monitors!(nodes[0], 1); - nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]); - nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]); nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]); @@ -4564,9 +4564,9 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() { //... and we can even still claim the payment! claim_payment(&nodes[2], &[&nodes[0], &nodes[1]], our_payment_preimage); - nodes[3].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[3].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let reestablish = get_event_msg!(nodes[3], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id()); - nodes[0].node.peer_connected(&nodes[3].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[0].node.peer_connected(&nodes[3].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); nodes[0].node.handle_channel_reestablish(&nodes[3].node.get_our_node_id(), &reestablish); let msg_events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(msg_events.len(), 1); @@ -6611,10 +6611,10 @@ fn test_update_add_htlc_bolt2_receiver_check_repeated_id_ignore() { //Disconnect and Reconnect nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false); nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false); - nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]); assert_eq!(reestablish_1.len(), 1); - nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]); assert_eq!(reestablish_2.len(), 1); nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]); @@ -7250,8 +7250,8 @@ fn test_data_loss_protect() { check_added_monitors!(nodes[0], 1); - nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); - nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); + nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let reestablish_0 = get_chan_reestablish_msgs!(nodes[1], nodes[0]); @@ -7398,10 +7398,10 @@ fn test_announce_disable_channels() { } } // Reconnect peers - nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]); assert_eq!(reestablish_1.len(), 3); - nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]); assert_eq!(reestablish_2.len(), 3); @@ -7573,8 +7573,8 @@ fn test_priv_forwarding_rejection() { check_added_monitors!(nodes[1], 2); nodes[1].node = &nodes_1_deserialized; - nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known() }); - nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); + nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let as_reestablish = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id()); let bs_reestablish = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id()); nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &as_reestablish); @@ -7582,8 +7582,8 @@ fn test_priv_forwarding_rejection() { get_event_msg!(nodes[0], MessageSendEvent::SendChannelUpdate, nodes[1].node.get_our_node_id()); get_event_msg!(nodes[1], MessageSendEvent::SendChannelUpdate, nodes[0].node.get_our_node_id()); - nodes[1].node.peer_connected(&nodes[2].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known() }); - nodes[2].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[1].node.peer_connected(&nodes[2].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); + nodes[2].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let bs_reestablish = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[2].node.get_our_node_id()); let cs_reestablish = get_event_msg!(nodes[2], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id()); nodes[2].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &bs_reestablish); @@ -9273,8 +9273,8 @@ fn test_keysend_payments_to_private_node() { let payer_pubkey = nodes[0].node.get_our_node_id(); let payee_pubkey = nodes[1].node.get_our_node_id(); - nodes[0].node.peer_connected(&payee_pubkey, &msgs::Init { features: InitFeatures::known() }); - nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known() }); + nodes[0].node.peer_connected(&payee_pubkey, &msgs::Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); + nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); let _chan = create_chan_between_nodes(&nodes[0], &nodes[1], InitFeatures::known(), InitFeatures::known()); let params = RouteParameters { diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index 87944ccae..4eb6c5074 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -40,7 +40,7 @@ use io_extras::read_to_end; use util::events::MessageSendEventsProvider; use util::logger; -use util::ser::{Readable, Writeable, Writer, FixedLengthReader, HighZeroBytesDroppedVarInt}; +use util::ser::{Readable, Writeable, Writer, FixedLengthReader, HighZeroBytesDroppedVarInt, IterWriteWrapper}; use ln::{PaymentPreimage, PaymentHash, PaymentSecret}; @@ -75,6 +75,9 @@ pub enum DecodeError { pub struct Init { /// The relevant features which the sender supports pub features: InitFeatures, + /// The set of encoding types which our peer supports for gossip messages, excluding those we + /// do not understand. + pub gossip_compression_encodings: Vec, } /// An error message to be sent or received from a peer @@ -696,10 +699,22 @@ pub struct GossipTimestampFilter { } /// Encoding type for data compression of collections in gossip queries. -/// We do not support encoding_type=1 zlib serialization defined in BOLT #7. -enum EncodingType { +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum GossipEncodingType { + // Note that the enum variants here are defined to the values as used in message encodings. + // Because they currently match the bit indexes for the gossip encodings field in Init they are + // re-used there. If future encodings have different bit positions from encoding fields, code + // in Init (de-)serialization will need to adapt. + /// Uncompressed gossip query messages sent as-is on the wire Uncompressed = 0x00, + /// Gossip messages compressed with the zlib compression algorithm. + /// For security reasons, we do not implement this or recommend anyone implement this. + Zlib = 0x01, } +const KNOWN_ENCODINGS: [GossipEncodingType; 2] = [GossipEncodingType::Uncompressed, GossipEncodingType::Zlib]; +/// The gossip encodings which we support here. Note that due to security concerns we do not +/// support reading zlib-compressed gossip messages. +pub const SUPPORTED_GOSSIP_ENCODINGS: [GossipEncodingType; 1] = [GossipEncodingType::Uncompressed]; /// Used to put an error message in a LightningError #[derive(Clone, Debug)] @@ -1132,7 +1147,22 @@ impl Writeable for Init { // global_features gets the bottom 13 bits of our features, and local_features gets all of // our relevant feature bits. This keeps us compatible with old nodes. self.features.write_up_to_13(w)?; - self.features.write(w) + self.features.write(w)?; + let mut highest_gossip_encoding = 0; + for enc in self.gossip_compression_encodings.iter() { + highest_gossip_encoding = cmp::max(1 << (*enc as u8), highest_gossip_encoding); + } + let mut gossip_compression_bits = Vec::new(); + gossip_compression_bits.resize(((highest_gossip_encoding + 7) / 8) as usize, 0); + for enc in self.gossip_compression_encodings.iter() { + let val = 1u32 << (*enc as u8); + gossip_compression_bits[(val / 8) as usize] |= (val % 8) as u8; + } + encode_tlv_stream!(w, { + // 1 - networks field to list genesis block hashes + (3, IterWriteWrapper(gossip_compression_bits.iter()), required) + }); + Ok(()) } } @@ -1140,8 +1170,23 @@ impl Readable for Init { fn read(r: &mut R) -> Result { let global_features: InitFeatures = Readable::read(r)?; let features: InitFeatures = Readable::read(r)?; + let mut gossip_compression_bits = Some(Vec::::new()); + decode_tlv_stream!(r, { + // 1 - networks field to list genesis block hashes + (3, gossip_compression_bits, vec_type), + }); + let gossip_compression_bits = gossip_compression_bits.unwrap(); + let mut gossip_compression_encodings = Vec::new(); + for encoding in &KNOWN_ENCODINGS { + let enc_val = 1u32 << (*encoding as u8); + if gossip_compression_bits.len() <= (enc_val / 8) as usize { continue; } + if gossip_compression_bits[(enc_val / 8) as usize] & (enc_val % 8) as u8 != 0 { + gossip_compression_encodings.push(*encoding); + } + } Ok(Init { features: features.or(global_features), + gossip_compression_encodings, }) } } @@ -1617,7 +1662,7 @@ impl Readable for QueryShortChannelIds { // Must be encoding_type=0 uncompressed serialization. We do not // support encoding_type=1 zlib serialization. - if encoding_type != EncodingType::Uncompressed as u8 { + if encoding_type != GossipEncodingType::Uncompressed as u8 { return Err(DecodeError::UnsupportedCompression); } @@ -1651,7 +1696,7 @@ impl Writeable for QueryShortChannelIds { encoding_len.write(w)?; // We only support type=0 uncompressed serialization - (EncodingType::Uncompressed as u8).write(w)?; + (GossipEncodingType::Uncompressed as u8).write(w)?; for scid in self.short_channel_ids.iter() { scid.write(w)?; @@ -1697,7 +1742,7 @@ impl Readable for ReplyChannelRange { // Must be encoding_type=0 uncompressed serialization. We do not // support encoding_type=1 zlib serialization. - if encoding_type != EncodingType::Uncompressed as u8 { + if encoding_type != GossipEncodingType::Uncompressed as u8 { return Err(DecodeError::UnsupportedCompression); } @@ -1734,7 +1779,7 @@ impl Writeable for ReplyChannelRange { self.sync_complete.write(w)?; encoding_len.write(w)?; - (EncodingType::Uncompressed as u8).write(w)?; + (GossipEncodingType::Uncompressed as u8).write(w)?; for scid in self.short_channel_ids.iter() { scid.write(w)?; } @@ -1755,7 +1800,7 @@ mod tests { use ln::{PaymentPreimage, PaymentHash, PaymentSecret}; use ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures}; use ln::msgs; - use ln::msgs::{FinalOnionHopData, OptionalField, OnionErrorPacket, OnionHopDataFormat}; + use ln::msgs::{FinalOnionHopData, OptionalField, OnionErrorPacket, OnionHopDataFormat, GossipEncodingType}; use util::ser::{Writeable, Readable}; use bitcoin::hashes::hex::FromHex; @@ -2390,13 +2435,24 @@ mod tests { fn encoding_init() { assert_eq!(msgs::Init { features: InitFeatures::from_le_bytes(vec![0xFF, 0xFF, 0xFF]), - }.encode(), hex::decode("00023fff0003ffffff").unwrap()); + gossip_compression_encodings: Vec::new(), + }.encode(), hex::decode("00023fff0003ffffff0300").unwrap()); assert_eq!(msgs::Init { features: InitFeatures::from_le_bytes(vec![0xFF]), - }.encode(), hex::decode("0001ff0001ff").unwrap()); + gossip_compression_encodings: Vec::new(), + }.encode(), hex::decode("0001ff0001ff0300").unwrap()); + assert_eq!(msgs::Init { + features: InitFeatures::from_le_bytes(vec![]), + gossip_compression_encodings: Vec::new(), + }.encode(), hex::decode("000000000300").unwrap()); + assert_eq!(msgs::Init { + features: InitFeatures::from_le_bytes(vec![]), + gossip_compression_encodings: vec![GossipEncodingType::Uncompressed], + }.encode(), hex::decode("00000000030101").unwrap()); assert_eq!(msgs::Init { features: InitFeatures::from_le_bytes(vec![]), - }.encode(), hex::decode("00000000").unwrap()); + gossip_compression_encodings: vec![GossipEncodingType::Uncompressed, GossipEncodingType::Zlib], + }.encode(), hex::decode("00000000030103").unwrap()); } #[test] diff --git a/lightning/src/ln/payment_tests.rs b/lightning/src/ln/payment_tests.rs index 7c9ff3199..b6f908ff8 100644 --- a/lightning/src/ln/payment_tests.rs +++ b/lightning/src/ln/payment_tests.rs @@ -377,12 +377,12 @@ fn do_retry_with_no_persist(confirm_before_reload: bool) { assert_eq!(as_broadcasted_txn[0], as_commitment_tx); nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false); - nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known()}); + nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); // Now nodes[1] should send a channel reestablish, which nodes[0] will respond to with an // error, as the channel has hit the chain. - nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known()}); + nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }); let bs_reestablish = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id()); nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &bs_reestablish); let as_err = nodes[0].node.get_and_clear_pending_msg_events(); diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index 89f3e9ff5..d43059d1c 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -19,7 +19,7 @@ use bitcoin::secp256k1::key::{SecretKey,PublicKey}; use ln::features::InitFeatures; use ln::msgs; -use ln::msgs::{ChannelMessageHandler, LightningError, RoutingMessageHandler}; +use ln::msgs::{ChannelMessageHandler, LightningError, RoutingMessageHandler, SUPPORTED_GOSSIP_ENCODINGS}; use ln::channelmanager::{SimpleArcChannelManager, SimpleRefChannelManager}; use util::ser::{VecWriter, Writeable, Writer}; use ln::peer_channel_encryptor::{PeerChannelEncryptor,NextNoiseStep}; @@ -858,7 +858,7 @@ impl P peer.their_node_id = Some(their_node_id); insert_node_id!(); let features = InitFeatures::known(); - let resp = msgs::Init { features }; + let resp = msgs::Init { features, gossip_compression_encodings: SUPPORTED_GOSSIP_ENCODINGS.iter().map(|e| *e).collect() }; self.enqueue_message(peer, &resp); peer.awaiting_pong_timer_tick_intervals = 0; }, @@ -869,7 +869,7 @@ impl P peer.their_node_id = Some(their_node_id); insert_node_id!(); let features = InitFeatures::known(); - let resp = msgs::Init { features }; + let resp = msgs::Init { features, gossip_compression_encodings: SUPPORTED_GOSSIP_ENCODINGS.iter().map(|e| *e).collect() }; self.enqueue_message(peer, &resp); peer.awaiting_pong_timer_tick_intervals = 0; }, diff --git a/lightning/src/ln/shutdown_tests.rs b/lightning/src/ln/shutdown_tests.rs index db76a2c76..0f8b5a5ca 100644 --- a/lightning/src/ln/shutdown_tests.rs +++ b/lightning/src/ln/shutdown_tests.rs @@ -247,9 +247,9 @@ fn do_test_shutdown_rebroadcast(recv_count: u8) { nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false); nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false); - nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let node_0_reestablish = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id()); - nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let node_1_reestablish = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id()); nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &node_0_reestablish); @@ -307,9 +307,9 @@ fn do_test_shutdown_rebroadcast(recv_count: u8) { nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false); nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false); - nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); let node_1_2nd_reestablish = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id()); - nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() }); + nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), gossip_compression_encodings: Vec::new() }); if recv_count == 0 { // If all closing_signeds weren't delivered we can just resume where we left off... let node_0_2nd_reestablish = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id()); diff --git a/lightning/src/ln/wire.rs b/lightning/src/ln/wire.rs index d3cc257f5..83369ed95 100644 --- a/lightning/src/ln/wire.rs +++ b/lightning/src/ln/wire.rs @@ -491,7 +491,8 @@ mod tests { let mut reader = io::Cursor::new(buffer); let decoded_msg = read(&mut reader, &IgnoringMessageHandler{}).unwrap(); match decoded_msg { - Message::Init(msgs::Init { features }) => { + Message::Init(msgs::Init { features, gossip_compression_encodings }) => { + assert!(gossip_compression_encodings.is_empty()); assert!(features.supports_variable_length_onion()); assert!(features.supports_upfront_shutdown_script()); assert!(features.supports_gossip_queries()); diff --git a/lightning/src/routing/network_graph.rs b/lightning/src/routing/network_graph.rs index 4d33bbdee..9e47d22d6 100644 --- a/lightning/src/routing/network_graph.rs +++ b/lightning/src/routing/network_graph.rs @@ -2215,7 +2215,7 @@ mod tests { // It should ignore if gossip_queries feature is not enabled { - let init_msg = Init { features: InitFeatures::known().clear_gossip_queries() }; + let init_msg = Init { features: InitFeatures::known().clear_gossip_queries(), gossip_compression_encodings: Vec::new() }; net_graph_msg_handler.sync_routing_table(&node_id_1, &init_msg); let events = net_graph_msg_handler.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 0); @@ -2223,7 +2223,7 @@ mod tests { // It should send a query_channel_message with the correct information { - let init_msg = Init { features: InitFeatures::known() }; + let init_msg = Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }; net_graph_msg_handler.sync_routing_table(&node_id_1, &init_msg); let events = net_graph_msg_handler.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); @@ -2244,7 +2244,7 @@ mod tests { { let network_graph = create_network_graph(); let (secp_ctx, net_graph_msg_handler) = create_net_graph_msg_handler(&network_graph); - let init_msg = Init { features: InitFeatures::known() }; + let init_msg = Init { features: InitFeatures::known(), gossip_compression_encodings: Vec::new() }; for n in 1..7 { let node_privkey = &SecretKey::from_slice(&[n; 32]).unwrap(); let node_id = PublicKey::from_secret_key(&secp_ctx, node_privkey); -- 2.39.5