X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;ds=sidebyside;f=lightning%2Fsrc%2Fln%2Fchannel.rs;h=388ef6a8b306f07500eff3d6eece76eebfe79dab;hb=15b1c9b83715ed98fa8c538195d13d44967031fb;hp=e74dbe42a77d52d0ad65a5e4d179fb68f543ec29;hpb=ba342de241f0b5e968d6ad0106e5690e7c9c68bc;p=rust-lightning diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index e74dbe42..388ef6a8 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -224,6 +224,7 @@ struct OutboundHTLCOutput { payment_hash: PaymentHash, state: OutboundHTLCState, source: HTLCSource, + skimmed_fee_msat: Option, } /// See AwaitingRemoteRevoke ChannelState for more info @@ -235,6 +236,8 @@ enum HTLCUpdateAwaitingACK { payment_hash: PaymentHash, source: HTLCSource, onion_routing_packet: msgs::OnionPacket, + // The extra fee we're skimming off the top of this HTLC. + skimmed_fee_msat: Option, }, ClaimHTLC { payment_preimage: PaymentPreimage, @@ -3052,8 +3055,13 @@ impl Channel { // handling this case better and maybe fulfilling some of the HTLCs while attempting // 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(), false, logger) { + &HTLCUpdateAwaitingACK::AddHTLC { + amount_msat, cltv_expiry, ref payment_hash, ref source, ref onion_routing_packet, + skimmed_fee_msat, .. + } => { + match self.send_htlc(amount_msat, *payment_hash, cltv_expiry, source.clone(), + onion_routing_packet.clone(), false, skimmed_fee_msat, logger) + { Ok(update_add_msg_option) => update_add_htlcs.push(update_add_msg_option.unwrap()), Err(e) => { match e { @@ -3695,6 +3703,7 @@ impl Channel { payment_hash: htlc.payment_hash, cltv_expiry: htlc.cltv_expiry, onion_routing_packet: (**onion_packet).clone(), + skimmed_fee_msat: htlc.skimmed_fee_msat, }); } } @@ -5042,11 +5051,13 @@ impl Channel { /// 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 { + pub fn queue_add_htlc( + &mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, + onion_routing_packet: msgs::OnionPacket, skimmed_fee_msat: Option, logger: &L + ) -> Result<(), ChannelError> where L::Target: Logger { self - .send_htlc(amount_msat, payment_hash, cltv_expiry, source, onion_routing_packet, true, logger) + .send_htlc(amount_msat, payment_hash, cltv_expiry, source, onion_routing_packet, true, + skimmed_fee_msat, logger) .map(|msg_opt| assert!(msg_opt.is_none(), "We forced holding cell?")) .map_err(|err| { if let ChannelError::Ignore(_) = err { /* fine */ } @@ -5071,9 +5082,11 @@ impl Channel { /// on this [`Channel`] if `force_holding_cell` is false. /// /// `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 { + 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, + skimmed_fee_msat: Option, logger: &L + ) -> Result, ChannelError> where L::Target: Logger { if (self.context.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())); } @@ -5125,6 +5138,7 @@ impl Channel { cltv_expiry, source, onion_routing_packet, + skimmed_fee_msat, }); return Ok(None); } @@ -5136,6 +5150,7 @@ impl Channel { cltv_expiry, state: OutboundHTLCState::LocalAnnounced(Box::new(onion_routing_packet.clone())), source, + skimmed_fee_msat, }); let res = msgs::UpdateAddHTLC { @@ -5145,6 +5160,7 @@ impl Channel { payment_hash, cltv_expiry, onion_routing_packet, + skimmed_fee_msat, }; self.context.next_holder_htlc_id += 1; @@ -5283,8 +5299,12 @@ impl Channel { /// /// Shorthand for calling [`Self::send_htlc`] followed by a commitment update, see docs on /// [`Self::send_htlc`] and [`Self::build_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 { - let send_res = self.send_htlc(amount_msat, payment_hash, cltv_expiry, source, onion_routing_packet, false, logger); + pub fn send_htlc_and_commit( + &mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, + onion_routing_packet: msgs::OnionPacket, skimmed_fee_msat: Option, logger: &L + ) -> Result, ChannelError> where L::Target: Logger { + let send_res = self.send_htlc(amount_msat, payment_hash, cltv_expiry, source, + onion_routing_packet, false, skimmed_fee_msat, logger); if let Err(e) = &send_res { if let ChannelError::Ignore(_) = e {} else { debug_assert!(false, "Sending cannot trigger channel failure"); } } match send_res? { Some(_) => { @@ -6609,9 +6629,10 @@ impl Writeable for Channel { } let mut preimages: Vec<&Option> = vec![]; + let mut pending_outbound_skimmed_fees: Vec> = Vec::new(); (self.context.pending_outbound_htlcs.len() as u64).write(writer)?; - for htlc in self.context.pending_outbound_htlcs.iter() { + for (idx, htlc) in self.context.pending_outbound_htlcs.iter().enumerate() { htlc.htlc_id.write(writer)?; htlc.amount_msat.write(writer)?; htlc.cltv_expiry.write(writer)?; @@ -6647,18 +6668,37 @@ impl Writeable for Channel { reason.write(writer)?; } } + if let Some(skimmed_fee) = htlc.skimmed_fee_msat { + if pending_outbound_skimmed_fees.is_empty() { + for _ in 0..idx { pending_outbound_skimmed_fees.push(None); } + } + pending_outbound_skimmed_fees.push(Some(skimmed_fee)); + } else if !pending_outbound_skimmed_fees.is_empty() { + pending_outbound_skimmed_fees.push(None); + } } + let mut holding_cell_skimmed_fees: Vec> = Vec::new(); (self.context.holding_cell_htlc_updates.len() as u64).write(writer)?; - for update in self.context.holding_cell_htlc_updates.iter() { + for (idx, update) in self.context.holding_cell_htlc_updates.iter().enumerate() { match update { - &HTLCUpdateAwaitingACK::AddHTLC { ref amount_msat, ref cltv_expiry, ref payment_hash, ref source, ref onion_routing_packet } => { + &HTLCUpdateAwaitingACK::AddHTLC { + ref amount_msat, ref cltv_expiry, ref payment_hash, ref source, ref onion_routing_packet, + skimmed_fee_msat, + } => { 0u8.write(writer)?; amount_msat.write(writer)?; cltv_expiry.write(writer)?; payment_hash.write(writer)?; source.write(writer)?; onion_routing_packet.write(writer)?; + + if let Some(skimmed_fee) = skimmed_fee_msat { + if holding_cell_skimmed_fees.is_empty() { + for _ in 0..idx { holding_cell_skimmed_fees.push(None); } + } + holding_cell_skimmed_fees.push(Some(skimmed_fee)); + } else if !holding_cell_skimmed_fees.is_empty() { holding_cell_skimmed_fees.push(None); } }, &HTLCUpdateAwaitingACK::ClaimHTLC { ref payment_preimage, ref htlc_id } => { 1u8.write(writer)?; @@ -6825,6 +6865,8 @@ impl Writeable for Channel { (29, self.context.temporary_channel_id, option), (31, channel_pending_event_emitted, option), (33, self.context.pending_monitor_updates, vec_type), + (35, pending_outbound_skimmed_fees, optional_vec), + (37, holding_cell_skimmed_fees, optional_vec), }); Ok(()) @@ -6935,6 +6977,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch }, _ => return Err(DecodeError::InvalidValue), }, + skimmed_fee_msat: None, }); } @@ -6948,6 +6991,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch payment_hash: Readable::read(reader)?, source: Readable::read(reader)?, onion_routing_packet: Readable::read(reader)?, + skimmed_fee_msat: None, }, 1 => HTLCUpdateAwaitingACK::ClaimHTLC { payment_preimage: Readable::read(reader)?, @@ -7103,6 +7147,9 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch let mut pending_monitor_updates = Some(Vec::new()); + let mut pending_outbound_skimmed_fees_opt: Option>> = None; + let mut holding_cell_skimmed_fees_opt: Option>> = None; + read_tlv_fields!(reader, { (0, announcement_sigs, option), (1, minimum_depth, option), @@ -7126,6 +7173,8 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch (29, temporary_channel_id, option), (31, channel_pending_event_emitted, option), (33, pending_monitor_updates, vec_type), + (35, pending_outbound_skimmed_fees_opt, optional_vec), + (37, holding_cell_skimmed_fees_opt, optional_vec), }); let (channel_keys_id, holder_signer) = if let Some(channel_keys_id) = channel_keys_id { @@ -7180,6 +7229,25 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch let holder_max_accepted_htlcs = holder_max_accepted_htlcs.unwrap_or(DEFAULT_MAX_HTLCS); + if let Some(skimmed_fees) = pending_outbound_skimmed_fees_opt { + let mut iter = skimmed_fees.into_iter(); + for htlc in pending_outbound_htlcs.iter_mut() { + htlc.skimmed_fee_msat = iter.next().ok_or(DecodeError::InvalidValue)?; + } + // We expect all skimmed fees to be consumed above + if iter.next().is_some() { return Err(DecodeError::InvalidValue) } + } + if let Some(skimmed_fees) = holding_cell_skimmed_fees_opt { + let mut iter = skimmed_fees.into_iter(); + for htlc in holding_cell_htlc_updates.iter_mut() { + if let HTLCUpdateAwaitingACK::AddHTLC { ref mut skimmed_fee_msat, .. } = htlc { + *skimmed_fee_msat = iter.next().ok_or(DecodeError::InvalidValue)?; + } + } + // We expect all skimmed fees to be consumed above + if iter.next().is_some() { return Err(DecodeError::InvalidValue) } + } + Ok(Channel { context: ChannelContext { user_id, @@ -7522,7 +7590,8 @@ mod tests { session_priv: SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(), first_hop_htlc_msat: 548, payment_id: PaymentId([42; 32]), - } + }, + skimmed_fee_msat: None, }); // Make sure when Node A calculates their local commitment transaction, none of the HTLCs pass @@ -8079,6 +8148,7 @@ mod tests { payment_hash: PaymentHash([0; 32]), state: OutboundHTLCState::Committed, source: HTLCSource::dummy(), + skimmed_fee_msat: None, }; out.payment_hash.0 = Sha256::hash(&hex::decode("0202020202020202020202020202020202020202020202020202020202020202").unwrap()).into_inner(); out @@ -8091,6 +8161,7 @@ mod tests { payment_hash: PaymentHash([0; 32]), state: OutboundHTLCState::Committed, source: HTLCSource::dummy(), + skimmed_fee_msat: None, }; out.payment_hash.0 = Sha256::hash(&hex::decode("0303030303030303030303030303030303030303030303030303030303030303").unwrap()).into_inner(); out @@ -8492,6 +8563,7 @@ mod tests { payment_hash: PaymentHash([0; 32]), state: OutboundHTLCState::Committed, source: HTLCSource::dummy(), + skimmed_fee_msat: None, }; out.payment_hash.0 = Sha256::hash(&hex::decode("0505050505050505050505050505050505050505050505050505050505050505").unwrap()).into_inner(); out @@ -8504,6 +8576,7 @@ mod tests { payment_hash: PaymentHash([0; 32]), state: OutboundHTLCState::Committed, source: HTLCSource::dummy(), + skimmed_fee_msat: None, }; out.payment_hash.0 = Sha256::hash(&hex::decode("0505050505050505050505050505050505050505050505050505050505050505").unwrap()).into_inner(); out