Skip to content

Commit 0da7bbd

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 41e6eba commit 0da7bbd

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> UtxoLookup for FuzzChainSource<'_, '_, Out> {
9999
&[1, _] => UtxoResult::Sync(Err(UtxoLookupError::UnknownTx)),
100100
&[2, _] => {
101101
let future = UtxoFuture::new();
102-
future.resolve(self.net_graph, Ok(txo_res));
102+
future.resolve_without_forwarding(self.net_graph, Ok(txo_res));
103103
UtxoResult::Async(future.clone())
104104
},
105105
&[3, _] => {
106106
let future = UtxoFuture::new();
107-
future.resolve(self.net_graph, Err(UtxoLookupError::UnknownTx));
107+
future.resolve_without_forwarding(self.net_graph, Err(UtxoLookupError::UnknownTx));
108108
UtxoResult::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
@@ -272,6 +272,36 @@ where U::Target: UtxoLookup, L::Target: Logger
272272
false
273273
}
274274
}
275+
276+
/// Used to broadcast forward gossip messages which were validated async.
277+
///
278+
/// Note that this will ignore events other than `Broadcast*` or messages with too much excess
279+
/// data.
280+
pub(super) fn forward_gossip_msg(&self, mut ev: MessageSendEvent) {
281+
match &mut ev {
282+
MessageSendEvent::BroadcastChannelAnnouncement { msg, ref mut update_msg } => {
283+
if msg.contents.excess_data.len() > MAX_EXCESS_BYTES_FOR_RELAY { return; }
284+
if update_msg.as_ref()
285+
.map(|msg| msg.contents.excess_data.len()).unwrap_or(0) > MAX_EXCESS_BYTES_FOR_RELAY
286+
{
287+
*update_msg = None;
288+
}
289+
},
290+
MessageSendEvent::BroadcastChannelUpdate { msg } => {
291+
if msg.contents.excess_data.len() > MAX_EXCESS_BYTES_FOR_RELAY { return; }
292+
},
293+
MessageSendEvent::BroadcastNodeAnnouncement { msg } => {
294+
if msg.contents.excess_data.len() > MAX_EXCESS_BYTES_FOR_RELAY ||
295+
msg.contents.excess_address_data.len() > MAX_EXCESS_BYTES_FOR_RELAY ||
296+
msg.contents.excess_data.len() + msg.contents.excess_address_data.len() > MAX_EXCESS_BYTES_FOR_RELAY
297+
{
298+
return;
299+
}
300+
},
301+
_ => return,
302+
}
303+
self.pending_events.lock().unwrap().push(ev);
304+
}
275305
}
276306

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

lightning/src/routing/utxo.rs

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ use bitcoin::hashes::hex::ToHex;
1818

1919
use crate::ln::chan_utils::make_funding_redeemscript_from_slices;
2020
use crate::ln::msgs::{self, LightningError, ErrorAction};
21-
use crate::routing::gossip::{NetworkGraph, NodeId};
21+
use crate::routing::gossip::{NetworkGraph, NodeId, P2PGossipSync};
22+
use crate::util::events::MessageSendEvent;
2223
use crate::util::logger::{Level, Logger};
2324
use crate::util::ser::Writeable;
2425

@@ -144,8 +145,32 @@ impl UtxoFuture {
144145
}
145146

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

161186
let announcement_msg = match async_messages.channel_announce.as_ref().unwrap() {
@@ -172,14 +197,22 @@ impl UtxoFuture {
172197
async_messages.latest_channel_update_b.take())
173198
};
174199

200+
let mut res = [None, None, None, None, None];
201+
let mut res_idx = 0;
202+
175203
// Now that we've updated our internal state, pass the pending messages back through the
176204
// network graph with a different `UtxoLookup` which will resolve immediately.
177205
// Note that we ignore errors as we don't disconnect peers anyway, so there's nothing to do
178206
// with them.
179207
let resolver = UtxoResolver(result);
180208
match announcement {
181209
ChannelAnnouncement::Full(signed_msg) => {
182-
let _ = graph.update_channel_from_announcement(&signed_msg, &Some(&resolver));
210+
if graph.update_channel_from_announcement(&signed_msg, &Some(&resolver)).is_ok() {
211+
res[res_idx] = Some(MessageSendEvent::BroadcastChannelAnnouncement {
212+
msg: signed_msg, update_msg: None,
213+
});
214+
res_idx += 1;
215+
}
183216
},
184217
ChannelAnnouncement::Unsigned(msg) => {
185218
let _ = graph.update_channel_from_unsigned_announcement(&msg, &Some(&resolver));
@@ -189,7 +222,12 @@ impl UtxoFuture {
189222
for announce in core::iter::once(node_a).chain(core::iter::once(node_b)) {
190223
match announce {
191224
Some(NodeAnnouncement::Full(signed_msg)) => {
192-
let _ = graph.update_node_from_announcement(&signed_msg);
225+
if graph.update_node_from_announcement(&signed_msg).is_ok() {
226+
res[res_idx] = Some(MessageSendEvent::BroadcastNodeAnnouncement {
227+
msg: signed_msg,
228+
});
229+
res_idx += 1;
230+
}
193231
},
194232
Some(NodeAnnouncement::Unsigned(msg)) => {
195233
let _ = graph.update_node_from_unsigned_announcement(&msg);
@@ -201,14 +239,21 @@ impl UtxoFuture {
201239
for update in core::iter::once(update_a).chain(core::iter::once(update_b)) {
202240
match update {
203241
Some(ChannelUpdate::Full(signed_msg)) => {
204-
let _ = graph.update_channel(&signed_msg);
242+
if graph.update_channel(&signed_msg).is_ok() {
243+
res[res_idx] = Some(MessageSendEvent::BroadcastChannelUpdate {
244+
msg: signed_msg,
245+
});
246+
res_idx += 1;
247+
}
205248
},
206249
Some(ChannelUpdate::Unsigned(msg)) => {
207250
let _ = graph.update_channel_unsigned(&msg);
208251
},
209252
None => {},
210253
}
211254
}
255+
256+
res
212257
}
213258
}
214259

0 commit comments

Comments
 (0)