Enable wumbo channels to be created
[rust-lightning] / lightning / src / ln / channel.rs
index 17f1976364859cdc973f5ec17f6ba4cafe835651..b172b8c52ad8a0fc78e44e3869e6820d68e2a83e 100644 (file)
@@ -734,9 +734,13 @@ pub const COMMITMENT_TX_WEIGHT_PER_HTLC: u64 = 172;
 
 pub const ANCHOR_OUTPUT_VALUE_SATOSHI: u64 = 330;
 
-/// Maximum `funding_satoshis` value, according to the BOLT #2 specification
-/// it's 2^24.
-pub const MAX_FUNDING_SATOSHIS: u64 = 1 << 24;
+/// Maximum `funding_satoshis` value according to the BOLT #2 specification, if
+/// `option_support_large_channel` (aka wumbo channels) is not supported.
+/// It's 2^24 - 1.
+pub const MAX_FUNDING_SATOSHIS_NO_WUMBO: u64 = (1 << 24) - 1;
+
+/// Total bitcoin supply in satoshis.
+pub const TOTAL_BITCOIN_SUPPLY_SATOSHIS: u64 = 21_000_000 * 1_0000_0000;
 
 /// The maximum network dust limit for standard script formats. This currently represents the
 /// minimum output value for a P2SH output before Bitcoin Core 22 considers the entire
@@ -810,6 +814,31 @@ impl<Signer: Sign> Channel<Signer> {
                self.channel_transaction_parameters.opt_anchors.is_some()
        }
 
+       fn get_initial_channel_type(config: &UserConfig) -> ChannelTypeFeatures {
+               // The default channel type (ie the first one we try) depends on whether the channel is
+               // public - if it is, we just go with `only_static_remotekey` as it's the only option
+               // available. If it's private, we first try `scid_privacy` as it provides better privacy
+               // with no other changes, and fall back to `only_static_remotekey`
+               let mut ret = ChannelTypeFeatures::only_static_remote_key();
+               if !config.channel_options.announced_channel && config.own_channel_config.negotiate_scid_privacy {
+                       ret.set_scid_privacy_required();
+               }
+               ret
+       }
+
+       /// If we receive an error message, it may only be a rejection of the channel type we tried,
+       /// not of our ability to open any channel at all. Thus, on error, we should first call this
+       /// and see if we get a new `OpenChannel` message, otherwise the channel is failed.
+       pub(crate) fn maybe_handle_error_without_close(&mut self, chain_hash: BlockHash) -> Result<msgs::OpenChannel, ()> {
+               if !self.is_outbound() || self.channel_state != ChannelState::OurInitSent as u32 { return Err(()); }
+               if self.channel_type == ChannelTypeFeatures::only_static_remote_key() {
+                       // We've exhausted our options
+                       return Err(());
+               }
+               self.channel_type = ChannelTypeFeatures::only_static_remote_key(); // We only currently support two types
+               Ok(self.get_open_channel(chain_hash))
+       }
+
        // Constructors:
        pub fn new_outbound<K: Deref, F: Deref>(
                fee_estimator: &F, keys_provider: &K, counterparty_node_id: PublicKey, their_features: &InitFeatures,
@@ -825,8 +854,11 @@ impl<Signer: Sign> Channel<Signer> {
                let holder_signer = keys_provider.get_channel_signer(false, channel_value_satoshis);
                let pubkeys = holder_signer.pubkeys().clone();
 
-               if channel_value_satoshis >= MAX_FUNDING_SATOSHIS {
-                       return Err(APIError::APIMisuseError{err: format!("funding_value must be smaller than {}, it was {}", MAX_FUNDING_SATOSHIS, channel_value_satoshis)});
+               if !their_features.supports_wumbo() && channel_value_satoshis > MAX_FUNDING_SATOSHIS_NO_WUMBO {
+                       return Err(APIError::APIMisuseError{err: format!("funding_value must not exceed {}, it was {}", MAX_FUNDING_SATOSHIS_NO_WUMBO, channel_value_satoshis)});
+               }
+               if channel_value_satoshis >= TOTAL_BITCOIN_SUPPLY_SATOSHIS {
+                       return Err(APIError::APIMisuseError{err: format!("funding_value must be smaller than the total bitcoin supply, it was {}", channel_value_satoshis)});
                }
                let channel_value_msat = channel_value_satoshis * 1000;
                if push_msat > channel_value_msat {
@@ -967,10 +999,7 @@ impl<Signer: Sign> Channel<Signer> {
                        #[cfg(any(test, fuzzing))]
                        historical_inbound_htlc_fulfills: HashSet::new(),
 
-                       // We currently only actually support one channel type, so don't retry with new types
-                       // on error messages. When we support more we'll need fallback support (assuming we
-                       // want to support old types).
-                       channel_type: ChannelTypeFeatures::only_static_remote_key(),
+                       channel_type: Self::get_initial_channel_type(&config),
                })
        }
 
@@ -1009,6 +1038,7 @@ impl<Signer: Sign> Channel<Signer> {
                      L::Target: Logger,
        {
                let opt_anchors = false; // TODO - should be based on features
+               let announced_channel = if (msg.channel_flags & 1) == 1 { true } else { false };
 
                // First check the channel type is known, failing before we do anything else if we don't
                // support this channel type.
@@ -1016,8 +1046,18 @@ impl<Signer: Sign> Channel<Signer> {
                        if channel_type.supports_any_optional_bits() {
                                return Err(ChannelError::Close("Channel Type field contained optional bits - this is not allowed".to_owned()));
                        }
-                       if *channel_type != ChannelTypeFeatures::only_static_remote_key() {
-                               return Err(ChannelError::Close("Channel Type was not understood".to_owned()));
+                       // We currently only allow two channel types, so write it all out here - we allow
+                       // `only_static_remote_key` in all contexts, and further allow
+                       // `static_remote_key|scid_privacy` if the channel is not publicly announced.
+                       let mut allowed_type = ChannelTypeFeatures::only_static_remote_key();
+                       if *channel_type != allowed_type {
+                               allowed_type.set_scid_privacy_required();
+                               if *channel_type != allowed_type {
+                                       return Err(ChannelError::Close("Channel Type was not understood".to_owned()));
+                               }
+                               if announced_channel {
+                                       return Err(ChannelError::Close("SCID Alias/Privacy Channel Type cannot be set on a public channel".to_owned()));
+                               }
                        }
                        channel_type.clone()
                } else {
@@ -1043,8 +1083,11 @@ impl<Signer: Sign> Channel<Signer> {
                }
 
                // Check sanity of message fields:
-               if msg.funding_satoshis >= MAX_FUNDING_SATOSHIS {
-                       return Err(ChannelError::Close(format!("Funding must be smaller than {}. It was {}", MAX_FUNDING_SATOSHIS, msg.funding_satoshis)));
+               if msg.funding_satoshis > config.peer_channel_config_limits.max_funding_satoshis {
+                       return Err(ChannelError::Close(format!("Per our config, funding must be at most {}. It was {}", config.peer_channel_config_limits.max_funding_satoshis, msg.funding_satoshis)));
+               }
+               if msg.funding_satoshis >= TOTAL_BITCOIN_SUPPLY_SATOSHIS {
+                       return Err(ChannelError::Close(format!("Funding must be smaller than the total bitcoin supply. It was {}", msg.funding_satoshis)));
                }
                if msg.channel_reserve_satoshis > msg.funding_satoshis {
                        return Err(ChannelError::Close(format!("Bogus channel_reserve_satoshis ({}). Must be not greater than funding_satoshis: {}", msg.channel_reserve_satoshis, msg.funding_satoshis)));
@@ -1098,14 +1141,13 @@ impl<Signer: Sign> Channel<Signer> {
 
                // Convert things into internal flags and prep our state:
 
-               let announce = if (msg.channel_flags & 1) == 1 { true } else { false };
                if config.peer_channel_config_limits.force_announced_channel_preference {
-                       if local_config.announced_channel != announce {
+                       if local_config.announced_channel != announced_channel {
                                return Err(ChannelError::Close("Peer tried to open channel but their announcement preference is different from ours".to_owned()));
                        }
                }
                // we either accept their preference or the preferences match
-               local_config.announced_channel = announce;
+               local_config.announced_channel = announced_channel;
 
                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 {
@@ -4078,7 +4120,7 @@ impl<Signer: Sign> Channel<Signer> {
                if !self.pending_inbound_htlcs.is_empty() || !self.pending_outbound_htlcs.is_empty() {
                        return Err(ChannelError::Close("Remote end sent us a closing_signed while there were still pending HTLCs".to_owned()));
                }
-               if msg.fee_satoshis > 21_000_000 * 1_0000_0000 { //this is required to stop potential overflow in build_closing_transaction
+               if msg.fee_satoshis > TOTAL_BITCOIN_SUPPLY_SATOSHIS { // this is required to stop potential overflow in build_closing_transaction
                        return Err(ChannelError::Close("Remote tried to send us a closing tx with > 21 million BTC fee".to_owned()));
                }
 
@@ -4232,6 +4274,11 @@ impl<Signer: Sign> Channel<Signer> {
                self.user_id
        }
 
+       /// Gets the channel's type
+       pub fn get_channel_type(&self) -> &ChannelTypeFeatures {
+               &self.channel_type
+       }
+
        /// Guaranteed to be Some after both FundingLocked messages have been exchanged (and, thus,
        /// is_usable() returns true).
        /// Allowed in any state (including after shutdown)
@@ -6252,44 +6299,39 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
 
 #[cfg(test)]
 mod tests {
-       use bitcoin::util::bip143;
-       use bitcoin::consensus::encode::serialize;
        use bitcoin::blockdata::script::{Script, Builder};
-       use bitcoin::blockdata::transaction::{Transaction, TxOut, SigHashType};
+       use bitcoin::blockdata::transaction::{Transaction, TxOut};
        use bitcoin::blockdata::constants::genesis_block;
        use bitcoin::blockdata::opcodes;
        use bitcoin::network::constants::Network;
-       use bitcoin::hashes::hex::FromHex;
        use hex;
-       use ln::{PaymentPreimage, PaymentHash};
+       use ln::PaymentHash;
        use ln::channelmanager::{HTLCSource, PaymentId};
-       use ln::channel::{Channel,InboundHTLCOutput,OutboundHTLCOutput,InboundHTLCState,OutboundHTLCState,HTLCOutputInCommitment,HTLCCandidate,HTLCInitiator,TxCreationKeys};
-       use ln::channel::MAX_FUNDING_SATOSHIS;
+       use ln::channel::{Channel, InboundHTLCOutput, OutboundHTLCOutput, InboundHTLCState, OutboundHTLCState, HTLCCandidate, HTLCInitiator};
+       use ln::channel::{MAX_FUNDING_SATOSHIS_NO_WUMBO, TOTAL_BITCOIN_SUPPLY_SATOSHIS};
        use ln::features::InitFeatures;
        use ln::msgs::{ChannelUpdate, DataLossProtect, DecodeError, OptionalField, UnsignedChannelUpdate};
        use ln::script::ShutdownScript;
        use ln::chan_utils;
-       use ln::chan_utils::{ChannelPublicKeys, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters, htlc_success_tx_weight, htlc_timeout_tx_weight};
+       use ln::chan_utils::{htlc_success_tx_weight, htlc_timeout_tx_weight};
        use chain::BestBlock;
        use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
-       use chain::keysinterface::{InMemorySigner, Recipient, KeyMaterial, KeysInterface, BaseSign};
+       use chain::keysinterface::{InMemorySigner, Recipient, KeyMaterial, KeysInterface};
        use chain::transaction::OutPoint;
        use util::config::UserConfig;
        use util::enforcing_trait_impls::EnforcingSigner;
        use util::errors::APIError;
        use util::test_utils;
        use util::test_utils::OnGetShutdownScriptpubkey;
-       use util::logger::Logger;
-       use bitcoin::secp256k1::{Secp256k1, Message, Signature, All};
+       use bitcoin::secp256k1::{Secp256k1, Signature};
        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};
+       use bitcoin::hash_types::WPubkeyHash;
        use core::num::NonZeroU8;
        use bitcoin::bech32::u5;
-       use sync::Arc;
        use prelude::*;
 
        struct TestFeeEstimator {
@@ -6302,9 +6344,10 @@ mod tests {
        }
 
        #[test]
-       fn test_max_funding_satoshis() {
-               assert!(MAX_FUNDING_SATOSHIS <= 21_000_000 * 100_000_000,
-                       "MAX_FUNDING_SATOSHIS is greater than all satoshis in existence");
+       fn test_max_funding_satoshis_no_wumbo() {
+               assert_eq!(TOTAL_BITCOIN_SUPPLY_SATOSHIS, 21_000_000 * 100_000_000);
+               assert!(MAX_FUNDING_SATOSHIS_NO_WUMBO <= TOTAL_BITCOIN_SUPPLY_SATOSHIS,
+                       "MAX_FUNDING_SATOSHIS_NO_WUMBO is greater than all satoshis in existence");
        }
 
        #[test]
@@ -6343,7 +6386,8 @@ mod tests {
                fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result<RecoverableSignature, ()> { panic!(); }
        }
 
-       fn public_from_secret_hex(secp_ctx: &Secp256k1<All>, hex: &str) -> PublicKey {
+       #[cfg(not(feature = "grind_signatures"))]
+       fn public_from_secret_hex(secp_ctx: &Secp256k1<bitcoin::secp256k1::All>, hex: &str) -> PublicKey {
                PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&hex::decode(hex).unwrap()[..]).unwrap())
        }
 
@@ -6629,8 +6673,22 @@ mod tests {
                }
        }
 
+       #[cfg(not(feature = "grind_signatures"))]
        #[test]
        fn outbound_commitment_test() {
+               use bitcoin::util::bip143;
+               use bitcoin::consensus::encode::serialize;
+               use bitcoin::blockdata::transaction::SigHashType;
+               use bitcoin::hashes::hex::FromHex;
+               use bitcoin::hash_types::Txid;
+               use bitcoin::secp256k1::Message;
+               use chain::keysinterface::BaseSign;
+               use ln::PaymentPreimage;
+               use ln::channel::{HTLCOutputInCommitment ,TxCreationKeys};
+               use ln::chan_utils::{ChannelPublicKeys, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters};
+               use util::logger::Logger;
+               use sync::Arc;
+
                // Test vectors from BOLT 3 Appendices C and F (anchors):
                let feeest = TestFeeEstimator{fee_est: 15000};
                let logger : Arc<Logger> = Arc::new(test_utils::TestLogger::new());