Rewrite channelmonitor framework and implement a bunch of it
authorMatt Corallo <git@bluematt.me>
Tue, 24 Apr 2018 04:19:52 +0000 (00:19 -0400)
committerMatt Corallo <git@bluematt.me>
Wed, 25 Apr 2018 00:42:24 +0000 (20:42 -0400)
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/util/test_utils.rs

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 fcdb9fcb94066e89598141af878c3c7ede9f5131..f16de61a836cf8c3552840af3a2b5c0c272134af 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?)
 
@@ -362,7 +366,7 @@ impl Channel {
                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 {
@@ -385,6 +389,8 @@ impl Channel {
                        next_remote_htlc_id: 0,
                        channel_update_count: 0,
 
+                       last_local_commitment_txn: Vec::new(),
+
                        last_sent_closing_fee: None,
 
                        funding_tx_confirmed_in: Default::default(),
@@ -477,9 +483,10 @@ impl Channel {
                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,
@@ -500,6 +507,8 @@ impl Channel {
                        next_remote_htlc_id: 0,
                        channel_update_count: 0,
 
+                       last_local_commitment_txn: Vec::new(),
+
                        last_sent_closing_fee: None,
 
                        funding_tx_confirmed_in: Default::default(),
@@ -855,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!");
                }
@@ -896,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
 
@@ -924,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,
@@ -989,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)
                }
        }
@@ -1067,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)
                }
        }
@@ -1122,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;
 
@@ -1146,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});
                }
@@ -1160,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);
@@ -1169,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});
                }
@@ -1200,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> {
@@ -1342,7 +1336,7 @@ impl Channel {
                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});
                }
@@ -1352,9 +1346,9 @@ impl Channel {
                let mut payment_hash = [0; 32];
                sha.result(&mut payment_hash);
 
-               self.channel_monitor.provide_payment_preimage(&msg.payment_preimage);
+               self.channel_monitor.provide_payment_preimage(&payment_hash, &msg.payment_preimage);
                self.mark_outbound_htlc_removed(msg.htlc_id, Some(payment_hash), None)?;
-               Ok(())
+               Ok(self.channel_monitor.clone())
        }
 
        pub fn update_fail_htlc(&mut self, msg: &msgs::UpdateFailHTLC, fail_reason: HTLCFailReason) -> Result<[u8; 32], HandleError> {
@@ -1374,7 +1368,7 @@ impl Channel {
                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});
                }
@@ -1382,7 +1376,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");
@@ -1391,17 +1385,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() {
@@ -1425,24 +1433,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);
@@ -1470,7 +1480,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);
                                                                }
@@ -1494,12 +1504,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)
                        }
@@ -1513,7 +1524,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});
                }
@@ -1522,7 +1533,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
@@ -1572,18 +1583,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()))
                                }
                        }
                }
@@ -1789,6 +1801,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> {
@@ -1837,13 +1856,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;
@@ -2006,7 +2018,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()?;
@@ -2014,7 +2026,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
@@ -2023,7 +2035,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!");
                }
@@ -2036,8 +2048,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);
@@ -2047,18 +2059,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
@@ -2170,7 +2182,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});
                }
@@ -2190,7 +2202,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
@@ -2221,23 +2233,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)
                }
        }
@@ -2283,6 +2298,16 @@ 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;
+               let mut res = Vec::new();
+               mem::swap(&mut res, &mut self.last_local_commitment_txn);
+               res
+       }
 }
 
 #[cfg(test)]
index 4fa34b4f9f533e8eeb514be514cc9a26ab0dea96..f612955bec4fcd2f6ccd2b201bb861458892f89c 100644 (file)
@@ -608,41 +608,51 @@ 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 (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)?
+                       };
+
+                       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) => msgs,
+                               None => return Ok(None),
                        }
-                       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,
-                       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");
+               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)
+               Ok(Some((update_add, commitment_signed)))
        }
 
        /// 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
@@ -653,15 +663,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 {
@@ -741,25 +745,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,
-                                               });
+                                               }));
                                        }
                                }
                        }
@@ -774,10 +778,19 @@ impl ChannelManager {
 
                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);
                }
        }
 
@@ -844,13 +857,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 => {},
@@ -910,7 +928,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
@@ -918,7 +936,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;
@@ -928,25 +946,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
                        },
                }
        }
@@ -955,6 +969,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 {
@@ -972,26 +993,47 @@ impl ChainListener for ChannelManager {
                {
                        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_funding_locked_messages.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();
+                                                               return false;
                                                        }
-                                               };
-                                               new_funding_locked_messages.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()));
-                                       },
-                                       None => {}
+                                               }
+                                       }
                                }
-                               //TODO: Check if channel was closed (or disabled) here
+                               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();
+                                       return false;
+                               }
+                               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);
@@ -1078,7 +1120,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) => {
@@ -1086,8 +1128,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);
@@ -1100,27 +1142,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,
@@ -1446,13 +1492,14 @@ 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(())
        }
 
@@ -1545,38 +1592,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);
                }
@@ -1673,8 +1723,10 @@ impl ChannelMessageHandler for ChannelManager {
                                        if let Some(short_id) = chan.get_short_channel_id() {
                                                short_to_id.remove(&short_id);
                                        }
-                                       //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.
+                                       let txn_to_broadcast = chan.force_shutdown();
+                                       for tx in txn_to_broadcast {
+                                               self.tx_broadcaster.broadcast_transaction(&tx);
+                                       }
                                        false
                                } else {
                                        true
@@ -1723,6 +1775,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
@@ -1940,6 +1993,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);
@@ -2084,6 +2143,11 @@ mod tests {
 
                let mut payment_event = {
                        let msgs = origin_node.node.send_payment(route, our_payment_hash).unwrap().unwrap();
+                       {
+                               let mut added_monitors = origin_node.chan_monitor.added_monitors.lock().unwrap();
+                               assert_eq!(added_monitors.len(), 1);
+                               added_monitors.clear();
+                       }
                        SendEvent {
                                node_id: expected_route[0].node.get_our_node_id(),
                                msgs: vec!(msgs.0),
@@ -2143,6 +2207,11 @@ mod tests {
                                        _ => panic!("Unexpected event"),
                                }
                        } else {
+                               {
+                                       let mut added_monitors = node.chan_monitor.added_monitors.lock().unwrap();
+                                       assert_eq!(added_monitors.len(), 1);
+                                       added_monitors.clear();
+                               }
                                for event in events_2.drain(..) {
                                        payment_event = SendEvent::from_event(event);
                                }
@@ -2165,13 +2234,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());
@@ -2197,7 +2276,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();
@@ -2214,7 +2293,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);
@@ -2226,8 +2305,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());
@@ -2237,7 +2318,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());
@@ -2264,30 +2345,47 @@ mod tests {
 
        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();
                                        }
                                }
@@ -2299,7 +2397,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();
@@ -2316,7 +2414,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);
@@ -2406,7 +2504,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;
@@ -2429,7 +2527,7 @@ 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;
@@ -2468,4 +2566,233 @@ 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
+       }
+
+       #[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);
+               }
+               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);
+               }
+               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);
+               }
+               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);
+               }
+               assert_eq!(nodes[3].node.list_channels().len(), 0);
+               assert_eq!(nodes[4].node.list_channels().len(), 0);
+
+               // TODO: Need to reenable this when we fix local route tracking
+               // 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 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)
        }