Move fuzz to top level. 2019-11-fuzz-top-level
authorMatt Corallo <git@bluematt.me>
Fri, 22 Nov 2019 20:40:58 +0000 (15:40 -0500)
committerMatt Corallo <git@bluematt.me>
Mon, 25 Nov 2019 20:42:07 +0000 (15:42 -0500)
77 files changed:
.travis.yml
fuzz/.gitignore [new file with mode: 0644]
fuzz/Cargo.toml [new file with mode: 0644]
fuzz/fuzz_targets/chanmon_deser_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/chanmon_fail_consistency.rs [new file with mode: 0644]
fuzz/fuzz_targets/full_stack_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/gen_target.sh [new file with mode: 0755]
fuzz/fuzz_targets/msg_targets/msg_accept_channel_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_announcement_signatures_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_channel_announcement_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_channel_reestablish_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_channel_update_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_closing_signed_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_commitment_signed_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_decoded_onion_error_packet_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_error_message_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_funding_created_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_funding_locked_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_funding_signed_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_init_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_node_announcement_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_onion_hop_data_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_open_channel_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_ping_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_pong_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_revoke_and_ack_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_shutdown_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_target_template.txt [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_update_add_htlc_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_update_fail_htlc_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_update_fail_malformed_htlc_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_update_fee_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/msg_update_fulfill_htlc_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/msg_targets/utils.rs [new file with mode: 0644]
fuzz/fuzz_targets/peer_crypt_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/router_target.rs [new file with mode: 0644]
fuzz/fuzz_targets/utils/mod.rs [new file with mode: 0644]
fuzz/fuzz_targets/utils/test_logger.rs [new file with mode: 0644]
fuzz/travis-fuzz.sh [new file with mode: 0755]
lightning/fuzz/.gitignore [deleted file]
lightning/fuzz/Cargo.toml [deleted file]
lightning/fuzz/fuzz_targets/chanmon_deser_target.rs [deleted file]
lightning/fuzz/fuzz_targets/chanmon_fail_consistency.rs [deleted file]
lightning/fuzz/fuzz_targets/full_stack_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/gen_target.sh [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_accept_channel_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_announcement_signatures_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_channel_announcement_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_channel_reestablish_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_channel_update_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_closing_signed_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_commitment_signed_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_decoded_onion_error_packet_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_error_message_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_funding_created_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_funding_locked_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_funding_signed_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_init_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_node_announcement_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_onion_hop_data_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_open_channel_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_ping_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_pong_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_revoke_and_ack_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_shutdown_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_target_template.txt [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_update_add_htlc_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_update_fail_htlc_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_update_fail_malformed_htlc_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_update_fee_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/msg_update_fulfill_htlc_target.rs [deleted file]
lightning/fuzz/fuzz_targets/msg_targets/utils.rs [deleted file]
lightning/fuzz/fuzz_targets/peer_crypt_target.rs [deleted file]
lightning/fuzz/fuzz_targets/router_target.rs [deleted file]
lightning/fuzz/fuzz_targets/utils/mod.rs [deleted file]
lightning/fuzz/fuzz_targets/utils/test_logger.rs [deleted file]
lightning/fuzz/travis-fuzz.sh [deleted file]

index 9c9257855cd33c6fefd13385a885a0eec0c4eee4..308c8d634d72debda99c692e549f8446a9c5a48f 100644 (file)
@@ -21,7 +21,7 @@ script:
      # Test lightning workspace for 1.22.0
      - if [ "$(rustup show | grep default | grep 1.22.0)" != "" ]; then RUSTFLAGS="-C link-dead-code" cargo test --verbose -p lightning; fi
      # Run lightning workspace fuzz tests for Rust 1.34.2
-     - if [ "$(rustup show | grep default | grep 1.34.2)" != "" ]; then cd lightning/fuzz && cargo test --verbose && ./travis-fuzz.sh; fi
+     - if [ "$(rustup show | grep default | grep 1.34.2)" != "" ]; then cd fuzz && cargo test --verbose && ./travis-fuzz.sh; fi
      - if [ "$(rustup show | grep default | grep stable)" != "" ]; then
            wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz &&
            tar xzf master.tar.gz &&
diff --git a/fuzz/.gitignore b/fuzz/.gitignore
new file mode 100644 (file)
index 0000000..8bf27ec
--- /dev/null
@@ -0,0 +1,3 @@
+hfuzz_target
+target
+hfuzz_workspace
diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml
new file mode 100644 (file)
index 0000000..96699a7
--- /dev/null
@@ -0,0 +1,158 @@
+[package]
+name = "lightning-fuzz"
+version = "0.0.1"
+authors = ["Automatically generated"]
+publish = false
+# Because the function is unused it gets dropped before we link lightning, so
+# we have to duplicate build.rs here. Note that this is only required for
+# fuzztarget mode.
+
+[package.metadata]
+cargo-fuzz = true
+
+[features]
+afl_fuzz = ["afl"]
+honggfuzz_fuzz = ["honggfuzz"]
+libfuzzer_fuzz = ["libfuzzer-sys"]
+
+[dependencies]
+afl = { version = "0.4", optional = true }
+lightning = { path = "../lightning", features = ["fuzztarget"] }
+bitcoin = { version = "0.20", features = ["fuzztarget"] }
+bitcoin_hashes = { version = "0.7", features = ["fuzztarget"] }
+hex = "0.3"
+honggfuzz = { version = "0.5", optional = true }
+secp256k1 = { version = "0.15", features=["fuzztarget"] }
+libfuzzer-sys = { git = "https://github.com/rust-fuzz/libfuzzer-sys.git", optional = true }
+
+[build-dependencies]
+cc = "1.0"
+
+# Prevent this from interfering with workspaces
+[workspace]
+members = ["."]
+
+[profile.release]
+lto = true
+codegen-units = 1
+
+[[bin]]
+name = "peer_crypt_target"
+path = "fuzz_targets/peer_crypt_target.rs"
+
+[[bin]]
+name = "full_stack_target"
+path = "fuzz_targets/full_stack_target.rs"
+
+[[bin]]
+name = "chanmon_fail_consistency"
+path = "fuzz_targets/chanmon_fail_consistency.rs"
+
+[[bin]]
+name = "router_target"
+path = "fuzz_targets/router_target.rs"
+
+[[bin]]
+name = "chanmon_deser_target"
+path = "fuzz_targets/chanmon_deser_target.rs"
+
+# message fuzz targets
+[[bin]]
+name = "msg_ping_target"
+path = "fuzz_targets/msg_targets/msg_ping_target.rs"
+
+[[bin]]
+name = "msg_pong_target"
+path = "fuzz_targets/msg_targets/msg_pong_target.rs"
+
+[[bin]]
+name = "msg_error_message_target"
+path = "fuzz_targets/msg_targets/msg_error_message_target.rs"
+
+[[bin]]
+name = "msg_update_add_htlc_target"
+path = "fuzz_targets/msg_targets/msg_update_add_htlc_target.rs"
+
+[[bin]]
+name = "msg_accept_channel_target"
+path = "fuzz_targets/msg_targets/msg_accept_channel_target.rs"
+
+[[bin]]
+name = "msg_closing_signed_target"
+path = "fuzz_targets/msg_targets/msg_closing_signed_target.rs"
+
+[[bin]]
+name = "msg_commitment_signed_target"
+path = "fuzz_targets/msg_targets/msg_commitment_signed_target.rs"
+
+[[bin]]
+name = "msg_funding_created_target"
+path = "fuzz_targets/msg_targets/msg_funding_created_target.rs"
+
+[[bin]]
+name = "msg_funding_locked_target"
+path = "fuzz_targets/msg_targets/msg_funding_locked_target.rs"
+
+[[bin]]
+name = "msg_funding_signed_target"
+path = "fuzz_targets/msg_targets/msg_funding_signed_target.rs"
+
+[[bin]]
+name = "msg_open_channel_target"
+path = "fuzz_targets/msg_targets/msg_open_channel_target.rs"
+
+[[bin]]
+name = "msg_revoke_and_ack_target"
+path = "fuzz_targets/msg_targets/msg_revoke_and_ack_target.rs"
+
+[[bin]]
+name = "msg_shutdown_target"
+path = "fuzz_targets/msg_targets/msg_shutdown_target.rs"
+
+[[bin]]
+name = "msg_update_fail_malformed_htlc_target"
+path = "fuzz_targets/msg_targets/msg_update_fail_malformed_htlc_target.rs"
+
+[[bin]]
+name = "msg_update_fee_target"
+path = "fuzz_targets/msg_targets/msg_update_fee_target.rs"
+
+[[bin]]
+name = "msg_update_fulfill_htlc_target"
+path = "fuzz_targets/msg_targets/msg_update_fulfill_htlc_target.rs"
+
+[[bin]]
+name = "msg_update_fail_htlc_target"
+path = "fuzz_targets/msg_targets/msg_update_fail_htlc_target.rs"
+
+[[bin]]
+name = "msg_channel_reestablish_target"
+path = "fuzz_targets/msg_targets/msg_channel_reestablish_target.rs"
+
+[[bin]]
+name = "msg_announcement_signatures_target"
+path = "fuzz_targets/msg_targets/msg_announcement_signatures_target.rs"
+
+[[bin]]
+name = "msg_channel_announcement_target"
+path = "fuzz_targets/msg_targets/msg_channel_announcement_target.rs"
+
+[[bin]]
+name = "msg_channel_update_target"
+path = "fuzz_targets/msg_targets/msg_channel_update_target.rs"
+
+[[bin]]
+name = "msg_decoded_onion_error_packet_target"
+path = "fuzz_targets/msg_targets/msg_decoded_onion_error_packet_target.rs"
+
+[[bin]]
+name = "msg_init_target"
+path = "fuzz_targets/msg_targets/msg_init_target.rs"
+
+[[bin]]
+name = "msg_node_announcement_target"
+path = "fuzz_targets/msg_targets/msg_node_announcement_target.rs"
+
+[[bin]]
+name = "msg_onion_hop_data_target"
+path = "fuzz_targets/msg_targets/msg_onion_hop_data_target.rs"
diff --git a/fuzz/fuzz_targets/chanmon_deser_target.rs b/fuzz/fuzz_targets/chanmon_deser_target.rs
new file mode 100644 (file)
index 0000000..f741832
--- /dev/null
@@ -0,0 +1,72 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate bitcoin;
+extern crate bitcoin_hashes;
+extern crate lightning;
+
+use bitcoin_hashes::sha256d::Hash as Sha256dHash;
+
+use lightning::ln::channelmonitor;
+use lightning::util::ser::{ReadableArgs, Writer};
+
+mod utils;
+use utils::test_logger;
+
+use std::io::Cursor;
+use std::sync::Arc;
+
+struct VecWriter(Vec<u8>);
+impl Writer for VecWriter {
+       fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
+               self.0.extend_from_slice(buf);
+               Ok(())
+       }
+       fn size_hint(&mut self, size: usize) {
+               self.0.reserve_exact(size);
+       }
+}
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       let logger = Arc::new(test_logger::TestLogger::new("".to_owned()));
+       if let Ok((latest_block_hash, monitor)) = <(Sha256dHash, channelmonitor::ChannelMonitor)>::read(&mut Cursor::new(data), logger.clone()) {
+               let mut w = VecWriter(Vec::new());
+               monitor.write_for_disk(&mut w).unwrap();
+               let deserialized_copy = <(Sha256dHash, channelmonitor::ChannelMonitor)>::read(&mut Cursor::new(&w.0), logger.clone()).unwrap();
+               assert!(latest_block_hash == deserialized_copy.0);
+               assert!(monitor == deserialized_copy.1);
+               w.0.clear();
+               monitor.write_for_watchtower(&mut w).unwrap();
+       }
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/chanmon_fail_consistency.rs b/fuzz/fuzz_targets/chanmon_fail_consistency.rs
new file mode 100644 (file)
index 0000000..459fca4
--- /dev/null
@@ -0,0 +1,781 @@
+//! Test that monitor update failures don't get our channel state out of sync.
+//! One of the biggest concern with the monitor update failure handling code is that messages
+//! resent after monitor updating is restored are delivered out-of-order, resulting in
+//! commitment_signed messages having "invalid signatures".
+//! To test this we stand up a network of three nodes and read bytes from the fuzz input to denote
+//! actions such as sending payments, handling events, or changing monitor update return values on
+//! a per-node basis. This should allow it to find any cases where the ordering of actions results
+//! in us getting out of sync with ourselves, and, assuming at least one of our recieve- or
+//! send-side handling is correct, other peers. We consider it a failure if any action results in a
+//! channel being force-closed.
+
+//Uncomment this for libfuzzer builds:
+//#![no_main]
+
+extern crate bitcoin;
+extern crate bitcoin_hashes;
+extern crate lightning;
+extern crate secp256k1;
+
+use bitcoin::BitcoinHash;
+use bitcoin::blockdata::block::BlockHeader;
+use bitcoin::blockdata::transaction::{Transaction, TxOut};
+use bitcoin::blockdata::script::{Builder, Script};
+use bitcoin::blockdata::opcodes;
+use bitcoin::network::constants::Network;
+
+use bitcoin_hashes::Hash as TraitImport;
+use bitcoin_hashes::hash160::Hash as Hash160;
+use bitcoin_hashes::sha256::Hash as Sha256;
+use bitcoin_hashes::sha256d::Hash as Sha256d;
+
+use lightning::chain::chaininterface;
+use lightning::chain::transaction::OutPoint;
+use lightning::chain::chaininterface::{BroadcasterInterface,ConfirmationTarget,ChainListener,FeeEstimator,ChainWatchInterfaceUtil};
+use lightning::chain::keysinterface::{ChannelKeys, KeysInterface};
+use lightning::ln::channelmonitor;
+use lightning::ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdateErr, HTLCUpdate};
+use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage, ChannelManagerReadArgs};
+use lightning::ln::router::{Route, RouteHop};
+use lightning::ln::msgs::{CommitmentUpdate, ChannelMessageHandler, ErrorAction, LightningError, UpdateAddHTLC, LocalFeatures};
+use lightning::util::events;
+use lightning::util::logger::Logger;
+use lightning::util::config::UserConfig;
+use lightning::util::events::{EventsProvider, MessageSendEventsProvider};
+use lightning::util::ser::{Readable, ReadableArgs, Writeable, Writer};
+
+mod utils;
+use utils::test_logger;
+
+use secp256k1::key::{PublicKey,SecretKey};
+use secp256k1::Secp256k1;
+
+use std::mem;
+use std::cmp::Ordering;
+use std::collections::{HashSet, hash_map, HashMap};
+use std::sync::{Arc,Mutex};
+use std::sync::atomic;
+use std::io::Cursor;
+
+struct FuzzEstimator {}
+impl FeeEstimator for FuzzEstimator {
+       fn get_est_sat_per_1000_weight(&self, _: ConfirmationTarget) -> u64 {
+               253
+       }
+}
+
+pub struct TestBroadcaster {}
+impl BroadcasterInterface for TestBroadcaster {
+       fn broadcast_transaction(&self, _tx: &Transaction) { }
+}
+
+pub struct VecWriter(pub Vec<u8>);
+impl Writer for VecWriter {
+       fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
+               self.0.extend_from_slice(buf);
+               Ok(())
+       }
+       fn size_hint(&mut self, size: usize) {
+               self.0.reserve_exact(size);
+       }
+}
+
+static mut IN_RESTORE: bool = false;
+pub struct TestChannelMonitor {
+       pub simple_monitor: Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint>>,
+       pub update_ret: Mutex<Result<(), channelmonitor::ChannelMonitorUpdateErr>>,
+       pub latest_good_update: Mutex<HashMap<OutPoint, Vec<u8>>>,
+       pub latest_update_good: Mutex<HashMap<OutPoint, bool>>,
+       pub latest_updates_good_at_last_ser: Mutex<HashMap<OutPoint, bool>>,
+       pub should_update_manager: atomic::AtomicBool,
+}
+impl TestChannelMonitor {
+       pub fn new(chain_monitor: Arc<chaininterface::ChainWatchInterface>, broadcaster: Arc<chaininterface::BroadcasterInterface>, logger: Arc<Logger>, feeest: Arc<chaininterface::FeeEstimator>) -> Self {
+               Self {
+                       simple_monitor: channelmonitor::SimpleManyChannelMonitor::new(chain_monitor, broadcaster, logger, feeest),
+                       update_ret: Mutex::new(Ok(())),
+                       latest_good_update: Mutex::new(HashMap::new()),
+                       latest_update_good: Mutex::new(HashMap::new()),
+                       latest_updates_good_at_last_ser: Mutex::new(HashMap::new()),
+                       should_update_manager: atomic::AtomicBool::new(false),
+               }
+       }
+}
+impl channelmonitor::ManyChannelMonitor for TestChannelMonitor {
+       fn add_update_monitor(&self, funding_txo: OutPoint, monitor: channelmonitor::ChannelMonitor) -> Result<(), channelmonitor::ChannelMonitorUpdateErr> {
+               let ret = self.update_ret.lock().unwrap().clone();
+               if let Ok(()) = ret {
+                       let mut ser = VecWriter(Vec::new());
+                       monitor.write_for_disk(&mut ser).unwrap();
+                       self.latest_good_update.lock().unwrap().insert(funding_txo, ser.0);
+                       match self.latest_update_good.lock().unwrap().entry(funding_txo) {
+                               hash_map::Entry::Vacant(mut e) => { e.insert(true); },
+                               hash_map::Entry::Occupied(mut e) => {
+                                       if !e.get() && unsafe { IN_RESTORE } {
+                                               // Technically we can't consider an update to be "good" unless we're doing
+                                               // it in response to a test_restore_channel_monitor as the channel may
+                                               // still be waiting on such a call, so only set us to good if we're in the
+                                               // middle of a restore call.
+                                               e.insert(true);
+                                       }
+                               },
+                       }
+                       self.should_update_manager.store(true, atomic::Ordering::Relaxed);
+               } else {
+                       self.latest_update_good.lock().unwrap().insert(funding_txo, false);
+               }
+               assert!(self.simple_monitor.add_update_monitor(funding_txo, monitor).is_ok());
+               ret
+       }
+
+       fn fetch_pending_htlc_updated(&self) -> Vec<HTLCUpdate> {
+               return self.simple_monitor.fetch_pending_htlc_updated();
+       }
+}
+
+struct KeyProvider {
+       node_id: u8,
+       session_id: atomic::AtomicU8,
+       channel_id: atomic::AtomicU8,
+}
+impl KeysInterface for KeyProvider {
+       fn get_node_secret(&self) -> SecretKey {
+               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, self.node_id]).unwrap()
+       }
+
+       fn get_destination_script(&self) -> Script {
+               let secp_ctx = Secp256k1::signing_only();
+               let channel_monitor_claim_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, self.node_id]).unwrap();
+               let our_channel_monitor_claim_key_hash = Hash160::hash(&PublicKey::from_secret_key(&secp_ctx, &channel_monitor_claim_key).serialize());
+               Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script()
+       }
+
+       fn get_shutdown_pubkey(&self) -> PublicKey {
+               let secp_ctx = Secp256k1::signing_only();
+               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, 3, self.node_id]).unwrap())
+       }
+
+       fn get_channel_keys(&self, _inbound: bool) -> ChannelKeys {
+               ChannelKeys {
+                       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, 4, self.node_id]).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, 5, self.node_id]).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, 6, self.node_id]).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, 7, self.node_id]).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, 8, self.node_id]).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, 9, self.node_id],
+               }
+       }
+
+       fn get_session_key(&self) -> SecretKey {
+               let id = self.session_id.fetch_add(1, atomic::Ordering::Relaxed);
+               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, id, 10, self.node_id]).unwrap()
+       }
+
+       fn get_channel_id(&self) -> [u8; 32] {
+               let id = self.channel_id.fetch_add(1, atomic::Ordering::Relaxed);
+               [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, id, 11, self.node_id]
+       }
+}
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       let fee_est = Arc::new(FuzzEstimator{});
+       let broadcast = Arc::new(TestBroadcaster{});
+
+       macro_rules! make_node {
+               ($node_id: expr) => { {
+                       let logger: Arc<Logger> = Arc::new(test_logger::TestLogger::new($node_id.to_string()));
+                       let watch = Arc::new(ChainWatchInterfaceUtil::new(Network::Bitcoin, Arc::clone(&logger)));
+                       let monitor = Arc::new(TestChannelMonitor::new(watch.clone(), broadcast.clone(), logger.clone(), fee_est.clone()));
+
+                       let keys_manager = Arc::new(KeyProvider { node_id: $node_id, session_id: atomic::AtomicU8::new(0), channel_id: atomic::AtomicU8::new(0) });
+                       let mut config = UserConfig::new();
+                       config.channel_options.fee_proportional_millionths = 0;
+                       config.channel_options.announced_channel = true;
+                       config.peer_channel_config_limits.min_dust_limit_satoshis = 0;
+                       (ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, 0).unwrap(),
+                       monitor)
+               } }
+       }
+
+       macro_rules! reload_node {
+               ($ser: expr, $node_id: expr, $old_monitors: expr) => { {
+                       let logger: Arc<Logger> = Arc::new(test_logger::TestLogger::new($node_id.to_string()));
+                       let watch = Arc::new(ChainWatchInterfaceUtil::new(Network::Bitcoin, Arc::clone(&logger)));
+                       let monitor = Arc::new(TestChannelMonitor::new(watch.clone(), broadcast.clone(), logger.clone(), fee_est.clone()));
+
+                       let keys_manager = Arc::new(KeyProvider { node_id: $node_id, session_id: atomic::AtomicU8::new(0), channel_id: atomic::AtomicU8::new(0) });
+                       let mut config = UserConfig::new();
+                       config.channel_options.fee_proportional_millionths = 0;
+                       config.channel_options.announced_channel = true;
+                       config.peer_channel_config_limits.min_dust_limit_satoshis = 0;
+
+                       let mut monitors = HashMap::new();
+                       let mut old_monitors = $old_monitors.latest_good_update.lock().unwrap();
+                       for (outpoint, monitor_ser) in old_monitors.drain() {
+                               monitors.insert(outpoint, <(Sha256d, ChannelMonitor)>::read(&mut Cursor::new(&monitor_ser), Arc::clone(&logger)).expect("Failed to read monitor").1);
+                               monitor.latest_good_update.lock().unwrap().insert(outpoint, monitor_ser);
+                       }
+                       let mut monitor_refs = HashMap::new();
+                       for (outpoint, monitor) in monitors.iter() {
+                               monitor_refs.insert(*outpoint, monitor);
+                       }
+
+                       let read_args = ChannelManagerReadArgs {
+                               keys_manager,
+                               fee_estimator: fee_est.clone(),
+                               monitor: monitor.clone(),
+                               tx_broadcaster: broadcast.clone(),
+                               logger,
+                               default_config: config,
+                               channel_monitors: &monitor_refs,
+                       };
+
+                       let res = (<(Sha256d, ChannelManager)>::read(&mut Cursor::new(&$ser.0), read_args).expect("Failed to read manager").1, monitor);
+                       for (_, was_good) in $old_monitors.latest_updates_good_at_last_ser.lock().unwrap().iter() {
+                               if !was_good {
+                                       // If the last time we updated a monitor we didn't successfully update (and we
+                                       // have sense updated our serialized copy of the ChannelManager) we may
+                                       // force-close the channel on our counterparty cause we know we're missing
+                                       // something. Thus, we just return here since we can't continue to test.
+                                       return;
+                               }
+                       }
+                       res
+               } }
+       }
+
+       let mut channel_txn = Vec::new();
+       macro_rules! make_channel {
+               ($source: expr, $dest: expr, $chan_id: expr) => { {
+                       $source.create_channel($dest.get_our_node_id(), 10000000, 42, 0).unwrap();
+                       let open_channel = {
+                               let events = $source.get_and_clear_pending_msg_events();
+                               assert_eq!(events.len(), 1);
+                               if let events::MessageSendEvent::SendOpenChannel { ref msg, .. } = events[0] {
+                                       msg.clone()
+                               } else { panic!("Wrong event type"); }
+                       };
+
+                       $dest.handle_open_channel(&$source.get_our_node_id(), LocalFeatures::new(), &open_channel).unwrap();
+                       let accept_channel = {
+                               let events = $dest.get_and_clear_pending_msg_events();
+                               assert_eq!(events.len(), 1);
+                               if let events::MessageSendEvent::SendAcceptChannel { ref msg, .. } = events[0] {
+                                       msg.clone()
+                               } else { panic!("Wrong event type"); }
+                       };
+
+                       $source.handle_accept_channel(&$dest.get_our_node_id(), LocalFeatures::new(), &accept_channel).unwrap();
+                       {
+                               let events = $source.get_and_clear_pending_events();
+                               assert_eq!(events.len(), 1);
+                               if let events::Event::FundingGenerationReady { ref temporary_channel_id, ref channel_value_satoshis, ref output_script, .. } = events[0] {
+                                       let tx = Transaction { version: $chan_id, lock_time: 0, input: Vec::new(), output: vec![TxOut {
+                                               value: *channel_value_satoshis, script_pubkey: output_script.clone(),
+                                       }]};
+                                       let funding_output = OutPoint::new(tx.txid(), 0);
+                                       $source.funding_transaction_generated(&temporary_channel_id, funding_output);
+                                       channel_txn.push(tx);
+                               } else { panic!("Wrong event type"); }
+                       }
+
+                       let funding_created = {
+                               let events = $source.get_and_clear_pending_msg_events();
+                               assert_eq!(events.len(), 1);
+                               if let events::MessageSendEvent::SendFundingCreated { ref msg, .. } = events[0] {
+                                       msg.clone()
+                               } else { panic!("Wrong event type"); }
+                       };
+                       $dest.handle_funding_created(&$source.get_our_node_id(), &funding_created).unwrap();
+
+                       let funding_signed = {
+                               let events = $dest.get_and_clear_pending_msg_events();
+                               assert_eq!(events.len(), 1);
+                               if let events::MessageSendEvent::SendFundingSigned { ref msg, .. } = events[0] {
+                                       msg.clone()
+                               } else { panic!("Wrong event type"); }
+                       };
+                       $source.handle_funding_signed(&$dest.get_our_node_id(), &funding_signed).unwrap();
+
+                       {
+                               let events = $source.get_and_clear_pending_events();
+                               assert_eq!(events.len(), 1);
+                               if let events::Event::FundingBroadcastSafe { .. } = events[0] {
+                               } else { panic!("Wrong event type"); }
+                       }
+               } }
+       }
+
+       macro_rules! confirm_txn {
+               ($node: expr) => { {
+                       let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+                       let mut txn = Vec::with_capacity(channel_txn.len());
+                       let mut posn = Vec::with_capacity(channel_txn.len());
+                       for i in 0..channel_txn.len() {
+                               txn.push(&channel_txn[i]);
+                               posn.push(i as u32 + 1);
+                       }
+                       $node.block_connected(&header, 1, &txn, &posn);
+                       for i in 2..100 {
+                               header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+                               $node.block_connected(&header, i, &Vec::new(), &[0; 0]);
+                       }
+               } }
+       }
+
+       macro_rules! lock_fundings {
+               ($nodes: expr) => { {
+                       let mut node_events = Vec::new();
+                       for node in $nodes.iter() {
+                               node_events.push(node.get_and_clear_pending_msg_events());
+                       }
+                       for (idx, node_event) in node_events.iter().enumerate() {
+                               for event in node_event {
+                                       if let events::MessageSendEvent::SendFundingLocked { ref node_id, ref msg } = event {
+                                               for node in $nodes.iter() {
+                                                       if node.get_our_node_id() == *node_id {
+                                                               node.handle_funding_locked(&$nodes[idx].get_our_node_id(), msg).unwrap();
+                                                       }
+                                               }
+                                       } else { panic!("Wrong event type"); }
+                               }
+                       }
+
+                       for node in $nodes.iter() {
+                               let events = node.get_and_clear_pending_msg_events();
+                               for event in events {
+                                       if let events::MessageSendEvent::SendAnnouncementSignatures { .. } = event {
+                                       } else { panic!("Wrong event type"); }
+                               }
+                       }
+               } }
+       }
+
+       // 3 nodes is enough to hit all the possible cases, notably unknown-source-unknown-dest
+       // forwarding.
+       let (mut node_a, mut monitor_a) = make_node!(0);
+       let (mut node_b, mut monitor_b) = make_node!(1);
+       let (mut node_c, mut monitor_c) = make_node!(2);
+
+       let mut nodes = [node_a, node_b, node_c];
+
+       make_channel!(nodes[0], nodes[1], 0);
+       make_channel!(nodes[1], nodes[2], 1);
+
+       for node in nodes.iter() {
+               confirm_txn!(node);
+       }
+
+       lock_fundings!(nodes);
+
+       let chan_a = nodes[0].list_usable_channels()[0].short_channel_id.unwrap();
+       let chan_b = nodes[2].list_usable_channels()[0].short_channel_id.unwrap();
+
+       let mut payment_id = 0;
+
+       let mut chan_a_disconnected = false;
+       let mut chan_b_disconnected = false;
+       let mut ba_events = Vec::new();
+       let mut bc_events = Vec::new();
+
+       let mut node_a_ser = VecWriter(Vec::new());
+       nodes[0].write(&mut node_a_ser).unwrap();
+       let mut node_b_ser = VecWriter(Vec::new());
+       nodes[1].write(&mut node_b_ser).unwrap();
+       let mut node_c_ser = VecWriter(Vec::new());
+       nodes[2].write(&mut node_c_ser).unwrap();
+
+       macro_rules! test_err {
+               ($res: expr) => {
+                       match $res {
+                               Ok(()) => {},
+                               Err(LightningError { action: ErrorAction::IgnoreError, .. }) => { },
+                               _ => { $res.unwrap() },
+                       }
+               }
+       }
+
+       macro_rules! test_return {
+               () => { {
+                       assert_eq!(nodes[0].list_channels().len(), 1);
+                       assert_eq!(nodes[1].list_channels().len(), 2);
+                       assert_eq!(nodes[2].list_channels().len(), 1);
+                       return;
+               } }
+       }
+
+       let mut read_pos = 0;
+       macro_rules! get_slice {
+               ($len: expr) => {
+                       {
+                               let slice_len = $len as usize;
+                               if data.len() < read_pos + slice_len {
+                                       test_return!();
+                               }
+                               read_pos += slice_len;
+                               &data[read_pos - slice_len..read_pos]
+                       }
+               }
+       }
+
+       loop {
+               macro_rules! send_payment {
+                       ($source: expr, $dest: expr) => { {
+                               let payment_hash = Sha256::hash(&[payment_id; 1]);
+                               payment_id = payment_id.wrapping_add(1);
+                               if let Err(_) = $source.send_payment(Route {
+                                       hops: vec![RouteHop {
+                                               pubkey: $dest.0.get_our_node_id(),
+                                               short_channel_id: $dest.1,
+                                               fee_msat: 5000000,
+                                               cltv_expiry_delta: 200,
+                                       }],
+                               }, PaymentHash(payment_hash.into_inner())) {
+                                       // Probably ran out of funds
+                                       test_return!();
+                               }
+                       } };
+                       ($source: expr, $middle: expr, $dest: expr) => { {
+                               let payment_hash = Sha256::hash(&[payment_id; 1]);
+                               payment_id = payment_id.wrapping_add(1);
+                               if let Err(_) = $source.send_payment(Route {
+                                       hops: vec![RouteHop {
+                                               pubkey: $middle.0.get_our_node_id(),
+                                               short_channel_id: $middle.1,
+                                               fee_msat: 50000,
+                                               cltv_expiry_delta: 100,
+                                       },RouteHop {
+                                               pubkey: $dest.0.get_our_node_id(),
+                                               short_channel_id: $dest.1,
+                                               fee_msat: 5000000,
+                                               cltv_expiry_delta: 200,
+                                       }],
+                               }, PaymentHash(payment_hash.into_inner())) {
+                                       // Probably ran out of funds
+                                       test_return!();
+                               }
+                       } }
+               }
+
+               macro_rules! process_msg_events {
+                       ($node: expr, $corrupt_forward: expr) => { {
+                               let events = if $node == 1 {
+                                       let mut new_events = Vec::new();
+                                       mem::swap(&mut new_events, &mut ba_events);
+                                       new_events.extend_from_slice(&bc_events[..]);
+                                       bc_events.clear();
+                                       new_events
+                               } else { Vec::new() };
+                               for event in events.iter().chain(nodes[$node].get_and_clear_pending_msg_events().iter()) {
+                                       match event {
+                                               events::MessageSendEvent::UpdateHTLCs { ref node_id, updates: CommitmentUpdate { ref update_add_htlcs, ref update_fail_htlcs, ref update_fulfill_htlcs, ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed } } => {
+                                                       for dest in nodes.iter() {
+                                                               if dest.get_our_node_id() == *node_id {
+                                                                       assert!(update_fee.is_none());
+                                                                       for update_add in update_add_htlcs {
+                                                                               if !$corrupt_forward {
+                                                                                       test_err!(dest.handle_update_add_htlc(&nodes[$node].get_our_node_id(), &update_add));
+                                                                               } else {
+                                                                                       // Corrupt the update_add_htlc message so that its HMAC
+                                                                                       // check will fail and we generate a
+                                                                                       // update_fail_malformed_htlc instead of an
+                                                                                       // update_fail_htlc as we do when we reject a payment.
+                                                                                       let mut msg_ser = update_add.encode();
+                                                                                       msg_ser[1000] ^= 0xff;
+                                                                                       let new_msg = UpdateAddHTLC::read(&mut Cursor::new(&msg_ser)).unwrap();
+                                                                                       test_err!(dest.handle_update_add_htlc(&nodes[$node].get_our_node_id(), &new_msg));
+                                                                               }
+                                                                       }
+                                                                       for update_fulfill in update_fulfill_htlcs {
+                                                                               test_err!(dest.handle_update_fulfill_htlc(&nodes[$node].get_our_node_id(), &update_fulfill));
+                                                                       }
+                                                                       for update_fail in update_fail_htlcs {
+                                                                               test_err!(dest.handle_update_fail_htlc(&nodes[$node].get_our_node_id(), &update_fail));
+                                                                       }
+                                                                       for update_fail_malformed in update_fail_malformed_htlcs {
+                                                                               test_err!(dest.handle_update_fail_malformed_htlc(&nodes[$node].get_our_node_id(), &update_fail_malformed));
+                                                                       }
+                                                                       test_err!(dest.handle_commitment_signed(&nodes[$node].get_our_node_id(), &commitment_signed));
+                                                               }
+                                                       }
+                                               },
+                                               events::MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => {
+                                                       for dest in nodes.iter() {
+                                                               if dest.get_our_node_id() == *node_id {
+                                                                       test_err!(dest.handle_revoke_and_ack(&nodes[$node].get_our_node_id(), msg));
+                                                               }
+                                                       }
+                                               },
+                                               events::MessageSendEvent::SendChannelReestablish { ref node_id, ref msg } => {
+                                                       for dest in nodes.iter() {
+                                                               if dest.get_our_node_id() == *node_id {
+                                                                       test_err!(dest.handle_channel_reestablish(&nodes[$node].get_our_node_id(), msg));
+                                                               }
+                                                       }
+                                               },
+                                               events::MessageSendEvent::SendFundingLocked { .. } => {
+                                                       // Can be generated as a reestablish response
+                                               },
+                                               events::MessageSendEvent::PaymentFailureNetworkUpdate { .. } => {
+                                                       // Can be generated due to a payment forward being rejected due to a
+                                                       // channel having previously failed a monitor update
+                                               },
+                                               _ => panic!("Unhandled message event"),
+                                       }
+                               }
+                       } }
+               }
+
+               macro_rules! drain_msg_events_on_disconnect {
+                       ($counterparty_id: expr) => { {
+                               if $counterparty_id == 0 {
+                                       for event in nodes[0].get_and_clear_pending_msg_events() {
+                                               match event {
+                                                       events::MessageSendEvent::UpdateHTLCs { .. } => {},
+                                                       events::MessageSendEvent::SendRevokeAndACK { .. } => {},
+                                                       events::MessageSendEvent::SendChannelReestablish { .. } => {},
+                                                       events::MessageSendEvent::SendFundingLocked { .. } => {},
+                                                       events::MessageSendEvent::PaymentFailureNetworkUpdate { .. } => {},
+                                                       _ => panic!("Unhandled message event"),
+                                               }
+                                       }
+                                       ba_events.clear();
+                               } else {
+                                       for event in nodes[2].get_and_clear_pending_msg_events() {
+                                               match event {
+                                                       events::MessageSendEvent::UpdateHTLCs { .. } => {},
+                                                       events::MessageSendEvent::SendRevokeAndACK { .. } => {},
+                                                       events::MessageSendEvent::SendChannelReestablish { .. } => {},
+                                                       events::MessageSendEvent::SendFundingLocked { .. } => {},
+                                                       events::MessageSendEvent::PaymentFailureNetworkUpdate { .. } => {},
+                                                       _ => panic!("Unhandled message event"),
+                                               }
+                                       }
+                                       bc_events.clear();
+                               }
+                               let mut events = nodes[1].get_and_clear_pending_msg_events();
+                               let drop_node_id = if $counterparty_id == 0 { nodes[0].get_our_node_id() } else { nodes[2].get_our_node_id() };
+                               let msg_sink = if $counterparty_id == 0 { &mut bc_events } else { &mut ba_events };
+                               for event in events.drain(..) {
+                                       let push = match event {
+                                               events::MessageSendEvent::UpdateHTLCs { ref node_id, .. } => {
+                                                       if *node_id != drop_node_id { true } else { false }
+                                               },
+                                               events::MessageSendEvent::SendRevokeAndACK { ref node_id, .. } => {
+                                                       if *node_id != drop_node_id { true } else { false }
+                                               },
+                                               events::MessageSendEvent::SendChannelReestablish { ref node_id, .. } => {
+                                                       if *node_id != drop_node_id { true } else { false }
+                                               },
+                                               events::MessageSendEvent::SendFundingLocked { .. } => false,
+                                               events::MessageSendEvent::PaymentFailureNetworkUpdate { .. } => false,
+                                               _ => panic!("Unhandled message event"),
+                                       };
+                                       if push { msg_sink.push(event); }
+                               }
+                       } }
+               }
+
+               macro_rules! process_events {
+                       ($node: expr, $fail: expr) => { {
+                               // In case we get 256 payments we may have a hash collision, resulting in the
+                               // second claim/fail call not finding the duplicate-hash HTLC, so we have to
+                               // deduplicate the calls here.
+                               let mut claim_set = HashSet::new();
+                               let mut events = nodes[$node].get_and_clear_pending_events();
+                               // Sort events so that PendingHTLCsForwardable get processed last. This avoids a
+                               // case where we first process a PendingHTLCsForwardable, then claim/fail on a
+                               // PaymentReceived, claiming/failing two HTLCs, but leaving a just-generated
+                               // PaymentReceived event for the second HTLC in our pending_events (and breaking
+                               // our claim_set deduplication).
+                               events.sort_by(|a, b| {
+                                       if let events::Event::PaymentReceived { .. } = a {
+                                               if let events::Event::PendingHTLCsForwardable { .. } = b {
+                                                       Ordering::Less
+                                               } else { Ordering::Equal }
+                                       } else if let events::Event::PendingHTLCsForwardable { .. } = a {
+                                               if let events::Event::PaymentReceived { .. } = b {
+                                                       Ordering::Greater
+                                               } else { Ordering::Equal }
+                                       } else { Ordering::Equal }
+                               });
+                               for event in events.drain(..) {
+                                       match event {
+                                               events::Event::PaymentReceived { payment_hash, .. } => {
+                                                       if claim_set.insert(payment_hash.0) {
+                                                               if $fail {
+                                                                       assert!(nodes[$node].fail_htlc_backwards(&payment_hash));
+                                                               } else {
+                                                                       assert!(nodes[$node].claim_funds(PaymentPreimage(payment_hash.0), 5_000_000));
+                                                               }
+                                                       }
+                                               },
+                                               events::Event::PaymentSent { .. } => {},
+                                               events::Event::PaymentFailed { .. } => {},
+                                               events::Event::PendingHTLCsForwardable { .. } => {
+                                                       nodes[$node].process_pending_htlc_forwards();
+                                               },
+                                               _ => panic!("Unhandled event"),
+                                       }
+                               }
+                       } }
+               }
+
+               match get_slice!(1)[0] {
+                       0x00 => *monitor_a.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure),
+                       0x01 => *monitor_b.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure),
+                       0x02 => *monitor_c.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure),
+                       0x03 => *monitor_a.update_ret.lock().unwrap() = Ok(()),
+                       0x04 => *monitor_b.update_ret.lock().unwrap() = Ok(()),
+                       0x05 => *monitor_c.update_ret.lock().unwrap() = Ok(()),
+                       0x06 => { unsafe { IN_RESTORE = true }; nodes[0].test_restore_channel_monitor(); unsafe { IN_RESTORE = false }; },
+                       0x07 => { unsafe { IN_RESTORE = true }; nodes[1].test_restore_channel_monitor(); unsafe { IN_RESTORE = false }; },
+                       0x08 => { unsafe { IN_RESTORE = true }; nodes[2].test_restore_channel_monitor(); unsafe { IN_RESTORE = false }; },
+                       0x09 => send_payment!(nodes[0], (&nodes[1], chan_a)),
+                       0x0a => send_payment!(nodes[1], (&nodes[0], chan_a)),
+                       0x0b => send_payment!(nodes[1], (&nodes[2], chan_b)),
+                       0x0c => send_payment!(nodes[2], (&nodes[1], chan_b)),
+                       0x0d => send_payment!(nodes[0], (&nodes[1], chan_a), (&nodes[2], chan_b)),
+                       0x0e => send_payment!(nodes[2], (&nodes[1], chan_b), (&nodes[0], chan_a)),
+                       0x0f => {
+                               if !chan_a_disconnected {
+                                       nodes[0].peer_disconnected(&nodes[1].get_our_node_id(), false);
+                                       nodes[1].peer_disconnected(&nodes[0].get_our_node_id(), false);
+                                       chan_a_disconnected = true;
+                                       drain_msg_events_on_disconnect!(0);
+                               }
+                       },
+                       0x10 => {
+                               if !chan_b_disconnected {
+                                       nodes[1].peer_disconnected(&nodes[2].get_our_node_id(), false);
+                                       nodes[2].peer_disconnected(&nodes[1].get_our_node_id(), false);
+                                       chan_b_disconnected = true;
+                                       drain_msg_events_on_disconnect!(2);
+                               }
+                       },
+                       0x11 => {
+                               if chan_a_disconnected {
+                                       nodes[0].peer_connected(&nodes[1].get_our_node_id());
+                                       nodes[1].peer_connected(&nodes[0].get_our_node_id());
+                                       chan_a_disconnected = false;
+                               }
+                       },
+                       0x12 => {
+                               if chan_b_disconnected {
+                                       nodes[1].peer_connected(&nodes[2].get_our_node_id());
+                                       nodes[2].peer_connected(&nodes[1].get_our_node_id());
+                                       chan_b_disconnected = false;
+                               }
+                       },
+                       0x13 => process_msg_events!(0, true),
+                       0x14 => process_msg_events!(0, false),
+                       0x15 => process_events!(0, true),
+                       0x16 => process_events!(0, false),
+                       0x17 => process_msg_events!(1, true),
+                       0x18 => process_msg_events!(1, false),
+                       0x19 => process_events!(1, true),
+                       0x1a => process_events!(1, false),
+                       0x1b => process_msg_events!(2, true),
+                       0x1c => process_msg_events!(2, false),
+                       0x1d => process_events!(2, true),
+                       0x1e => process_events!(2, false),
+                       0x1f => {
+                               if !chan_a_disconnected {
+                                       nodes[1].peer_disconnected(&nodes[0].get_our_node_id(), false);
+                                       chan_a_disconnected = true;
+                                       drain_msg_events_on_disconnect!(0);
+                               }
+                               let (new_node_a, new_monitor_a) = reload_node!(node_a_ser, 0, monitor_a);
+                               node_a = Arc::new(new_node_a);
+                               nodes[0] = node_a.clone();
+                               monitor_a = new_monitor_a;
+                       },
+                       0x20 => {
+                               if !chan_a_disconnected {
+                                       nodes[0].peer_disconnected(&nodes[1].get_our_node_id(), false);
+                                       chan_a_disconnected = true;
+                                       nodes[0].get_and_clear_pending_msg_events();
+                                       ba_events.clear();
+                               }
+                               if !chan_b_disconnected {
+                                       nodes[2].peer_disconnected(&nodes[1].get_our_node_id(), false);
+                                       chan_b_disconnected = true;
+                                       nodes[2].get_and_clear_pending_msg_events();
+                                       bc_events.clear();
+                               }
+                               let (new_node_b, new_monitor_b) = reload_node!(node_b_ser, 1, monitor_b);
+                               node_b = Arc::new(new_node_b);
+                               nodes[1] = node_b.clone();
+                               monitor_b = new_monitor_b;
+                       },
+                       0x21 => {
+                               if !chan_b_disconnected {
+                                       nodes[1].peer_disconnected(&nodes[2].get_our_node_id(), false);
+                                       chan_b_disconnected = true;
+                                       drain_msg_events_on_disconnect!(2);
+                               }
+                               let (new_node_c, new_monitor_c) = reload_node!(node_c_ser, 2, monitor_c);
+                               node_c = Arc::new(new_node_c);
+                               nodes[2] = node_c.clone();
+                               monitor_c = new_monitor_c;
+                       },
+                       _ => test_return!(),
+               }
+
+               if monitor_a.should_update_manager.load(atomic::Ordering::Relaxed) {
+                       node_a_ser.0.clear();
+                       nodes[0].write(&mut node_a_ser).unwrap();
+                       monitor_a.should_update_manager.store(false, atomic::Ordering::Relaxed);
+                       *monitor_a.latest_updates_good_at_last_ser.lock().unwrap() = monitor_a.latest_update_good.lock().unwrap().clone();
+               }
+               if monitor_b.should_update_manager.load(atomic::Ordering::Relaxed) {
+                       node_b_ser.0.clear();
+                       nodes[1].write(&mut node_b_ser).unwrap();
+                       monitor_b.should_update_manager.store(false, atomic::Ordering::Relaxed);
+                       *monitor_b.latest_updates_good_at_last_ser.lock().unwrap() = monitor_b.latest_update_good.lock().unwrap().clone();
+               }
+               if monitor_c.should_update_manager.load(atomic::Ordering::Relaxed) {
+                       node_c_ser.0.clear();
+                       nodes[2].write(&mut node_c_ser).unwrap();
+                       monitor_c.should_update_manager.store(false, atomic::Ordering::Relaxed);
+                       *monitor_c.latest_updates_good_at_last_ser.lock().unwrap() = monitor_c.latest_update_good.lock().unwrap().clone();
+               }
+       }
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+#[cfg(feature = "libfuzzer_fuzz")]
+#[macro_use] extern crate libfuzzer_sys;
+#[cfg(feature = "libfuzzer_fuzz")]
+fuzz_target!(|data: &[u8]| {
+       do_test(data);
+});
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/full_stack_target.rs b/fuzz/fuzz_targets/full_stack_target.rs
new file mode 100644 (file)
index 0000000..cd65a2f
--- /dev/null
@@ -0,0 +1,891 @@
+//! Test that no series of bytes received over the wire/connections created/payments sent can
+//! result in a crash. We do this by standing up a node and then reading bytes from input to denote
+//! actions such as creating new inbound/outbound connections, bytes to be read from a connection,
+//! or payments to send/ways to handle events generated.
+//! This test has been very useful, though due to its complexity good starting inputs are critical.
+
+//Uncomment this for libfuzzer builds:
+//#![no_main]
+
+extern crate bitcoin;
+extern crate bitcoin_hashes;
+extern crate lightning;
+extern crate secp256k1;
+
+use bitcoin::blockdata::block::BlockHeader;
+use bitcoin::blockdata::transaction::{Transaction, TxOut};
+use bitcoin::blockdata::script::{Builder, Script};
+use bitcoin::blockdata::opcodes;
+use bitcoin::consensus::encode::deserialize;
+use bitcoin::network::constants::Network;
+use bitcoin::util::hash::BitcoinHash;
+
+use bitcoin_hashes::Hash as TraitImport;
+use bitcoin_hashes::HashEngine as TraitImportEngine;
+use bitcoin_hashes::sha256::Hash as Sha256;
+use bitcoin_hashes::hash160::Hash as Hash160;
+use bitcoin_hashes::sha256d::Hash as Sha256dHash;
+
+use lightning::chain::chaininterface::{BroadcasterInterface,ConfirmationTarget,ChainListener,FeeEstimator,ChainWatchInterfaceUtil};
+use lightning::chain::transaction::OutPoint;
+use lightning::chain::keysinterface::{ChannelKeys, KeysInterface};
+use lightning::ln::channelmonitor;
+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::logger::Logger;
+use lightning::util::config::UserConfig;
+
+mod utils;
+
+use utils::test_logger;
+
+use secp256k1::key::{PublicKey,SecretKey};
+use secp256k1::Secp256k1;
+
+use std::cell::RefCell;
+use std::collections::{HashMap, hash_map};
+use std::cmp;
+use std::hash::Hash;
+use std::sync::Arc;
+use std::sync::atomic::{AtomicU64,AtomicUsize,Ordering};
+
+#[inline]
+pub fn slice_to_be16(v: &[u8]) -> u16 {
+       ((v[0] as u16) << 8*1) |
+       ((v[1] as u16) << 8*0)
+}
+
+#[inline]
+pub fn slice_to_be24(v: &[u8]) -> u32 {
+       ((v[0] as u32) << 8*2) |
+       ((v[1] as u32) << 8*1) |
+       ((v[2] as u32) << 8*0)
+}
+
+#[inline]
+pub fn slice_to_be32(v: &[u8]) -> u32 {
+       ((v[0] as u32) << 8*3) |
+       ((v[1] as u32) << 8*2) |
+       ((v[2] as u32) << 8*1) |
+       ((v[3] as u32) << 8*0)
+}
+
+#[inline]
+pub fn be64_to_array(u: u64) -> [u8; 8] {
+       let mut v = [0; 8];
+       v[0] = ((u >> 8*7) & 0xff) as u8;
+       v[1] = ((u >> 8*6) & 0xff) as u8;
+       v[2] = ((u >> 8*5) & 0xff) as u8;
+       v[3] = ((u >> 8*4) & 0xff) as u8;
+       v[4] = ((u >> 8*3) & 0xff) as u8;
+       v[5] = ((u >> 8*2) & 0xff) as u8;
+       v[6] = ((u >> 8*1) & 0xff) as u8;
+       v[7] = ((u >> 8*0) & 0xff) as u8;
+       v
+}
+
+struct InputData {
+       data: Vec<u8>,
+       read_pos: AtomicUsize,
+}
+impl InputData {
+       fn get_slice(&self, len: usize) -> Option<&[u8]> {
+               let old_pos = self.read_pos.fetch_add(len, Ordering::AcqRel);
+               if self.data.len() < old_pos + len {
+                       return None;
+               }
+               Some(&self.data[old_pos..old_pos + len])
+       }
+}
+
+struct FuzzEstimator {
+       input: Arc<InputData>,
+}
+impl FeeEstimator for FuzzEstimator {
+       fn get_est_sat_per_1000_weight(&self, _: ConfirmationTarget) -> u64 {
+               //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
+               }
+       }
+}
+
+struct TestBroadcaster {}
+impl BroadcasterInterface for TestBroadcaster {
+       fn broadcast_transaction(&self, _tx: &Transaction) {}
+}
+
+#[derive(Clone)]
+struct Peer<'a> {
+       id: u8,
+       peers_connected: &'a RefCell<[bool; 256]>,
+}
+impl<'a> SocketDescriptor for Peer<'a> {
+       fn send_data(&mut self, data: &[u8], _resume_read: bool) -> usize {
+               data.len()
+       }
+       fn disconnect_socket(&mut self) {
+               assert!(self.peers_connected.borrow()[self.id as usize]);
+               self.peers_connected.borrow_mut()[self.id as usize] = false;
+       }
+}
+impl<'a> PartialEq for Peer<'a> {
+       fn eq(&self, other: &Self) -> bool {
+               self.id == other.id
+       }
+}
+impl<'a> Eq for Peer<'a> {}
+impl<'a> Hash for Peer<'a> {
+       fn hash<H : std::hash::Hasher>(&self, h: &mut H) {
+               self.id.hash(h)
+       }
+}
+
+struct MoneyLossDetector<'a, 'b> {
+       manager: Arc<ChannelManager<'b>>,
+       monitor: Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint>>,
+       handler: PeerManager<Peer<'a>>,
+
+       peers: &'a RefCell<[bool; 256]>,
+       funding_txn: Vec<Transaction>,
+       txids_confirmed: HashMap<Sha256dHash, usize>,
+       header_hashes: Vec<Sha256dHash>,
+       height: usize,
+       max_height: usize,
+       blocks_connected: u32,
+}
+impl<'a, 'b> MoneyLossDetector<'a, 'b> {
+       pub fn new(peers: &'a RefCell<[bool; 256]>, manager: Arc<ChannelManager<'b>>, monitor: Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint>>, handler: PeerManager<Peer<'a>>) -> Self {
+               MoneyLossDetector {
+                       manager,
+                       monitor,
+                       handler,
+
+                       peers,
+                       funding_txn: Vec::new(),
+                       txids_confirmed: HashMap::new(),
+                       header_hashes: vec![Default::default()],
+                       height: 0,
+                       max_height: 0,
+                       blocks_connected: 0,
+               }
+       }
+
+       fn connect_block(&mut self, all_txn: &[Transaction]) {
+               let mut txn = Vec::with_capacity(all_txn.len());
+               let mut txn_idxs = Vec::with_capacity(all_txn.len());
+               for (idx, tx) in all_txn.iter().enumerate() {
+                       let txid = tx.txid();
+                       match self.txids_confirmed.entry(txid) {
+                               hash_map::Entry::Vacant(e) => {
+                                       e.insert(self.height);
+                                       txn.push(tx);
+                                       txn_idxs.push(idx as u32 + 1);
+                               },
+                               _ => {},
+                       }
+               }
+
+               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;
+               self.manager.block_connected(&header, self.height as u32, &txn[..], &txn_idxs[..]);
+               (*self.monitor).block_connected(&header, self.height as u32, &txn[..], &txn_idxs[..]);
+               if self.header_hashes.len() > self.height {
+                       self.header_hashes[self.height] = header.bitcoin_hash();
+               } else {
+                       assert_eq!(self.header_hashes.len(), self.height);
+                       self.header_hashes.push(header.bitcoin_hash());
+               }
+               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) {
+                       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);
+                       let removal_height = self.height;
+                       self.txids_confirmed.retain(|_, height| {
+                               removal_height != *height
+                       });
+               }
+       }
+}
+
+impl<'a, 'b> Drop for MoneyLossDetector<'a, 'b> {
+       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});
+                               }
+                       }
+
+                       // Force all channels onto the chain (and time out claim txn)
+                       self.manager.force_close_all_channels();
+               }
+       }
+}
+
+struct KeyProvider {
+       node_secret: SecretKey,
+       counter: AtomicU64,
+}
+impl KeysInterface for KeyProvider {
+       fn get_node_secret(&self) -> SecretKey {
+               self.node_secret.clone()
+       }
+
+       fn get_destination_script(&self) -> Script {
+               let secp_ctx = Secp256k1::signing_only();
+               let channel_monitor_claim_key = SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap();
+               let our_channel_monitor_claim_key_hash = <Hash160 as bitcoin_hashes::Hash>::hash(&PublicKey::from_secret_key(&secp_ctx, &channel_monitor_claim_key).serialize());
+               Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script()
+       }
+
+       fn get_shutdown_pubkey(&self) -> PublicKey {
+               let secp_ctx = Secp256k1::signing_only();
+               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) -> ChannelKeys {
+               let ctr = self.counter.fetch_add(1, Ordering::Relaxed) as u8;
+               if inbound {
+                       ChannelKeys {
+                               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],
+                       }
+               } else {
+                       ChannelKeys {
+                               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],
+                       }
+               }
+       }
+
+       fn get_session_key(&self) -> SecretKey {
+               let ctr = self.counter.fetch_add(1, Ordering::Relaxed) as u8;
+               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, 13, ctr]).unwrap()
+       }
+
+       fn get_channel_id(&self) -> [u8; 32] {
+               let ctr = self.counter.fetch_add(1, Ordering::Relaxed);
+               [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+               (ctr >> 8*7) as u8, (ctr >> 8*6) as u8, (ctr >> 8*5) as u8, (ctr >> 8*4) as u8, (ctr >> 8*3) as u8, (ctr >> 8*2) as u8, (ctr >> 8*1) as u8, 14, (ctr >> 8*0) as u8]
+       }
+}
+
+#[inline]
+pub fn do_test(data: &[u8], logger: &Arc<Logger>) {
+       let input = Arc::new(InputData {
+               data: data.to_vec(),
+               read_pos: AtomicUsize::new(0),
+       });
+       let fee_est = Arc::new(FuzzEstimator {
+               input: input.clone(),
+       });
+
+       macro_rules! get_slice {
+               ($len: expr) => {
+                       match input.get_slice($len as usize) {
+                               Some(slice) => slice,
+                               None => return,
+                       }
+               }
+       }
+
+       macro_rules! get_pubkey {
+               () => {
+                       match PublicKey::from_slice(get_slice!(33)) {
+                               Ok(key) => key,
+                               Err(_) => return,
+                       }
+               }
+       }
+
+       let our_network_key = match SecretKey::from_slice(get_slice!(32)) {
+               Ok(key) => key,
+               Err(_) => return,
+       };
+
+       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 keys_manager = Arc::new(KeyProvider { node_secret: our_network_key.clone(), counter: AtomicU64::new(0) });
+       let mut config = UserConfig::new();
+       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 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]);
+       let mut loss_detector = MoneyLossDetector::new(&peers, channelmanager.clone(), monitor.clone(), PeerManager::new(MessageHandler {
+               chan_handler: channelmanager.clone(),
+               route_handler: router.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;
+       let mut payments_received: Vec<(PaymentHash, u64)> = Vec::new();
+       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] {
+                       0 => {
+                               let mut new_id = 0;
+                               for i in 1..256 {
+                                       if !peers.borrow()[i-1] {
+                                               new_id = i;
+                                               break;
+                                       }
+                               }
+                               if new_id == 0 { return; }
+                               loss_detector.handler.new_outbound_connection(get_pubkey!(), Peer{id: (new_id - 1) as u8, peers_connected: &peers}).unwrap();
+                               peers.borrow_mut()[new_id - 1] = true;
+                       },
+                       1 => {
+                               let mut new_id = 0;
+                               for i in 1..256 {
+                                       if !peers.borrow()[i-1] {
+                                               new_id = i;
+                                               break;
+                                       }
+                               }
+                               if new_id == 0 { return; }
+                               loss_detector.handler.new_inbound_connection(Peer{id: (new_id - 1) as u8, peers_connected: &peers}).unwrap();
+                               peers.borrow_mut()[new_id - 1] = true;
+                       },
+                       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});
+                               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()) {
+                                       Ok(res) => assert!(!res),
+                                       Err(_) => { peers.borrow_mut()[peer_id as usize] = false; }
+                               }
+                       },
+                       4 => {
+                               let value = slice_to_be24(get_slice!(3)) as u64;
+                               let route = match router.get_route(&get_pubkey!(), None, &Vec::new(), value, 42) {
+                                       Ok(route) => route,
+                                       Err(_) => return,
+                               };
+                               let mut payment_hash = PaymentHash([0; 32]);
+                               payment_hash.0[0..8].copy_from_slice(&be64_to_array(payments_sent));
+                               let mut sha = Sha256::engine();
+                               sha.input(&payment_hash.0[..]);
+                               payment_hash.0 = Sha256::from_engine(sha).into_inner();
+                               payments_sent += 1;
+                               match channelmanager.send_payment(route, payment_hash) {
+                                       Ok(_) => {},
+                                       Err(_) => return,
+                               }
+                       },
+                       5 => {
+                               let peer_id = get_slice!(1)[0];
+                               if !peers.borrow()[peer_id as usize] { return; }
+                               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; }
+                       },
+                       6 => {
+                               let mut channels = channelmanager.list_channels();
+                               let channel_id = get_slice!(1)[0] as usize;
+                               if channel_id >= channels.len() { return; }
+                               channels.sort_by(|a, b| { a.channel_id.cmp(&b.channel_id) });
+                               if channelmanager.close_channel(&channels[channel_id].channel_id).is_err() { return; }
+                       },
+                       7 => {
+                               if should_forward {
+                                       channelmanager.process_pending_htlc_forwards();
+                                       should_forward = false;
+                               }
+                       },
+                       8 => {
+                               for (payment, amt) in payments_received.drain(..) {
+                                       // SHA256 is defined as XOR of all input bytes placed in the first byte, and 0s
+                                       // for the remaining bytes. Thus, if not all remaining bytes are 0s we cannot
+                                       // fulfill this HTLC, but if they are, we can just take the first byte and
+                                       // place that anywhere in our preimage.
+                                       if &payment.0[1..] != &[0; 31] {
+                                               channelmanager.fail_htlc_backwards(&payment);
+                                       } else {
+                                               let mut payment_preimage = PaymentPreimage([0; 32]);
+                                               payment_preimage.0[0] = payment.0[0];
+                                               channelmanager.claim_funds(payment_preimage, amt);
+                                       }
+                               }
+                       },
+                       9 => {
+                               for (payment, _) in payments_received.drain(..) {
+                                       channelmanager.fail_htlc_backwards(&payment);
+                               }
+                       },
+                       10 => {
+                               'outer_loop: for funding_generation in pending_funding_generation.drain(..) {
+                                       let mut tx = Transaction { version: 0, lock_time: 0, input: Vec::new(), output: vec![TxOut {
+                                                       value: funding_generation.1, script_pubkey: funding_generation.2,
+                                               }] };
+                                       let funding_output = 'search_loop: loop {
+                                               let funding_txid = tx.txid();
+                                               if let None = loss_detector.txids_confirmed.get(&funding_txid) {
+                                                       let outpoint = OutPoint::new(funding_txid, 0);
+                                                       for chan in channelmanager.list_channels() {
+                                                               if chan.channel_id == outpoint.to_channel_id() {
+                                                                       tx.version += 1;
+                                                                       continue 'search_loop;
+                                                               }
+                                                       }
+                                                       break outpoint;
+                                               }
+                                               tx.version += 1;
+                                               if tx.version > 0xff {
+                                                       continue 'outer_loop;
+                                               }
+                                       };
+                                       channelmanager.funding_transaction_generated(&funding_generation.0, funding_output.clone());
+                                       pending_funding_signatures.insert(funding_output, tx);
+                               }
+                       },
+                       11 => {
+                               if !pending_funding_relay.is_empty() {
+                                       loss_detector.connect_block(&pending_funding_relay[..]);
+                                       for _ in 2..100 {
+                                               loss_detector.connect_block(&[]);
+                                       }
+                               }
+                               for tx in pending_funding_relay.drain(..) {
+                                       loss_detector.funding_txn.push(tx);
+                               }
+                       },
+                       12 => {
+                               let txlen = slice_to_be16(get_slice!(2));
+                               if txlen == 0 {
+                                       loss_detector.connect_block(&[]);
+                               } else {
+                                       let txres: Result<Transaction, _> = deserialize(get_slice!(txlen));
+                                       if let Ok(tx) = txres {
+                                               loss_detector.connect_block(&[tx]);
+                                       } else {
+                                               return;
+                                       }
+                               }
+                       },
+                       13 => {
+                               loss_detector.disconnect_block();
+                       },
+                       14 => {
+                               let mut channels = channelmanager.list_channels();
+                               let channel_id = get_slice!(1)[0] as usize;
+                               if channel_id >= channels.len() { return; }
+                               channels.sort_by(|a, b| { a.channel_id.cmp(&b.channel_id) });
+                               channelmanager.force_close_channel(&channels[channel_id].channel_id);
+                       },
+                       _ => return,
+               }
+               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, .. } => {
+                                       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, amt } => {
+                                       //TODO: enhance by fetching random amounts from fuzz input?
+                                       payments_received.push((payment_hash, amt));
+                               },
+                               Event::PaymentSent {..} => {},
+                               Event::PaymentFailed {..} => {},
+                               Event::PendingHTLCsForwardable {..} => {
+                                       should_forward = true;
+                               },
+                               Event::SpendableOutputs {..} => {},
+                       }
+               }
+       }
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               let logger: Arc<Logger> = Arc::new(test_logger::TestLogger::new("".to_owned()));
+               do_test(data, &logger);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       let logger: Arc<Logger> = Arc::new(test_logger::TestLogger::new("".to_owned()));
+                       do_test(data, &logger);
+               });
+       }
+}
+
+#[cfg(feature = "libfuzzer_fuzz")]
+#[macro_use] extern crate libfuzzer_sys;
+#[cfg(feature = "libfuzzer_fuzz")]
+fuzz_target!(|data: &[u8]| {
+       let logger: Arc<Logger> = Arc::new(test_logger::TestLogger::new("".to_owned()));
+       do_test(data, &logger);
+});
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       use utils::test_logger;
+       use lightning::util::logger::{Logger, Record};
+       use std::collections::HashMap;
+       use std::sync::{Arc, Mutex};
+
+       #[test]
+       fn duplicate_crash() {
+               let logger: Arc<Logger> = Arc::new(test_logger::TestLogger::new("".to_owned()));
+               super::do_test(&::hex::decode("00").unwrap(), &logger);
+       }
+
+       struct TrackingLogger {
+               /// (module, message) -> count
+               pub lines: Mutex<HashMap<(String, String), usize>>,
+       }
+       impl Logger for TrackingLogger {
+               fn log(&self, record: &Record) {
+                       *self.lines.lock().unwrap().entry((record.module_path.to_string(), format!("{}", record.args))).or_insert(0) += 1;
+                       println!("{:<5} [{} : {}, {}] {}", record.level.to_string(), record.module_path, record.file, record.line, record.args);
+               }
+       }
+
+       #[test]
+       fn test_no_existing_test_breakage() {
+               // To avoid accidentally causing all existing fuzz test cases to be useless by making minor
+               // changes (such as requesting feerate info in a new place), we run a pretty full
+               // step-through with two peers and HTLC forwarding here. Obviously this is pretty finicky,
+               // so this should be updated pretty liberally, but at least we'll know when changes occur.
+               // If nothing else, this test serves as a pretty great initial full_stack_target seed.
+
+               // What each byte represents is broken down below, and then everything is concatenated into
+               // one large test at the end (you want %s/ -.*//g %s/\n\| \|\t\|\///g).
+
+               // Following BOLT 8, lightning message on the wire are: 2-byte encrypted message length + 
+               // 16-byte MAC of the encrypted message length + encrypted Lightning message + 16-byte MAC
+               // of the Lightning message
+               // I.e 2nd inbound read, len 18 : 0006 (encrypted message length) + 03000000000000000000000000000000 (MAC of the encrypted message length)
+               // Len 22 : 0010 00000000 (encrypted lightning message) + 03000000000000000000000000000000 (MAC of the Lightning message)
+
+               // 0000000000000000000000000000000000000000000000000000000000000000 - our network key
+               // 00000000 - fee_proportional_millionths
+               // 01 - announce_channels_publicly
+               //
+               // 00 - new outbound connection with id 0
+               // 030000000000000000000000000000000000000000000000000000000000000000 - peer's pubkey
+               // 030032 - inbound read from peer id 0 of len 50
+               // 00 030000000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - noise act two (0||pubkey||mac)
+               //
+               // 030012 - inbound read from peer id 0 of len 18
+               // 0006 03000000000000000000000000000000 - message header indicating message length 6
+               // 030016 - inbound read from peer id 0 of len 22
+               // 0010 00000000 03000000000000000000000000000000 - init message with no features (type 16) and mac
+               //
+               // 030012 - inbound read from peer id 0 of len 18
+               // 0141 03000000000000000000000000000000 - message header indicating message length 321
+               // 0300fe - inbound read from peer id 0 of len 254
+               // 0020 7500000000000000000000000000000000000000000000000000000000000000 ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679 000000000000c350 0000000000000000 0000000000000222 ffffffffffffffff 0000000000000222 0000000000000000 000000fd 0006 01e3 030000000000000000000000000000000000000000000000000000000000000001 030000000000000000000000000000000000000000000000000000000000000002 030000000000000000000000000000000000000000000000000000000000000003 030000000000000000000000000000000000000000000000000000000000000004 - beginning of open_channel message
+               // 030053 - inbound read from peer id 0 of len 83
+               // 030000000000000000000000000000000000000000000000000000000000000005 030000000000000000000000000000000000000000000000000000000000000000 01 03000000000000000000000000000000 - rest of open_channel and mac
+               //
+               // 00fd00fd00fd - Three feerate requests (all returning min feerate, which our open_channel also uses) (gonna be ingested by FuzzEstimator)
+               // - client should now respond with accept_channel (CHECK 1: type 33 to peer 03000000)
+               //
+               // 030012 - inbound read from peer id 0 of len 18
+               // 0084 03000000000000000000000000000000 - message header indicating message length 132
+               // 030094 - inbound read from peer id 0 of len 148
+               // 0022 ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679 3d00000000000000000000000000000000000000000000000000000000000000 0000 5c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 03000000000000000000000000000000 - funding_created and mac
+               // - client should now respond with funding_signed (CHECK 2: type 35 to peer 03000000)
+               //
+               // 0c005e - connect a block with one transaction of len 94
+               // 020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0150c3000000000000220020ae0000000000000000000000000000000000000000000000000000000000000000000000 - the funding transaction
+               // 0c0000 - connect a block with no transactions
+               // 0c0000 - connect a block with no transactions
+               // 0c0000 - connect a block with no transactions
+               // 0c0000 - connect a block with no transactions
+               // 0c0000 - connect a block with no transactions
+               // 0c0000 - connect a block with no transactions
+               // 0c0000 - connect a block with no transactions
+               // 0c0000 - connect a block with no transactions
+               // 0c0000 - connect a block with no transactions
+               // 0c0000 - connect a block with no transactions
+               // 0c0000 - connect a block with no transactions
+               // 0c0000 - connect a block with no transactions
+               // - by now client should have sent a funding_locked (CHECK 3: SendFundingLocked to 03000000 for chan 3d000000)
+               //
+               // 030012 - inbound read from peer id 0 of len 18
+               // 0043 03000000000000000000000000000000 - message header indicating message length 67
+               // 030053 - inbound read from peer id 0 of len 83
+               // 0024 3d00000000000000000000000000000000000000000000000000000000000000 030100000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - funding_locked and mac
+               //
+               // 01 - new inbound connection with id 1
+               // 030132 - inbound read from peer id 1 of len 50
+               // 0003000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000 - inbound noise act 1
+               // 030142 - inbound read from peer id 1 of len 66
+               // 000302000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003000000000000000000000000000000 - inbound noise act 3
+               //
+               // 030112 - inbound read from peer id 1 of len 18
+               // 0006 01000000000000000000000000000000 - message header indicating message length 6
+               // 030116 - inbound read from peer id 1 of len 22
+               // 0010 00000000 01000000000000000000000000000000 - init message with no features (type 16)
+               //
+               // 05 01 030200000000000000000000000000000000000000000000000000000000000000 00c350 0003e8 - create outbound channel to peer 1 for 50k sat
+               // 00fd00fd00fd - Three feerate requests (all returning min feerate) (gonna be ingested by FuzzEstimator)
+               //
+               // 030112 - inbound read from peer id 1 of len 18
+               // 0110 01000000000000000000000000000000 - message header indicating message length 272
+               // 0301ff - inbound read from peer id 1 of len 255
+               // 0021 0000000000000000000000000000000000000000000000000000000000000e02 000000000000001a 00000000004c4b40 00000000000003e8 00000000000003e8 00000002 03f0 0005 030000000000000000000000000000000000000000000000000000000000000100 030000000000000000000000000000000000000000000000000000000000000200 030000000000000000000000000000000000000000000000000000000000000300 030000000000000000000000000000000000000000000000000000000000000400 030000000000000000000000000000000000000000000000000000000000000500 03000000000000000000000000000000 - beginning of accept_channel
+               // 030121 - inbound read from peer id 1 of len 33
+               // 0000000000000000000000000000000000 01000000000000000000000000000000 - rest of accept_channel and mac
+               //
+               // 0a - create the funding transaction (client should send funding_created now)
+               //
+               // 030112 - inbound read from peer id 1 of len 18
+               // 0062 01000000000000000000000000000000 - message header indicating message length 98
+               // 030172 - inbound read from peer id 1 of len 114
+               // 0023 3900000000000000000000000000000000000000000000000000000000000000 f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100 01000000000000000000000000000000 - funding_signed message and mac
+               //
+               // 0b - broadcast funding transaction
+               // - by now client should have sent a funding_locked (CHECK 4: SendFundingLocked to 03020000 for chan 3f000000)
+               //
+               // 030112 - inbound read from peer id 1 of len 18
+               // 0043 01000000000000000000000000000000 - message header indicating message length 67
+               // 030153 - inbound read from peer id 1 of len 83
+               // 0024 3900000000000000000000000000000000000000000000000000000000000000 030100000000000000000000000000000000000000000000000000000000000000 01000000000000000000000000000000 - funding_locked and mac
+               //
+               // 030012 - inbound read from peer id 0 of len 18
+               // 05ac 03000000000000000000000000000000 - message header indicating message length 1452
+               // 0300ff - inbound read from peer id 0 of len 255
+               // 0080 3d00000000000000000000000000000000000000000000000000000000000000 0000000000000000 0000000000003e80 ff00000000000000000000000000000000000000000000000000000000000000 00000121 00 030000000000000000000000000000000000000000000000000000000000000555 0000000e000001000000000000000003e8000000010000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - beginning of update_add_htlc from 0 to 1 via client
+               // 0300ff - inbound read from peer id 0 of len 255
+               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+               // 0300ff - inbound read from peer id 0 of len 255
+               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+               // 0300ff - inbound read from peer id 0 of len 255
+               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+               // 0300ff - inbound read from peer id 0 of len 255
+               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+               // 0300c1 - inbound read from peer id 0 of len 193
+               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ef00000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - end of update_add_htlc from 0 to 1 via client and mac
+               //
+               // 00fd - A feerate request (returning min feerate, which our open_channel also uses) (gonna be ingested by FuzzEstimator)
+               //
+               // 030012 - inbound read from peer id 0 of len 18
+               // 0064 03000000000000000000000000000000 - message header indicating message length 100
+               // 030074 - inbound read from peer id 0 of len 116
+               // 0084 3d00000000000000000000000000000000000000000000000000000000000000 4d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 0000 03000000000000000000000000000000 - commitment_signed and mac
+               // - client should now respond with revoke_and_ack and commitment_signed (CHECK 5/6: types 133 and 132 to peer 03000000)
+               //
+               // 030012 - inbound read from peer id 0 of len 18
+               // 0063 03000000000000000000000000000000 - message header indicating message length 99
+               // 030073 - inbound read from peer id 0 of len 115
+               // 0085 3d00000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 030200000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - revoke_and_ack and mac
+               //
+               // 07 - process the now-pending HTLC forward
+               // - client now sends id 1 update_add_htlc and commitment_signed (CHECK 7: SendHTLCs event for node 03020000 with 1 HTLCs for channel 3f000000)
+               //
+               // - we respond with commitment_signed then revoke_and_ack (a weird, but valid, order)
+               // 030112 - inbound read from peer id 1 of len 18
+               // 0064 01000000000000000000000000000000 - message header indicating message length 100
+               // 030174 - inbound read from peer id 1 of len 116
+               // 0084 3900000000000000000000000000000000000000000000000000000000000000 f1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100 0000 01000000000000000000000000000000 - commitment_signed and mac
+               //
+               // 030112 - inbound read from peer id 1 of len 18
+               // 0063 01000000000000000000000000000000 - message header indicating message length 99
+               // 030173 - inbound read from peer id 1 of len 115
+               // 0085 3900000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 030200000000000000000000000000000000000000000000000000000000000000 01000000000000000000000000000000 - revoke_and_ack and mac
+               //
+               // 030112 - inbound read from peer id 1 of len 18
+               // 004a 01000000000000000000000000000000 - message header indicating message length 74
+               // 03015a - inbound read from peer id 1 of len 90
+               // 0082 3900000000000000000000000000000000000000000000000000000000000000 0000000000000000 ff00888888888888888888888888888888888888888888888888888888888888 01000000000000000000000000000000 - update_fulfill_htlc and mac
+               // - client should immediately claim the pending HTLC from peer 0 (CHECK 8: SendFulfillHTLCs for node 03000000 with preimage ff00888888 for channel 3d000000)
+               //
+               // 030112 - inbound read from peer id 1 of len 18
+               // 0064 01000000000000000000000000000000 - message header indicating message length 100
+               // 030174 - inbound read from peer id 1 of len 116
+               // 0084 3900000000000000000000000000000000000000000000000000000000000000 fd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100 0000 01000000000000000000000000000000 - commitment_signed and mac
+               //
+               // 030112 - inbound read from peer id 1 of len 18
+               // 0063 01000000000000000000000000000000 - message header indicating message length 99
+               // 030173 - inbound read from peer id 1 of len 115
+               // 0085 3900000000000000000000000000000000000000000000000000000000000000 0100000000000000000000000000000000000000000000000000000000000000 030300000000000000000000000000000000000000000000000000000000000000 01000000000000000000000000000000 - revoke_and_ack and mac
+               //
+               // - before responding to the commitment_signed generated above, send a new HTLC
+               // 030012 - inbound read from peer id 0 of len 18
+               // 05ac 03000000000000000000000000000000 - message header indicating message length 1452
+               // 0300ff - inbound read from peer id 0 of len 255
+               // 0080 3d00000000000000000000000000000000000000000000000000000000000000 0000000000000001 0000000000003e80 ff00000000000000000000000000000000000000000000000000000000000000 00000121 00 030000000000000000000000000000000000000000000000000000000000000555 0000000e000001000000000000000003e8000000010000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - beginning of update_add_htlc from 0 to 1 via client
+               // 0300ff - inbound read from peer id 0 of len 255
+               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+               // 0300ff - inbound read from peer id 0 of len 255
+               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+               // 0300ff - inbound read from peer id 0 of len 255
+               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+               // 0300ff - inbound read from peer id 0 of len 255
+               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+               // 0300c1 - inbound read from peer id 0 of len 193
+               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ef00000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - end of update_add_htlc from 0 to 1 via client and mac
+               //
+               // 00fd - A feerate request (returning min feerate, which our open_channel also uses) (gonna be ingested by FuzzEstimator)
+               //
+               // - now respond to the update_fulfill_htlc+commitment_signed messages the client sent to peer 0
+               // 030012 - inbound read from peer id 0 of len 18
+               // 0063 03000000000000000000000000000000 - message header indicating message length 99
+               // 030073 - inbound read from peer id 0 of len 115
+               // 0085 3d00000000000000000000000000000000000000000000000000000000000000 0100000000000000000000000000000000000000000000000000000000000000 030300000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - revoke_and_ack and mac
+               // - client should now respond with revoke_and_ack and commitment_signed (CHECK 5/6 duplicates)
+               //
+               // 030012 - inbound read from peer id 0 of len 18
+               // 0064 03000000000000000000000000000000 - message header indicating message length 100
+               // 030074 - inbound read from peer id 0 of len 116
+               // 0084 3d00000000000000000000000000000000000000000000000000000000000000 be000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 0000 03000000000000000000000000000000 - commitment_signed and mac
+               //
+               // 030012 - inbound read from peer id 0 of len 18
+               // 0063 03000000000000000000000000000000 - message header indicating message length 99
+               // 030073 - inbound read from peer id 0 of len 115
+               // 0085 3d00000000000000000000000000000000000000000000000000000000000000 0200000000000000000000000000000000000000000000000000000000000000 030400000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - revoke_and_ack and mac
+               //
+               // 07 - process the now-pending HTLC forward
+               // - client now sends id 1 update_add_htlc and commitment_signed (CHECK 7 duplicate)
+               // - we respond with revoke_and_ack, then commitment_signed, then update_fail_htlc
+               //
+               // 030112 - inbound read from peer id 1 of len 18
+               // 0064 01000000000000000000000000000000 - message header indicating message length 100
+               // 030174 - inbound read from peer id 1 of len 116
+               // 0084 3900000000000000000000000000000000000000000000000000000000000000 fc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100 0000 01000000000000000000000000000000 - commitment_signed and mac
+               //
+               // 030112 - inbound read from peer id 1 of len 18
+               // 0063 01000000000000000000000000000000 - message header indicating message length 99
+               // 030173 - inbound read from peer id 1 of len 115
+               // 0085 3900000000000000000000000000000000000000000000000000000000000000 0200000000000000000000000000000000000000000000000000000000000000 030400000000000000000000000000000000000000000000000000000000000000 01000000000000000000000000000000 - revoke_and_ack and mac
+               //
+               // 030112 - inbound read from peer id 1 of len 18
+               // 002c 01000000000000000000000000000000 - message header indicating message length 44
+               // 03013c - inbound read from peer id 1 of len 60
+               // 0083 3900000000000000000000000000000000000000000000000000000000000000 0000000000000001 0000 01000000000000000000000000000000 - update_fail_htlc and mac
+               //
+               // 030112 - inbound read from peer id 1 of len 18
+               // 0064 01000000000000000000000000000000 - message header indicating message length 100
+               // 030174 - inbound read from peer id 1 of len 116
+               // 0084 3900000000000000000000000000000000000000000000000000000000000000 fb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100 0000 01000000000000000000000000000000 - commitment_signed and mac
+               //
+               // 030112 - inbound read from peer id 1 of len 18
+               // 0063 01000000000000000000000000000000 - message header indicating message length 99
+               // 030173 - inbound read from peer id 1 of len 115
+               // 0085 3900000000000000000000000000000000000000000000000000000000000000 0300000000000000000000000000000000000000000000000000000000000000 030500000000000000000000000000000000000000000000000000000000000000 01000000000000000000000000000000 - revoke_and_ack and mac
+               //
+               // 07 - process the now-pending HTLC forward
+               // - client now sends id 0 update_fail_htlc and commitment_signed (CHECK 9)
+               // - now respond to the update_fail_htlc+commitment_signed messages the client sent to peer 0
+               //
+               // 030012 - inbound read from peer id 0 of len 18
+               // 0063 03000000000000000000000000000000 - message header indicating message length 99
+               // 030073 - inbound read from peer id 0 of len 115
+               // 0085 3d00000000000000000000000000000000000000000000000000000000000000 0300000000000000000000000000000000000000000000000000000000000000 030500000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - revoke_and_ack and mac
+               //
+               // 030012 - inbound read from peer id 0 of len 18
+               // 0064 03000000000000000000000000000000 - message header indicating message length 100
+               // 030074 - inbound read from peer id 0 of len 116
+               // 0084 3d00000000000000000000000000000000000000000000000000000000000000 4f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 0000 03000000000000000000000000000000 - commitment_signed and mac
+               // - client should now respond with revoke_and_ack (CHECK 5 duplicate)
+               //
+               // 030012 - inbound read from peer id 0 of len 18
+               // 05ac 03000000000000000000000000000000 - message header indicating message length 1452
+               // 0300ff - inbound read from peer id 0 of len 255
+               // 0080 3d00000000000000000000000000000000000000000000000000000000000000 0000000000000002 00000000000b0838 ff00000000000000000000000000000000000000000000000000000000000000 00000121 00 030000000000000000000000000000000000000000000000000000000000000555 0000000e0000010000000000000003e800000000010000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - beginning of update_add_htlc from 0 to 1 via client
+               // 0300ff - inbound read from peer id 0 of len 255
+               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+               // 0300ff - inbound read from peer id 0 of len 255
+               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+               // 0300ff - inbound read from peer id 0 of len 255
+               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+               // 0300ff - inbound read from peer id 0 of len 255
+               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+               // 0300c1 - inbound read from peer id 0 of len 193
+               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ef00000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - end of update_add_htlc from 0 to 1 via client and mac
+               //
+               // 00fd - A feerate request (returning min feerate, which our open_channel also uses) (gonna be ingested by FuzzEstimator)
+               //
+               // 030012 - inbound read from peer id 0 of len 18
+               // 00a4 03000000000000000000000000000000 - message header indicating message length 164
+               // 0300b4 - inbound read from peer id 0 of len 180
+               // 0084 3d00000000000000000000000000000000000000000000000000000000000000 07000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 0001 c8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f00000000000000 03000000000000000000000000000000 - commitment_signed and mac
+               // - client should now respond with revoke_and_ack and commitment_signed (CHECK 5/6 duplicates)
+               //
+               // 030012 - inbound read from peer id 0 of len 18
+               // 0063 03000000000000000000000000000000 - message header indicating message length 99
+               // 030073 - inbound read from peer id 0 of len 115
+               // 0085 3d00000000000000000000000000000000000000000000000000000000000000 0400000000000000000000000000000000000000000000000000000000000000 030600000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - revoke_and_ack and mac
+               //
+               // 07 - process the now-pending HTLC forward
+               // - client now sends id 1 update_add_htlc and commitment_signed (CHECK 7 duplicate)
+               //
+               // 0c007d - connect a block with one transaction of len 125
+               // 0200000001390000000000000000000000000000000000000000000000000000000000000000000000000000008002000100000000000022002090000000000000000000000000000000000000000000000000000000000000006cc10000000000001600145c0000000000000000000000000000000000000005000020 - the commitment transaction for channel 3f00000000000000000000000000000000000000000000000000000000000000
+               // 00fd - A feerate request (returning min feerate, which our open_channel also uses) (gonna be ingested by FuzzEstimator)
+               // 00fd - A feerate request (returning min feerate, which our open_channel also uses) (gonna be ingested by FuzzEstimator)
+               // 0c005e - connect a block with one transaction of len 94
+               // 0200000001fd00000000000000000000000000000000000000000000000000000000000000000000000000000000014f00000000000000220020f60000000000000000000000000000000000000000000000000000000000000000000000 - the funding transaction
+               // 0c0000 - connect a block with no transactions
+               // 0c0000 - connect a block with no transactions
+               // 0c0000 - connect a block with no transactions
+               // 0c0000 - connect a block with no transactions
+               // 0c0000 - connect a block with no transactions
+               //
+               // 07 - process the now-pending HTLC forward
+               // - client now fails the HTLC backwards as it was unable to extract the payment preimage (CHECK 9 duplicate and CHECK 10)
+
+               let logger = Arc::new(TrackingLogger { lines: Mutex::new(HashMap::new()) });
+               super::do_test(&::hex::decode("00000000000000000000000000000000000000000000000000000000000000000000000001000300000000000000000000000000000000000000000000000000000000000000000300320003000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000030012000603000000000000000000000000000000030016001000000000030000000000000000000000000000000300120141030000000000000000000000000000000300fe00207500000000000000000000000000000000000000000000000000000000000000ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679000000000000c35000000000000000000000000000000222ffffffffffffffff00000000000002220000000000000000000000fd000601e3030000000000000000000000000000000000000000000000000000000000000001030000000000000000000000000000000000000000000000000000000000000002030000000000000000000000000000000000000000000000000000000000000003030000000000000000000000000000000000000000000000000000000000000004030053030000000000000000000000000000000000000000000000000000000000000005030000000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000fd00fd00fd0300120084030000000000000000000000000000000300940022ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb1819096793d0000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001030000000000000000000000000000000c005e020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0150c3000000000000220020ae00000000000000000000000000000000000000000000000000000000000000000000000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c000003001200430300000000000000000000000000000003005300243d000000000000000000000000000000000000000000000000000000000000000301000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001030132000300000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003014200030200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000300000000000000000000000000000003011200060100000000000000000000000000000003011600100000000001000000000000000000000000000000050103020000000000000000000000000000000000000000000000000000000000000000c3500003e800fd00fd00fd0301120110010000000000000000000000000000000301ff00210000000000000000000000000000000000000000000000000000000000000e02000000000000001a00000000004c4b4000000000000003e800000000000003e80000000203f00005030000000000000000000000000000000000000000000000000000000000000100030000000000000000000000000000000000000000000000000000000000000200030000000000000000000000000000000000000000000000000000000000000300030000000000000000000000000000000000000000000000000000000000000400030000000000000000000000000000000000000000000000000000000000000500030000000000000000000000000000000301210000000000000000000000000000000000010000000000000000000000000000000a03011200620100000000000000000000000000000003017200233900000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100010000000000000000000000000000000b030112004301000000000000000000000000000000030153002439000000000000000000000000000000000000000000000000000000000000000301000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e80ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000003e8000000010000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000004d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000f100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112004a0100000000000000000000000000000003015a008239000000000000000000000000000000000000000000000000000000000000000000000000000000ff008888888888888888888888888888888888888888888888888888888888880100000000000000000000000000000003011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000fd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000010000000000000000000000000000000301120063010000000000000000000000000000000301730085390000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000303000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000010000000000003e80ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000003e8000000010000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200630300000000000000000000000000000003007300853d0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000303000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d00000000000000000000000000000000000000000000000000000000000000be00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030400000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000fc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003040000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112002c0100000000000000000000000000000003013c00833900000000000000000000000000000000000000000000000000000000000000000000000000000100000100000000000000000000000000000003011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000fb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000001000000000000000000000000000000030112006301000000000000000000000000000000030173008539000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000030500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000703001200630300000000000000000000000000000003007300853d0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000305000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000004f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d00000000000000000000000000000000000000000000000000000000000000000000000000000200000000000b0838ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e0000010000000000000003e800000000010000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200a4030000000000000000000000000000000300b400843d00000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001c8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f000000000000000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000003060000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000070c007d0200000001390000000000000000000000000000000000000000000000000000000000000000000000000000008002000100000000000022002090000000000000000000000000000000000000000000000000000000000000006cc10000000000001600145c000000000000000000000000000000000000000500002000fd00fd0c005e0200000001fd00000000000000000000000000000000000000000000000000000000000000000000000000000000014f00000000000000220020f600000000000000000000000000000000000000000000000000000000000000000000000c00000c00000c00000c00000c000007").unwrap(), &(Arc::clone(&logger) as Arc<Logger>));
+
+               let log_entries = logger.lines.lock().unwrap();
+               assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendAcceptChannel event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679".to_string())), Some(&1)); // 1
+               assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendFundingSigned event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 2
+               assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendFundingLocked event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 3
+               assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendFundingLocked event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 for channel 3900000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 4
+               assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendRevokeAndACK event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&4)); // 5
+               assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 with 0 adds, 0 fulfills, 0 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&3)); // 6
+               assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 with 1 adds, 0 fulfills, 0 fails for channel 3900000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&3)); // 7
+               assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 with 0 adds, 1 fulfills, 0 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 8
+               assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 with 0 adds, 0 fulfills, 1 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&2)); // 9
+               assert_eq!(log_entries.get(&("lightning::ln::channelmonitor".to_string(), "Input spending remote commitment tx (00000000000000000000000000000000000000000000000000000000000000fd:0) in 0000000000000000000000000000000000000000000000000000000000000044 resolves outbound HTLC with payment hash ff00000000000000000000000000000000000000000000000000000000000000 with timeout".to_string())), Some(&1)); // 10
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/gen_target.sh b/fuzz/fuzz_targets/msg_targets/gen_target.sh
new file mode 100755 (executable)
index 0000000..cfd100f
--- /dev/null
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+GEN_TEST() {
+       tn=$(echo $1 | sed 's/\([a-z0-9]\)\([A-Z]\)/\1_\2/g')
+       fn=msg_$(echo $tn | tr '[:upper:]' '[:lower:]')_target.rs
+       cat msg_target_template.txt | sed s/MSG_TARGET/$1/ | sed "s/TEST_MSG/$2/" | sed "s/EXTRA_ARGS/$3/" > $fn
+}
+
+GEN_TEST AcceptChannel test_msg ""
+GEN_TEST AnnouncementSignatures test_msg ""
+GEN_TEST ChannelReestablish test_msg ""
+GEN_TEST ClosingSigned test_msg ""
+GEN_TEST CommitmentSigned test_msg ""
+GEN_TEST DecodedOnionErrorPacket test_msg ""
+GEN_TEST FundingCreated test_msg ""
+GEN_TEST FundingLocked test_msg ""
+GEN_TEST FundingSigned test_msg ""
+GEN_TEST Init test_msg ""
+GEN_TEST OpenChannel test_msg ""
+GEN_TEST RevokeAndACK test_msg ""
+GEN_TEST Shutdown test_msg ""
+GEN_TEST UpdateFailHTLC test_msg ""
+GEN_TEST UpdateFailMalformedHTLC test_msg ""
+GEN_TEST UpdateFee test_msg ""
+GEN_TEST UpdateFulfillHTLC test_msg ""
+
+GEN_TEST ChannelAnnouncement test_msg_exact ""
+GEN_TEST ChannelUpdate test_msg_exact ""
+GEN_TEST NodeAnnouncement test_msg_exact ""
+
+GEN_TEST UpdateAddHTLC test_msg_hole ", 85, 33"
+GEN_TEST ErrorMessage test_msg_hole ", 32, 2"
+GEN_TEST OnionHopData test_msg_hole ", 1+8+8+4, 12"
+
+GEN_TEST Ping test_msg_simple ""
+GEN_TEST Pong test_msg_simple ""
diff --git a/fuzz/fuzz_targets/msg_targets/msg_accept_channel_target.rs b/fuzz/fuzz_targets/msg_targets/msg_accept_channel_target.rs
new file mode 100644 (file)
index 0000000..0f18d02
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg!(msgs::AcceptChannel, data);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_announcement_signatures_target.rs b/fuzz/fuzz_targets/msg_targets/msg_announcement_signatures_target.rs
new file mode 100644 (file)
index 0000000..226028e
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg!(msgs::AnnouncementSignatures, data);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_channel_announcement_target.rs b/fuzz/fuzz_targets/msg_targets/msg_channel_announcement_target.rs
new file mode 100644 (file)
index 0000000..0bdc10e
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg_exact!(msgs::ChannelAnnouncement, data);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_channel_reestablish_target.rs b/fuzz/fuzz_targets/msg_targets/msg_channel_reestablish_target.rs
new file mode 100644 (file)
index 0000000..4af5937
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg!(msgs::ChannelReestablish, data);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_channel_update_target.rs b/fuzz/fuzz_targets/msg_targets/msg_channel_update_target.rs
new file mode 100644 (file)
index 0000000..724dca4
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg_exact!(msgs::ChannelUpdate, data);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_closing_signed_target.rs b/fuzz/fuzz_targets/msg_targets/msg_closing_signed_target.rs
new file mode 100644 (file)
index 0000000..faeeae3
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg!(msgs::ClosingSigned, data);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_commitment_signed_target.rs b/fuzz/fuzz_targets/msg_targets/msg_commitment_signed_target.rs
new file mode 100644 (file)
index 0000000..97c4b30
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg!(msgs::CommitmentSigned, data);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_decoded_onion_error_packet_target.rs b/fuzz/fuzz_targets/msg_targets/msg_decoded_onion_error_packet_target.rs
new file mode 100644 (file)
index 0000000..9b190b0
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg!(msgs::DecodedOnionErrorPacket, data);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_error_message_target.rs b/fuzz/fuzz_targets/msg_targets/msg_error_message_target.rs
new file mode 100644 (file)
index 0000000..d749dc9
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg_hole!(msgs::ErrorMessage, data, 32, 2);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_funding_created_target.rs b/fuzz/fuzz_targets/msg_targets/msg_funding_created_target.rs
new file mode 100644 (file)
index 0000000..45b257b
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg!(msgs::FundingCreated, data);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_funding_locked_target.rs b/fuzz/fuzz_targets/msg_targets/msg_funding_locked_target.rs
new file mode 100644 (file)
index 0000000..cd1e897
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg!(msgs::FundingLocked, data);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_funding_signed_target.rs b/fuzz/fuzz_targets/msg_targets/msg_funding_signed_target.rs
new file mode 100644 (file)
index 0000000..5992d69
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg!(msgs::FundingSigned, data);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_init_target.rs b/fuzz/fuzz_targets/msg_targets/msg_init_target.rs
new file mode 100644 (file)
index 0000000..cdca848
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg!(msgs::Init, data);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_node_announcement_target.rs b/fuzz/fuzz_targets/msg_targets/msg_node_announcement_target.rs
new file mode 100644 (file)
index 0000000..f0a7a4c
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg_exact!(msgs::NodeAnnouncement, data);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_onion_hop_data_target.rs b/fuzz/fuzz_targets/msg_targets/msg_onion_hop_data_target.rs
new file mode 100644 (file)
index 0000000..058c050
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg_hole!(msgs::OnionHopData, data, 1+8+8+4, 12);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_open_channel_target.rs b/fuzz/fuzz_targets/msg_targets/msg_open_channel_target.rs
new file mode 100644 (file)
index 0000000..aa13e96
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg!(msgs::OpenChannel, data);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_ping_target.rs b/fuzz/fuzz_targets/msg_targets/msg_ping_target.rs
new file mode 100644 (file)
index 0000000..d2ea913
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg_simple!(msgs::Ping, data);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_pong_target.rs b/fuzz/fuzz_targets/msg_targets/msg_pong_target.rs
new file mode 100644 (file)
index 0000000..18120e2
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg_simple!(msgs::Pong, data);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_revoke_and_ack_target.rs b/fuzz/fuzz_targets/msg_targets/msg_revoke_and_ack_target.rs
new file mode 100644 (file)
index 0000000..d82268d
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg!(msgs::RevokeAndACK, data);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_shutdown_target.rs b/fuzz/fuzz_targets/msg_targets/msg_shutdown_target.rs
new file mode 100644 (file)
index 0000000..34d4d20
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg!(msgs::Shutdown, data);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_target_template.txt b/fuzz/fuzz_targets/msg_targets/msg_target_template.txt
new file mode 100644 (file)
index 0000000..2704bcd
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       TEST_MSG!(msgs::MSG_TARGET, dataEXTRA_ARGS);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_update_add_htlc_target.rs b/fuzz/fuzz_targets/msg_targets/msg_update_add_htlc_target.rs
new file mode 100644 (file)
index 0000000..e64a5c2
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg_hole!(msgs::UpdateAddHTLC, data, 85, 33);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_update_fail_htlc_target.rs b/fuzz/fuzz_targets/msg_targets/msg_update_fail_htlc_target.rs
new file mode 100644 (file)
index 0000000..fedce56
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg!(msgs::UpdateFailHTLC, data);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_update_fail_malformed_htlc_target.rs b/fuzz/fuzz_targets/msg_targets/msg_update_fail_malformed_htlc_target.rs
new file mode 100644 (file)
index 0000000..377378f
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg!(msgs::UpdateFailMalformedHTLC, data);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_update_fee_target.rs b/fuzz/fuzz_targets/msg_targets/msg_update_fee_target.rs
new file mode 100644 (file)
index 0000000..56b9ac4
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg!(msgs::UpdateFee, data);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/msg_update_fulfill_htlc_target.rs b/fuzz/fuzz_targets/msg_targets/msg_update_fulfill_htlc_target.rs
new file mode 100644 (file)
index 0000000..f0c936d
--- /dev/null
@@ -0,0 +1,43 @@
+// This file is auto-generated by gen_target.sh based on msg_target_template.txt
+// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
+
+extern crate lightning;
+
+use lightning::ln::msgs;
+
+mod utils;
+use utils::VecWriter;
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       test_msg!(msgs::UpdateFulfillHTLC, data);
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/msg_targets/utils.rs b/fuzz/fuzz_targets/msg_targets/utils.rs
new file mode 100644 (file)
index 0000000..a5257ba
--- /dev/null
@@ -0,0 +1,81 @@
+#![macro_use]
+
+use lightning::util::ser::Writer;
+pub struct VecWriter(pub Vec<u8>);
+impl Writer for VecWriter {
+       fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
+               assert!(self.0.capacity() >= self.0.len() + buf.len());
+               self.0.extend_from_slice(buf);
+               Ok(())
+       }
+       fn size_hint(&mut self, size: usize) {
+               self.0.reserve_exact(size);
+       }
+}
+
+#[macro_export]
+macro_rules! test_msg {
+       ($MsgType: path, $data: ident) => {
+               {
+                       use lightning::util::ser::{Writeable, Readable};
+                       let mut r = ::std::io::Cursor::new($data);
+                       if let Ok(msg) = <$MsgType as Readable<::std::io::Cursor<&[u8]>>>::read(&mut r) {
+                               let p = r.position() as usize;
+                               let mut w = VecWriter(Vec::new());
+                               msg.write(&mut w).unwrap();
+
+                               assert_eq!(w.0.len(), p);
+                               assert_eq!(&r.into_inner()[..p], &w.0[..p]);
+                       }
+               }
+       }
+}
+
+#[macro_export]
+macro_rules! test_msg_simple {
+       ($MsgType: path, $data: ident) => {
+               {
+                       use lightning::util::ser::{Writeable, Readable};
+                       let mut r = ::std::io::Cursor::new($data);
+                       if let Ok(msg) = <$MsgType as Readable<::std::io::Cursor<&[u8]>>>::read(&mut r) {
+                               let mut w = VecWriter(Vec::new());
+                               msg.write(&mut w).unwrap();
+                       }
+               }
+       }
+}
+
+#[macro_export]
+macro_rules! test_msg_exact {
+       ($MsgType: path, $data: ident) => {
+               {
+                       use lightning::util::ser::{Writeable, Readable};
+                       let mut r = ::std::io::Cursor::new($data);
+                       if let Ok(msg) = <$MsgType as Readable<::std::io::Cursor<&[u8]>>>::read(&mut r) {
+                               let mut w = VecWriter(Vec::new());
+                               msg.write(&mut w).unwrap();
+
+                               assert_eq!(&r.into_inner()[..], &w.0[..]);
+                       }
+               }
+       }
+}
+
+#[macro_export]
+macro_rules! test_msg_hole {
+       ($MsgType: path, $data: ident, $hole: expr, $hole_len: expr) => {
+               {
+                       use lightning::util::ser::{Writeable, Readable};
+                       let mut r = ::std::io::Cursor::new($data);
+                       if let Ok(msg) = <$MsgType as Readable<::std::io::Cursor<&[u8]>>>::read(&mut r) {
+                               let mut w = VecWriter(Vec::new());
+                               msg.write(&mut w).unwrap();
+                               let p = w.0.len() as usize;
+
+                               assert_eq!(w.0.len(), p);
+                               assert_eq!(&r.get_ref()[..$hole], &w.0[..$hole]);
+                               assert_eq!(&r.get_ref()[$hole+$hole_len..p], &w.0[$hole+$hole_len..]);
+                       }
+               }
+       }
+}
diff --git a/fuzz/fuzz_targets/peer_crypt_target.rs b/fuzz/fuzz_targets/peer_crypt_target.rs
new file mode 100644 (file)
index 0000000..0b82303
--- /dev/null
@@ -0,0 +1,109 @@
+extern crate lightning;
+extern crate secp256k1;
+
+use lightning::ln::peer_channel_encryptor::PeerChannelEncryptor;
+
+use secp256k1::key::{PublicKey,SecretKey};
+
+#[inline]
+fn slice_to_be16(v: &[u8]) -> u16 {
+       ((v[0] as u16) << 8*1) |
+       ((v[1] as u16) << 8*0)
+}
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       let mut read_pos = 0;
+       macro_rules! get_slice {
+               ($len: expr) => {
+                       {
+                               let slice_len = $len as usize;
+                               if data.len() < read_pos + slice_len {
+                                       return;
+                               }
+                               read_pos += slice_len;
+                               &data[read_pos - slice_len..read_pos]
+                       }
+               }
+       }
+
+       let our_network_key = match SecretKey::from_slice(get_slice!(32)) {
+               Ok(key) => key,
+               Err(_) => return,
+       };
+       let ephemeral_key = match SecretKey::from_slice(get_slice!(32)) {
+               Ok(key) => key,
+               Err(_) => return,
+       };
+
+       let mut crypter = if get_slice!(1)[0] != 0 {
+               let their_pubkey = match PublicKey::from_slice(get_slice!(33)) {
+                       Ok(key) => key,
+                       Err(_) => return,
+               };
+               let mut crypter = PeerChannelEncryptor::new_outbound(their_pubkey, ephemeral_key);
+               crypter.get_act_one();
+               match crypter.process_act_two(get_slice!(50), &our_network_key) {
+                       Ok(_) => {},
+                       Err(_) => return,
+               }
+               assert!(crypter.is_ready_for_encryption());
+               crypter
+       } else {
+               let mut crypter = PeerChannelEncryptor::new_inbound(&our_network_key);
+               match crypter.process_act_one_with_keys(get_slice!(50), &our_network_key, ephemeral_key) {
+                       Ok(_) => {},
+                       Err(_) => return,
+               }
+               match crypter.process_act_three(get_slice!(66)) {
+                       Ok(_) => {},
+                       Err(_) => return,
+               }
+               assert!(crypter.is_ready_for_encryption());
+               crypter
+       };
+       loop {
+               if get_slice!(1)[0] == 0 {
+                       crypter.encrypt_message(get_slice!(slice_to_be16(get_slice!(2))));
+               } else {
+                       let len = match crypter.decrypt_length_header(get_slice!(16+2)) {
+                               Ok(len) => len,
+                               Err(_) => return,
+                       };
+                       match crypter.decrypt_message(get_slice!(len as usize + 16)) {
+                               Ok(_) => {},
+                               Err(_) => return,
+                       }
+               }
+       }
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("01").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/router_target.rs b/fuzz/fuzz_targets/router_target.rs
new file mode 100644 (file)
index 0000000..d9a8f78
--- /dev/null
@@ -0,0 +1,269 @@
+extern crate bitcoin;
+extern crate bitcoin_hashes;
+extern crate lightning;
+extern crate secp256k1;
+
+use bitcoin_hashes::sha256d::Hash as Sha256dHash;
+use bitcoin::blockdata::script::{Script, Builder};
+use bitcoin::blockdata::block::Block;
+use bitcoin::blockdata::transaction::Transaction;
+
+use lightning::chain::chaininterface::{ChainError,ChainWatchInterface};
+use lightning::ln::channelmanager::ChannelDetails;
+use lightning::ln::msgs;
+use lightning::ln::msgs::{RoutingMessageHandler};
+use lightning::ln::router::{Router, RouteHint};
+use lightning::util::logger::Logger;
+use lightning::util::ser::Readable;
+
+use secp256k1::key::PublicKey;
+
+mod utils;
+
+use utils::test_logger;
+
+use std::sync::Arc;
+use std::sync::atomic::{AtomicUsize, Ordering};
+
+#[inline]
+pub fn slice_to_be16(v: &[u8]) -> u16 {
+       ((v[0] as u16) << 8*1) |
+       ((v[1] as u16) << 8*0)
+}
+
+#[inline]
+pub fn slice_to_be32(v: &[u8]) -> u32 {
+       ((v[0] as u32) << 8*3) |
+       ((v[1] as u32) << 8*2) |
+       ((v[2] as u32) << 8*1) |
+       ((v[3] as u32) << 8*0)
+}
+
+#[inline]
+pub fn slice_to_be64(v: &[u8]) -> u64 {
+       ((v[0] as u64) << 8*7) |
+       ((v[1] as u64) << 8*6) |
+       ((v[2] as u64) << 8*5) |
+       ((v[3] as u64) << 8*4) |
+       ((v[4] as u64) << 8*3) |
+       ((v[5] as u64) << 8*2) |
+       ((v[6] as u64) << 8*1) |
+       ((v[7] as u64) << 8*0)
+}
+
+
+struct InputData {
+       data: Vec<u8>,
+       read_pos: AtomicUsize,
+}
+impl InputData {
+       fn get_slice(&self, len: usize) -> Option<&[u8]> {
+               let old_pos = self.read_pos.fetch_add(len, Ordering::AcqRel);
+               if self.data.len() < old_pos + len {
+                       return None;
+               }
+               Some(&self.data[old_pos..old_pos + len])
+       }
+       fn get_slice_nonadvancing(&self, len: usize) -> Option<&[u8]> {
+               let old_pos = self.read_pos.load(Ordering::Acquire);
+               if self.data.len() < old_pos + len {
+                       return None;
+               }
+               Some(&self.data[old_pos..old_pos + len])
+       }
+}
+
+struct DummyChainWatcher {
+       input: Arc<InputData>,
+}
+
+impl ChainWatchInterface for DummyChainWatcher {
+       fn install_watch_tx(&self, _txid: &Sha256dHash, _script_pub_key: &Script) { }
+       fn install_watch_outpoint(&self, _outpoint: (Sha256dHash, u32), _out_script: &Script) { }
+       fn watch_all_txn(&self) { }
+       fn filter_block<'a>(&self, _block: &'a Block) -> (Vec<&'a Transaction>, Vec<u32>) {
+               (Vec::new(), Vec::new())
+       }
+       fn reentered(&self) -> usize { 0 }
+
+       fn get_chain_utxo(&self, _genesis_hash: Sha256dHash, _unspent_tx_output_identifier: u64) -> Result<(Script, u64), ChainError> {
+               match self.input.get_slice(2) {
+                       Some(&[0, _]) => Err(ChainError::NotSupported),
+                       Some(&[1, _]) => Err(ChainError::NotWatched),
+                       Some(&[2, _]) => Err(ChainError::UnknownTx),
+                       Some(&[_, x]) => Ok((Builder::new().push_int(x as i64).into_script().to_v0_p2wsh(), 0)),
+                       None => Err(ChainError::UnknownTx),
+                       _ => unreachable!(),
+               }
+       }
+}
+
+#[inline]
+pub fn do_test(data: &[u8]) {
+       let input = Arc::new(InputData {
+               data: data.to_vec(),
+               read_pos: AtomicUsize::new(0),
+       });
+       macro_rules! get_slice_nonadvancing {
+               ($len: expr) => {
+                       match input.get_slice_nonadvancing($len as usize) {
+                               Some(slice) => slice,
+                               None => return,
+                       }
+               }
+       }
+       macro_rules! get_slice {
+               ($len: expr) => {
+                       match input.get_slice($len as usize) {
+                               Some(slice) => slice,
+                               None => return,
+                       }
+               }
+       }
+
+       macro_rules! decode_msg {
+               ($MsgType: path, $len: expr) => {{
+                       let mut reader = ::std::io::Cursor::new(get_slice!($len));
+                       match <($MsgType)>::read(&mut reader) {
+                               Ok(msg) => msg,
+                               Err(e) => match e {
+                                       msgs::DecodeError::UnknownVersion => return,
+                                       msgs::DecodeError::UnknownRequiredFeature => return,
+                                       msgs::DecodeError::InvalidValue => return,
+                                       msgs::DecodeError::ExtraAddressesPerType => return,
+                                       msgs::DecodeError::BadLengthDescriptor => return,
+                                       msgs::DecodeError::ShortRead => panic!("We picked the length..."),
+                                       msgs::DecodeError::Io(e) => panic!(format!("{}", e)),
+                               }
+                       }
+               }}
+       }
+
+       macro_rules! decode_msg_with_len16 {
+               ($MsgType: path, $begin_len: expr, $excess: expr) => {
+                       {
+                               let extra_len = slice_to_be16(&get_slice_nonadvancing!($begin_len as usize + 2)[$begin_len..$begin_len + 2]);
+                               decode_msg!($MsgType, $begin_len as usize + 2 + (extra_len as usize) + $excess)
+                       }
+               }
+       }
+
+       macro_rules! get_pubkey {
+               () => {
+                       match PublicKey::from_slice(get_slice!(33)) {
+                               Ok(key) => key,
+                               Err(_) => return,
+                       }
+               }
+       }
+
+       let logger: Arc<Logger> = Arc::new(test_logger::TestLogger::new("".to_owned()));
+       let chain_monitor = Arc::new(DummyChainWatcher {
+               input: Arc::clone(&input),
+       });
+
+       let our_pubkey = get_pubkey!();
+       let router = Router::new(our_pubkey.clone(), chain_monitor, Arc::clone(&logger));
+
+       loop {
+               match get_slice!(1)[0] {
+                       0 => {
+                               let start_len = slice_to_be16(&get_slice_nonadvancing!(64 + 2)[64..64 + 2]) as usize;
+                               let addr_len = slice_to_be16(&get_slice_nonadvancing!(64+start_len+2 + 74)[64+start_len+2 + 72..64+start_len+2 + 74]);
+                               if addr_len > (37+1)*4 {
+                                       return;
+                               }
+                               let _ = router.handle_node_announcement(&decode_msg_with_len16!(msgs::NodeAnnouncement, 64, 288));
+                       },
+                       1 => {
+                               let _ = router.handle_channel_announcement(&decode_msg_with_len16!(msgs::ChannelAnnouncement, 64*4, 32+8+33*4));
+                       },
+                       2 => {
+                               let _ = router.handle_channel_update(&decode_msg!(msgs::ChannelUpdate, 128));
+                       },
+                       3 => {
+                               match get_slice!(1)[0] {
+                                       0 => {
+                                               router.handle_htlc_fail_channel_update(&msgs::HTLCFailChannelUpdate::ChannelUpdateMessage {msg: decode_msg!(msgs::ChannelUpdate, 128)});
+                                       },
+                                       1 => {
+                                               let short_channel_id = slice_to_be64(get_slice!(8));
+                                               router.handle_htlc_fail_channel_update(&msgs::HTLCFailChannelUpdate::ChannelClosed {short_channel_id, is_permanent: false});
+                                       },
+                                       _ => return,
+                               }
+                       },
+                       4 => {
+                               let target = get_pubkey!();
+                               let mut first_hops_vec = Vec::new();
+                               let first_hops = match get_slice!(1)[0] {
+                                       0 => None,
+                                       1 => {
+                                               let count = slice_to_be16(get_slice!(2));
+                                               for _ in 0..count {
+                                                       first_hops_vec.push(ChannelDetails {
+                                                               channel_id: [0; 32],
+                                                               short_channel_id: Some(slice_to_be64(get_slice!(8))),
+                                                               remote_network_id: get_pubkey!(),
+                                                               channel_value_satoshis: slice_to_be64(get_slice!(8)),
+                                                               user_id: 0,
+                                                               inbound_capacity_msat: 0,
+                                                               is_live: true,
+                                                               outbound_capacity_msat: 0,
+                                                       });
+                                               }
+                                               Some(&first_hops_vec[..])
+                                       },
+                                       _ => return,
+                               };
+                               let mut last_hops_vec = Vec::new();
+                               let last_hops = {
+                                       let count = slice_to_be16(get_slice!(2));
+                                       for _ in 0..count {
+                                               last_hops_vec.push(RouteHint {
+                                                       src_node_id: get_pubkey!(),
+                                                       short_channel_id: slice_to_be64(get_slice!(8)),
+                                                       fee_base_msat: slice_to_be32(get_slice!(4)),
+                                                       fee_proportional_millionths: slice_to_be32(get_slice!(4)),
+                                                       cltv_expiry_delta: slice_to_be16(get_slice!(2)),
+                                                       htlc_minimum_msat: slice_to_be64(get_slice!(8)),
+                                               });
+                                       }
+                                       &last_hops_vec[..]
+                               };
+                               let _ = router.get_route(&target, first_hops, last_hops, slice_to_be64(get_slice!(8)), slice_to_be32(get_slice!(4)));
+                       },
+                       _ => return,
+               }
+       }
+}
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+       fuzz!(|data| {
+               do_test(data);
+       });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+       loop {
+               fuzz!(|data| {
+                       do_test(data);
+               });
+       }
+}
+
+extern crate hex;
+#[cfg(test)]
+mod tests {
+
+       #[test]
+       fn duplicate_crash() {
+               super::do_test(&::hex::decode("00").unwrap());
+       }
+}
diff --git a/fuzz/fuzz_targets/utils/mod.rs b/fuzz/fuzz_targets/utils/mod.rs
new file mode 100644 (file)
index 0000000..a7d7c32
--- /dev/null
@@ -0,0 +1 @@
+pub(crate) mod test_logger;
diff --git a/fuzz/fuzz_targets/utils/test_logger.rs b/fuzz/fuzz_targets/utils/test_logger.rs
new file mode 100644 (file)
index 0000000..097d001
--- /dev/null
@@ -0,0 +1,23 @@
+use lightning::util::logger::{Logger, Record};
+pub struct TestLogger {
+       #[cfg(test)]
+       id: String,
+}
+
+impl TestLogger {
+       pub fn new(_id: String) -> TestLogger {
+               TestLogger {
+                       #[cfg(test)]
+                       id: _id
+               }
+       }
+}
+
+impl Logger for TestLogger {
+       fn log(&self, record: &Record) {
+               #[cfg(test)]
+               println!("{:<5} {} [{} : {}, {}] {}", record.level.to_string(), self.id, record.module_path, record.file, record.line, record.args);
+               #[cfg(not(test))]
+               let _ = format!("{}", record.args);
+       }
+}
diff --git a/fuzz/travis-fuzz.sh b/fuzz/travis-fuzz.sh
new file mode 100755 (executable)
index 0000000..e602e95
--- /dev/null
@@ -0,0 +1,29 @@
+#!/bin/bash
+set -e
+
+pushd fuzz_targets/msg_targets
+rm *_target.rs
+./gen_target.sh
+[ "$(git diff)" != "" ] && exit 1
+popd
+
+cargo install --force honggfuzz
+for TARGET in fuzz_targets/*.rs fuzz_targets/msg_targets/*_target.rs; do
+       FILENAME=$(basename $TARGET)
+       FILE="${FILENAME%.*}"
+       HFUZZ_RUN_ARGS="--exit_upon_crash -v -n2"
+       if [ "$FILE" = "chanmon_fail_consistency" ]; then
+               HFUZZ_RUN_ARGS="$HFUZZ_RUN_ARGS -F 64 -N100000"
+       else
+               HFUZZ_RUN_ARGS="$HFUZZ_RUN_ARGS -N1000000"
+       fi
+       export HFUZZ_RUN_ARGS
+       HFUZZ_BUILD_ARGS="--features honggfuzz_fuzz" cargo hfuzz run $FILE
+       if [ -f hfuzz_workspace/$FILE/HONGGFUZZ.REPORT.TXT ]; then
+               cat hfuzz_workspace/$FILE/HONGGFUZZ.REPORT.TXT
+               for CASE in hfuzz_workspace/$FILE/SIG*; do
+                       cat $CASE | xxd -p
+               done
+               exit 1
+       fi
+done
diff --git a/lightning/fuzz/.gitignore b/lightning/fuzz/.gitignore
deleted file mode 100644 (file)
index 8bf27ec..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-hfuzz_target
-target
-hfuzz_workspace
diff --git a/lightning/fuzz/Cargo.toml b/lightning/fuzz/Cargo.toml
deleted file mode 100644 (file)
index 19d832e..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-[package]
-name = "lightning-fuzz"
-version = "0.0.1"
-authors = ["Automatically generated"]
-publish = false
-# Because the function is unused it gets dropped before we link lightning, so
-# we have to duplicate build.rs here. Note that this is only required for
-# fuzztarget mode.
-
-[package.metadata]
-cargo-fuzz = true
-
-[features]
-afl_fuzz = ["afl"]
-honggfuzz_fuzz = ["honggfuzz"]
-libfuzzer_fuzz = ["libfuzzer-sys"]
-
-[dependencies]
-afl = { version = "0.4", optional = true }
-lightning = { path = "..", features = ["fuzztarget"] }
-bitcoin = { version = "0.20", features = ["fuzztarget"] }
-bitcoin_hashes = { version = "0.7", features = ["fuzztarget"] }
-hex = "0.3"
-honggfuzz = { version = "0.5", optional = true }
-secp256k1 = { version = "0.15", features=["fuzztarget"] }
-libfuzzer-sys = { git = "https://github.com/rust-fuzz/libfuzzer-sys.git", optional = true }
-
-[build-dependencies]
-cc = "1.0"
-
-# Prevent this from interfering with workspaces
-[workspace]
-members = ["."]
-
-[profile.release]
-lto = true
-codegen-units = 1
-
-[[bin]]
-name = "peer_crypt_target"
-path = "fuzz_targets/peer_crypt_target.rs"
-
-[[bin]]
-name = "full_stack_target"
-path = "fuzz_targets/full_stack_target.rs"
-
-[[bin]]
-name = "chanmon_fail_consistency"
-path = "fuzz_targets/chanmon_fail_consistency.rs"
-
-[[bin]]
-name = "router_target"
-path = "fuzz_targets/router_target.rs"
-
-[[bin]]
-name = "chanmon_deser_target"
-path = "fuzz_targets/chanmon_deser_target.rs"
-
-# message fuzz targets
-[[bin]]
-name = "msg_ping_target"
-path = "fuzz_targets/msg_targets/msg_ping_target.rs"
-
-[[bin]]
-name = "msg_pong_target"
-path = "fuzz_targets/msg_targets/msg_pong_target.rs"
-
-[[bin]]
-name = "msg_error_message_target"
-path = "fuzz_targets/msg_targets/msg_error_message_target.rs"
-
-[[bin]]
-name = "msg_update_add_htlc_target"
-path = "fuzz_targets/msg_targets/msg_update_add_htlc_target.rs"
-
-[[bin]]
-name = "msg_accept_channel_target"
-path = "fuzz_targets/msg_targets/msg_accept_channel_target.rs"
-
-[[bin]]
-name = "msg_closing_signed_target"
-path = "fuzz_targets/msg_targets/msg_closing_signed_target.rs"
-
-[[bin]]
-name = "msg_commitment_signed_target"
-path = "fuzz_targets/msg_targets/msg_commitment_signed_target.rs"
-
-[[bin]]
-name = "msg_funding_created_target"
-path = "fuzz_targets/msg_targets/msg_funding_created_target.rs"
-
-[[bin]]
-name = "msg_funding_locked_target"
-path = "fuzz_targets/msg_targets/msg_funding_locked_target.rs"
-
-[[bin]]
-name = "msg_funding_signed_target"
-path = "fuzz_targets/msg_targets/msg_funding_signed_target.rs"
-
-[[bin]]
-name = "msg_open_channel_target"
-path = "fuzz_targets/msg_targets/msg_open_channel_target.rs"
-
-[[bin]]
-name = "msg_revoke_and_ack_target"
-path = "fuzz_targets/msg_targets/msg_revoke_and_ack_target.rs"
-
-[[bin]]
-name = "msg_shutdown_target"
-path = "fuzz_targets/msg_targets/msg_shutdown_target.rs"
-
-[[bin]]
-name = "msg_update_fail_malformed_htlc_target"
-path = "fuzz_targets/msg_targets/msg_update_fail_malformed_htlc_target.rs"
-
-[[bin]]
-name = "msg_update_fee_target"
-path = "fuzz_targets/msg_targets/msg_update_fee_target.rs"
-
-[[bin]]
-name = "msg_update_fulfill_htlc_target"
-path = "fuzz_targets/msg_targets/msg_update_fulfill_htlc_target.rs"
-
-[[bin]]
-name = "msg_update_fail_htlc_target"
-path = "fuzz_targets/msg_targets/msg_update_fail_htlc_target.rs"
-
-[[bin]]
-name = "msg_channel_reestablish_target"
-path = "fuzz_targets/msg_targets/msg_channel_reestablish_target.rs"
-
-[[bin]]
-name = "msg_announcement_signatures_target"
-path = "fuzz_targets/msg_targets/msg_announcement_signatures_target.rs"
-
-[[bin]]
-name = "msg_channel_announcement_target"
-path = "fuzz_targets/msg_targets/msg_channel_announcement_target.rs"
-
-[[bin]]
-name = "msg_channel_update_target"
-path = "fuzz_targets/msg_targets/msg_channel_update_target.rs"
-
-[[bin]]
-name = "msg_decoded_onion_error_packet_target"
-path = "fuzz_targets/msg_targets/msg_decoded_onion_error_packet_target.rs"
-
-[[bin]]
-name = "msg_init_target"
-path = "fuzz_targets/msg_targets/msg_init_target.rs"
-
-[[bin]]
-name = "msg_node_announcement_target"
-path = "fuzz_targets/msg_targets/msg_node_announcement_target.rs"
-
-[[bin]]
-name = "msg_onion_hop_data_target"
-path = "fuzz_targets/msg_targets/msg_onion_hop_data_target.rs"
diff --git a/lightning/fuzz/fuzz_targets/chanmon_deser_target.rs b/lightning/fuzz/fuzz_targets/chanmon_deser_target.rs
deleted file mode 100644 (file)
index f741832..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate bitcoin;
-extern crate bitcoin_hashes;
-extern crate lightning;
-
-use bitcoin_hashes::sha256d::Hash as Sha256dHash;
-
-use lightning::ln::channelmonitor;
-use lightning::util::ser::{ReadableArgs, Writer};
-
-mod utils;
-use utils::test_logger;
-
-use std::io::Cursor;
-use std::sync::Arc;
-
-struct VecWriter(Vec<u8>);
-impl Writer for VecWriter {
-       fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
-               self.0.extend_from_slice(buf);
-               Ok(())
-       }
-       fn size_hint(&mut self, size: usize) {
-               self.0.reserve_exact(size);
-       }
-}
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       let logger = Arc::new(test_logger::TestLogger::new("".to_owned()));
-       if let Ok((latest_block_hash, monitor)) = <(Sha256dHash, channelmonitor::ChannelMonitor)>::read(&mut Cursor::new(data), logger.clone()) {
-               let mut w = VecWriter(Vec::new());
-               monitor.write_for_disk(&mut w).unwrap();
-               let deserialized_copy = <(Sha256dHash, channelmonitor::ChannelMonitor)>::read(&mut Cursor::new(&w.0), logger.clone()).unwrap();
-               assert!(latest_block_hash == deserialized_copy.0);
-               assert!(monitor == deserialized_copy.1);
-               w.0.clear();
-               monitor.write_for_watchtower(&mut w).unwrap();
-       }
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/chanmon_fail_consistency.rs b/lightning/fuzz/fuzz_targets/chanmon_fail_consistency.rs
deleted file mode 100644 (file)
index 459fca4..0000000
+++ /dev/null
@@ -1,781 +0,0 @@
-//! Test that monitor update failures don't get our channel state out of sync.
-//! One of the biggest concern with the monitor update failure handling code is that messages
-//! resent after monitor updating is restored are delivered out-of-order, resulting in
-//! commitment_signed messages having "invalid signatures".
-//! To test this we stand up a network of three nodes and read bytes from the fuzz input to denote
-//! actions such as sending payments, handling events, or changing monitor update return values on
-//! a per-node basis. This should allow it to find any cases where the ordering of actions results
-//! in us getting out of sync with ourselves, and, assuming at least one of our recieve- or
-//! send-side handling is correct, other peers. We consider it a failure if any action results in a
-//! channel being force-closed.
-
-//Uncomment this for libfuzzer builds:
-//#![no_main]
-
-extern crate bitcoin;
-extern crate bitcoin_hashes;
-extern crate lightning;
-extern crate secp256k1;
-
-use bitcoin::BitcoinHash;
-use bitcoin::blockdata::block::BlockHeader;
-use bitcoin::blockdata::transaction::{Transaction, TxOut};
-use bitcoin::blockdata::script::{Builder, Script};
-use bitcoin::blockdata::opcodes;
-use bitcoin::network::constants::Network;
-
-use bitcoin_hashes::Hash as TraitImport;
-use bitcoin_hashes::hash160::Hash as Hash160;
-use bitcoin_hashes::sha256::Hash as Sha256;
-use bitcoin_hashes::sha256d::Hash as Sha256d;
-
-use lightning::chain::chaininterface;
-use lightning::chain::transaction::OutPoint;
-use lightning::chain::chaininterface::{BroadcasterInterface,ConfirmationTarget,ChainListener,FeeEstimator,ChainWatchInterfaceUtil};
-use lightning::chain::keysinterface::{ChannelKeys, KeysInterface};
-use lightning::ln::channelmonitor;
-use lightning::ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdateErr, HTLCUpdate};
-use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage, ChannelManagerReadArgs};
-use lightning::ln::router::{Route, RouteHop};
-use lightning::ln::msgs::{CommitmentUpdate, ChannelMessageHandler, ErrorAction, LightningError, UpdateAddHTLC, LocalFeatures};
-use lightning::util::events;
-use lightning::util::logger::Logger;
-use lightning::util::config::UserConfig;
-use lightning::util::events::{EventsProvider, MessageSendEventsProvider};
-use lightning::util::ser::{Readable, ReadableArgs, Writeable, Writer};
-
-mod utils;
-use utils::test_logger;
-
-use secp256k1::key::{PublicKey,SecretKey};
-use secp256k1::Secp256k1;
-
-use std::mem;
-use std::cmp::Ordering;
-use std::collections::{HashSet, hash_map, HashMap};
-use std::sync::{Arc,Mutex};
-use std::sync::atomic;
-use std::io::Cursor;
-
-struct FuzzEstimator {}
-impl FeeEstimator for FuzzEstimator {
-       fn get_est_sat_per_1000_weight(&self, _: ConfirmationTarget) -> u64 {
-               253
-       }
-}
-
-pub struct TestBroadcaster {}
-impl BroadcasterInterface for TestBroadcaster {
-       fn broadcast_transaction(&self, _tx: &Transaction) { }
-}
-
-pub struct VecWriter(pub Vec<u8>);
-impl Writer for VecWriter {
-       fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
-               self.0.extend_from_slice(buf);
-               Ok(())
-       }
-       fn size_hint(&mut self, size: usize) {
-               self.0.reserve_exact(size);
-       }
-}
-
-static mut IN_RESTORE: bool = false;
-pub struct TestChannelMonitor {
-       pub simple_monitor: Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint>>,
-       pub update_ret: Mutex<Result<(), channelmonitor::ChannelMonitorUpdateErr>>,
-       pub latest_good_update: Mutex<HashMap<OutPoint, Vec<u8>>>,
-       pub latest_update_good: Mutex<HashMap<OutPoint, bool>>,
-       pub latest_updates_good_at_last_ser: Mutex<HashMap<OutPoint, bool>>,
-       pub should_update_manager: atomic::AtomicBool,
-}
-impl TestChannelMonitor {
-       pub fn new(chain_monitor: Arc<chaininterface::ChainWatchInterface>, broadcaster: Arc<chaininterface::BroadcasterInterface>, logger: Arc<Logger>, feeest: Arc<chaininterface::FeeEstimator>) -> Self {
-               Self {
-                       simple_monitor: channelmonitor::SimpleManyChannelMonitor::new(chain_monitor, broadcaster, logger, feeest),
-                       update_ret: Mutex::new(Ok(())),
-                       latest_good_update: Mutex::new(HashMap::new()),
-                       latest_update_good: Mutex::new(HashMap::new()),
-                       latest_updates_good_at_last_ser: Mutex::new(HashMap::new()),
-                       should_update_manager: atomic::AtomicBool::new(false),
-               }
-       }
-}
-impl channelmonitor::ManyChannelMonitor for TestChannelMonitor {
-       fn add_update_monitor(&self, funding_txo: OutPoint, monitor: channelmonitor::ChannelMonitor) -> Result<(), channelmonitor::ChannelMonitorUpdateErr> {
-               let ret = self.update_ret.lock().unwrap().clone();
-               if let Ok(()) = ret {
-                       let mut ser = VecWriter(Vec::new());
-                       monitor.write_for_disk(&mut ser).unwrap();
-                       self.latest_good_update.lock().unwrap().insert(funding_txo, ser.0);
-                       match self.latest_update_good.lock().unwrap().entry(funding_txo) {
-                               hash_map::Entry::Vacant(mut e) => { e.insert(true); },
-                               hash_map::Entry::Occupied(mut e) => {
-                                       if !e.get() && unsafe { IN_RESTORE } {
-                                               // Technically we can't consider an update to be "good" unless we're doing
-                                               // it in response to a test_restore_channel_monitor as the channel may
-                                               // still be waiting on such a call, so only set us to good if we're in the
-                                               // middle of a restore call.
-                                               e.insert(true);
-                                       }
-                               },
-                       }
-                       self.should_update_manager.store(true, atomic::Ordering::Relaxed);
-               } else {
-                       self.latest_update_good.lock().unwrap().insert(funding_txo, false);
-               }
-               assert!(self.simple_monitor.add_update_monitor(funding_txo, monitor).is_ok());
-               ret
-       }
-
-       fn fetch_pending_htlc_updated(&self) -> Vec<HTLCUpdate> {
-               return self.simple_monitor.fetch_pending_htlc_updated();
-       }
-}
-
-struct KeyProvider {
-       node_id: u8,
-       session_id: atomic::AtomicU8,
-       channel_id: atomic::AtomicU8,
-}
-impl KeysInterface for KeyProvider {
-       fn get_node_secret(&self) -> SecretKey {
-               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, self.node_id]).unwrap()
-       }
-
-       fn get_destination_script(&self) -> Script {
-               let secp_ctx = Secp256k1::signing_only();
-               let channel_monitor_claim_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, self.node_id]).unwrap();
-               let our_channel_monitor_claim_key_hash = Hash160::hash(&PublicKey::from_secret_key(&secp_ctx, &channel_monitor_claim_key).serialize());
-               Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script()
-       }
-
-       fn get_shutdown_pubkey(&self) -> PublicKey {
-               let secp_ctx = Secp256k1::signing_only();
-               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, 3, self.node_id]).unwrap())
-       }
-
-       fn get_channel_keys(&self, _inbound: bool) -> ChannelKeys {
-               ChannelKeys {
-                       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, 4, self.node_id]).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, 5, self.node_id]).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, 6, self.node_id]).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, 7, self.node_id]).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, 8, self.node_id]).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, 9, self.node_id],
-               }
-       }
-
-       fn get_session_key(&self) -> SecretKey {
-               let id = self.session_id.fetch_add(1, atomic::Ordering::Relaxed);
-               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, id, 10, self.node_id]).unwrap()
-       }
-
-       fn get_channel_id(&self) -> [u8; 32] {
-               let id = self.channel_id.fetch_add(1, atomic::Ordering::Relaxed);
-               [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, id, 11, self.node_id]
-       }
-}
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       let fee_est = Arc::new(FuzzEstimator{});
-       let broadcast = Arc::new(TestBroadcaster{});
-
-       macro_rules! make_node {
-               ($node_id: expr) => { {
-                       let logger: Arc<Logger> = Arc::new(test_logger::TestLogger::new($node_id.to_string()));
-                       let watch = Arc::new(ChainWatchInterfaceUtil::new(Network::Bitcoin, Arc::clone(&logger)));
-                       let monitor = Arc::new(TestChannelMonitor::new(watch.clone(), broadcast.clone(), logger.clone(), fee_est.clone()));
-
-                       let keys_manager = Arc::new(KeyProvider { node_id: $node_id, session_id: atomic::AtomicU8::new(0), channel_id: atomic::AtomicU8::new(0) });
-                       let mut config = UserConfig::new();
-                       config.channel_options.fee_proportional_millionths = 0;
-                       config.channel_options.announced_channel = true;
-                       config.peer_channel_config_limits.min_dust_limit_satoshis = 0;
-                       (ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, 0).unwrap(),
-                       monitor)
-               } }
-       }
-
-       macro_rules! reload_node {
-               ($ser: expr, $node_id: expr, $old_monitors: expr) => { {
-                       let logger: Arc<Logger> = Arc::new(test_logger::TestLogger::new($node_id.to_string()));
-                       let watch = Arc::new(ChainWatchInterfaceUtil::new(Network::Bitcoin, Arc::clone(&logger)));
-                       let monitor = Arc::new(TestChannelMonitor::new(watch.clone(), broadcast.clone(), logger.clone(), fee_est.clone()));
-
-                       let keys_manager = Arc::new(KeyProvider { node_id: $node_id, session_id: atomic::AtomicU8::new(0), channel_id: atomic::AtomicU8::new(0) });
-                       let mut config = UserConfig::new();
-                       config.channel_options.fee_proportional_millionths = 0;
-                       config.channel_options.announced_channel = true;
-                       config.peer_channel_config_limits.min_dust_limit_satoshis = 0;
-
-                       let mut monitors = HashMap::new();
-                       let mut old_monitors = $old_monitors.latest_good_update.lock().unwrap();
-                       for (outpoint, monitor_ser) in old_monitors.drain() {
-                               monitors.insert(outpoint, <(Sha256d, ChannelMonitor)>::read(&mut Cursor::new(&monitor_ser), Arc::clone(&logger)).expect("Failed to read monitor").1);
-                               monitor.latest_good_update.lock().unwrap().insert(outpoint, monitor_ser);
-                       }
-                       let mut monitor_refs = HashMap::new();
-                       for (outpoint, monitor) in monitors.iter() {
-                               monitor_refs.insert(*outpoint, monitor);
-                       }
-
-                       let read_args = ChannelManagerReadArgs {
-                               keys_manager,
-                               fee_estimator: fee_est.clone(),
-                               monitor: monitor.clone(),
-                               tx_broadcaster: broadcast.clone(),
-                               logger,
-                               default_config: config,
-                               channel_monitors: &monitor_refs,
-                       };
-
-                       let res = (<(Sha256d, ChannelManager)>::read(&mut Cursor::new(&$ser.0), read_args).expect("Failed to read manager").1, monitor);
-                       for (_, was_good) in $old_monitors.latest_updates_good_at_last_ser.lock().unwrap().iter() {
-                               if !was_good {
-                                       // If the last time we updated a monitor we didn't successfully update (and we
-                                       // have sense updated our serialized copy of the ChannelManager) we may
-                                       // force-close the channel on our counterparty cause we know we're missing
-                                       // something. Thus, we just return here since we can't continue to test.
-                                       return;
-                               }
-                       }
-                       res
-               } }
-       }
-
-       let mut channel_txn = Vec::new();
-       macro_rules! make_channel {
-               ($source: expr, $dest: expr, $chan_id: expr) => { {
-                       $source.create_channel($dest.get_our_node_id(), 10000000, 42, 0).unwrap();
-                       let open_channel = {
-                               let events = $source.get_and_clear_pending_msg_events();
-                               assert_eq!(events.len(), 1);
-                               if let events::MessageSendEvent::SendOpenChannel { ref msg, .. } = events[0] {
-                                       msg.clone()
-                               } else { panic!("Wrong event type"); }
-                       };
-
-                       $dest.handle_open_channel(&$source.get_our_node_id(), LocalFeatures::new(), &open_channel).unwrap();
-                       let accept_channel = {
-                               let events = $dest.get_and_clear_pending_msg_events();
-                               assert_eq!(events.len(), 1);
-                               if let events::MessageSendEvent::SendAcceptChannel { ref msg, .. } = events[0] {
-                                       msg.clone()
-                               } else { panic!("Wrong event type"); }
-                       };
-
-                       $source.handle_accept_channel(&$dest.get_our_node_id(), LocalFeatures::new(), &accept_channel).unwrap();
-                       {
-                               let events = $source.get_and_clear_pending_events();
-                               assert_eq!(events.len(), 1);
-                               if let events::Event::FundingGenerationReady { ref temporary_channel_id, ref channel_value_satoshis, ref output_script, .. } = events[0] {
-                                       let tx = Transaction { version: $chan_id, lock_time: 0, input: Vec::new(), output: vec![TxOut {
-                                               value: *channel_value_satoshis, script_pubkey: output_script.clone(),
-                                       }]};
-                                       let funding_output = OutPoint::new(tx.txid(), 0);
-                                       $source.funding_transaction_generated(&temporary_channel_id, funding_output);
-                                       channel_txn.push(tx);
-                               } else { panic!("Wrong event type"); }
-                       }
-
-                       let funding_created = {
-                               let events = $source.get_and_clear_pending_msg_events();
-                               assert_eq!(events.len(), 1);
-                               if let events::MessageSendEvent::SendFundingCreated { ref msg, .. } = events[0] {
-                                       msg.clone()
-                               } else { panic!("Wrong event type"); }
-                       };
-                       $dest.handle_funding_created(&$source.get_our_node_id(), &funding_created).unwrap();
-
-                       let funding_signed = {
-                               let events = $dest.get_and_clear_pending_msg_events();
-                               assert_eq!(events.len(), 1);
-                               if let events::MessageSendEvent::SendFundingSigned { ref msg, .. } = events[0] {
-                                       msg.clone()
-                               } else { panic!("Wrong event type"); }
-                       };
-                       $source.handle_funding_signed(&$dest.get_our_node_id(), &funding_signed).unwrap();
-
-                       {
-                               let events = $source.get_and_clear_pending_events();
-                               assert_eq!(events.len(), 1);
-                               if let events::Event::FundingBroadcastSafe { .. } = events[0] {
-                               } else { panic!("Wrong event type"); }
-                       }
-               } }
-       }
-
-       macro_rules! confirm_txn {
-               ($node: expr) => { {
-                       let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
-                       let mut txn = Vec::with_capacity(channel_txn.len());
-                       let mut posn = Vec::with_capacity(channel_txn.len());
-                       for i in 0..channel_txn.len() {
-                               txn.push(&channel_txn[i]);
-                               posn.push(i as u32 + 1);
-                       }
-                       $node.block_connected(&header, 1, &txn, &posn);
-                       for i in 2..100 {
-                               header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
-                               $node.block_connected(&header, i, &Vec::new(), &[0; 0]);
-                       }
-               } }
-       }
-
-       macro_rules! lock_fundings {
-               ($nodes: expr) => { {
-                       let mut node_events = Vec::new();
-                       for node in $nodes.iter() {
-                               node_events.push(node.get_and_clear_pending_msg_events());
-                       }
-                       for (idx, node_event) in node_events.iter().enumerate() {
-                               for event in node_event {
-                                       if let events::MessageSendEvent::SendFundingLocked { ref node_id, ref msg } = event {
-                                               for node in $nodes.iter() {
-                                                       if node.get_our_node_id() == *node_id {
-                                                               node.handle_funding_locked(&$nodes[idx].get_our_node_id(), msg).unwrap();
-                                                       }
-                                               }
-                                       } else { panic!("Wrong event type"); }
-                               }
-                       }
-
-                       for node in $nodes.iter() {
-                               let events = node.get_and_clear_pending_msg_events();
-                               for event in events {
-                                       if let events::MessageSendEvent::SendAnnouncementSignatures { .. } = event {
-                                       } else { panic!("Wrong event type"); }
-                               }
-                       }
-               } }
-       }
-
-       // 3 nodes is enough to hit all the possible cases, notably unknown-source-unknown-dest
-       // forwarding.
-       let (mut node_a, mut monitor_a) = make_node!(0);
-       let (mut node_b, mut monitor_b) = make_node!(1);
-       let (mut node_c, mut monitor_c) = make_node!(2);
-
-       let mut nodes = [node_a, node_b, node_c];
-
-       make_channel!(nodes[0], nodes[1], 0);
-       make_channel!(nodes[1], nodes[2], 1);
-
-       for node in nodes.iter() {
-               confirm_txn!(node);
-       }
-
-       lock_fundings!(nodes);
-
-       let chan_a = nodes[0].list_usable_channels()[0].short_channel_id.unwrap();
-       let chan_b = nodes[2].list_usable_channels()[0].short_channel_id.unwrap();
-
-       let mut payment_id = 0;
-
-       let mut chan_a_disconnected = false;
-       let mut chan_b_disconnected = false;
-       let mut ba_events = Vec::new();
-       let mut bc_events = Vec::new();
-
-       let mut node_a_ser = VecWriter(Vec::new());
-       nodes[0].write(&mut node_a_ser).unwrap();
-       let mut node_b_ser = VecWriter(Vec::new());
-       nodes[1].write(&mut node_b_ser).unwrap();
-       let mut node_c_ser = VecWriter(Vec::new());
-       nodes[2].write(&mut node_c_ser).unwrap();
-
-       macro_rules! test_err {
-               ($res: expr) => {
-                       match $res {
-                               Ok(()) => {},
-                               Err(LightningError { action: ErrorAction::IgnoreError, .. }) => { },
-                               _ => { $res.unwrap() },
-                       }
-               }
-       }
-
-       macro_rules! test_return {
-               () => { {
-                       assert_eq!(nodes[0].list_channels().len(), 1);
-                       assert_eq!(nodes[1].list_channels().len(), 2);
-                       assert_eq!(nodes[2].list_channels().len(), 1);
-                       return;
-               } }
-       }
-
-       let mut read_pos = 0;
-       macro_rules! get_slice {
-               ($len: expr) => {
-                       {
-                               let slice_len = $len as usize;
-                               if data.len() < read_pos + slice_len {
-                                       test_return!();
-                               }
-                               read_pos += slice_len;
-                               &data[read_pos - slice_len..read_pos]
-                       }
-               }
-       }
-
-       loop {
-               macro_rules! send_payment {
-                       ($source: expr, $dest: expr) => { {
-                               let payment_hash = Sha256::hash(&[payment_id; 1]);
-                               payment_id = payment_id.wrapping_add(1);
-                               if let Err(_) = $source.send_payment(Route {
-                                       hops: vec![RouteHop {
-                                               pubkey: $dest.0.get_our_node_id(),
-                                               short_channel_id: $dest.1,
-                                               fee_msat: 5000000,
-                                               cltv_expiry_delta: 200,
-                                       }],
-                               }, PaymentHash(payment_hash.into_inner())) {
-                                       // Probably ran out of funds
-                                       test_return!();
-                               }
-                       } };
-                       ($source: expr, $middle: expr, $dest: expr) => { {
-                               let payment_hash = Sha256::hash(&[payment_id; 1]);
-                               payment_id = payment_id.wrapping_add(1);
-                               if let Err(_) = $source.send_payment(Route {
-                                       hops: vec![RouteHop {
-                                               pubkey: $middle.0.get_our_node_id(),
-                                               short_channel_id: $middle.1,
-                                               fee_msat: 50000,
-                                               cltv_expiry_delta: 100,
-                                       },RouteHop {
-                                               pubkey: $dest.0.get_our_node_id(),
-                                               short_channel_id: $dest.1,
-                                               fee_msat: 5000000,
-                                               cltv_expiry_delta: 200,
-                                       }],
-                               }, PaymentHash(payment_hash.into_inner())) {
-                                       // Probably ran out of funds
-                                       test_return!();
-                               }
-                       } }
-               }
-
-               macro_rules! process_msg_events {
-                       ($node: expr, $corrupt_forward: expr) => { {
-                               let events = if $node == 1 {
-                                       let mut new_events = Vec::new();
-                                       mem::swap(&mut new_events, &mut ba_events);
-                                       new_events.extend_from_slice(&bc_events[..]);
-                                       bc_events.clear();
-                                       new_events
-                               } else { Vec::new() };
-                               for event in events.iter().chain(nodes[$node].get_and_clear_pending_msg_events().iter()) {
-                                       match event {
-                                               events::MessageSendEvent::UpdateHTLCs { ref node_id, updates: CommitmentUpdate { ref update_add_htlcs, ref update_fail_htlcs, ref update_fulfill_htlcs, ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed } } => {
-                                                       for dest in nodes.iter() {
-                                                               if dest.get_our_node_id() == *node_id {
-                                                                       assert!(update_fee.is_none());
-                                                                       for update_add in update_add_htlcs {
-                                                                               if !$corrupt_forward {
-                                                                                       test_err!(dest.handle_update_add_htlc(&nodes[$node].get_our_node_id(), &update_add));
-                                                                               } else {
-                                                                                       // Corrupt the update_add_htlc message so that its HMAC
-                                                                                       // check will fail and we generate a
-                                                                                       // update_fail_malformed_htlc instead of an
-                                                                                       // update_fail_htlc as we do when we reject a payment.
-                                                                                       let mut msg_ser = update_add.encode();
-                                                                                       msg_ser[1000] ^= 0xff;
-                                                                                       let new_msg = UpdateAddHTLC::read(&mut Cursor::new(&msg_ser)).unwrap();
-                                                                                       test_err!(dest.handle_update_add_htlc(&nodes[$node].get_our_node_id(), &new_msg));
-                                                                               }
-                                                                       }
-                                                                       for update_fulfill in update_fulfill_htlcs {
-                                                                               test_err!(dest.handle_update_fulfill_htlc(&nodes[$node].get_our_node_id(), &update_fulfill));
-                                                                       }
-                                                                       for update_fail in update_fail_htlcs {
-                                                                               test_err!(dest.handle_update_fail_htlc(&nodes[$node].get_our_node_id(), &update_fail));
-                                                                       }
-                                                                       for update_fail_malformed in update_fail_malformed_htlcs {
-                                                                               test_err!(dest.handle_update_fail_malformed_htlc(&nodes[$node].get_our_node_id(), &update_fail_malformed));
-                                                                       }
-                                                                       test_err!(dest.handle_commitment_signed(&nodes[$node].get_our_node_id(), &commitment_signed));
-                                                               }
-                                                       }
-                                               },
-                                               events::MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => {
-                                                       for dest in nodes.iter() {
-                                                               if dest.get_our_node_id() == *node_id {
-                                                                       test_err!(dest.handle_revoke_and_ack(&nodes[$node].get_our_node_id(), msg));
-                                                               }
-                                                       }
-                                               },
-                                               events::MessageSendEvent::SendChannelReestablish { ref node_id, ref msg } => {
-                                                       for dest in nodes.iter() {
-                                                               if dest.get_our_node_id() == *node_id {
-                                                                       test_err!(dest.handle_channel_reestablish(&nodes[$node].get_our_node_id(), msg));
-                                                               }
-                                                       }
-                                               },
-                                               events::MessageSendEvent::SendFundingLocked { .. } => {
-                                                       // Can be generated as a reestablish response
-                                               },
-                                               events::MessageSendEvent::PaymentFailureNetworkUpdate { .. } => {
-                                                       // Can be generated due to a payment forward being rejected due to a
-                                                       // channel having previously failed a monitor update
-                                               },
-                                               _ => panic!("Unhandled message event"),
-                                       }
-                               }
-                       } }
-               }
-
-               macro_rules! drain_msg_events_on_disconnect {
-                       ($counterparty_id: expr) => { {
-                               if $counterparty_id == 0 {
-                                       for event in nodes[0].get_and_clear_pending_msg_events() {
-                                               match event {
-                                                       events::MessageSendEvent::UpdateHTLCs { .. } => {},
-                                                       events::MessageSendEvent::SendRevokeAndACK { .. } => {},
-                                                       events::MessageSendEvent::SendChannelReestablish { .. } => {},
-                                                       events::MessageSendEvent::SendFundingLocked { .. } => {},
-                                                       events::MessageSendEvent::PaymentFailureNetworkUpdate { .. } => {},
-                                                       _ => panic!("Unhandled message event"),
-                                               }
-                                       }
-                                       ba_events.clear();
-                               } else {
-                                       for event in nodes[2].get_and_clear_pending_msg_events() {
-                                               match event {
-                                                       events::MessageSendEvent::UpdateHTLCs { .. } => {},
-                                                       events::MessageSendEvent::SendRevokeAndACK { .. } => {},
-                                                       events::MessageSendEvent::SendChannelReestablish { .. } => {},
-                                                       events::MessageSendEvent::SendFundingLocked { .. } => {},
-                                                       events::MessageSendEvent::PaymentFailureNetworkUpdate { .. } => {},
-                                                       _ => panic!("Unhandled message event"),
-                                               }
-                                       }
-                                       bc_events.clear();
-                               }
-                               let mut events = nodes[1].get_and_clear_pending_msg_events();
-                               let drop_node_id = if $counterparty_id == 0 { nodes[0].get_our_node_id() } else { nodes[2].get_our_node_id() };
-                               let msg_sink = if $counterparty_id == 0 { &mut bc_events } else { &mut ba_events };
-                               for event in events.drain(..) {
-                                       let push = match event {
-                                               events::MessageSendEvent::UpdateHTLCs { ref node_id, .. } => {
-                                                       if *node_id != drop_node_id { true } else { false }
-                                               },
-                                               events::MessageSendEvent::SendRevokeAndACK { ref node_id, .. } => {
-                                                       if *node_id != drop_node_id { true } else { false }
-                                               },
-                                               events::MessageSendEvent::SendChannelReestablish { ref node_id, .. } => {
-                                                       if *node_id != drop_node_id { true } else { false }
-                                               },
-                                               events::MessageSendEvent::SendFundingLocked { .. } => false,
-                                               events::MessageSendEvent::PaymentFailureNetworkUpdate { .. } => false,
-                                               _ => panic!("Unhandled message event"),
-                                       };
-                                       if push { msg_sink.push(event); }
-                               }
-                       } }
-               }
-
-               macro_rules! process_events {
-                       ($node: expr, $fail: expr) => { {
-                               // In case we get 256 payments we may have a hash collision, resulting in the
-                               // second claim/fail call not finding the duplicate-hash HTLC, so we have to
-                               // deduplicate the calls here.
-                               let mut claim_set = HashSet::new();
-                               let mut events = nodes[$node].get_and_clear_pending_events();
-                               // Sort events so that PendingHTLCsForwardable get processed last. This avoids a
-                               // case where we first process a PendingHTLCsForwardable, then claim/fail on a
-                               // PaymentReceived, claiming/failing two HTLCs, but leaving a just-generated
-                               // PaymentReceived event for the second HTLC in our pending_events (and breaking
-                               // our claim_set deduplication).
-                               events.sort_by(|a, b| {
-                                       if let events::Event::PaymentReceived { .. } = a {
-                                               if let events::Event::PendingHTLCsForwardable { .. } = b {
-                                                       Ordering::Less
-                                               } else { Ordering::Equal }
-                                       } else if let events::Event::PendingHTLCsForwardable { .. } = a {
-                                               if let events::Event::PaymentReceived { .. } = b {
-                                                       Ordering::Greater
-                                               } else { Ordering::Equal }
-                                       } else { Ordering::Equal }
-                               });
-                               for event in events.drain(..) {
-                                       match event {
-                                               events::Event::PaymentReceived { payment_hash, .. } => {
-                                                       if claim_set.insert(payment_hash.0) {
-                                                               if $fail {
-                                                                       assert!(nodes[$node].fail_htlc_backwards(&payment_hash));
-                                                               } else {
-                                                                       assert!(nodes[$node].claim_funds(PaymentPreimage(payment_hash.0), 5_000_000));
-                                                               }
-                                                       }
-                                               },
-                                               events::Event::PaymentSent { .. } => {},
-                                               events::Event::PaymentFailed { .. } => {},
-                                               events::Event::PendingHTLCsForwardable { .. } => {
-                                                       nodes[$node].process_pending_htlc_forwards();
-                                               },
-                                               _ => panic!("Unhandled event"),
-                                       }
-                               }
-                       } }
-               }
-
-               match get_slice!(1)[0] {
-                       0x00 => *monitor_a.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure),
-                       0x01 => *monitor_b.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure),
-                       0x02 => *monitor_c.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure),
-                       0x03 => *monitor_a.update_ret.lock().unwrap() = Ok(()),
-                       0x04 => *monitor_b.update_ret.lock().unwrap() = Ok(()),
-                       0x05 => *monitor_c.update_ret.lock().unwrap() = Ok(()),
-                       0x06 => { unsafe { IN_RESTORE = true }; nodes[0].test_restore_channel_monitor(); unsafe { IN_RESTORE = false }; },
-                       0x07 => { unsafe { IN_RESTORE = true }; nodes[1].test_restore_channel_monitor(); unsafe { IN_RESTORE = false }; },
-                       0x08 => { unsafe { IN_RESTORE = true }; nodes[2].test_restore_channel_monitor(); unsafe { IN_RESTORE = false }; },
-                       0x09 => send_payment!(nodes[0], (&nodes[1], chan_a)),
-                       0x0a => send_payment!(nodes[1], (&nodes[0], chan_a)),
-                       0x0b => send_payment!(nodes[1], (&nodes[2], chan_b)),
-                       0x0c => send_payment!(nodes[2], (&nodes[1], chan_b)),
-                       0x0d => send_payment!(nodes[0], (&nodes[1], chan_a), (&nodes[2], chan_b)),
-                       0x0e => send_payment!(nodes[2], (&nodes[1], chan_b), (&nodes[0], chan_a)),
-                       0x0f => {
-                               if !chan_a_disconnected {
-                                       nodes[0].peer_disconnected(&nodes[1].get_our_node_id(), false);
-                                       nodes[1].peer_disconnected(&nodes[0].get_our_node_id(), false);
-                                       chan_a_disconnected = true;
-                                       drain_msg_events_on_disconnect!(0);
-                               }
-                       },
-                       0x10 => {
-                               if !chan_b_disconnected {
-                                       nodes[1].peer_disconnected(&nodes[2].get_our_node_id(), false);
-                                       nodes[2].peer_disconnected(&nodes[1].get_our_node_id(), false);
-                                       chan_b_disconnected = true;
-                                       drain_msg_events_on_disconnect!(2);
-                               }
-                       },
-                       0x11 => {
-                               if chan_a_disconnected {
-                                       nodes[0].peer_connected(&nodes[1].get_our_node_id());
-                                       nodes[1].peer_connected(&nodes[0].get_our_node_id());
-                                       chan_a_disconnected = false;
-                               }
-                       },
-                       0x12 => {
-                               if chan_b_disconnected {
-                                       nodes[1].peer_connected(&nodes[2].get_our_node_id());
-                                       nodes[2].peer_connected(&nodes[1].get_our_node_id());
-                                       chan_b_disconnected = false;
-                               }
-                       },
-                       0x13 => process_msg_events!(0, true),
-                       0x14 => process_msg_events!(0, false),
-                       0x15 => process_events!(0, true),
-                       0x16 => process_events!(0, false),
-                       0x17 => process_msg_events!(1, true),
-                       0x18 => process_msg_events!(1, false),
-                       0x19 => process_events!(1, true),
-                       0x1a => process_events!(1, false),
-                       0x1b => process_msg_events!(2, true),
-                       0x1c => process_msg_events!(2, false),
-                       0x1d => process_events!(2, true),
-                       0x1e => process_events!(2, false),
-                       0x1f => {
-                               if !chan_a_disconnected {
-                                       nodes[1].peer_disconnected(&nodes[0].get_our_node_id(), false);
-                                       chan_a_disconnected = true;
-                                       drain_msg_events_on_disconnect!(0);
-                               }
-                               let (new_node_a, new_monitor_a) = reload_node!(node_a_ser, 0, monitor_a);
-                               node_a = Arc::new(new_node_a);
-                               nodes[0] = node_a.clone();
-                               monitor_a = new_monitor_a;
-                       },
-                       0x20 => {
-                               if !chan_a_disconnected {
-                                       nodes[0].peer_disconnected(&nodes[1].get_our_node_id(), false);
-                                       chan_a_disconnected = true;
-                                       nodes[0].get_and_clear_pending_msg_events();
-                                       ba_events.clear();
-                               }
-                               if !chan_b_disconnected {
-                                       nodes[2].peer_disconnected(&nodes[1].get_our_node_id(), false);
-                                       chan_b_disconnected = true;
-                                       nodes[2].get_and_clear_pending_msg_events();
-                                       bc_events.clear();
-                               }
-                               let (new_node_b, new_monitor_b) = reload_node!(node_b_ser, 1, monitor_b);
-                               node_b = Arc::new(new_node_b);
-                               nodes[1] = node_b.clone();
-                               monitor_b = new_monitor_b;
-                       },
-                       0x21 => {
-                               if !chan_b_disconnected {
-                                       nodes[1].peer_disconnected(&nodes[2].get_our_node_id(), false);
-                                       chan_b_disconnected = true;
-                                       drain_msg_events_on_disconnect!(2);
-                               }
-                               let (new_node_c, new_monitor_c) = reload_node!(node_c_ser, 2, monitor_c);
-                               node_c = Arc::new(new_node_c);
-                               nodes[2] = node_c.clone();
-                               monitor_c = new_monitor_c;
-                       },
-                       _ => test_return!(),
-               }
-
-               if monitor_a.should_update_manager.load(atomic::Ordering::Relaxed) {
-                       node_a_ser.0.clear();
-                       nodes[0].write(&mut node_a_ser).unwrap();
-                       monitor_a.should_update_manager.store(false, atomic::Ordering::Relaxed);
-                       *monitor_a.latest_updates_good_at_last_ser.lock().unwrap() = monitor_a.latest_update_good.lock().unwrap().clone();
-               }
-               if monitor_b.should_update_manager.load(atomic::Ordering::Relaxed) {
-                       node_b_ser.0.clear();
-                       nodes[1].write(&mut node_b_ser).unwrap();
-                       monitor_b.should_update_manager.store(false, atomic::Ordering::Relaxed);
-                       *monitor_b.latest_updates_good_at_last_ser.lock().unwrap() = monitor_b.latest_update_good.lock().unwrap().clone();
-               }
-               if monitor_c.should_update_manager.load(atomic::Ordering::Relaxed) {
-                       node_c_ser.0.clear();
-                       nodes[2].write(&mut node_c_ser).unwrap();
-                       monitor_c.should_update_manager.store(false, atomic::Ordering::Relaxed);
-                       *monitor_c.latest_updates_good_at_last_ser.lock().unwrap() = monitor_c.latest_update_good.lock().unwrap().clone();
-               }
-       }
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-#[cfg(feature = "libfuzzer_fuzz")]
-#[macro_use] extern crate libfuzzer_sys;
-#[cfg(feature = "libfuzzer_fuzz")]
-fuzz_target!(|data: &[u8]| {
-       do_test(data);
-});
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/full_stack_target.rs b/lightning/fuzz/fuzz_targets/full_stack_target.rs
deleted file mode 100644 (file)
index cd65a2f..0000000
+++ /dev/null
@@ -1,891 +0,0 @@
-//! Test that no series of bytes received over the wire/connections created/payments sent can
-//! result in a crash. We do this by standing up a node and then reading bytes from input to denote
-//! actions such as creating new inbound/outbound connections, bytes to be read from a connection,
-//! or payments to send/ways to handle events generated.
-//! This test has been very useful, though due to its complexity good starting inputs are critical.
-
-//Uncomment this for libfuzzer builds:
-//#![no_main]
-
-extern crate bitcoin;
-extern crate bitcoin_hashes;
-extern crate lightning;
-extern crate secp256k1;
-
-use bitcoin::blockdata::block::BlockHeader;
-use bitcoin::blockdata::transaction::{Transaction, TxOut};
-use bitcoin::blockdata::script::{Builder, Script};
-use bitcoin::blockdata::opcodes;
-use bitcoin::consensus::encode::deserialize;
-use bitcoin::network::constants::Network;
-use bitcoin::util::hash::BitcoinHash;
-
-use bitcoin_hashes::Hash as TraitImport;
-use bitcoin_hashes::HashEngine as TraitImportEngine;
-use bitcoin_hashes::sha256::Hash as Sha256;
-use bitcoin_hashes::hash160::Hash as Hash160;
-use bitcoin_hashes::sha256d::Hash as Sha256dHash;
-
-use lightning::chain::chaininterface::{BroadcasterInterface,ConfirmationTarget,ChainListener,FeeEstimator,ChainWatchInterfaceUtil};
-use lightning::chain::transaction::OutPoint;
-use lightning::chain::keysinterface::{ChannelKeys, KeysInterface};
-use lightning::ln::channelmonitor;
-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::logger::Logger;
-use lightning::util::config::UserConfig;
-
-mod utils;
-
-use utils::test_logger;
-
-use secp256k1::key::{PublicKey,SecretKey};
-use secp256k1::Secp256k1;
-
-use std::cell::RefCell;
-use std::collections::{HashMap, hash_map};
-use std::cmp;
-use std::hash::Hash;
-use std::sync::Arc;
-use std::sync::atomic::{AtomicU64,AtomicUsize,Ordering};
-
-#[inline]
-pub fn slice_to_be16(v: &[u8]) -> u16 {
-       ((v[0] as u16) << 8*1) |
-       ((v[1] as u16) << 8*0)
-}
-
-#[inline]
-pub fn slice_to_be24(v: &[u8]) -> u32 {
-       ((v[0] as u32) << 8*2) |
-       ((v[1] as u32) << 8*1) |
-       ((v[2] as u32) << 8*0)
-}
-
-#[inline]
-pub fn slice_to_be32(v: &[u8]) -> u32 {
-       ((v[0] as u32) << 8*3) |
-       ((v[1] as u32) << 8*2) |
-       ((v[2] as u32) << 8*1) |
-       ((v[3] as u32) << 8*0)
-}
-
-#[inline]
-pub fn be64_to_array(u: u64) -> [u8; 8] {
-       let mut v = [0; 8];
-       v[0] = ((u >> 8*7) & 0xff) as u8;
-       v[1] = ((u >> 8*6) & 0xff) as u8;
-       v[2] = ((u >> 8*5) & 0xff) as u8;
-       v[3] = ((u >> 8*4) & 0xff) as u8;
-       v[4] = ((u >> 8*3) & 0xff) as u8;
-       v[5] = ((u >> 8*2) & 0xff) as u8;
-       v[6] = ((u >> 8*1) & 0xff) as u8;
-       v[7] = ((u >> 8*0) & 0xff) as u8;
-       v
-}
-
-struct InputData {
-       data: Vec<u8>,
-       read_pos: AtomicUsize,
-}
-impl InputData {
-       fn get_slice(&self, len: usize) -> Option<&[u8]> {
-               let old_pos = self.read_pos.fetch_add(len, Ordering::AcqRel);
-               if self.data.len() < old_pos + len {
-                       return None;
-               }
-               Some(&self.data[old_pos..old_pos + len])
-       }
-}
-
-struct FuzzEstimator {
-       input: Arc<InputData>,
-}
-impl FeeEstimator for FuzzEstimator {
-       fn get_est_sat_per_1000_weight(&self, _: ConfirmationTarget) -> u64 {
-               //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
-               }
-       }
-}
-
-struct TestBroadcaster {}
-impl BroadcasterInterface for TestBroadcaster {
-       fn broadcast_transaction(&self, _tx: &Transaction) {}
-}
-
-#[derive(Clone)]
-struct Peer<'a> {
-       id: u8,
-       peers_connected: &'a RefCell<[bool; 256]>,
-}
-impl<'a> SocketDescriptor for Peer<'a> {
-       fn send_data(&mut self, data: &[u8], _resume_read: bool) -> usize {
-               data.len()
-       }
-       fn disconnect_socket(&mut self) {
-               assert!(self.peers_connected.borrow()[self.id as usize]);
-               self.peers_connected.borrow_mut()[self.id as usize] = false;
-       }
-}
-impl<'a> PartialEq for Peer<'a> {
-       fn eq(&self, other: &Self) -> bool {
-               self.id == other.id
-       }
-}
-impl<'a> Eq for Peer<'a> {}
-impl<'a> Hash for Peer<'a> {
-       fn hash<H : std::hash::Hasher>(&self, h: &mut H) {
-               self.id.hash(h)
-       }
-}
-
-struct MoneyLossDetector<'a, 'b> {
-       manager: Arc<ChannelManager<'b>>,
-       monitor: Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint>>,
-       handler: PeerManager<Peer<'a>>,
-
-       peers: &'a RefCell<[bool; 256]>,
-       funding_txn: Vec<Transaction>,
-       txids_confirmed: HashMap<Sha256dHash, usize>,
-       header_hashes: Vec<Sha256dHash>,
-       height: usize,
-       max_height: usize,
-       blocks_connected: u32,
-}
-impl<'a, 'b> MoneyLossDetector<'a, 'b> {
-       pub fn new(peers: &'a RefCell<[bool; 256]>, manager: Arc<ChannelManager<'b>>, monitor: Arc<channelmonitor::SimpleManyChannelMonitor<OutPoint>>, handler: PeerManager<Peer<'a>>) -> Self {
-               MoneyLossDetector {
-                       manager,
-                       monitor,
-                       handler,
-
-                       peers,
-                       funding_txn: Vec::new(),
-                       txids_confirmed: HashMap::new(),
-                       header_hashes: vec![Default::default()],
-                       height: 0,
-                       max_height: 0,
-                       blocks_connected: 0,
-               }
-       }
-
-       fn connect_block(&mut self, all_txn: &[Transaction]) {
-               let mut txn = Vec::with_capacity(all_txn.len());
-               let mut txn_idxs = Vec::with_capacity(all_txn.len());
-               for (idx, tx) in all_txn.iter().enumerate() {
-                       let txid = tx.txid();
-                       match self.txids_confirmed.entry(txid) {
-                               hash_map::Entry::Vacant(e) => {
-                                       e.insert(self.height);
-                                       txn.push(tx);
-                                       txn_idxs.push(idx as u32 + 1);
-                               },
-                               _ => {},
-                       }
-               }
-
-               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;
-               self.manager.block_connected(&header, self.height as u32, &txn[..], &txn_idxs[..]);
-               (*self.monitor).block_connected(&header, self.height as u32, &txn[..], &txn_idxs[..]);
-               if self.header_hashes.len() > self.height {
-                       self.header_hashes[self.height] = header.bitcoin_hash();
-               } else {
-                       assert_eq!(self.header_hashes.len(), self.height);
-                       self.header_hashes.push(header.bitcoin_hash());
-               }
-               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) {
-                       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);
-                       let removal_height = self.height;
-                       self.txids_confirmed.retain(|_, height| {
-                               removal_height != *height
-                       });
-               }
-       }
-}
-
-impl<'a, 'b> Drop for MoneyLossDetector<'a, 'b> {
-       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});
-                               }
-                       }
-
-                       // Force all channels onto the chain (and time out claim txn)
-                       self.manager.force_close_all_channels();
-               }
-       }
-}
-
-struct KeyProvider {
-       node_secret: SecretKey,
-       counter: AtomicU64,
-}
-impl KeysInterface for KeyProvider {
-       fn get_node_secret(&self) -> SecretKey {
-               self.node_secret.clone()
-       }
-
-       fn get_destination_script(&self) -> Script {
-               let secp_ctx = Secp256k1::signing_only();
-               let channel_monitor_claim_key = SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap();
-               let our_channel_monitor_claim_key_hash = <Hash160 as bitcoin_hashes::Hash>::hash(&PublicKey::from_secret_key(&secp_ctx, &channel_monitor_claim_key).serialize());
-               Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script()
-       }
-
-       fn get_shutdown_pubkey(&self) -> PublicKey {
-               let secp_ctx = Secp256k1::signing_only();
-               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) -> ChannelKeys {
-               let ctr = self.counter.fetch_add(1, Ordering::Relaxed) as u8;
-               if inbound {
-                       ChannelKeys {
-                               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],
-                       }
-               } else {
-                       ChannelKeys {
-                               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],
-                       }
-               }
-       }
-
-       fn get_session_key(&self) -> SecretKey {
-               let ctr = self.counter.fetch_add(1, Ordering::Relaxed) as u8;
-               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, 13, ctr]).unwrap()
-       }
-
-       fn get_channel_id(&self) -> [u8; 32] {
-               let ctr = self.counter.fetch_add(1, Ordering::Relaxed);
-               [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-               (ctr >> 8*7) as u8, (ctr >> 8*6) as u8, (ctr >> 8*5) as u8, (ctr >> 8*4) as u8, (ctr >> 8*3) as u8, (ctr >> 8*2) as u8, (ctr >> 8*1) as u8, 14, (ctr >> 8*0) as u8]
-       }
-}
-
-#[inline]
-pub fn do_test(data: &[u8], logger: &Arc<Logger>) {
-       let input = Arc::new(InputData {
-               data: data.to_vec(),
-               read_pos: AtomicUsize::new(0),
-       });
-       let fee_est = Arc::new(FuzzEstimator {
-               input: input.clone(),
-       });
-
-       macro_rules! get_slice {
-               ($len: expr) => {
-                       match input.get_slice($len as usize) {
-                               Some(slice) => slice,
-                               None => return,
-                       }
-               }
-       }
-
-       macro_rules! get_pubkey {
-               () => {
-                       match PublicKey::from_slice(get_slice!(33)) {
-                               Ok(key) => key,
-                               Err(_) => return,
-                       }
-               }
-       }
-
-       let our_network_key = match SecretKey::from_slice(get_slice!(32)) {
-               Ok(key) => key,
-               Err(_) => return,
-       };
-
-       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 keys_manager = Arc::new(KeyProvider { node_secret: our_network_key.clone(), counter: AtomicU64::new(0) });
-       let mut config = UserConfig::new();
-       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 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]);
-       let mut loss_detector = MoneyLossDetector::new(&peers, channelmanager.clone(), monitor.clone(), PeerManager::new(MessageHandler {
-               chan_handler: channelmanager.clone(),
-               route_handler: router.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;
-       let mut payments_received: Vec<(PaymentHash, u64)> = Vec::new();
-       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] {
-                       0 => {
-                               let mut new_id = 0;
-                               for i in 1..256 {
-                                       if !peers.borrow()[i-1] {
-                                               new_id = i;
-                                               break;
-                                       }
-                               }
-                               if new_id == 0 { return; }
-                               loss_detector.handler.new_outbound_connection(get_pubkey!(), Peer{id: (new_id - 1) as u8, peers_connected: &peers}).unwrap();
-                               peers.borrow_mut()[new_id - 1] = true;
-                       },
-                       1 => {
-                               let mut new_id = 0;
-                               for i in 1..256 {
-                                       if !peers.borrow()[i-1] {
-                                               new_id = i;
-                                               break;
-                                       }
-                               }
-                               if new_id == 0 { return; }
-                               loss_detector.handler.new_inbound_connection(Peer{id: (new_id - 1) as u8, peers_connected: &peers}).unwrap();
-                               peers.borrow_mut()[new_id - 1] = true;
-                       },
-                       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});
-                               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()) {
-                                       Ok(res) => assert!(!res),
-                                       Err(_) => { peers.borrow_mut()[peer_id as usize] = false; }
-                               }
-                       },
-                       4 => {
-                               let value = slice_to_be24(get_slice!(3)) as u64;
-                               let route = match router.get_route(&get_pubkey!(), None, &Vec::new(), value, 42) {
-                                       Ok(route) => route,
-                                       Err(_) => return,
-                               };
-                               let mut payment_hash = PaymentHash([0; 32]);
-                               payment_hash.0[0..8].copy_from_slice(&be64_to_array(payments_sent));
-                               let mut sha = Sha256::engine();
-                               sha.input(&payment_hash.0[..]);
-                               payment_hash.0 = Sha256::from_engine(sha).into_inner();
-                               payments_sent += 1;
-                               match channelmanager.send_payment(route, payment_hash) {
-                                       Ok(_) => {},
-                                       Err(_) => return,
-                               }
-                       },
-                       5 => {
-                               let peer_id = get_slice!(1)[0];
-                               if !peers.borrow()[peer_id as usize] { return; }
-                               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; }
-                       },
-                       6 => {
-                               let mut channels = channelmanager.list_channels();
-                               let channel_id = get_slice!(1)[0] as usize;
-                               if channel_id >= channels.len() { return; }
-                               channels.sort_by(|a, b| { a.channel_id.cmp(&b.channel_id) });
-                               if channelmanager.close_channel(&channels[channel_id].channel_id).is_err() { return; }
-                       },
-                       7 => {
-                               if should_forward {
-                                       channelmanager.process_pending_htlc_forwards();
-                                       should_forward = false;
-                               }
-                       },
-                       8 => {
-                               for (payment, amt) in payments_received.drain(..) {
-                                       // SHA256 is defined as XOR of all input bytes placed in the first byte, and 0s
-                                       // for the remaining bytes. Thus, if not all remaining bytes are 0s we cannot
-                                       // fulfill this HTLC, but if they are, we can just take the first byte and
-                                       // place that anywhere in our preimage.
-                                       if &payment.0[1..] != &[0; 31] {
-                                               channelmanager.fail_htlc_backwards(&payment);
-                                       } else {
-                                               let mut payment_preimage = PaymentPreimage([0; 32]);
-                                               payment_preimage.0[0] = payment.0[0];
-                                               channelmanager.claim_funds(payment_preimage, amt);
-                                       }
-                               }
-                       },
-                       9 => {
-                               for (payment, _) in payments_received.drain(..) {
-                                       channelmanager.fail_htlc_backwards(&payment);
-                               }
-                       },
-                       10 => {
-                               'outer_loop: for funding_generation in pending_funding_generation.drain(..) {
-                                       let mut tx = Transaction { version: 0, lock_time: 0, input: Vec::new(), output: vec![TxOut {
-                                                       value: funding_generation.1, script_pubkey: funding_generation.2,
-                                               }] };
-                                       let funding_output = 'search_loop: loop {
-                                               let funding_txid = tx.txid();
-                                               if let None = loss_detector.txids_confirmed.get(&funding_txid) {
-                                                       let outpoint = OutPoint::new(funding_txid, 0);
-                                                       for chan in channelmanager.list_channels() {
-                                                               if chan.channel_id == outpoint.to_channel_id() {
-                                                                       tx.version += 1;
-                                                                       continue 'search_loop;
-                                                               }
-                                                       }
-                                                       break outpoint;
-                                               }
-                                               tx.version += 1;
-                                               if tx.version > 0xff {
-                                                       continue 'outer_loop;
-                                               }
-                                       };
-                                       channelmanager.funding_transaction_generated(&funding_generation.0, funding_output.clone());
-                                       pending_funding_signatures.insert(funding_output, tx);
-                               }
-                       },
-                       11 => {
-                               if !pending_funding_relay.is_empty() {
-                                       loss_detector.connect_block(&pending_funding_relay[..]);
-                                       for _ in 2..100 {
-                                               loss_detector.connect_block(&[]);
-                                       }
-                               }
-                               for tx in pending_funding_relay.drain(..) {
-                                       loss_detector.funding_txn.push(tx);
-                               }
-                       },
-                       12 => {
-                               let txlen = slice_to_be16(get_slice!(2));
-                               if txlen == 0 {
-                                       loss_detector.connect_block(&[]);
-                               } else {
-                                       let txres: Result<Transaction, _> = deserialize(get_slice!(txlen));
-                                       if let Ok(tx) = txres {
-                                               loss_detector.connect_block(&[tx]);
-                                       } else {
-                                               return;
-                                       }
-                               }
-                       },
-                       13 => {
-                               loss_detector.disconnect_block();
-                       },
-                       14 => {
-                               let mut channels = channelmanager.list_channels();
-                               let channel_id = get_slice!(1)[0] as usize;
-                               if channel_id >= channels.len() { return; }
-                               channels.sort_by(|a, b| { a.channel_id.cmp(&b.channel_id) });
-                               channelmanager.force_close_channel(&channels[channel_id].channel_id);
-                       },
-                       _ => return,
-               }
-               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, .. } => {
-                                       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, amt } => {
-                                       //TODO: enhance by fetching random amounts from fuzz input?
-                                       payments_received.push((payment_hash, amt));
-                               },
-                               Event::PaymentSent {..} => {},
-                               Event::PaymentFailed {..} => {},
-                               Event::PendingHTLCsForwardable {..} => {
-                                       should_forward = true;
-                               },
-                               Event::SpendableOutputs {..} => {},
-                       }
-               }
-       }
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               let logger: Arc<Logger> = Arc::new(test_logger::TestLogger::new("".to_owned()));
-               do_test(data, &logger);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       let logger: Arc<Logger> = Arc::new(test_logger::TestLogger::new("".to_owned()));
-                       do_test(data, &logger);
-               });
-       }
-}
-
-#[cfg(feature = "libfuzzer_fuzz")]
-#[macro_use] extern crate libfuzzer_sys;
-#[cfg(feature = "libfuzzer_fuzz")]
-fuzz_target!(|data: &[u8]| {
-       let logger: Arc<Logger> = Arc::new(test_logger::TestLogger::new("".to_owned()));
-       do_test(data, &logger);
-});
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       use utils::test_logger;
-       use lightning::util::logger::{Logger, Record};
-       use std::collections::HashMap;
-       use std::sync::{Arc, Mutex};
-
-       #[test]
-       fn duplicate_crash() {
-               let logger: Arc<Logger> = Arc::new(test_logger::TestLogger::new("".to_owned()));
-               super::do_test(&::hex::decode("00").unwrap(), &logger);
-       }
-
-       struct TrackingLogger {
-               /// (module, message) -> count
-               pub lines: Mutex<HashMap<(String, String), usize>>,
-       }
-       impl Logger for TrackingLogger {
-               fn log(&self, record: &Record) {
-                       *self.lines.lock().unwrap().entry((record.module_path.to_string(), format!("{}", record.args))).or_insert(0) += 1;
-                       println!("{:<5} [{} : {}, {}] {}", record.level.to_string(), record.module_path, record.file, record.line, record.args);
-               }
-       }
-
-       #[test]
-       fn test_no_existing_test_breakage() {
-               // To avoid accidentally causing all existing fuzz test cases to be useless by making minor
-               // changes (such as requesting feerate info in a new place), we run a pretty full
-               // step-through with two peers and HTLC forwarding here. Obviously this is pretty finicky,
-               // so this should be updated pretty liberally, but at least we'll know when changes occur.
-               // If nothing else, this test serves as a pretty great initial full_stack_target seed.
-
-               // What each byte represents is broken down below, and then everything is concatenated into
-               // one large test at the end (you want %s/ -.*//g %s/\n\| \|\t\|\///g).
-
-               // Following BOLT 8, lightning message on the wire are: 2-byte encrypted message length + 
-               // 16-byte MAC of the encrypted message length + encrypted Lightning message + 16-byte MAC
-               // of the Lightning message
-               // I.e 2nd inbound read, len 18 : 0006 (encrypted message length) + 03000000000000000000000000000000 (MAC of the encrypted message length)
-               // Len 22 : 0010 00000000 (encrypted lightning message) + 03000000000000000000000000000000 (MAC of the Lightning message)
-
-               // 0000000000000000000000000000000000000000000000000000000000000000 - our network key
-               // 00000000 - fee_proportional_millionths
-               // 01 - announce_channels_publicly
-               //
-               // 00 - new outbound connection with id 0
-               // 030000000000000000000000000000000000000000000000000000000000000000 - peer's pubkey
-               // 030032 - inbound read from peer id 0 of len 50
-               // 00 030000000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - noise act two (0||pubkey||mac)
-               //
-               // 030012 - inbound read from peer id 0 of len 18
-               // 0006 03000000000000000000000000000000 - message header indicating message length 6
-               // 030016 - inbound read from peer id 0 of len 22
-               // 0010 00000000 03000000000000000000000000000000 - init message with no features (type 16) and mac
-               //
-               // 030012 - inbound read from peer id 0 of len 18
-               // 0141 03000000000000000000000000000000 - message header indicating message length 321
-               // 0300fe - inbound read from peer id 0 of len 254
-               // 0020 7500000000000000000000000000000000000000000000000000000000000000 ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679 000000000000c350 0000000000000000 0000000000000222 ffffffffffffffff 0000000000000222 0000000000000000 000000fd 0006 01e3 030000000000000000000000000000000000000000000000000000000000000001 030000000000000000000000000000000000000000000000000000000000000002 030000000000000000000000000000000000000000000000000000000000000003 030000000000000000000000000000000000000000000000000000000000000004 - beginning of open_channel message
-               // 030053 - inbound read from peer id 0 of len 83
-               // 030000000000000000000000000000000000000000000000000000000000000005 030000000000000000000000000000000000000000000000000000000000000000 01 03000000000000000000000000000000 - rest of open_channel and mac
-               //
-               // 00fd00fd00fd - Three feerate requests (all returning min feerate, which our open_channel also uses) (gonna be ingested by FuzzEstimator)
-               // - client should now respond with accept_channel (CHECK 1: type 33 to peer 03000000)
-               //
-               // 030012 - inbound read from peer id 0 of len 18
-               // 0084 03000000000000000000000000000000 - message header indicating message length 132
-               // 030094 - inbound read from peer id 0 of len 148
-               // 0022 ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679 3d00000000000000000000000000000000000000000000000000000000000000 0000 5c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 03000000000000000000000000000000 - funding_created and mac
-               // - client should now respond with funding_signed (CHECK 2: type 35 to peer 03000000)
-               //
-               // 0c005e - connect a block with one transaction of len 94
-               // 020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0150c3000000000000220020ae0000000000000000000000000000000000000000000000000000000000000000000000 - the funding transaction
-               // 0c0000 - connect a block with no transactions
-               // 0c0000 - connect a block with no transactions
-               // 0c0000 - connect a block with no transactions
-               // 0c0000 - connect a block with no transactions
-               // 0c0000 - connect a block with no transactions
-               // 0c0000 - connect a block with no transactions
-               // 0c0000 - connect a block with no transactions
-               // 0c0000 - connect a block with no transactions
-               // 0c0000 - connect a block with no transactions
-               // 0c0000 - connect a block with no transactions
-               // 0c0000 - connect a block with no transactions
-               // 0c0000 - connect a block with no transactions
-               // - by now client should have sent a funding_locked (CHECK 3: SendFundingLocked to 03000000 for chan 3d000000)
-               //
-               // 030012 - inbound read from peer id 0 of len 18
-               // 0043 03000000000000000000000000000000 - message header indicating message length 67
-               // 030053 - inbound read from peer id 0 of len 83
-               // 0024 3d00000000000000000000000000000000000000000000000000000000000000 030100000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - funding_locked and mac
-               //
-               // 01 - new inbound connection with id 1
-               // 030132 - inbound read from peer id 1 of len 50
-               // 0003000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000 - inbound noise act 1
-               // 030142 - inbound read from peer id 1 of len 66
-               // 000302000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003000000000000000000000000000000 - inbound noise act 3
-               //
-               // 030112 - inbound read from peer id 1 of len 18
-               // 0006 01000000000000000000000000000000 - message header indicating message length 6
-               // 030116 - inbound read from peer id 1 of len 22
-               // 0010 00000000 01000000000000000000000000000000 - init message with no features (type 16)
-               //
-               // 05 01 030200000000000000000000000000000000000000000000000000000000000000 00c350 0003e8 - create outbound channel to peer 1 for 50k sat
-               // 00fd00fd00fd - Three feerate requests (all returning min feerate) (gonna be ingested by FuzzEstimator)
-               //
-               // 030112 - inbound read from peer id 1 of len 18
-               // 0110 01000000000000000000000000000000 - message header indicating message length 272
-               // 0301ff - inbound read from peer id 1 of len 255
-               // 0021 0000000000000000000000000000000000000000000000000000000000000e02 000000000000001a 00000000004c4b40 00000000000003e8 00000000000003e8 00000002 03f0 0005 030000000000000000000000000000000000000000000000000000000000000100 030000000000000000000000000000000000000000000000000000000000000200 030000000000000000000000000000000000000000000000000000000000000300 030000000000000000000000000000000000000000000000000000000000000400 030000000000000000000000000000000000000000000000000000000000000500 03000000000000000000000000000000 - beginning of accept_channel
-               // 030121 - inbound read from peer id 1 of len 33
-               // 0000000000000000000000000000000000 01000000000000000000000000000000 - rest of accept_channel and mac
-               //
-               // 0a - create the funding transaction (client should send funding_created now)
-               //
-               // 030112 - inbound read from peer id 1 of len 18
-               // 0062 01000000000000000000000000000000 - message header indicating message length 98
-               // 030172 - inbound read from peer id 1 of len 114
-               // 0023 3900000000000000000000000000000000000000000000000000000000000000 f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100 01000000000000000000000000000000 - funding_signed message and mac
-               //
-               // 0b - broadcast funding transaction
-               // - by now client should have sent a funding_locked (CHECK 4: SendFundingLocked to 03020000 for chan 3f000000)
-               //
-               // 030112 - inbound read from peer id 1 of len 18
-               // 0043 01000000000000000000000000000000 - message header indicating message length 67
-               // 030153 - inbound read from peer id 1 of len 83
-               // 0024 3900000000000000000000000000000000000000000000000000000000000000 030100000000000000000000000000000000000000000000000000000000000000 01000000000000000000000000000000 - funding_locked and mac
-               //
-               // 030012 - inbound read from peer id 0 of len 18
-               // 05ac 03000000000000000000000000000000 - message header indicating message length 1452
-               // 0300ff - inbound read from peer id 0 of len 255
-               // 0080 3d00000000000000000000000000000000000000000000000000000000000000 0000000000000000 0000000000003e80 ff00000000000000000000000000000000000000000000000000000000000000 00000121 00 030000000000000000000000000000000000000000000000000000000000000555 0000000e000001000000000000000003e8000000010000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - beginning of update_add_htlc from 0 to 1 via client
-               // 0300ff - inbound read from peer id 0 of len 255
-               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-               // 0300ff - inbound read from peer id 0 of len 255
-               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-               // 0300ff - inbound read from peer id 0 of len 255
-               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-               // 0300ff - inbound read from peer id 0 of len 255
-               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-               // 0300c1 - inbound read from peer id 0 of len 193
-               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ef00000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - end of update_add_htlc from 0 to 1 via client and mac
-               //
-               // 00fd - A feerate request (returning min feerate, which our open_channel also uses) (gonna be ingested by FuzzEstimator)
-               //
-               // 030012 - inbound read from peer id 0 of len 18
-               // 0064 03000000000000000000000000000000 - message header indicating message length 100
-               // 030074 - inbound read from peer id 0 of len 116
-               // 0084 3d00000000000000000000000000000000000000000000000000000000000000 4d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 0000 03000000000000000000000000000000 - commitment_signed and mac
-               // - client should now respond with revoke_and_ack and commitment_signed (CHECK 5/6: types 133 and 132 to peer 03000000)
-               //
-               // 030012 - inbound read from peer id 0 of len 18
-               // 0063 03000000000000000000000000000000 - message header indicating message length 99
-               // 030073 - inbound read from peer id 0 of len 115
-               // 0085 3d00000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 030200000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - revoke_and_ack and mac
-               //
-               // 07 - process the now-pending HTLC forward
-               // - client now sends id 1 update_add_htlc and commitment_signed (CHECK 7: SendHTLCs event for node 03020000 with 1 HTLCs for channel 3f000000)
-               //
-               // - we respond with commitment_signed then revoke_and_ack (a weird, but valid, order)
-               // 030112 - inbound read from peer id 1 of len 18
-               // 0064 01000000000000000000000000000000 - message header indicating message length 100
-               // 030174 - inbound read from peer id 1 of len 116
-               // 0084 3900000000000000000000000000000000000000000000000000000000000000 f1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100 0000 01000000000000000000000000000000 - commitment_signed and mac
-               //
-               // 030112 - inbound read from peer id 1 of len 18
-               // 0063 01000000000000000000000000000000 - message header indicating message length 99
-               // 030173 - inbound read from peer id 1 of len 115
-               // 0085 3900000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 030200000000000000000000000000000000000000000000000000000000000000 01000000000000000000000000000000 - revoke_and_ack and mac
-               //
-               // 030112 - inbound read from peer id 1 of len 18
-               // 004a 01000000000000000000000000000000 - message header indicating message length 74
-               // 03015a - inbound read from peer id 1 of len 90
-               // 0082 3900000000000000000000000000000000000000000000000000000000000000 0000000000000000 ff00888888888888888888888888888888888888888888888888888888888888 01000000000000000000000000000000 - update_fulfill_htlc and mac
-               // - client should immediately claim the pending HTLC from peer 0 (CHECK 8: SendFulfillHTLCs for node 03000000 with preimage ff00888888 for channel 3d000000)
-               //
-               // 030112 - inbound read from peer id 1 of len 18
-               // 0064 01000000000000000000000000000000 - message header indicating message length 100
-               // 030174 - inbound read from peer id 1 of len 116
-               // 0084 3900000000000000000000000000000000000000000000000000000000000000 fd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100 0000 01000000000000000000000000000000 - commitment_signed and mac
-               //
-               // 030112 - inbound read from peer id 1 of len 18
-               // 0063 01000000000000000000000000000000 - message header indicating message length 99
-               // 030173 - inbound read from peer id 1 of len 115
-               // 0085 3900000000000000000000000000000000000000000000000000000000000000 0100000000000000000000000000000000000000000000000000000000000000 030300000000000000000000000000000000000000000000000000000000000000 01000000000000000000000000000000 - revoke_and_ack and mac
-               //
-               // - before responding to the commitment_signed generated above, send a new HTLC
-               // 030012 - inbound read from peer id 0 of len 18
-               // 05ac 03000000000000000000000000000000 - message header indicating message length 1452
-               // 0300ff - inbound read from peer id 0 of len 255
-               // 0080 3d00000000000000000000000000000000000000000000000000000000000000 0000000000000001 0000000000003e80 ff00000000000000000000000000000000000000000000000000000000000000 00000121 00 030000000000000000000000000000000000000000000000000000000000000555 0000000e000001000000000000000003e8000000010000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - beginning of update_add_htlc from 0 to 1 via client
-               // 0300ff - inbound read from peer id 0 of len 255
-               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-               // 0300ff - inbound read from peer id 0 of len 255
-               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-               // 0300ff - inbound read from peer id 0 of len 255
-               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-               // 0300ff - inbound read from peer id 0 of len 255
-               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-               // 0300c1 - inbound read from peer id 0 of len 193
-               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ef00000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - end of update_add_htlc from 0 to 1 via client and mac
-               //
-               // 00fd - A feerate request (returning min feerate, which our open_channel also uses) (gonna be ingested by FuzzEstimator)
-               //
-               // - now respond to the update_fulfill_htlc+commitment_signed messages the client sent to peer 0
-               // 030012 - inbound read from peer id 0 of len 18
-               // 0063 03000000000000000000000000000000 - message header indicating message length 99
-               // 030073 - inbound read from peer id 0 of len 115
-               // 0085 3d00000000000000000000000000000000000000000000000000000000000000 0100000000000000000000000000000000000000000000000000000000000000 030300000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - revoke_and_ack and mac
-               // - client should now respond with revoke_and_ack and commitment_signed (CHECK 5/6 duplicates)
-               //
-               // 030012 - inbound read from peer id 0 of len 18
-               // 0064 03000000000000000000000000000000 - message header indicating message length 100
-               // 030074 - inbound read from peer id 0 of len 116
-               // 0084 3d00000000000000000000000000000000000000000000000000000000000000 be000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 0000 03000000000000000000000000000000 - commitment_signed and mac
-               //
-               // 030012 - inbound read from peer id 0 of len 18
-               // 0063 03000000000000000000000000000000 - message header indicating message length 99
-               // 030073 - inbound read from peer id 0 of len 115
-               // 0085 3d00000000000000000000000000000000000000000000000000000000000000 0200000000000000000000000000000000000000000000000000000000000000 030400000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - revoke_and_ack and mac
-               //
-               // 07 - process the now-pending HTLC forward
-               // - client now sends id 1 update_add_htlc and commitment_signed (CHECK 7 duplicate)
-               // - we respond with revoke_and_ack, then commitment_signed, then update_fail_htlc
-               //
-               // 030112 - inbound read from peer id 1 of len 18
-               // 0064 01000000000000000000000000000000 - message header indicating message length 100
-               // 030174 - inbound read from peer id 1 of len 116
-               // 0084 3900000000000000000000000000000000000000000000000000000000000000 fc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100 0000 01000000000000000000000000000000 - commitment_signed and mac
-               //
-               // 030112 - inbound read from peer id 1 of len 18
-               // 0063 01000000000000000000000000000000 - message header indicating message length 99
-               // 030173 - inbound read from peer id 1 of len 115
-               // 0085 3900000000000000000000000000000000000000000000000000000000000000 0200000000000000000000000000000000000000000000000000000000000000 030400000000000000000000000000000000000000000000000000000000000000 01000000000000000000000000000000 - revoke_and_ack and mac
-               //
-               // 030112 - inbound read from peer id 1 of len 18
-               // 002c 01000000000000000000000000000000 - message header indicating message length 44
-               // 03013c - inbound read from peer id 1 of len 60
-               // 0083 3900000000000000000000000000000000000000000000000000000000000000 0000000000000001 0000 01000000000000000000000000000000 - update_fail_htlc and mac
-               //
-               // 030112 - inbound read from peer id 1 of len 18
-               // 0064 01000000000000000000000000000000 - message header indicating message length 100
-               // 030174 - inbound read from peer id 1 of len 116
-               // 0084 3900000000000000000000000000000000000000000000000000000000000000 fb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100 0000 01000000000000000000000000000000 - commitment_signed and mac
-               //
-               // 030112 - inbound read from peer id 1 of len 18
-               // 0063 01000000000000000000000000000000 - message header indicating message length 99
-               // 030173 - inbound read from peer id 1 of len 115
-               // 0085 3900000000000000000000000000000000000000000000000000000000000000 0300000000000000000000000000000000000000000000000000000000000000 030500000000000000000000000000000000000000000000000000000000000000 01000000000000000000000000000000 - revoke_and_ack and mac
-               //
-               // 07 - process the now-pending HTLC forward
-               // - client now sends id 0 update_fail_htlc and commitment_signed (CHECK 9)
-               // - now respond to the update_fail_htlc+commitment_signed messages the client sent to peer 0
-               //
-               // 030012 - inbound read from peer id 0 of len 18
-               // 0063 03000000000000000000000000000000 - message header indicating message length 99
-               // 030073 - inbound read from peer id 0 of len 115
-               // 0085 3d00000000000000000000000000000000000000000000000000000000000000 0300000000000000000000000000000000000000000000000000000000000000 030500000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - revoke_and_ack and mac
-               //
-               // 030012 - inbound read from peer id 0 of len 18
-               // 0064 03000000000000000000000000000000 - message header indicating message length 100
-               // 030074 - inbound read from peer id 0 of len 116
-               // 0084 3d00000000000000000000000000000000000000000000000000000000000000 4f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 0000 03000000000000000000000000000000 - commitment_signed and mac
-               // - client should now respond with revoke_and_ack (CHECK 5 duplicate)
-               //
-               // 030012 - inbound read from peer id 0 of len 18
-               // 05ac 03000000000000000000000000000000 - message header indicating message length 1452
-               // 0300ff - inbound read from peer id 0 of len 255
-               // 0080 3d00000000000000000000000000000000000000000000000000000000000000 0000000000000002 00000000000b0838 ff00000000000000000000000000000000000000000000000000000000000000 00000121 00 030000000000000000000000000000000000000000000000000000000000000555 0000000e0000010000000000000003e800000000010000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - beginning of update_add_htlc from 0 to 1 via client
-               // 0300ff - inbound read from peer id 0 of len 255
-               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-               // 0300ff - inbound read from peer id 0 of len 255
-               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-               // 0300ff - inbound read from peer id 0 of len 255
-               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-               // 0300ff - inbound read from peer id 0 of len 255
-               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-               // 0300c1 - inbound read from peer id 0 of len 193
-               // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ef00000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - end of update_add_htlc from 0 to 1 via client and mac
-               //
-               // 00fd - A feerate request (returning min feerate, which our open_channel also uses) (gonna be ingested by FuzzEstimator)
-               //
-               // 030012 - inbound read from peer id 0 of len 18
-               // 00a4 03000000000000000000000000000000 - message header indicating message length 164
-               // 0300b4 - inbound read from peer id 0 of len 180
-               // 0084 3d00000000000000000000000000000000000000000000000000000000000000 07000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 0001 c8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f00000000000000 03000000000000000000000000000000 - commitment_signed and mac
-               // - client should now respond with revoke_and_ack and commitment_signed (CHECK 5/6 duplicates)
-               //
-               // 030012 - inbound read from peer id 0 of len 18
-               // 0063 03000000000000000000000000000000 - message header indicating message length 99
-               // 030073 - inbound read from peer id 0 of len 115
-               // 0085 3d00000000000000000000000000000000000000000000000000000000000000 0400000000000000000000000000000000000000000000000000000000000000 030600000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - revoke_and_ack and mac
-               //
-               // 07 - process the now-pending HTLC forward
-               // - client now sends id 1 update_add_htlc and commitment_signed (CHECK 7 duplicate)
-               //
-               // 0c007d - connect a block with one transaction of len 125
-               // 0200000001390000000000000000000000000000000000000000000000000000000000000000000000000000008002000100000000000022002090000000000000000000000000000000000000000000000000000000000000006cc10000000000001600145c0000000000000000000000000000000000000005000020 - the commitment transaction for channel 3f00000000000000000000000000000000000000000000000000000000000000
-               // 00fd - A feerate request (returning min feerate, which our open_channel also uses) (gonna be ingested by FuzzEstimator)
-               // 00fd - A feerate request (returning min feerate, which our open_channel also uses) (gonna be ingested by FuzzEstimator)
-               // 0c005e - connect a block with one transaction of len 94
-               // 0200000001fd00000000000000000000000000000000000000000000000000000000000000000000000000000000014f00000000000000220020f60000000000000000000000000000000000000000000000000000000000000000000000 - the funding transaction
-               // 0c0000 - connect a block with no transactions
-               // 0c0000 - connect a block with no transactions
-               // 0c0000 - connect a block with no transactions
-               // 0c0000 - connect a block with no transactions
-               // 0c0000 - connect a block with no transactions
-               //
-               // 07 - process the now-pending HTLC forward
-               // - client now fails the HTLC backwards as it was unable to extract the payment preimage (CHECK 9 duplicate and CHECK 10)
-
-               let logger = Arc::new(TrackingLogger { lines: Mutex::new(HashMap::new()) });
-               super::do_test(&::hex::decode("00000000000000000000000000000000000000000000000000000000000000000000000001000300000000000000000000000000000000000000000000000000000000000000000300320003000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000030012000603000000000000000000000000000000030016001000000000030000000000000000000000000000000300120141030000000000000000000000000000000300fe00207500000000000000000000000000000000000000000000000000000000000000ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679000000000000c35000000000000000000000000000000222ffffffffffffffff00000000000002220000000000000000000000fd000601e3030000000000000000000000000000000000000000000000000000000000000001030000000000000000000000000000000000000000000000000000000000000002030000000000000000000000000000000000000000000000000000000000000003030000000000000000000000000000000000000000000000000000000000000004030053030000000000000000000000000000000000000000000000000000000000000005030000000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000fd00fd00fd0300120084030000000000000000000000000000000300940022ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb1819096793d0000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001030000000000000000000000000000000c005e020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0150c3000000000000220020ae00000000000000000000000000000000000000000000000000000000000000000000000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c000003001200430300000000000000000000000000000003005300243d000000000000000000000000000000000000000000000000000000000000000301000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001030132000300000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003014200030200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000300000000000000000000000000000003011200060100000000000000000000000000000003011600100000000001000000000000000000000000000000050103020000000000000000000000000000000000000000000000000000000000000000c3500003e800fd00fd00fd0301120110010000000000000000000000000000000301ff00210000000000000000000000000000000000000000000000000000000000000e02000000000000001a00000000004c4b4000000000000003e800000000000003e80000000203f00005030000000000000000000000000000000000000000000000000000000000000100030000000000000000000000000000000000000000000000000000000000000200030000000000000000000000000000000000000000000000000000000000000300030000000000000000000000000000000000000000000000000000000000000400030000000000000000000000000000000000000000000000000000000000000500030000000000000000000000000000000301210000000000000000000000000000000000010000000000000000000000000000000a03011200620100000000000000000000000000000003017200233900000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100010000000000000000000000000000000b030112004301000000000000000000000000000000030153002439000000000000000000000000000000000000000000000000000000000000000301000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e80ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000003e8000000010000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000004d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000f100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112004a0100000000000000000000000000000003015a008239000000000000000000000000000000000000000000000000000000000000000000000000000000ff008888888888888888888888888888888888888888888888888888888888880100000000000000000000000000000003011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000fd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000010000000000000000000000000000000301120063010000000000000000000000000000000301730085390000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000303000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000010000000000003e80ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000003e8000000010000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200630300000000000000000000000000000003007300853d0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000303000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d00000000000000000000000000000000000000000000000000000000000000be00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030400000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000fc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003040000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112002c0100000000000000000000000000000003013c00833900000000000000000000000000000000000000000000000000000000000000000000000000000100000100000000000000000000000000000003011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000fb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000001000000000000000000000000000000030112006301000000000000000000000000000000030173008539000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000030500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000703001200630300000000000000000000000000000003007300853d0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000305000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000004f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d00000000000000000000000000000000000000000000000000000000000000000000000000000200000000000b0838ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e0000010000000000000003e800000000010000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200a4030000000000000000000000000000000300b400843d00000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001c8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f000000000000000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000003060000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000070c007d0200000001390000000000000000000000000000000000000000000000000000000000000000000000000000008002000100000000000022002090000000000000000000000000000000000000000000000000000000000000006cc10000000000001600145c000000000000000000000000000000000000000500002000fd00fd0c005e0200000001fd00000000000000000000000000000000000000000000000000000000000000000000000000000000014f00000000000000220020f600000000000000000000000000000000000000000000000000000000000000000000000c00000c00000c00000c00000c000007").unwrap(), &(Arc::clone(&logger) as Arc<Logger>));
-
-               let log_entries = logger.lines.lock().unwrap();
-               assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendAcceptChannel event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679".to_string())), Some(&1)); // 1
-               assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendFundingSigned event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 2
-               assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendFundingLocked event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 3
-               assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendFundingLocked event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 for channel 3900000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 4
-               assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendRevokeAndACK event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&4)); // 5
-               assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 with 0 adds, 0 fulfills, 0 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&3)); // 6
-               assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 with 1 adds, 0 fulfills, 0 fails for channel 3900000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&3)); // 7
-               assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 with 0 adds, 1 fulfills, 0 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 8
-               assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 with 0 adds, 0 fulfills, 1 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&2)); // 9
-               assert_eq!(log_entries.get(&("lightning::ln::channelmonitor".to_string(), "Input spending remote commitment tx (00000000000000000000000000000000000000000000000000000000000000fd:0) in 0000000000000000000000000000000000000000000000000000000000000044 resolves outbound HTLC with payment hash ff00000000000000000000000000000000000000000000000000000000000000 with timeout".to_string())), Some(&1)); // 10
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/gen_target.sh b/lightning/fuzz/fuzz_targets/msg_targets/gen_target.sh
deleted file mode 100755 (executable)
index cfd100f..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/sh
-
-GEN_TEST() {
-       tn=$(echo $1 | sed 's/\([a-z0-9]\)\([A-Z]\)/\1_\2/g')
-       fn=msg_$(echo $tn | tr '[:upper:]' '[:lower:]')_target.rs
-       cat msg_target_template.txt | sed s/MSG_TARGET/$1/ | sed "s/TEST_MSG/$2/" | sed "s/EXTRA_ARGS/$3/" > $fn
-}
-
-GEN_TEST AcceptChannel test_msg ""
-GEN_TEST AnnouncementSignatures test_msg ""
-GEN_TEST ChannelReestablish test_msg ""
-GEN_TEST ClosingSigned test_msg ""
-GEN_TEST CommitmentSigned test_msg ""
-GEN_TEST DecodedOnionErrorPacket test_msg ""
-GEN_TEST FundingCreated test_msg ""
-GEN_TEST FundingLocked test_msg ""
-GEN_TEST FundingSigned test_msg ""
-GEN_TEST Init test_msg ""
-GEN_TEST OpenChannel test_msg ""
-GEN_TEST RevokeAndACK test_msg ""
-GEN_TEST Shutdown test_msg ""
-GEN_TEST UpdateFailHTLC test_msg ""
-GEN_TEST UpdateFailMalformedHTLC test_msg ""
-GEN_TEST UpdateFee test_msg ""
-GEN_TEST UpdateFulfillHTLC test_msg ""
-
-GEN_TEST ChannelAnnouncement test_msg_exact ""
-GEN_TEST ChannelUpdate test_msg_exact ""
-GEN_TEST NodeAnnouncement test_msg_exact ""
-
-GEN_TEST UpdateAddHTLC test_msg_hole ", 85, 33"
-GEN_TEST ErrorMessage test_msg_hole ", 32, 2"
-GEN_TEST OnionHopData test_msg_hole ", 1+8+8+4, 12"
-
-GEN_TEST Ping test_msg_simple ""
-GEN_TEST Pong test_msg_simple ""
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_accept_channel_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_accept_channel_target.rs
deleted file mode 100644 (file)
index 0f18d02..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg!(msgs::AcceptChannel, data);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_announcement_signatures_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_announcement_signatures_target.rs
deleted file mode 100644 (file)
index 226028e..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg!(msgs::AnnouncementSignatures, data);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_channel_announcement_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_channel_announcement_target.rs
deleted file mode 100644 (file)
index 0bdc10e..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg_exact!(msgs::ChannelAnnouncement, data);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_channel_reestablish_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_channel_reestablish_target.rs
deleted file mode 100644 (file)
index 4af5937..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg!(msgs::ChannelReestablish, data);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_channel_update_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_channel_update_target.rs
deleted file mode 100644 (file)
index 724dca4..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg_exact!(msgs::ChannelUpdate, data);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_closing_signed_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_closing_signed_target.rs
deleted file mode 100644 (file)
index faeeae3..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg!(msgs::ClosingSigned, data);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_commitment_signed_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_commitment_signed_target.rs
deleted file mode 100644 (file)
index 97c4b30..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg!(msgs::CommitmentSigned, data);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_decoded_onion_error_packet_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_decoded_onion_error_packet_target.rs
deleted file mode 100644 (file)
index 9b190b0..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg!(msgs::DecodedOnionErrorPacket, data);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_error_message_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_error_message_target.rs
deleted file mode 100644 (file)
index d749dc9..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg_hole!(msgs::ErrorMessage, data, 32, 2);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_funding_created_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_funding_created_target.rs
deleted file mode 100644 (file)
index 45b257b..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg!(msgs::FundingCreated, data);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_funding_locked_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_funding_locked_target.rs
deleted file mode 100644 (file)
index cd1e897..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg!(msgs::FundingLocked, data);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_funding_signed_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_funding_signed_target.rs
deleted file mode 100644 (file)
index 5992d69..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg!(msgs::FundingSigned, data);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_init_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_init_target.rs
deleted file mode 100644 (file)
index cdca848..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg!(msgs::Init, data);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_node_announcement_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_node_announcement_target.rs
deleted file mode 100644 (file)
index f0a7a4c..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg_exact!(msgs::NodeAnnouncement, data);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_onion_hop_data_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_onion_hop_data_target.rs
deleted file mode 100644 (file)
index 058c050..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg_hole!(msgs::OnionHopData, data, 1+8+8+4, 12);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_open_channel_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_open_channel_target.rs
deleted file mode 100644 (file)
index aa13e96..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg!(msgs::OpenChannel, data);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_ping_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_ping_target.rs
deleted file mode 100644 (file)
index d2ea913..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg_simple!(msgs::Ping, data);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_pong_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_pong_target.rs
deleted file mode 100644 (file)
index 18120e2..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg_simple!(msgs::Pong, data);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_revoke_and_ack_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_revoke_and_ack_target.rs
deleted file mode 100644 (file)
index d82268d..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg!(msgs::RevokeAndACK, data);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_shutdown_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_shutdown_target.rs
deleted file mode 100644 (file)
index 34d4d20..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg!(msgs::Shutdown, data);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_target_template.txt b/lightning/fuzz/fuzz_targets/msg_targets/msg_target_template.txt
deleted file mode 100644 (file)
index 2704bcd..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       TEST_MSG!(msgs::MSG_TARGET, dataEXTRA_ARGS);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_update_add_htlc_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_update_add_htlc_target.rs
deleted file mode 100644 (file)
index e64a5c2..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg_hole!(msgs::UpdateAddHTLC, data, 85, 33);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_update_fail_htlc_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_update_fail_htlc_target.rs
deleted file mode 100644 (file)
index fedce56..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg!(msgs::UpdateFailHTLC, data);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_update_fail_malformed_htlc_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_update_fail_malformed_htlc_target.rs
deleted file mode 100644 (file)
index 377378f..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg!(msgs::UpdateFailMalformedHTLC, data);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_update_fee_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_update_fee_target.rs
deleted file mode 100644 (file)
index 56b9ac4..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg!(msgs::UpdateFee, data);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/msg_update_fulfill_htlc_target.rs b/lightning/fuzz/fuzz_targets/msg_targets/msg_update_fulfill_htlc_target.rs
deleted file mode 100644 (file)
index f0c936d..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// This file is auto-generated by gen_target.sh based on msg_target_template.txt
-// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
-
-extern crate lightning;
-
-use lightning::ln::msgs;
-
-mod utils;
-use utils::VecWriter;
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       test_msg!(msgs::UpdateFulfillHTLC, data);
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/msg_targets/utils.rs b/lightning/fuzz/fuzz_targets/msg_targets/utils.rs
deleted file mode 100644 (file)
index a5257ba..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-#![macro_use]
-
-use lightning::util::ser::Writer;
-pub struct VecWriter(pub Vec<u8>);
-impl Writer for VecWriter {
-       fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
-               assert!(self.0.capacity() >= self.0.len() + buf.len());
-               self.0.extend_from_slice(buf);
-               Ok(())
-       }
-       fn size_hint(&mut self, size: usize) {
-               self.0.reserve_exact(size);
-       }
-}
-
-#[macro_export]
-macro_rules! test_msg {
-       ($MsgType: path, $data: ident) => {
-               {
-                       use lightning::util::ser::{Writeable, Readable};
-                       let mut r = ::std::io::Cursor::new($data);
-                       if let Ok(msg) = <$MsgType as Readable<::std::io::Cursor<&[u8]>>>::read(&mut r) {
-                               let p = r.position() as usize;
-                               let mut w = VecWriter(Vec::new());
-                               msg.write(&mut w).unwrap();
-
-                               assert_eq!(w.0.len(), p);
-                               assert_eq!(&r.into_inner()[..p], &w.0[..p]);
-                       }
-               }
-       }
-}
-
-#[macro_export]
-macro_rules! test_msg_simple {
-       ($MsgType: path, $data: ident) => {
-               {
-                       use lightning::util::ser::{Writeable, Readable};
-                       let mut r = ::std::io::Cursor::new($data);
-                       if let Ok(msg) = <$MsgType as Readable<::std::io::Cursor<&[u8]>>>::read(&mut r) {
-                               let mut w = VecWriter(Vec::new());
-                               msg.write(&mut w).unwrap();
-                       }
-               }
-       }
-}
-
-#[macro_export]
-macro_rules! test_msg_exact {
-       ($MsgType: path, $data: ident) => {
-               {
-                       use lightning::util::ser::{Writeable, Readable};
-                       let mut r = ::std::io::Cursor::new($data);
-                       if let Ok(msg) = <$MsgType as Readable<::std::io::Cursor<&[u8]>>>::read(&mut r) {
-                               let mut w = VecWriter(Vec::new());
-                               msg.write(&mut w).unwrap();
-
-                               assert_eq!(&r.into_inner()[..], &w.0[..]);
-                       }
-               }
-       }
-}
-
-#[macro_export]
-macro_rules! test_msg_hole {
-       ($MsgType: path, $data: ident, $hole: expr, $hole_len: expr) => {
-               {
-                       use lightning::util::ser::{Writeable, Readable};
-                       let mut r = ::std::io::Cursor::new($data);
-                       if let Ok(msg) = <$MsgType as Readable<::std::io::Cursor<&[u8]>>>::read(&mut r) {
-                               let mut w = VecWriter(Vec::new());
-                               msg.write(&mut w).unwrap();
-                               let p = w.0.len() as usize;
-
-                               assert_eq!(w.0.len(), p);
-                               assert_eq!(&r.get_ref()[..$hole], &w.0[..$hole]);
-                               assert_eq!(&r.get_ref()[$hole+$hole_len..p], &w.0[$hole+$hole_len..]);
-                       }
-               }
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/peer_crypt_target.rs b/lightning/fuzz/fuzz_targets/peer_crypt_target.rs
deleted file mode 100644 (file)
index 0b82303..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-extern crate lightning;
-extern crate secp256k1;
-
-use lightning::ln::peer_channel_encryptor::PeerChannelEncryptor;
-
-use secp256k1::key::{PublicKey,SecretKey};
-
-#[inline]
-fn slice_to_be16(v: &[u8]) -> u16 {
-       ((v[0] as u16) << 8*1) |
-       ((v[1] as u16) << 8*0)
-}
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       let mut read_pos = 0;
-       macro_rules! get_slice {
-               ($len: expr) => {
-                       {
-                               let slice_len = $len as usize;
-                               if data.len() < read_pos + slice_len {
-                                       return;
-                               }
-                               read_pos += slice_len;
-                               &data[read_pos - slice_len..read_pos]
-                       }
-               }
-       }
-
-       let our_network_key = match SecretKey::from_slice(get_slice!(32)) {
-               Ok(key) => key,
-               Err(_) => return,
-       };
-       let ephemeral_key = match SecretKey::from_slice(get_slice!(32)) {
-               Ok(key) => key,
-               Err(_) => return,
-       };
-
-       let mut crypter = if get_slice!(1)[0] != 0 {
-               let their_pubkey = match PublicKey::from_slice(get_slice!(33)) {
-                       Ok(key) => key,
-                       Err(_) => return,
-               };
-               let mut crypter = PeerChannelEncryptor::new_outbound(their_pubkey, ephemeral_key);
-               crypter.get_act_one();
-               match crypter.process_act_two(get_slice!(50), &our_network_key) {
-                       Ok(_) => {},
-                       Err(_) => return,
-               }
-               assert!(crypter.is_ready_for_encryption());
-               crypter
-       } else {
-               let mut crypter = PeerChannelEncryptor::new_inbound(&our_network_key);
-               match crypter.process_act_one_with_keys(get_slice!(50), &our_network_key, ephemeral_key) {
-                       Ok(_) => {},
-                       Err(_) => return,
-               }
-               match crypter.process_act_three(get_slice!(66)) {
-                       Ok(_) => {},
-                       Err(_) => return,
-               }
-               assert!(crypter.is_ready_for_encryption());
-               crypter
-       };
-       loop {
-               if get_slice!(1)[0] == 0 {
-                       crypter.encrypt_message(get_slice!(slice_to_be16(get_slice!(2))));
-               } else {
-                       let len = match crypter.decrypt_length_header(get_slice!(16+2)) {
-                               Ok(len) => len,
-                               Err(_) => return,
-                       };
-                       match crypter.decrypt_message(get_slice!(len as usize + 16)) {
-                               Ok(_) => {},
-                               Err(_) => return,
-                       }
-               }
-       }
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("01").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/router_target.rs b/lightning/fuzz/fuzz_targets/router_target.rs
deleted file mode 100644 (file)
index d9a8f78..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-extern crate bitcoin;
-extern crate bitcoin_hashes;
-extern crate lightning;
-extern crate secp256k1;
-
-use bitcoin_hashes::sha256d::Hash as Sha256dHash;
-use bitcoin::blockdata::script::{Script, Builder};
-use bitcoin::blockdata::block::Block;
-use bitcoin::blockdata::transaction::Transaction;
-
-use lightning::chain::chaininterface::{ChainError,ChainWatchInterface};
-use lightning::ln::channelmanager::ChannelDetails;
-use lightning::ln::msgs;
-use lightning::ln::msgs::{RoutingMessageHandler};
-use lightning::ln::router::{Router, RouteHint};
-use lightning::util::logger::Logger;
-use lightning::util::ser::Readable;
-
-use secp256k1::key::PublicKey;
-
-mod utils;
-
-use utils::test_logger;
-
-use std::sync::Arc;
-use std::sync::atomic::{AtomicUsize, Ordering};
-
-#[inline]
-pub fn slice_to_be16(v: &[u8]) -> u16 {
-       ((v[0] as u16) << 8*1) |
-       ((v[1] as u16) << 8*0)
-}
-
-#[inline]
-pub fn slice_to_be32(v: &[u8]) -> u32 {
-       ((v[0] as u32) << 8*3) |
-       ((v[1] as u32) << 8*2) |
-       ((v[2] as u32) << 8*1) |
-       ((v[3] as u32) << 8*0)
-}
-
-#[inline]
-pub fn slice_to_be64(v: &[u8]) -> u64 {
-       ((v[0] as u64) << 8*7) |
-       ((v[1] as u64) << 8*6) |
-       ((v[2] as u64) << 8*5) |
-       ((v[3] as u64) << 8*4) |
-       ((v[4] as u64) << 8*3) |
-       ((v[5] as u64) << 8*2) |
-       ((v[6] as u64) << 8*1) |
-       ((v[7] as u64) << 8*0)
-}
-
-
-struct InputData {
-       data: Vec<u8>,
-       read_pos: AtomicUsize,
-}
-impl InputData {
-       fn get_slice(&self, len: usize) -> Option<&[u8]> {
-               let old_pos = self.read_pos.fetch_add(len, Ordering::AcqRel);
-               if self.data.len() < old_pos + len {
-                       return None;
-               }
-               Some(&self.data[old_pos..old_pos + len])
-       }
-       fn get_slice_nonadvancing(&self, len: usize) -> Option<&[u8]> {
-               let old_pos = self.read_pos.load(Ordering::Acquire);
-               if self.data.len() < old_pos + len {
-                       return None;
-               }
-               Some(&self.data[old_pos..old_pos + len])
-       }
-}
-
-struct DummyChainWatcher {
-       input: Arc<InputData>,
-}
-
-impl ChainWatchInterface for DummyChainWatcher {
-       fn install_watch_tx(&self, _txid: &Sha256dHash, _script_pub_key: &Script) { }
-       fn install_watch_outpoint(&self, _outpoint: (Sha256dHash, u32), _out_script: &Script) { }
-       fn watch_all_txn(&self) { }
-       fn filter_block<'a>(&self, _block: &'a Block) -> (Vec<&'a Transaction>, Vec<u32>) {
-               (Vec::new(), Vec::new())
-       }
-       fn reentered(&self) -> usize { 0 }
-
-       fn get_chain_utxo(&self, _genesis_hash: Sha256dHash, _unspent_tx_output_identifier: u64) -> Result<(Script, u64), ChainError> {
-               match self.input.get_slice(2) {
-                       Some(&[0, _]) => Err(ChainError::NotSupported),
-                       Some(&[1, _]) => Err(ChainError::NotWatched),
-                       Some(&[2, _]) => Err(ChainError::UnknownTx),
-                       Some(&[_, x]) => Ok((Builder::new().push_int(x as i64).into_script().to_v0_p2wsh(), 0)),
-                       None => Err(ChainError::UnknownTx),
-                       _ => unreachable!(),
-               }
-       }
-}
-
-#[inline]
-pub fn do_test(data: &[u8]) {
-       let input = Arc::new(InputData {
-               data: data.to_vec(),
-               read_pos: AtomicUsize::new(0),
-       });
-       macro_rules! get_slice_nonadvancing {
-               ($len: expr) => {
-                       match input.get_slice_nonadvancing($len as usize) {
-                               Some(slice) => slice,
-                               None => return,
-                       }
-               }
-       }
-       macro_rules! get_slice {
-               ($len: expr) => {
-                       match input.get_slice($len as usize) {
-                               Some(slice) => slice,
-                               None => return,
-                       }
-               }
-       }
-
-       macro_rules! decode_msg {
-               ($MsgType: path, $len: expr) => {{
-                       let mut reader = ::std::io::Cursor::new(get_slice!($len));
-                       match <($MsgType)>::read(&mut reader) {
-                               Ok(msg) => msg,
-                               Err(e) => match e {
-                                       msgs::DecodeError::UnknownVersion => return,
-                                       msgs::DecodeError::UnknownRequiredFeature => return,
-                                       msgs::DecodeError::InvalidValue => return,
-                                       msgs::DecodeError::ExtraAddressesPerType => return,
-                                       msgs::DecodeError::BadLengthDescriptor => return,
-                                       msgs::DecodeError::ShortRead => panic!("We picked the length..."),
-                                       msgs::DecodeError::Io(e) => panic!(format!("{}", e)),
-                               }
-                       }
-               }}
-       }
-
-       macro_rules! decode_msg_with_len16 {
-               ($MsgType: path, $begin_len: expr, $excess: expr) => {
-                       {
-                               let extra_len = slice_to_be16(&get_slice_nonadvancing!($begin_len as usize + 2)[$begin_len..$begin_len + 2]);
-                               decode_msg!($MsgType, $begin_len as usize + 2 + (extra_len as usize) + $excess)
-                       }
-               }
-       }
-
-       macro_rules! get_pubkey {
-               () => {
-                       match PublicKey::from_slice(get_slice!(33)) {
-                               Ok(key) => key,
-                               Err(_) => return,
-                       }
-               }
-       }
-
-       let logger: Arc<Logger> = Arc::new(test_logger::TestLogger::new("".to_owned()));
-       let chain_monitor = Arc::new(DummyChainWatcher {
-               input: Arc::clone(&input),
-       });
-
-       let our_pubkey = get_pubkey!();
-       let router = Router::new(our_pubkey.clone(), chain_monitor, Arc::clone(&logger));
-
-       loop {
-               match get_slice!(1)[0] {
-                       0 => {
-                               let start_len = slice_to_be16(&get_slice_nonadvancing!(64 + 2)[64..64 + 2]) as usize;
-                               let addr_len = slice_to_be16(&get_slice_nonadvancing!(64+start_len+2 + 74)[64+start_len+2 + 72..64+start_len+2 + 74]);
-                               if addr_len > (37+1)*4 {
-                                       return;
-                               }
-                               let _ = router.handle_node_announcement(&decode_msg_with_len16!(msgs::NodeAnnouncement, 64, 288));
-                       },
-                       1 => {
-                               let _ = router.handle_channel_announcement(&decode_msg_with_len16!(msgs::ChannelAnnouncement, 64*4, 32+8+33*4));
-                       },
-                       2 => {
-                               let _ = router.handle_channel_update(&decode_msg!(msgs::ChannelUpdate, 128));
-                       },
-                       3 => {
-                               match get_slice!(1)[0] {
-                                       0 => {
-                                               router.handle_htlc_fail_channel_update(&msgs::HTLCFailChannelUpdate::ChannelUpdateMessage {msg: decode_msg!(msgs::ChannelUpdate, 128)});
-                                       },
-                                       1 => {
-                                               let short_channel_id = slice_to_be64(get_slice!(8));
-                                               router.handle_htlc_fail_channel_update(&msgs::HTLCFailChannelUpdate::ChannelClosed {short_channel_id, is_permanent: false});
-                                       },
-                                       _ => return,
-                               }
-                       },
-                       4 => {
-                               let target = get_pubkey!();
-                               let mut first_hops_vec = Vec::new();
-                               let first_hops = match get_slice!(1)[0] {
-                                       0 => None,
-                                       1 => {
-                                               let count = slice_to_be16(get_slice!(2));
-                                               for _ in 0..count {
-                                                       first_hops_vec.push(ChannelDetails {
-                                                               channel_id: [0; 32],
-                                                               short_channel_id: Some(slice_to_be64(get_slice!(8))),
-                                                               remote_network_id: get_pubkey!(),
-                                                               channel_value_satoshis: slice_to_be64(get_slice!(8)),
-                                                               user_id: 0,
-                                                               inbound_capacity_msat: 0,
-                                                               is_live: true,
-                                                               outbound_capacity_msat: 0,
-                                                       });
-                                               }
-                                               Some(&first_hops_vec[..])
-                                       },
-                                       _ => return,
-                               };
-                               let mut last_hops_vec = Vec::new();
-                               let last_hops = {
-                                       let count = slice_to_be16(get_slice!(2));
-                                       for _ in 0..count {
-                                               last_hops_vec.push(RouteHint {
-                                                       src_node_id: get_pubkey!(),
-                                                       short_channel_id: slice_to_be64(get_slice!(8)),
-                                                       fee_base_msat: slice_to_be32(get_slice!(4)),
-                                                       fee_proportional_millionths: slice_to_be32(get_slice!(4)),
-                                                       cltv_expiry_delta: slice_to_be16(get_slice!(2)),
-                                                       htlc_minimum_msat: slice_to_be64(get_slice!(8)),
-                                               });
-                                       }
-                                       &last_hops_vec[..]
-                               };
-                               let _ = router.get_route(&target, first_hops, last_hops, slice_to_be64(get_slice!(8)), slice_to_be32(get_slice!(4)));
-                       },
-                       _ => return,
-               }
-       }
-}
-
-#[cfg(feature = "afl")]
-#[macro_use] extern crate afl;
-#[cfg(feature = "afl")]
-fn main() {
-       fuzz!(|data| {
-               do_test(data);
-       });
-}
-
-#[cfg(feature = "honggfuzz")]
-#[macro_use] extern crate honggfuzz;
-#[cfg(feature = "honggfuzz")]
-fn main() {
-       loop {
-               fuzz!(|data| {
-                       do_test(data);
-               });
-       }
-}
-
-extern crate hex;
-#[cfg(test)]
-mod tests {
-
-       #[test]
-       fn duplicate_crash() {
-               super::do_test(&::hex::decode("00").unwrap());
-       }
-}
diff --git a/lightning/fuzz/fuzz_targets/utils/mod.rs b/lightning/fuzz/fuzz_targets/utils/mod.rs
deleted file mode 100644 (file)
index a7d7c32..0000000
+++ /dev/null
@@ -1 +0,0 @@
-pub(crate) mod test_logger;
diff --git a/lightning/fuzz/fuzz_targets/utils/test_logger.rs b/lightning/fuzz/fuzz_targets/utils/test_logger.rs
deleted file mode 100644 (file)
index 097d001..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-use lightning::util::logger::{Logger, Record};
-pub struct TestLogger {
-       #[cfg(test)]
-       id: String,
-}
-
-impl TestLogger {
-       pub fn new(_id: String) -> TestLogger {
-               TestLogger {
-                       #[cfg(test)]
-                       id: _id
-               }
-       }
-}
-
-impl Logger for TestLogger {
-       fn log(&self, record: &Record) {
-               #[cfg(test)]
-               println!("{:<5} {} [{} : {}, {}] {}", record.level.to_string(), self.id, record.module_path, record.file, record.line, record.args);
-               #[cfg(not(test))]
-               let _ = format!("{}", record.args);
-       }
-}
diff --git a/lightning/fuzz/travis-fuzz.sh b/lightning/fuzz/travis-fuzz.sh
deleted file mode 100755 (executable)
index e602e95..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash
-set -e
-
-pushd fuzz_targets/msg_targets
-rm *_target.rs
-./gen_target.sh
-[ "$(git diff)" != "" ] && exit 1
-popd
-
-cargo install --force honggfuzz
-for TARGET in fuzz_targets/*.rs fuzz_targets/msg_targets/*_target.rs; do
-       FILENAME=$(basename $TARGET)
-       FILE="${FILENAME%.*}"
-       HFUZZ_RUN_ARGS="--exit_upon_crash -v -n2"
-       if [ "$FILE" = "chanmon_fail_consistency" ]; then
-               HFUZZ_RUN_ARGS="$HFUZZ_RUN_ARGS -F 64 -N100000"
-       else
-               HFUZZ_RUN_ARGS="$HFUZZ_RUN_ARGS -N1000000"
-       fi
-       export HFUZZ_RUN_ARGS
-       HFUZZ_BUILD_ARGS="--features honggfuzz_fuzz" cargo hfuzz run $FILE
-       if [ -f hfuzz_workspace/$FILE/HONGGFUZZ.REPORT.TXT ]; then
-               cat hfuzz_workspace/$FILE/HONGGFUZZ.REPORT.TXT
-               for CASE in hfuzz_workspace/$FILE/SIG*; do
-                       cat $CASE | xxd -p
-               done
-               exit 1
-       fi
-done