Implement spendable output to_local output on local commitment tx
[rust-lightning] / src / ln / channelmonitor.rs
index 09f052426c5b5f32b99038175ac9a8d3b599a03b..2bdbfec2cdcbcde5bbcac31aab00738b1cfb3945 100644 (file)
@@ -15,10 +15,8 @@ use bitcoin::blockdata::block::BlockHeader;
 use bitcoin::blockdata::transaction::{TxIn,TxOut,SigHashType,Transaction};
 use bitcoin::blockdata::transaction::OutPoint as BitcoinOutPoint;
 use bitcoin::blockdata::script::Script;
-use bitcoin::network::serialize;
-use bitcoin::network::serialize::BitcoinHash;
-use bitcoin::network::encodable::{ConsensusDecodable, ConsensusEncodable};
-use bitcoin::util::hash::Sha256dHash;
+use bitcoin::consensus::encode::{self, Decodable, Encodable};
+use bitcoin::util::hash::{BitcoinHash,Sha256dHash};
 use bitcoin::util::bip143;
 
 use crypto::digest::Digest;
@@ -112,6 +110,7 @@ pub struct SimpleManyChannelMonitor<Key> {
        chain_monitor: Arc<ChainWatchInterface>,
        broadcaster: Arc<BroadcasterInterface>,
        pending_events: Mutex<Vec<events::Event>>,
+       logger: Arc<Logger>,
 }
 
 impl<Key : Send + cmp::Eq + hash::Hash> ChainListener for SimpleManyChannelMonitor<Key> {
@@ -144,12 +143,13 @@ impl<Key : Send + cmp::Eq + hash::Hash> ChainListener for SimpleManyChannelMonit
 impl<Key : Send + cmp::Eq + hash::Hash + 'static> SimpleManyChannelMonitor<Key> {
        /// Creates a new object which can be used to monitor several channels given the chain
        /// interface with which to register to receive notifications.
-       pub fn new(chain_monitor: Arc<ChainWatchInterface>, broadcaster: Arc<BroadcasterInterface>) -> Arc<SimpleManyChannelMonitor<Key>> {
+       pub fn new(chain_monitor: Arc<ChainWatchInterface>, broadcaster: Arc<BroadcasterInterface>, logger: Arc<Logger>) -> Arc<SimpleManyChannelMonitor<Key>> {
                let res = Arc::new(SimpleManyChannelMonitor {
                        monitors: Mutex::new(HashMap::new()),
                        chain_monitor,
                        broadcaster,
                        pending_events: Mutex::new(Vec::new()),
+                       logger,
                });
                let weak_res = Arc::downgrade(&res);
                res.chain_monitor.register_listener(weak_res);
@@ -160,12 +160,19 @@ impl<Key : Send + cmp::Eq + hash::Hash + 'static> SimpleManyChannelMonitor<Key>
        pub fn add_update_monitor_by_key(&self, key: Key, monitor: ChannelMonitor) -> Result<(), HandleError> {
                let mut monitors = self.monitors.lock().unwrap();
                match monitors.get_mut(&key) {
-                       Some(orig_monitor) => return orig_monitor.insert_combine(monitor),
+                       Some(orig_monitor) => {
+                               log_trace!(self, "Updating Channel Monitor for channel {}", log_funding_option!(monitor.funding_txo));
+                               return orig_monitor.insert_combine(monitor);
+                       },
                        None => {}
                };
                match &monitor.funding_txo {
-                       &None => self.chain_monitor.watch_all_txn(),
+                       &None => {
+                               log_trace!(self, "Got new Channel Monitor for no-funding-set channel (monitoring all txn!)");
+                               self.chain_monitor.watch_all_txn()
+                       },
                        &Some((ref outpoint, ref script)) => {
+                               log_trace!(self, "Got new Channel Monitor for channel {}", log_bytes!(outpoint.to_channel_id()[..]));
                                self.chain_monitor.install_watch_tx(&outpoint.txid, script);
                                self.chain_monitor.install_watch_outpoint((outpoint.txid, outpoint.index as u32), script);
                        },
@@ -278,6 +285,10 @@ pub struct ChannelMonitor {
        prev_local_signed_commitment_tx: Option<LocalSignedTx>,
        current_local_signed_commitment_tx: Option<LocalSignedTx>,
 
+       // Used just for ChannelManager to make sure it has the latest channel data during
+       // deserialization
+       current_remote_commitment_number: u64,
+
        payment_preimages: HashMap<[u8; 32], [u8; 32]>,
 
        destination_script: Script,
@@ -309,6 +320,7 @@ impl PartialEq for ChannelMonitor {
                        self.remote_commitment_txn_on_chain != other.remote_commitment_txn_on_chain ||
                        self.remote_hash_commitment_number != other.remote_hash_commitment_number ||
                        self.prev_local_signed_commitment_tx != other.prev_local_signed_commitment_tx ||
+                       self.current_remote_commitment_number != other.current_remote_commitment_number ||
                        self.current_local_signed_commitment_tx != other.current_local_signed_commitment_tx ||
                        self.payment_preimages != other.payment_preimages ||
                        self.destination_script != other.destination_script
@@ -352,6 +364,7 @@ impl ChannelMonitor {
 
                        prev_local_signed_commitment_tx: None,
                        current_local_signed_commitment_tx: None,
+                       current_remote_commitment_number: 1 << 48,
 
                        payment_preimages: HashMap::new(),
                        destination_script: destination_script,
@@ -471,6 +484,7 @@ impl ChannelMonitor {
                        self.remote_hash_commitment_number.insert(htlc.payment_hash, commitment_number);
                }
                self.remote_claimable_outpoints.insert(unsigned_commitment_tx.txid(), htlc_outputs);
+               self.current_remote_commitment_number = commitment_number;
        }
 
        /// Informs this monitor of the latest local (ie broadcastable) commitment transaction. The
@@ -528,6 +542,8 @@ impl ChannelMonitor {
                if our_min_secret > other_min_secret {
                        self.provide_secret(other_min_secret, other.get_secret(other_min_secret).unwrap(), None)?;
                }
+               // TODO: We should use current_remote_commitment_number and the commitment number out of
+               // local transactions to decide how to merge
                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() {
@@ -541,6 +557,7 @@ impl ChannelMonitor {
                        }
                        self.payment_preimages = other.payment_preimages;
                }
+               self.current_remote_commitment_number = cmp::min(self.current_remote_commitment_number, other.current_remote_commitment_number);
                Ok(())
        }
 
@@ -682,7 +699,7 @@ impl ChannelMonitor {
                }
 
                writer.write_all(&byte_utils::be64_to_array(self.remote_claimable_outpoints.len() as u64))?;
-               for (txid, htlc_outputs) in self.remote_claimable_outpoints.iter() {
+               for (ref txid, ref htlc_outputs) in self.remote_claimable_outpoints.iter() {
                        writer.write_all(&txid[..])?;
                        writer.write_all(&byte_utils::be64_to_array(htlc_outputs.len() as u64))?;
                        for htlc_output in htlc_outputs.iter() {
@@ -691,9 +708,9 @@ impl ChannelMonitor {
                }
 
                writer.write_all(&byte_utils::be64_to_array(self.remote_commitment_txn_on_chain.len() as u64))?;
-               for (txid, (commitment_number, txouts)) in self.remote_commitment_txn_on_chain.iter() {
+               for (ref txid, &(commitment_number, ref txouts)) in self.remote_commitment_txn_on_chain.iter() {
                        writer.write_all(&txid[..])?;
-                       writer.write_all(&byte_utils::be48_to_array(*commitment_number))?;
+                       writer.write_all(&byte_utils::be48_to_array(commitment_number))?;
                        (txouts.len() as u64).write(writer)?;
                        for script in txouts.iter() {
                                script.write(writer)?;
@@ -702,8 +719,8 @@ impl ChannelMonitor {
 
                if for_local_storage {
                        writer.write_all(&byte_utils::be64_to_array(self.remote_hash_commitment_number.len() as u64))?;
-                       for (payment_hash, commitment_number) in self.remote_hash_commitment_number.iter() {
-                               writer.write_all(payment_hash)?;
+                       for (ref payment_hash, commitment_number) in self.remote_hash_commitment_number.iter() {
+                               writer.write_all(*payment_hash)?;
                                writer.write_all(&byte_utils::be48_to_array(*commitment_number))?;
                        }
                } else {
@@ -712,9 +729,9 @@ impl ChannelMonitor {
 
                macro_rules! serialize_local_tx {
                        ($local_tx: expr) => {
-                               if let Err(e) = $local_tx.tx.consensus_encode(&mut serialize::RawEncoder::new(WriterWriteAdaptor(writer))) {
+                               if let Err(e) = $local_tx.tx.consensus_encode(&mut WriterWriteAdaptor(writer)) {
                                        match e {
-                                               serialize::Error::Io(e) => return Err(e),
+                                               encode::Error::Io(e) => return Err(e),
                                                _ => panic!("local tx must have been well-formed!"),
                                        }
                                }
@@ -748,6 +765,12 @@ impl ChannelMonitor {
                        writer.write_all(&[0; 1])?;
                }
 
+               if for_local_storage {
+                       writer.write_all(&byte_utils::be48_to_array(self.current_remote_commitment_number))?;
+               } else {
+                       writer.write_all(&byte_utils::be48_to_array(0))?;
+               }
+
                writer.write_all(&byte_utils::be64_to_array(self.payment_preimages.len() as u64))?;
                for payment_preimage in self.payment_preimages.values() {
                        writer.write_all(payment_preimage)?;
@@ -806,6 +829,16 @@ impl ChannelMonitor {
                min
        }
 
+       pub(super) fn get_cur_remote_commitment_number(&self) -> u64 {
+               self.current_remote_commitment_number
+       }
+
+       pub(super) fn get_cur_local_commitment_number(&self) -> u64 {
+               if let &Some(ref local_tx) = &self.current_local_signed_commitment_tx {
+                       0xffff_ffff_ffff - ((((local_tx.tx.input[0].sequence as u64 & 0xffffff) << 3*8) | (local_tx.tx.lock_time as u64 & 0xffffff)) ^ self.commitment_transaction_number_obscure_factor)
+               } else { 0xffff_ffff_ffff }
+       }
+
        /// 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
@@ -1197,6 +1230,33 @@ impl ChannelMonitor {
                let mut res = Vec::with_capacity(local_tx.htlc_outputs.len());
                let mut spendable_outputs = Vec::with_capacity(local_tx.htlc_outputs.len());
 
+               macro_rules! add_dynamic_output {
+                       ($father_tx: expr, $vout: expr) => {
+                               if let Some(ref per_commitment_point) = *per_commitment_point {
+                                       if let Some(ref delayed_payment_base_key) = *delayed_payment_base_key {
+                                               if let Ok(local_delayedkey) = chan_utils::derive_private_key(&self.secp_ctx, per_commitment_point, delayed_payment_base_key) {
+                                                       spendable_outputs.push(SpendableOutputDescriptor::DynamicOutput {
+                                                               outpoint: BitcoinOutPoint { txid: $father_tx.txid(), vout: $vout },
+                                                               local_delayedkey,
+                                                               witness_script: chan_utils::get_revokeable_redeemscript(&local_tx.revocation_key, self.our_to_self_delay, &local_tx.delayed_payment_key),
+                                                               to_self_delay: self.our_to_self_delay
+                                                       });
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+
+               let redeemscript = chan_utils::get_revokeable_redeemscript(&local_tx.revocation_key, self.their_to_self_delay.unwrap(), &local_tx.delayed_payment_key);
+               let revokeable_p2wsh = redeemscript.to_v0_p2wsh();
+               for (idx, output) in local_tx.tx.output.iter().enumerate() {
+                       if output.script_pubkey == revokeable_p2wsh {
+                               add_dynamic_output!(local_tx.tx, idx as u32);
+                               break;
+                       }
+               }
+
                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);
@@ -1211,18 +1271,7 @@ impl ChannelMonitor {
                                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_bytes());
 
-                               if let Some(ref per_commitment_point) = *per_commitment_point {
-                                       if let Some(ref delayed_payment_base_key) = *delayed_payment_base_key {
-                                               if let Ok(local_delayedkey) = chan_utils::derive_private_key(&self.secp_ctx, per_commitment_point, delayed_payment_base_key) {
-                                                       spendable_outputs.push(SpendableOutputDescriptor::DynamicOutput {
-                                                               outpoint: BitcoinOutPoint { txid: htlc_timeout_tx.txid(), vout: 0 },
-                                                               local_delayedkey,
-                                                               witness_script: chan_utils::get_revokeable_redeemscript(&local_tx.revocation_key, self.our_to_self_delay, &local_tx.delayed_payment_key),
-                                                               to_self_delay: self.our_to_self_delay
-                                                       });
-                                               }
-                                       }
-                               }
+                               add_dynamic_output!(htlc_timeout_tx, 0);
                                res.push(htlc_timeout_tx);
                        } else {
                                if let Some(payment_preimage) = self.payment_preimages.get(&htlc.payment_hash) {
@@ -1238,18 +1287,7 @@ impl ChannelMonitor {
                                        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_bytes());
 
-                                       if let Some(ref per_commitment_point) = *per_commitment_point {
-                                               if let Some(ref delayed_payment_base_key) = *delayed_payment_base_key {
-                                                       if let Ok(local_delayedkey) = chan_utils::derive_private_key(&self.secp_ctx, per_commitment_point, delayed_payment_base_key) {
-                                                               spendable_outputs.push(SpendableOutputDescriptor::DynamicOutput {
-                                                                       outpoint: BitcoinOutPoint { txid: htlc_success_tx.txid(), vout: 0 },
-                                                                       local_delayedkey,
-                                                                       witness_script: chan_utils::get_revokeable_redeemscript(&local_tx.revocation_key, self.our_to_self_delay, &local_tx.delayed_payment_key),
-                                                                       to_self_delay: self.our_to_self_delay
-                                                               });
-                                                       }
-                                               }
-                                       }
+                                       add_dynamic_output!(htlc_success_tx, 0);
                                        res.push(htlc_success_tx);
                                }
                        }
@@ -1290,6 +1328,23 @@ impl ChannelMonitor {
                (Vec::new(), Vec::new())
        }
 
+       /// Used by ChannelManager deserialization to broadcast the latest local state if it's copy of
+       /// the Channel was out-of-date.
+       pub(super) fn get_latest_local_commitment_txn(&self) -> Vec<Transaction> {
+               if let &Some(ref local_tx) = &self.current_local_signed_commitment_tx {
+                       let mut res = vec![local_tx.tx.clone()];
+                       match self.key_storage {
+                               KeyStorage::PrivMode { ref delayed_payment_base_key, ref prev_latest_per_commitment_point, .. } => {
+                                       res.append(&mut self.broadcast_by_local_state(local_tx, prev_latest_per_commitment_point, &Some(*delayed_payment_base_key)).0);
+                               },
+                               _ => panic!("Can only broadcast by local channelmonitor"),
+                       };
+                       res
+               } else {
+                       Vec::new()
+               }
+       }
+
        fn block_connected(&mut self, txn_matched: &[&Transaction], height: u32, block_hash: &Sha256dHash, broadcaster: &BroadcasterInterface)-> (Vec<(Sha256dHash, Vec<TxOut>)>, Vec<SpendableOutputDescriptor>) {
                let mut watch_outputs = Vec::new();
                let mut spendable_outputs = Vec::new();
@@ -1527,10 +1582,10 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
                macro_rules! read_local_tx {
                        () => {
                                {
-                                       let tx = match Transaction::consensus_decode(&mut serialize::RawDecoder::new(reader.by_ref())) {
+                                       let tx = match Transaction::consensus_decode(reader.by_ref()) {
                                                Ok(tx) => tx,
                                                Err(e) => match e {
-                                                       serialize::Error::Io(ioe) => return Err(DecodeError::Io(ioe)),
+                                                       encode::Error::Io(ioe) => return Err(DecodeError::Io(ioe)),
                                                        _ => return Err(DecodeError::InvalidValue),
                                                },
                                        };
@@ -1576,6 +1631,8 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
                        _ => return Err(DecodeError::InvalidValue),
                };
 
+               let current_remote_commitment_number = <U48 as Readable<R>>::read(reader)?.0;
+
                let payment_preimages_len: u64 = Readable::read(reader)?;
                let mut payment_preimages = HashMap::with_capacity(cmp::min(payment_preimages_len as usize, MAX_ALLOC_SIZE / 32));
                let mut sha = Sha256::new();
@@ -1612,6 +1669,7 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
 
                        prev_local_signed_commitment_tx,
                        current_local_signed_commitment_tx,
+                       current_remote_commitment_number,
 
                        payment_preimages,