X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannel.rs;h=e0f7a1ae7c2bae2aee35c5f8310389729a3be0cb;hb=a4822e5b27b7bffbae2e5337709c75f7c18dc800;hp=c2e158627ad03c9a2a3333f78c28de9c1e29bb87;hpb=0d5050833d99728f0cf4799f7fbb2f2108b1ed93;p=rust-lightning diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index c2e15862..e0f7a1ae 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -23,7 +23,7 @@ use bitcoin::secp256k1::{Secp256k1,Signature}; use bitcoin::secp256k1; use ln::{PaymentPreimage, PaymentHash}; -use ln::features::{ChannelFeatures, InitFeatures}; +use ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures}; use ln::msgs; use ln::msgs::{DecodeError, OptionalField, DataLossProtect}; use ln::script::{self, ShutdownScript}; @@ -32,9 +32,10 @@ use ln::chan_utils::{CounterpartyCommitmentSecrets, TxCreationKeys, HTLCOutputIn use ln::chan_utils; use chain::BestBlock; use chain::chaininterface::{FeeEstimator,ConfirmationTarget}; -use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, HTLC_FAIL_BACK_BUFFER}; +use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, LATENCY_GRACE_PERIOD_BLOCKS}; use chain::transaction::{OutPoint, TransactionData}; use chain::keysinterface::{Sign, KeysInterface}; +use util::events::ClosureReason; use util::ser::{Readable, ReadableArgs, Writeable, Writer, VecWriter}; use util::logger::Logger; use util::errors::APIError; @@ -378,6 +379,11 @@ pub const FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE: u64 = 2; #[cfg(not(fuzzing))] const FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE: u64 = 2; +/// If we fail to see a funding transaction confirmed on-chain within this many blocks after the +/// channel creation on an inbound channel, we simply force-close and move on. +/// This constant is the one suggested in BOLT 2. +pub(crate) const FUNDING_CONF_DEADLINE_BLOCKS: u32 = 2016; + // 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 @@ -475,6 +481,10 @@ pub(super) struct Channel { funding_tx_confirmed_in: Option, funding_tx_confirmation_height: u32, short_channel_id: Option, + /// Either the height at which this channel was created or the height at which it was last + /// serialized if it was serialized by versions prior to 0.0.103. + /// We use this to close if funding is never broadcasted. + channel_creation_height: u32, counterparty_dust_limit_satoshis: u64, #[cfg(test)] @@ -550,6 +560,9 @@ pub(super) struct Channel { // is fine, but as a sanity check in our failure to generate the second claim, we check here // that the original was a claim, and that we aren't now trying to fulfill a failed HTLC. historical_inbound_htlc_fulfills: HashSet, + + /// This channel's type, as negotiated during channel open + channel_type: ChannelTypeFeatures, } #[cfg(any(test, feature = "fuzztarget"))] @@ -643,7 +656,10 @@ impl Channel { } // Constructors: - pub fn new_outbound(fee_estimator: &F, keys_provider: &K, counterparty_node_id: PublicKey, their_features: &InitFeatures, channel_value_satoshis: u64, push_msat: u64, user_id: u64, config: &UserConfig) -> Result, APIError> + pub fn new_outbound( + fee_estimator: &F, keys_provider: &K, counterparty_node_id: PublicKey, their_features: &InitFeatures, + channel_value_satoshis: u64, push_msat: u64, user_id: u64, config: &UserConfig, current_chain_height: u32 + ) -> Result, APIError> where K::Target: KeysInterface, F::Target: FeeEstimator, { @@ -731,6 +747,7 @@ impl Channel { funding_tx_confirmed_in: None, funding_tx_confirmation_height: 0, short_channel_id: None, + channel_creation_height: current_chain_height, feerate_per_kw: feerate, counterparty_dust_limit_satoshis: 0, @@ -775,6 +792,11 @@ impl Channel { #[cfg(any(test, feature = "fuzztarget"))] 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(), }) } @@ -799,10 +821,30 @@ impl Channel { /// Creates a new channel from a remote sides' request for one. /// Assumes chain_hash has already been checked and corresponds with what we expect! - pub fn new_from_req(fee_estimator: &F, keys_provider: &K, counterparty_node_id: PublicKey, their_features: &InitFeatures, msg: &msgs::OpenChannel, user_id: u64, config: &UserConfig) -> Result, ChannelError> + pub fn new_from_req( + fee_estimator: &F, keys_provider: &K, counterparty_node_id: PublicKey, their_features: &InitFeatures, + msg: &msgs::OpenChannel, user_id: u64, config: &UserConfig, current_chain_height: u32 + ) -> Result, ChannelError> where K::Target: KeysInterface, F::Target: FeeEstimator { + // First check the channel type is known, failing before we do anything else if we don't + // support this channel type. + let channel_type = if let Some(channel_type) = &msg.channel_type { + 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())); + } + channel_type.clone() + } else { + ChannelTypeFeatures::from_counterparty_init(&their_features) + }; + if !channel_type.supports_static_remote_key() { + return Err(ChannelError::Close("Channel Type was not understood - we require static remote key".to_owned())); + } + let holder_signer = keys_provider.get_channel_signer(true, msg.funding_satoshis); let pubkeys = holder_signer.pubkeys().clone(); let counterparty_pubkeys = ChannelPublicKeys { @@ -995,6 +1037,7 @@ impl Channel { funding_tx_confirmed_in: None, funding_tx_confirmation_height: 0, short_channel_id: None, + channel_creation_height: current_chain_height, feerate_per_kw: msg.feerate_per_kw, channel_value_satoshis: msg.funding_satoshis, @@ -1043,6 +1086,8 @@ impl Channel { #[cfg(any(test, feature = "fuzztarget"))] historical_inbound_htlc_fulfills: HashSet::new(), + + channel_type, }; Ok(chan) @@ -4090,7 +4135,7 @@ impl Channel { /// In the first case, we store the confirmation height and calculating the short channel id. /// In the second, we simply return an Err indicating we need to be force-closed now. pub fn transactions_confirmed(&mut self, block_hash: &BlockHash, height: u32, txdata: &TransactionData, logger: &L) - -> Result, msgs::ErrorMessage> where L::Target: Logger { + -> Result, ClosureReason> where L::Target: Logger { let non_shutdown_state = self.channel_state & (!MULTI_STATE_FLAGS); for &(index_in_block, tx) in txdata.iter() { if let Some(funding_txo) = self.get_funding_txo() { @@ -4111,10 +4156,8 @@ impl Channel { panic!("Client called ChannelManager::funding_transaction_generated with bogus transaction!"); } self.update_time_counter += 1; - return Err(msgs::ErrorMessage { - channel_id: self.channel_id(), - data: "funding tx had wrong script/value or output index".to_owned() - }); + let err_reason = "funding tx had wrong script/value or output index"; + return Err(ClosureReason::ProcessingError { err: err_reason.to_owned() }); } else { if self.is_outbound() { for input in tx.input.iter() { @@ -4145,10 +4188,7 @@ impl Channel { for inp in tx.input.iter() { if inp.previous_output == funding_txo.into_bitcoin_outpoint() { log_info!(logger, "Detected channel-closing tx {} spending {}:{}, closing channel {}", tx.txid(), inp.previous_output.txid, inp.previous_output.vout, log_bytes!(self.channel_id())); - return Err(msgs::ErrorMessage { - channel_id: self.channel_id(), - data: "Commitment or closing transaction was confirmed on chain.".to_owned() - }); + return Err(ClosureReason::CommitmentTxConfirmed); } } } @@ -4168,9 +4208,12 @@ impl Channel { /// May return some HTLCs (and their payment_hash) which have timed out and should be failed /// back. pub fn best_block_updated(&mut self, height: u32, highest_header_time: u32, logger: &L) - -> Result<(Option, Vec<(HTLCSource, PaymentHash)>), msgs::ErrorMessage> where L::Target: Logger { + -> Result<(Option, Vec<(HTLCSource, PaymentHash)>), ClosureReason> where L::Target: Logger { let mut timed_out_htlcs = Vec::new(); - let unforwarded_htlc_cltv_limit = height + HTLC_FAIL_BACK_BUFFER; + // This mirrors the check in ChannelManager::decode_update_add_htlc_onion, refusing to + // forward an HTLC when our counterparty should almost certainly just fail it for expiring + // ~now. + let unforwarded_htlc_cltv_limit = height + LATENCY_GRACE_PERIOD_BLOCKS; self.holding_cell_htlc_updates.retain(|htlc_update| { match htlc_update { &HTLCUpdateAwaitingACK::AddHTLC { ref payment_hash, ref source, ref cltv_expiry, .. } => { @@ -4206,11 +4249,17 @@ impl Channel { // close the channel and hope we can get the latest state on chain (because presumably // the funding transaction is at least still in the mempool of most nodes). if funding_tx_confirmations < self.minimum_depth.unwrap() as i64 / 2 { - return Err(msgs::ErrorMessage { - channel_id: self.channel_id(), - data: format!("Funding transaction was un-confirmed. Locked at {} confs, now have {} confs.", self.minimum_depth.unwrap(), funding_tx_confirmations), - }); + let err_reason = format!("Funding transaction was un-confirmed. Locked at {} confs, now have {} confs.", + self.minimum_depth.unwrap(), funding_tx_confirmations); + return Err(ClosureReason::ProcessingError { err: err_reason }); } + } else if !self.is_outbound() && self.funding_tx_confirmed_in.is_none() && + height >= self.channel_creation_height + FUNDING_CONF_DEADLINE_BLOCKS { + log_info!(logger, "Closing channel {} due to funding timeout", log_bytes!(self.channel_id)); + // If funding_tx_confirmed_in is unset, the channel must not be active + assert!(non_shutdown_state <= ChannelState::ChannelFunded as u32); + assert_eq!(non_shutdown_state & ChannelState::OurFundingLocked as u32, 0); + return Err(ClosureReason::FundingTimedOut); } Ok((None, timed_out_htlcs)) @@ -4219,7 +4268,7 @@ impl Channel { /// Indicates the funding transaction is no longer confirmed in the main chain. This may /// force-close the channel, but may also indicate a harmless reorganization of a block or two /// before the channel has reached funding_locked and we can just wait for more blocks. - pub fn funding_transaction_unconfirmed(&mut self, logger: &L) -> Result<(), msgs::ErrorMessage> where L::Target: Logger { + pub fn funding_transaction_unconfirmed(&mut self, logger: &L) -> Result<(), ClosureReason> where L::Target: Logger { if self.funding_tx_confirmation_height != 0 { // 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. @@ -4283,6 +4332,7 @@ impl Channel { Some(script) => script.clone().into_inner(), None => Builder::new().into_script(), }), + channel_type: Some(self.channel_type.clone()), } } @@ -5226,6 +5276,13 @@ impl Writeable for Channel { htlc.write(writer)?; } + // If the channel type is something other than only-static-remote-key, then we need to have + // older clients fail to deserialize this channel at all. If the type is + // only-static-remote-key, we simply consider it "default" and don't write the channel type + // out at all. + let chan_type = if self.channel_type != ChannelTypeFeatures::only_static_remote_key() { + Some(&self.channel_type) } else { None }; + write_tlv_fields!(writer, { (0, self.announcement_sigs, option), // minimum_depth and counterparty_selected_channel_reserve_satoshis used to have a @@ -5235,11 +5292,13 @@ impl Writeable for Channel { // and new versions map the default values to None and allow the TLV entries here to // override that. (1, self.minimum_depth, option), + (2, chan_type, option), (3, self.counterparty_selected_channel_reserve_satoshis, option), (5, self.config, required), (7, self.shutdown_scriptpubkey, option), (9, self.target_closing_feerate_sats_per_kw, option), (11, self.monitor_pending_finalized_fulfills, vec_type), + (13, self.channel_creation_height, required), }); Ok(()) @@ -5247,9 +5306,10 @@ impl Writeable for Channel { } const MAX_ALLOC_SIZE: usize = 64*1024; -impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel +impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel where K::Target: KeysInterface { - fn read(reader: &mut R, keys_source: &'a K) -> Result { + fn read(reader: &mut R, args: (&'a K, u32)) -> Result { + let (keys_source, serialized_height) = args; let ver = read_ver_prefix!(reader, SERIALIZATION_VERSION); let user_id = Readable::read(reader)?; @@ -5474,16 +5534,29 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel let mut announcement_sigs = None; let mut target_closing_feerate_sats_per_kw = None; let mut monitor_pending_finalized_fulfills = Some(Vec::new()); + // Prior to supporting channel type negotiation, all of our channels were static_remotekey + // only, so we default to that if none was written. + let mut channel_type = Some(ChannelTypeFeatures::only_static_remote_key()); + let mut channel_creation_height = Some(serialized_height); read_tlv_fields!(reader, { (0, announcement_sigs, option), (1, minimum_depth, option), + (2, channel_type, option), (3, counterparty_selected_channel_reserve_satoshis, option), (5, config, option), // Note that if none is provided we will *not* overwrite the existing one. (7, shutdown_scriptpubkey, option), (9, target_closing_feerate_sats_per_kw, option), (11, monitor_pending_finalized_fulfills, vec_type), + (13, channel_creation_height, option), }); + let chan_features = channel_type.as_ref().unwrap(); + if chan_features.supports_unknown_bits() || chan_features.requires_unknown_bits() { + // If the channel was written by a new version and negotiated with features we don't + // understand yet, refuse to read it. + return Err(DecodeError::UnknownRequiredFeature); + } + let mut secp_ctx = Secp256k1::new(); secp_ctx.seeded_randomize(&keys_source.get_secure_random_bytes()); @@ -5539,6 +5612,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel funding_tx_confirmed_in, funding_tx_confirmation_height, short_channel_id, + channel_creation_height: channel_creation_height.unwrap(), counterparty_dust_limit_satoshis, holder_dust_limit_satoshis, @@ -5576,6 +5650,8 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel #[cfg(any(test, feature = "fuzztarget"))] historical_inbound_htlc_fulfills, + + channel_type: channel_type.unwrap(), }) } } @@ -5685,7 +5761,7 @@ mod tests { let secp_ctx = Secp256k1::new(); let node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); let config = UserConfig::default(); - match Channel::::new_outbound(&&fee_estimator, &&keys_provider, node_id, &features, 10000000, 100000, 42, &config) { + match Channel::::new_outbound(&&fee_estimator, &&keys_provider, node_id, &features, 10000000, 100000, 42, &config, 0) { Err(APIError::IncompatibleShutdownScript { script }) => { assert_eq!(script.into_inner(), non_v0_segwit_shutdown_script.into_inner()); }, @@ -5707,7 +5783,7 @@ mod tests { let node_a_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); let config = UserConfig::default(); - let node_a_chan = Channel::::new_outbound(&&fee_est, &&keys_provider, node_a_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config).unwrap(); + let node_a_chan = Channel::::new_outbound(&&fee_est, &&keys_provider, node_a_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap(); // Now change the fee so we can check that the fee in the open_channel message is the // same as the old fee. @@ -5732,13 +5808,13 @@ mod tests { // Create Node A's channel pointing to Node B's pubkey let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); let config = UserConfig::default(); - let mut node_a_chan = Channel::::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config).unwrap(); + let mut node_a_chan = Channel::::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap(); // 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()); let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap()); - let node_b_chan = Channel::::new_from_req(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), &open_channel_msg, 7, &config).unwrap(); + let node_b_chan = Channel::::new_from_req(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), &open_channel_msg, 7, &config, 0).unwrap(); // Node B --> Node A: accept channel, explicitly setting B's dust limit. let mut accept_channel_msg = node_b_chan.get_accept_channel(); @@ -5768,6 +5844,7 @@ mod tests { first_hop_htlc_msat: 548, payment_id: PaymentId([42; 32]), payment_secret: None, + payee: None, } }); @@ -5801,7 +5878,7 @@ mod tests { let node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); let config = UserConfig::default(); - let mut chan = Channel::::new_outbound(&&fee_est, &&keys_provider, node_id, &InitFeatures::known(), 10000000, 100000, 42, &config).unwrap(); + let mut chan = Channel::::new_outbound(&&fee_est, &&keys_provider, node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap(); let commitment_tx_fee_0_htlcs = chan.commit_tx_fee_msat(0); let commitment_tx_fee_1_htlc = chan.commit_tx_fee_msat(1); @@ -5850,12 +5927,12 @@ mod tests { // Create Node A's channel pointing to Node B's pubkey let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); let config = UserConfig::default(); - let mut node_a_chan = Channel::::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config).unwrap(); + let mut node_a_chan = Channel::::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap(); // Create Node B's channel by receiving Node A's open_channel message let open_channel_msg = node_a_chan.get_open_channel(chain_hash); let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap()); - let mut node_b_chan = Channel::::new_from_req(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), &open_channel_msg, 7, &config).unwrap(); + let mut node_b_chan = Channel::::new_from_req(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), &open_channel_msg, 7, &config, 0).unwrap(); // Node B --> Node A: accept channel let accept_channel_msg = node_b_chan.get_accept_channel(); @@ -5912,7 +5989,7 @@ mod tests { // Create a channel. let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); let config = UserConfig::default(); - let mut node_a_chan = Channel::::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config).unwrap(); + let mut node_a_chan = Channel::::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap(); assert!(node_a_chan.counterparty_forwarding_info.is_none()); assert_eq!(node_a_chan.holder_htlc_minimum_msat, 1); // the default assert!(node_a_chan.counterparty_forwarding_info().is_none()); @@ -5976,7 +6053,7 @@ mod tests { let counterparty_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); let mut config = UserConfig::default(); config.channel_options.announced_channel = false; - let mut chan = Channel::::new_outbound(&&feeest, &&keys_provider, counterparty_node_id, &InitFeatures::known(), 10_000_000, 100000, 42, &config).unwrap(); // Nothing uses their network key in this test + let mut chan = Channel::::new_outbound(&&feeest, &&keys_provider, counterparty_node_id, &InitFeatures::known(), 10_000_000, 100000, 42, &config, 0).unwrap(); // Nothing uses their network key in this test chan.holder_dust_limit_satoshis = 546; chan.counterparty_selected_channel_reserve_satoshis = Some(0); // Filled in in accept_channel