Skip to content

Commit b56b4ad

Browse files
committed
[fuzz] Make router_target a bit easier for fuzzers to explore
It turns out (somewhat obviously) that expecting a fuzzer to correctly build multiple signatures which verify against multiple public keys in the same message was a bit too daunting, so we now skip message signatures in routing messages. We also take this opportunity to simplify the target itself somewhat, avoiding reading public keys over and over and instead generating routes to all the public keys that appeared in messages while running.
1 parent c53d8a3 commit b56b4ad

File tree

1 file changed

+46
-41
lines changed

1 file changed

+46
-41
lines changed

fuzz/src/router.rs

+46-41
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,22 @@ use bitcoin::blockdata::script::Builder;
1111
use bitcoin::blockdata::transaction::TxOut;
1212
use bitcoin::hash_types::BlockHash;
1313

14+
use bitcoin::secp256k1;
15+
1416
use lightning::chain;
1517
use lightning::ln::channelmanager::ChannelDetails;
1618
use lightning::ln::features::InitFeatures;
1719
use lightning::ln::msgs;
18-
use lightning::ln::msgs::RoutingMessageHandler;
1920
use lightning::routing::router::{get_route, RouteHint};
2021
use lightning::util::logger::Logger;
2122
use lightning::util::ser::Readable;
22-
use lightning::routing::network_graph::{NetGraphMsgHandler, RoutingFees};
23+
use lightning::routing::network_graph::{NetworkGraph, RoutingFees};
2324

2425
use bitcoin::secp256k1::key::PublicKey;
2526

2627
use utils::test_logger;
2728

29+
use std::collections::HashSet;
2830
use std::sync::Arc;
2931
use std::sync::atomic::{AtomicUsize, Ordering};
3032

@@ -150,16 +152,12 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
150152
}
151153

152154
let logger: Arc<dyn Logger> = Arc::new(test_logger::TestLogger::new("".to_owned(), out));
153-
let chain_source = if get_slice!(1)[0] % 2 == 0 {
154-
None
155-
} else {
156-
Some(Arc::new(FuzzChainSource {
157-
input: Arc::clone(&input),
158-
}))
159-
};
160155

161156
let our_pubkey = get_pubkey!();
162-
let net_graph_msg_handler = NetGraphMsgHandler::new(chain_source, Arc::clone(&logger));
157+
let mut net_graph = NetworkGraph::new();
158+
159+
let mut node_pks = HashSet::new();
160+
let mut scid = 42;
163161

164162
loop {
165163
match get_slice!(1)[0] {
@@ -169,39 +167,44 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
169167
if addr_len > (37+1)*4 {
170168
return;
171169
}
172-
let _ = net_graph_msg_handler.handle_node_announcement(&decode_msg_with_len16!(msgs::NodeAnnouncement, 64, 288));
170+
let msg = decode_msg_with_len16!(msgs::NodeAnnouncement, 64, 288);
171+
node_pks.insert(msg.contents.node_id);
172+
let _ = net_graph.update_node_from_announcement::<secp256k1::VerifyOnly>(&msg, None);
173173
},
174174
1 => {
175-
let _ = net_graph_msg_handler.handle_channel_announcement(&decode_msg_with_len16!(msgs::ChannelAnnouncement, 64*4, 32+8+33*4));
175+
let msg = decode_msg_with_len16!(msgs::ChannelAnnouncement, 64*4, 32+8+33*4);
176+
node_pks.insert(msg.contents.node_id_1);
177+
node_pks.insert(msg.contents.node_id_2);
178+
let _ = net_graph.update_channel_from_announcement::<secp256k1::VerifyOnly>(&msg, None, None);
176179
},
177180
2 => {
178-
let _ = net_graph_msg_handler.handle_channel_update(&decode_msg!(msgs::ChannelUpdate, 136));
181+
let msg = decode_msg_with_len16!(msgs::ChannelAnnouncement, 64*4, 32+8+33*4);
182+
node_pks.insert(msg.contents.node_id_1);
183+
node_pks.insert(msg.contents.node_id_2);
184+
let val = slice_to_be64(get_slice!(8));
185+
let _ = net_graph.update_channel_from_announcement::<secp256k1::VerifyOnly>(&msg, Some(val), None);
179186
},
180187
3 => {
181-
match get_slice!(1)[0] {
182-
0 => {
183-
net_graph_msg_handler.handle_htlc_fail_channel_update(&msgs::HTLCFailChannelUpdate::ChannelUpdateMessage {msg: decode_msg!(msgs::ChannelUpdate, 136)});
184-
},
185-
1 => {
186-
let short_channel_id = slice_to_be64(get_slice!(8));
187-
net_graph_msg_handler.handle_htlc_fail_channel_update(&msgs::HTLCFailChannelUpdate::ChannelClosed {short_channel_id, is_permanent: false});
188-
},
189-
_ => return,
190-
}
188+
let _ = net_graph.update_channel(&decode_msg!(msgs::ChannelUpdate, 136), None);
191189
},
192190
4 => {
193-
let target = get_pubkey!();
191+
let short_channel_id = slice_to_be64(get_slice!(8));
192+
net_graph.close_channel_from_update(short_channel_id, false);
193+
},
194+
_ if node_pks.is_empty() => {},
195+
_ => {
194196
let mut first_hops_vec = Vec::new();
195197
let first_hops = match get_slice!(1)[0] {
196198
0 => None,
197-
1 => {
198-
let count = slice_to_be16(get_slice!(2));
199+
count => {
199200
for _ in 0..count {
201+
scid += 1;
202+
let rnid = node_pks.iter().skip(slice_to_be16(get_slice!(2))as usize % node_pks.len()).next().unwrap();
200203
first_hops_vec.push(ChannelDetails {
201204
channel_id: [0; 32],
202-
short_channel_id: Some(slice_to_be64(get_slice!(8))),
203-
remote_network_id: get_pubkey!(),
204-
counterparty_features: InitFeatures::empty(),
205+
short_channel_id: Some(scid),
206+
remote_network_id: *rnid,
207+
counterparty_features: InitFeatures::known(),
205208
channel_value_satoshis: slice_to_be64(get_slice!(8)),
206209
user_id: 0,
207210
inbound_capacity_msat: 0,
@@ -211,15 +214,16 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
211214
}
212215
Some(&first_hops_vec[..])
213216
},
214-
_ => return,
215217
};
216218
let mut last_hops_vec = Vec::new();
217-
let last_hops = {
218-
let count = slice_to_be16(get_slice!(2));
219+
{
220+
let count = get_slice!(1)[0];
219221
for _ in 0..count {
222+
scid += 1;
223+
let rnid = node_pks.iter().skip(slice_to_be16(get_slice!(2))as usize % node_pks.len()).next().unwrap();
220224
last_hops_vec.push(RouteHint {
221-
src_node_id: get_pubkey!(),
222-
short_channel_id: slice_to_be64(get_slice!(8)),
225+
src_node_id: *rnid,
226+
short_channel_id: scid,
223227
fees: RoutingFees {
224228
base_msat: slice_to_be32(get_slice!(4)),
225229
proportional_millionths: slice_to_be32(get_slice!(4)),
@@ -228,14 +232,15 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
228232
htlc_minimum_msat: slice_to_be64(get_slice!(8)),
229233
});
230234
}
231-
&last_hops_vec[..]
232-
};
233-
let _ = get_route(&our_pubkey, &net_graph_msg_handler.network_graph.read().unwrap(), &target,
234-
first_hops.map(|c| c.iter().collect::<Vec<_>>()).as_ref().map(|a| a.as_slice()),
235-
&last_hops.iter().collect::<Vec<_>>(),
236-
slice_to_be64(get_slice!(8)), slice_to_be32(get_slice!(4)), Arc::clone(&logger));
235+
}
236+
let last_hops = &last_hops_vec[..];
237+
for target in node_pks.iter() {
238+
let _ = get_route(&our_pubkey, &net_graph, target,
239+
first_hops.map(|c| c.iter().collect::<Vec<_>>()).as_ref().map(|a| a.as_slice()),
240+
&last_hops.iter().collect::<Vec<_>>(),
241+
slice_to_be64(get_slice!(8)), slice_to_be32(get_slice!(4)), Arc::clone(&logger));
242+
}
237243
},
238-
_ => return,
239244
}
240245
}
241246
}

0 commit comments

Comments
 (0)