TESTING
[rust-lightning] / fuzz / src / full_stack.rs
index afdb5a83877b2a9669fbcadf6bb75be0fc073061..4c1504edf9339a68b33c86feeae6fe780974238a 100644 (file)
@@ -23,7 +23,8 @@ use lightning::chain::keysinterface::{InMemoryChannelKeys, KeysInterface};
 use lightning::ln::channelmonitor;
 use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage, PaymentSecret};
 use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor};
-use lightning::ln::router::Router;
+use lightning::routing::router::get_route;
+use lightning::routing::network_graph::NetGraphMsgHandler;
 use lightning::util::events::{EventsProvider,Event};
 use lightning::util::enforcing_trait_impls::EnforcingChannelKeys;
 use lightning::util::logger::Logger;
@@ -37,7 +38,7 @@ use bitcoin::secp256k1::Secp256k1;
 use std::cell::RefCell;
 use std::collections::{HashMap, hash_map};
 use std::cmp;
-use std::sync::Arc;
+use std::sync::{Arc,Mutex};
 use std::sync::atomic::{AtomicU64,AtomicUsize,Ordering};
 
 #[inline]
@@ -94,6 +95,7 @@ struct FuzzEstimator {
 }
 impl FeeEstimator for FuzzEstimator {
        fn get_est_sat_per_1000_weight(&self, _: ConfirmationTarget) -> u64 {
+println!("fee_get");
                //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),
@@ -102,9 +104,13 @@ impl FeeEstimator for FuzzEstimator {
        }
 }
 
-struct TestBroadcaster {}
+pub struct TestBroadcaster {
+       pub txn_broadcasted: Mutex<Vec<Transaction>>,
+}
 impl BroadcasterInterface for TestBroadcaster {
-       fn broadcast_transaction(&self, _tx: &Transaction) {}
+       fn broadcast_transaction(&self, tx: &Transaction) {
+               self.txn_broadcasted.lock().unwrap().push(tx.clone());
+       }
 }
 
 #[derive(Clone)]
@@ -134,9 +140,10 @@ impl<'a> std::hash::Hash for Peer<'a> {
 }
 
 struct MoneyLossDetector<'a> {
-       manager: Arc<ChannelManager<EnforcingChannelKeys, Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>>>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>>>,
-       monitor: Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>>>,
-       handler: PeerManager<Peer<'a>, Arc<ChannelManager<EnforcingChannelKeys, Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>>>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>>>>,
+       manager: Arc<ChannelManager<EnforcingChannelKeys, Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<ChainWatchInterfaceUtil>>>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>, Arc<dyn Logger>>>,
+       monitor: Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<ChainWatchInterfaceUtil>>>,
+       broadcaster: Arc<TestBroadcaster>,
+       handler: PeerManager<Peer<'a>, Arc<ChannelManager<EnforcingChannelKeys, Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<ChainWatchInterfaceUtil>>>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>, Arc<dyn Logger>>>, Arc<dyn Logger>>,
 
        peers: &'a RefCell<[bool; 256]>,
        funding_txn: Vec<Transaction>,
@@ -148,12 +155,14 @@ struct MoneyLossDetector<'a> {
 }
 impl<'a> MoneyLossDetector<'a> {
        pub fn new(peers: &'a RefCell<[bool; 256]>,
-                  manager: Arc<ChannelManager<EnforcingChannelKeys, Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>>>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>>>,
-                  monitor: Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>>>,
-                  handler: PeerManager<Peer<'a>, Arc<ChannelManager<EnforcingChannelKeys, Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>>>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>>>>) -> Self {
+                  manager: Arc<ChannelManager<EnforcingChannelKeys, Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<ChainWatchInterfaceUtil>>>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>, Arc<dyn Logger>>>,
+                  monitor: Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<ChainWatchInterfaceUtil>>>,
+                  broadcaster: Arc<TestBroadcaster>,
+                  handler: PeerManager<Peer<'a>, Arc<ChannelManager<EnforcingChannelKeys, Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint, EnforcingChannelKeys, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<ChainWatchInterfaceUtil>>>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>, Arc<dyn Logger>>>, Arc<dyn Logger>>) -> Self {
                MoneyLossDetector {
                        manager,
                        monitor,
+                       broadcaster,
                        handler,
 
                        peers,
@@ -221,7 +230,38 @@ impl<'a> Drop for MoneyLossDetector<'a> {
 
                        // Force all channels onto the chain (and time out claim txn)
                        self.manager.force_close_all_channels();
+                       for _ in 0..6*24*14 {
+                               self.connect_block(&[]);
+                       }
+               }
+
+               // Test that all broadcasted transactions either spend one of our funding transactions or
+               // some other broadcasted transaction:
+
+               let mut txn_map = HashMap::new();
+               let mut funding_txn_map = HashMap::new();
+               for tx in self.funding_txn.drain(..) {
+                       funding_txn_map.insert(tx.txid(), tx);
                }
+               let mut txn_broadcasted = self.broadcaster.txn_broadcasted.lock().unwrap();
+               for tx in txn_broadcasted.drain(..) {
+                       txn_map.insert(tx.txid(), tx);
+               }
+               /*for (_, tx) in txn_map.iter() {
+                       for inp in tx.input.iter() {
+                               let prev_tx = match funding_txn_map.get(&inp.prev_hash) {
+                                       Some(ptx) => ptx,
+                                       None => {
+                                               txn_map.get(&inp.prev_hash).unwrap()
+                                       }
+                               };
+                               assert!(prev_tx.output.len() > inp.prev_index as usize);
+                       }
+               }*/
+
+               //XXX: Find all non-conflicting sets of txn broadcasted and ensure that in each case we
+               //always get back at least the amount we expect minus tx fees (which we should be able to
+               //calculate now!
        }
 }
 
@@ -322,8 +362,8 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
                Err(_) => return,
        };
 
-       let watch = Arc::new(ChainWatchInterfaceUtil::new(Network::Bitcoin, Arc::clone(&logger)));
-       let broadcast = Arc::new(TestBroadcaster{});
+       let watch = Arc::new(ChainWatchInterfaceUtil::new(Network::Bitcoin));
+       let broadcast = Arc::new(TestBroadcaster{ txn_broadcasted: Mutex::new(Vec::new()) });
        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) });
@@ -332,12 +372,13 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
        config.channel_options.announced_channel = get_slice!(1)[0] != 0;
        config.peer_channel_config_limits.min_dust_limit_satoshis = 0;
        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 our_id = PublicKey::from_secret_key(&Secp256k1::signing_only(), &keys_manager.get_node_secret());
+       let net_graph_msg_handler = Arc::new(NetGraphMsgHandler::new(watch.clone(), Arc::clone(&logger)));
 
        let peers = RefCell::new([false; 256]);
-       let mut loss_detector = MoneyLossDetector::new(&peers, channelmanager.clone(), monitor.clone(), PeerManager::new(MessageHandler {
+       let mut loss_detector = MoneyLossDetector::new(&peers, channelmanager.clone(), monitor.clone(), broadcast.clone(), PeerManager::new(MessageHandler {
                chan_handler: channelmanager.clone(),
-               route_handler: router.clone(),
+               route_handler: net_graph_msg_handler.clone(),
        }, our_network_key, &[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, 15, 0], Arc::clone(&logger)));
 
        let mut should_forward = false;
@@ -348,7 +389,9 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
        let mut pending_funding_relay = Vec::new();
 
        loop {
-               match get_slice!(1)[0] {
+let a = get_slice!(1)[0];
+println!("action: {}", a);
+               match a {
                        0 => {
                                let mut new_id = 0;
                                for i in 1..256 {
@@ -389,7 +432,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
                        },
                        4 => {
                                let value = slice_to_be24(get_slice!(3)) as u64;
-                               let route = match router.get_route(&get_pubkey!(), None, &Vec::new(), value, 42) {
+                               let route = match get_route(&our_id, &net_graph_msg_handler, &get_pubkey!(), None, &Vec::new(), value, 42, Arc::clone(&logger)) {
                                        Ok(route) => route,
                                        Err(_) => return,
                                };
@@ -406,7 +449,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
                        },
                        15 => {
                                let value = slice_to_be24(get_slice!(3)) as u64;
-                               let mut route = match router.get_route(&get_pubkey!(), None, &Vec::new(), value, 42) {
+                               let mut route = match get_route(&our_id, &net_graph_msg_handler, &get_pubkey!(), None, &Vec::new(), value, 42, Arc::clone(&logger)) {
                                        Ok(route) => route,
                                        Err(_) => return,
                                };
@@ -535,13 +578,16 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
                        // 15 is above
                        _ => return,
                }
+println!("PROCESSING EVENTS");
                loss_detector.handler.process_events();
                for event in loss_detector.manager.get_and_clear_pending_events() {
                        match event {
                                Event::FundingGenerationReady { temporary_channel_id, channel_value_satoshis, output_script, .. } => {
+println!("fgr");
                                        pending_funding_generation.push((temporary_channel_id, channel_value_satoshis, output_script));
                                },
                                Event::FundingBroadcastSafe { funding_txo, .. } => {
+println!("fbs");
                                        pending_funding_relay.push(pending_funding_signatures.remove(&funding_txo).unwrap());
                                },
                                Event::PaymentReceived { payment_hash, payment_secret, amt } => {
@@ -551,6 +597,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
                                Event::PaymentSent {..} => {},
                                Event::PaymentFailed {..} => {},
                                Event::PendingHTLCsForwardable {..} => {
+println!("PENDING HTLCS FORWARDABLE");
                                        should_forward = true;
                                },
                                Event::SpendableOutputs {..} => {},