Add a comment describing the timestamp field's use
[rust-lightning] / lightning / src / ln / channel.rs
index 5aaabd2b4b4d74ec940727d136a23efc6975619e..55dd76cc033faee51a13dad560f6ce64595db858 100644 (file)
@@ -408,6 +408,11 @@ pub(crate) const FUNDING_CONF_DEADLINE_BLOCKS: u32 = 2016;
 /// design of LN state machines, allowing asynchronous updates.
 pub(crate) const CONCURRENT_INBOUND_HTLC_FEE_BUFFER: u32 = 2;
 
+/// When a channel is opened, we check that the funding amount is enough to pay for relevant
+/// commitment transaction fees, with at least this many HTLCs present on the commitment
+/// transaction (not counting the value of the HTLCs themselves).
+pub(crate) const MIN_AFFORDABLE_HTLC_COUNT: usize = 4;
+
 // TODO: We should refactor this to be an Inbound/OutboundChannel until initial setup handshaking
 // has been completed, and then turn into a Channel to get compiler-time enforcement of things like
 // calling channel_id() before we're set up or things like get_outbound_funding_signed on an
@@ -476,9 +481,14 @@ pub(super) struct Channel<Signer: Sign> {
        holding_cell_update_fee: Option<u32>,
        next_holder_htlc_id: u64,
        next_counterparty_htlc_id: u64,
-       update_time_counter: u32,
        feerate_per_kw: u32,
 
+       /// The timestamp set on our latest `channel_update` message for this channel. It is updated
+       /// when the channel is updated in ways which may impact the `channel_update` message or when a
+       /// new block is received, ensuring it's always at least moderately close to the current real
+       /// time.
+       update_time_counter: u32,
+
        #[cfg(debug_assertions)]
        /// Max to_local and to_remote outputs in a locally-generated commitment transaction
        holder_max_commitment_tx_output: Mutex<(u64, u64)>,
@@ -679,6 +689,10 @@ impl<Signer: Sign> Channel<Signer> {
                cmp::min(channel_value_satoshis, cmp::max(q, 1000)) //TODO
        }
 
+       pub(crate) fn opt_anchors(&self) -> bool {
+               self.channel_transaction_parameters.opt_anchors.is_some()
+       }
+
        // Constructors:
        pub fn new_outbound<K: Deref, F: Deref>(
                fee_estimator: &F, keys_provider: &K, counterparty_node_id: PublicKey, their_features: &InitFeatures,
@@ -708,6 +722,12 @@ impl<Signer: Sign> Channel<Signer> {
 
                let feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Normal);
 
+               let value_to_self_msat = channel_value_satoshis * 1000 - push_msat;
+               let commitment_tx_fee = Self::commit_tx_fee_msat(feerate, MIN_AFFORDABLE_HTLC_COUNT);
+               if value_to_self_msat < commitment_tx_fee {
+                       return Err(APIError::APIMisuseError{ err: format!("Funding amount ({}) can't even pay fee for initial commitment transaction fee of {}.", value_to_self_msat / 1000, commitment_tx_fee / 1000) });
+               }
+
                let mut secp_ctx = Secp256k1::new();
                secp_ctx.seeded_randomize(&keys_provider.get_secure_random_bytes());
 
@@ -738,7 +758,7 @@ impl<Signer: Sign> Channel<Signer> {
 
                        cur_holder_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
                        cur_counterparty_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
-                       value_to_self_msat: channel_value_satoshis * 1000 - push_msat,
+                       value_to_self_msat,
 
                        pending_inbound_htlcs: Vec::new(),
                        pending_outbound_htlcs: Vec::new(),
@@ -790,7 +810,8 @@ impl<Signer: Sign> Channel<Signer> {
                                holder_selected_contest_delay: config.own_channel_config.our_to_self_delay,
                                is_outbound_from_holder: true,
                                counterparty_parameters: None,
-                               funding_outpoint: None
+                               funding_outpoint: None,
+                               opt_anchors: None,
                        },
                        funding_transaction: None,
 
@@ -952,8 +973,6 @@ impl<Signer: Sign> Channel<Signer> {
                // we either accept their preference or the preferences match
                local_config.announced_channel = announce;
 
-               let background_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background);
-
                let holder_selected_channel_reserve_satoshis = Channel::<Signer>::get_holder_selected_channel_reserve_satoshis(msg.funding_satoshis);
                if holder_selected_channel_reserve_satoshis < MIN_CHAN_DUST_LIMIT_SATOSHIS {
                        return Err(ChannelError::Close(format!("Suitable channel reserve not found. remote_channel_reserve was ({}). dust_limit_satoshis is ({}).", holder_selected_channel_reserve_satoshis, MIN_CHAN_DUST_LIMIT_SATOSHIS)));
@@ -966,17 +985,18 @@ impl<Signer: Sign> Channel<Signer> {
                }
 
                // check if the funder's amount for the initial commitment tx is sufficient
-               // for full fee payment
+               // for full fee payment plus a few HTLCs to ensure the channel will be useful.
                let funders_amount_msat = msg.funding_satoshis * 1000 - msg.push_msat;
-               let lower_limit = background_feerate as u64 * COMMITMENT_TX_BASE_WEIGHT;
-               if funders_amount_msat < lower_limit {
-                       return Err(ChannelError::Close(format!("Insufficient funding amount ({}) for initial commitment. Must be at least {}", funders_amount_msat, lower_limit)));
+               let commitment_tx_fee = Self::commit_tx_fee_msat(msg.feerate_per_kw, MIN_AFFORDABLE_HTLC_COUNT) / 1000;
+               if funders_amount_msat / 1000 < commitment_tx_fee {
+                       return Err(ChannelError::Close(format!("Funding amount ({} sats) can't even pay fee for initial commitment transaction fee of {} sats.", funders_amount_msat / 1000, commitment_tx_fee)));
                }
 
-               let to_local_msat = msg.push_msat;
-               let to_remote_msat = funders_amount_msat - background_feerate as u64 * COMMITMENT_TX_BASE_WEIGHT;
-               if to_local_msat <= msg.channel_reserve_satoshis * 1000 && to_remote_msat <= holder_selected_channel_reserve_satoshis * 1000 {
-                       return Err(ChannelError::Close("Insufficient funding amount for initial commitment".to_owned()));
+               let to_remote_satoshis = funders_amount_msat / 1000 - commitment_tx_fee;
+               // While it's reasonable for us to not meet the channel reserve initially (if they don't
+               // want to push much to us), our counterparty should always have more than our reserve.
+               if to_remote_satoshis < holder_selected_channel_reserve_satoshis {
+                       return Err(ChannelError::Close("Insufficient funding amount for initial reserve".to_owned()));
                }
 
                let counterparty_shutdown_scriptpubkey = if their_features.supports_upfront_shutdown_script() {
@@ -1084,7 +1104,8 @@ impl<Signer: Sign> Channel<Signer> {
                                        selected_contest_delay: msg.to_self_delay,
                                        pubkeys: counterparty_pubkeys,
                                }),
-                               funding_outpoint: None
+                               funding_outpoint: None,
+                               opt_anchors: None
                        },
                        funding_transaction: None,
 
@@ -1311,7 +1332,7 @@ impl<Signer: Sign> Channel<Signer> {
                let tx = CommitmentTransaction::new_with_auxiliary_htlc_data(commitment_number,
                                                                             value_to_a as u64,
                                                                             value_to_b as u64,
-                                                                            false,
+                                                                            self.channel_transaction_parameters.opt_anchors.is_some(),
                                                                             funding_pubkey_a,
                                                                             funding_pubkey_b,
                                                                             keys.clone(),
@@ -2575,10 +2596,10 @@ impl<Signer: Sign> Channel<Signer> {
                for (idx, (htlc, source)) in htlcs_cloned.drain(..).enumerate() {
                        if let Some(_) = htlc.transaction_output_index {
                                let htlc_tx = chan_utils::build_htlc_transaction(&commitment_txid, commitment_stats.feerate_per_kw,
-                                       self.get_counterparty_selected_contest_delay().unwrap(), &htlc,
+                                       self.get_counterparty_selected_contest_delay().unwrap(), &htlc, self.opt_anchors(),
                                        &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
 
-                               let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &keys);
+                               let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, self.opt_anchors(), &keys);
                                let htlc_sighash = hash_to_message!(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, SigHashType::All)[..]);
                                log_trace!(logger, "Checking HTLC tx signature {} by key {} against tx {} (sighash {}) with redeemscript {} in channel {}.",
                                        log_bytes!(msg.htlc_signatures[idx].serialize_compact()[..]), log_bytes!(keys.countersignatory_htlc_key.serialize()),
@@ -4151,6 +4172,7 @@ impl<Signer: Sign> Channel<Signer> {
        }
 
        pub fn set_channel_update_status(&mut self, status: ChannelUpdateStatus) {
+               self.update_time_counter += 1;
                self.channel_update_status = status;
        }
 
@@ -4921,8 +4943,8 @@ impl<Signer: Sign> Channel<Signer> {
 
                        for (ref htlc_sig, ref htlc) in htlc_signatures.iter().zip(htlcs) {
                                log_trace!(logger, "Signed remote HTLC tx {} with redeemscript {} with pubkey {} -> {} in channel {}",
-                                       encode::serialize_hex(&chan_utils::build_htlc_transaction(&counterparty_commitment_txid, commitment_stats.feerate_per_kw, self.get_holder_selected_contest_delay(), htlc, &counterparty_keys.broadcaster_delayed_payment_key, &counterparty_keys.revocation_key)),
-                                       encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, &counterparty_keys)),
+                                       encode::serialize_hex(&chan_utils::build_htlc_transaction(&counterparty_commitment_txid, commitment_stats.feerate_per_kw, self.get_holder_selected_contest_delay(), htlc, self.opt_anchors(), &counterparty_keys.broadcaster_delayed_payment_key, &counterparty_keys.revocation_key)),
+                                       encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, self.opt_anchors(), &counterparty_keys)),
                                        log_bytes!(counterparty_keys.broadcaster_htlc_key.serialize()),
                                        log_bytes!(htlc_sig.serialize_compact()[..]), log_bytes!(self.channel_id()));
                        }
@@ -5626,6 +5648,11 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
                        return Err(DecodeError::UnknownRequiredFeature);
                }
 
+               if channel_parameters.opt_anchors.is_some() {
+                       // Relax this check when ChannelTypeFeatures supports anchors.
+                       return Err(DecodeError::InvalidValue);
+               }
+
                let mut secp_ctx = Secp256k1::new();
                secp_ctx.seeded_randomize(&keys_source.get_secure_random_bytes());
 
@@ -6212,10 +6239,11 @@ mod tests {
                                        let remote_signature = Signature::from_der(&hex::decode($counterparty_htlc_sig_hex).unwrap()[..]).unwrap();
 
                                        let ref htlc = htlcs[$htlc_idx];
+                                       let opt_anchors = false;
                                        let htlc_tx = chan_utils::build_htlc_transaction(&unsigned_tx.txid, chan.feerate_per_kw,
                                                chan.get_counterparty_selected_contest_delay().unwrap(),
-                                               &htlc, &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
-                                       let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &keys);
+                                               &htlc, opt_anchors, &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
+                                       let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, opt_anchors, &keys);
                                        let htlc_sighash = Message::from_slice(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, SigHashType::All)[..]).unwrap();
                                        secp_ctx.verify(&htlc_sighash, &remote_signature, &keys.countersignatory_htlc_key).unwrap();