@@ -224,6 +224,7 @@ struct OutboundHTLCOutput {
224
224
payment_hash: PaymentHash,
225
225
state: OutboundHTLCState,
226
226
source: HTLCSource,
227
+ skimmed_fee_msat: Option<u64>,
227
228
}
228
229
229
230
/// See AwaitingRemoteRevoke ChannelState for more info
@@ -235,6 +236,8 @@ enum HTLCUpdateAwaitingACK {
235
236
payment_hash: PaymentHash,
236
237
source: HTLCSource,
237
238
onion_routing_packet: msgs::OnionPacket,
239
+ // The extra fee we're skimming off the top of this HTLC.
240
+ skimmed_fee_msat: Option<u64>,
238
241
},
239
242
ClaimHTLC {
240
243
payment_preimage: PaymentPreimage,
@@ -5042,6 +5045,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
5042
5045
cltv_expiry,
5043
5046
source,
5044
5047
onion_routing_packet,
5048
+ skimmed_fee_msat: None,
5045
5049
});
5046
5050
return Ok(None);
5047
5051
}
@@ -5053,6 +5057,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
5053
5057
cltv_expiry,
5054
5058
state: OutboundHTLCState::LocalAnnounced(Box::new(onion_routing_packet.clone())),
5055
5059
source,
5060
+ skimmed_fee_msat: None,
5056
5061
});
5057
5062
5058
5063
let res = msgs::UpdateAddHTLC {
@@ -6612,9 +6617,10 @@ impl<Signer: WriteableEcdsaChannelSigner> Writeable for Channel<Signer> {
6612
6617
}
6613
6618
6614
6619
let mut preimages: Vec<&Option<PaymentPreimage>> = vec![];
6620
+ let mut pending_outbound_skimmed_fees: Vec<Option<u64>> = Vec::new();
6615
6621
6616
6622
(self.context.pending_outbound_htlcs.len() as u64).write(writer)?;
6617
- for htlc in self . context . pending_outbound_htlcs . iter ( ) {
6623
+ for (idx, htlc) in self.context.pending_outbound_htlcs.iter().enumerate () {
6618
6624
htlc.htlc_id.write(writer)?;
6619
6625
htlc.amount_msat.write(writer)?;
6620
6626
htlc.cltv_expiry.write(writer)?;
@@ -6650,18 +6656,37 @@ impl<Signer: WriteableEcdsaChannelSigner> Writeable for Channel<Signer> {
6650
6656
reason.write(writer)?;
6651
6657
}
6652
6658
}
6659
+ if let Some(skimmed_fee) = htlc.skimmed_fee_msat {
6660
+ if pending_outbound_skimmed_fees.is_empty() {
6661
+ for _ in 0..idx { pending_outbound_skimmed_fees.push(None); }
6662
+ }
6663
+ pending_outbound_skimmed_fees.push(Some(skimmed_fee));
6664
+ } else if !pending_outbound_skimmed_fees.is_empty() {
6665
+ pending_outbound_skimmed_fees.push(None);
6666
+ }
6653
6667
}
6654
6668
6669
+ let mut holding_cell_skimmed_fees: Vec<Option<u64>> = Vec::new();
6655
6670
(self.context.holding_cell_htlc_updates.len() as u64).write(writer)?;
6656
- for update in self . context . holding_cell_htlc_updates . iter ( ) {
6671
+ for (idx, update) in self.context.holding_cell_htlc_updates.iter().enumerate () {
6657
6672
match update {
6658
- & HTLCUpdateAwaitingACK :: AddHTLC { ref amount_msat, ref cltv_expiry, ref payment_hash, ref source, ref onion_routing_packet } => {
6673
+ &HTLCUpdateAwaitingACK::AddHTLC {
6674
+ ref amount_msat, ref cltv_expiry, ref payment_hash, ref source, ref onion_routing_packet,
6675
+ skimmed_fee_msat,
6676
+ } => {
6659
6677
0u8.write(writer)?;
6660
6678
amount_msat.write(writer)?;
6661
6679
cltv_expiry.write(writer)?;
6662
6680
payment_hash.write(writer)?;
6663
6681
source.write(writer)?;
6664
6682
onion_routing_packet.write(writer)?;
6683
+
6684
+ if let Some(skimmed_fee) = skimmed_fee_msat {
6685
+ if holding_cell_skimmed_fees.is_empty() {
6686
+ for _ in 0..idx { holding_cell_skimmed_fees.push(None); }
6687
+ }
6688
+ holding_cell_skimmed_fees.push(Some(skimmed_fee));
6689
+ } else if !holding_cell_skimmed_fees.is_empty() { holding_cell_skimmed_fees.push(None); }
6665
6690
},
6666
6691
&HTLCUpdateAwaitingACK::ClaimHTLC { ref payment_preimage, ref htlc_id } => {
6667
6692
1u8.write(writer)?;
@@ -6828,6 +6853,8 @@ impl<Signer: WriteableEcdsaChannelSigner> Writeable for Channel<Signer> {
6828
6853
(29, self.context.temporary_channel_id, option),
6829
6854
(31, channel_pending_event_emitted, option),
6830
6855
(33, self.context.pending_monitor_updates, vec_type),
6856
+ (35, pending_outbound_skimmed_fees, optional_vec),
6857
+ (37, holding_cell_skimmed_fees, optional_vec),
6831
6858
});
6832
6859
6833
6860
Ok(())
@@ -6938,6 +6965,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
6938
6965
},
6939
6966
_ => return Err(DecodeError::InvalidValue),
6940
6967
},
6968
+ skimmed_fee_msat: None,
6941
6969
});
6942
6970
}
6943
6971
@@ -6951,6 +6979,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
6951
6979
payment_hash: Readable::read(reader)?,
6952
6980
source: Readable::read(reader)?,
6953
6981
onion_routing_packet: Readable::read(reader)?,
6982
+ skimmed_fee_msat: None,
6954
6983
},
6955
6984
1 => HTLCUpdateAwaitingACK::ClaimHTLC {
6956
6985
payment_preimage: Readable::read(reader)?,
@@ -7106,6 +7135,9 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
7106
7135
7107
7136
let mut pending_monitor_updates = Some(Vec::new());
7108
7137
7138
+ let mut pending_outbound_skimmed_fees_opt: Option<Vec<Option<u64>>> = None;
7139
+ let mut holding_cell_skimmed_fees_opt: Option<Vec<Option<u64>>> = None;
7140
+
7109
7141
read_tlv_fields!(reader, {
7110
7142
(0, announcement_sigs, option),
7111
7143
(1, minimum_depth, option),
@@ -7129,6 +7161,8 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
7129
7161
(29, temporary_channel_id, option),
7130
7162
(31, channel_pending_event_emitted, option),
7131
7163
(33, pending_monitor_updates, vec_type),
7164
+ (35, pending_outbound_skimmed_fees_opt, optional_vec),
7165
+ (37, holding_cell_skimmed_fees_opt, optional_vec),
7132
7166
});
7133
7167
7134
7168
let (channel_keys_id, holder_signer) = if let Some(channel_keys_id) = channel_keys_id {
@@ -7183,6 +7217,25 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
7183
7217
7184
7218
let holder_max_accepted_htlcs = holder_max_accepted_htlcs.unwrap_or(DEFAULT_MAX_HTLCS);
7185
7219
7220
+ if let Some(skimmed_fees) = pending_outbound_skimmed_fees_opt {
7221
+ let mut iter = skimmed_fees.into_iter();
7222
+ for htlc in pending_outbound_htlcs.iter_mut() {
7223
+ htlc.skimmed_fee_msat = iter.next().ok_or(DecodeError::InvalidValue)?;
7224
+ }
7225
+ // We expect all skimmed fees to be consumed above
7226
+ if iter.next().is_some() { return Err(DecodeError::InvalidValue) }
7227
+ }
7228
+ if let Some(skimmed_fees) = holding_cell_skimmed_fees_opt {
7229
+ let mut iter = skimmed_fees.into_iter();
7230
+ for htlc in holding_cell_htlc_updates.iter_mut() {
7231
+ if let HTLCUpdateAwaitingACK::AddHTLC { ref mut skimmed_fee_msat, .. } = htlc {
7232
+ *skimmed_fee_msat = iter.next().ok_or(DecodeError::InvalidValue)?;
7233
+ }
7234
+ }
7235
+ // We expect all skimmed fees to be consumed above
7236
+ if iter.next().is_some() { return Err(DecodeError::InvalidValue) }
7237
+ }
7238
+
7186
7239
Ok(Channel {
7187
7240
context: ChannelContext {
7188
7241
user_id,
@@ -7525,7 +7578,8 @@ mod tests {
7525
7578
session_priv: SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(),
7526
7579
first_hop_htlc_msat: 548,
7527
7580
payment_id: PaymentId([42; 32]),
7528
- }
7581
+ },
7582
+ skimmed_fee_msat: None,
7529
7583
});
7530
7584
7531
7585
// Make sure when Node A calculates their local commitment transaction, none of the HTLCs pass
@@ -8082,6 +8136,7 @@ mod tests {
8082
8136
payment_hash: PaymentHash([0; 32]),
8083
8137
state: OutboundHTLCState::Committed,
8084
8138
source: HTLCSource::dummy(),
8139
+ skimmed_fee_msat: None,
8085
8140
};
8086
8141
out.payment_hash.0 = Sha256::hash(&hex::decode("0202020202020202020202020202020202020202020202020202020202020202").unwrap()).into_inner();
8087
8142
out
@@ -8094,6 +8149,7 @@ mod tests {
8094
8149
payment_hash: PaymentHash([0; 32]),
8095
8150
state: OutboundHTLCState::Committed,
8096
8151
source: HTLCSource::dummy(),
8152
+ skimmed_fee_msat: None,
8097
8153
};
8098
8154
out.payment_hash.0 = Sha256::hash(&hex::decode("0303030303030303030303030303030303030303030303030303030303030303").unwrap()).into_inner();
8099
8155
out
@@ -8495,6 +8551,7 @@ mod tests {
8495
8551
payment_hash: PaymentHash([0; 32]),
8496
8552
state: OutboundHTLCState::Committed,
8497
8553
source: HTLCSource::dummy(),
8554
+ skimmed_fee_msat: None,
8498
8555
};
8499
8556
out.payment_hash.0 = Sha256::hash(&hex::decode("0505050505050505050505050505050505050505050505050505050505050505").unwrap()).into_inner();
8500
8557
out
@@ -8507,6 +8564,7 @@ mod tests {
8507
8564
payment_hash: PaymentHash([0; 32]),
8508
8565
state: OutboundHTLCState::Committed,
8509
8566
source: HTLCSource::dummy(),
8567
+ skimmed_fee_msat: None,
8510
8568
};
8511
8569
out.payment_hash.0 = Sha256::hash(&hex::decode("0505050505050505050505050505050505050505050505050505050505050505").unwrap()).into_inner();
8512
8570
out
0 commit comments