X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;ds=sidebyside;f=fuzz%2Fsrc%2Ffull_stack.rs;h=3ae4e56b5f1903093d621d6f91327fcc58d79b5f;hb=33b7c906f2ec1522e466a42ca70b82806d89d8a6;hp=4408c4392bc7e4d9bcbad7b90b03394008db7ad2;hpb=f2a2fd0d48be78972ed81481c2dfbfb68ecda44e;p=rust-lightning diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index 4408c439..3ae4e56b 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -26,6 +26,7 @@ use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor}; use lightning::ln::router::Router; use lightning::util::events::{EventsProvider,Event}; +use lightning::util::enforcing_trait_impls::EnforcingChannelKeys; use lightning::util::logger::Logger; use lightning::util::config::UserConfig; @@ -98,7 +99,7 @@ impl FeeEstimator for FuzzEstimator { //TODO: We should actually be testing at least much more than 64k... match self.input.get_slice(2) { Some(slice) => cmp::max(slice_to_be16(slice) as u64, 253), - None => 0 + None => 253 } } } @@ -134,10 +135,10 @@ impl<'a> Hash for Peer<'a> { } } -struct MoneyLossDetector<'a, 'b> { - manager: Arc>, - monitor: Arc>, - handler: PeerManager>, +struct MoneyLossDetector<'a> { + manager: Arc, Arc>>, Arc, Arc, Arc>>, + monitor: Arc, Arc>>, + handler: PeerManager, Arc, Arc>>, Arc, Arc, Arc>>>, peers: &'a RefCell<[bool; 256]>, funding_txn: Vec, @@ -147,8 +148,11 @@ struct MoneyLossDetector<'a, 'b> { max_height: usize, blocks_connected: u32, } -impl<'a, 'b> MoneyLossDetector<'a, 'b> { - pub fn new(peers: &'a RefCell<[bool; 256]>, manager: Arc>, monitor: Arc>, handler: PeerManager>) -> Self { +impl<'a> MoneyLossDetector<'a> { + pub fn new(peers: &'a RefCell<[bool; 256]>, + manager: Arc, Arc>>, Arc, Arc, Arc>>, + monitor: Arc, Arc>>, + handler: PeerManager, Arc, Arc>>, Arc, Arc, Arc>>>) -> Self { MoneyLossDetector { manager, monitor, @@ -195,10 +199,10 @@ impl<'a, 'b> MoneyLossDetector<'a, 'b> { fn disconnect_block(&mut self) { if self.height > 0 && (self.max_height < 6 || self.height >= self.max_height - 6) { - self.height -= 1; let header = BlockHeader { version: 0x20000000, prev_blockhash: self.header_hashes[self.height], merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; self.manager.block_disconnected(&header, self.height as u32); self.monitor.block_disconnected(&header, self.height as u32); + self.height -= 1; let removal_height = self.height; self.txids_confirmed.retain(|_, height| { removal_height != *height @@ -207,13 +211,13 @@ impl<'a, 'b> MoneyLossDetector<'a, 'b> { } } -impl<'a, 'b> Drop for MoneyLossDetector<'a, 'b> { +impl<'a> Drop for MoneyLossDetector<'a> { fn drop(&mut self) { if !::std::thread::panicking() { // Disconnect all peers for (idx, peer) in self.peers.borrow().iter().enumerate() { if *peer { - self.handler.disconnect_event(&Peer{id: idx as u8, peers_connected: &self.peers}); + self.handler.socket_disconnected(&Peer{id: idx as u8, peers_connected: &self.peers}); } } @@ -228,7 +232,7 @@ struct KeyProvider { counter: AtomicU64, } impl KeysInterface for KeyProvider { - type ChanKeySigner = InMemoryChannelKeys; + type ChanKeySigner = EnforcingChannelKeys; fn get_node_secret(&self) -> SecretKey { self.node_secret.clone() @@ -246,27 +250,32 @@ impl KeysInterface for KeyProvider { PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap()) } - fn get_channel_keys(&self, inbound: bool) -> InMemoryChannelKeys { + fn get_channel_keys(&self, inbound: bool, channel_value_satoshis: u64) -> EnforcingChannelKeys { let ctr = self.counter.fetch_add(1, Ordering::Relaxed) as u8; - if inbound { - InMemoryChannelKeys { - funding_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, ctr]).unwrap(), - revocation_base_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, ctr]).unwrap(), - payment_base_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, ctr]).unwrap(), - delayed_payment_base_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, ctr]).unwrap(), - htlc_base_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, ctr]).unwrap(), - commitment_seed: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, ctr], - } + let secp_ctx = Secp256k1::signing_only(); + EnforcingChannelKeys::new(if inbound { + InMemoryChannelKeys::new( + &secp_ctx, + SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, ctr]).unwrap(), + SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, ctr]).unwrap(), + SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, ctr]).unwrap(), + SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, ctr]).unwrap(), + SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, ctr]).unwrap(), + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, ctr], + channel_value_satoshis, + ) } else { - InMemoryChannelKeys { - funding_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, ctr]).unwrap(), - revocation_base_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, ctr]).unwrap(), - payment_base_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, ctr]).unwrap(), - delayed_payment_base_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, ctr]).unwrap(), - htlc_base_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, ctr]).unwrap(), - commitment_seed: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, ctr], - } - } + InMemoryChannelKeys::new( + &secp_ctx, + SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, ctr]).unwrap(), + SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, ctr]).unwrap(), + SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, ctr]).unwrap(), + SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, ctr]).unwrap(), + SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, ctr]).unwrap(), + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, ctr], + channel_value_satoshis, + ) + }) } fn get_onion_rand(&self) -> (SecretKey, [u8; 32]) { @@ -317,14 +326,14 @@ pub fn do_test(data: &[u8], logger: &Arc) { let watch = Arc::new(ChainWatchInterfaceUtil::new(Network::Bitcoin, Arc::clone(&logger))); let broadcast = Arc::new(TestBroadcaster{}); - let monitor = channelmonitor::SimpleManyChannelMonitor::new(watch.clone(), broadcast.clone(), Arc::clone(&logger), fee_est.clone()); + let monitor = Arc::new(channelmonitor::SimpleManyChannelMonitor::new(watch.clone(), broadcast.clone(), Arc::clone(&logger), fee_est.clone())); let keys_manager = Arc::new(KeyProvider { node_secret: our_network_key.clone(), counter: AtomicU64::new(0) }); let mut config = UserConfig::default(); config.channel_options.fee_proportional_millionths = slice_to_be32(get_slice!(4)); config.channel_options.announced_channel = get_slice!(1)[0] != 0; config.peer_channel_config_limits.min_dust_limit_satoshis = 0; - let channelmanager = ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, 0).unwrap(); + let channelmanager = Arc::new(ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, 0).unwrap()); let router = Arc::new(Router::new(PublicKey::from_secret_key(&Secp256k1::signing_only(), &keys_manager.get_node_secret()), watch.clone(), Arc::clone(&logger))); let peers = RefCell::new([false; 256]); @@ -369,13 +378,13 @@ pub fn do_test(data: &[u8], logger: &Arc) { 2 => { let peer_id = get_slice!(1)[0]; if !peers.borrow()[peer_id as usize] { return; } - loss_detector.handler.disconnect_event(&Peer{id: peer_id, peers_connected: &peers}); + loss_detector.handler.socket_disconnected(&Peer{id: peer_id, peers_connected: &peers}); peers.borrow_mut()[peer_id as usize] = false; }, 3 => { let peer_id = get_slice!(1)[0]; if !peers.borrow()[peer_id as usize] { return; } - match loss_detector.handler.read_event(&mut Peer{id: peer_id, peers_connected: &peers}, get_slice!(get_slice!(1)[0]).to_vec()) { + match loss_detector.handler.read_event(&mut Peer{id: peer_id, peers_connected: &peers}, get_slice!(get_slice!(1)[0])) { Ok(res) => assert!(!res), Err(_) => { peers.borrow_mut()[peer_id as usize] = false; } } @@ -403,7 +412,7 @@ pub fn do_test(data: &[u8], logger: &Arc) { let their_key = get_pubkey!(); let chan_value = slice_to_be24(get_slice!(3)) as u64; let push_msat_value = slice_to_be24(get_slice!(3)) as u64; - if channelmanager.create_channel(their_key, chan_value, push_msat_value, 0).is_err() { return; } + if channelmanager.create_channel(their_key, chan_value, push_msat_value, 0, None).is_err() { return; } }, 6 => { let mut channels = channelmanager.list_channels(); @@ -482,6 +491,12 @@ pub fn do_test(data: &[u8], logger: &Arc) { } else { let txres: Result = deserialize(get_slice!(txlen)); if let Ok(tx) = txres { + let mut output_val = 0; + for out in tx.output.iter() { + if out.value > 21_000_000_0000_0000 { return; } + output_val += out.value; + if output_val > 21_000_000_0000_0000 { return; } + } loss_detector.connect_block(&[tx]); } else { return; @@ -537,12 +552,6 @@ mod tests { use std::collections::HashMap; use std::sync::{Arc, Mutex}; - #[test] - fn duplicate_crash() { - let logger: Arc = Arc::new(test_logger::TestLogger::new("".to_owned())); - super::do_test(&::hex::decode("00").unwrap(), &logger); - } - struct TrackingLogger { /// (module, message) -> count pub lines: Mutex>,