Skip to content

Commit e0f53ac

Browse files
committed
Pipe channel node information through to forward_broadcast_msg
Sadly, the lightning gossip protocol operates by always flooding peers with all the latest gossip they receive. For nodes with many peers, this can result in lots of duplicative gossip as they receive every message from every peer. As a results, some lightning implementations disable gossip with new peers after some threshold. This should mostly work as these peers expect to receive the latest gossip from their many other peers. However, in some cases an LDK node may wish to open public channels but only has a single connection to the bulk of the rest of the network - with one such peer which requests that it not receive any gossip. In that case, LDK would dutifully never send any gossip to its only connection to the outside world. We would still send gossip for channels with that peer as it would be sent as unicast gossip, but if we then open another connection to another peer which doesn't have any connection to the outside world any information on that channel wouldn't propagate. We've seen this setup on some LSPs, where they have a public node and then an LSP which only connects through that public node, but expects to open public channels to its LSP clients. In the next commit we'll start forwarding such gossip to all peers by ignoring peer gossip limitations about all of our own channels. Here we do the final prep work, passing the two sides of each channel back from `handle_channel_update` calls and into `forward_broadcast_msg`.
1 parent 2c8e001 commit e0f53ac

File tree

6 files changed

+75
-49
lines changed

6 files changed

+75
-49
lines changed

lightning-net-tokio/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -660,8 +660,8 @@ mod tests {
660660
}
661661
fn handle_channel_update(
662662
&self, _their_node_id: Option<PublicKey>, _msg: &ChannelUpdate,
663-
) -> Result<bool, LightningError> {
664-
Ok(false)
663+
) -> Result<Option<(NodeId, NodeId)>, LightningError> {
664+
Ok(None)
665665
}
666666
fn get_next_channel_announcement(
667667
&self, _starting_point: u64,

lightning/src/ln/msgs.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2199,13 +2199,13 @@ pub trait RoutingMessageHandler: BaseMessageHandler {
21992199
fn handle_channel_announcement(
22002200
&self, their_node_id: Option<PublicKey>, msg: &ChannelAnnouncement,
22012201
) -> Result<bool, LightningError>;
2202-
/// Handle an incoming `channel_update` message, returning true if it should be forwarded on,
2203-
/// `false` or returning an `Err` otherwise.
2202+
/// Handle an incoming `channel_update` message, returning the node IDs of the channel
2203+
/// participants if the message should be forwarded on, `None` or returning an `Err` otherwise.
22042204
///
22052205
/// If `their_node_id` is `None`, the message was generated by our own local node.
22062206
fn handle_channel_update(
22072207
&self, their_node_id: Option<PublicKey>, msg: &ChannelUpdate,
2208-
) -> Result<bool, LightningError>;
2208+
) -> Result<Option<(NodeId, NodeId)>, LightningError>;
22092209
/// Gets channel announcements and updates required to dump our routing table to a remote node,
22102210
/// starting at the `short_channel_id` indicated by `starting_point` and including announcements
22112211
/// for a single channel.

lightning/src/ln/peer_handler.rs

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,8 @@ impl RoutingMessageHandler for IgnoringMessageHandler {
157157
}
158158
fn handle_channel_update(
159159
&self, _their_node_id: Option<PublicKey>, _msg: &msgs::ChannelUpdate,
160-
) -> Result<bool, LightningError> {
161-
Ok(false)
160+
) -> Result<Option<(NodeId, NodeId)>, LightningError> {
161+
Ok(None)
162162
}
163163
fn get_next_channel_announcement(
164164
&self, _starting_point: u64,
@@ -611,6 +611,19 @@ where
611611
pub send_only_message_handler: SM,
612612
}
613613

614+
/// A gossip message to be forwarded to all peers.
615+
enum BroadcastGossipMessage {
616+
ChannelAnnouncement(msgs::ChannelAnnouncement),
617+
NodeAnnouncement(msgs::NodeAnnouncement),
618+
ChannelUpdate {
619+
msg: msgs::ChannelUpdate,
620+
/// One of the two channel endpoints.
621+
node_id_1: NodeId,
622+
/// One of the two channel endpoints.
623+
node_id_2: NodeId,
624+
},
625+
}
626+
614627
/// Provides an object which can be used to send data to and which uniquely identifies a connection
615628
/// to a remote host. You will need to be able to generate multiple of these which meet Eq and
616629
/// implement Hash to meet the PeerManager API.
@@ -2045,10 +2058,7 @@ where
20452058
message: wire::Message<
20462059
<<CMH as Deref>::Target as wire::CustomMessageReader>::CustomMessage,
20472060
>,
2048-
) -> Result<
2049-
Option<wire::Message<<<CMH as Deref>::Target as wire::CustomMessageReader>::CustomMessage>>,
2050-
MessageHandlingError,
2051-
> {
2061+
) -> Result<Option<BroadcastGossipMessage>, MessageHandlingError> {
20522062
let their_node_id = peer_lock
20532063
.their_node_id
20542064
.expect("We know the peer's public key by the time we receive messages")
@@ -2390,10 +2400,7 @@ where
23902400
<<CMH as Deref>::Target as wire::CustomMessageReader>::CustomMessage,
23912401
>,
23922402
their_node_id: PublicKey, logger: &WithContext<'a, L>,
2393-
) -> Result<
2394-
Option<wire::Message<<<CMH as Deref>::Target as wire::CustomMessageReader>::CustomMessage>>,
2395-
MessageHandlingError,
2396-
> {
2403+
) -> Result<Option<BroadcastGossipMessage>, MessageHandlingError> {
23972404
if is_gossip_msg(message.type_id()) {
23982405
log_gossip!(logger, "Received message {:?} from {}", message, their_node_id);
23992406
} else {
@@ -2575,7 +2582,7 @@ where
25752582
.handle_channel_announcement(Some(their_node_id), &msg)
25762583
.map_err(|e| -> MessageHandlingError { e.into() })?
25772584
{
2578-
should_forward = Some(wire::Message::ChannelAnnouncement(msg));
2585+
should_forward = Some(BroadcastGossipMessage::ChannelAnnouncement(msg));
25792586
}
25802587
self.update_gossip_backlogged();
25812588
},
@@ -2585,7 +2592,7 @@ where
25852592
.handle_node_announcement(Some(their_node_id), &msg)
25862593
.map_err(|e| -> MessageHandlingError { e.into() })?
25872594
{
2588-
should_forward = Some(wire::Message::NodeAnnouncement(msg));
2595+
should_forward = Some(BroadcastGossipMessage::NodeAnnouncement(msg));
25892596
}
25902597
self.update_gossip_backlogged();
25912598
},
@@ -2594,11 +2601,12 @@ where
25942601
chan_handler.handle_channel_update(their_node_id, &msg);
25952602

25962603
let route_handler = &self.message_handler.route_handler;
2597-
if route_handler
2604+
if let Some((node_id_1, node_id_2)) = route_handler
25982605
.handle_channel_update(Some(their_node_id), &msg)
25992606
.map_err(|e| -> MessageHandlingError { e.into() })?
26002607
{
2601-
should_forward = Some(wire::Message::ChannelUpdate(msg));
2608+
should_forward =
2609+
Some(BroadcastGossipMessage::ChannelUpdate { msg, node_id_1, node_id_2 });
26022610
}
26032611
self.update_gossip_backlogged();
26042612
},
@@ -2652,12 +2660,11 @@ where
26522660
/// unless `allow_large_buffer` is set, in which case the message will be treated as critical
26532661
/// and delivered no matter the available buffer space.
26542662
fn forward_broadcast_msg(
2655-
&self, peers: &HashMap<Descriptor, Mutex<Peer>>,
2656-
msg: &wire::Message<<<CMH as Deref>::Target as wire::CustomMessageReader>::CustomMessage>,
2663+
&self, peers: &HashMap<Descriptor, Mutex<Peer>>, msg: &BroadcastGossipMessage,
26572664
except_node: Option<&PublicKey>, allow_large_buffer: bool,
26582665
) {
26592666
match msg {
2660-
wire::Message::ChannelAnnouncement(ref msg) => {
2667+
BroadcastGossipMessage::ChannelAnnouncement(ref msg) => {
26612668
log_gossip!(self.logger, "Sending message to all peers except {:?} or the announced channel's counterparties: {:?}", except_node, msg);
26622669
let encoded_msg = encode_msg!(msg);
26632670

@@ -2696,7 +2703,7 @@ where
26962703
peer.gossip_broadcast_buffer.push_back(encoded_message);
26972704
}
26982705
},
2699-
wire::Message::NodeAnnouncement(ref msg) => {
2706+
BroadcastGossipMessage::NodeAnnouncement(ref msg) => {
27002707
log_gossip!(
27012708
self.logger,
27022709
"Sending message to all peers except {:?} or the announced node: {:?}",
@@ -2738,7 +2745,7 @@ where
27382745
peer.gossip_broadcast_buffer.push_back(encoded_message);
27392746
}
27402747
},
2741-
wire::Message::ChannelUpdate(ref msg) => {
2748+
BroadcastGossipMessage::ChannelUpdate { msg, node_id_1: _, node_id_2: _ } => {
27422749
log_gossip!(
27432750
self.logger,
27442751
"Sending message to all peers except {:?}: {:?}",
@@ -2775,9 +2782,6 @@ where
27752782
peer.gossip_broadcast_buffer.push_back(encoded_message);
27762783
}
27772784
},
2778-
_ => {
2779-
debug_assert!(false, "We shouldn't attempt to forward anything but gossip messages")
2780-
},
27812785
}
27822786
}
27832787

@@ -3129,13 +3133,15 @@ where
31293133
},
31303134
MessageSendEvent::BroadcastChannelAnnouncement { msg, update_msg } => {
31313135
log_debug!(self.logger, "Handling BroadcastChannelAnnouncement event in peer_handler for short channel id {}", msg.contents.short_channel_id);
3136+
let node_id_1 = msg.contents.node_id_1;
3137+
let node_id_2 = msg.contents.node_id_2;
31323138
match route_handler.handle_channel_announcement(None, &msg) {
31333139
Ok(_)
31343140
| Err(LightningError {
31353141
action: msgs::ErrorAction::IgnoreDuplicateGossip,
31363142
..
31373143
}) => {
3138-
let forward = wire::Message::ChannelAnnouncement(msg);
3144+
let forward = BroadcastGossipMessage::ChannelAnnouncement(msg);
31393145
self.forward_broadcast_msg(
31403146
peers,
31413147
&forward,
@@ -3152,7 +3158,11 @@ where
31523158
action: msgs::ErrorAction::IgnoreDuplicateGossip,
31533159
..
31543160
}) => {
3155-
let forward = wire::Message::ChannelUpdate(msg);
3161+
let forward = BroadcastGossipMessage::ChannelUpdate {
3162+
msg,
3163+
node_id_1,
3164+
node_id_2,
3165+
};
31563166
self.forward_broadcast_msg(
31573167
peers,
31583168
&forward,
@@ -3164,15 +3174,19 @@ where
31643174
}
31653175
}
31663176
},
3167-
MessageSendEvent::BroadcastChannelUpdate { msg, .. } => {
3177+
MessageSendEvent::BroadcastChannelUpdate { msg, node_id_1, node_id_2 } => {
31683178
log_debug!(self.logger, "Handling BroadcastChannelUpdate event in peer_handler for contents {:?}", msg.contents);
31693179
match route_handler.handle_channel_update(None, &msg) {
31703180
Ok(_)
31713181
| Err(LightningError {
31723182
action: msgs::ErrorAction::IgnoreDuplicateGossip,
31733183
..
31743184
}) => {
3175-
let forward = wire::Message::ChannelUpdate(msg);
3185+
let forward = BroadcastGossipMessage::ChannelUpdate {
3186+
msg,
3187+
node_id_1,
3188+
node_id_2,
3189+
};
31763190
self.forward_broadcast_msg(
31773191
peers,
31783192
&forward,
@@ -3191,7 +3205,7 @@ where
31913205
action: msgs::ErrorAction::IgnoreDuplicateGossip,
31923206
..
31933207
}) => {
3194-
let forward = wire::Message::NodeAnnouncement(msg);
3208+
let forward = BroadcastGossipMessage::NodeAnnouncement(msg);
31953209
self.forward_broadcast_msg(
31963210
peers,
31973211
&forward,
@@ -3668,7 +3682,7 @@ where
36683682
let _ = self.message_handler.route_handler.handle_node_announcement(None, &msg);
36693683
self.forward_broadcast_msg(
36703684
&*self.peers.read().unwrap(),
3671-
&wire::Message::NodeAnnouncement(msg),
3685+
&BroadcastGossipMessage::NodeAnnouncement(msg),
36723686
None,
36733687
true,
36743688
);

lightning/src/routing/gossip.rs

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -556,9 +556,12 @@ where
556556

557557
fn handle_channel_update(
558558
&self, _their_node_id: Option<PublicKey>, msg: &msgs::ChannelUpdate,
559-
) -> Result<bool, LightningError> {
560-
self.network_graph.update_channel(msg)?;
561-
Ok(msg.contents.excess_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY)
559+
) -> Result<Option<(NodeId, NodeId)>, LightningError> {
560+
match self.network_graph.update_channel(msg) {
561+
Ok(nodes) if msg.contents.excess_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY => Ok(nodes),
562+
Ok(_) => Ok(None),
563+
Err(e) => Err(e),
564+
}
562565
}
563566

564567
fn get_next_channel_announcement(
@@ -2433,7 +2436,11 @@ where
24332436
///
24342437
/// If not built with `std`, any updates with a timestamp more than two weeks in the past or
24352438
/// materially in the future will be rejected.
2436-
pub fn update_channel(&self, msg: &msgs::ChannelUpdate) -> Result<(), LightningError> {
2439+
///
2440+
/// Returns the [`NodeId`]s of both sides of the channel if it was applied.
2441+
pub fn update_channel(
2442+
&self, msg: &msgs::ChannelUpdate,
2443+
) -> Result<Option<(NodeId, NodeId)>, LightningError> {
24372444
self.update_channel_internal(&msg.contents, Some(&msg), Some(&msg.signature), false)
24382445
}
24392446

@@ -2443,9 +2450,11 @@ where
24432450
///
24442451
/// If not built with `std`, any updates with a timestamp more than two weeks in the past or
24452452
/// materially in the future will be rejected.
2453+
///
2454+
/// Returns the [`NodeId`]s of both sides of the channel if it was applied.
24462455
pub fn update_channel_unsigned(
24472456
&self, msg: &msgs::UnsignedChannelUpdate,
2448-
) -> Result<(), LightningError> {
2457+
) -> Result<Option<(NodeId, NodeId)>, LightningError> {
24492458
self.update_channel_internal(msg, None, None, false)
24502459
}
24512460

@@ -2456,13 +2465,14 @@ where
24562465
/// If not built with `std`, any updates with a timestamp more than two weeks in the past or
24572466
/// materially in the future will be rejected.
24582467
pub fn verify_channel_update(&self, msg: &msgs::ChannelUpdate) -> Result<(), LightningError> {
2459-
self.update_channel_internal(&msg.contents, Some(&msg), Some(&msg.signature), true)
2468+
self.update_channel_internal(&msg.contents, Some(&msg), Some(&msg.signature), true)?;
2469+
Ok(())
24602470
}
24612471

24622472
fn update_channel_internal(
24632473
&self, msg: &msgs::UnsignedChannelUpdate, full_msg: Option<&msgs::ChannelUpdate>,
24642474
sig: Option<&secp256k1::ecdsa::Signature>, only_verify: bool,
2465-
) -> Result<(), LightningError> {
2475+
) -> Result<Option<(NodeId, NodeId)>, LightningError> {
24662476
let chan_enabled = msg.channel_flags & (1 << 1) != (1 << 1);
24672477

24682478
if msg.chain_hash != self.chain_hash {
@@ -2602,7 +2612,7 @@ where
26022612
}
26032613

26042614
if only_verify {
2605-
return Ok(());
2615+
return Ok(None);
26062616
}
26072617

26082618
let mut channels = self.channels.write().unwrap();
@@ -2633,9 +2643,11 @@ where
26332643
} else {
26342644
channel.one_to_two = new_channel_info;
26352645
}
2636-
}
26372646

2638-
Ok(())
2647+
Ok(Some((channel.node_one, channel.node_two)))
2648+
} else {
2649+
Ok(None)
2650+
}
26392651
}
26402652

26412653
fn remove_channel_in_nodes_callback<RM: FnMut(IndexedMapOccupiedEntry<NodeId, NodeInfo>)>(
@@ -3180,7 +3192,7 @@ pub(crate) mod tests {
31803192
let valid_channel_update = get_signed_channel_update(|_| {}, node_1_privkey, &secp_ctx);
31813193
network_graph.verify_channel_update(&valid_channel_update).unwrap();
31823194
match gossip_sync.handle_channel_update(Some(node_1_pubkey), &valid_channel_update) {
3183-
Ok(res) => assert!(res),
3195+
Ok(res) => assert!(res.is_some()),
31843196
_ => panic!(),
31853197
};
31863198

@@ -3202,9 +3214,9 @@ pub(crate) mod tests {
32023214
node_1_privkey,
32033215
&secp_ctx,
32043216
);
3205-
// Return false because contains excess data
3217+
// Update is accepted but won't be relayed because contains excess data
32063218
match gossip_sync.handle_channel_update(Some(node_1_pubkey), &valid_channel_update) {
3207-
Ok(res) => assert!(!res),
3219+
Ok(res) => assert!(res.is_none()),
32083220
_ => panic!(),
32093221
};
32103222

lightning/src/routing/test_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ pub(crate) fn update_channel(
111111
};
112112

113113
match gossip_sync.handle_channel_update(Some(node_pubkey), &valid_channel_update) {
114-
Ok(res) => assert!(res),
114+
Ok(res) => assert!(res.is_some()),
115115
Err(e) => panic!("{e:?}")
116116
};
117117
}

lightning/src/util/test_utils.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,9 +1522,9 @@ impl msgs::RoutingMessageHandler for TestRoutingMessageHandler {
15221522
}
15231523
fn handle_channel_update(
15241524
&self, _their_node_id: Option<PublicKey>, _msg: &msgs::ChannelUpdate,
1525-
) -> Result<bool, msgs::LightningError> {
1525+
) -> Result<Option<(NodeId, NodeId)>, msgs::LightningError> {
15261526
self.chan_upds_recvd.fetch_add(1, Ordering::AcqRel);
1527-
Ok(true)
1527+
Ok(Some((NodeId::from_slice(&[2; 33]).unwrap(), NodeId::from_slice(&[3; 33]).unwrap())))
15281528
}
15291529
fn get_next_channel_announcement(
15301530
&self, starting_point: u64,

0 commit comments

Comments
 (0)