Force-close channels if their feerate gets stale without any update
[rust-lightning] / lightning / src / ln / channel.rs
index 37ce1082e0a0065c9cd65662172735a0a3c4477b..75d1c0949e4fbd846e98a6641beddb663866ceae 100644 (file)
@@ -710,7 +710,7 @@ pub const MIN_THEIR_CHAN_RESERVE_SATOSHIS: u64 = 1000;
 pub(super) enum ChannelError {
        Ignore(String),
        Warn(String),
-       Close(String),
+       Close((String, ClosureReason)),
 }
 
 impl fmt::Debug for ChannelError {
@@ -718,7 +718,7 @@ impl fmt::Debug for ChannelError {
                match self {
                        &ChannelError::Ignore(ref e) => write!(f, "Ignore : {}", e),
                        &ChannelError::Warn(ref e) => write!(f, "Warn : {}", e),
-                       &ChannelError::Close(ref e) => write!(f, "Close : {}", e),
+                       &ChannelError::Close((ref e, _)) => write!(f, "Close : {}", e),
                }
        }
 }
@@ -728,14 +728,14 @@ impl fmt::Display for ChannelError {
                match self {
                        &ChannelError::Ignore(ref e) => write!(f, "{}", e),
                        &ChannelError::Warn(ref e) => write!(f, "{}", e),
-                       &ChannelError::Close(ref e) => write!(f, "{}", e),
+                       &ChannelError::Close((ref e, _)) => write!(f, "{}", e),
                }
        }
 }
 
 impl ChannelError {
        pub(super) fn close(err: String) -> Self {
-               ChannelError::Close(err.clone())
+               ChannelError::Close((err.clone(), ClosureReason::ProcessingError { err }))
        }
 }
 
@@ -3512,7 +3512,12 @@ impl<SP: Deref> Channel<SP> where
                                        return Ok(());
                                }
                        }
-                       return Err(ChannelError::close(format!("Peer's feerate much too low. Actual: {}. Our expected lower limit: {}", feerate_per_kw, lower_limit)));
+                       return Err(ChannelError::Close((format!(
+                               "Peer's feerate much too low. Actual: {}. Our expected lower limit: {}", feerate_per_kw, lower_limit
+                       ), ClosureReason::PeerFeerateTooLow {
+                               peer_feerate_sat_per_kw: feerate_per_kw,
+                               required_feerate_sat_per_kw: lower_limit,
+                       })));
                }
                Ok(())
        }
@@ -5112,6 +5117,26 @@ impl<SP: Deref> Channel<SP> where
                }
        }
 
+       pub fn check_for_stale_feerate<L: Logger>(&mut self, logger: &L, min_feerate: u32) -> Result<(), ClosureReason> {
+               if self.context.is_outbound() {
+                       // While its possible our fee is too low for an outbound channel because we've been
+                       // unable to increase the fee, we don't try to force-close directly here.
+                       return Ok(());
+               }
+               if self.context.feerate_per_kw < min_feerate {
+                       log_info!(logger,
+                               "Closing channel as feerate of {} is below required {} (the minimum required rate over the past day)",
+                               self.context.feerate_per_kw, min_feerate
+                       );
+                       Err(ClosureReason::PeerFeerateTooLow {
+                               peer_feerate_sat_per_kw: self.context.feerate_per_kw,
+                               required_feerate_sat_per_kw: min_feerate,
+                       })
+               } else {
+                       Ok(())
+               }
+       }
+
        pub fn update_fee<F: Deref, L: Deref>(&mut self, fee_estimator: &LowerBoundedFeeEstimator<F>, msg: &msgs::UpdateFee, logger: &L) -> Result<(), ChannelError>
                where F::Target: FeeEstimator, L::Target: Logger
        {