Merge pull request #901 from jkczyz/2021-04-invoice-feature-semantics
[rust-lightning] / lightning / src / ln / channel.rs
index 5f987427979cbb9d267a73ea7f3fc0b0dd374378..413dc8313a6c5d18c73b92f74c5ee9d685c44dda 100644 (file)
@@ -21,10 +21,11 @@ use bitcoin::secp256k1::key::{PublicKey,SecretKey};
 use bitcoin::secp256k1::{Secp256k1,Signature};
 use bitcoin::secp256k1;
 
+use ln::{PaymentPreimage, PaymentHash};
 use ln::features::{ChannelFeatures, InitFeatures};
 use ln::msgs;
 use ln::msgs::{DecodeError, OptionalField, DataLossProtect};
-use ln::channelmanager::{BestBlock, PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, PaymentPreimage, PaymentHash, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, MAX_LOCAL_BREAKDOWN_TIMEOUT};
+use ln::channelmanager::{BestBlock, PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, MAX_LOCAL_BREAKDOWN_TIMEOUT};
 use ln::chan_utils::{CounterpartyCommitmentSecrets, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys, CommitmentTransaction, HolderCommitmentTransaction, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, MAX_HTLCS, get_commitment_transaction_number_obscure_factor};
 use ln::chan_utils;
 use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
@@ -438,7 +439,6 @@ struct CommitmentTxInfoCached {
 
 pub const OUR_MAX_HTLCS: u16 = 50; //TODO
 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?)
 
 #[cfg(not(test))]
 const COMMITMENT_TX_BASE_WEIGHT: u64 = 724;
@@ -453,6 +453,22 @@ pub const COMMITMENT_TX_WEIGHT_PER_HTLC: u64 = 172;
 /// it's 2^24.
 pub const MAX_FUNDING_SATOSHIS: u64 = 1 << 24;
 
+/// Maximum counterparty `dust_limit_satoshis` allowed. 2 * standard dust threshold on p2wsh output
+/// Scales up on Bitcoin Core's proceeding policy with dust outputs. A typical p2wsh output is 43
+/// bytes to which Core's `GetDustThreshold()` sums up a minimal spend of 67 bytes (even if
+/// a p2wsh witnessScript might be *effectively* smaller), `dustRelayFee` is set to 3000sat/kb, thus
+/// 110 * 3000 / 1000 = 330. Per-protocol rules, all time-sensitive outputs are p2wsh, a value of
+/// 330 sats is the lower bound desired to ensure good propagation of transactions. We give a bit
+/// of margin to our counterparty and pick up 660 satoshis as an accepted `dust_limit_satoshis`
+/// upper bound to avoid negotiation conflicts with other implementations.
+pub const MAX_DUST_LIMIT_SATOSHIS: u64 = 2 * 330;
+
+/// A typical p2wsh output is 43 bytes to which Core's `GetDustThreshold()` sums up a minimal
+/// spend of 67 bytes (even if a p2wsh witnessScript might be *effectively* smaller), `dustRelayFee`
+/// is set to 3000sat/kb, thus 110 * 3000 / 1000 = 330. Per-protocol rules, all time-sensitive outputs
+/// are p2wsh, a value of 330 sats is the lower bound desired to ensure good propagation of transactions.
+pub const MIN_DUST_LIMIT_SATOSHIS: u64 = 330;
+
 /// Used to return a simple Error back to ChannelManager. Will get converted to a
 /// msgs::ErrorAction::SendErrorMessage or msgs::ErrorAction::IgnoreError as appropriate with our
 /// channel_id in ChannelManager.
@@ -496,10 +512,6 @@ impl<Signer: Sign> Channel<Signer> {
                cmp::min(channel_value_satoshis, cmp::max(q, 1000)) //TODO
        }
 
-       fn derive_holder_dust_limit_satoshis(at_open_background_feerate: u32) -> u64 {
-               cmp::max(at_open_background_feerate as u64 * B_OUTPUT_PLUS_SPENDING_INPUT_WEIGHT / 1000, 546) //TODO
-       }
-
        // Constructors:
        pub fn new_outbound<K: Deref, F: Deref>(fee_estimator: &F, keys_provider: &K, counterparty_node_id: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_id: u64, config: &UserConfig) -> Result<Channel<Signer>, APIError>
        where K::Target: KeysInterface<Signer = Signer>,
@@ -519,9 +531,9 @@ impl<Signer: Sign> Channel<Signer> {
                if holder_selected_contest_delay < BREAKDOWN_TIMEOUT {
                        return Err(APIError::APIMisuseError {err: format!("Configured with an unreasonable our_to_self_delay ({}) putting user funds at risks", holder_selected_contest_delay)});
                }
-               let background_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background);
-               if Channel::<Signer>::get_holder_selected_channel_reserve_satoshis(channel_value_satoshis) < Channel::<Signer>::derive_holder_dust_limit_satoshis(background_feerate) {
-                       return Err(APIError::FeeRateTooHigh{err: format!("Not enough reserve above dust limit can be found at current fee rate({})", background_feerate), feerate: background_feerate});
+               let holder_selected_channel_reserve_satoshis = Channel::<Signer>::get_holder_selected_channel_reserve_satoshis(channel_value_satoshis);
+               if holder_selected_channel_reserve_satoshis < MIN_DUST_LIMIT_SATOSHIS {
+                       return Err(APIError::APIMisuseError { err: format!("Holder selected channel  reserve below implemention limit dust_limit_satoshis {}", holder_selected_channel_reserve_satoshis) });
                }
 
                let feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Normal);
@@ -578,7 +590,7 @@ impl<Signer: Sign> Channel<Signer> {
 
                        feerate_per_kw: feerate,
                        counterparty_dust_limit_satoshis: 0,
-                       holder_dust_limit_satoshis: Channel::<Signer>::derive_holder_dust_limit_satoshis(background_feerate),
+                       holder_dust_limit_satoshis: MIN_DUST_LIMIT_SATOSHIS,
                        counterparty_max_htlc_value_in_flight_msat: 0,
                        counterparty_selected_channel_reserve_satoshis: 0,
                        counterparty_htlc_minimum_msat: 0,
@@ -699,11 +711,11 @@ impl<Signer: Sign> Channel<Signer> {
                if msg.max_accepted_htlcs < config.peer_channel_config_limits.min_max_accepted_htlcs {
                        return Err(ChannelError::Close(format!("max_accepted_htlcs ({}) is less than the user specified limit ({})", msg.max_accepted_htlcs, config.peer_channel_config_limits.min_max_accepted_htlcs)));
                }
-               if msg.dust_limit_satoshis < config.peer_channel_config_limits.min_dust_limit_satoshis {
-                       return Err(ChannelError::Close(format!("dust_limit_satoshis ({}) is less than the user specified limit ({})", msg.dust_limit_satoshis, config.peer_channel_config_limits.min_dust_limit_satoshis)));
+               if msg.dust_limit_satoshis < MIN_DUST_LIMIT_SATOSHIS {
+                       return Err(ChannelError::Close(format!("dust_limit_satoshis ({}) is less than the implementation limit ({})", msg.dust_limit_satoshis, MIN_DUST_LIMIT_SATOSHIS)));
                }
-               if msg.dust_limit_satoshis > config.peer_channel_config_limits.max_dust_limit_satoshis {
-                       return Err(ChannelError::Close(format!("dust_limit_satoshis ({}) is greater than the user specified limit ({})", msg.dust_limit_satoshis, config.peer_channel_config_limits.max_dust_limit_satoshis)));
+               if msg.dust_limit_satoshis >  MAX_DUST_LIMIT_SATOSHIS {
+                       return Err(ChannelError::Close(format!("dust_limit_satoshis ({}) is greater than the implementation limit ({})", msg.dust_limit_satoshis, MAX_DUST_LIMIT_SATOSHIS)));
                }
 
                // Convert things into internal flags and prep our state:
@@ -719,13 +731,12 @@ impl<Signer: Sign> Channel<Signer> {
 
                let background_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background);
 
-               let holder_dust_limit_satoshis = Channel::<Signer>::derive_holder_dust_limit_satoshis(background_feerate);
                let holder_selected_channel_reserve_satoshis = Channel::<Signer>::get_holder_selected_channel_reserve_satoshis(msg.funding_satoshis);
-               if holder_selected_channel_reserve_satoshis < holder_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, holder_dust_limit_satoshis)));
+               if holder_selected_channel_reserve_satoshis < MIN_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_DUST_LIMIT_SATOSHIS)));
                }
-               if msg.channel_reserve_satoshis < holder_dust_limit_satoshis {
-                       return Err(ChannelError::Close(format!("channel_reserve_satoshis ({}) is smaller than our dust limit ({})", msg.channel_reserve_satoshis, holder_dust_limit_satoshis)));
+               if msg.channel_reserve_satoshis < MIN_DUST_LIMIT_SATOSHIS {
+                       return Err(ChannelError::Close(format!("channel_reserve_satoshis ({}) is smaller than our dust limit ({})", msg.channel_reserve_satoshis, MIN_DUST_LIMIT_SATOSHIS)));
                }
                if holder_selected_channel_reserve_satoshis < msg.dust_limit_satoshis {
                        return Err(ChannelError::Close(format!("Dust limit ({}) too high for the channel reserve we require the remote to keep ({})", msg.dust_limit_satoshis, holder_selected_channel_reserve_satoshis)));
@@ -817,7 +828,7 @@ impl<Signer: Sign> Channel<Signer> {
                        feerate_per_kw: msg.feerate_per_kw,
                        channel_value_satoshis: msg.funding_satoshis,
                        counterparty_dust_limit_satoshis: msg.dust_limit_satoshis,
-                       holder_dust_limit_satoshis,
+                       holder_dust_limit_satoshis: MIN_DUST_LIMIT_SATOSHIS,
                        counterparty_max_htlc_value_in_flight_msat: cmp::min(msg.max_htlc_value_in_flight_msat, msg.funding_satoshis * 1000),
                        counterparty_selected_channel_reserve_satoshis: msg.channel_reserve_satoshis,
                        counterparty_htlc_minimum_msat: msg.htlc_minimum_msat,
@@ -1441,11 +1452,11 @@ impl<Signer: Sign> Channel<Signer> {
                if msg.max_accepted_htlcs < config.peer_channel_config_limits.min_max_accepted_htlcs {
                        return Err(ChannelError::Close(format!("max_accepted_htlcs ({}) is less than the user specified limit ({})", msg.max_accepted_htlcs, config.peer_channel_config_limits.min_max_accepted_htlcs)));
                }
-               if msg.dust_limit_satoshis < config.peer_channel_config_limits.min_dust_limit_satoshis {
-                       return Err(ChannelError::Close(format!("dust_limit_satoshis ({}) is less than the user specified limit ({})", msg.dust_limit_satoshis, config.peer_channel_config_limits.min_dust_limit_satoshis)));
+               if msg.dust_limit_satoshis < MIN_DUST_LIMIT_SATOSHIS {
+                       return Err(ChannelError::Close(format!("dust_limit_satoshis ({}) is less than the implementation limit ({})", msg.dust_limit_satoshis, MIN_DUST_LIMIT_SATOSHIS)));
                }
-               if msg.dust_limit_satoshis > config.peer_channel_config_limits.max_dust_limit_satoshis {
-                       return Err(ChannelError::Close(format!("dust_limit_satoshis ({}) is greater than the user specified limit ({})", msg.dust_limit_satoshis, config.peer_channel_config_limits.max_dust_limit_satoshis)));
+               if msg.dust_limit_satoshis > MAX_DUST_LIMIT_SATOSHIS {
+                       return Err(ChannelError::Close(format!("dust_limit_satoshis ({}) is greater than the implementation limit ({})", msg.dust_limit_satoshis, MAX_DUST_LIMIT_SATOSHIS)));
                }
                if msg.minimum_depth > config.peer_channel_config_limits.max_minimum_depth {
                        return Err(ChannelError::Close(format!("We consider the minimum depth to be unreasonably large. Expected minimum: ({}). Actual: ({})", config.peer_channel_config_limits.max_minimum_depth, msg.minimum_depth)));
@@ -3574,7 +3585,6 @@ impl<Signer: Sign> Channel<Signer> {
                                                                #[cfg(not(feature = "fuzztarget"))]
                                                                panic!("Client called ChannelManager::funding_transaction_generated with bogus transaction!");
                                                        }
-                                                       self.channel_state = ChannelState::ShutdownComplete as u32;
                                                        self.update_time_counter += 1;
                                                        return Err(msgs::ErrorMessage {
                                                                channel_id: self.channel_id(),
@@ -3600,7 +3610,7 @@ impl<Signer: Sign> Channel<Signer> {
                                                }
                                        }
                                        // If we allow 1-conf funding, we may need to check for funding_locked here and
-                                       // send it immediately instead of waiting for an update_best_block call (which
+                                       // send it immediately instead of waiting for a best_block_updated call (which
                                        // may have already happened for this block).
                                        if let Some(funding_locked) = self.check_get_funding_locked(height) {
                                                return Ok(Some(funding_locked));
@@ -3631,7 +3641,7 @@ impl<Signer: Sign> Channel<Signer> {
        ///
        /// May return some HTLCs (and their payment_hash) which have timed out and should be failed
        /// back.
-       pub fn update_best_block(&mut self, height: u32, highest_header_time: u32) -> Result<(Option<msgs::FundingLocked>, Vec<(HTLCSource, PaymentHash)>), msgs::ErrorMessage> {
+       pub fn best_block_updated(&mut self, height: u32, highest_header_time: u32) -> Result<(Option<msgs::FundingLocked>, Vec<(HTLCSource, PaymentHash)>), msgs::ErrorMessage> {
                let mut timed_out_htlcs = Vec::new();
                let unforwarded_htlc_cltv_limit = height + HTLC_FAIL_BACK_BUFFER;
                self.holding_cell_htlc_updates.retain(|htlc_update| {
@@ -3683,14 +3693,14 @@ impl<Signer: Sign> Channel<Signer> {
        /// before the channel has reached funding_locked and we can just wait for more blocks.
        pub fn funding_transaction_unconfirmed(&mut self) -> Result<(), msgs::ErrorMessage> {
                if self.funding_tx_confirmation_height != 0 {
-                       // We handle the funding disconnection by calling update_best_block with a height one
+                       // We handle the funding disconnection by calling best_block_updated with a height one
                        // below where our funding was connected, implying a reorg back to conf_height - 1.
                        let reorg_height = self.funding_tx_confirmation_height - 1;
                        // We use the time field to bump the current time we set on channel updates if its
                        // larger. If we don't know that time has moved forward, we can just set it to the last
                        // time we saw and it will be ignored.
                        let best_time = self.update_time_counter;
-                       match self.update_best_block(reorg_height, best_time) {
+                       match self.best_block_updated(reorg_height, best_time) {
                                Ok((funding_locked, timed_out_htlcs)) => {
                                        assert!(funding_locked.is_none(), "We can't generate a funding with 0 confirmations?");
                                        assert!(timed_out_htlcs.is_empty(), "We can't have accepted HTLCs with a timeout before our funding confirmation?");
@@ -4825,7 +4835,8 @@ mod tests {
        use bitcoin::network::constants::Network;
        use bitcoin::hashes::hex::FromHex;
        use hex;
-       use ln::channelmanager::{BestBlock, HTLCSource, PaymentPreimage, PaymentHash};
+       use ln::{PaymentPreimage, PaymentHash};
+       use ln::channelmanager::{BestBlock, HTLCSource};
        use ln::channel::{Channel,InboundHTLCOutput,OutboundHTLCOutput,InboundHTLCState,OutboundHTLCState,HTLCOutputInCommitment,HTLCCandidate,HTLCInitiator,TxCreationKeys};
        use ln::channel::MAX_FUNDING_SATOSHIS;
        use ln::features::InitFeatures;
@@ -4842,6 +4853,7 @@ mod tests {
        use bitcoin::secp256k1::{Secp256k1, Message, Signature, All};
        use bitcoin::secp256k1::ffi::Signature as FFISignature;
        use bitcoin::secp256k1::key::{SecretKey,PublicKey};
+       use bitcoin::secp256k1::recovery::RecoverableSignature;
        use bitcoin::hashes::sha256::Hash as Sha256;
        use bitcoin::hashes::Hash;
        use bitcoin::hash_types::{Txid, WPubkeyHash};
@@ -4887,6 +4899,7 @@ mod tests {
                }
                fn get_secure_random_bytes(&self) -> [u8; 32] { [0; 32] }
                fn read_chan_signer(&self, _data: &[u8]) -> Result<Self::Signer, DecodeError> { panic!(); }
+               fn sign_invoice(&self, _invoice_preimage: Vec<u8>) -> Result<RecoverableSignature, ()> { panic!(); }
        }
 
        fn public_from_secret_hex(secp_ctx: &Secp256k1<All>, hex: &str) -> PublicKey {
@@ -4936,7 +4949,6 @@ mod tests {
                // Create Node B's channel by receiving Node A's open_channel message
                // Make sure A's dust limit is as we expect.
                let open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.block_hash());
-               assert_eq!(open_channel_msg.dust_limit_satoshis, 1560);
                let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
                let node_b_chan = Channel::<EnforcingSigner>::new_from_req(&&feeest, &&keys_provider, node_b_node_id, InitFeatures::known(), &open_channel_msg, 7, &config).unwrap();
 
@@ -4944,6 +4956,7 @@ mod tests {
                let mut accept_channel_msg = node_b_chan.get_accept_channel();
                accept_channel_msg.dust_limit_satoshis = 546;
                node_a_chan.accept_channel(&accept_channel_msg, &config, InitFeatures::known()).unwrap();
+               node_a_chan.holder_dust_limit_satoshis = 1560;
 
                // Put some inbound and outbound HTLCs in A's channel.
                let htlc_amount_msat = 11_092_000; // put an amount below A's effective dust limit but above B's.