1 use bitcoin::blockdata::script::Builder;
2 use bitcoin::blockdata::transaction::TxOut;
3 use bitcoin::hash_types::BlockHash;
6 use lightning::ln::channelmanager::ChannelDetails;
7 use lightning::ln::features::InitFeatures;
8 use lightning::ln::msgs;
9 use lightning::ln::msgs::RoutingMessageHandler;
10 use lightning::routing::router::{get_route, RouteHint};
11 use lightning::util::logger::Logger;
12 use lightning::util::ser::Readable;
13 use lightning::routing::network_graph::{NetGraphMsgHandler, RoutingFees};
15 use bitcoin::secp256k1::key::PublicKey;
17 use utils::test_logger;
20 use std::sync::atomic::{AtomicUsize, Ordering};
23 pub fn slice_to_be16(v: &[u8]) -> u16 {
24 ((v[0] as u16) << 8*1) |
25 ((v[1] as u16) << 8*0)
29 pub fn slice_to_be32(v: &[u8]) -> u32 {
30 ((v[0] as u32) << 8*3) |
31 ((v[1] as u32) << 8*2) |
32 ((v[2] as u32) << 8*1) |
33 ((v[3] as u32) << 8*0)
37 pub fn slice_to_be64(v: &[u8]) -> u64 {
38 ((v[0] as u64) << 8*7) |
39 ((v[1] as u64) << 8*6) |
40 ((v[2] as u64) << 8*5) |
41 ((v[3] as u64) << 8*4) |
42 ((v[4] as u64) << 8*3) |
43 ((v[5] as u64) << 8*2) |
44 ((v[6] as u64) << 8*1) |
45 ((v[7] as u64) << 8*0)
51 read_pos: AtomicUsize,
54 fn get_slice(&self, len: usize) -> Option<&[u8]> {
55 let old_pos = self.read_pos.fetch_add(len, Ordering::AcqRel);
56 if self.data.len() < old_pos + len {
59 Some(&self.data[old_pos..old_pos + len])
61 fn get_slice_nonadvancing(&self, len: usize) -> Option<&[u8]> {
62 let old_pos = self.read_pos.load(Ordering::Acquire);
63 if self.data.len() < old_pos + len {
66 Some(&self.data[old_pos..old_pos + len])
70 struct FuzzChainSource {
71 input: Arc<InputData>,
73 impl chain::Access for FuzzChainSource {
74 fn get_utxo(&self, _genesis_hash: &BlockHash, _short_channel_id: u64) -> Result<TxOut, chain::AccessError> {
75 match self.input.get_slice(2) {
76 Some(&[0, _]) => Err(chain::AccessError::UnknownChain),
77 Some(&[1, _]) => Err(chain::AccessError::UnknownTx),
78 Some(&[_, x]) => Ok(TxOut { value: 0, script_pubkey: Builder::new().push_int(x as i64).into_script().to_v0_p2wsh() }),
79 None => Err(chain::AccessError::UnknownTx),
86 pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
87 let input = Arc::new(InputData {
89 read_pos: AtomicUsize::new(0),
91 macro_rules! get_slice_nonadvancing {
93 match input.get_slice_nonadvancing($len as usize) {
99 macro_rules! get_slice {
101 match input.get_slice($len as usize) {
102 Some(slice) => slice,
108 macro_rules! decode_msg {
109 ($MsgType: path, $len: expr) => {{
110 let mut reader = ::std::io::Cursor::new(get_slice!($len));
111 match <$MsgType>::read(&mut reader) {
114 msgs::DecodeError::UnknownVersion => return,
115 msgs::DecodeError::UnknownRequiredFeature => return,
116 msgs::DecodeError::InvalidValue => return,
117 msgs::DecodeError::BadLengthDescriptor => return,
118 msgs::DecodeError::ShortRead => panic!("We picked the length..."),
119 msgs::DecodeError::Io(e) => panic!(format!("{}", e)),
125 macro_rules! decode_msg_with_len16 {
126 ($MsgType: path, $begin_len: expr, $excess: expr) => {
128 let extra_len = slice_to_be16(&get_slice_nonadvancing!($begin_len as usize + 2)[$begin_len..$begin_len + 2]);
129 decode_msg!($MsgType, $begin_len as usize + 2 + (extra_len as usize) + $excess)
134 macro_rules! get_pubkey {
136 match PublicKey::from_slice(get_slice!(33)) {
143 let logger: Arc<dyn Logger> = Arc::new(test_logger::TestLogger::new("".to_owned(), out));
144 let chain_source = Arc::new(FuzzChainSource {
145 input: Arc::clone(&input),
148 let our_pubkey = get_pubkey!();
149 let net_graph_msg_handler = NetGraphMsgHandler::new(Some(chain_source), Arc::clone(&logger));
152 match get_slice!(1)[0] {
154 let start_len = slice_to_be16(&get_slice_nonadvancing!(64 + 2)[64..64 + 2]) as usize;
155 let addr_len = slice_to_be16(&get_slice_nonadvancing!(64+start_len+2 + 74)[64+start_len+2 + 72..64+start_len+2 + 74]);
156 if addr_len > (37+1)*4 {
159 let _ = net_graph_msg_handler.handle_node_announcement(&decode_msg_with_len16!(msgs::NodeAnnouncement, 64, 288));
162 let _ = net_graph_msg_handler.handle_channel_announcement(&decode_msg_with_len16!(msgs::ChannelAnnouncement, 64*4, 32+8+33*4));
165 let _ = net_graph_msg_handler.handle_channel_update(&decode_msg!(msgs::ChannelUpdate, 136));
168 match get_slice!(1)[0] {
170 net_graph_msg_handler.handle_htlc_fail_channel_update(&msgs::HTLCFailChannelUpdate::ChannelUpdateMessage {msg: decode_msg!(msgs::ChannelUpdate, 136)});
173 let short_channel_id = slice_to_be64(get_slice!(8));
174 net_graph_msg_handler.handle_htlc_fail_channel_update(&msgs::HTLCFailChannelUpdate::ChannelClosed {short_channel_id, is_permanent: false});
180 let target = get_pubkey!();
181 let mut first_hops_vec = Vec::new();
182 let first_hops = match get_slice!(1)[0] {
185 let count = slice_to_be16(get_slice!(2));
187 first_hops_vec.push(ChannelDetails {
189 short_channel_id: Some(slice_to_be64(get_slice!(8))),
190 remote_network_id: get_pubkey!(),
191 counterparty_features: InitFeatures::empty(),
192 channel_value_satoshis: slice_to_be64(get_slice!(8)),
194 inbound_capacity_msat: 0,
196 outbound_capacity_msat: 0,
199 Some(&first_hops_vec[..])
203 let mut last_hops_vec = Vec::new();
205 let count = slice_to_be16(get_slice!(2));
207 last_hops_vec.push(RouteHint {
208 src_node_id: get_pubkey!(),
209 short_channel_id: slice_to_be64(get_slice!(8)),
211 base_msat: slice_to_be32(get_slice!(4)),
212 proportional_millionths: slice_to_be32(get_slice!(4)),
214 cltv_expiry_delta: slice_to_be16(get_slice!(2)),
215 htlc_minimum_msat: slice_to_be64(get_slice!(8)),
220 let _ = get_route(&our_pubkey, &net_graph_msg_handler.network_graph.read().unwrap(), &target, first_hops, last_hops, slice_to_be64(get_slice!(8)), slice_to_be32(get_slice!(4)), Arc::clone(&logger));
227 pub fn router_test<Out: test_logger::Output>(data: &[u8], out: Out) {
232 pub extern "C" fn router_run(data: *const u8, datalen: usize) {
233 do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, test_logger::DevNull {});