]> git.bitcoin.ninja Git - rust-lightning/commitdiff
Merge pull request #21 from TheBlueMatt/master
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Thu, 26 Apr 2018 15:37:46 +0000 (11:37 -0400)
committerGitHub <noreply@github.com>
Thu, 26 Apr 2018 15:37:46 +0000 (11:37 -0400)
Begin handling errors/tx broadcasts robustly

fuzz/fuzz_targets/channel_target.rs
fuzz/fuzz_targets/full_stack_target.rs
src/ln/chan_utils.rs
src/ln/channel.rs
src/ln/channelmanager.rs
src/ln/channelmonitor.rs
src/ln/msgs.rs
src/ln/peer_handler.rs
src/ln/router.rs
src/util/events.rs
src/util/test_utils.rs

index 20fd4b4352d176df8c8f1749298ce3948354d1a5..2c0da092ed335ead955cfe0e15b9ef16b045c790 100644 (file)
@@ -7,14 +7,14 @@ use bitcoin::blockdata::transaction::{Transaction, TxOut};
 use bitcoin::util::hash::Sha256dHash;
 use bitcoin::network::serialize::{serialize, BitcoinHash};
 
-use lightning::ln::channel::Channel;
+use lightning::ln::channel::{Channel, ChannelKeys};
 use lightning::ln::channelmanager::{HTLCFailReason, PendingForwardHTLCInfo};
 use lightning::ln::msgs;
 use lightning::ln::msgs::MsgDecodable;
 use lightning::chain::chaininterface::{FeeEstimator, ConfirmationTarget};
 use lightning::util::reset_rng_state;
 
-use secp256k1::key::PublicKey;
+use secp256k1::key::{PublicKey, SecretKey};
 use secp256k1::Secp256k1;
 
 use std::sync::atomic::{AtomicUsize,Ordering};
@@ -164,13 +164,29 @@ pub fn do_test(data: &[u8]) {
                }
        }
 
+       macro_rules! chan_keys {
+               () => {
+                       ChannelKeys {
+                               funding_key:               SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 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(),
+                               revocation_base_key:       SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 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(),
+                               payment_base_key:          SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 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(),
+                               delayed_payment_base_key:  SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 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(),
+                               htlc_base_key:             SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 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(),
+                               channel_close_key:         SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 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(),
+                               channel_monitor_claim_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 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(),
+                               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, 0, 0],
+                       }
+               }
+       }
+
        let their_pubkey = get_pubkey!();
 
        let mut tx = Transaction { version: 0, lock_time: 0, input: Vec::new(), output: Vec::new() };
 
        let mut channel = if get_slice!(1)[0] != 0 {
                let chan_value = slice_to_be24(get_slice!(3));
-               let mut chan = Channel::new_outbound(&fee_est, their_pubkey, chan_value, get_slice!(1)[0] == 0, slice_to_be64(get_slice!(8)));
+
+               let mut chan = Channel::new_outbound(&fee_est, chan_keys!(), their_pubkey, chan_value, get_slice!(1)[0] == 0, slice_to_be64(get_slice!(8)));
                chan.get_open_channel(Sha256dHash::from(get_slice!(32)), &fee_est).unwrap();
                let accept_chan = if get_slice!(1)[0] == 0 {
                        decode_msg_with_len16!(msgs::AcceptChannel, 270, 1)
@@ -192,7 +208,7 @@ pub fn do_test(data: &[u8]) {
                } else {
                        decode_msg!(msgs::OpenChannel, 2*32+6*8+4+2*2+6*33+1)
                };
-               let mut chan = match Channel::new_from_req(&fee_est, their_pubkey, &open_chan, slice_to_be64(get_slice!(8)), get_slice!(1)[0] == 0) {
+               let mut chan = match Channel::new_from_req(&fee_est, chan_keys!(), their_pubkey, &open_chan, slice_to_be64(get_slice!(8)), get_slice!(1)[0] == 0) {
                        Ok(chan) => chan,
                        Err(_) => return,
                };
index e36f64206359e1b541a2ba5fc36e0a665acdfd4f..4ae9be413b81ad83c19d7893fb58254309e5a17a 100644 (file)
@@ -15,7 +15,7 @@ use crypto::sha2::Sha256;
 use crypto::digest::Digest;
 
 use lightning::chain::chaininterface::{BroadcasterInterface,ConfirmationTarget,ChainListener,FeeEstimator,ChainWatchInterfaceUtil};
-use lightning::ln::{channelmonitor,msgs};
+use lightning::ln::channelmonitor;
 use lightning::ln::channelmanager::ChannelManager;
 use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor};
 use lightning::ln::router::Router;
@@ -93,7 +93,7 @@ impl FeeEstimator for FuzzEstimator {
 
 struct TestChannelMonitor {}
 impl channelmonitor::ManyChannelMonitor for TestChannelMonitor {
-       fn add_update_monitor(&self, _funding_txo: (Sha256dHash, u16), _monitor: channelmonitor::ChannelMonitor) -> Result<(), msgs::HandleError> {
+       fn add_update_monitor(&self, _funding_txo: (Sha256dHash, u16), _monitor: channelmonitor::ChannelMonitor) -> Result<(), channelmonitor::ChannelMonitorUpdateErr> {
                //TODO!
                Ok(())
        }
index 81fa29f554113a5cb156205ab5be351ceb3290fb..45f674377307f362fecac115a4ba90d32c97cf4b 100644 (file)
@@ -1,6 +1,7 @@
 use bitcoin::blockdata::script::{Script,Builder};
 use bitcoin::blockdata::opcodes;
-use bitcoin::util::hash::Hash160;
+use bitcoin::blockdata::transaction::{TxIn,TxOut,Transaction};
+use bitcoin::util::hash::{Hash160,Sha256dHash};
 
 use secp256k1::key::{PublicKey,SecretKey};
 use secp256k1::Secp256k1;
@@ -11,6 +12,9 @@ use crypto::ripemd160::Ripemd160;
 
 use util::sha2::Sha256;
 
+pub const HTLC_SUCCESS_TX_WEIGHT: u64 = 703;
+pub const HTLC_TIMEOUT_TX_WEIGHT: u64 = 663;
+
 // Various functions for key derivation and transaction creation for use within channels. Primarily
 // used in Channel and ChannelMonitor.
 
@@ -233,3 +237,33 @@ pub fn get_htlc_redeemscript_with_explicit_keys(htlc: &HTLCOutputInCommitment, a
 pub fn get_htlc_redeemscript(htlc: &HTLCOutputInCommitment, keys: &TxCreationKeys) -> Script {
        get_htlc_redeemscript_with_explicit_keys(htlc, &keys.a_htlc_key, &keys.b_htlc_key, &keys.revocation_key)
 }
+
+pub fn build_htlc_transaction(prev_hash: &Sha256dHash, feerate_per_kw: u64, to_self_delay: u16, htlc: &HTLCOutputInCommitment, a_delayed_payment_key: &PublicKey, revocation_key: &PublicKey) -> Transaction {
+       let mut txins: Vec<TxIn> = Vec::new();
+       txins.push(TxIn {
+               prev_hash: prev_hash.clone(),
+               prev_index: htlc.transaction_output_index,
+               script_sig: Script::new(),
+               sequence: 0,
+               witness: Vec::new(),
+       });
+
+       let total_fee = if htlc.offered {
+                       feerate_per_kw * HTLC_TIMEOUT_TX_WEIGHT / 1000
+               } else {
+                       feerate_per_kw * HTLC_SUCCESS_TX_WEIGHT / 1000
+               };
+
+       let mut txouts: Vec<TxOut> = Vec::new();
+       txouts.push(TxOut {
+               script_pubkey: get_revokeable_redeemscript(revocation_key, to_self_delay, a_delayed_payment_key).to_v0_p2wsh(),
+               value: htlc.amount_msat / 1000 - total_fee //TODO: BOLT 3 does not specify if we should add amount_msat before dividing or if we should divide by 1000 before subtracting (as we do here)
+       });
+
+       Transaction {
+               version: 2,
+               lock_time: if htlc.offered { htlc.cltv_expiry } else { 0 },
+               input: txins,
+               output: txouts,
+       }
+}
index 067b2bc530dd1ae551c324f65318197421466ab1..7c9e69074e9848e9ffa461225518c598bd76641e 100644 (file)
@@ -18,7 +18,7 @@ use ln::msgs;
 use ln::msgs::{HandleError, MsgEncodable};
 use ln::channelmonitor::ChannelMonitor;
 use ln::channelmanager::{PendingForwardHTLCInfo, HTLCFailReason};
-use ln::chan_utils::{TxCreationKeys,HTLCOutputInCommitment};
+use ln::chan_utils::{TxCreationKeys,HTLCOutputInCommitment,HTLC_SUCCESS_TX_WEIGHT,HTLC_TIMEOUT_TX_WEIGHT};
 use ln::chan_utils;
 use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
 use util::{transaction_utils,rng};
@@ -254,6 +254,12 @@ pub struct Channel {
        channel_update_count: u32,
        feerate_per_kw: u64,
 
+       #[cfg(test)]
+       // Used in ChannelManager's tests to send a revoked transaction
+       pub last_local_commitment_txn: Vec<Transaction>,
+       #[cfg(not(test))]
+       last_local_commitment_txn: Vec<Transaction>,
+
        last_sent_closing_fee: Option<(u64, u64)>, // (feerate, fee)
 
        /// The hash of the block in which the funding transaction reached our CONF_TARGET. We use this
@@ -307,8 +313,6 @@ const BREAKDOWN_TIMEOUT: u16 = 6 * 24 * 7; //TODO?
 const MAX_LOCAL_BREAKDOWN_TIMEOUT: u16 = 6 * 24 * 14;
 const COMMITMENT_TX_BASE_WEIGHT: u64 = 724;
 const COMMITMENT_TX_WEIGHT_PER_HTLC: u64 = 172;
-const HTLC_SUCCESS_TX_WEIGHT: u64 = 703;
-const HTLC_TIMEOUT_TX_WEIGHT: u64 = 663;
 const SPENDING_INPUT_FOR_A_OUTPUT_WEIGHT: u64 = 79; // prevout: 36, nSequence: 4, script len: 1, witness lengths: (3+1)/4, sig: 73/4, if-selector: 1, redeemScript: (6 ops + 2*33 pubkeys + 1*2 delay)/4
 const B_OUTPUT_PLUS_SPENDING_INPUT_WEIGHT: u64 = 104; // prevout: 40, nSequence: 4, script len: 1, witness lengths: 3/4, sig: 73/4, pubkey: 33/4, output: 31 (TODO: Wrong? Useless?)
 
@@ -349,7 +353,7 @@ impl Channel {
        // Constructors:
 
        /// panics if channel_value_satoshis is >= (1 << 24)
-       pub fn new_outbound(fee_estimator: &FeeEstimator, their_node_id: PublicKey, channel_value_satoshis: u64, announce_publicly: bool, user_id: u64) -> Channel {
+       pub fn new_outbound(fee_estimator: &FeeEstimator, chan_keys: ChannelKeys, their_node_id: PublicKey, channel_value_satoshis: u64, announce_publicly: bool, user_id: u64) -> Channel {
                if channel_value_satoshis >= (1 << 24) {
                        panic!("funding value > 2^24");
                }
@@ -357,19 +361,12 @@ impl Channel {
                let feerate = fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::Normal);
                let background_feerate = fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::Background);
 
-               let mut key_seed = [0u8; 32];
-               rng::fill_bytes(&mut key_seed);
-               let chan_keys = match ChannelKeys::new_from_seed(&key_seed) {
-                       Ok(key) => key,
-                       Err(_) => panic!("RNG is busted!")
-               };
-
                let secp_ctx = Secp256k1::new();
                let our_channel_monitor_claim_key_hash = Hash160::from_data(&PublicKey::from_secret_key(&secp_ctx, &chan_keys.channel_monitor_claim_key).unwrap().serialize());
                let our_channel_monitor_claim_script = Builder::new().push_opcode(opcodes::All::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script();
                let channel_monitor = ChannelMonitor::new(&chan_keys.revocation_base_key,
                                                          &PublicKey::from_secret_key(&secp_ctx, &chan_keys.delayed_payment_base_key).unwrap(),
-                                                         &PublicKey::from_secret_key(&secp_ctx, &chan_keys.htlc_base_key).unwrap(),
+                                                         &chan_keys.htlc_base_key,
                                                          BREAKDOWN_TIMEOUT, our_channel_monitor_claim_script);
 
                Channel {
@@ -390,7 +387,9 @@ impl Channel {
                        holding_cell_htlc_updates: Vec::new(),
                        next_local_htlc_id: 0,
                        next_remote_htlc_id: 0,
-                       channel_update_count: 0,
+                       channel_update_count: 1,
+
+                       last_local_commitment_txn: Vec::new(),
 
                        last_sent_closing_fee: None,
 
@@ -439,7 +438,7 @@ impl Channel {
        /// Assumes chain_hash has already been checked and corresponds with what we expect!
        /// Generally prefers to take the DisconnectPeer action on failure, as a notice to the sender
        /// that we're rejecting the new channel.
-       pub fn new_from_req(fee_estimator: &FeeEstimator, their_node_id: PublicKey, msg: &msgs::OpenChannel, user_id: u64, announce_publicly: bool) -> Result<Channel, HandleError> {
+       pub fn new_from_req(fee_estimator: &FeeEstimator, chan_keys: ChannelKeys, their_node_id: PublicKey, msg: &msgs::OpenChannel, user_id: u64, announce_publicly: bool) -> Result<Channel, HandleError> {
                // Check sanity of message fields:
                if msg.funding_satoshis >= (1 << 24) {
                        return Err(HandleError{err: "funding value > 2^24", msg: Some(msgs::ErrorAction::DisconnectPeer{})});
@@ -479,21 +478,15 @@ impl Channel {
 
                let background_feerate = fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::Background);
 
-               let mut key_seed = [0u8; 32];
-               rng::fill_bytes(&mut key_seed);
-               let chan_keys = match ChannelKeys::new_from_seed(&key_seed) {
-                       Ok(key) => key,
-                       Err(_) => panic!("RNG is busted!")
-               };
-
                let secp_ctx = Secp256k1::new();
                let our_channel_monitor_claim_key_hash = Hash160::from_data(&PublicKey::from_secret_key(&secp_ctx, &chan_keys.channel_monitor_claim_key).unwrap().serialize());
                let our_channel_monitor_claim_script = Builder::new().push_opcode(opcodes::All::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script();
                let mut channel_monitor = ChannelMonitor::new(&chan_keys.revocation_base_key,
                                                          &PublicKey::from_secret_key(&secp_ctx, &chan_keys.delayed_payment_base_key).unwrap(),
-                                                         &PublicKey::from_secret_key(&secp_ctx, &chan_keys.htlc_base_key).unwrap(),
+                                                         &chan_keys.htlc_base_key,
                                                          BREAKDOWN_TIMEOUT, our_channel_monitor_claim_script);
                channel_monitor.set_their_htlc_base_key(&msg.htlc_basepoint);
+               channel_monitor.set_their_to_self_delay(msg.to_self_delay);
 
                let mut chan = Channel {
                        user_id: user_id,
@@ -512,7 +505,9 @@ impl Channel {
                        holding_cell_htlc_updates: Vec::new(),
                        next_local_htlc_id: 0,
                        next_remote_htlc_id: 0,
-                       channel_update_count: 0,
+                       channel_update_count: 1,
+
+                       last_local_commitment_txn: Vec::new(),
 
                        last_sent_closing_fee: None,
 
@@ -869,40 +864,25 @@ impl Channel {
        /// @local is used only to convert relevant internal structures which refer to remote vs local
        /// to decide value of outputs and direction of HTLCs.
        fn build_htlc_transaction(&self, prev_hash: &Sha256dHash, htlc: &HTLCOutputInCommitment, local: bool, keys: &TxCreationKeys) -> Transaction {
-               let mut txins: Vec<TxIn> = Vec::new();
-               txins.push(TxIn {
-                       prev_hash: prev_hash.clone(),
-                       prev_index: htlc.transaction_output_index,
-                       script_sig: Script::new(),
-                       sequence: 0,
-                       witness: Vec::new(),
-               });
+               chan_utils::build_htlc_transaction(prev_hash, self.feerate_per_kw, if local { self.their_to_self_delay } else { BREAKDOWN_TIMEOUT }, htlc, &keys.a_delayed_payment_key, &keys.revocation_key)
+       }
 
-               let total_fee = if htlc.offered {
-                               self.feerate_per_kw * HTLC_TIMEOUT_TX_WEIGHT / 1000
-                       } else {
-                               self.feerate_per_kw * HTLC_SUCCESS_TX_WEIGHT / 1000
-                       };
+       fn create_htlc_tx_signature(&self, tx: &Transaction, htlc: &HTLCOutputInCommitment, keys: &TxCreationKeys) -> Result<(Script, Signature, bool), HandleError> {
+               if tx.input.len() != 1 {
+                       panic!("Tried to sign HTLC transaction that had input count != 1!");
+               }
 
-               let mut txouts: Vec<TxOut> = Vec::new();
-               txouts.push(TxOut {
-                       script_pubkey: chan_utils::get_revokeable_redeemscript(&keys.revocation_key,
-                                                                              if local { self.their_to_self_delay } else { BREAKDOWN_TIMEOUT },
-                                                                              &keys.a_delayed_payment_key).to_v0_p2wsh(),
-                       value: htlc.amount_msat / 1000 - total_fee //TODO: BOLT 3 does not specify if we should add amount_msat before dividing or if we should divide by 1000 before subtracting (as we do here)
-               });
+               let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &keys);
 
-               Transaction {
-                       version: 2,
-                       lock_time: if htlc.offered { htlc.cltv_expiry } else { 0 },
-                       input: txins,
-                       output: txouts,
-               }
+               let our_htlc_key = secp_derived_key!(chan_utils::derive_private_key(&self.secp_ctx, &keys.per_commitment_point, &self.local_keys.htlc_base_key));
+               let sighash = Message::from_slice(&bip143::SighashComponents::new(&tx).sighash_all(&tx.input[0], &htlc_redeemscript, htlc.amount_msat / 1000)[..]).unwrap();
+               let is_local_tx = PublicKey::from_secret_key(&self.secp_ctx, &our_htlc_key).unwrap() == keys.a_htlc_key;
+               Ok((htlc_redeemscript, self.secp_ctx.sign(&sighash, &our_htlc_key).unwrap(), is_local_tx))
        }
 
        /// Signs a transaction created by build_htlc_transaction. If the transaction is an
        /// HTLC-Success transaction (ie htlc.offered is false), preimate must be set!
-       fn sign_htlc_transaction(&self, tx: &mut Transaction, their_sig: &Signature, preimage: &Option<[u8; 32]>, htlc: &HTLCOutputInCommitment, keys: &TxCreationKeys) -> Result<(), HandleError> {
+       fn sign_htlc_transaction(&self, tx: &mut Transaction, their_sig: &Signature, preimage: &Option<[u8; 32]>, htlc: &HTLCOutputInCommitment, keys: &TxCreationKeys) -> Result<Signature, HandleError> {
                if tx.input.len() != 1 {
                        panic!("Tried to sign HTLC transaction that had input count != 1!");
                }
@@ -910,13 +890,7 @@ impl Channel {
                        panic!("Tried to re-sign HTLC transaction");
                }
 
-               let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &keys);
-
-               let our_htlc_key = secp_derived_key!(chan_utils::derive_private_key(&self.secp_ctx, &keys.per_commitment_point, &self.local_keys.htlc_base_key));
-               let sighash = Message::from_slice(&bip143::SighashComponents::new(&tx).sighash_all(&tx.input[0], &htlc_redeemscript, htlc.amount_msat / 1000)[..]).unwrap();
-               let our_sig = self.secp_ctx.sign(&sighash, &our_htlc_key).unwrap();
-
-               let local_tx = PublicKey::from_secret_key(&self.secp_ctx, &our_htlc_key).unwrap() == keys.a_htlc_key;
+               let (htlc_redeemscript, our_sig, local_tx) = self.create_htlc_tx_signature(tx, htlc, keys)?;
 
                tx.input[0].witness.push(Vec::new()); // First is the multisig dummy
 
@@ -938,10 +912,10 @@ impl Channel {
 
                tx.input[0].witness.push(htlc_redeemscript.into_vec());
 
-               Ok(())
+               Ok(our_sig)
        }
 
-       pub fn get_update_fulfill_htlc(&mut self, payment_preimage_arg: [u8; 32]) -> Result<Option<msgs::UpdateFulfillHTLC>, HandleError> {
+       pub fn get_update_fulfill_htlc(&mut self, payment_preimage_arg: [u8; 32]) -> Result<Option<(msgs::UpdateFulfillHTLC, ChannelMonitor)>, HandleError> {
                // Either ChannelFunded got set (which means it wont bet unset) or there is no way any
                // caller thought we could have something claimed (cause we wouldn't have accepted in an
                // incoming HTLC anyway). If we got to ShutdownComplete, callers aren't allowed to call us,
@@ -1003,19 +977,21 @@ impl Channel {
                if htlc_amount_msat == 0 {
                        return Err(HandleError{err: "Unable to find a pending HTLC which matched the given payment preimage", msg: None});
                }
-               self.channel_monitor.provide_payment_preimage(&payment_preimage_arg);
+               self.channel_monitor.provide_payment_preimage(&payment_hash_calc, &payment_preimage_arg);
 
-               Ok(Some(msgs::UpdateFulfillHTLC {
+               Ok(Some((msgs::UpdateFulfillHTLC {
                        channel_id: self.channel_id(),
                        htlc_id: htlc_id,
                        payment_preimage: payment_preimage_arg,
-               }))
+               }, self.channel_monitor.clone())))
        }
 
-       pub fn get_update_fulfill_htlc_and_commit(&mut self, payment_preimage: [u8; 32]) -> Result<Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned)>, HandleError> {
+       pub fn get_update_fulfill_htlc_and_commit(&mut self, payment_preimage: [u8; 32]) -> Result<Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned, ChannelMonitor)>, HandleError> {
                match self.get_update_fulfill_htlc(payment_preimage)? {
-                       Some(update_fulfill_htlc) =>
-                               Ok(Some((update_fulfill_htlc, self.send_commitment_no_status_check()?))),
+                       Some(update_fulfill_htlc) => {
+                               let (commitment, monitor_update) = self.send_commitment_no_status_check()?;
+                               Ok(Some((update_fulfill_htlc.0, commitment, monitor_update)))
+                       },
                        None => Ok(None)
                }
        }
@@ -1081,10 +1057,12 @@ impl Channel {
                }))
        }
 
-       pub fn get_update_fail_htlc_and_commit(&mut self, payment_hash: &[u8; 32], err_packet: msgs::OnionErrorPacket) -> Result<Option<(msgs::UpdateFailHTLC, msgs::CommitmentSigned)>, HandleError> {
+       pub fn get_update_fail_htlc_and_commit(&mut self, payment_hash: &[u8; 32], err_packet: msgs::OnionErrorPacket) -> Result<Option<(msgs::UpdateFailHTLC, msgs::CommitmentSigned, ChannelMonitor)>, HandleError> {
                match self.get_update_fail_htlc(payment_hash, err_packet)? {
-                       Some(update_fail_htlc) =>
-                               Ok(Some((update_fail_htlc, self.send_commitment_no_status_check()?))),
+                       Some(update_fail_htlc) => {
+                               let (commitment, monitor_update) = self.send_commitment_no_status_check()?;
+                               Ok(Some((update_fail_htlc, commitment, monitor_update)))
+                       },
                        None => Ok(None)
                }
        }
@@ -1136,6 +1114,7 @@ impl Channel {
 
                let obscure_factor = self.get_commitment_transaction_number_obscure_factor();
                self.channel_monitor.set_commitment_obscure_factor(obscure_factor);
+               self.channel_monitor.set_their_to_self_delay(msg.to_self_delay);
 
                self.channel_state = ChannelState::OurInitSent as u32 | ChannelState::TheirInitSent as u32;
 
@@ -1160,7 +1139,7 @@ impl Channel {
                Ok((remote_initial_commitment_tx, self.secp_ctx.sign(&remote_sighash, &self.local_keys.funding_key).unwrap()))
        }
 
-       pub fn funding_created(&mut self, msg: &msgs::FundingCreated) -> Result<msgs::FundingSigned, HandleError> {
+       pub fn funding_created(&mut self, msg: &msgs::FundingCreated) -> Result<(msgs::FundingSigned, ChannelMonitor), HandleError> {
                if self.channel_outbound {
                        return Err(HandleError{err: "Received funding_created for an outbound channel?", msg: None});
                }
@@ -1174,7 +1153,7 @@ impl Channel {
                self.channel_monitor.set_funding_info(msg.funding_txid, msg.funding_output_index);
 
                let (remote_initial_commitment_tx, our_signature) = match self.funding_created_signature(&msg.signature) {
-                       Ok((remote_initial_commitment_tx, sig)) => (remote_initial_commitment_tx, sig),
+                       Ok(res) => res,
                        Err(e) => {
                                self.channel_monitor.unset_funding_info();
                                return Err(e);
@@ -1183,24 +1162,22 @@ impl Channel {
 
                // Now that we're past error-generating stuff, update our local state:
 
-               //TODO: Determine which tx index in remote_initial_commitment_transaction's outputs
-               //represent a revokeable script!
-               self.channel_monitor.provide_tx_info(&remote_initial_commitment_tx, 0, Vec::new());
+               self.channel_monitor.provide_latest_remote_commitment_tx_info(&remote_initial_commitment_tx, Vec::new());
                self.channel_state = ChannelState::FundingSent as u32;
                let funding_txo = self.channel_monitor.get_funding_txo().unwrap();
                self.channel_id = funding_txo.0.into_be() ^ Uint256::from_u64(funding_txo.1 as u64).unwrap(); //TODO: or le?
                self.cur_remote_commitment_transaction_number -= 1;
                self.cur_local_commitment_transaction_number -= 1;
 
-               Ok(msgs::FundingSigned {
+               Ok((msgs::FundingSigned {
                        channel_id: self.channel_id,
                        signature: our_signature
-               })
+               }, self.channel_monitor.clone()))
        }
 
        /// Handles a funding_signed message from the remote end.
        /// If this call is successful, broadcast the funding transaction (and not before!)
-       pub fn funding_signed(&mut self, msg: &msgs::FundingSigned) -> Result<(), HandleError> {
+       pub fn funding_signed(&mut self, msg: &msgs::FundingSigned) -> Result<ChannelMonitor, HandleError> {
                if !self.channel_outbound {
                        return Err(HandleError{err: "Received funding_signed for an inbound channel?", msg: None});
                }
@@ -1214,16 +1191,19 @@ impl Channel {
                let funding_script = self.get_funding_redeemscript();
 
                let local_keys = self.build_local_transaction_keys(self.cur_local_commitment_transaction_number)?;
-               let local_initial_commitment_tx = self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false).0;
+               let mut local_initial_commitment_tx = self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false).0;
                let local_sighash = Message::from_slice(&bip143::SighashComponents::new(&local_initial_commitment_tx).sighash_all(&local_initial_commitment_tx.input[0], &funding_script, self.channel_value_satoshis)[..]).unwrap();
 
                // They sign the "local" commitment transaction, allowing us to broadcast the tx if we wish.
                secp_call!(self.secp_ctx.verify(&local_sighash, &msg.signature, &self.their_funding_pubkey), "Invalid funding_signed signature from peer");
 
+               self.sign_commitment_transaction(&mut local_initial_commitment_tx, &msg.signature);
+               self.channel_monitor.provide_latest_local_commitment_tx_info(local_initial_commitment_tx.clone(), local_keys, self.feerate_per_kw, Vec::new());
+               self.last_local_commitment_txn = vec![local_initial_commitment_tx];
                self.channel_state = ChannelState::FundingSent as u32;
                self.cur_local_commitment_transaction_number -= 1;
 
-               Ok(())
+               Ok(self.channel_monitor.clone())
        }
 
        pub fn funding_locked(&mut self, msg: &msgs::FundingLocked) -> Result<(), HandleError> {
@@ -1232,6 +1212,7 @@ impl Channel {
                        self.channel_state |= ChannelState::TheirFundingLocked as u32;
                } else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::OurFundingLocked as u32) {
                        self.channel_state = ChannelState::ChannelFunded as u32 | (self.channel_state & BOTH_SIDES_SHUTDOWN_MASK);
+                       self.channel_update_count += 1;
                } else {
                        return Err(HandleError{err: "Peer sent a funding_locked at a strange time", msg: None});
                }
@@ -1329,7 +1310,8 @@ impl Channel {
        }
 
        /// Removes an outbound HTLC which has been commitment_signed by the remote end
-       fn mark_outbound_htlc_removed(&mut self, htlc_id: u64, check_preimage: Option<[u8; 32]>, fail_reason: Option<HTLCFailReason>) -> Result<(), HandleError> {
+       #[inline]
+       fn mark_outbound_htlc_removed(&mut self, htlc_id: u64, check_preimage: Option<[u8; 32]>, fail_reason: Option<HTLCFailReason>) -> Result<[u8; 32], HandleError> {
                for mut htlc in self.pending_htlcs.iter_mut() {
                        if htlc.outbound && htlc.htlc_id == htlc_id {
                                match check_preimage {
@@ -1349,13 +1331,13 @@ impl Channel {
                                } else {
                                        panic!("Got a non-outbound state on an outbound HTLC");
                                }
-                               return Ok(());
+                               return Ok(htlc.payment_hash.clone());
                        }
                }
                Err(HandleError{err: "Remote tried to fulfill/fail an HTLC we couldn't find", msg: None})
        }
 
-       pub fn update_fulfill_htlc(&mut self, msg: &msgs::UpdateFulfillHTLC) -> Result<(), HandleError> {
+       pub fn update_fulfill_htlc(&mut self, msg: &msgs::UpdateFulfillHTLC) -> Result<ChannelMonitor, HandleError> {
                if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) {
                        return Err(HandleError{err: "Got add HTLC message when channel was not in an operational state", msg: None});
                }
@@ -1365,11 +1347,12 @@ impl Channel {
                let mut payment_hash = [0; 32];
                sha.result(&mut payment_hash);
 
-               self.channel_monitor.provide_payment_preimage(&msg.payment_preimage);
-               self.mark_outbound_htlc_removed(msg.htlc_id, Some(payment_hash), None)
+               self.channel_monitor.provide_payment_preimage(&payment_hash, &msg.payment_preimage);
+               self.mark_outbound_htlc_removed(msg.htlc_id, Some(payment_hash), None)?;
+               Ok(self.channel_monitor.clone())
        }
 
-       pub fn update_fail_htlc(&mut self, msg: &msgs::UpdateFailHTLC, fail_reason: HTLCFailReason) -> Result<(), HandleError> {
+       pub fn update_fail_htlc(&mut self, msg: &msgs::UpdateFailHTLC, fail_reason: HTLCFailReason) -> Result<[u8; 32], HandleError> {
                if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) {
                        return Err(HandleError{err: "Got add HTLC message when channel was not in an operational state", msg: None});
                }
@@ -1382,10 +1365,11 @@ impl Channel {
                        return Err(HandleError{err: "Got add HTLC message when channel was not in an operational state", msg: None});
                }
 
-               self.mark_outbound_htlc_removed(msg.htlc_id, None, Some(fail_reason))
+               self.mark_outbound_htlc_removed(msg.htlc_id, None, Some(fail_reason))?;
+               Ok(())
        }
 
-       pub fn commitment_signed(&mut self, msg: &msgs::CommitmentSigned) -> Result<(msgs::RevokeAndACK, Option<msgs::CommitmentSigned>), HandleError> {
+       pub fn commitment_signed(&mut self, msg: &msgs::CommitmentSigned) -> Result<(msgs::RevokeAndACK, Option<msgs::CommitmentSigned>, ChannelMonitor), HandleError> {
                if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) {
                        return Err(HandleError{err: "Got commitment signed message when channel was not in an operational state", msg: None});
                }
@@ -1393,7 +1377,7 @@ impl Channel {
                let funding_script = self.get_funding_redeemscript();
 
                let local_keys = self.build_local_transaction_keys(self.cur_local_commitment_transaction_number)?;
-               let local_commitment_tx = self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false);
+               let mut local_commitment_tx = self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false);
                let local_commitment_txid = local_commitment_tx.0.txid();
                let local_sighash = Message::from_slice(&bip143::SighashComponents::new(&local_commitment_tx.0).sighash_all(&local_commitment_tx.0.input[0], &funding_script, self.channel_value_satoshis)[..]).unwrap();
                secp_call!(self.secp_ctx.verify(&local_sighash, &msg.signature, &self.their_funding_pubkey), "Invalid commitment tx signature from peer");
@@ -1402,17 +1386,31 @@ impl Channel {
                        return Err(HandleError{err: "Got wrong number of HTLC signatures from remote", msg: None});
                }
 
+               let mut new_local_commitment_txn = Vec::with_capacity(local_commitment_tx.1.len() + 1);
+               self.sign_commitment_transaction(&mut local_commitment_tx.0, &msg.signature);
+               new_local_commitment_txn.push(local_commitment_tx.0.clone());
+
+               let mut htlcs_and_sigs = Vec::with_capacity(local_commitment_tx.1.len());
                for (idx, ref htlc) in local_commitment_tx.1.iter().enumerate() {
-                       let htlc_tx = self.build_htlc_transaction(&local_commitment_txid, htlc, true, &local_keys);
+                       let mut htlc_tx = self.build_htlc_transaction(&local_commitment_txid, htlc, true, &local_keys);
                        let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &local_keys);
                        let htlc_sighash = Message::from_slice(&bip143::SighashComponents::new(&htlc_tx).sighash_all(&htlc_tx.input[0], &htlc_redeemscript, htlc.amount_msat / 1000)[..]).unwrap();
                        secp_call!(self.secp_ctx.verify(&htlc_sighash, &msg.htlc_signatures[idx], &local_keys.b_htlc_key), "Invalid HTLC tx siganture from peer");
+                       let htlc_sig = if htlc.offered {
+                               let htlc_sig = self.sign_htlc_transaction(&mut htlc_tx, &msg.htlc_signatures[idx], &None, htlc, &local_keys)?;
+                               new_local_commitment_txn.push(htlc_tx);
+                               htlc_sig
+                       } else {
+                               self.create_htlc_tx_signature(&htlc_tx, htlc, &local_keys)?.1
+                       };
+                       htlcs_and_sigs.push(((*htlc).clone(), msg.htlc_signatures[idx], htlc_sig));
                }
 
                let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number - 1)).unwrap();
                let per_commitment_secret = chan_utils::build_commitment_secret(self.local_keys.commitment_seed, self.cur_local_commitment_transaction_number + 1);
 
                // Update state now that we've passed all the can-fail calls...
+               self.channel_monitor.provide_latest_local_commitment_tx_info(local_commitment_tx.0, local_keys, self.feerate_per_kw, htlcs_and_sigs);
 
                let mut need_our_commitment = false;
                for htlc in self.pending_htlcs.iter_mut() {
@@ -1436,24 +1434,26 @@ impl Channel {
                self.value_to_self_msat += claimed_value_msat;
 
                self.cur_local_commitment_transaction_number -= 1;
+               self.last_local_commitment_txn = new_local_commitment_txn;
 
-               let our_commitment_signed = if need_our_commitment && (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) == 0 {
+               let (our_commitment_signed, monitor_update) = if need_our_commitment && (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) == 0 {
                        // If we're AwaitingRemoteRevoke we can't send a new commitment here, but that's ok -
                        // we'll send one right away when we get the revoke_and_ack when we
                        // free_holding_cell_htlcs().
-                       Some(self.send_commitment_no_status_check()?)
-               } else { None };
+                       let (msg, monitor) = self.send_commitment_no_status_check()?;
+                       (Some(msg), monitor)
+               } else { (None, self.channel_monitor.clone()) };
 
                Ok((msgs::RevokeAndACK {
                        channel_id: self.channel_id,
                        per_commitment_secret: per_commitment_secret,
                        next_per_commitment_point: next_per_commitment_point,
-               }, our_commitment_signed))
+               }, our_commitment_signed, monitor_update))
        }
 
        /// Used to fulfill holding_cell_htlcs when we get a remote ack (or implicitly get it by them
        /// fulfilling or failing the last pending HTLC)
-       fn free_holding_cell_htlcs(&mut self) -> Result<Option<msgs::CommitmentUpdate>, HandleError> {
+       fn free_holding_cell_htlcs(&mut self) -> Result<Option<(msgs::CommitmentUpdate, ChannelMonitor)>, HandleError> {
                if self.holding_cell_htlc_updates.len() != 0 {
                        let mut htlc_updates = Vec::new();
                        mem::swap(&mut htlc_updates, &mut self.holding_cell_htlc_updates);
@@ -1481,7 +1481,7 @@ impl Channel {
                                                },
                                                &HTLCUpdateAwaitingACK::ClaimHTLC { payment_preimage, .. } => {
                                                        match self.get_update_fulfill_htlc(payment_preimage) {
-                                                               Ok(update_fulfill_msg_option) => update_fulfill_htlcs.push(update_fulfill_msg_option.unwrap()),
+                                                               Ok(update_fulfill_msg_option) => update_fulfill_htlcs.push(update_fulfill_msg_option.unwrap().0),
                                                                Err(e) => {
                                                                        err = Some(e);
                                                                }
@@ -1505,12 +1505,13 @@ impl Channel {
                        //fail it back the route, if its a temporary issue we can ignore it...
                        match err {
                                None => {
-                                       Ok(Some(msgs::CommitmentUpdate {
+                                       let (commitment_signed, monitor_update) = self.send_commitment_no_status_check()?;
+                                       Ok(Some((msgs::CommitmentUpdate {
                                                update_add_htlcs,
                                                update_fulfill_htlcs,
                                                update_fail_htlcs,
-                                               commitment_signed: self.send_commitment_no_status_check()?
-                                       }))
+                                               commitment_signed,
+                                       }, monitor_update)))
                                },
                                Some(e) => Err(e)
                        }
@@ -1524,7 +1525,7 @@ impl Channel {
        /// waiting on this revoke_and_ack. The generation of this new commitment_signed may also fail,
        /// generating an appropriate error *after* the channel state has been updated based on the
        /// revoke_and_ack message.
-       pub fn revoke_and_ack(&mut self, msg: &msgs::RevokeAndACK) -> Result<(Option<msgs::CommitmentUpdate>, Vec<PendingForwardHTLCInfo>, Vec<([u8; 32], HTLCFailReason)>), HandleError> {
+       pub fn revoke_and_ack(&mut self, msg: &msgs::RevokeAndACK) -> Result<(Option<msgs::CommitmentUpdate>, Vec<PendingForwardHTLCInfo>, Vec<([u8; 32], HTLCFailReason)>, ChannelMonitor), HandleError> {
                if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) {
                        return Err(HandleError{err: "Got revoke/ACK message when channel was not in an operational state", msg: None});
                }
@@ -1533,7 +1534,7 @@ impl Channel {
                                return Err(HandleError{err: "Got a revoke commitment secret which didn't correspond to their current pubkey", msg: None});
                        }
                }
-               self.channel_monitor.provide_secret(self.cur_remote_commitment_transaction_number + 1, msg.per_commitment_secret)?;
+               self.channel_monitor.provide_secret(self.cur_remote_commitment_transaction_number + 1, msg.per_commitment_secret, Some((self.cur_remote_commitment_transaction_number - 1, msg.next_per_commitment_point)))?;
 
                // Update state now that we've passed all the can-fail calls...
                // (note that we may still fail to generate the new commitment_signed message, but that's
@@ -1583,18 +1584,19 @@ impl Channel {
 
                match self.free_holding_cell_htlcs()? {
                        Some(commitment_update) => {
-                               Ok((Some(commitment_update), to_forward_infos, revoked_htlcs))
+                               Ok((Some(commitment_update.0), to_forward_infos, revoked_htlcs, commitment_update.1))
                        },
                        None => {
                                if require_commitment {
+                                       let (commitment_signed, monitor_update) = self.send_commitment_no_status_check()?;
                                        Ok((Some(msgs::CommitmentUpdate {
                                                update_add_htlcs: Vec::new(),
                                                update_fulfill_htlcs: Vec::new(),
                                                update_fail_htlcs: Vec::new(),
-                                               commitment_signed: self.send_commitment_no_status_check()?
-                                       }), to_forward_infos, revoked_htlcs))
+                                               commitment_signed
+                                       }), to_forward_infos, revoked_htlcs, monitor_update))
                                } else {
-                                       Ok((None, to_forward_infos, revoked_htlcs))
+                                       Ok((None, to_forward_infos, revoked_htlcs, self.channel_monitor.clone()))
                                }
                        }
                }
@@ -1605,6 +1607,7 @@ impl Channel {
                        return Err(HandleError{err: "Non-funding remote tried to update channel fee", msg: None});
                }
                Channel::check_remote_fee(fee_estimator, msg.feerate_per_kw)?;
+               self.channel_update_count += 1;
                self.feerate_per_kw = msg.feerate_per_kw as u64;
                Ok(())
        }
@@ -1612,6 +1615,7 @@ impl Channel {
        pub fn shutdown(&mut self, fee_estimator: &FeeEstimator, msg: &msgs::Shutdown) -> Result<(Option<msgs::Shutdown>, Option<msgs::ClosingSigned>, Vec<[u8; 32]>), HandleError> {
                if self.channel_state < ChannelState::FundingSent as u32 {
                        self.channel_state = ChannelState::ShutdownComplete as u32;
+                       self.channel_update_count += 1;
                        return Ok((None, None, Vec::new()));
                }
                for htlc in self.pending_htlcs.iter() {
@@ -1659,6 +1663,7 @@ impl Channel {
                // From here on out, we may not fail!
 
                self.channel_state |= ChannelState::RemoteShutdownSent as u32;
+               self.channel_update_count += 1;
 
                // We can't send our shutdown until we've committed all of our pending HTLCs, but the
                // remote side is unlikely to accept any new HTLCs, so we go ahead and "free" any holding
@@ -1689,6 +1694,7 @@ impl Channel {
                };
 
                self.channel_state |= ChannelState::LocalShutdownSent as u32;
+               self.channel_update_count += 1;
                if self.pending_htlcs.is_empty() && self.channel_outbound {
                        // There are no more HTLCs and we're the funder, this means we start the closing_signed
                        // dance with an initial fee proposal!
@@ -1736,6 +1742,7 @@ impl Channel {
                        if last_fee == msg.fee_satoshis {
                                self.sign_commitment_transaction(&mut closing_tx, &msg.signature);
                                self.channel_state = ChannelState::ShutdownComplete as u32;
+                               self.channel_update_count += 1;
                                return Ok((None, Some(closing_tx)));
                        }
                }
@@ -1780,6 +1787,7 @@ impl Channel {
 
                let our_sig = self.sign_commitment_transaction(&mut closing_tx, &msg.signature);
                self.channel_state = ChannelState::ShutdownComplete as u32;
+               self.channel_update_count += 1;
 
                Ok((Some(msgs::ClosingSigned {
                        channel_id: self.channel_id,
@@ -1800,6 +1808,13 @@ impl Channel {
                self.user_id
        }
 
+       pub fn channel_monitor(&self) -> ChannelMonitor {
+               if self.channel_state < ChannelState::FundingCreated as u32 {
+                       panic!("Can't get a channel monitor until funding has been created");
+               }
+               self.channel_monitor.clone()
+       }
+
        /// Guaranteed to be Some after both FundingLocked messages have been exchanged (and, thus,
        /// is_usable() returns true).
        pub fn get_short_channel_id(&self) -> Option<u64> {
@@ -1824,8 +1839,7 @@ impl Channel {
                self.channel_value_satoshis
        }
 
-       pub fn get_channel_update_count(&mut self) -> u32 {
-               self.channel_update_count += 1; //TODO: This should be base on updates, not updates *sent*
+       pub fn get_channel_update_count(&self) -> u32 {
                self.channel_update_count
        }
 
@@ -1848,13 +1862,6 @@ impl Channel {
                res as u32
        }
 
-       pub fn channel_monitor(&self) -> ChannelMonitor {
-               if self.channel_state < ChannelState::FundingCreated as u32 {
-                       panic!("Can't get a channel monitor until funding has been created");
-               }
-               self.channel_monitor.clone()
-       }
-
        /// Returns true if this channel is fully established and not known to be closing.
        pub fn is_usable(&self) -> bool {
                let mask = ChannelState::ChannelFunded as u32 | BOTH_SIDES_SHUTDOWN_MASK;
@@ -1891,6 +1898,7 @@ impl Channel {
                                                self.channel_state |= ChannelState::OurFundingLocked as u32;
                                        } else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32) {
                                                self.channel_state = ChannelState::ChannelFunded as u32 | (self.channel_state & BOTH_SIDES_SHUTDOWN_MASK);
+                                               self.channel_update_count += 1;
                                                //TODO: Something about a state where we "lost confirmation"
                                        } else if self.channel_state < ChannelState::ChannelFunded as u32 {
                                                panic!("Started confirming a channel in a state pre-FundingSent?");
@@ -1917,6 +1925,7 @@ impl Channel {
                                        if txo_idx >= tx.output.len() || tx.output[txo_idx].script_pubkey != self.get_funding_redeemscript().to_v0_p2wsh() ||
                                                tx.output[txo_idx].value != self.channel_value_satoshis {
                                                self.channel_state = ChannelState::ShutdownComplete as u32;
+                                               self.channel_update_count += 1;
                                        } else {
                                                self.funding_tx_confirmations = 1;
                                                self.short_channel_id = Some(((height as u64)          << (5*8)) |
@@ -2017,7 +2026,7 @@ impl Channel {
                })
        }
 
-       fn get_outbound_funding_created_signature(&mut self) -> Result<Signature, HandleError> {
+       fn get_outbound_funding_created_signature(&mut self) -> Result<(Signature, Transaction), HandleError> {
                let funding_script = self.get_funding_redeemscript();
 
                let remote_keys = self.build_remote_transaction_keys()?;
@@ -2025,7 +2034,7 @@ impl Channel {
                let remote_sighash = Message::from_slice(&bip143::SighashComponents::new(&remote_initial_commitment_tx).sighash_all(&remote_initial_commitment_tx.input[0], &funding_script, self.channel_value_satoshis)[..]).unwrap();
 
                // We sign the "remote" commitment transaction, allowing them to broadcast the tx if they wish.
-               Ok(self.secp_ctx.sign(&remote_sighash, &self.local_keys.funding_key).unwrap())
+               Ok((self.secp_ctx.sign(&remote_sighash, &self.local_keys.funding_key).unwrap(), remote_initial_commitment_tx))
        }
 
        /// Updates channel state with knowledge of the funding transaction's txid/index, and generates
@@ -2034,7 +2043,7 @@ impl Channel {
        /// or if called on an inbound channel.
        /// Note that channel_id changes during this call!
        /// Do NOT broadcast the funding transaction until after a successful funding_signed call!
-       pub fn get_outbound_funding_created(&mut self, funding_txid: Sha256dHash, funding_output_index: u16) -> Result<msgs::FundingCreated, HandleError> {
+       pub fn get_outbound_funding_created(&mut self, funding_txid: Sha256dHash, funding_output_index: u16) -> Result<(msgs::FundingCreated, ChannelMonitor), HandleError> {
                if !self.channel_outbound {
                        panic!("Tried to create outbound funding_created message on an inbound channel!");
                }
@@ -2047,8 +2056,8 @@ impl Channel {
 
                self.channel_monitor.set_funding_info(funding_txid, funding_output_index);
 
-               let our_signature = match self.get_outbound_funding_created_signature() {
-                       Ok(sig) => sig,
+               let (our_signature, commitment_tx) = match self.get_outbound_funding_created_signature() {
+                       Ok(res) => res,
                        Err(e) => {
                                self.channel_monitor.unset_funding_info();
                                return Err(e);
@@ -2058,18 +2067,18 @@ impl Channel {
                let temporary_channel_id = self.channel_id;
 
                // Now that we're past error-generating stuff, update our local state:
-
+               self.channel_monitor.provide_latest_remote_commitment_tx_info(&commitment_tx, Vec::new());
                self.channel_state = ChannelState::FundingCreated as u32;
                let funding_txo = self.channel_monitor.get_funding_txo().unwrap();
                self.channel_id = funding_txo.0.into_be() ^ Uint256::from_u64(funding_txo.1 as u64).unwrap(); //TODO: or le?
                self.cur_remote_commitment_transaction_number -= 1;
 
-               Ok(msgs::FundingCreated {
+               Ok((msgs::FundingCreated {
                        temporary_channel_id: temporary_channel_id,
                        funding_txid: funding_txid,
                        funding_output_index: funding_output_index,
                        signature: our_signature
-               })
+               }, self.channel_monitor.clone()))
        }
 
        /// Gets an UnsignedChannelAnnouncement, as well as a signature covering it using our
@@ -2181,7 +2190,7 @@ impl Channel {
        }
 
        /// Creates a signed commitment transaction to send to the remote peer.
-       pub fn send_commitment(&mut self) -> Result<msgs::CommitmentSigned, HandleError> {
+       pub fn send_commitment(&mut self) -> Result<(msgs::CommitmentSigned, ChannelMonitor), HandleError> {
                if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) {
                        return Err(HandleError{err: "Cannot create commitment tx until channel is fully established", msg: None});
                }
@@ -2201,7 +2210,7 @@ impl Channel {
                self.send_commitment_no_status_check()
        }
        /// Only fails in case of bad keys
-       fn send_commitment_no_status_check(&mut self) -> Result<msgs::CommitmentSigned, HandleError> {
+       fn send_commitment_no_status_check(&mut self) -> Result<(msgs::CommitmentSigned, ChannelMonitor), HandleError> {
                let funding_script = self.get_funding_redeemscript();
 
                // We can upgrade the status of some HTLCs that are waiting on a commitment, even if we
@@ -2232,23 +2241,26 @@ impl Channel {
                }
 
                // Update state now that we've passed all the can-fail calls...
+               self.channel_monitor.provide_latest_remote_commitment_tx_info(&remote_commitment_tx.0, remote_commitment_tx.1);
                self.channel_state |= ChannelState::AwaitingRemoteRevoke as u32;
 
-               Ok(msgs::CommitmentSigned {
+               Ok((msgs::CommitmentSigned {
                        channel_id: self.channel_id,
                        signature: our_sig,
                        htlc_signatures: htlc_sigs,
-               })
+               }, self.channel_monitor.clone()))
        }
 
        /// Adds a pending outbound HTLC to this channel, and creates a signed commitment transaction
        /// to send to the remote peer in one go.
        /// Shorthand for calling send_htlc() followed by send_commitment(), see docs on those for
        /// more info.
-       pub fn send_htlc_and_commit(&mut self, amount_msat: u64, payment_hash: [u8; 32], cltv_expiry: u32, onion_routing_packet: msgs::OnionPacket) -> Result<Option<(msgs::UpdateAddHTLC, msgs::CommitmentSigned)>, HandleError> {
+       pub fn send_htlc_and_commit(&mut self, amount_msat: u64, payment_hash: [u8; 32], cltv_expiry: u32, onion_routing_packet: msgs::OnionPacket) -> Result<Option<(msgs::UpdateAddHTLC, msgs::CommitmentSigned, ChannelMonitor)>, HandleError> {
                match self.send_htlc(amount_msat, payment_hash, cltv_expiry, onion_routing_packet)? {
-                       Some(update_add_htlc) =>
-                               Ok(Some((update_add_htlc, self.send_commitment_no_status_check()?))),
+                       Some(update_add_htlc) => {
+                               let (commitment_signed, monitor_update) = self.send_commitment_no_status_check()?;
+                               Ok(Some((update_add_htlc, commitment_signed, monitor_update)))
+                       },
                        None => Ok(None)
                }
        }
@@ -2274,6 +2286,7 @@ impl Channel {
                } else {
                        self.channel_state |= ChannelState::LocalShutdownSent as u32;
                }
+               self.channel_update_count += 1;
 
                // We can't send our shutdown until we've committed all of our pending HTLCs, but the
                // remote side is unlikely to accept any new HTLCs, so we go ahead and "free" any holding
@@ -2294,6 +2307,17 @@ impl Channel {
                        scriptpubkey: our_closing_script,
                }, dropped_outbound_htlcs))
        }
+
+       /// Gets the latest commitment transaction and any dependant transactions for relay (forcing
+       /// shutdown of this channel - no more calls into this Channel may be made afterwards.
+       pub fn force_shutdown(&mut self) -> Vec<Transaction> {
+               assert!(self.channel_state != ChannelState::ShutdownComplete as u32);
+               self.channel_state = ChannelState::ShutdownComplete as u32;
+               self.channel_update_count += 1;
+               let mut res = Vec::new();
+               mem::swap(&mut res, &mut self.last_local_commitment_txn);
+               res
+       }
 }
 
 #[cfg(test)]
@@ -2303,7 +2327,7 @@ mod tests {
        use bitcoin::util::bip143;
        use bitcoin::network::serialize::serialize;
        use bitcoin::blockdata::transaction::Transaction;
-       use ln::channel::{Channel,HTLCOutput,HTLCState,HTLCOutputInCommitment,TxCreationKeys};
+       use ln::channel::{Channel,ChannelKeys,HTLCOutput,HTLCState,HTLCOutputInCommitment,TxCreationKeys};
        use ln::chan_utils;
        use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
        use secp256k1::{Secp256k1,Message,Signature};
@@ -2324,20 +2348,26 @@ mod tests {
        fn outbound_commitment_test() {
                // Test vectors from BOLT 3 Appendix C:
                let feeest = TestFeeEstimator{fee_est: 15000/250};
-               let mut chan = Channel::new_outbound(&feeest, PublicKey::new(), 10000000, false, 42); // Nothing uses their network key in this test
-               chan.their_to_self_delay = 144;
-               chan.our_dust_limit_satoshis = 546;
-
                let secp_ctx = Secp256k1::new();
 
-               chan.local_keys.funding_key = SecretKey::from_slice(&secp_ctx, &hex_bytes("30ff4956bbdd3222d44cc5e8a1261dab1e07957bdac5ae88fe3261ef321f3749").unwrap()[..]).unwrap();
-               assert_eq!(PublicKey::from_secret_key(&secp_ctx, &chan.local_keys.funding_key).unwrap().serialize()[..],
+               let chan_keys = ChannelKeys {
+                       funding_key: SecretKey::from_slice(&secp_ctx, &hex_bytes("30ff4956bbdd3222d44cc5e8a1261dab1e07957bdac5ae88fe3261ef321f3749").unwrap()[..]).unwrap(),
+                       payment_base_key: SecretKey::from_slice(&secp_ctx, &hex_bytes("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..]).unwrap(),
+                       delayed_payment_base_key: SecretKey::from_slice(&secp_ctx, &hex_bytes("3333333333333333333333333333333333333333333333333333333333333333").unwrap()[..]).unwrap(),
+                       htlc_base_key: SecretKey::from_slice(&secp_ctx, &hex_bytes("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..]).unwrap(),
+
+                       // These aren't set in the test vectors:
+                       revocation_base_key: SecretKey::from_slice(&secp_ctx, &hex_bytes("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(),
+                       channel_close_key: SecretKey::from_slice(&secp_ctx, &hex_bytes("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(),
+                       channel_monitor_claim_key: SecretKey::from_slice(&secp_ctx, &hex_bytes("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(),
+                       commitment_seed: [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
+               };
+               assert_eq!(PublicKey::from_secret_key(&secp_ctx, &chan_keys.funding_key).unwrap().serialize()[..],
                                hex_bytes("023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb").unwrap()[..]);
 
-               chan.local_keys.payment_base_key = SecretKey::from_slice(&secp_ctx, &hex_bytes("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..]).unwrap();
-               chan.local_keys.delayed_payment_base_key = SecretKey::from_slice(&secp_ctx, &hex_bytes("3333333333333333333333333333333333333333333333333333333333333333").unwrap()[..]).unwrap();
-               chan.local_keys.htlc_base_key = SecretKey::from_slice(&secp_ctx, &hex_bytes("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..]).unwrap();
-               // chan.local_keys.commitment_seed isn't derived in the test vectors :(
+               let mut chan = Channel::new_outbound(&feeest, chan_keys, PublicKey::new(), 10000000, false, 42); // Nothing uses their network key in this test
+               chan.their_to_self_delay = 144;
+               chan.our_dust_limit_satoshis = 546;
 
                chan.channel_monitor.set_funding_info(Sha256dHash::from_hex("8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be").unwrap(), 0);
 
index 68cfed8fd0d422cce1f17550bdefde7d129dbae1..da93443d6d7ed03378e47c22374fe43ef5ac174d 100644 (file)
@@ -12,14 +12,15 @@ use secp256k1::ecdh::SharedSecret;
 use secp256k1;
 
 use chain::chaininterface::{BroadcasterInterface,ChainListener,ChainWatchInterface,FeeEstimator};
-use ln::channel::Channel;
+use ln::channel::{Channel, ChannelKeys};
 use ln::channelmonitor::ManyChannelMonitor;
-use ln::router::Route;
+use ln::router::{Route,RouteHop};
 use ln::msgs;
 use ln::msgs::{HandleError,ChannelMessageHandler,MsgEncodable,MsgDecodable};
 use util::{byte_utils, events, internal_traits, rng};
 use util::sha2::Sha256;
 
+use crypto;
 use crypto::mac::{Mac,MacResult};
 use crypto::hmac::Hmac;
 use crypto::digest::Digest;
@@ -91,12 +92,14 @@ enum PendingOutboundHTLC {
        },
        OutboundRoute {
                route: Route,
+               session_priv: SecretKey,
        },
        /// Used for channel rebalancing
        CycledRoute {
                source_short_channel_id: u64,
                incoming_packet_shared_secret: SharedSecret,
                route: Route,
+               session_priv: SecretKey,
        }
 }
 
@@ -230,7 +233,27 @@ impl ChannelManager {
        }
 
        pub fn create_channel(&self, their_network_key: PublicKey, channel_value_satoshis: u64, user_id: u64) -> Result<msgs::OpenChannel, HandleError> {
-               let channel = Channel::new_outbound(&*self.fee_estimator, their_network_key, channel_value_satoshis, self.announce_channels_publicly, user_id);
+               let chan_keys = if cfg!(feature = "fuzztarget") {
+                       ChannelKeys {
+                               funding_key:               SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 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(),
+                               revocation_base_key:       SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 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(),
+                               payment_base_key:          SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 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(),
+                               delayed_payment_base_key:  SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 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(),
+                               htlc_base_key:             SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 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(),
+                               channel_close_key:         SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 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(),
+                               channel_monitor_claim_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 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(),
+                               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, 0, 0],
+                       }
+               } else {
+                       let mut key_seed = [0u8; 32];
+                       rng::fill_bytes(&mut key_seed);
+                       match ChannelKeys::new_from_seed(&key_seed) {
+                               Ok(key) => key,
+                               Err(_) => panic!("RNG is busted!")
+                       }
+               };
+
+               let channel = Channel::new_outbound(&*self.fee_estimator, chan_keys, their_network_key, channel_value_satoshis, self.announce_channels_publicly, user_id);
                let res = channel.get_open_channel(self.genesis_hash.clone(), &*self.fee_estimator)?;
                let mut channel_state = self.channel_state.lock().unwrap();
                match channel_state.by_id.insert(channel.channel_id(), channel) {
@@ -260,15 +283,18 @@ impl ChannelManager {
        /// will be accepted on the given channel, and after additional timeout/the closing of all
        /// pending HTLCs, the channel will be closed on chain.
        pub fn close_channel(&self, channel_id: &Uint256) -> Result<msgs::Shutdown, HandleError> {
-               let res = {
-                       let mut channel_state = self.channel_state.lock().unwrap();
+               let (res, chan_option) = {
+                       let mut channel_state_lock = self.channel_state.lock().unwrap();
+                       let channel_state = channel_state_lock.borrow_parts();
                        match channel_state.by_id.entry(channel_id.clone()) {
                                hash_map::Entry::Occupied(mut chan_entry) => {
                                        let res = chan_entry.get_mut().get_shutdown()?;
                                        if chan_entry.get().is_shutdown() {
-                                               chan_entry.remove_entry();
-                                       }
-                                       res
+                                               if let Some(short_id) = chan_entry.get().get_short_channel_id() {
+                                                       channel_state.short_to_id.remove(&short_id);
+                                               }
+                                               (res, Some(chan_entry.remove_entry().1))
+                                       } else { (res, None) }
                                },
                                hash_map::Entry::Vacant(_) => return Err(HandleError{err: "No such channel", msg: None})
                        }
@@ -277,6 +303,14 @@ impl ChannelManager {
                        // unknown_next_peer...I dunno who that is anymore....
                        self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), &payment_hash, HTLCFailReason::Reason { failure_code: 0x4000 | 10, data: Vec::new() });
                }
+               if let Some(chan) = chan_option {
+                       if let Ok(update) = self.get_channel_update(&chan) {
+                               let mut events = self.pending_events.lock().unwrap();
+                               events.push(events::Event::BroadcastChannelUpdate {
+                                       msg: update
+                               });
+                       }
+               }
                Ok(res.0)
        }
 
@@ -316,8 +350,9 @@ impl ChannelManager {
                res
        }
 
-       fn construct_onion_keys(secp_ctx: &Secp256k1, route: &Route, session_priv: &SecretKey) -> Result<Vec<OnionKeys>, HandleError> {
-               let mut res = Vec::with_capacity(route.hops.len());
+       // can only fail if an intermediary hop has an invalid public key or session_priv is invalid
+       #[inline]
+       fn construct_onion_keys_callback<FType: FnMut(SharedSecret, [u8; 32], PublicKey, &RouteHop)> (secp_ctx: &Secp256k1, route: &Route, session_priv: &SecretKey, mut callback: FType) -> Result<(), HandleError> {
                let mut blinded_priv = session_priv.clone();
                let mut blinded_pub = secp_call!(PublicKey::from_secret_key(secp_ctx, &blinded_priv));
                let mut first_iteration = true;
@@ -340,18 +375,29 @@ impl ChannelManager {
                        secp_call!(blinded_priv.mul_assign(secp_ctx, &secp_call!(SecretKey::from_slice(secp_ctx, &blinding_factor))));
                        blinded_pub = secp_call!(PublicKey::from_secret_key(secp_ctx, &blinded_priv));
 
+                       callback(shared_secret, blinding_factor, ephemeral_pubkey, hop);
+               }
+
+               Ok(())
+       }
+
+       // can only fail if an intermediary hop has an invalid public key or session_priv is invalid
+       fn construct_onion_keys(secp_ctx: &Secp256k1, route: &Route, session_priv: &SecretKey) -> Result<Vec<OnionKeys>, HandleError> {
+               let mut res = Vec::with_capacity(route.hops.len());
+
+               Self::construct_onion_keys_callback(secp_ctx, route, session_priv, |shared_secret, _blinding_factor, ephemeral_pubkey, _| {
                        let (rho, mu) = ChannelManager::gen_rho_mu_from_shared_secret(&shared_secret);
 
                        res.push(OnionKeys {
                                #[cfg(test)]
-                               shared_secret: shared_secret,
+                               shared_secret,
                                #[cfg(test)]
-                               blinding_factor: blinding_factor,
-                               ephemeral_pubkey: ephemeral_pubkey,
-                               rho: rho,
-                               mu: mu,
+                               blinding_factor: _blinding_factor,
+                               ephemeral_pubkey,
+                               rho,
+                               mu,
                        });
-               }
+               })?;
 
                Ok(res)
        }
@@ -513,7 +559,7 @@ impl ChannelManager {
        }
 
        /// only fails if the channel does not yet have an assigned short_id
-       fn get_channel_update(&self, chan: &mut Channel) -> Result<msgs::ChannelUpdate, HandleError> {
+       fn get_channel_update(&self, chan: &Channel) -> Result<msgs::ChannelUpdate, HandleError> {
                let short_channel_id = match chan.get_short_channel_id() {
                        None => return Err(HandleError{err: "Channel not yet established", msg: None}),
                        Some(id) => id,
@@ -541,11 +587,12 @@ impl ChannelManager {
                })
        }
 
-       /// Sends a payment along a given route, returning the UpdateAddHTLC message to give to the
-       /// first hop in route. Value parameters are provided via the last hop in route, see
-       /// documentation for RouteHop fields for more info.
+       /// Sends a payment along a given route.
+       /// Value parameters are provided via the last hop in route, see documentation for RouteHop
+       /// fields for more info.
        /// See-also docs on Channel::send_htlc_and_commit.
-       pub fn send_payment(&self, route: Route, payment_hash: [u8; 32]) -> Result<Option<(msgs::UpdateAddHTLC, msgs::CommitmentSigned)>, HandleError> {
+       /// May generate a SendHTLCs event on success, which should be relayed.
+       pub fn send_payment(&self, route: Route, payment_hash: [u8; 32]) -> Result<(), HandleError> {
                if route.hops.len() < 1 || route.hops.len() > 20 {
                        return Err(HandleError{err: "Route didn't go anywhere/had bogus size", msg: None});
                }
@@ -568,40 +615,60 @@ impl ChannelManager {
                let (onion_payloads, htlc_msat, htlc_cltv) = ChannelManager::build_onion_payloads(&route)?;
                let onion_packet = ChannelManager::construct_onion_packet(onion_payloads, onion_keys, associated_data)?;
 
-               let mut channel_state = self.channel_state.lock().unwrap();
-               let id = match channel_state.short_to_id.get(&route.hops.first().unwrap().short_channel_id) {
-                       None => return Err(HandleError{err: "No channel available with first hop!", msg: None}),
-                       Some(id) => id.clone()
-               };
-               let res = {
-                       let chan = channel_state.by_id.get_mut(&id).unwrap();
-                       if chan.get_their_node_id() != route.hops.first().unwrap().pubkey {
-                               return Err(HandleError{err: "Node ID mismatch on first hop!", msg: None});
+               let (first_hop_node_id, (update_add, commitment_signed, chan_monitor)) = {
+                       let mut channel_state = self.channel_state.lock().unwrap();
+                       let id = match channel_state.short_to_id.get(&route.hops.first().unwrap().short_channel_id) {
+                               None => return Err(HandleError{err: "No channel available with first hop!", msg: None}),
+                               Some(id) => id.clone()
+                       };
+                       let res = {
+                               let chan = channel_state.by_id.get_mut(&id).unwrap();
+                               if chan.get_their_node_id() != route.hops.first().unwrap().pubkey {
+                                       return Err(HandleError{err: "Node ID mismatch on first hop!", msg: None});
+                               }
+                               chan.send_htlc_and_commit(htlc_msat, payment_hash.clone(), htlc_cltv, onion_packet)?
+                       };
+
+                       let first_hop_node_id = route.hops.first().unwrap().pubkey;
+
+                       if channel_state.claimable_htlcs.insert(payment_hash, PendingOutboundHTLC::OutboundRoute {
+                               route,
+                               session_priv,
+                       }).is_some() {
+                               // TODO: We need to track these better, we're not generating these, so a
+                               // third-party might make this happen:
+                               panic!("payment_hash was repeated! Don't let this happen");
+                       }
+
+                       match res {
+                               Some(msgs) => (first_hop_node_id, msgs),
+                               None => return Ok(()),
                        }
-                       chan.send_htlc_and_commit(htlc_msat, payment_hash.clone(), htlc_cltv, onion_packet)?
                };
 
-               if channel_state.claimable_htlcs.insert(payment_hash, PendingOutboundHTLC::OutboundRoute {
-                       route: route,
-               }).is_some() {
-                       // TODO: We need to track these better, we're not generating these, so a
-                       // third-party might make this happen:
-                       panic!("payment_hash was repeated! Don't let this happen");
+               if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
+                       unimplemented!(); // maybe remove from claimable_htlcs?
                }
 
-               Ok(res)
+               let mut events = self.pending_events.lock().unwrap();
+               events.push(events::Event::SendHTLCs {
+                       node_id: first_hop_node_id,
+                       msgs: vec![update_add],
+                       commitment_msg: commitment_signed,
+               });
+               Ok(())
        }
 
        /// Call this upon creation of a funding transaction for the given channel.
        /// Panics if a funding transaction has already been provided for this channel.
        pub fn funding_transaction_generated(&self, temporary_channel_id: &Uint256, funding_txo: (Sha256dHash, u16)) {
-               let (chan, msg) = {
+               let (chan, msg, chan_monitor) = {
                        let mut channel_state = self.channel_state.lock().unwrap();
                        match channel_state.by_id.remove(&temporary_channel_id) {
                                Some(mut chan) => {
                                        match chan.get_outbound_funding_created(funding_txo.0, funding_txo.1) {
                                                Ok(funding_msg) => {
-                                                       (chan, funding_msg)
+                                                       (chan, funding_msg.0, funding_msg.1)
                                                },
                                                Err(_e) => {
                                                        //TODO: Push e to pendingevents
@@ -612,15 +679,9 @@ impl ChannelManager {
                                None => return
                        }
                }; // Release channel lock for install_watch_outpoint call,
-               let chan_monitor = chan.channel_monitor();
-               match self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
-                       Ok(()) => {},
-                       Err(_e) => {
-                               //TODO: Push e to pendingevents?
-                               return;
-                       }
-               };
-
+               if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
+                       unimplemented!(); // maybe remove from claimable_htlcs?
+               }
                {
                        let mut pending_events = self.pending_events.lock().unwrap();
                        pending_events.push(events::Event::SendFundingCreated {
@@ -700,25 +761,25 @@ impl ChannelManager {
                                        }
 
                                        if !add_htlc_msgs.is_empty() {
-                                               let commitment_msg = match forward_chan.send_commitment() {
-                                                       Ok(msg) => msg,
+                                               let (commitment_msg, monitor) = match forward_chan.send_commitment() {
+                                                       Ok(res) => res,
                                                        Err(_) => {
                                                                //TODO: Handle...this is bad!
                                                                continue;
                                                        },
                                                };
-                                               new_events.push(events::Event::SendHTLCs {
+                                               new_events.push((Some(monitor), events::Event::SendHTLCs {
                                                        node_id: forward_chan.get_their_node_id(),
                                                        msgs: add_htlc_msgs,
                                                        commitment_msg: commitment_msg,
-                                               });
+                                               }));
                                        }
                                } else {
                                        for forward_info in pending_forwards {
-                                               new_events.push(events::Event::PaymentReceived {
+                                               new_events.push((None, events::Event::PaymentReceived {
                                                        payment_hash: forward_info.payment_hash,
                                                        amt: forward_info.amt_to_forward,
-                                               });
+                                               }));
                                        }
                                }
                        }
@@ -727,16 +788,25 @@ impl ChannelManager {
                for failed_forward in failed_forwards.drain(..) {
                        match failed_forward.2 {
                                None => self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), &failed_forward.0, HTLCFailReason::Reason { failure_code: failed_forward.1, data: Vec::new() }),
-                               Some(chan_update) => self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), &failed_forward.0, HTLCFailReason::Reason { failure_code: failed_forward.1, data: chan_update.encode() }),
+                               Some(chan_update) => self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), &failed_forward.0, HTLCFailReason::Reason { failure_code: failed_forward.1, data: chan_update.encode_with_len() }),
                        };
                }
 
                if new_events.is_empty() { return }
 
+               new_events.retain(|event| {
+                       if let &Some(ref monitor) = &event.0 {
+                               if let Err(_e) = self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor.clone()) {
+                                       unimplemented!();// but def dont push the event...
+                               }
+                       }
+                       true
+               });
+
                let mut events = self.pending_events.lock().unwrap();
                events.reserve(new_events.len());
                for event in new_events.drain(..) {
-                       events.push(event);
+                       events.push(event.1);
                }
        }
 
@@ -754,7 +824,11 @@ impl ChannelManager {
                };
 
                match pending_htlc {
-                       PendingOutboundHTLC::CycledRoute { source_short_channel_id, incoming_packet_shared_secret, .. } => {
+                       PendingOutboundHTLC::CycledRoute { source_short_channel_id, incoming_packet_shared_secret, route, session_priv } => {
+                               channel_state.claimable_htlcs.insert(payment_hash.clone(), PendingOutboundHTLC::OutboundRoute {
+                                       route,
+                                       session_priv,
+                               });
                                pending_htlc = PendingOutboundHTLC::IntermediaryHopData { source_short_channel_id, incoming_packet_shared_secret };
                        },
                        _ => {}
@@ -763,8 +837,8 @@ impl ChannelManager {
                match pending_htlc {
                        PendingOutboundHTLC::CycledRoute { .. } => { panic!("WAT"); },
                        PendingOutboundHTLC::OutboundRoute { .. } => {
-                               //TODO: DECRYPT route from OutboundRoute
                                mem::drop(channel_state);
+
                                let mut pending_events = self.pending_events.lock().unwrap();
                                pending_events.push(events::Event::PaymentFailed {
                                        payment_hash: payment_hash.clone()
@@ -799,13 +873,18 @@ impl ChannelManager {
                                };
 
                                match fail_msgs {
-                                       Some(msgs) => {
+                                       Some((msg, commitment_msg, chan_monitor)) => {
                                                mem::drop(channel_state);
+
+                                               if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
+                                                       unimplemented!();// but def dont push the event...
+                                               }
+
                                                let mut pending_events = self.pending_events.lock().unwrap();
                                                pending_events.push(events::Event::SendFailHTLC {
                                                        node_id,
-                                                       msg: msgs.0,
-                                                       commitment_msg: msgs.1,
+                                                       msg: msg,
+                                                       commitment_msg: commitment_msg,
                                                });
                                        },
                                        None => {},
@@ -838,13 +917,13 @@ impl ChannelManager {
                };
 
                match pending_htlc {
-                       PendingOutboundHTLC::CycledRoute { source_short_channel_id, incoming_packet_shared_secret, route } => {
+                       PendingOutboundHTLC::CycledRoute { source_short_channel_id, incoming_packet_shared_secret, route, session_priv } => {
                                if from_user { // This was the end hop back to us
                                        pending_htlc = PendingOutboundHTLC::IntermediaryHopData { source_short_channel_id, incoming_packet_shared_secret };
-                                       channel_state.claimable_htlcs.insert(payment_hash, PendingOutboundHTLC::OutboundRoute { route });
+                                       channel_state.claimable_htlcs.insert(payment_hash, PendingOutboundHTLC::OutboundRoute { route, session_priv });
                                } else { // This came from the first upstream node
                                        // Bank error in our favor! Maybe we should tell the user this somehow???
-                                       pending_htlc = PendingOutboundHTLC::OutboundRoute { route };
+                                       pending_htlc = PendingOutboundHTLC::OutboundRoute { route, session_priv };
                                        channel_state.claimable_htlcs.insert(payment_hash, PendingOutboundHTLC::IntermediaryHopData { source_short_channel_id, incoming_packet_shared_secret });
                                }
                        },
@@ -865,7 +944,7 @@ impl ChannelManager {
                                false
                        },
                        PendingOutboundHTLC::IntermediaryHopData { source_short_channel_id, .. } => {
-                               let (node_id, fulfill_msgs, monitor) = {
+                               let (node_id, fulfill_msgs) = {
                                        let chan_id = match channel_state.short_to_id.get(&source_short_channel_id) {
                                                Some(chan_id) => chan_id.clone(),
                                                None => return false
@@ -873,7 +952,7 @@ impl ChannelManager {
 
                                        let chan = channel_state.by_id.get_mut(&chan_id).unwrap();
                                        match chan.get_update_fulfill_htlc_and_commit(payment_preimage) {
-                                               Ok(msg) => (chan.get_their_node_id(), msg, if from_user { Some(chan.channel_monitor()) } else { None }),
+                                               Ok(msg) => (chan.get_their_node_id(), msg),
                                                Err(_e) => {
                                                        //TODO: Do something with e?
                                                        return false;
@@ -883,25 +962,21 @@ impl ChannelManager {
 
                                mem::drop(channel_state);
                                match fulfill_msgs {
-                                       Some(msgs) => {
+                                       Some((msg, commitment_msg, chan_monitor)) => {
+                                               if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
+                                                       unimplemented!();// but def dont push the event...
+                                               }
+
                                                let mut pending_events = self.pending_events.lock().unwrap();
                                                pending_events.push(events::Event::SendFulfillHTLC {
                                                        node_id: node_id,
-                                                       msg: msgs.0,
-                                                       commitment_msg: msgs.1,
+                                                       msg,
+                                                       commitment_msg,
                                                });
                                        },
                                        None => {},
                                }
-
-                               //TODO: It may not be possible to handle add_update_monitor fails gracefully, maybe
-                               //it should return no Err? Sadly, panic!()s instead doesn't help much :(
-                               if from_user {
-                                       match self.monitor.add_update_monitor(monitor.as_ref().unwrap().get_funding_txo().unwrap(), monitor.unwrap()) {
-                                               Ok(()) => true,
-                                               Err(_) => true,
-                                       }
-                               } else { true }
+                               true
                        },
                }
        }
@@ -910,6 +985,13 @@ impl ChannelManager {
        pub fn get_our_node_id(&self) -> PublicKey {
                PublicKey::from_secret_key(&self.secp_ctx, &self.our_network_key).unwrap()
        }
+
+       /// Used to restore channels to normal operation after a
+       /// ChannelMonitorUpdateErr::TemporaryFailure was returned from a channel monitor update
+       /// operation.
+       pub fn test_restore_channel_monitor(&self) {
+               unimplemented!();
+       }
 }
 
 impl events::EventsProvider for ChannelManager {
@@ -923,37 +1005,68 @@ impl events::EventsProvider for ChannelManager {
 
 impl ChainListener for ChannelManager {
        fn block_connected(&self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], indexes_of_txn_matched: &[u32]) {
-               let mut new_funding_locked_messages = Vec::new();
+               let mut new_events = Vec::new();
                {
                        let mut channel_state = self.channel_state.lock().unwrap();
                        let mut short_to_ids_to_insert = Vec::new();
-                       for channel in channel_state.by_id.values_mut() {
-                               match channel.block_connected(header, height, txn_matched, indexes_of_txn_matched) {
-                                       Some(funding_locked) => {
-                                               let announcement_sigs = match self.get_announcement_sigs(channel) {
-                                                       Ok(res) => res,
-                                                       Err(_e) => {
-                                                               //TODO: push e on events and blow up the channel (it has bad keys)
-                                                               continue;
+                       let mut short_to_ids_to_remove = Vec::new();
+                       channel_state.by_id.retain(|_, channel| {
+                               if let Some(funding_locked) = channel.block_connected(header, height, txn_matched, indexes_of_txn_matched) {
+                                       let announcement_sigs = match self.get_announcement_sigs(channel) {
+                                               Ok(res) => res,
+                                               Err(_e) => {
+                                                       //TODO: push e on events and blow up the channel (it has bad keys)
+                                                       return true;
+                                               }
+                                       };
+                                       new_events.push(events::Event::SendFundingLocked {
+                                               node_id: channel.get_their_node_id(),
+                                               msg: funding_locked,
+                                               announcement_sigs: announcement_sigs
+                                       });
+                                       short_to_ids_to_insert.push((channel.get_short_channel_id().unwrap(), channel.channel_id()));
+                               }
+                               if let Some(funding_txo) = channel.get_funding_txo() {
+                                       for tx in txn_matched {
+                                               for inp in tx.input.iter() {
+                                                       if inp.prev_hash == funding_txo.0 && inp.prev_index == funding_txo.1 as u32 {
+                                                               if let Some(short_id) = channel.get_short_channel_id() {
+                                                                       short_to_ids_to_remove.push(short_id);
+                                                               }
+                                                               channel.force_shutdown();
+                                                               if let Ok(update) = self.get_channel_update(&channel) {
+                                                                       new_events.push(events::Event::BroadcastChannelUpdate {
+                                                                               msg: update
+                                                                       });
+                                                               }
+                                                               return false;
                                                        }
-                                               };
-                                               new_funding_locked_messages.push(events::Event::SendFundingLocked {
-                                                       node_id: channel.get_their_node_id(),
-                                                       msg: funding_locked,
-                                                       announcement_sigs: announcement_sigs
+                                               }
+                                       }
+                               }
+                               if channel.channel_monitor().would_broadcast_at_height(height) {
+                                       if let Some(short_id) = channel.get_short_channel_id() {
+                                               short_to_ids_to_remove.push(short_id);
+                                       }
+                                       channel.force_shutdown();
+                                       if let Ok(update) = self.get_channel_update(&channel) {
+                                               new_events.push(events::Event::BroadcastChannelUpdate {
+                                                       msg: update
                                                });
-                                               short_to_ids_to_insert.push((channel.get_short_channel_id().unwrap(), channel.channel_id()));
-                                       },
-                                       None => {}
+                                       }
+                                       return false;
                                }
-                               //TODO: Check if channel was closed (or disabled) here
+                               true
+                       });
+                       for to_remove in short_to_ids_to_remove {
+                               channel_state.short_to_id.remove(&to_remove);
                        }
                        for to_insert in short_to_ids_to_insert {
                                channel_state.short_to_id.insert(to_insert.0, to_insert.1);
                        }
                }
                let mut pending_events = self.pending_events.lock().unwrap();
-               for funding_locked in new_funding_locked_messages.drain(..) {
+               for funding_locked in new_events.drain(..) {
                        pending_events.push(funding_locked);
                }
        }
@@ -978,7 +1091,28 @@ impl ChannelMessageHandler for ChannelManager {
                if channel_state.by_id.contains_key(&msg.temporary_channel_id) {
                        return Err(HandleError{err: "temporary_channel_id collision!", msg: None});
                }
-               let channel = Channel::new_from_req(&*self.fee_estimator, their_node_id.clone(), msg, 0, self.announce_channels_publicly)?;
+
+               let chan_keys = if cfg!(feature = "fuzztarget") {
+                       ChannelKeys {
+                               funding_key:               SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 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(),
+                               revocation_base_key:       SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 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(),
+                               payment_base_key:          SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 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(),
+                               delayed_payment_base_key:  SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 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(),
+                               htlc_base_key:             SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 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(),
+                               channel_close_key:         SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 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(),
+                               channel_monitor_claim_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 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(),
+                               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, 0, 0],
+                       }
+               } else {
+                       let mut key_seed = [0u8; 32];
+                       rng::fill_bytes(&mut key_seed);
+                       match ChannelKeys::new_from_seed(&key_seed) {
+                               Ok(key) => key,
+                               Err(_) => panic!("RNG is busted!")
+                       }
+               };
+
+               let channel = Channel::new_from_req(&*self.fee_estimator, chan_keys, their_node_id.clone(), msg, 0, self.announce_channels_publicly)?;
                let accept_msg = channel.get_accept_channel()?;
                channel_state.by_id.insert(channel.channel_id(), channel);
                Ok(accept_msg)
@@ -1012,7 +1146,7 @@ impl ChannelMessageHandler for ChannelManager {
                //TODO: broke this - a node shouldn't be able to get their channel removed by sending a
                //funding_created a second time, or long after the first, or whatever (note this also
                //leaves the short_to_id map in a busted state.
-               let chan = {
+               let (chan, funding_msg, monitor_update) = {
                        let mut channel_state = self.channel_state.lock().unwrap();
                        match channel_state.by_id.remove(&msg.temporary_channel_id) {
                                Some(mut chan) => {
@@ -1020,8 +1154,8 @@ impl ChannelMessageHandler for ChannelManager {
                                                return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
                                        }
                                        match chan.funding_created(msg) {
-                                               Ok(funding_msg) => {
-                                                       (chan, funding_msg)
+                                               Ok((funding_msg, monitor_update)) => {
+                                                       (chan, funding_msg, monitor_update)
                                                },
                                                Err(e) => {
                                                        return Err(e);
@@ -1034,27 +1168,31 @@ impl ChannelMessageHandler for ChannelManager {
                   // note that this means if the remote end is misbehaving and sends a message for the same
                   // channel back-to-back with funding_created, we'll end up thinking they sent a message
                   // for a bogus channel.
-               let chan_monitor = chan.0.channel_monitor();
-               self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor)?;
+               if let Err(_e) = self.monitor.add_update_monitor(monitor_update.get_funding_txo().unwrap(), monitor_update) {
+                       unimplemented!();
+               }
                let mut channel_state = self.channel_state.lock().unwrap();
-               channel_state.by_id.insert(chan.1.channel_id, chan.0);
-               Ok(chan.1)
+               channel_state.by_id.insert(funding_msg.channel_id, chan);
+               Ok(funding_msg)
        }
 
        fn handle_funding_signed(&self, their_node_id: &PublicKey, msg: &msgs::FundingSigned) -> Result<(), HandleError> {
-               let (funding_txo, user_id) = {
+               let (funding_txo, user_id, monitor) = {
                        let mut channel_state = self.channel_state.lock().unwrap();
                        match channel_state.by_id.get_mut(&msg.channel_id) {
                                Some(chan) => {
                                        if chan.get_their_node_id() != *their_node_id {
                                                return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
                                        }
-                                       chan.funding_signed(&msg)?;
-                                       (chan.get_funding_txo().unwrap(), chan.get_user_id())
+                                       let chan_monitor = chan.funding_signed(&msg)?;
+                                       (chan.get_funding_txo().unwrap(), chan.get_user_id(), chan_monitor)
                                },
                                None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
                        }
                };
+               if let Err(_e) = self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor) {
+                       unimplemented!();
+               }
                let mut pending_events = self.pending_events.lock().unwrap();
                pending_events.push(events::Event::FundingBroadcastSafe {
                        funding_txo: funding_txo,
@@ -1078,8 +1216,9 @@ impl ChannelMessageHandler for ChannelManager {
        }
 
        fn handle_shutdown(&self, their_node_id: &PublicKey, msg: &msgs::Shutdown) -> Result<(Option<msgs::Shutdown>, Option<msgs::ClosingSigned>), HandleError> {
-               let res = {
-                       let mut channel_state = self.channel_state.lock().unwrap();
+               let (res, chan_option) = {
+                       let mut channel_state_lock = self.channel_state.lock().unwrap();
+                       let channel_state = channel_state_lock.borrow_parts();
 
                        match channel_state.by_id.entry(msg.channel_id.clone()) {
                                hash_map::Entry::Occupied(mut chan_entry) => {
@@ -1088,9 +1227,11 @@ impl ChannelMessageHandler for ChannelManager {
                                        }
                                        let res = chan_entry.get_mut().shutdown(&*self.fee_estimator, &msg)?;
                                        if chan_entry.get().is_shutdown() {
-                                               chan_entry.remove_entry();
-                                       }
-                                       res
+                                               if let Some(short_id) = chan_entry.get().get_short_channel_id() {
+                                                       channel_state.short_to_id.remove(&short_id);
+                                               }
+                                               (res, Some(chan_entry.remove_entry().1))
+                                       } else { (res, None) }
                                },
                                hash_map::Entry::Vacant(_) => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
                        }
@@ -1099,12 +1240,21 @@ impl ChannelMessageHandler for ChannelManager {
                        // unknown_next_peer...I dunno who that is anymore....
                        self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), &payment_hash, HTLCFailReason::Reason { failure_code: 0x4000 | 10, data: Vec::new() });
                }
+               if let Some(chan) = chan_option {
+                       if let Ok(update) = self.get_channel_update(&chan) {
+                               let mut events = self.pending_events.lock().unwrap();
+                               events.push(events::Event::BroadcastChannelUpdate {
+                                       msg: update
+                               });
+                       }
+               }
                Ok((res.0, res.1))
        }
 
        fn handle_closing_signed(&self, their_node_id: &PublicKey, msg: &msgs::ClosingSigned) -> Result<Option<msgs::ClosingSigned>, HandleError> {
-               let res = {
-                       let mut channel_state = self.channel_state.lock().unwrap();
+               let (res, chan_option) = {
+                       let mut channel_state_lock = self.channel_state.lock().unwrap();
+                       let channel_state = channel_state_lock.borrow_parts();
                        match channel_state.by_id.entry(msg.channel_id.clone()) {
                                hash_map::Entry::Occupied(mut chan_entry) => {
                                        if chan_entry.get().get_their_node_id() != *their_node_id {
@@ -1117,9 +1267,11 @@ impl ChannelMessageHandler for ChannelManager {
                                                // also implies there are no pending HTLCs left on the channel, so we can
                                                // fully delete it from tracking (the channel monitor is still around to
                                                // watch for old state broadcasts)!
-                                               chan_entry.remove_entry();
-                                       }
-                                       res
+                                               if let Some(short_id) = chan_entry.get().get_short_channel_id() {
+                                                       channel_state.short_to_id.remove(&short_id);
+                                               }
+                                               (res, Some(chan_entry.remove_entry().1))
+                                       } else { (res, None) }
                                },
                                hash_map::Entry::Vacant(_) => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
                        }
@@ -1127,6 +1279,14 @@ impl ChannelMessageHandler for ChannelManager {
                if let Some(broadcast_tx) = res.1 {
                        self.tx_broadcaster.broadcast_transaction(&broadcast_tx);
                }
+               if let Some(chan) = chan_option {
+                       if let Ok(update) = self.get_channel_update(&chan) {
+                               let mut events = self.pending_events.lock().unwrap();
+                               events.push(events::Event::BroadcastChannelUpdate {
+                                       msg: update
+                               });
+                       }
+               }
                Ok(res.0)
        }
 
@@ -1291,7 +1451,7 @@ impl ChannelMessageHandler for ChannelManager {
                        let chan = channel_state.by_id.get_mut(&forwarding_id).unwrap();
                        if !chan.is_live() {
                                let chan_update = self.get_channel_update(chan).unwrap();
-                               return_err!("Forwarding channel is not in a ready state.", 0x4000 | 10, &chan_update.encode()[..]);
+                               return_err!("Forwarding channel is not in a ready state.", 0x4000 | 7, &chan_update.encode_with_len()[..]);
                        }
                }
 
@@ -1335,16 +1495,17 @@ impl ChannelMessageHandler for ChannelManager {
                match claimable_htlcs_entry {
                        hash_map::Entry::Occupied(mut e) => {
                                let outbound_route = e.get_mut();
-                               let route = match outbound_route {
-                                       &mut PendingOutboundHTLC::OutboundRoute { ref route } => {
-                                               route.clone()
+                               let (route, session_priv) = match outbound_route {
+                                       &mut PendingOutboundHTLC::OutboundRoute { ref route, ref session_priv } => {
+                                               (route.clone(), session_priv.clone())
                                        },
                                        _ => { panic!("WAT") },
                                };
                                *outbound_route = PendingOutboundHTLC::CycledRoute {
                                        source_short_channel_id,
                                        incoming_packet_shared_secret: shared_secret,
-                                       route
+                                       route,
+                                       session_priv,
                                };
                        },
                        hash_map::Entry::Vacant(e) => {
@@ -1371,19 +1532,20 @@ impl ChannelMessageHandler for ChannelManager {
                                        if chan.get_their_node_id() != *their_node_id {
                                                return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
                                        }
-                                       chan.update_fulfill_htlc(&msg)?;
-                                       chan.channel_monitor()
+                                       chan.update_fulfill_htlc(&msg)?
                                },
                                None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
                        }
                };
-               self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor)?;
+               if let Err(_e) = self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor) {
+                       unimplemented!();
+               }
                Ok(())
        }
 
-       fn handle_update_fail_htlc(&self, their_node_id: &PublicKey, msg: &msgs::UpdateFailHTLC) -> Result<(), HandleError> {
+       fn handle_update_fail_htlc(&self, their_node_id: &PublicKey, msg: &msgs::UpdateFailHTLC) -> Result<Option<msgs::HTLCFailChannelUpdate>, HandleError> {
                let mut channel_state = self.channel_state.lock().unwrap();
-               match channel_state.by_id.get_mut(&msg.channel_id) {
+               let payment_hash = match channel_state.by_id.get_mut(&msg.channel_id) {
                        Some(chan) => {
                                if chan.get_their_node_id() != *their_node_id {
                                        return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
@@ -1391,6 +1553,68 @@ impl ChannelMessageHandler for ChannelManager {
                                chan.update_fail_htlc(&msg, HTLCFailReason::ErrorPacket { err: msg.reason.clone() })
                        },
                        None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+               }?;
+
+               if let Some(pending_htlc) = channel_state.claimable_htlcs.get(&payment_hash) {
+                       match pending_htlc {
+                               &PendingOutboundHTLC::OutboundRoute { ref route, ref session_priv } => {
+                                       // Handle packed channel/node updates for passing back for the route handler
+                                       let mut packet_decrypted = msg.reason.data.clone();
+                                       let mut res = None;
+                                       Self::construct_onion_keys_callback(&self.secp_ctx, &route, &session_priv, |shared_secret, _, _, route_hop| {
+                                               if res.is_some() { return; }
+
+                                               let ammag = ChannelManager::gen_ammag_from_shared_secret(&shared_secret);
+
+                                               let mut decryption_tmp = Vec::with_capacity(packet_decrypted.len());
+                                               decryption_tmp.resize(packet_decrypted.len(), 0);
+                                               let mut chacha = ChaCha20::new(&ammag, &[0u8; 8]);
+                                               chacha.process(&packet_decrypted, &mut decryption_tmp[..]);
+                                               packet_decrypted = decryption_tmp;
+
+                                               if let Ok(err_packet) = msgs::DecodedOnionErrorPacket::decode(&packet_decrypted) {
+                                                       if err_packet.failuremsg.len() >= 2 {
+                                                               let um = ChannelManager::gen_um_from_shared_secret(&shared_secret);
+
+                                                               let mut hmac = Hmac::new(Sha256::new(), &um);
+                                                               hmac.input(&err_packet.encode()[32..]);
+                                                               let mut calc_tag =  [0u8; 32];
+                                                               hmac.raw_result(&mut calc_tag);
+                                                               if crypto::util::fixed_time_eq(&calc_tag, &err_packet.hmac) {
+                                                                       const UNKNOWN_CHAN: u16 = 0x4000|10;
+                                                                       const TEMP_CHAN_FAILURE: u16 = 0x4000|7;
+                                                                       match byte_utils::slice_to_be16(&err_packet.failuremsg[0..2]) {
+                                                                               TEMP_CHAN_FAILURE => {
+                                                                                       if err_packet.failuremsg.len() >= 4 {
+                                                                                               let update_len = byte_utils::slice_to_be16(&err_packet.failuremsg[2..4]) as usize;
+                                                                                               if err_packet.failuremsg.len() >= 4 + update_len {
+                                                                                                       if let Ok(chan_update) = msgs::ChannelUpdate::decode(&err_packet.failuremsg[4..4 + update_len]) {
+                                                                                                               res = Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage {
+                                                                                                                       msg: chan_update,
+                                                                                                               });
+                                                                                                       }
+                                                                                               }
+                                                                                       }
+                                                                               },
+                                                                               UNKNOWN_CHAN => {
+                                                                                       // No such next-hop. We know this came from the
+                                                                                       // current node as the HMAC validated.
+                                                                                       res = Some(msgs::HTLCFailChannelUpdate::ChannelClosed {
+                                                                                               short_channel_id: route_hop.short_channel_id
+                                                                                       });
+                                                                               },
+                                                                               _ => {}, //TODO: Enumerate all of these!
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }).unwrap();
+                                       Ok(res)
+                               },
+                               _ => { Ok(None) },
+                       }
+               } else {
+                       Ok(None)
                }
        }
 
@@ -1408,38 +1632,41 @@ impl ChannelMessageHandler for ChannelManager {
        }
 
        fn handle_commitment_signed(&self, their_node_id: &PublicKey, msg: &msgs::CommitmentSigned) -> Result<(msgs::RevokeAndACK, Option<msgs::CommitmentSigned>), HandleError> {
-               let (res, monitor) = {
+               let (revoke_and_ack, commitment_signed, chan_monitor) = {
                        let mut channel_state = self.channel_state.lock().unwrap();
                        match channel_state.by_id.get_mut(&msg.channel_id) {
                                Some(chan) => {
                                        if chan.get_their_node_id() != *their_node_id {
                                                return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
                                        }
-                                       (chan.commitment_signed(&msg)?, chan.channel_monitor())
+                                       chan.commitment_signed(&msg)?
                                },
                                None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
                        }
                };
-               //TODO: Only if we store HTLC sigs
-               self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor)?;
+               if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
+                       unimplemented!();
+               }
 
-               Ok(res)
+               Ok((revoke_and_ack, commitment_signed))
        }
 
        fn handle_revoke_and_ack(&self, their_node_id: &PublicKey, msg: &msgs::RevokeAndACK) -> Result<Option<msgs::CommitmentUpdate>, HandleError> {
-               let ((res, mut pending_forwards, mut pending_failures), monitor) = {
+               let (res, mut pending_forwards, mut pending_failures, chan_monitor) = {
                        let mut channel_state = self.channel_state.lock().unwrap();
                        match channel_state.by_id.get_mut(&msg.channel_id) {
                                Some(chan) => {
                                        if chan.get_their_node_id() != *their_node_id {
                                                return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
                                        }
-                                       (chan.revoke_and_ack(&msg)?, chan.channel_monitor())
+                                       chan.revoke_and_ack(&msg)?
                                },
                                None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
                        }
                };
-               self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor)?;
+               if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
+                       unimplemented!();
+               }
                for failure in pending_failures.drain(..) {
                        self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), &failure.0, failure.1);
                }
@@ -1527,34 +1754,47 @@ impl ChannelMessageHandler for ChannelManager {
        }
 
        fn peer_disconnected(&self, their_node_id: &PublicKey, no_connection_possible: bool) {
-               let mut channel_state_lock = self.channel_state.lock().unwrap();
-               let channel_state = channel_state_lock.borrow_parts();
-               let short_to_id = channel_state.short_to_id;
-               if no_connection_possible {
-                       channel_state.by_id.retain(move |_, chan| {
-                               if chan.get_their_node_id() == *their_node_id {
-                                       match chan.get_short_channel_id() {
-                                               Some(short_id) => {
+               let mut new_events = Vec::new();
+               {
+                       let mut channel_state_lock = self.channel_state.lock().unwrap();
+                       let channel_state = channel_state_lock.borrow_parts();
+                       let short_to_id = channel_state.short_to_id;
+                       if no_connection_possible {
+                               channel_state.by_id.retain(|_, chan| {
+                                       if chan.get_their_node_id() == *their_node_id {
+                                               if let Some(short_id) = chan.get_short_channel_id() {
                                                        short_to_id.remove(&short_id);
-                                               },
-                                               None => {},
+                                               }
+                                               let txn_to_broadcast = chan.force_shutdown();
+                                               for tx in txn_to_broadcast {
+                                                       self.tx_broadcaster.broadcast_transaction(&tx);
+                                               }
+                                               if let Ok(update) = self.get_channel_update(&chan) {
+                                                       new_events.push(events::Event::BroadcastChannelUpdate {
+                                                               msg: update
+                                                       });
+                                               }
+                                               false
+                                       } else {
+                                               true
+                                       }
+                               });
+                       } else {
+                               for chan in channel_state.by_id {
+                                       if chan.1.get_their_node_id() == *their_node_id {
+                                               //TODO: mark channel disabled (and maybe announce such after a timeout). Also
+                                               //fail and wipe any uncommitted outbound HTLCs as those are considered after
+                                               //reconnect.
                                        }
-                                       //TODO: get the latest commitment tx, any HTLC txn built on top of it, etc out
-                                       //of the channel and throw those into the announcement blackhole.
-                                       false
-                               } else {
-                                       true
-                               }
-                       });
-               } else {
-                       for chan in channel_state.by_id {
-                               if chan.1.get_their_node_id() == *their_node_id {
-                                       //TODO: mark channel disabled (and maybe announce such after a timeout). Also
-                                       //fail and wipe any uncommitted outbound HTLCs as those are considered after
-                                       //reconnect.
                                }
                        }
                }
+               if !new_events.is_empty() {
+                       let mut pending_events = self.pending_events.lock().unwrap();
+                       for event in new_events.drain(..) {
+                               pending_events.push(event);
+                       }
+               }
        }
 }
 
@@ -1589,6 +1829,7 @@ mod tests {
        use std::default::Default;
        use std::sync::{Arc, Mutex};
        use std::time::Instant;
+       use std::mem;
 
        fn build_test_onion_keys() -> Vec<OnionKeys> {
                // Keys from BOLT 4, used in both test vector tests
@@ -1806,6 +2047,12 @@ mod tests {
                };
 
                node_a.node.handle_funding_signed(&node_b.node.get_our_node_id(), &funding_signed).unwrap();
+               {
+                       let mut added_monitors = node_a.chan_monitor.added_monitors.lock().unwrap();
+                       assert_eq!(added_monitors.len(), 1);
+                       assert_eq!(added_monitors[0].0, funding_output);
+                       added_monitors.clear();
+               }
 
                let events_3 = node_a.node.get_and_clear_pending_events();
                assert_eq!(events_3.len(), 1);
@@ -1882,7 +2129,7 @@ mod tests {
                (chan_announcement.1, chan_announcement.2, chan_announcement.3, chan_announcement.4)
        }
 
-       fn close_channel(outbound_node: &Node, inbound_node: &Node, channel_id: &Uint256, funding_tx: Transaction, close_inbound_first: bool) {
+       fn close_channel(outbound_node: &Node, inbound_node: &Node, channel_id: &Uint256, funding_tx: Transaction, close_inbound_first: bool) -> (msgs::ChannelUpdate, msgs::ChannelUpdate) {
                let (node_a, broadcaster_a) = if close_inbound_first { (&inbound_node.node, &inbound_node.tx_broadcaster) } else { (&outbound_node.node, &outbound_node.tx_broadcaster) };
                let (node_b, broadcaster_b) = if close_inbound_first { (&outbound_node.node, &outbound_node.tx_broadcaster) } else { (&inbound_node.node, &inbound_node.tx_broadcaster) };
                let (tx_a, tx_b);
@@ -1918,6 +2165,26 @@ mod tests {
                let mut funding_tx_map = HashMap::new();
                funding_tx_map.insert(funding_tx.txid(), funding_tx);
                tx_a.verify(&funding_tx_map).unwrap();
+
+               let events_1 = node_a.get_and_clear_pending_events();
+               assert_eq!(events_1.len(), 1);
+               let as_update = match events_1[0] {
+                       Event::BroadcastChannelUpdate { ref msg } => {
+                               msg.clone()
+                       },
+                       _ => panic!("Unexpected event"),
+               };
+
+               let events_2 = node_b.get_and_clear_pending_events();
+               assert_eq!(events_2.len(), 1);
+               let bs_update = match events_2[0] {
+                       Event::BroadcastChannelUpdate { ref msg } => {
+                               msg.clone()
+                       },
+                       _ => panic!("Unexpected event"),
+               };
+
+               (as_update, bs_update)
        }
 
        struct SendEvent {
@@ -1949,12 +2216,16 @@ mod tests {
                };
 
                let mut payment_event = {
-                       let msgs = origin_node.node.send_payment(route, our_payment_hash).unwrap().unwrap();
-                       SendEvent {
-                               node_id: expected_route[0].node.get_our_node_id(),
-                               msgs: vec!(msgs.0),
-                               commitment_msg: msgs.1,
+                       origin_node.node.send_payment(route, our_payment_hash).unwrap();
+                       {
+                               let mut added_monitors = origin_node.chan_monitor.added_monitors.lock().unwrap();
+                               assert_eq!(added_monitors.len(), 1);
+                               added_monitors.clear();
                        }
+
+                       let mut events = origin_node.node.get_and_clear_pending_events();
+                       assert_eq!(events.len(), 1);
+                       SendEvent::from_event(events.remove(0))
                };
                let mut prev_node = origin_node;
 
@@ -2009,9 +2280,12 @@ mod tests {
                                        _ => panic!("Unexpected event"),
                                }
                        } else {
-                               for event in events_2.drain(..) {
-                                       payment_event = SendEvent::from_event(event);
+                               {
+                                       let mut added_monitors = node.chan_monitor.added_monitors.lock().unwrap();
+                                       assert_eq!(added_monitors.len(), 1);
+                                       added_monitors.clear();
                                }
+                               payment_event = SendEvent::from_event(events_2.remove(0));
                                assert_eq!(payment_event.msgs.len(), 1);
                        }
 
@@ -2031,13 +2305,23 @@ mod tests {
 
                let mut next_msgs: Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned)> = None;
                macro_rules! update_fulfill_dance {
-                       ($node: expr, $prev_node: expr) => {
+                       ($node: expr, $prev_node: expr, $last_node: expr) => {
                                {
                                        $node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0).unwrap();
+                                       {
+                                               let mut added_monitors = $node.chan_monitor.added_monitors.lock().unwrap();
+                                               if $last_node {
+                                                       assert_eq!(added_monitors.len(), 1);
+                                               } else {
+                                                       assert_eq!(added_monitors.len(), 2);
+                                                       assert!(added_monitors[0].0 != added_monitors[1].0);
+                                               }
+                                               added_monitors.clear();
+                                       }
                                        let revoke_and_commit = $node.node.handle_commitment_signed(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().1).unwrap();
                                        {
                                                let mut added_monitors = $node.chan_monitor.added_monitors.lock().unwrap();
-                                               assert_eq!(added_monitors.len(), 2);
+                                               assert_eq!(added_monitors.len(), 1);
                                                added_monitors.clear();
                                        }
                                        assert!($prev_node.node.handle_revoke_and_ack(&$node.node.get_our_node_id(), &revoke_and_commit.0).unwrap().is_none());
@@ -2063,7 +2347,7 @@ mod tests {
                for node in expected_route.iter().rev() {
                        assert_eq!(expected_next_node, node.node.get_our_node_id());
                        if next_msgs.is_some() {
-                               update_fulfill_dance!(node, prev_node);
+                               update_fulfill_dance!(node, prev_node, false);
                        }
 
                        let events = node.node.get_and_clear_pending_events();
@@ -2080,7 +2364,7 @@ mod tests {
                }
 
                assert_eq!(expected_next_node, origin_node.node.get_our_node_id());
-               update_fulfill_dance!(origin_node, expected_route.first().unwrap());
+               update_fulfill_dance!(origin_node, expected_route.first().unwrap(), true);
 
                let events = origin_node.node.get_and_clear_pending_events();
                assert_eq!(events.len(), 1);
@@ -2092,8 +2376,10 @@ mod tests {
                }
        }
 
+       const TEST_FINAL_CLTV: u32 = 32;
+
        fn route_payment(origin_node: &Node, expected_route: &[&Node], recv_value: u64) -> ([u8; 32], [u8; 32]) {
-               let route = origin_node.router.get_route(&expected_route.last().unwrap().node.get_our_node_id(), &Vec::new(), recv_value, 142).unwrap();
+               let route = origin_node.router.get_route(&expected_route.last().unwrap().node.get_our_node_id(), &Vec::new(), recv_value, TEST_FINAL_CLTV).unwrap();
                assert_eq!(route.hops.len(), expected_route.len());
                for (node, hop) in expected_route.iter().zip(route.hops.iter()) {
                        assert_eq!(hop.pubkey, node.node.get_our_node_id());
@@ -2103,7 +2389,7 @@ mod tests {
        }
 
        fn route_over_limit(origin_node: &Node, expected_route: &[&Node], recv_value: u64) {
-               let route = origin_node.router.get_route(&expected_route.last().unwrap().node.get_our_node_id(), &Vec::new(), recv_value, 142).unwrap();
+               let route = origin_node.router.get_route(&expected_route.last().unwrap().node.get_our_node_id(), &Vec::new(), recv_value, TEST_FINAL_CLTV).unwrap();
                assert_eq!(route.hops.len(), expected_route.len());
                for (node, hop) in expected_route.iter().zip(route.hops.iter()) {
                        assert_eq!(hop.pubkey, node.node.get_our_node_id());
@@ -2128,39 +2414,49 @@ mod tests {
                claim_payment(&origin, expected_route, our_payment_preimage);
        }
 
-       fn send_failed_payment(origin_node: &Node, expected_route: &[&Node]) {
-               let route = origin_node.router.get_route(&expected_route.last().unwrap().node.get_our_node_id(), &Vec::new(), 1000000, 142).unwrap();
-               assert_eq!(route.hops.len(), expected_route.len());
-               for (node, hop) in expected_route.iter().zip(route.hops.iter()) {
-                       assert_eq!(hop.pubkey, node.node.get_our_node_id());
-               }
-               let our_payment_hash = send_along_route(origin_node, route, expected_route, 1000000).1;
-
+       fn fail_payment(origin_node: &Node, expected_route: &[&Node], our_payment_hash: [u8; 32]) {
                assert!(expected_route.last().unwrap().node.fail_htlc_backwards(&our_payment_hash));
+               {
+                       let mut added_monitors = expected_route.last().unwrap().chan_monitor.added_monitors.lock().unwrap();
+                       assert_eq!(added_monitors.len(), 1);
+                       added_monitors.clear();
+               }
 
                let mut next_msgs: Option<(msgs::UpdateFailHTLC, msgs::CommitmentSigned)> = None;
                macro_rules! update_fail_dance {
-                       ($node: expr, $prev_node: expr) => {
+                       ($node: expr, $prev_node: expr, $last_node: expr) => {
                                {
                                        $node.node.handle_update_fail_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0).unwrap();
                                        let revoke_and_commit = $node.node.handle_commitment_signed(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().1).unwrap();
+
                                        {
                                                let mut added_monitors = $node.chan_monitor.added_monitors.lock().unwrap();
                                                assert_eq!(added_monitors.len(), 1);
                                                added_monitors.clear();
                                        }
                                        assert!($prev_node.node.handle_revoke_and_ack(&$node.node.get_our_node_id(), &revoke_and_commit.0).unwrap().is_none());
+                                       {
+                                               let mut added_monitors = $prev_node.chan_monitor.added_monitors.lock().unwrap();
+                                               assert_eq!(added_monitors.len(), 1);
+                                               added_monitors.clear();
+                                       }
                                        let revoke_and_ack = $prev_node.node.handle_commitment_signed(&$node.node.get_our_node_id(), &revoke_and_commit.1.unwrap()).unwrap();
-                                       assert!(revoke_and_ack.1.is_none());
                                        {
                                                let mut added_monitors = $prev_node.chan_monitor.added_monitors.lock().unwrap();
-                                               assert_eq!(added_monitors.len(), 2);
+                                               assert_eq!(added_monitors.len(), 1);
                                                added_monitors.clear();
                                        }
+                                       assert!(revoke_and_ack.1.is_none());
+                                       assert!($node.node.get_and_clear_pending_events().is_empty());
                                        assert!($node.node.handle_revoke_and_ack(&$prev_node.node.get_our_node_id(), &revoke_and_ack.0).unwrap().is_none());
                                        {
                                                let mut added_monitors = $node.chan_monitor.added_monitors.lock().unwrap();
-                                               assert_eq!(added_monitors.len(), 1);
+                                               if $last_node {
+                                                       assert_eq!(added_monitors.len(), 1);
+                                               } else {
+                                                       assert_eq!(added_monitors.len(), 2);
+                                                       assert!(added_monitors[0].0 != added_monitors[1].0);
+                                               }
                                                added_monitors.clear();
                                        }
                                }
@@ -2172,7 +2468,7 @@ mod tests {
                for node in expected_route.iter().rev() {
                        assert_eq!(expected_next_node, node.node.get_our_node_id());
                        if next_msgs.is_some() {
-                               update_fail_dance!(node, prev_node);
+                               update_fail_dance!(node, prev_node, false);
                        }
 
                        let events = node.node.get_and_clear_pending_events();
@@ -2189,7 +2485,7 @@ mod tests {
                }
 
                assert_eq!(expected_next_node, origin_node.node.get_our_node_id());
-               update_fail_dance!(origin_node, expected_route.first().unwrap());
+               update_fail_dance!(origin_node, expected_route.first().unwrap(), true);
 
                let events = origin_node.node.get_and_clear_pending_events();
                assert_eq!(events.len(), 1);
@@ -2247,7 +2543,8 @@ mod tests {
                send_payment(&nodes[3], &vec!(&nodes[2], &nodes[1])[..], 1000000);
 
                // Test failure packets
-               send_failed_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3])[..]);
+               let payment_hash_1 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3])[..], 1000000).1;
+               fail_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3])[..], payment_hash_1);
 
                // Add a new channel that skips 3
                let chan_4 = create_announced_chan_between_nodes(&nodes, 1, 3);
@@ -2278,7 +2575,7 @@ mod tests {
                        pubkey: nodes[1].node.get_our_node_id(),
                        short_channel_id: chan_4.0.contents.short_channel_id,
                        fee_msat: 1000000,
-                       cltv_expiry_delta: 142,
+                       cltv_expiry_delta: TEST_FINAL_CLTV,
                });
                hops[1].fee_msat = chan_4.1.contents.fee_base_msat as u64 + chan_4.1.contents.fee_proportional_millionths as u64 * hops[2].fee_msat as u64 / 1000000;
                hops[0].fee_msat = chan_3.0.contents.fee_base_msat as u64 + chan_3.0.contents.fee_proportional_millionths as u64 * hops[1].fee_msat as u64 / 1000000;
@@ -2301,14 +2598,14 @@ mod tests {
                        pubkey: nodes[1].node.get_our_node_id(),
                        short_channel_id: chan_2.0.contents.short_channel_id,
                        fee_msat: 1000000,
-                       cltv_expiry_delta: 142,
+                       cltv_expiry_delta: TEST_FINAL_CLTV,
                });
                hops[1].fee_msat = chan_2.1.contents.fee_base_msat as u64 + chan_2.1.contents.fee_proportional_millionths as u64 * hops[2].fee_msat as u64 / 1000000;
                hops[0].fee_msat = chan_3.1.contents.fee_base_msat as u64 + chan_3.1.contents.fee_proportional_millionths as u64 * hops[1].fee_msat as u64 / 1000000;
-               let payment_preimage_2 = send_along_route(&nodes[1], Route { hops }, &vec!(&nodes[3], &nodes[2], &nodes[1])[..], 1000000).0;
+               let payment_hash_2 = send_along_route(&nodes[1], Route { hops }, &vec!(&nodes[3], &nodes[2], &nodes[1])[..], 1000000).1;
 
                // Claim the rebalances...
-               claim_payment(&nodes[1], &vec!(&nodes[3], &nodes[2], &nodes[1])[..], payment_preimage_2);
+               fail_payment(&nodes[1], &vec!(&nodes[3], &nodes[2], &nodes[1])[..], payment_hash_2);
                claim_payment(&nodes[1], &vec!(&nodes[2], &nodes[3], &nodes[1])[..], payment_preimage_1);
 
                // Add a duplicate new channel from 2 to 4
@@ -2340,4 +2637,261 @@ mod tests {
                        assert_eq!(node.chan_monitor.added_monitors.lock().unwrap().len(), 0);
                }
        }
+
+       #[derive(PartialEq)]
+       enum HTLCType { NONE, TIMEOUT, SUCCESS }
+       fn test_txn_broadcast(node: &Node, chan: &(msgs::ChannelUpdate, msgs::ChannelUpdate, Uint256, Transaction), commitment_tx: Option<Transaction>, has_htlc_tx: HTLCType) -> Vec<Transaction> {
+               let mut node_txn = node.tx_broadcaster.txn_broadcasted.lock().unwrap();
+               assert!(node_txn.len() >= if commitment_tx.is_some() { 0 } else { 1 } + if has_htlc_tx == HTLCType::NONE { 0 } else { 1 });
+
+               let mut res = Vec::with_capacity(2);
+
+               if let Some(explicit_tx) = commitment_tx {
+                       res.push(explicit_tx.clone());
+               } else {
+                       for tx in node_txn.iter() {
+                               if tx.input.len() == 1 && tx.input[0].prev_hash == chan.3.txid() {
+                                       let mut funding_tx_map = HashMap::new();
+                                       funding_tx_map.insert(chan.3.txid(), chan.3.clone());
+                                       tx.verify(&funding_tx_map).unwrap();
+                                       res.push(tx.clone());
+                               }
+                       }
+               }
+               assert_eq!(res.len(), 1);
+
+               if has_htlc_tx != HTLCType::NONE {
+                       for tx in node_txn.iter() {
+                               if tx.input.len() == 1 && tx.input[0].prev_hash == res[0].txid() {
+                                       let mut funding_tx_map = HashMap::new();
+                                       funding_tx_map.insert(res[0].txid(), res[0].clone());
+                                       tx.verify(&funding_tx_map).unwrap();
+                                       if has_htlc_tx == HTLCType::TIMEOUT {
+                                               assert!(tx.lock_time != 0);
+                                       } else {
+                                               assert!(tx.lock_time == 0);
+                                       }
+                                       res.push(tx.clone());
+                                       break;
+                               }
+                       }
+                       assert_eq!(res.len(), 2);
+               }
+               node_txn.clear();
+               res
+       }
+
+       fn check_preimage_claim(node: &Node, prev_txn: &Vec<Transaction>) -> Vec<Transaction> {
+               let mut node_txn = node.tx_broadcaster.txn_broadcasted.lock().unwrap();
+
+               assert!(node_txn.len() >= 1);
+               assert_eq!(node_txn[0].input.len(), 1);
+               let mut found_prev = false;
+
+               for tx in prev_txn {
+                       if node_txn[0].input[0].prev_hash == tx.txid() {
+                               let mut funding_tx_map = HashMap::new();
+                               funding_tx_map.insert(tx.txid(), tx.clone());
+                               node_txn[0].verify(&funding_tx_map).unwrap();
+
+                               assert!(node_txn[0].input[0].witness[2].len() > 106); // must spend an htlc output
+                               assert_eq!(tx.input.len(), 1); // must spend a commitment tx
+
+                               found_prev = true;
+                               break;
+                       }
+               }
+               assert!(found_prev);
+
+               let mut res = Vec::new();
+               mem::swap(&mut *node_txn, &mut res);
+               res
+       }
+
+       fn get_announce_close_broadcast_events(nodes: &Vec<Node>, a: usize, b: usize) {
+               let events_1 = nodes[a].node.get_and_clear_pending_events();
+               assert_eq!(events_1.len(), 1);
+               let as_update = match events_1[0] {
+                       Event::BroadcastChannelUpdate { ref msg } => {
+                               msg.clone()
+                       },
+                       _ => panic!("Unexpected event"),
+               };
+
+               let events_2 = nodes[b].node.get_and_clear_pending_events();
+               assert_eq!(events_2.len(), 1);
+               let bs_update = match events_2[0] {
+                       Event::BroadcastChannelUpdate { ref msg } => {
+                               msg.clone()
+                       },
+                       _ => panic!("Unexpected event"),
+               };
+
+               for node in nodes {
+                       node.router.handle_channel_update(&as_update).unwrap();
+                       node.router.handle_channel_update(&bs_update).unwrap();
+               }
+       }
+
+       #[test]
+       fn channel_monitor_network_test() {
+               // Simple test which builds a network of ChannelManagers, connects them to each other, and
+               // tests that ChannelMonitor is able to recover from various states.
+               let nodes = create_network(5);
+
+               // Create some initial channels
+               let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
+               let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
+               let chan_3 = create_announced_chan_between_nodes(&nodes, 2, 3);
+               let chan_4 = create_announced_chan_between_nodes(&nodes, 3, 4);
+
+               // Rebalance the network a bit by relaying one payment through all the channels...
+               send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3], &nodes[4])[..], 8000000);
+               send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3], &nodes[4])[..], 8000000);
+               send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3], &nodes[4])[..], 8000000);
+               send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2], &nodes[3], &nodes[4])[..], 8000000);
+
+               // Simple case with no pending HTLCs:
+               nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), true);
+               {
+                       let node_txn = test_txn_broadcast(&nodes[1], &chan_1, None, HTLCType::NONE);
+                       let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+                       nodes[0].chain_monitor.block_connected_checked(&header, 1, &[&node_txn[0]; 1], &[4; 1]);
+                       assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 0);
+               }
+               get_announce_close_broadcast_events(&nodes, 0, 1);
+               assert_eq!(nodes[0].node.list_channels().len(), 0);
+               assert_eq!(nodes[1].node.list_channels().len(), 1);
+
+               // One pending HTLC is discarded by the force-close:
+               let payment_preimage_1 = route_payment(&nodes[1], &vec!(&nodes[2], &nodes[3])[..], 3000000).0;
+
+               // Simple case of one pending HTLC to HTLC-Timeout
+               nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id(), true);
+               {
+                       let node_txn = test_txn_broadcast(&nodes[1], &chan_2, None, HTLCType::TIMEOUT);
+                       let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+                       nodes[2].chain_monitor.block_connected_checked(&header, 1, &[&node_txn[0]; 1], &[4; 1]);
+                       assert_eq!(nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 0);
+               }
+               get_announce_close_broadcast_events(&nodes, 1, 2);
+               assert_eq!(nodes[1].node.list_channels().len(), 0);
+               assert_eq!(nodes[2].node.list_channels().len(), 1);
+
+               macro_rules! claim_funds {
+                       ($node: expr, $prev_node: expr, $preimage: expr) => {
+                               {
+                                       assert!($node.node.claim_funds($preimage));
+                                       {
+                                               let mut added_monitors = $node.chan_monitor.added_monitors.lock().unwrap();
+                                               assert_eq!(added_monitors.len(), 1);
+                                               added_monitors.clear();
+                                       }
+
+                                       let events = $node.node.get_and_clear_pending_events();
+                                       assert_eq!(events.len(), 1);
+                                       match events[0] {
+                                               Event::SendFulfillHTLC { ref node_id, .. } => {
+                                                       assert_eq!(*node_id, $prev_node.node.get_our_node_id());
+                                               },
+                                               _ => panic!("Unexpected event"),
+                                       };
+                               }
+                       }
+               }
+
+               // nodes[3] gets the preimage, but nodes[2] already disconnected, resulting in a nodes[2]
+               // HTLC-Timeout and a nodes[3] claim against it (+ its own announces)
+               nodes[2].node.peer_disconnected(&nodes[3].node.get_our_node_id(), true);
+               {
+                       let node_txn = test_txn_broadcast(&nodes[2], &chan_3, None, HTLCType::TIMEOUT);
+
+                       // Claim the payment on nodes[3], giving it knowledge of the preimage
+                       claim_funds!(nodes[3], nodes[2], payment_preimage_1);
+
+                       let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+                       nodes[3].chain_monitor.block_connected_checked(&header, 1, &[&node_txn[0]; 1], &[4; 1]);
+
+                       check_preimage_claim(&nodes[3], &node_txn);
+               }
+               get_announce_close_broadcast_events(&nodes, 2, 3);
+               assert_eq!(nodes[2].node.list_channels().len(), 0);
+               assert_eq!(nodes[3].node.list_channels().len(), 1);
+
+               // One pending HTLC to time out:
+               let payment_preimage_2 = route_payment(&nodes[3], &vec!(&nodes[4])[..], 3000000).0;
+
+               {
+                       let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+                       nodes[3].chain_monitor.block_connected_checked(&header, 1, &Vec::new()[..], &[0; 0]);
+                       for i in 2..TEST_FINAL_CLTV - 5 {
+                               header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+                               nodes[3].chain_monitor.block_connected_checked(&header, i, &Vec::new()[..], &[0; 0]);
+                       }
+
+                       let node_txn = test_txn_broadcast(&nodes[3], &chan_4, None, HTLCType::TIMEOUT);
+
+                       // Claim the payment on nodes[3], giving it knowledge of the preimage
+                       claim_funds!(nodes[4], nodes[3], payment_preimage_2);
+
+                       header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+                       nodes[4].chain_monitor.block_connected_checked(&header, 1, &Vec::new()[..], &[0; 0]);
+                       for i in 2..TEST_FINAL_CLTV - 5 {
+                               header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+                               nodes[4].chain_monitor.block_connected_checked(&header, i, &Vec::new()[..], &[0; 0]);
+                       }
+
+                       test_txn_broadcast(&nodes[4], &chan_4, None, HTLCType::SUCCESS);
+
+                       header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+                       nodes[4].chain_monitor.block_connected_checked(&header, TEST_FINAL_CLTV - 5, &[&node_txn[0]; 1], &[4; 1]);
+
+                       check_preimage_claim(&nodes[4], &node_txn);
+               }
+               get_announce_close_broadcast_events(&nodes, 3, 4);
+               assert_eq!(nodes[3].node.list_channels().len(), 0);
+               assert_eq!(nodes[4].node.list_channels().len(), 0);
+
+               // Create some new channels:
+               let chan_5 = create_announced_chan_between_nodes(&nodes, 0, 1);
+
+               // A pending HTLC which will be revoked:
+               let payment_preimage_3 = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0;
+               // Get the will-be-revoked local txn from nodes[0]
+               let revoked_local_txn = nodes[0].node.channel_state.lock().unwrap().by_id.iter().next().unwrap().1.last_local_commitment_txn.clone();
+               // Revoke the old state
+               claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage_3);
+
+               {
+                       let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+                       nodes[1].chain_monitor.block_connected_checked(&header, 1, &vec![&revoked_local_txn[0]; 1], &[4; 1]);
+                       {
+                               let mut node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
+                               assert_eq!(node_txn.len(), 1);
+                               assert_eq!(node_txn[0].input.len(), 1);
+
+                               let mut funding_tx_map = HashMap::new();
+                               funding_tx_map.insert(revoked_local_txn[0].txid(), revoked_local_txn[0].clone());
+                               node_txn[0].verify(&funding_tx_map).unwrap();
+                               node_txn.clear();
+                       }
+
+                       nodes[0].chain_monitor.block_connected_checked(&header, 1, &vec![&revoked_local_txn[0]; 1], &[4; 0]);
+                       let node_txn = test_txn_broadcast(&nodes[0], &chan_5, Some(revoked_local_txn[0].clone()), HTLCType::TIMEOUT);
+                       header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+                       nodes[1].chain_monitor.block_connected_checked(&header, 1, &[&node_txn[1]; 1], &[4; 1]);
+
+                       //TODO: At this point nodes[1] should claim the revoked HTLC-Timeout output, but that's
+                       //not yet implemented in ChannelMonitor
+               }
+               get_announce_close_broadcast_events(&nodes, 0, 1);
+               assert_eq!(nodes[0].node.list_channels().len(), 0);
+               assert_eq!(nodes[1].node.list_channels().len(), 0);
+
+               // Check that we processed all pending events
+               for node in nodes {
+                       assert_eq!(node.node.get_and_clear_pending_events().len(), 0);
+                       assert_eq!(node.chan_monitor.added_monitors.lock().unwrap().len(), 0);
+               }
+       }
 }
index 3021163f9e7271493a4c9d30ea7e98413640091c..c36df8e754044f1295dc284fdfdc32b40cbf7d8a 100644 (file)
@@ -19,13 +19,31 @@ use std::collections::HashMap;
 use std::sync::{Arc,Mutex};
 use std::{hash,cmp};
 
+pub enum ChannelMonitorUpdateErr {
+       /// Used to indicate a temporary failure (eg connection to a watchtower failed, but is expected
+       /// to succeed at some point in the future).
+       /// Such a failure will "freeze" a channel, preventing us from revoking old states or
+       /// submitting new commitment transactions to the remote party.
+       /// ChannelManager::test_restore_channel_monitor can be used to retry the update(s) and restore
+       /// the channel to an operational state.
+       TemporaryFailure,
+       /// Used to indicate no further channel monitor updates will be allowed (eg we've moved on to a
+       /// different watchtower and cannot update with all watchtowers that were previously informed
+       /// of this channel). This will force-close the channel in question.
+       PermanentFailure,
+}
+
 /// Simple trait indicating ability to track a set of ChannelMonitors and multiplex events between
 /// them. Generally should be implemented by keeping a local SimpleManyChannelMonitor and passing
 /// events to it, while also taking any add_update_monitor events and passing them to some remote
 /// server(s).
+/// Note that any updates to a channel's monitor *must* be applied to each instance of the
+/// channel's monitor everywhere (including remote watchtowers) *before* this function returns. If
+/// an update occurs and a remote watchtower is left with old state, it may broadcast transactions
+/// which we have revoked, allowing our counterparty to claim all funds in the channel!
 pub trait ManyChannelMonitor: Send + Sync {
        /// Adds or updates a monitor for the given funding_txid+funding_output_index.
-       fn add_update_monitor(&self, funding_txo: (Sha256dHash, u16), monitor: ChannelMonitor) -> Result<(), HandleError>;
+       fn add_update_monitor(&self, funding_txo: (Sha256dHash, u16), monitor: ChannelMonitor) -> Result<(), ChannelMonitorUpdateErr>;
 }
 
 /// A simple implementation of a ManyChannelMonitor and ChainListener. Can be used to create a
@@ -81,68 +99,129 @@ impl<Key : Send + cmp::Eq + hash::Hash + 'static> SimpleManyChannelMonitor<Key>
 }
 
 impl ManyChannelMonitor for SimpleManyChannelMonitor<(Sha256dHash, u16)> {
-       fn add_update_monitor(&self, funding_txo: (Sha256dHash, u16), monitor: ChannelMonitor) -> Result<(), HandleError> {
-               self.add_update_monitor_by_key(funding_txo, monitor)
+       fn add_update_monitor(&self, funding_txo: (Sha256dHash, u16), monitor: ChannelMonitor) -> Result<(), ChannelMonitorUpdateErr> {
+               match self.add_update_monitor_by_key(funding_txo, monitor) {
+                       Ok(_) => Ok(()),
+                       Err(_) => Err(ChannelMonitorUpdateErr::PermanentFailure),
+               }
        }
 }
 
-/// If an HTLC expires within this many blocks, don't try to claim it directly, instead broadcast
-/// the HTLC-Success/HTLC-Timeout transaction and claim the revocation from that.
-const CLTV_CLAIM_BUFFER: u32 = 12;
+/// If an HTLC expires within this many blocks, don't try to claim it in a shared transaction,
+/// instead claiming it in its own individual transaction.
+const CLTV_SHARED_CLAIM_BUFFER: u32 = 12;
+/// If an HTLC expires within this many blocks, force-close the channel to broadcast the
+/// HTLC-Success transaction.
+const CLTV_CLAIM_BUFFER: u32 = 6;
 
 #[derive(Clone)]
-enum RevocationStorage {
+enum KeyStorage {
        PrivMode {
                revocation_base_key: SecretKey,
+               htlc_base_key: SecretKey,
        },
        SigsMode {
                revocation_base_key: PublicKey,
+               htlc_base_key: PublicKey,
                sigs: HashMap<Sha256dHash, Signature>,
        }
 }
 
 #[derive(Clone)]
-struct PerCommitmentTransactionData {
-       revoked_output_index: u32,
-       htlcs: Vec<(HTLCOutputInCommitment, Signature)>,
+struct LocalSignedTx {
+       txid: Sha256dHash,
+       tx: Transaction,
+       revocation_key: PublicKey,
+       a_htlc_key: PublicKey,
+       b_htlc_key: PublicKey,
+       delayed_payment_key: PublicKey,
+       feerate_per_kw: u64,
+       htlc_outputs: Vec<(HTLCOutputInCommitment, Signature, Signature)>,
 }
 
-#[derive(Clone)]
 pub struct ChannelMonitor {
        funding_txo: Option<(Sha256dHash, u16)>,
        commitment_transaction_number_obscure_factor: u64,
 
-       revocation_base_key: RevocationStorage,
+       key_storage: KeyStorage,
        delayed_payment_base_key: PublicKey,
-       htlc_base_key: PublicKey,
        their_htlc_base_key: Option<PublicKey>,
-       to_self_delay: u16,
+       // first is the idx of the first of the two revocation points
+       their_cur_revocation_points: Option<(u64, PublicKey, Option<PublicKey>)>,
+
+       our_to_self_delay: u16,
+       their_to_self_delay: Option<u16>,
 
        old_secrets: [([u8; 32], u64); 49],
-       claimable_outpoints: HashMap<Sha256dHash, PerCommitmentTransactionData>,
-       payment_preimages: Vec<[u8; 32]>,
+       remote_claimable_outpoints: HashMap<Sha256dHash, Vec<HTLCOutputInCommitment>>,
+       remote_htlc_outputs_on_chain: Mutex<HashMap<Sha256dHash, u64>>,
+
+       // We store two local commitment transactions to avoid any race conditions where we may update
+       // some monitors (potentially on watchtowers) but then fail to update others, resulting in the
+       // various monitors for one channel being out of sync, and us broadcasting a local
+       // transaction for which we have deleted claim information on some watchtowers.
+       prev_local_signed_commitment_tx: Option<LocalSignedTx>,
+       current_local_signed_commitment_tx: Option<LocalSignedTx>,
+
+       payment_preimages: HashMap<[u8; 32], [u8; 32]>,
 
        destination_script: Script,
        secp_ctx: Secp256k1, //TODO: dedup this a bit...
 }
+impl Clone for ChannelMonitor {
+       fn clone(&self) -> Self {
+               ChannelMonitor {
+                       funding_txo: self.funding_txo.clone(),
+                       commitment_transaction_number_obscure_factor: self.commitment_transaction_number_obscure_factor.clone(),
+
+                       key_storage: self.key_storage.clone(),
+                       delayed_payment_base_key: self.delayed_payment_base_key.clone(),
+                       their_htlc_base_key: self.their_htlc_base_key.clone(),
+                       their_cur_revocation_points: self.their_cur_revocation_points.clone(),
+
+                       our_to_self_delay: self.our_to_self_delay,
+                       their_to_self_delay: self.their_to_self_delay,
+
+                       old_secrets: self.old_secrets.clone(),
+                       remote_claimable_outpoints: self.remote_claimable_outpoints.clone(),
+                       remote_htlc_outputs_on_chain: Mutex::new((*self.remote_htlc_outputs_on_chain.lock().unwrap()).clone()),
+
+                       prev_local_signed_commitment_tx: self.prev_local_signed_commitment_tx.clone(),
+                       current_local_signed_commitment_tx: self.current_local_signed_commitment_tx.clone(),
+
+                       payment_preimages: self.payment_preimages.clone(),
+
+                       destination_script: self.destination_script.clone(),
+                       secp_ctx: self.secp_ctx.clone(),
+               }
+       }
+}
 
 impl ChannelMonitor {
-       pub fn new(revocation_base_key: &SecretKey, delayed_payment_base_key: &PublicKey, htlc_base_key: &PublicKey, to_self_delay: u16, destination_script: Script) -> ChannelMonitor {
+       pub fn new(revocation_base_key: &SecretKey, delayed_payment_base_key: &PublicKey, htlc_base_key: &SecretKey, our_to_self_delay: u16, destination_script: Script) -> ChannelMonitor {
                ChannelMonitor {
                        funding_txo: None,
                        commitment_transaction_number_obscure_factor: 0,
 
-                       revocation_base_key: RevocationStorage::PrivMode {
+                       key_storage: KeyStorage::PrivMode {
                                revocation_base_key: revocation_base_key.clone(),
+                               htlc_base_key: htlc_base_key.clone(),
                        },
                        delayed_payment_base_key: delayed_payment_base_key.clone(),
-                       htlc_base_key: htlc_base_key.clone(),
                        their_htlc_base_key: None,
-                       to_self_delay: to_self_delay,
+                       their_cur_revocation_points: None,
+
+                       our_to_self_delay: our_to_self_delay,
+                       their_to_self_delay: None,
 
                        old_secrets: [([0; 32], 1 << 48); 49],
-                       claimable_outpoints: HashMap::new(),
-                       payment_preimages: Vec::new(),
+                       remote_claimable_outpoints: HashMap::new(),
+                       remote_htlc_outputs_on_chain: Mutex::new(HashMap::new()),
+
+                       prev_local_signed_commitment_tx: None,
+                       current_local_signed_commitment_tx: None,
+
+                       payment_preimages: HashMap::new(),
 
                        destination_script: destination_script,
                        secp_ctx: Secp256k1::new(),
@@ -174,10 +253,10 @@ impl ChannelMonitor {
                res
        }
 
-       /// Inserts a revocation secret into this channel monitor. Requires the revocation_base_key of
-       /// the node which we are monitoring the channel on behalf of in order to generate signatures
-       /// over revocation-claim transactions.
-       pub fn provide_secret(&mut self, idx: u64, secret: [u8; 32]) -> Result<(), HandleError> {
+       /// Inserts a revocation secret into this channel monitor. Also optionally tracks the next
+       /// revocation point which may be required to claim HTLC outputs which we know the preimage of
+       /// in case the remote end force-closes using their latest state.
+       pub fn provide_secret(&mut self, idx: u64, secret: [u8; 32], their_next_revocation_point: Option<(u64, PublicKey)>) -> Result<(), HandleError> {
                let pos = ChannelMonitor::place_secret(idx);
                for i in 0..pos {
                        let (old_secret, old_idx) = self.old_secrets[i as usize];
@@ -186,25 +265,71 @@ impl ChannelMonitor {
                        }
                }
                self.old_secrets[pos as usize] = (secret, idx);
+
+               if let Some(new_revocation_point) = their_next_revocation_point {
+                       match self.their_cur_revocation_points {
+                               Some(old_points) => {
+                                       if old_points.0 == new_revocation_point.0 + 1 {
+                                               self.their_cur_revocation_points = Some((old_points.0, old_points.1, Some(new_revocation_point.1)));
+                                       } else if old_points.0 == new_revocation_point.0 + 2 {
+                                               if let Some(old_second_point) = old_points.2 {
+                                                       self.their_cur_revocation_points = Some((old_points.0 - 1, old_second_point, Some(new_revocation_point.1)));
+                                               } else {
+                                                       self.their_cur_revocation_points = Some((new_revocation_point.0, new_revocation_point.1, None));
+                                               }
+                                       } else {
+                                               self.their_cur_revocation_points = Some((new_revocation_point.0, new_revocation_point.1, None));
+                                       }
+                               },
+                               None => {
+                                       self.their_cur_revocation_points = Some((new_revocation_point.0, new_revocation_point.1, None));
+                               }
+                       }
+               }
+               // TODO: Prune payment_preimages no longer needed by the revocation (just have to check
+               // that non-revoked remote commitment tx(n) do not need it, and our latest local commitment
+               // tx does not need it.
                Ok(())
        }
 
-       /// Informs this watcher of the set of HTLC outputs in a commitment transaction which our
-       /// counterparty may broadcast. This allows us to reconstruct the commitment transaction's
-       /// outputs fully, claiming revoked, unexpired HTLC outputs as well as revoked refund outputs.
-       /// TODO: Doc new params!
-       /// TODO: This seems to be wrong...we should be calling this from commitment_signed, but we
-       /// should be calling this about remote transactions, ie ones that they can revoke_and_ack...
-       pub fn provide_tx_info(&mut self, commitment_tx: &Transaction, revokeable_out_index: u32, htlc_outputs: Vec<(HTLCOutputInCommitment, Signature)>) {
+       /// Informs this monitor of the latest remote (ie non-broadcastable) commitment transaction.
+       /// The monitor watches for it to be broadcasted and then uses the HTLC information (and
+       /// possibly future revocation/preimage information) to claim outputs where possible.
+       pub fn provide_latest_remote_commitment_tx_info(&mut self, unsigned_commitment_tx: &Transaction, htlc_outputs: Vec<HTLCOutputInCommitment>) {
                // TODO: Encrypt the htlc_outputs data with the single-hash of the commitment transaction
                // so that a remote monitor doesn't learn anything unless there is a malicious close.
-               self.claimable_outpoints.insert(commitment_tx.txid(), PerCommitmentTransactionData{
-                       revoked_output_index: revokeable_out_index,
-                       htlcs: htlc_outputs
+               // (only maybe, sadly we cant do the same for local info, as we need to be aware of
+               // timeouts)
+               self.remote_claimable_outpoints.insert(unsigned_commitment_tx.txid(), htlc_outputs);
+       }
+
+       /// Informs this monitor of the latest local (ie broadcastable) commitment transaction. The
+       /// monitor watches for timeouts and may broadcast it if we approach such a timeout. Thus, it
+       /// is important that any clones of this channel monitor (including remote clones) by kept
+       /// up-to-date as our local commitment transaction is updated.
+       /// Panics if set_their_to_self_delay has never been called.
+       pub fn provide_latest_local_commitment_tx_info(&mut self, signed_commitment_tx: Transaction, local_keys: chan_utils::TxCreationKeys, feerate_per_kw: u64, htlc_outputs: Vec<(HTLCOutputInCommitment, Signature, Signature)>) {
+               assert!(self.their_to_self_delay.is_some());
+               self.prev_local_signed_commitment_tx = self.current_local_signed_commitment_tx.take();
+               self.current_local_signed_commitment_tx = Some(LocalSignedTx {
+                       txid: signed_commitment_tx.txid(),
+                       tx: signed_commitment_tx,
+                       revocation_key: local_keys.revocation_key,
+                       a_htlc_key: local_keys.a_htlc_key,
+                       b_htlc_key: local_keys.b_htlc_key,
+                       delayed_payment_key: local_keys.a_delayed_payment_key,
+                       feerate_per_kw,
+                       htlc_outputs,
                });
        }
 
-       pub fn insert_combine(&mut self, other: ChannelMonitor) -> Result<(), HandleError> {
+       /// Provides a payment_hash->payment_preimage mapping. Will be automatically pruned when all
+       /// commitment_tx_infos which contain the payment hash have been revoked.
+       pub fn provide_payment_preimage(&mut self, payment_hash: &[u8; 32], payment_preimage: &[u8; 32]) {
+               self.payment_preimages.insert(payment_hash.clone(), payment_preimage.clone());
+       }
+
+       pub fn insert_combine(&mut self, mut other: ChannelMonitor) -> Result<(), HandleError> {
                match self.funding_txo {
                        Some(txo) => if other.funding_txo.is_some() && other.funding_txo.unwrap() != txo {
                                return Err(HandleError{err: "Funding transaction outputs are not identical!", msg: None});
@@ -213,10 +338,25 @@ impl ChannelMonitor {
                                self.funding_txo = other.funding_txo;
                        }
                }
-               let other_max_secret = other.get_min_seen_secret();
-               if self.get_min_seen_secret() > other_max_secret {
-                       self.provide_secret(other_max_secret, other.get_secret(other_max_secret).unwrap())
-               } else { Ok(()) }
+               let other_min_secret = other.get_min_seen_secret();
+               let our_min_secret = self.get_min_seen_secret();
+               if our_min_secret > other_min_secret {
+                       self.provide_secret(other_min_secret, other.get_secret(other_min_secret).unwrap(), None)?;
+               }
+               if our_min_secret >= other_min_secret {
+                       self.their_cur_revocation_points = other.their_cur_revocation_points;
+                       for (txid, htlcs) in other.remote_claimable_outpoints.drain() {
+                               self.remote_claimable_outpoints.insert(txid, htlcs);
+                       }
+                       if let Some(local_tx) = other.prev_local_signed_commitment_tx {
+                               self.prev_local_signed_commitment_tx = Some(local_tx);
+                       }
+                       if let Some(local_tx) = other.current_local_signed_commitment_tx {
+                               self.current_local_signed_commitment_tx = Some(local_tx);
+                       }
+                       self.payment_preimages = other.payment_preimages;
+               }
+               Ok(())
        }
 
        /// Panics if commitment_transaction_number_obscure_factor doesn't fit in 48 bits
@@ -237,6 +377,10 @@ impl ChannelMonitor {
                self.their_htlc_base_key = Some(their_htlc_base_key.clone());
        }
 
+       pub fn set_their_to_self_delay(&mut self, their_to_self_delay: u16) {
+               self.their_to_self_delay = Some(their_to_self_delay);
+       }
+
        pub fn unset_funding_info(&mut self) {
                self.funding_txo = None;
        }
@@ -270,113 +414,147 @@ impl ChannelMonitor {
                min
        }
 
-       pub fn provide_payment_preimage(&mut self, payment_preimage: &[u8; 32]) {
-               //TODO: Some kind of timeout here or ability to mark all states containing this preimage
-               //revoked?
-               self.payment_preimages.push(payment_preimage.clone());
-       }
-
-       #[inline]
-       fn check_spend_transaction(&self, tx: &Transaction, height: u32) -> Vec<Transaction> {
+       /// Attempts to claim a remote commitment transaction's outputs using the revocation key and
+       /// data in remote_claimable_outpoints. Will directly claim any HTLC outputs which expire at a
+       /// height > height + CLTV_SHARED_CLAIM_BUFFER. In any case, will install monitoring for
+       /// HTLC-Success/HTLC-Timeout transactions, and claim them using the revocation key (if
+       /// applicable) as well.
+       fn check_spend_remote_transaction(&self, tx: &Transaction, height: u32) -> Vec<Transaction> {
                // Most secp and related errors trying to create keys means we have no hope of constructing
                // a spend transaction...so we return no transactions to broadcast
+               let mut txn_to_broadcast = Vec::new();
                macro_rules! ignore_error {
                        ( $thing : expr ) => {
                                match $thing {
                                        Ok(a) => a,
-                                       Err(_) => return Vec::new()
+                                       Err(_) => return txn_to_broadcast
                                }
                        };
                }
 
-               let mut txn_to_broadcast = Vec::new();
+               let commitment_txid = tx.txid(); //TODO: This is gonna be a performance bottleneck for watchtowers!
+               let per_commitment_option = self.remote_claimable_outpoints.get(&commitment_txid);
 
                let commitment_number = (((tx.input[0].sequence as u64 & 0xffffff) << 3*8) | (tx.lock_time as u64 & 0xffffff)) ^ self.commitment_transaction_number_obscure_factor;
                if commitment_number >= self.get_min_seen_secret() {
                        let secret = self.get_secret(commitment_number).unwrap();
                        let per_commitment_key = ignore_error!(SecretKey::from_slice(&self.secp_ctx, &secret));
-                       let revocation_pubkey = match self.revocation_base_key {
-                               RevocationStorage::PrivMode { ref revocation_base_key } => {
-                                       ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, &ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key)), &ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &revocation_base_key))))
+                       let (revocation_pubkey, b_htlc_key) = match self.key_storage {
+                               KeyStorage::PrivMode { ref revocation_base_key, ref htlc_base_key } => {
+                                       let per_commitment_point = ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key));
+                                       (ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, &per_commitment_point, &ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &revocation_base_key)))),
+                                       ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &per_commitment_point, &ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &htlc_base_key)))))
                                },
-                               RevocationStorage::SigsMode { ref revocation_base_key, .. } => {
-                                       ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, &ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key)), &revocation_base_key))
+                               KeyStorage::SigsMode { ref revocation_base_key, ref htlc_base_key, .. } => {
+                                       let per_commitment_point = ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key));
+                                       (ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, &per_commitment_point, &revocation_base_key)),
+                                       ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &per_commitment_point, &htlc_base_key)))
                                },
                        };
                        let delayed_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key)), &self.delayed_payment_base_key));
-                       let a_htlc_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key)), &self.htlc_base_key));
-                       let b_htlc_key = match self.their_htlc_base_key {
-                               None => return Vec::new(),
+                       let a_htlc_key = match self.their_htlc_base_key {
+                               None => return txn_to_broadcast,
                                Some(their_htlc_base_key) => ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key)), &their_htlc_base_key)),
                        };
 
-                       let revokeable_redeemscript = chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.to_self_delay, &delayed_key);
-
-                       let commitment_txid = tx.txid();
+                       let revokeable_redeemscript = chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.our_to_self_delay, &delayed_key);
+                       let revokeable_p2wsh = revokeable_redeemscript.to_v0_p2wsh();
 
                        let mut total_value = 0;
                        let mut values = Vec::new();
-                       let inputs = match self.claimable_outpoints.get(&commitment_txid) {
-                               Some(per_commitment_data) => {
-                                       let mut inp = Vec::with_capacity(per_commitment_data.htlcs.len() + 1);
-
-                                       if per_commitment_data.revoked_output_index as usize >= tx.output.len() || tx.output[per_commitment_data.revoked_output_index as usize].script_pubkey != revokeable_redeemscript.to_v0_p2wsh() {
-                                               return Vec::new(); // Corrupted per_commitment_data, not much we can do
-                                       }
+                       let mut inputs = Vec::new();
+                       let mut htlc_idxs = Vec::new();
 
-                                       inp.push(TxIn {
+                       for (idx, outp) in tx.output.iter().enumerate() {
+                               if outp.script_pubkey == revokeable_p2wsh {
+                                       inputs.push(TxIn {
                                                prev_hash: commitment_txid,
-                                               prev_index: per_commitment_data.revoked_output_index,
+                                               prev_index: idx as u32,
                                                script_sig: Script::new(),
-                                               sequence: 0xffffffff,
+                                               sequence: 0xfffffffd,
                                                witness: Vec::new(),
                                        });
-                                       values.push(tx.output[per_commitment_data.revoked_output_index as usize].value);
-                                       total_value += tx.output[per_commitment_data.revoked_output_index as usize].value;
-
-                                       for &(ref htlc, ref _next_tx_sig) in per_commitment_data.htlcs.iter() {
-                                               let expected_script = chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, &a_htlc_key, &b_htlc_key, &revocation_pubkey);
-                                               if htlc.transaction_output_index as usize >= tx.output.len() ||
-                                                               tx.output[htlc.transaction_output_index as usize].value != htlc.amount_msat / 1000 ||
-                                                               tx.output[htlc.transaction_output_index as usize].script_pubkey != expected_script.to_v0_p2wsh() {
-                                                       return Vec::new(); // Corrupted per_commitment_data, fuck this user
-                                               }
-                                               if htlc.cltv_expiry > height + CLTV_CLAIM_BUFFER {
-                                                       inp.push(TxIn {
-                                                               prev_hash: commitment_txid,
-                                                               prev_index: htlc.transaction_output_index,
-                                                               script_sig: Script::new(),
-                                                               sequence: 0xffffffff,
-                                                               witness: Vec::new(),
-                                                       });
-                                                       values.push(tx.output[htlc.transaction_output_index as usize].value);
-                                                       total_value += htlc.amount_msat / 1000;
+                                       htlc_idxs.push(None);
+                                       values.push(outp.value);
+                                       total_value += outp.value;
+                                       break; // There can only be one of these
+                               }
+                       }
+
+                       macro_rules! sign_input {
+                               ($sighash_parts: expr, $input: expr, $htlc_idx: expr, $amount: expr) => {
+                                       {
+                                               let (sig, redeemscript) = match self.key_storage {
+                                                       KeyStorage::PrivMode { ref revocation_base_key, .. } => {
+                                                               let redeemscript = if $htlc_idx.is_none() { revokeable_redeemscript.clone() } else {
+                                                                       let htlc = &per_commitment_option.unwrap()[$htlc_idx.unwrap()];
+                                                                       chan_utils::get_htlc_redeemscript_with_explicit_keys(htlc, &a_htlc_key, &b_htlc_key, &revocation_pubkey)
+                                                               };
+                                                               let sighash = ignore_error!(Message::from_slice(&$sighash_parts.sighash_all(&$input, &redeemscript, $amount)[..]));
+                                                               let revocation_key = ignore_error!(chan_utils::derive_private_revocation_key(&self.secp_ctx, &per_commitment_key, &revocation_base_key));
+                                                               (ignore_error!(self.secp_ctx.sign(&sighash, &revocation_key)), redeemscript)
+                                                       },
+                                                       KeyStorage::SigsMode { .. } => {
+                                                               unimplemented!();
+                                                       }
+                                               };
+                                               $input.witness.push(sig.serialize_der(&self.secp_ctx).to_vec());
+                                               $input.witness[0].push(SigHashType::All as u8);
+                                               if $htlc_idx.is_none() {
+                                                       $input.witness.push(vec!(1));
                                                } else {
-                                                       //TODO: Mark as "bad"
-                                                       //then broadcast using next_tx_sig
+                                                       $input.witness.push(revocation_pubkey.serialize().to_vec());
                                                }
+                                               $input.witness.push(redeemscript.into_vec());
                                        }
-                                       inp
-                               }, None => {
-                                       let mut inp = Vec::new(); // This is unlikely to succeed
-                                       for (idx, outp) in tx.output.iter().enumerate() {
-                                               if outp.script_pubkey == revokeable_redeemscript.to_v0_p2wsh() {
-                                                       inp.push(TxIn {
-                                                               prev_hash: commitment_txid,
-                                                               prev_index: idx as u32,
-                                                               script_sig: Script::new(),
-                                                               sequence: 0xffffffff,
-                                                               witness: Vec::new(),
-                                                       });
-                                                       values.push(outp.value);
-                                                       total_value += outp.value;
-                                                       break; // There can only be one of these
-                                               }
+                               }
+                       }
+
+                       if let Some(per_commitment_data) = per_commitment_option {
+                               inputs.reserve_exact(per_commitment_data.len());
+
+                               for (idx, htlc) in per_commitment_data.iter().enumerate() {
+                                       let expected_script = chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, &a_htlc_key, &b_htlc_key, &revocation_pubkey);
+                                       if htlc.transaction_output_index as usize >= tx.output.len() ||
+                                                       tx.output[htlc.transaction_output_index as usize].value != htlc.amount_msat / 1000 ||
+                                                       tx.output[htlc.transaction_output_index as usize].script_pubkey != expected_script.to_v0_p2wsh() {
+                                               return txn_to_broadcast; // Corrupted per_commitment_data, fuck this user
+                                       }
+                                       let input = TxIn {
+                                               prev_hash: commitment_txid,
+                                               prev_index: htlc.transaction_output_index,
+                                               script_sig: Script::new(),
+                                               sequence: 0xfffffffd,
+                                               witness: Vec::new(),
+                                       };
+                                       if htlc.cltv_expiry > height + CLTV_SHARED_CLAIM_BUFFER {
+                                               inputs.push(input);
+                                               htlc_idxs.push(Some(idx));
+                                               values.push(tx.output[htlc.transaction_output_index as usize].value);
+                                               total_value += htlc.amount_msat / 1000;
+                                       } else {
+                                               let mut single_htlc_tx = Transaction {
+                                                       version: 2,
+                                                       lock_time: 0,
+                                                       input: vec![input],
+                                                       output: vec!(TxOut {
+                                                               script_pubkey: self.destination_script.clone(),
+                                                               value: htlc.amount_msat / 1000, //TODO: - fee
+                                                       }),
+                                               };
+                                               let sighash_parts = bip143::SighashComponents::new(&single_htlc_tx);
+                                               sign_input!(sighash_parts, single_htlc_tx.input[0], Some(idx), htlc.amount_msat / 1000);
+                                               txn_to_broadcast.push(single_htlc_tx); // TODO: This is not yet tested in ChannelManager!
                                        }
-                                       if inp.is_empty() { return Vec::new(); } // Nothing to be done...probably a false positive
-                                       inp
                                }
-                       };
+                       }
+
+                       if !inputs.is_empty() || !txn_to_broadcast.is_empty() {
+                               // We're definitely a remote commitment transaction!
+                               // TODO: Register commitment_txid with the ChainWatchInterface!
+                               self.remote_htlc_outputs_on_chain.lock().unwrap().insert(commitment_txid, commitment_number);
+                       }
+                       if inputs.is_empty() { return txn_to_broadcast; } // Nothing to be done...probably a false positive/local tx
 
                        let outputs = vec!(TxOut {
                                script_pubkey: self.destination_script.clone(),
@@ -390,82 +568,227 @@ impl ChannelMonitor {
                        };
 
                        let mut values_drain = values.drain(..);
-
-                       // First input is the generic revokeable_redeemscript
                        let sighash_parts = bip143::SighashComponents::new(&spend_tx);
-                       {
-                               let sig = match self.revocation_base_key {
-                                       RevocationStorage::PrivMode { ref revocation_base_key } => {
-                                               let sighash = ignore_error!(Message::from_slice(&sighash_parts.sighash_all(&spend_tx.input[0], &revokeable_redeemscript, values_drain.next().unwrap())[..]));
-                                               let revocation_key = ignore_error!(chan_utils::derive_private_revocation_key(&self.secp_ctx, &per_commitment_key, &revocation_base_key));
-                                               ignore_error!(self.secp_ctx.sign(&sighash, &revocation_key))
-                                       },
-                                       RevocationStorage::SigsMode { .. } => {
-                                               unimplemented!();
-                                       }
-                               };
 
-                               spend_tx.input[0].witness.push(sig.serialize_der(&self.secp_ctx).to_vec());
-                               spend_tx.input[0].witness[0].push(SigHashType::All as u8);
-                               spend_tx.input[0].witness.push(vec!(1)); // First if branch is revocation_key
+                       for (input, htlc_idx) in spend_tx.input.iter_mut().zip(htlc_idxs.iter()) {
+                               let value = values_drain.next().unwrap();
+                               sign_input!(sighash_parts, input, htlc_idx, value);
                        }
 
-                       match self.claimable_outpoints.get(&commitment_txid) {
-                               None => {},
-                               Some(per_commitment_data) => {
-                                       let mut htlc_idx = 0;
-                                       for (idx, input) in spend_tx.input.iter_mut().enumerate() {
-                                               if idx == 0 { continue; } // We already signed the first input
-
-                                               let mut htlc;
-                                               while {
-                                                       htlc = &per_commitment_data.htlcs[htlc_idx].0;
-                                                       htlc_idx += 1;
-                                                       htlc.cltv_expiry > height + CLTV_CLAIM_BUFFER
-                                               } {}
-
-                                               let sig = match self.revocation_base_key {
-                                                       RevocationStorage::PrivMode { ref revocation_base_key } => {
-                                                               let htlc_redeemscript = chan_utils::get_htlc_redeemscript_with_explicit_keys(htlc, &a_htlc_key, &b_htlc_key, &revocation_pubkey);
-                                                               let sighash = ignore_error!(Message::from_slice(&sighash_parts.sighash_all(&input, &htlc_redeemscript, values_drain.next().unwrap())[..]));
+                       txn_to_broadcast.push(spend_tx);
+               } else if let Some(per_commitment_data) = per_commitment_option {
+                       if let Some(revocation_points) = self.their_cur_revocation_points {
+                               let revocation_point_option =
+                                       if revocation_points.0 == commitment_number { Some(&revocation_points.1) }
+                                       else if let Some(point) = revocation_points.2.as_ref() {
+                                               if revocation_points.0 == commitment_number + 1 { Some(point) } else { None }
+                                       } else { None };
+                               if let Some(revocation_point) = revocation_point_option {
+                                       let (revocation_pubkey, b_htlc_key) = match self.key_storage {
+                                               KeyStorage::PrivMode { ref revocation_base_key, ref htlc_base_key } => {
+                                                       (ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, revocation_point, &ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &revocation_base_key)))),
+                                                       ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, revocation_point, &ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &htlc_base_key)))))
+                                               },
+                                               KeyStorage::SigsMode { ref revocation_base_key, ref htlc_base_key, .. } => {
+                                                       (ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, revocation_point, &revocation_base_key)),
+                                                       ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, revocation_point, &htlc_base_key)))
+                                               },
+                                       };
+                                       let a_htlc_key = match self.their_htlc_base_key {
+                                               None => return txn_to_broadcast,
+                                               Some(their_htlc_base_key) => ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, revocation_point, &their_htlc_base_key)),
+                                       };
+
+                                       let mut total_value = 0;
+                                       let mut values = Vec::new();
+                                       let mut inputs = Vec::new();
+
+                                       macro_rules! sign_input {
+                                               ($sighash_parts: expr, $input: expr, $amount: expr, $preimage: expr) => {
+                                                       {
+                                                               let (sig, redeemscript) = match self.key_storage {
+                                                                       KeyStorage::PrivMode { ref htlc_base_key, .. } => {
+                                                                               let htlc = &per_commitment_option.unwrap()[$input.sequence as usize];
+                                                                               let redeemscript = chan_utils::get_htlc_redeemscript_with_explicit_keys(htlc, &a_htlc_key, &b_htlc_key, &revocation_pubkey);
+                                                                               let sighash = ignore_error!(Message::from_slice(&$sighash_parts.sighash_all(&$input, &redeemscript, $amount)[..]));
+                                                                               let htlc_key = ignore_error!(chan_utils::derive_private_key(&self.secp_ctx, revocation_point, &htlc_base_key));
+                                                                               (ignore_error!(self.secp_ctx.sign(&sighash, &htlc_key)), redeemscript)
+                                                                       },
+                                                                       KeyStorage::SigsMode { .. } => {
+                                                                               unimplemented!();
+                                                                       }
+                                                               };
+                                                               $input.witness.push(sig.serialize_der(&self.secp_ctx).to_vec());
+                                                               $input.witness[0].push(SigHashType::All as u8);
+                                                               $input.witness.push($preimage);
+                                                               $input.witness.push(redeemscript.into_vec());
+                                                       }
+                                               }
+                                       }
 
-                                                               let revocation_key = ignore_error!(chan_utils::derive_private_revocation_key(&self.secp_ctx, &per_commitment_key, &revocation_base_key));
-                                                               ignore_error!(self.secp_ctx.sign(&sighash, &revocation_key))
-                                                       },
-                                                       RevocationStorage::SigsMode { .. } => {
-                                                               unimplemented!();
+                                       for (idx, htlc) in per_commitment_data.iter().enumerate() {
+                                               if let Some(payment_preimage) = self.payment_preimages.get(&htlc.payment_hash) {
+                                                       let input = TxIn {
+                                                               prev_hash: commitment_txid,
+                                                               prev_index: htlc.transaction_output_index,
+                                                               script_sig: Script::new(),
+                                                               sequence: idx as u32, // reset to 0xfffffffd in sign_input
+                                                               witness: Vec::new(),
+                                                       };
+                                                       if htlc.cltv_expiry > height + CLTV_SHARED_CLAIM_BUFFER {
+                                                               inputs.push(input);
+                                                               values.push((tx.output[htlc.transaction_output_index as usize].value, payment_preimage));
+                                                               total_value += htlc.amount_msat / 1000;
+                                                       } else {
+                                                               let mut single_htlc_tx = Transaction {
+                                                                       version: 2,
+                                                                       lock_time: 0,
+                                                                       input: vec![input],
+                                                                       output: vec!(TxOut {
+                                                                               script_pubkey: self.destination_script.clone(),
+                                                                               value: htlc.amount_msat / 1000, //TODO: - fee
+                                                                       }),
+                                                               };
+                                                               let sighash_parts = bip143::SighashComponents::new(&single_htlc_tx);
+                                                               sign_input!(sighash_parts, single_htlc_tx.input[0], htlc.amount_msat / 1000, payment_preimage.to_vec());
+                                                               txn_to_broadcast.push(single_htlc_tx);
                                                        }
-                                               };
+                                               }
+                                       }
 
-                                               input.witness.push(revocation_pubkey.serialize().to_vec()); // First if branch is revocation_key
-                                               input.witness.push(sig.serialize_der(&self.secp_ctx).to_vec());
-                                               input.witness[0].push(SigHashType::All as u8);
+                                       if inputs.is_empty() { return txn_to_broadcast; } // Nothing to be done...probably a false positive/local tx
+
+                                       let outputs = vec!(TxOut {
+                                               script_pubkey: self.destination_script.clone(),
+                                               value: total_value, //TODO: - fee
+                                       });
+                                       let mut spend_tx = Transaction {
+                                               version: 2,
+                                               lock_time: 0,
+                                               input: inputs,
+                                               output: outputs,
+                                       };
+
+                                       let mut values_drain = values.drain(..);
+                                       let sighash_parts = bip143::SighashComponents::new(&spend_tx);
+
+                                       for input in spend_tx.input.iter_mut() {
+                                               let value = values_drain.next().unwrap();
+                                               sign_input!(sighash_parts, input, value.0, value.1.to_vec());
                                        }
+
+                                       txn_to_broadcast.push(spend_tx);
                                }
                        }
-
-                       txn_to_broadcast.push(spend_tx);
+               } else {
+                       //TODO: For each input check if its in our remote_htlc_outputs_on_chain map!
                }
 
                txn_to_broadcast
        }
 
-       fn block_connected(&self, txn_matched: &[&Transaction], height: u32, broadcaster: &BroadcasterInterface) {
-               for tx in txn_matched {
-                       if tx.input.len() != 1 {
-                               // We currently only ever sign something spending a commitment or HTLC
-                               // transaction with 1 input, so we can skip most transactions trivially.
-                               continue;
+       fn broadcast_by_local_state(&self, local_tx: &LocalSignedTx) -> Vec<Transaction> {
+               let mut res = Vec::with_capacity(local_tx.htlc_outputs.len());
+
+               for &(ref htlc, ref their_sig, ref our_sig) in local_tx.htlc_outputs.iter() {
+                       if htlc.offered {
+                               let mut htlc_timeout_tx = chan_utils::build_htlc_transaction(&local_tx.txid, local_tx.feerate_per_kw, self.their_to_self_delay.unwrap(), htlc, &local_tx.delayed_payment_key, &local_tx.revocation_key);
+
+                               htlc_timeout_tx.input[0].witness.push(Vec::new()); // First is the multisig dummy
+
+                               htlc_timeout_tx.input[0].witness.push(their_sig.serialize_der(&self.secp_ctx).to_vec());
+                               htlc_timeout_tx.input[0].witness[1].push(SigHashType::All as u8);
+                               htlc_timeout_tx.input[0].witness.push(our_sig.serialize_der(&self.secp_ctx).to_vec());
+                               htlc_timeout_tx.input[0].witness[2].push(SigHashType::All as u8);
+
+                               htlc_timeout_tx.input[0].witness.push(Vec::new());
+                               htlc_timeout_tx.input[0].witness.push(chan_utils::get_htlc_redeemscript_with_explicit_keys(htlc, &local_tx.a_htlc_key, &local_tx.b_htlc_key, &local_tx.revocation_key).into_vec());
+
+                               res.push(htlc_timeout_tx);
+                       } else {
+                               if let Some(payment_preimage) = self.payment_preimages.get(&htlc.payment_hash) {
+                                       let mut htlc_success_tx = chan_utils::build_htlc_transaction(&local_tx.txid, local_tx.feerate_per_kw, self.their_to_self_delay.unwrap(), htlc, &local_tx.delayed_payment_key, &local_tx.revocation_key);
+
+                                       htlc_success_tx.input[0].witness.push(Vec::new()); // First is the multisig dummy
+
+                                       htlc_success_tx.input[0].witness.push(their_sig.serialize_der(&self.secp_ctx).to_vec());
+                                       htlc_success_tx.input[0].witness[1].push(SigHashType::All as u8);
+                                       htlc_success_tx.input[0].witness.push(our_sig.serialize_der(&self.secp_ctx).to_vec());
+                                       htlc_success_tx.input[0].witness[2].push(SigHashType::All as u8);
+
+                                       htlc_success_tx.input[0].witness.push(payment_preimage.to_vec());
+                                       htlc_success_tx.input[0].witness.push(chan_utils::get_htlc_redeemscript_with_explicit_keys(htlc, &local_tx.a_htlc_key, &local_tx.b_htlc_key, &local_tx.revocation_key).into_vec());
+
+                                       res.push(htlc_success_tx);
+                               }
                        }
+               }
+
+               res
+       }
+
+       /// Attempts to claim any claimable HTLCs in a commitment transaction which was not (yet)
+       /// revoked using data in local_claimable_outpoints.
+       /// Should not be used if check_spend_revoked_transaction succeeds.
+       fn check_spend_local_transaction(&self, tx: &Transaction, _height: u32) -> Vec<Transaction> {
+               let commitment_txid = tx.txid();
+               if let &Some(ref local_tx) = &self.current_local_signed_commitment_tx {
+                       if local_tx.txid == commitment_txid {
+                               return self.broadcast_by_local_state(local_tx);
+                       }
+               }
+               if let &Some(ref local_tx) = &self.prev_local_signed_commitment_tx {
+                       if local_tx.txid == commitment_txid {
+                               return self.broadcast_by_local_state(local_tx);
+                       }
+               }
+               Vec::new()
+       }
 
+       fn block_connected(&self, txn_matched: &[&Transaction], height: u32, broadcaster: &BroadcasterInterface) {
+               for tx in txn_matched {
                        for txin in tx.input.iter() {
                                if self.funding_txo.is_none() || (txin.prev_hash == self.funding_txo.unwrap().0 && txin.prev_index == self.funding_txo.unwrap().1 as u32) {
-                                       for tx in self.check_spend_transaction(tx, height).iter() {
+                                       let mut txn = self.check_spend_remote_transaction(tx, height);
+                                       if txn.is_empty() {
+                                               txn = self.check_spend_local_transaction(tx, height);
+                                       }
+                                       for tx in txn.iter() {
                                                broadcaster.broadcast_transaction(tx);
                                        }
                                }
                        }
                }
+               if let Some(ref cur_local_tx) = self.current_local_signed_commitment_tx {
+                       let mut needs_broadcast = false;
+                       for &(ref htlc, _, _) in cur_local_tx.htlc_outputs.iter() {
+                               if htlc.cltv_expiry <= height + CLTV_CLAIM_BUFFER {
+                                       if htlc.offered || self.payment_preimages.contains_key(&htlc.payment_hash) {
+                                               needs_broadcast = true;
+                                       }
+                               }
+                       }
+
+                       if needs_broadcast {
+                               broadcaster.broadcast_transaction(&cur_local_tx.tx);
+                               for tx in self.broadcast_by_local_state(&cur_local_tx) {
+                                       broadcaster.broadcast_transaction(&tx);
+                               }
+                       }
+               }
+       }
+
+       pub fn would_broadcast_at_height(&self, height: u32) -> bool {
+               if let Some(ref cur_local_tx) = self.current_local_signed_commitment_tx {
+                       for &(ref htlc, _, _) in cur_local_tx.htlc_outputs.iter() {
+                               if htlc.cltv_expiry <= height + CLTV_CLAIM_BUFFER {
+                                       if htlc.offered || self.payment_preimages.contains_key(&htlc.payment_hash) {
+                                               return true;
+                                       }
+                               }
+                       }
+               }
+               false
        }
 }
 
@@ -498,336 +821,338 @@ mod tests {
 
                {
                        // insert_secret correct sequence
-                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &PublicKey::new(), 0, Script::new());
+                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
                        secrets.clear();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap());
-                       monitor.provide_secret(281474976710655, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710655, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap());
-                       monitor.provide_secret(281474976710654, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710654, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8").unwrap());
-                       monitor.provide_secret(281474976710653, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710653, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap());
-                       monitor.provide_secret(281474976710652, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710652, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("c65716add7aa98ba7acb236352d665cab17345fe45b55fb879ff80e6bd0c41dd").unwrap());
-                       monitor.provide_secret(281474976710651, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710651, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("969660042a28f32d9be17344e09374b379962d03db1574df5a8a5a47e19ce3f2").unwrap());
-                       monitor.provide_secret(281474976710650, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710650, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("a5a64476122ca0925fb344bdc1854c1c0a59fc614298e50a33e331980a220f32").unwrap());
-                       monitor.provide_secret(281474976710649, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710649, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("05cde6323d949933f7f7b78776bcc1ea6d9b31447732e3802e1f7ac44b650e17").unwrap());
-                       monitor.provide_secret(281474976710648, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710648, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
                }
 
                {
                        // insert_secret #1 incorrect
-                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &PublicKey::new(), 0, Script::new());
+                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
                        secrets.clear();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("02a40c85b6f28da08dfdbe0926c53fab2de6d28c10301f8f7c4073d5e42e3148").unwrap());
-                       monitor.provide_secret(281474976710655, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710655, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap());
-                       assert_eq!(monitor.provide_secret(281474976710654, secrets.last().unwrap().clone()).unwrap_err().err,
+                       assert_eq!(monitor.provide_secret(281474976710654, secrets.last().unwrap().clone(), None).unwrap_err().err,
                                        "Previous secret did not match new one");
                }
 
                {
                        // insert_secret #2 incorrect (#1 derived from incorrect)
-                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &PublicKey::new(), 0, Script::new());
+                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
                        secrets.clear();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("02a40c85b6f28da08dfdbe0926c53fab2de6d28c10301f8f7c4073d5e42e3148").unwrap());
-                       monitor.provide_secret(281474976710655, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710655, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("dddc3a8d14fddf2b68fa8c7fbad2748274937479dd0f8930d5ebb4ab6bd866a3").unwrap());
-                       monitor.provide_secret(281474976710654, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710654, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8").unwrap());
-                       monitor.provide_secret(281474976710653, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710653, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap());
-                       assert_eq!(monitor.provide_secret(281474976710652, secrets.last().unwrap().clone()).unwrap_err().err,
+                       assert_eq!(monitor.provide_secret(281474976710652, secrets.last().unwrap().clone(), None).unwrap_err().err,
                                        "Previous secret did not match new one");
                }
 
                {
                        // insert_secret #3 incorrect
-                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &PublicKey::new(), 0, Script::new());
+                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
                        secrets.clear();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap());
-                       monitor.provide_secret(281474976710655, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710655, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap());
-                       monitor.provide_secret(281474976710654, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710654, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("c51a18b13e8527e579ec56365482c62f180b7d5760b46e9477dae59e87ed423a").unwrap());
-                       monitor.provide_secret(281474976710653, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710653, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap());
-                       assert_eq!(monitor.provide_secret(281474976710652, secrets.last().unwrap().clone()).unwrap_err().err,
+                       assert_eq!(monitor.provide_secret(281474976710652, secrets.last().unwrap().clone(), None).unwrap_err().err,
                                        "Previous secret did not match new one");
                }
 
                {
                        // insert_secret #4 incorrect (1,2,3 derived from incorrect)
-                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &PublicKey::new(), 0, Script::new());
+                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
                        secrets.clear();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("02a40c85b6f28da08dfdbe0926c53fab2de6d28c10301f8f7c4073d5e42e3148").unwrap());
-                       monitor.provide_secret(281474976710655, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710655, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("dddc3a8d14fddf2b68fa8c7fbad2748274937479dd0f8930d5ebb4ab6bd866a3").unwrap());
-                       monitor.provide_secret(281474976710654, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710654, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("c51a18b13e8527e579ec56365482c62f180b7d5760b46e9477dae59e87ed423a").unwrap());
-                       monitor.provide_secret(281474976710653, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710653, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("ba65d7b0ef55a3ba300d4e87af29868f394f8f138d78a7011669c79b37b936f4").unwrap());
-                       monitor.provide_secret(281474976710652, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710652, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("c65716add7aa98ba7acb236352d665cab17345fe45b55fb879ff80e6bd0c41dd").unwrap());
-                       monitor.provide_secret(281474976710651, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710651, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("969660042a28f32d9be17344e09374b379962d03db1574df5a8a5a47e19ce3f2").unwrap());
-                       monitor.provide_secret(281474976710650, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710650, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("a5a64476122ca0925fb344bdc1854c1c0a59fc614298e50a33e331980a220f32").unwrap());
-                       monitor.provide_secret(281474976710649, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710649, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("05cde6323d949933f7f7b78776bcc1ea6d9b31447732e3802e1f7ac44b650e17").unwrap());
-                       assert_eq!(monitor.provide_secret(281474976710648, secrets.last().unwrap().clone()).unwrap_err().err,
+                       assert_eq!(monitor.provide_secret(281474976710648, secrets.last().unwrap().clone(), None).unwrap_err().err,
                                        "Previous secret did not match new one");
                }
 
                {
                        // insert_secret #5 incorrect
-                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &PublicKey::new(), 0, Script::new());
+                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
                        secrets.clear();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap());
-                       monitor.provide_secret(281474976710655, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710655, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap());
-                       monitor.provide_secret(281474976710654, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710654, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8").unwrap());
-                       monitor.provide_secret(281474976710653, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710653, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap());
-                       monitor.provide_secret(281474976710652, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710652, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("631373ad5f9ef654bb3dade742d09504c567edd24320d2fcd68e3cc47e2ff6a6").unwrap());
-                       monitor.provide_secret(281474976710651, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710651, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("969660042a28f32d9be17344e09374b379962d03db1574df5a8a5a47e19ce3f2").unwrap());
-                       assert_eq!(monitor.provide_secret(281474976710650, secrets.last().unwrap().clone()).unwrap_err().err,
+                       assert_eq!(monitor.provide_secret(281474976710650, secrets.last().unwrap().clone(), None).unwrap_err().err,
                                        "Previous secret did not match new one");
                }
 
                {
                        // insert_secret #6 incorrect (5 derived from incorrect)
-                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &PublicKey::new(), 0, Script::new());
+                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
                        secrets.clear();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap());
-                       monitor.provide_secret(281474976710655, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710655, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap());
-                       monitor.provide_secret(281474976710654, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710654, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8").unwrap());
-                       monitor.provide_secret(281474976710653, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710653, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap());
-                       monitor.provide_secret(281474976710652, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710652, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("631373ad5f9ef654bb3dade742d09504c567edd24320d2fcd68e3cc47e2ff6a6").unwrap());
-                       monitor.provide_secret(281474976710651, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710651, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("b7e76a83668bde38b373970155c868a653304308f9896692f904a23731224bb1").unwrap());
-                       monitor.provide_secret(281474976710650, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710650, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("a5a64476122ca0925fb344bdc1854c1c0a59fc614298e50a33e331980a220f32").unwrap());
-                       monitor.provide_secret(281474976710649, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710649, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("05cde6323d949933f7f7b78776bcc1ea6d9b31447732e3802e1f7ac44b650e17").unwrap());
-                       assert_eq!(monitor.provide_secret(281474976710648, secrets.last().unwrap().clone()).unwrap_err().err,
+                       assert_eq!(monitor.provide_secret(281474976710648, secrets.last().unwrap().clone(), None).unwrap_err().err,
                                        "Previous secret did not match new one");
                }
 
                {
                        // insert_secret #7 incorrect
-                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &PublicKey::new(), 0, Script::new());
+                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
                        secrets.clear();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap());
-                       monitor.provide_secret(281474976710655, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710655, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap());
-                       monitor.provide_secret(281474976710654, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710654, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8").unwrap());
-                       monitor.provide_secret(281474976710653, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710653, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap());
-                       monitor.provide_secret(281474976710652, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710652, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("c65716add7aa98ba7acb236352d665cab17345fe45b55fb879ff80e6bd0c41dd").unwrap());
-                       monitor.provide_secret(281474976710651, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710651, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("969660042a28f32d9be17344e09374b379962d03db1574df5a8a5a47e19ce3f2").unwrap());
-                       monitor.provide_secret(281474976710650, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710650, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("e7971de736e01da8ed58b94c2fc216cb1dca9e326f3a96e7194fe8ea8af6c0a3").unwrap());
-                       monitor.provide_secret(281474976710649, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710649, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("05cde6323d949933f7f7b78776bcc1ea6d9b31447732e3802e1f7ac44b650e17").unwrap());
-                       assert_eq!(monitor.provide_secret(281474976710648, secrets.last().unwrap().clone()).unwrap_err().err,
+                       assert_eq!(monitor.provide_secret(281474976710648, secrets.last().unwrap().clone(), None).unwrap_err().err,
                                        "Previous secret did not match new one");
                }
 
                {
                        // insert_secret #8 incorrect
-                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &PublicKey::new(), 0, Script::new());
+                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
                        secrets.clear();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap());
-                       monitor.provide_secret(281474976710655, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710655, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap());
-                       monitor.provide_secret(281474976710654, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710654, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8").unwrap());
-                       monitor.provide_secret(281474976710653, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710653, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap());
-                       monitor.provide_secret(281474976710652, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710652, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("c65716add7aa98ba7acb236352d665cab17345fe45b55fb879ff80e6bd0c41dd").unwrap());
-                       monitor.provide_secret(281474976710651, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710651, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("969660042a28f32d9be17344e09374b379962d03db1574df5a8a5a47e19ce3f2").unwrap());
-                       monitor.provide_secret(281474976710650, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710650, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("a5a64476122ca0925fb344bdc1854c1c0a59fc614298e50a33e331980a220f32").unwrap());
-                       monitor.provide_secret(281474976710649, secrets.last().unwrap().clone()).unwrap();
+                       monitor.provide_secret(281474976710649, secrets.last().unwrap().clone(), None).unwrap();
                        test_secrets!();
 
                        secrets.push([0; 32]);
                        secrets.last_mut().unwrap()[0..32].clone_from_slice(&hex_bytes("a7efbc61aac46d34f77778bac22c8a20c6a46ca460addc49009bda875ec88fa4").unwrap());
-                       assert_eq!(monitor.provide_secret(281474976710648, secrets.last().unwrap().clone()).unwrap_err().err,
+                       assert_eq!(monitor.provide_secret(281474976710648, secrets.last().unwrap().clone(), None).unwrap_err().err,
                                        "Previous secret did not match new one");
                }
        }
+
+       // Further testing is done in the ChannelManager integration tests.
 }
index c48e0568169c121e6f434df99dc5ec495eecd329..681817a9e1c007720d15da34c95f4f26ef51eeab 100644 (file)
@@ -15,6 +15,14 @@ pub trait MsgEncodable {
        fn encode(&self) -> Vec<u8>;
        #[inline]
        fn encoded_len(&self) -> usize { self.encode().len() }
+       #[inline]
+       fn encode_with_len(&self) -> Vec<u8> {
+               let enc = self.encode();
+               let mut res = Vec::with_capacity(enc.len() + 2);
+               res.extend_from_slice(&byte_utils::be16_to_array(enc.len() as u16));
+               res.extend_from_slice(&enc);
+               res
+       }
 }
 #[derive(Debug)]
 pub enum DecodeError {
@@ -366,6 +374,15 @@ pub struct CommitmentUpdate {
        pub commitment_signed: CommitmentSigned,
 }
 
+pub enum HTLCFailChannelUpdate {
+       ChannelUpdateMessage {
+               msg: ChannelUpdate,
+       },
+       ChannelClosed {
+               short_channel_id: u64,
+       },
+}
+
 /// A trait to describe an object which can receive channel messages. Messages MAY be called in
 /// paralell when they originate from different their_node_ids, however they MUST NOT be called in
 /// paralell when the two calls have the same their_node_id.
@@ -384,7 +401,7 @@ pub trait ChannelMessageHandler : events::EventsProvider {
        // HTLC handling:
        fn handle_update_add_htlc(&self, their_node_id: &PublicKey, msg: &UpdateAddHTLC) -> Result<(), HandleError>;
        fn handle_update_fulfill_htlc(&self, their_node_id: &PublicKey, msg: &UpdateFulfillHTLC) -> Result<(), HandleError>;
-       fn handle_update_fail_htlc(&self, their_node_id: &PublicKey, msg: &UpdateFailHTLC) -> Result<(), HandleError>;
+       fn handle_update_fail_htlc(&self, their_node_id: &PublicKey, msg: &UpdateFailHTLC) -> Result<Option<HTLCFailChannelUpdate>, HandleError>;
        fn handle_update_fail_malformed_htlc(&self, their_node_id: &PublicKey, msg: &UpdateFailMalformedHTLC) -> Result<(), HandleError>;
        fn handle_commitment_signed(&self, their_node_id: &PublicKey, msg: &CommitmentSigned) -> Result<(RevokeAndACK, Option<CommitmentSigned>), HandleError>;
        fn handle_revoke_and_ack(&self, their_node_id: &PublicKey, msg: &RevokeAndACK) -> Result<Option<CommitmentUpdate>, HandleError>;
@@ -408,6 +425,7 @@ pub trait RoutingMessageHandler {
        /// or returning an Err otherwise.
        fn handle_channel_announcement(&self, msg: &ChannelAnnouncement) -> Result<bool, HandleError>;
        fn handle_channel_update(&self, msg: &ChannelUpdate) -> Result<(), HandleError>;
+       fn handle_htlc_fail_channel_update(&self, update: &HTLCFailChannelUpdate);
 }
 
 pub struct OnionRealm0HopData {
@@ -1316,8 +1334,26 @@ impl MsgEncodable for OnionPacket {
 }
 
 impl MsgDecodable for DecodedOnionErrorPacket {
-       fn decode(_v: &[u8]) -> Result<Self, DecodeError> {
-               unimplemented!();
+       fn decode(v: &[u8]) -> Result<Self, DecodeError> {
+               if v.len() < 32 + 4 {
+                       return Err(DecodeError::WrongLength);
+               }
+               let failuremsg_len = byte_utils::slice_to_be16(&v[32..34]) as usize;
+               if v.len() < 32 + 4 + failuremsg_len {
+                       return Err(DecodeError::WrongLength);
+               }
+               let padding_len = byte_utils::slice_to_be16(&v[34 + failuremsg_len..]) as usize;
+               if v.len() < 32 + 4 + failuremsg_len + padding_len {
+                       return Err(DecodeError::WrongLength);
+               }
+
+               let mut hmac = [0; 32];
+               hmac.copy_from_slice(&v[0..32]);
+               Ok(Self {
+                       hmac,
+                       failuremsg: v[34..34 + failuremsg_len].to_vec(),
+                       pad: v[36 + failuremsg_len..36 + failuremsg_len + padding_len].to_vec(),
+               })
        }
 }
 impl MsgEncodable for DecodedOnionErrorPacket {
index d7b1e9d691238f34161c53d6c0e1eebf5ba35606..9df01489f214071d146f46cdb307180e1d01307e 100644 (file)
@@ -424,7 +424,10 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
                                                                                        },
                                                                                        131 => {
                                                                                                let msg = try_potential_decodeerror!(msgs::UpdateFailHTLC::decode(&msg_data[2..]));
-                                                                                               try_potential_handleerror!(self.message_handler.chan_handler.handle_update_fail_htlc(&peer.their_node_id.unwrap(), &msg));
+                                                                                               let chan_update = try_potential_handleerror!(self.message_handler.chan_handler.handle_update_fail_htlc(&peer.their_node_id.unwrap(), &msg));
+                                                                                               if let Some(update) = chan_update {
+                                                                                                       self.message_handler.route_handler.handle_htlc_fail_channel_update(&update);
+                                                                                               }
                                                                                        },
                                                                                        135 => {
                                                                                                let msg = try_potential_decodeerror!(msgs::UpdateFailMalformedHTLC::decode(&msg_data[2..]));
@@ -609,24 +612,40 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
                                                continue;
                                        },
                                        Event::BroadcastChannelAnnouncement { ref msg, ref update_msg } => {
-                                               let encoded_msg = encode_msg!(msg, 256);
-                                               let encoded_update_msg = encode_msg!(update_msg, 258);
+                                               if self.message_handler.route_handler.handle_channel_announcement(msg).is_ok() && self.message_handler.route_handler.handle_channel_update(update_msg).is_ok() {
+                                                       let encoded_msg = encode_msg!(msg, 256);
+                                                       let encoded_update_msg = encode_msg!(update_msg, 258);
 
-                                               for (ref descriptor, ref mut peer) in peers.peers.iter_mut() {
-                                                       if !peer.channel_encryptor.is_ready_for_encryption() {
-                                                               continue
-                                                       }
-                                                       match peer.their_node_id {
-                                                               None => continue,
-                                                               Some(their_node_id) => {
-                                                                       if their_node_id == msg.contents.node_id_1 || their_node_id == msg.contents.node_id_2 {
-                                                                               continue
+                                                       for (ref descriptor, ref mut peer) in peers.peers.iter_mut() {
+                                                               if !peer.channel_encryptor.is_ready_for_encryption() {
+                                                                       continue
+                                                               }
+                                                               match peer.their_node_id {
+                                                                       None => continue,
+                                                                       Some(their_node_id) => {
+                                                                               if their_node_id == msg.contents.node_id_1 || their_node_id == msg.contents.node_id_2 {
+                                                                                       continue
+                                                                               }
                                                                        }
                                                                }
+                                                               peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encoded_msg[..]));
+                                                               peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encoded_update_msg[..]));
+                                                               Self::do_attempt_write_data(&mut (*descriptor).clone(), peer);
+                                                       }
+                                               }
+                                               continue;
+                                       },
+                                       Event::BroadcastChannelUpdate { ref msg } => {
+                                               if self.message_handler.route_handler.handle_channel_update(msg).is_ok() {
+                                                       let encoded_msg = encode_msg!(msg, 258);
+
+                                                       for (ref descriptor, ref mut peer) in peers.peers.iter_mut() {
+                                                               if !peer.channel_encryptor.is_ready_for_encryption() {
+                                                                       continue
+                                                               }
+                                                               peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encoded_msg[..]));
+                                                               Self::do_attempt_write_data(&mut (*descriptor).clone(), peer);
                                                        }
-                                                       peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encoded_msg[..]));
-                                                       peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encoded_update_msg[..]));
-                                                       Self::do_attempt_write_data(&mut (*descriptor).clone(), peer);
                                                }
                                                continue;
                                        },
index 75df79450f3507d80969ee0eb186a3a8022d28f6..19a677580a5c101fe08e78d52ac17dbee4dc0ffe 100644 (file)
@@ -51,9 +51,9 @@ struct ChannelInfo {
 
 struct NodeInfo {
        #[cfg(feature = "non_bitcoin_chain_hash_routing")]
-    channels: Vec<(u64, Sha256dHash)>,
+       channels: Vec<(u64, Sha256dHash)>,
        #[cfg(not(feature = "non_bitcoin_chain_hash_routing"))]
-    channels: Vec<u64>,
+       channels: Vec<u64>,
 
        lowest_inbound_channel_fee_base_msat: u32,
        lowest_inbound_channel_fee_proportional_millionths: u32,
@@ -214,6 +214,18 @@ impl RoutingMessageHandler for Router {
                Ok(!msg.contents.features.supports_unknown_bits())
        }
 
+       fn handle_htlc_fail_channel_update(&self, update: &msgs::HTLCFailChannelUpdate) {
+               match update {
+                       &msgs::HTLCFailChannelUpdate::ChannelUpdateMessage { ref msg } => {
+                               let _ = self.handle_channel_update(msg);
+                       },
+                       &msgs::HTLCFailChannelUpdate::ChannelClosed { ref short_channel_id } => {
+                               let mut network = self.network_map.write().unwrap();
+                               network.channels.remove(short_channel_id);
+                       },
+               }
+       }
+
        fn handle_channel_update(&self, msg: &msgs::ChannelUpdate) -> Result<(), HandleError> {
                let mut network = self.network_map.write().unwrap();
                let dest_node_id;
index db4769067e35ba95b5c0a1d5038c9de3b7d60378..7c724243570b25bd5feb1402eb3171eedcfbdbd6 100644 (file)
@@ -90,6 +90,10 @@ pub enum Event {
                msg: msgs::ChannelAnnouncement,
                update_msg: msgs::ChannelUpdate,
        },
+       /// Used to indicate that a channel_update should be broadcast to all peers.
+       BroadcastChannelUpdate {
+               msg: msgs::ChannelUpdate,
+       },
 }
 
 pub trait EventsProvider {
index 7e28f54374051d13035823b73e38e1eebf9ab6ba..4502bccec1bd9dc28bff06cf46b838f2c9bf91ff 100644 (file)
@@ -1,7 +1,6 @@
 use chain::chaininterface;
 use chain::chaininterface::ConfirmationTarget;
 use ln::channelmonitor;
-use ln::msgs::HandleError;
 
 use bitcoin::blockdata::transaction::Transaction;
 use bitcoin::util::hash::Sha256dHash;
@@ -30,7 +29,7 @@ impl TestChannelMonitor {
        }
 }
 impl channelmonitor::ManyChannelMonitor for TestChannelMonitor {
-       fn add_update_monitor(&self, funding_txo: (Sha256dHash, u16), monitor: channelmonitor::ChannelMonitor) -> Result<(), HandleError> {
+       fn add_update_monitor(&self, funding_txo: (Sha256dHash, u16), monitor: channelmonitor::ChannelMonitor) -> Result<(), channelmonitor::ChannelMonitorUpdateErr> {
                self.added_monitors.lock().unwrap().push((funding_txo, monitor.clone()));
                self.simple_monitor.add_update_monitor(funding_txo, monitor)
        }