X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannel.rs;h=76dc15065c05cd298b532247de377b757ce5491f;hb=1ded1d21bd9f31a39fd2f77e961a3559dd77ffc2;hp=f7ea1ba552bb2c5b4979d30d5b8390bff602a149;hpb=2390dbcb2236888f1a06f8b5666486eb54ace4b1;p=rust-lightning diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index f7ea1ba5..76dc1506 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -35,7 +35,7 @@ use crate::chain::BestBlock; use crate::chain::chaininterface::{FeeEstimator, ConfirmationTarget, LowerBoundedFeeEstimator}; use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, LATENCY_GRACE_PERIOD_BLOCKS}; use crate::chain::transaction::{OutPoint, TransactionData}; -use crate::chain::keysinterface::{Sign, KeysInterface, BaseSign}; +use crate::chain::keysinterface::{Sign, EntropySource, KeysInterface, BaseSign, SignerProvider}; use crate::util::events::ClosureReason; use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer, VecWriter}; use crate::util::logger::Logger; @@ -740,7 +740,7 @@ pub(super) struct Channel { channel_ready_event_emitted: bool, /// The unique identifier used to re-derive the private key material for the channel through - /// [`KeysInterface::derive_channel_signer`]. + /// [`SignerProvider::derive_channel_signer`]. channel_keys_id: [u8; 32], } @@ -1955,9 +1955,26 @@ impl Channel { /// an HTLC more than once or fulfill once and then attempt to fail after reconnect. We cannot, /// however, fail more than once as we wait for an upstream failure to be irrevocably committed /// before we fail backwards. - /// If we do fail twice, we debug_assert!(false) and return Ok(None). Thus, will always return - /// Ok(_) if debug assertions are turned on or preconditions are met. - pub fn get_update_fail_htlc(&mut self, htlc_id_arg: u64, err_packet: msgs::OnionErrorPacket, logger: &L) -> Result, ChannelError> where L::Target: Logger { + /// + /// If we do fail twice, we `debug_assert!(false)` and return `Ok(None)`. Thus, this will always + /// return `Ok(_)` if preconditions are met. In any case, `Err`s will only be + /// [`ChannelError::Ignore`]. + pub fn queue_fail_htlc(&mut self, htlc_id_arg: u64, err_packet: msgs::OnionErrorPacket, logger: &L) + -> Result<(), ChannelError> where L::Target: Logger { + self.fail_htlc(htlc_id_arg, err_packet, true, logger) + .map(|msg_opt| assert!(msg_opt.is_none(), "We forced holding cell?")) + } + + /// We can only have one resolution per HTLC. In some cases around reconnect, we may fulfill + /// an HTLC more than once or fulfill once and then attempt to fail after reconnect. We cannot, + /// however, fail more than once as we wait for an upstream failure to be irrevocably committed + /// before we fail backwards. + /// + /// If we do fail twice, we `debug_assert!(false)` and return `Ok(None)`. Thus, this will always + /// return `Ok(_)` if preconditions are met. In any case, `Err`s will only be + /// [`ChannelError::Ignore`]. + fn fail_htlc(&mut self, htlc_id_arg: u64, err_packet: msgs::OnionErrorPacket, mut force_holding_cell: bool, logger: &L) + -> Result, ChannelError> where L::Target: Logger { if (self.channel_state & (ChannelState::ChannelReady as u32)) != (ChannelState::ChannelReady as u32) { panic!("Was asked to fail an HTLC when channel was not in an operational state"); } @@ -1995,8 +2012,13 @@ impl Channel { return Ok(None); } - // Now update local state: if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateInProgress as u32)) != 0 { + debug_assert!(force_holding_cell, "!force_holding_cell is only called when emptying the holding cell, so we shouldn't end up back in it!"); + force_holding_cell = true; + } + + // Now update local state: + if force_holding_cell { for pending_update in self.holding_cell_htlc_updates.iter() { match pending_update { &HTLCUpdateAwaitingACK::ClaimHTLC { htlc_id, .. } => { @@ -2201,7 +2223,7 @@ impl Channel { pub fn funding_created( &mut self, msg: &msgs::FundingCreated, best_block: BestBlock, keys_source: &K, logger: &L - ) -> Result<(msgs::FundingSigned, ChannelMonitor<::Signer>, Option), ChannelError> + ) -> Result<(msgs::FundingSigned, ChannelMonitor<::Signer>, Option), ChannelError> where K::Target: KeysInterface, L::Target: Logger @@ -2289,7 +2311,7 @@ impl Channel { /// If this call is successful, broadcast the funding transaction (and not before!) pub fn funding_signed( &mut self, msg: &msgs::FundingSigned, best_block: BestBlock, keys_source: &K, logger: &L - ) -> Result<(ChannelMonitor<::Signer>, Transaction, Option), ChannelError> + ) -> Result<(ChannelMonitor<::Signer>, Transaction, Option), ChannelError> where K::Target: KeysInterface, L::Target: Logger @@ -3171,8 +3193,8 @@ impl Channel { } else { Ok((None, Vec::new())) } } - /// Used to fulfill holding_cell_htlcs when we get a remote ack (or implicitly get it by them - /// fulfilling or failing the last pending HTLC) + /// Frees any pending commitment updates in the holding cell, generating the relevant messages + /// for our counterparty. fn free_holding_cell_htlcs(&mut self, logger: &L) -> Result<(Option<(msgs::CommitmentUpdate, ChannelMonitorUpdate)>, Vec<(HTLCSource, PaymentHash)>), ChannelError> where L::Target: Logger { assert_eq!(self.channel_state & ChannelState::MonitorUpdateInProgress as u32, 0); if self.holding_cell_htlc_updates.len() != 0 || self.holding_cell_update_fee.is_some() { @@ -3198,7 +3220,7 @@ impl Channel { // to rebalance channels. match &htlc_update { &HTLCUpdateAwaitingACK::AddHTLC {amount_msat, cltv_expiry, ref payment_hash, ref source, ref onion_routing_packet, ..} => { - match self.send_htlc(amount_msat, *payment_hash, cltv_expiry, source.clone(), onion_routing_packet.clone(), logger) { + match self.send_htlc(amount_msat, *payment_hash, cltv_expiry, source.clone(), onion_routing_packet.clone(), false, logger) { Ok(update_add_msg_option) => update_add_htlcs.push(update_add_msg_option.unwrap()), Err(e) => { match e { @@ -3234,13 +3256,13 @@ impl Channel { monitor_update.updates.append(&mut additional_monitor_update.updates); }, &HTLCUpdateAwaitingACK::FailHTLC { htlc_id, ref err_packet } => { - match self.get_update_fail_htlc(htlc_id, err_packet.clone(), logger) { + match self.fail_htlc(htlc_id, err_packet.clone(), false, logger) { Ok(update_fail_msg_option) => { // If an HTLC failure was previously added to the holding cell (via - // `get_update_fail_htlc`) then generating the fail message itself - // must not fail - we should never end up in a state where we - // double-fail an HTLC or fail-then-claim an HTLC as it indicates - // we didn't wait for a full revocation before failing. + // `queue_fail_htlc`) then generating the fail message itself must + // not fail - we should never end up in a state where we double-fail + // an HTLC or fail-then-claim an HTLC as it indicates we didn't wait + // for a full revocation before failing. update_fail_htlcs.push(update_fail_msg_option.unwrap()) }, Err(e) => { @@ -3257,7 +3279,7 @@ impl Channel { return Ok((None, htlcs_to_fail)); } let update_fee = if let Some(feerate) = self.holding_cell_update_fee.take() { - self.send_update_fee(feerate, logger) + self.send_update_fee(feerate, false, logger) } else { None }; @@ -3557,12 +3579,22 @@ impl Channel { } } + /// Queues up an outbound update fee by placing it in the holding cell. You should call + /// [`Self::maybe_free_holding_cell_htlcs`] in order to actually generate and send the + /// commitment update. + pub fn queue_update_fee(&mut self, feerate_per_kw: u32, logger: &L) where L::Target: Logger { + let msg_opt = self.send_update_fee(feerate_per_kw, true, logger); + assert!(msg_opt.is_none(), "We forced holding cell?"); + } + /// Adds a pending update to this channel. See the doc for send_htlc for /// further details on the optionness of the return value. /// If our balance is too low to cover the cost of the next commitment transaction at the /// new feerate, the update is cancelled. - /// You MUST call send_commitment prior to any other calls on this Channel - fn send_update_fee(&mut self, feerate_per_kw: u32, logger: &L) -> Option where L::Target: Logger { + /// + /// You MUST call [`Self::send_commitment_no_state_update`] prior to any other calls on this + /// [`Channel`] if `force_holding_cell` is false. + fn send_update_fee(&mut self, feerate_per_kw: u32, mut force_holding_cell: bool, logger: &L) -> Option where L::Target: Logger { if !self.is_outbound() { panic!("Cannot send fee from inbound channel"); } @@ -3599,6 +3631,10 @@ impl Channel { } if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::MonitorUpdateInProgress as u32)) != 0 { + force_holding_cell = true; + } + + if force_holding_cell { self.holding_cell_update_fee = Some(feerate_per_kw); return None; } @@ -3612,16 +3648,6 @@ impl Channel { }) } - pub fn send_update_fee_and_commit(&mut self, feerate_per_kw: u32, logger: &L) -> Result, ChannelError> where L::Target: Logger { - match self.send_update_fee(feerate_per_kw, logger) { - Some(update_fee) => { - let (commitment_signed, monitor_update) = self.send_commitment_no_status_check(logger)?; - Ok(Some((update_fee, commitment_signed, monitor_update))) - }, - None => Ok(None) - } - } - /// Removes any uncommitted inbound HTLCs and resets the state of uncommitted outbound HTLC /// updates, to be used on peer disconnection. After this, update_*_htlc messages need to be /// resent. @@ -5495,8 +5521,26 @@ impl Channel { // Send stuff to our remote peers: + /// Queues up an outbound HTLC to send by placing it in the holding cell. You should call + /// [`Self::maybe_free_holding_cell_htlcs`] in order to actually generate and send the + /// commitment update. + /// + /// `Err`s will only be [`ChannelError::Ignore`]. + pub fn queue_add_htlc(&mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, + onion_routing_packet: msgs::OnionPacket, logger: &L) + -> Result<(), ChannelError> where L::Target: Logger { + self + .send_htlc(amount_msat, payment_hash, cltv_expiry, source, onion_routing_packet, true, logger) + .map(|msg_opt| assert!(msg_opt.is_none(), "We forced holding cell?")) + .map_err(|err| { + if let ChannelError::Ignore(_) = err { /* fine */ } + else { debug_assert!(false, "Queueing cannot trigger channel failure"); } + err + }) + } + /// Adds a pending outbound HTLC to this channel, note that you probably want - /// send_htlc_and_commit instead cause you'll want both messages at once. + /// [`Self::send_htlc_and_commit`] instead cause you'll want both messages at once. /// /// This returns an optional UpdateAddHTLC as we may be in a state where we cannot add HTLCs on /// the wire: @@ -5507,10 +5551,13 @@ impl Channel { /// we may not yet have sent the previous commitment update messages and will need to /// regenerate them. /// - /// You MUST call send_commitment prior to calling any other methods on this Channel! + /// You MUST call [`Self::send_commitment_no_state_update`] prior to calling any other methods + /// on this [`Channel`] if `force_holding_cell` is false. /// - /// If an Err is returned, it's a ChannelError::Ignore! - pub fn send_htlc(&mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, onion_routing_packet: msgs::OnionPacket, logger: &L) -> Result, ChannelError> where L::Target: Logger { + /// `Err`s will only be [`ChannelError::Ignore`]. + fn send_htlc(&mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, + onion_routing_packet: msgs::OnionPacket, mut force_holding_cell: bool, logger: &L) + -> Result, ChannelError> where L::Target: Logger { if (self.channel_state & (ChannelState::ChannelReady as u32 | BOTH_SIDES_SHUTDOWN_MASK)) != (ChannelState::ChannelReady as u32) { return Err(ChannelError::Ignore("Cannot send HTLC until channel is fully established and we haven't started shutting down".to_owned())); } @@ -5605,8 +5652,12 @@ impl Channel { return Err(ChannelError::Ignore(format!("Cannot send value that would put our balance under counterparty-announced channel reserve value ({})", chan_reserve_msat))); } - // Now update local state: if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::MonitorUpdateInProgress as u32)) != 0 { + force_holding_cell = true; + } + + // Now update local state: + if force_holding_cell { self.holding_cell_htlc_updates.push(HTLCUpdateAwaitingACK::AddHTLC { amount_msat, payment_hash, @@ -5639,41 +5690,6 @@ impl Channel { Ok(Some(res)) } - /// Creates a signed commitment transaction to send to the remote peer. - /// Always returns a ChannelError::Close if an immediately-preceding (read: the - /// last call to this Channel) send_htlc returned Ok(Some(_)) and there is an Err. - /// May panic if called except immediately after a successful, Ok(Some(_))-returning send_htlc. - pub fn send_commitment(&mut self, logger: &L) -> Result<(msgs::CommitmentSigned, ChannelMonitorUpdate), ChannelError> where L::Target: Logger { - if (self.channel_state & (ChannelState::ChannelReady as u32)) != (ChannelState::ChannelReady as u32) { - panic!("Cannot create commitment tx until channel is fully established"); - } - if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) == (ChannelState::AwaitingRemoteRevoke as u32) { - panic!("Cannot create commitment tx until remote revokes their previous commitment"); - } - if (self.channel_state & (ChannelState::PeerDisconnected as u32)) == (ChannelState::PeerDisconnected as u32) { - panic!("Cannot create commitment tx while disconnected, as send_htlc will have returned an Err so a send_commitment precondition has been violated"); - } - if (self.channel_state & (ChannelState::MonitorUpdateInProgress as u32)) == (ChannelState::MonitorUpdateInProgress as u32) { - panic!("Cannot create commitment tx while awaiting monitor update unfreeze, as send_htlc will have returned an Err so a send_commitment precondition has been violated"); - } - let mut have_updates = self.is_outbound() && self.pending_update_fee.is_some(); - for htlc in self.pending_outbound_htlcs.iter() { - if let OutboundHTLCState::LocalAnnounced(_) = htlc.state { - have_updates = true; - } - if have_updates { break; } - } - for htlc in self.pending_inbound_htlcs.iter() { - if let InboundHTLCState::LocalRemoved(_) = htlc.state { - have_updates = true; - } - if have_updates { break; } - } - if !have_updates { - panic!("Cannot create commitment tx until we have some updates to send"); - } - self.send_commitment_no_status_check(logger) - } /// Only fails in case of bad keys fn send_commitment_no_status_check(&mut self, logger: &L) -> Result<(msgs::CommitmentSigned, ChannelMonitorUpdate), ChannelError> where L::Target: Logger { log_trace!(logger, "Updating HTLC state for a newly-sent commitment_signed..."); @@ -5796,10 +5812,11 @@ impl Channel { /// Adds a pending outbound HTLC to this channel, and creates a signed commitment transaction /// to send to the remote peer in one go. - /// Shorthand for calling send_htlc() followed by send_commitment(), see docs on those for - /// more info. + /// + /// Shorthand for calling [`Self::send_htlc`] followed by a commitment update, see docs on + /// [`Self::send_htlc`] and [`Self::send_commitment_no_state_update`] for more info. pub fn send_htlc_and_commit(&mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, onion_routing_packet: msgs::OnionPacket, logger: &L) -> Result, ChannelError> where L::Target: Logger { - match self.send_htlc(amount_msat, payment_hash, cltv_expiry, source, onion_routing_packet, logger)? { + match self.send_htlc(amount_msat, payment_hash, cltv_expiry, source, onion_routing_packet, false, logger)? { Some(update_add_htlc) => { let (commitment_signed, monitor_update) = self.send_commitment_no_status_check(logger)?; Ok(Some((update_add_htlc, commitment_signed, monitor_update))) @@ -6312,7 +6329,7 @@ impl Writeable for Channel { } const MAX_ALLOC_SIZE: usize = 64*1024; -impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<::Signer> +impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<::Signer> where K::Target: KeysInterface { fn read(reader: &mut R, args: (&'a K, u32)) -> Result { let (keys_source, serialized_height) = args; @@ -6785,7 +6802,7 @@ mod tests { use crate::ln::chan_utils::{htlc_success_tx_weight, htlc_timeout_tx_weight}; use crate::chain::BestBlock; use crate::chain::chaininterface::{FeeEstimator, LowerBoundedFeeEstimator, ConfirmationTarget}; - use crate::chain::keysinterface::{BaseSign, InMemorySigner, Recipient, KeyMaterial, KeysInterface}; + use crate::chain::keysinterface::{BaseSign, InMemorySigner, Recipient, KeyMaterial, KeysInterface, EntropySource, NodeSigner, SignerProvider}; use crate::chain::transaction::OutPoint; use crate::util::config::UserConfig; use crate::util::enforcing_trait_impls::EnforcingSigner; @@ -6834,12 +6851,39 @@ mod tests { struct Keys { signer: InMemorySigner, } - impl KeysInterface for Keys { - type Signer = InMemorySigner; + impl EntropySource for Keys { + fn get_secure_random_bytes(&self) -> [u8; 32] { [0; 32] } + } + + impl NodeSigner for Keys { fn get_node_secret(&self, _recipient: Recipient) -> Result { panic!(); } + + fn get_node_id(&self, recipient: Recipient) -> Result { + let secp_ctx = Secp256k1::signing_only(); + Ok(PublicKey::from_secret_key(&secp_ctx, &self.get_node_secret(recipient)?)) + } + fn ecdh(&self, _recipient: Recipient, _other_key: &PublicKey, _tweak: Option<&Scalar>) -> Result { panic!(); } + fn get_inbound_payment_key_material(&self) -> KeyMaterial { panic!(); } + + fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result { panic!(); } + } + + impl SignerProvider for Keys { + type Signer = InMemorySigner; + + fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32] { + self.signer.channel_keys_id() + } + + fn derive_channel_signer(&self, _channel_value_satoshis: u64, _channel_keys_id: [u8; 32]) -> Self::Signer { + self.signer.clone() + } + + fn read_chan_signer(&self, _data: &[u8]) -> Result { panic!(); } + fn get_destination_script(&self) -> Script { let secp_ctx = Secp256k1::signing_only(); let channel_monitor_claim_key = SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(); @@ -6852,18 +6896,10 @@ mod tests { let channel_close_key = SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(); ShutdownScript::new_p2wpkh_from_pubkey(PublicKey::from_secret_key(&secp_ctx, &channel_close_key)) } - - fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32] { - self.signer.channel_keys_id() - } - fn derive_channel_signer(&self, _channel_value_satoshis: u64, _channel_keys_id: [u8; 32]) -> Self::Signer { - self.signer.clone() - } - fn get_secure_random_bytes(&self) -> [u8; 32] { [0; 32] } - fn read_chan_signer(&self, _data: &[u8]) -> Result { panic!(); } - fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result { panic!(); } } + impl KeysInterface for Keys {} + #[cfg(not(feature = "grind_signatures"))] fn public_from_secret_hex(secp_ctx: &Secp256k1, hex: &str) -> PublicKey { PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&hex::decode(hex).unwrap()[..]).unwrap())