@@ -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,
@@ -5126,6 +5129,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
5126
5129
cltv_expiry,
5127
5130
source,
5128
5131
onion_routing_packet,
5132
+ skimmed_fee_msat: None,
5129
5133
});
5130
5134
return Ok(None);
5131
5135
}
@@ -5137,6 +5141,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
5137
5141
cltv_expiry,
5138
5142
state: OutboundHTLCState::LocalAnnounced(Box::new(onion_routing_packet.clone())),
5139
5143
source,
5144
+ skimmed_fee_msat: None,
5140
5145
});
5141
5146
5142
5147
let res = msgs::UpdateAddHTLC {
@@ -6611,9 +6616,10 @@ impl<Signer: WriteableEcdsaChannelSigner> Writeable for Channel<Signer> {
6611
6616
}
6612
6617
6613
6618
let mut preimages: Vec<&Option<PaymentPreimage>> = vec![];
6619
+ let mut pending_outbound_skimmed_fees: Vec<Option<u64>> = Vec::new();
6614
6620
6615
6621
(self.context.pending_outbound_htlcs.len() as u64).write(writer)?;
6616
- for htlc in self . context . pending_outbound_htlcs . iter ( ) {
6622
+ for (idx, htlc) in self.context.pending_outbound_htlcs.iter().enumerate () {
6617
6623
htlc.htlc_id.write(writer)?;
6618
6624
htlc.amount_msat.write(writer)?;
6619
6625
htlc.cltv_expiry.write(writer)?;
@@ -6649,18 +6655,37 @@ impl<Signer: WriteableEcdsaChannelSigner> Writeable for Channel<Signer> {
6649
6655
reason.write(writer)?;
6650
6656
}
6651
6657
}
6658
+ if let Some(skimmed_fee) = htlc.skimmed_fee_msat {
6659
+ if pending_outbound_skimmed_fees.is_empty() {
6660
+ for _ in 0..idx { pending_outbound_skimmed_fees.push(None); }
6661
+ }
6662
+ pending_outbound_skimmed_fees.push(Some(skimmed_fee));
6663
+ } else if !pending_outbound_skimmed_fees.is_empty() {
6664
+ pending_outbound_skimmed_fees.push(None);
6665
+ }
6652
6666
}
6653
6667
6668
+ let mut holding_cell_skimmed_fees: Vec<Option<u64>> = Vec::new();
6654
6669
(self.context.holding_cell_htlc_updates.len() as u64).write(writer)?;
6655
- for update in self . context . holding_cell_htlc_updates . iter ( ) {
6670
+ for (idx, update) in self.context.holding_cell_htlc_updates.iter().enumerate () {
6656
6671
match update {
6657
- & HTLCUpdateAwaitingACK :: AddHTLC { ref amount_msat, ref cltv_expiry, ref payment_hash, ref source, ref onion_routing_packet } => {
6672
+ &HTLCUpdateAwaitingACK::AddHTLC {
6673
+ ref amount_msat, ref cltv_expiry, ref payment_hash, ref source, ref onion_routing_packet,
6674
+ skimmed_fee_msat,
6675
+ } => {
6658
6676
0u8.write(writer)?;
6659
6677
amount_msat.write(writer)?;
6660
6678
cltv_expiry.write(writer)?;
6661
6679
payment_hash.write(writer)?;
6662
6680
source.write(writer)?;
6663
6681
onion_routing_packet.write(writer)?;
6682
+
6683
+ if let Some(skimmed_fee) = skimmed_fee_msat {
6684
+ if holding_cell_skimmed_fees.is_empty() {
6685
+ for _ in 0..idx { holding_cell_skimmed_fees.push(None); }
6686
+ }
6687
+ holding_cell_skimmed_fees.push(Some(skimmed_fee));
6688
+ } else if !holding_cell_skimmed_fees.is_empty() { holding_cell_skimmed_fees.push(None); }
6664
6689
},
6665
6690
&HTLCUpdateAwaitingACK::ClaimHTLC { ref payment_preimage, ref htlc_id } => {
6666
6691
1u8.write(writer)?;
@@ -6827,6 +6852,8 @@ impl<Signer: WriteableEcdsaChannelSigner> Writeable for Channel<Signer> {
6827
6852
(29, self.context.temporary_channel_id, option),
6828
6853
(31, channel_pending_event_emitted, option),
6829
6854
(33, self.context.pending_monitor_updates, vec_type),
6855
+ (35, pending_outbound_skimmed_fees, optional_vec),
6856
+ (37, holding_cell_skimmed_fees, optional_vec),
6830
6857
});
6831
6858
6832
6859
Ok(())
@@ -6937,6 +6964,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
6937
6964
},
6938
6965
_ => return Err(DecodeError::InvalidValue),
6939
6966
},
6967
+ skimmed_fee_msat: None,
6940
6968
});
6941
6969
}
6942
6970
@@ -6950,6 +6978,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
6950
6978
payment_hash: Readable::read(reader)?,
6951
6979
source: Readable::read(reader)?,
6952
6980
onion_routing_packet: Readable::read(reader)?,
6981
+ skimmed_fee_msat: None,
6953
6982
},
6954
6983
1 => HTLCUpdateAwaitingACK::ClaimHTLC {
6955
6984
payment_preimage: Readable::read(reader)?,
@@ -7105,6 +7134,9 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
7105
7134
7106
7135
let mut pending_monitor_updates = Some(Vec::new());
7107
7136
7137
+ let mut pending_outbound_skimmed_fees_opt: Option<Vec<Option<u64>>> = None;
7138
+ let mut holding_cell_skimmed_fees_opt: Option<Vec<Option<u64>>> = None;
7139
+
7108
7140
read_tlv_fields!(reader, {
7109
7141
(0, announcement_sigs, option),
7110
7142
(1, minimum_depth, option),
@@ -7128,6 +7160,8 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
7128
7160
(29, temporary_channel_id, option),
7129
7161
(31, channel_pending_event_emitted, option),
7130
7162
(33, pending_monitor_updates, vec_type),
7163
+ (35, pending_outbound_skimmed_fees_opt, optional_vec),
7164
+ (37, holding_cell_skimmed_fees_opt, optional_vec),
7131
7165
});
7132
7166
7133
7167
let (channel_keys_id, holder_signer) = if let Some(channel_keys_id) = channel_keys_id {
@@ -7182,6 +7216,25 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
7182
7216
7183
7217
let holder_max_accepted_htlcs = holder_max_accepted_htlcs.unwrap_or(DEFAULT_MAX_HTLCS);
7184
7218
7219
+ if let Some(skimmed_fees) = pending_outbound_skimmed_fees_opt {
7220
+ let mut iter = skimmed_fees.into_iter();
7221
+ for htlc in pending_outbound_htlcs.iter_mut() {
7222
+ htlc.skimmed_fee_msat = iter.next().ok_or(DecodeError::InvalidValue)?;
7223
+ }
7224
+ // We expect all skimmed fees to be consumed above
7225
+ if iter.next().is_some() { return Err(DecodeError::InvalidValue) }
7226
+ }
7227
+ if let Some(skimmed_fees) = holding_cell_skimmed_fees_opt {
7228
+ let mut iter = skimmed_fees.into_iter();
7229
+ for htlc in holding_cell_htlc_updates.iter_mut() {
7230
+ if let HTLCUpdateAwaitingACK::AddHTLC { ref mut skimmed_fee_msat, .. } = htlc {
7231
+ *skimmed_fee_msat = iter.next().ok_or(DecodeError::InvalidValue)?;
7232
+ }
7233
+ }
7234
+ // We expect all skimmed fees to be consumed above
7235
+ if iter.next().is_some() { return Err(DecodeError::InvalidValue) }
7236
+ }
7237
+
7185
7238
Ok(Channel {
7186
7239
context: ChannelContext {
7187
7240
user_id,
@@ -7524,7 +7577,8 @@ mod tests {
7524
7577
session_priv: SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(),
7525
7578
first_hop_htlc_msat: 548,
7526
7579
payment_id: PaymentId([42; 32]),
7527
- }
7580
+ },
7581
+ skimmed_fee_msat: None,
7528
7582
});
7529
7583
7530
7584
// Make sure when Node A calculates their local commitment transaction, none of the HTLCs pass
@@ -8081,6 +8135,7 @@ mod tests {
8081
8135
payment_hash: PaymentHash([0; 32]),
8082
8136
state: OutboundHTLCState::Committed,
8083
8137
source: HTLCSource::dummy(),
8138
+ skimmed_fee_msat: None,
8084
8139
};
8085
8140
out.payment_hash.0 = Sha256::hash(&hex::decode("0202020202020202020202020202020202020202020202020202020202020202").unwrap()).into_inner();
8086
8141
out
@@ -8093,6 +8148,7 @@ mod tests {
8093
8148
payment_hash: PaymentHash([0; 32]),
8094
8149
state: OutboundHTLCState::Committed,
8095
8150
source: HTLCSource::dummy(),
8151
+ skimmed_fee_msat: None,
8096
8152
};
8097
8153
out.payment_hash.0 = Sha256::hash(&hex::decode("0303030303030303030303030303030303030303030303030303030303030303").unwrap()).into_inner();
8098
8154
out
@@ -8494,6 +8550,7 @@ mod tests {
8494
8550
payment_hash: PaymentHash([0; 32]),
8495
8551
state: OutboundHTLCState::Committed,
8496
8552
source: HTLCSource::dummy(),
8553
+ skimmed_fee_msat: None,
8497
8554
};
8498
8555
out.payment_hash.0 = Sha256::hash(&hex::decode("0505050505050505050505050505050505050505050505050505050505050505").unwrap()).into_inner();
8499
8556
out
@@ -8506,6 +8563,7 @@ mod tests {
8506
8563
payment_hash: PaymentHash([0; 32]),
8507
8564
state: OutboundHTLCState::Committed,
8508
8565
source: HTLCSource::dummy(),
8566
+ skimmed_fee_msat: None,
8509
8567
};
8510
8568
out.payment_hash.0 = Sha256::hash(&hex::decode("0505050505050505050505050505050505050505050505050505050505050505").unwrap()).into_inner();
8511
8569
out
0 commit comments