From: Matt Corallo Date: Tue, 30 Jul 2024 16:20:31 +0000 (+0000) Subject: Add BOLT 12 sends to `full_stack_target` fuzzer X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=608b3163d9b07ef813b864024a8b2f9b4116d5f7;p=rust-lightning Add BOLT 12 sends to `full_stack_target` fuzzer --- diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index 59f1275a6..be40af501 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -49,9 +49,11 @@ use lightning::ln::peer_handler::{ }; use lightning::ln::script::ShutdownScript; use lightning::ln::types::ChannelId; -use lightning::offers::invoice::UnsignedBolt12Invoice; -use lightning::offers::invoice_request::UnsignedInvoiceRequest; +use lightning::offers::invoice::{Bolt12Invoice, UnsignedBolt12Invoice}; +use lightning::offers::invoice_request::{InvoiceRequest, UnsignedInvoiceRequest}; +use lightning::offers::offer::{self, Offer}; use lightning::onion_message::messenger::{Destination, MessageRouter, OnionMessagePath}; +use lightning::onion_message::offers::{OffersMessage, OffersMessageHandler}; use lightning::routing::gossip::{NetworkGraph, P2PGossipSync}; use lightning::routing::router::{ InFlightHtlcs, PaymentParameters, Route, RouteParameters, Router, @@ -148,7 +150,7 @@ impl FeeEstimator for FuzzEstimator { } } -struct FuzzRouter {} +struct FuzzRouter(Arc); impl Router for FuzzRouter { fn find_route( @@ -177,10 +179,12 @@ impl MessageRouter for FuzzRouter { } fn create_blinded_paths( - &self, _recipient: PublicKey, _context: MessageContext, _peers: Vec, - _secp_ctx: &Secp256k1, + &self, recipient: PublicKey, ctx: MessageContext, _peers: Vec, + secp_ctx: &Secp256k1, ) -> Result, ()> { - unreachable!() + let es = &*self.0; + let path = BlindedMessagePath::one_hop(recipient, ctx, es, secp_ctx).unwrap(); + Ok(vec![path]) } } @@ -596,7 +600,6 @@ pub fn do_test(mut data: &[u8], logger: &Arc) { halt_fee_est_reads: AtomicBool::new(false), }); let fee_est = Arc::new(FuzzEstimator { input: input.clone() }); - let router = FuzzRouter {}; macro_rules! get_slice { ($len: expr) => { @@ -647,6 +650,7 @@ pub fn do_test(mut data: &[u8], logger: &Arc) { counter: AtomicU64::new(0), signer_state: RefCell::new(new_hash_map()), }); + let router = FuzzRouter(Arc::clone(&keys_manager)); let network = Network::Bitcoin; let best_block_timestamp = genesis_block(network).header.time; let params = ChainParameters { network, best_block: BestBlock::from_network(network) }; @@ -1039,6 +1043,60 @@ pub fn do_test(mut data: &[u8], logger: &Arc) { ); } }, + 0x30 => { + let offer_len = u16::from_be_bytes(get_bytes!(2)); + let offer_opt = input + .get_slice(offer_len as usize) + .and_then(|slice| Offer::try_from(slice.to_vec()).ok()); + let offer = if let Some(offer) = offer_opt { offer } else { return }; + let quantity = if offer.expects_quantity() { Some(1) } else { None }; + let amount = if let Some(amt) = offer.amount() { + match amt { + offer::Amount::Bitcoin { amount_msats } => Some(amount_msats), + offer::Amount::Currency { .. } => Some(1_000), + } + } else { + Some(1_000) + }; + let idx = (get_bytes!(1)[0] as u16) % cmp::max(payments_sent, 1); + let mut payment_id = PaymentId([0; 32]); + payment_id.0[0..2].copy_from_slice(&idx.to_be_bytes()); + let _ = channelmanager.pay_for_offer( + &offer, + quantity, + amount, + None, + payment_id, + Retry::Attempts(2), + Some(100), + ); + }, + 0x31 => { + let inv_len = u16::from_be_bytes(get_bytes!(2)); + let inv_opt = input + .get_slice((inv_len & 0x7fff) as usize) + .and_then(|slice| Bolt12Invoice::try_from(slice.to_vec()).ok()); + let inv = if let Some(inv) = inv_opt { inv } else { return }; + let context = if let Ok(c) = Readable::read(&mut &*input) { c } else { return }; + if inv_len & 0x8000 != 0 { + let _ = channelmanager.send_payment_for_bolt12_invoice(&inv, Some(&context)); + } else { + let msg = OffersMessage::Invoice(inv); + let _ = channelmanager.handle_message(msg, Some(context), None); + } + }, + 0x32 => { + let invreq_len = u16::from_be_bytes(get_bytes!(2)); + let invreq_opt = input + .get_slice(invreq_len as usize) + .and_then(|slice| InvoiceRequest::try_from(slice.to_vec()).ok()); + let invreq = if let Some(invreq) = invreq_opt { invreq } else { return }; + let context = if let Ok(c) = Readable::read(&mut &*input) { c } else { return }; + let response_path = + if let Ok(p) = Readable::read(&mut &*input) { Some(p) } else { return }; + let msg = OffersMessage::InvoiceRequest(invreq); + let _ = channelmanager.handle_message(msg, context, response_path); + }, _ => return, } loss_detector.handler.process_events();