Process monitor update events in block_[dis]connected asynchronously
[rust-lightning] / lightning / src / ln / channel.rs
index 0040541cbc18dcbc286c8a59040bd855fc1689be..a5f4b16e6a1a1b5b05bc1b0c49a1fac1cdfd8438 100644 (file)
@@ -45,6 +45,7 @@ use std::ops::Deref;
 #[cfg(any(test, feature = "fuzztarget"))]
 use std::sync::Mutex;
 use bitcoin::hashes::hex::ToHex;
+use bitcoin::blockdata::opcodes::all::OP_PUSHBYTES_0;
 
 #[cfg(test)]
 pub struct ChannelValueStat {
@@ -520,13 +521,16 @@ impl<Signer: Sign> Channel<Signer> {
 
                let feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Normal);
 
+               let mut secp_ctx = Secp256k1::new();
+               secp_ctx.seeded_randomize(&keys_provider.get_secure_random_bytes());
+
                Ok(Channel {
                        user_id,
                        config: config.channel_options.clone(),
 
                        channel_id: keys_provider.get_secure_random_bytes(),
                        channel_state: ChannelState::OurInitSent as u32,
-                       secp_ctx: Secp256k1::new(),
+                       secp_ctx,
                        channel_value_satoshis,
 
                        latest_monitor_update_id: 0,
@@ -737,15 +741,14 @@ impl<Signer: Sign> Channel<Signer> {
                let counterparty_shutdown_scriptpubkey = if their_features.supports_upfront_shutdown_script() {
                        match &msg.shutdown_scriptpubkey {
                                &OptionalField::Present(ref script) => {
-                                       // Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. We enforce it while receiving shutdown msg
-                                       if script.is_p2pkh() || script.is_p2sh() || script.is_v0_p2wsh() || script.is_v0_p2wpkh() {
-                                               Some(script.clone())
                                        // Peer is signaling upfront_shutdown and has opt-out with a 0-length script. We don't enforce anything
-                                       } else if script.len() == 0 {
+                                       if script.len() == 0 {
                                                None
                                        // Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. Fail the channel
-                                       } else {
+                                       } else if is_unsupported_shutdown_script(&their_features, script) {
                                                return Err(ChannelError::Close(format!("Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format. script: ({})", script.to_bytes().to_hex())));
+                                       } else {
+                                               Some(script.clone())
                                        }
                                },
                                // Peer is signaling upfront shutdown but don't opt-out with correct mechanism (a.k.a 0-length script). Peer looks buggy, we fail the channel
@@ -755,13 +758,16 @@ impl<Signer: Sign> Channel<Signer> {
                        }
                } else { None };
 
+               let mut secp_ctx = Secp256k1::new();
+               secp_ctx.seeded_randomize(&keys_provider.get_secure_random_bytes());
+
                let chan = Channel {
                        user_id,
                        config: local_config,
 
                        channel_id: msg.temporary_channel_id,
                        channel_state: (ChannelState::OurInitSent as u32) | (ChannelState::TheirInitSent as u32),
-                       secp_ctx: Secp256k1::new(),
+                       secp_ctx,
 
                        latest_monitor_update_id: 0,
 
@@ -1439,15 +1445,14 @@ impl<Signer: Sign> Channel<Signer> {
                let counterparty_shutdown_scriptpubkey = if their_features.supports_upfront_shutdown_script() {
                        match &msg.shutdown_scriptpubkey {
                                &OptionalField::Present(ref script) => {
-                                       // Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. We enforce it while receiving shutdown msg
-                                       if script.is_p2pkh() || script.is_p2sh() || script.is_v0_p2wsh() || script.is_v0_p2wpkh() {
-                                               Some(script.clone())
                                        // Peer is signaling upfront_shutdown and has opt-out with a 0-length script. We don't enforce anything
-                                       } else if script.len() == 0 {
+                                       if script.len() == 0 {
                                                None
                                        // Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. Fail the channel
+                                       } else if is_unsupported_shutdown_script(&their_features, script) {
+                                               return Err(ChannelError::Close(format!("Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format. script: ({})", script.to_bytes().to_hex())));
                                        } else {
-                                               return Err(ChannelError::Close(format!("Peer is signaling upfront_shutdown but has provided a non-accepted scriptpubkey format. scriptpubkey: ({})", script.to_bytes().to_hex())));
+                                               Some(script.clone())
                                        }
                                },
                                // Peer is signaling upfront shutdown but don't opt-out with correct mechanism (a.k.a 0-length script). Peer looks buggy, we fail the channel
@@ -1565,13 +1570,13 @@ impl<Signer: Sign> Channel<Signer> {
                let funding_redeemscript = self.get_funding_redeemscript();
                let funding_txo_script = funding_redeemscript.to_v0_p2wsh();
                let obscure_factor = get_commitment_transaction_number_obscure_factor(&self.get_holder_pubkeys().payment_point, &self.get_counterparty_pubkeys().payment_point, self.is_outbound());
-               let mut channel_monitor = ChannelMonitor::new(self.holder_signer.clone(),
-                                                             &self.shutdown_pubkey, self.get_holder_selected_contest_delay(),
-                                                             &self.destination_script, (funding_txo, funding_txo_script.clone()),
-                                                             &self.channel_transaction_parameters,
-                                                             funding_redeemscript.clone(), self.channel_value_satoshis,
-                                                             obscure_factor,
-                                                             holder_commitment_tx);
+               let channel_monitor = ChannelMonitor::new(self.secp_ctx.clone(), self.holder_signer.clone(),
+                                                         &self.shutdown_pubkey, self.get_holder_selected_contest_delay(),
+                                                         &self.destination_script, (funding_txo, funding_txo_script.clone()),
+                                                         &self.channel_transaction_parameters,
+                                                         funding_redeemscript.clone(), self.channel_value_satoshis,
+                                                         obscure_factor,
+                                                         holder_commitment_tx);
 
                channel_monitor.provide_latest_counterparty_commitment_tx(counterparty_initial_commitment_txid, Vec::new(), self.cur_counterparty_commitment_transaction_number, self.counterparty_cur_commitment_point.unwrap(), logger);
 
@@ -1635,13 +1640,13 @@ impl<Signer: Sign> Channel<Signer> {
                let funding_txo = self.get_funding_txo().unwrap();
                let funding_txo_script = funding_redeemscript.to_v0_p2wsh();
                let obscure_factor = get_commitment_transaction_number_obscure_factor(&self.get_holder_pubkeys().payment_point, &self.get_counterparty_pubkeys().payment_point, self.is_outbound());
-               let mut channel_monitor = ChannelMonitor::new(self.holder_signer.clone(),
-                                                             &self.shutdown_pubkey, self.get_holder_selected_contest_delay(),
-                                                             &self.destination_script, (funding_txo, funding_txo_script),
-                                                             &self.channel_transaction_parameters,
-                                                             funding_redeemscript.clone(), self.channel_value_satoshis,
-                                                             obscure_factor,
-                                                             holder_commitment_tx);
+               let channel_monitor = ChannelMonitor::new(self.secp_ctx.clone(), self.holder_signer.clone(),
+                                                         &self.shutdown_pubkey, self.get_holder_selected_contest_delay(),
+                                                         &self.destination_script, (funding_txo, funding_txo_script),
+                                                         &self.channel_transaction_parameters,
+                                                         funding_redeemscript.clone(), self.channel_value_satoshis,
+                                                         obscure_factor,
+                                                         holder_commitment_tx);
 
                channel_monitor.provide_latest_counterparty_commitment_tx(counterparty_initial_bitcoin_tx.txid, Vec::new(), self.cur_counterparty_commitment_transaction_number, self.counterparty_cur_commitment_point.unwrap(), logger);
 
@@ -3066,7 +3071,7 @@ impl<Signer: Sign> Channel<Signer> {
                })
        }
 
-       pub fn shutdown<F: Deref>(&mut self, fee_estimator: &F, msg: &msgs::Shutdown) -> Result<(Option<msgs::Shutdown>, Option<msgs::ClosingSigned>, Vec<(HTLCSource, PaymentHash)>), ChannelError>
+       pub fn shutdown<F: Deref>(&mut self, fee_estimator: &F, their_features: &InitFeatures, msg: &msgs::Shutdown) -> Result<(Option<msgs::Shutdown>, Option<msgs::ClosingSigned>, Vec<(HTLCSource, PaymentHash)>), ChannelError>
                where F::Target: FeeEstimator
        {
                if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 {
@@ -3085,14 +3090,7 @@ impl<Signer: Sign> Channel<Signer> {
                }
                assert_eq!(self.channel_state & ChannelState::ShutdownComplete as u32, 0);
 
-               // BOLT 2 says we must only send a scriptpubkey of certain standard forms, which are up to
-               // 34 bytes in length, so don't let the remote peer feed us some super fee-heavy script.
-               if self.is_outbound() && msg.scriptpubkey.len() > 34 {
-                       return Err(ChannelError::Close(format!("Got counterparty shutdown_scriptpubkey ({}) of absurd length from remote peer", msg.scriptpubkey.to_bytes().to_hex())));
-               }
-
-               //Check counterparty_shutdown_scriptpubkey form as BOLT says we must
-               if !msg.scriptpubkey.is_p2pkh() && !msg.scriptpubkey.is_p2sh() && !msg.scriptpubkey.is_v0_p2wpkh() && !msg.scriptpubkey.is_v0_p2wsh() {
+               if is_unsupported_shutdown_script(&their_features, &msg.scriptpubkey) {
                        return Err(ChannelError::Close(format!("Got a nonstandard scriptpubkey ({}) from remote peer", msg.scriptpubkey.to_bytes().to_hex())));
                }
 
@@ -3327,7 +3325,7 @@ impl<Signer: Sign> Channel<Signer> {
                        // Upper bound by capacity. We make it a bit less than full capacity to prevent attempts
                        // to use full capacity. This is an effort to reduce routing failures, because in many cases
                        // channel might have been used to route very small values (either by honest users or as DoS).
-                       self.channel_value_satoshis * 9 / 10,
+                       self.channel_value_satoshis * 1000 * 9 / 10,
 
                        Channel::<Signer>::get_holder_max_htlc_value_in_flight_msat(self.channel_value_satoshis)
                );
@@ -4089,7 +4087,8 @@ impl<Signer: Sign> Channel<Signer> {
                        signature = res.0;
                        htlc_signatures = res.1;
 
-                       log_trace!(logger, "Signed remote commitment tx {} with redeemscript {} -> {}",
+                       log_trace!(logger, "Signed remote commitment tx {} (txid {}) with redeemscript {} -> {}",
+                               encode::serialize_hex(&counterparty_commitment_tx.0.trust().built_transaction().transaction),
                                &counterparty_commitment_txid,
                                encode::serialize_hex(&self.get_funding_redeemscript()),
                                log_bytes!(signature.serialize_compact()[..]));
@@ -4180,7 +4179,11 @@ impl<Signer: Sign> Channel<Signer> {
        /// those explicitly stated to be allowed after shutdown completes, eg some simple getters).
        /// Also returns the list of payment_hashes for channels which we can safely fail backwards
        /// immediately (others we will have to allow to time out).
-       pub fn force_shutdown(&mut self, should_broadcast: bool) -> (Option<OutPoint>, ChannelMonitorUpdate, Vec<(HTLCSource, PaymentHash)>) {
+       pub fn force_shutdown(&mut self, should_broadcast: bool) -> (Option<(OutPoint, ChannelMonitorUpdate)>, Vec<(HTLCSource, PaymentHash)>) {
+               // Note that we MUST only generate a monitor update that indicates force-closure - we're
+               // called during initialization prior to the chain_monitor in the encompassing ChannelManager
+               // being fully configured in some cases. Thus, its likely any monitor events we generate will
+               // be delayed in being processed! See the docs for `ChannelManagerReadArgs` for more.
                assert!(self.channel_state != ChannelState::ShutdownComplete as u32);
 
                // We go ahead and "free" any holding cell HTLCs or HTLCs we haven't yet committed to and
@@ -4194,7 +4197,7 @@ impl<Signer: Sign> Channel<Signer> {
                                _ => {}
                        }
                }
-               let funding_txo = if let Some(funding_txo) = self.get_funding_txo() {
+               let monitor_update = if let Some(funding_txo) = self.get_funding_txo() {
                        // If we haven't yet exchanged funding signatures (ie channel_state < FundingSent),
                        // returning a channel monitor update here would imply a channel monitor update before
                        // we even registered the channel monitor to begin with, which is invalid.
@@ -4203,18 +4206,36 @@ impl<Signer: Sign> Channel<Signer> {
                        // monitor update to the user, even if we return one).
                        // See test_duplicate_chan_id and test_pre_lockin_no_chan_closed_update for more.
                        if self.channel_state & (ChannelState::FundingSent as u32 | ChannelState::ChannelFunded as u32 | ChannelState::ShutdownComplete as u32) != 0 {
-                               Some(funding_txo.clone())
+                               self.latest_monitor_update_id += 1;
+                               Some((funding_txo, ChannelMonitorUpdate {
+                                       update_id: self.latest_monitor_update_id,
+                                       updates: vec![ChannelMonitorUpdateStep::ChannelForceClosed { should_broadcast }],
+                               }))
                        } else { None }
                } else { None };
 
                self.channel_state = ChannelState::ShutdownComplete as u32;
                self.update_time_counter += 1;
-               self.latest_monitor_update_id += 1;
-               (funding_txo, ChannelMonitorUpdate {
-                       update_id: self.latest_monitor_update_id,
-                       updates: vec![ChannelMonitorUpdateStep::ChannelForceClosed { should_broadcast }],
-               }, dropped_outbound_htlcs)
+               (monitor_update, dropped_outbound_htlcs)
+       }
+}
+
+fn is_unsupported_shutdown_script(their_features: &InitFeatures, script: &Script) -> bool {
+       // We restrain shutdown scripts to standards forms to avoid transactions not propagating on the p2p tx-relay network
+
+       // BOLT 2 says we must only send a scriptpubkey of certain standard forms,
+       // which for a a BIP-141-compliant witness program is at max 42 bytes in length.
+       // So don't let the remote peer feed us some super fee-heavy script.
+       let is_script_too_long = script.len() > 42;
+       if is_script_too_long {
+               return true;
+       }
+
+       if their_features.supports_shutdown_anysegwit() && script.is_witness_program() && script.as_bytes()[0] != OP_PUSHBYTES_0.into_u8() {
+               return false;
        }
+
+       return !script.is_p2pkh() && !script.is_p2sh() && !script.is_v0_p2wpkh() && !script.is_v0_p2wsh()
 }
 
 const SERIALIZATION_VERSION: u8 = 1;
@@ -4598,13 +4619,16 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
                let counterparty_shutdown_scriptpubkey = Readable::read(reader)?;
                let commitment_secrets = Readable::read(reader)?;
 
+               let mut secp_ctx = Secp256k1::new();
+               secp_ctx.seeded_randomize(&keys_source.get_secure_random_bytes());
+
                Ok(Channel {
                        user_id,
 
                        config,
                        channel_id,
                        channel_state,
-                       secp_ctx: Secp256k1::new(),
+                       secp_ctx,
                        channel_value_satoshis,
 
                        latest_monitor_update_id,