Skip to content

Commit f867252

Browse files
committed
Forward gossip messages which were verified asynchronously
Gossip messages which were verified against the chain asynchronously should still be forwarded to peers, but must now go out via a new `P2PGossipSync` parameter in the `AccessResolver::resolve` method, allowing us to wire them up to the `P2PGossipSync`'s `MessageSendEventsProvider` implementation.
1 parent 9b302f9 commit f867252

File tree

3 files changed

+83
-8
lines changed

3 files changed

+83
-8
lines changed

fuzz/src/router.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,12 @@ impl<Out: test_logger::Output> ChainAccess for FuzzChainSource<'_, '_, Out> {
9999
&[1, _] => ChainAccessResult::Sync(Err(ChainAccessError::UnknownTx)),
100100
&[2, _] => {
101101
let future = AccessFuture::new();
102-
future.resolve(self.net_graph, Ok(txo_res));
102+
future.resolve_without_forwarding(self.net_graph, Ok(txo_res));
103103
ChainAccessResult::Async(future.clone())
104104
},
105105
&[3, _] => {
106106
let future = AccessFuture::new();
107-
future.resolve(self.net_graph, Err(ChainAccessError::UnknownTx));
107+
future.resolve_without_forwarding(self.net_graph, Err(ChainAccessError::UnknownTx));
108108
ChainAccessResult::Async(future.clone())
109109
},
110110
&[4, _] => {

lightning/src/routing/gossip.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,36 @@ where C::Target: ChainAccess, L::Target: Logger
268268
false
269269
}
270270
}
271+
272+
/// Used to broadcast forward gossip messages which were validated async.
273+
///
274+
/// Note that this will ignore events other than `Broadcast*` or messages with too much excess
275+
/// data.
276+
pub(super) fn forward_gossip_msg(&self, mut ev: MessageSendEvent) {
277+
match &mut ev {
278+
MessageSendEvent::BroadcastChannelAnnouncement { msg, ref mut update_msg } => {
279+
if msg.contents.excess_data.len() > MAX_EXCESS_BYTES_FOR_RELAY { return; }
280+
if update_msg.as_ref()
281+
.map(|msg| msg.contents.excess_data.len()).unwrap_or(0) > MAX_EXCESS_BYTES_FOR_RELAY
282+
{
283+
*update_msg = None;
284+
}
285+
},
286+
MessageSendEvent::BroadcastChannelUpdate { msg } => {
287+
if msg.contents.excess_data.len() > MAX_EXCESS_BYTES_FOR_RELAY { return; }
288+
},
289+
MessageSendEvent::BroadcastNodeAnnouncement { msg } => {
290+
if msg.contents.excess_data.len() > MAX_EXCESS_BYTES_FOR_RELAY ||
291+
msg.contents.excess_address_data.len() > MAX_EXCESS_BYTES_FOR_RELAY ||
292+
msg.contents.excess_data.len() + msg.contents.excess_address_data.len() > MAX_EXCESS_BYTES_FOR_RELAY
293+
{
294+
return;
295+
}
296+
},
297+
_ => return,
298+
}
299+
self.pending_events.lock().unwrap().push(ev);
300+
}
271301
}
272302

273303
impl<L: Deref> NetworkGraph<L> where L::Target: Logger {

lightning/src/routing/gossip_checking.rs

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ use bitcoin::secp256k1::PublicKey;
2020

2121
use crate::ln::chan_utils::make_funding_redeemscript;
2222
use crate::ln::msgs::{self, LightningError, ErrorAction};
23-
use crate::routing::gossip::{NetworkGraph, NodeId};
23+
use crate::routing::gossip::{NetworkGraph, NodeId, P2PGossipSync};
24+
use crate::util::events::MessageSendEvent;
2425
use crate::util::logger::{Level, Logger};
2526
use crate::util::ser::Writeable;
2627

@@ -147,8 +148,32 @@ impl AccessFuture {
147148
}
148149

149150
/// Resolves this future against the given `graph` and with the given `result`.
150-
pub fn resolve<L: Deref>(&self, graph: &NetworkGraph<L>, result: Result<TxOut, ChainAccessError>)
151+
///
152+
/// This is identical to calling [`AccessFuture::resolve`] with a dummy `gossip`, disabling
153+
/// forwarding the validated gossip message onwards to peers.
154+
pub fn resolve_without_forwarding<L: Deref>(&self,
155+
graph: &NetworkGraph<L>, result: Result<TxOut, ChainAccessError>)
151156
where L::Target: Logger {
157+
self.do_resolve(graph, result);
158+
}
159+
160+
/// Resolves this future against the given `graph` and with the given `result`.
161+
///
162+
/// The given `gossip` is used to broadcast any validated messages onwards to all peers which
163+
/// have available buffer space.
164+
pub fn resolve<L: Deref, G: Deref<Target=NetworkGraph<L>>, C: Deref, GS: Deref<Target = P2PGossipSync<G, C, L>>>(&self,
165+
graph: &NetworkGraph<L>, gossip: GS, result: Result<TxOut, ChainAccessError>
166+
) where L::Target: Logger, C::Target: ChainAccess {
167+
let mut res = self.do_resolve(graph, result);
168+
for msg_opt in res.iter_mut() {
169+
if let Some(msg) = msg_opt.take() {
170+
gossip.forward_gossip_msg(msg);
171+
}
172+
}
173+
}
174+
175+
fn do_resolve<L: Deref>(&self, graph: &NetworkGraph<L>, result: Result<TxOut, ChainAccessError>)
176+
-> [Option<MessageSendEvent>; 5] where L::Target: Logger {
152177
let (announcement, node_a, node_b, update_a, update_b) = {
153178
let mut pending_checks = graph.pending_checks.internal.lock().unwrap();
154179
let mut async_messages = self.state.lock().unwrap();
@@ -158,7 +183,7 @@ impl AccessFuture {
158183
// `channel_announce` yet. That's okay, we can set the `complete` field which it will
159184
// check once it gets control again.
160185
async_messages.complete = Some(result);
161-
return;
186+
return [None, None, None, None, None];
162187
}
163188

164189
let announcement_msg = match async_messages.channel_announce.as_ref().unwrap() {
@@ -175,14 +200,22 @@ impl AccessFuture {
175200
async_messages.latest_channel_update_b.take())
176201
};
177202

203+
let mut res = [None, None, None, None, None];
204+
let mut res_idx = 0;
205+
178206
// Now that we've updated our internal state, pass the pending messages back through the
179207
// network graph with a different `ChainAccess` which will resolve immediately.
180208
// Note that we ignore errors as we don't disconnect peers anyway, so there's nothing to do
181209
// with them.
182210
let resolver = AccessResolver(result);
183211
match announcement {
184212
ChannelAnnouncement::Full(signed_msg) => {
185-
let _ = graph.update_channel_from_announcement(&signed_msg, &Some(&resolver));
213+
if graph.update_channel_from_announcement(&signed_msg, &Some(&resolver)).is_ok() {
214+
res[res_idx] = Some(MessageSendEvent::BroadcastChannelAnnouncement {
215+
msg: signed_msg, update_msg: None,
216+
});
217+
res_idx += 1;
218+
}
186219
},
187220
ChannelAnnouncement::Unsigned(msg) => {
188221
let _ = graph.update_channel_from_unsigned_announcement(&msg, &Some(&resolver));
@@ -192,7 +225,12 @@ impl AccessFuture {
192225
for announce in core::iter::once(node_a).chain(core::iter::once(node_b)) {
193226
match announce {
194227
Some(NodeAnnouncement::Full(signed_msg)) => {
195-
let _ = graph.update_node_from_announcement(&signed_msg);
228+
if graph.update_node_from_announcement(&signed_msg).is_ok() {
229+
res[res_idx] = Some(MessageSendEvent::BroadcastNodeAnnouncement {
230+
msg: signed_msg,
231+
});
232+
res_idx += 1;
233+
}
196234
},
197235
Some(NodeAnnouncement::Unsigned(msg)) => {
198236
let _ = graph.update_node_from_unsigned_announcement(&msg);
@@ -204,14 +242,21 @@ impl AccessFuture {
204242
for update in core::iter::once(update_a).chain(core::iter::once(update_b)) {
205243
match update {
206244
Some(ChannelUpdate::Full(signed_msg)) => {
207-
let _ = graph.update_channel(&signed_msg);
245+
if graph.update_channel(&signed_msg).is_ok() {
246+
res[res_idx] = Some(MessageSendEvent::BroadcastChannelUpdate {
247+
msg: signed_msg,
248+
});
249+
res_idx += 1;
250+
}
208251
},
209252
Some(ChannelUpdate::Unsigned(msg)) => {
210253
let _ = graph.update_channel_unsigned(&msg);
211254
},
212255
None => {},
213256
}
214257
}
258+
259+
res
215260
}
216261
}
217262

0 commit comments

Comments
 (0)