Take the full funding transaction from the user on generation
[rust-lightning] / fuzz / src / full_stack.rs
index a6672a7450b96ba9f51682be3bf885b0fbd1ca50..3acf7ba53ca7c642c6d3bcf4685480eab1131741 100644 (file)
@@ -51,7 +51,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]
@@ -116,9 +116,13 @@ impl FeeEstimator for FuzzEstimator {
        }
 }
 
-struct TestBroadcaster {}
+struct TestBroadcaster {
+       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)]
@@ -161,7 +165,7 @@ struct MoneyLossDetector<'a> {
        peers: &'a RefCell<[bool; 256]>,
        funding_txn: Vec<Transaction>,
        txids_confirmed: HashMap<Txid, usize>,
-       header_hashes: Vec<BlockHash>,
+       header_hashes: Vec<(BlockHash, u32)>,
        height: usize,
        max_height: usize,
        blocks_connected: u32,
@@ -179,7 +183,7 @@ impl<'a> MoneyLossDetector<'a> {
                        peers,
                        funding_txn: Vec::new(),
                        txids_confirmed: HashMap::new(),
-                       header_hashes: vec![Default::default()],
+                       header_hashes: vec![(genesis_block(Network::Bitcoin).block_hash(), 0)],
                        height: 0,
                        max_height: 0,
                        blocks_connected: 0,
@@ -199,23 +203,23 @@ impl<'a> MoneyLossDetector<'a> {
                        }
                }
 
-               let header = BlockHeader { version: 0x20000000, prev_blockhash: self.header_hashes[self.height], merkle_root: Default::default(), time: self.blocks_connected, bits: 42, nonce: 42 };
-               self.height += 1;
                self.blocks_connected += 1;
+               let header = BlockHeader { version: 0x20000000, prev_blockhash: self.header_hashes[self.height].0, merkle_root: Default::default(), time: self.blocks_connected, bits: 42, nonce: 42 };
+               self.height += 1;
                self.manager.block_connected(&header, &txdata, self.height as u32);
                (*self.monitor).block_connected(&header, &txdata, self.height as u32);
                if self.header_hashes.len() > self.height {
-                       self.header_hashes[self.height] = header.block_hash();
+                       self.header_hashes[self.height] = (header.block_hash(), self.blocks_connected);
                } else {
                        assert_eq!(self.header_hashes.len(), self.height);
-                       self.header_hashes.push(header.block_hash());
+                       self.header_hashes.push((header.block_hash(), self.blocks_connected));
                }
                self.max_height = cmp::max(self.height, self.max_height);
        }
 
        fn disconnect_block(&mut self) {
                if self.height > 0 && (self.max_height < 6 || self.height >= self.max_height - 6) {
-                       let header = BlockHeader { version: 0x20000000, prev_blockhash: self.header_hashes[self.height], merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+                       let header = BlockHeader { version: 0x20000000, prev_blockhash: self.header_hashes[self.height - 1].0, merkle_root: Default::default(), time: self.header_hashes[self.height].1, bits: 42, nonce: 42 };
                        self.manager.block_disconnected(&header);
                        self.monitor.block_disconnected(&header, self.height as u32);
                        self.height -= 1;
@@ -340,7 +344,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
                Err(_) => return,
        };
 
-       let broadcast = Arc::new(TestBroadcaster{});
+       let broadcast = Arc::new(TestBroadcaster{ txn_broadcasted: Mutex::new(Vec::new()) });
        let monitor = Arc::new(chainmonitor::ChainMonitor::new(None, broadcast.clone(), Arc::clone(&logger), fee_est.clone(), Arc::new(TestPersister{})));
 
        let keys_manager = Arc::new(KeyProvider { node_secret: our_network_key.clone(), counter: AtomicU64::new(0) });
@@ -370,7 +374,6 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
        let mut payments_sent = 0;
        let mut pending_funding_generation: Vec<([u8; 32], u64, Script)> = Vec::new();
        let mut pending_funding_signatures = HashMap::new();
-       let mut pending_funding_relay = Vec::new();
 
        loop {
                match get_slice!(1)[0] {
@@ -513,18 +516,19 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
                                                        continue 'outer_loop;
                                                }
                                        };
-                                       channelmanager.funding_transaction_generated(&funding_generation.0, funding_output.clone());
+                                       channelmanager.funding_transaction_generated(&funding_generation.0, tx.clone()).unwrap();
                                        pending_funding_signatures.insert(funding_output, tx);
                                }
                        },
                        11 => {
-                               if !pending_funding_relay.is_empty() {
-                                       loss_detector.connect_block(&pending_funding_relay[..]);
+                               let mut txn = broadcast.txn_broadcasted.lock().unwrap();
+                               if !txn.is_empty() {
+                                       loss_detector.connect_block(&txn[..]);
                                        for _ in 2..100 {
                                                loss_detector.connect_block(&[]);
                                        }
                                }
-                               for tx in pending_funding_relay.drain(..) {
+                               for tx in txn.drain(..) {
                                        loss_detector.funding_txn.push(tx);
                                }
                        },
@@ -566,9 +570,6 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
                                Event::FundingGenerationReady { temporary_channel_id, channel_value_satoshis, output_script, .. } => {
                                        pending_funding_generation.push((temporary_channel_id, channel_value_satoshis, output_script));
                                },
-                               Event::FundingBroadcastSafe { funding_txo, .. } => {
-                                       pending_funding_relay.push(pending_funding_signatures.remove(&funding_txo).unwrap());
-                               },
                                Event::PaymentReceived { payment_hash, payment_secret, amt } => {
                                        //TODO: enhance by fetching random amounts from fuzz input?
                                        payments_received.push((payment_hash, payment_secret, amt));