Skip to content

Commit 6c18c8c

Browse files
committed
impl ser for the now-changed htlc failure packet
1 parent 023064f commit 6c18c8c

File tree

5 files changed

+106
-25
lines changed

5 files changed

+106
-25
lines changed

lightning/src/ln/channel.rs

+79-12
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use crate::ln::interactivetxs::{
3636
TX_COMMON_FIELDS_WEIGHT,
3737
};
3838
use crate::ln::msgs;
39-
use crate::ln::msgs::{ClosingSigned, ClosingSignedFeeRange, DecodeError};
39+
use crate::ln::msgs::{ClosingSigned, ClosingSignedFeeRange, DecodeError, OnionErrorPacket};
4040
use crate::ln::script::{self, ShutdownScript};
4141
use crate::ln::channel_state::{ChannelShutdownState, CounterpartyForwardingInfo, InboundHTLCDetails, InboundHTLCStateDetails, OutboundHTLCDetails, OutboundHTLCStateDetails};
4242
use crate::ln::channelmanager::{self, OpenChannelMessage, PendingHTLCStatus, HTLCSource, SentHTLCId, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, PaymentClaimDetails, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, MAX_LOCAL_BREAKDOWN_TIMEOUT};
@@ -9840,11 +9840,6 @@ fn get_initial_channel_type(config: &UserConfig, their_features: &InitFeatures)
98409840
const SERIALIZATION_VERSION: u8 = 4;
98419841
const MIN_SERIALIZATION_VERSION: u8 = 4;
98429842

9843-
impl_writeable_tlv_based_enum_legacy!(InboundHTLCRemovalReason,;
9844-
(0, FailRelay),
9845-
(1, FailMalformed),
9846-
(2, Fulfill),
9847-
);
98489843

98499844
impl Writeable for ChannelUpdateStatus {
98509845
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
@@ -9950,6 +9945,7 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
99509945
dropped_inbound_htlcs += 1;
99519946
}
99529947
}
9948+
let mut removed_htlc_failure_attribution_data: Vec<&Option<[u8; ATTRIBUTION_DATA_LEN]>> = Vec::new();
99539949
(self.context.pending_inbound_htlcs.len() as u64 - dropped_inbound_htlcs).write(writer)?;
99549950
for htlc in self.context.pending_inbound_htlcs.iter() {
99559951
if let &InboundHTLCState::RemoteAnnounced(_) = &htlc.state {
@@ -9974,7 +9970,21 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
99749970
},
99759971
&InboundHTLCState::LocalRemoved(ref removal_reason) => {
99769972
4u8.write(writer)?;
9977-
removal_reason.write(writer)?;
9973+
match removal_reason {
9974+
InboundHTLCRemovalReason::FailRelay(msgs::OnionErrorPacket { data, attribution_data }) => {
9975+
0u8.write(writer)?;
9976+
data.write(writer)?;
9977+
removed_htlc_failure_attribution_data.push(&attribution_data);
9978+
},
9979+
InboundHTLCRemovalReason::FailMalformed((hash, code)) => {
9980+
1u8.write(writer)?;
9981+
(hash, code).write(writer)?;
9982+
},
9983+
InboundHTLCRemovalReason::Fulfill(preimage) => {
9984+
2u8.write(writer)?;
9985+
preimage.write(writer)?;
9986+
},
9987+
}
99789988
},
99799989
}
99809990
}
@@ -10026,6 +10036,7 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1002610036

1002710037
let mut holding_cell_skimmed_fees: Vec<Option<u64>> = Vec::new();
1002810038
let mut holding_cell_blinding_points: Vec<Option<PublicKey>> = Vec::new();
10039+
let mut holding_cell_failure_attribution_data: Vec<&Option<[u8; ATTRIBUTION_DATA_LEN]>> = Vec::new();
1002910040
// Vec of (htlc_id, failure_code, sha256_of_onion)
1003010041
let mut malformed_htlcs: Vec<(u64, u16, [u8; 32])> = Vec::new();
1003110042
(self.context.holding_cell_htlc_updates.len() as u64).write(writer)?;
@@ -10053,7 +10064,8 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1005310064
&HTLCUpdateAwaitingACK::FailHTLC { ref htlc_id, ref err_packet } => {
1005410065
2u8.write(writer)?;
1005510066
htlc_id.write(writer)?;
10056-
err_packet.write(writer)?;
10067+
err_packet.data.write(writer)?;
10068+
holding_cell_failure_attribution_data.push(&err_packet.attribution_data);
1005710069
}
1005810070
&HTLCUpdateAwaitingACK::FailMalformedHTLC {
1005910071
htlc_id, failure_code, sha256_of_onion
@@ -10062,10 +10074,9 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1006210074
// `::FailHTLC` variant and write the real malformed error as an optional TLV.
1006310075
malformed_htlcs.push((htlc_id, failure_code, sha256_of_onion));
1006410076

10065-
let dummy_err_packet = msgs::OnionErrorPacket { data: Vec::new(), attribution_data: [0; ATTRIBUTION_DATA_LEN] };
1006610077
2u8.write(writer)?;
1006710078
htlc_id.write(writer)?;
10068-
dummy_err_packet.write(writer)?;
10079+
Vec::<u8>::new().write(writer)?;
1006910080
}
1007010081
}
1007110082
}
@@ -10238,6 +10249,8 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1023810249
(49, self.context.local_initiated_shutdown, option), // Added in 0.0.122
1023910250
(51, is_manual_broadcast, option), // Added in 0.0.124
1024010251
(53, funding_tx_broadcast_safe_event_emitted, option), // Added in 0.0.124
10252+
(55, removed_htlc_failure_attribution_data, optional_vec), // Added in 0.2
10253+
(57, holding_cell_failure_attribution_data, optional_vec), // Added in 0.2
1024110254
});
1024210255

1024310256
Ok(())
@@ -10330,7 +10343,18 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
1033010343
InboundHTLCState::AwaitingAnnouncedRemoteRevoke(resolution)
1033110344
},
1033210345
3 => InboundHTLCState::Committed,
10333-
4 => InboundHTLCState::LocalRemoved(Readable::read(reader)?),
10346+
4 => {
10347+
let reason = match <u8 as Readable>::read(reader)? {
10348+
0 => InboundHTLCRemovalReason::FailRelay(msgs::OnionErrorPacket {
10349+
data: Readable::read(reader)?,
10350+
attribution_data: None,
10351+
}),
10352+
1 => InboundHTLCRemovalReason::FailMalformed(Readable::read(reader)?),
10353+
2 => InboundHTLCRemovalReason::Fulfill(Readable::read(reader)?),
10354+
_ => return Err(DecodeError::InvalidValue),
10355+
};
10356+
InboundHTLCState::LocalRemoved(reason)
10357+
},
1033410358
_ => return Err(DecodeError::InvalidValue),
1033510359
},
1033610360
});
@@ -10386,7 +10410,10 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
1038610410
},
1038710411
2 => HTLCUpdateAwaitingACK::FailHTLC {
1038810412
htlc_id: Readable::read(reader)?,
10389-
err_packet: Readable::read(reader)?,
10413+
err_packet: OnionErrorPacket {
10414+
data: Readable::read(reader)?,
10415+
attribution_data: None,
10416+
},
1039010417
},
1039110418
_ => return Err(DecodeError::InvalidValue),
1039210419
});
@@ -10535,6 +10562,9 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
1053510562
let mut pending_outbound_blinding_points_opt: Option<Vec<Option<PublicKey>>> = None;
1053610563
let mut holding_cell_blinding_points_opt: Option<Vec<Option<PublicKey>>> = None;
1053710564

10565+
let mut removed_htlc_failure_attribution_data: Option<Vec<Option<[u8; ATTRIBUTION_DATA_LEN]>>> = None;
10566+
let mut holding_cell_failure_attribution_data: Option<Vec<Option<[u8; ATTRIBUTION_DATA_LEN]>>> = None;
10567+
1053810568
let mut malformed_htlcs: Option<Vec<(u64, u16, [u8; 32])>> = None;
1053910569
let mut monitor_pending_update_adds: Option<Vec<msgs::UpdateAddHTLC>> = None;
1054010570

@@ -10577,6 +10607,8 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
1057710607
(49, local_initiated_shutdown, option),
1057810608
(51, is_manual_broadcast, option),
1057910609
(53, funding_tx_broadcast_safe_event_emitted, option),
10610+
(55, removed_htlc_failure_attribution_data, option),
10611+
(57, holding_cell_failure_attribution_data, option),
1058010612
});
1058110613

1058210614
let (channel_keys_id, holder_signer) = if let Some(channel_keys_id) = channel_keys_id {
@@ -10671,6 +10703,41 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
1067110703
if iter.next().is_some() { return Err(DecodeError::InvalidValue) }
1067210704
}
1067310705

10706+
if let Some(attribution_datas) = removed_htlc_failure_attribution_data {
10707+
let mut removed_htlc_relay_failures =
10708+
pending_inbound_htlcs.iter_mut().filter_map(|status|
10709+
if let InboundHTLCState::LocalRemoved(ref mut reason) = &mut status.state {
10710+
if let InboundHTLCRemovalReason::FailRelay(ref mut packet) = reason {
10711+
Some(&mut packet.attribution_data)
10712+
} else {
10713+
None
10714+
}
10715+
} else {
10716+
None
10717+
}
10718+
);
10719+
10720+
for attribution_data in attribution_datas {
10721+
*removed_htlc_relay_failures.next().ok_or(DecodeError::InvalidValue)? = attribution_data;
10722+
}
10723+
if removed_htlc_relay_failures.next().is_some() { return Err(DecodeError::InvalidValue); }
10724+
}
10725+
if let Some(attribution_datas) = holding_cell_failure_attribution_data {
10726+
let mut holding_cell_failures =
10727+
holding_cell_htlc_updates.iter_mut().filter_map(|upd|
10728+
if let HTLCUpdateAwaitingACK::FailHTLC { err_packet: OnionErrorPacket { ref mut attribution_data, .. }, .. } = upd {
10729+
Some(attribution_data)
10730+
} else {
10731+
None
10732+
}
10733+
);
10734+
10735+
for attribution_data in attribution_datas {
10736+
*holding_cell_failures.next().ok_or(DecodeError::InvalidValue)? = attribution_data;
10737+
}
10738+
if holding_cell_failures.next().is_some() { return Err(DecodeError::InvalidValue); }
10739+
}
10740+
1067410741
if let Some(malformed_htlcs) = malformed_htlcs {
1067510742
for (malformed_htlc_id, failure_code, sha256_of_onion) in malformed_htlcs {
1067610743
let htlc_idx = holding_cell_htlc_updates.iter().position(|htlc| {

lightning/src/ln/channelmanager.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -13117,19 +13117,19 @@ impl Writeable for HTLCForwardInfo {
1311713117
FAIL_HTLC_VARIANT_ID.write(w)?;
1311813118
write_tlv_fields!(w, {
1311913119
(0, htlc_id, required),
13120-
(2, err_packet, required),
13120+
(2, err_packet.data, required),
13121+
(5, err_packet.attribution_data, option),
1312113122
});
1312213123
},
1312313124
Self::FailMalformedHTLC { htlc_id, failure_code, sha256_of_onion } => {
1312413125
// Since this variant was added in 0.0.119, write this as `::FailHTLC` with an empty error
1312513126
// packet so older versions have something to fail back with, but serialize the real data as
1312613127
// optional TLVs for the benefit of newer versions.
1312713128
FAIL_HTLC_VARIANT_ID.write(w)?;
13128-
let dummy_err_packet = msgs::OnionErrorPacket { data: Vec::new(), attribution_data: [0; ATTRIBUTION_DATA_LEN] };
1312913129
write_tlv_fields!(w, {
1313013130
(0, htlc_id, required),
1313113131
(1, failure_code, required),
13132-
(2, dummy_err_packet, required),
13132+
(2, Vec::<u8>::new(), required),
1313313133
(3, sha256_of_onion, required),
1313413134
});
1313513135
},
@@ -13149,8 +13149,12 @@ impl Readable for HTLCForwardInfo {
1314913149
(1, malformed_htlc_failure_code, option),
1315013150
(2, err_packet, required),
1315113151
(3, sha256_of_onion, option),
13152+
(5, attribution_data, option),
1315213153
});
1315313154
if let Some(failure_code) = malformed_htlc_failure_code {
13155+
if attribution_data.is_some() {
13156+
return Err(DecodeError::InvalidValue);
13157+
}
1315413158
Self::FailMalformedHTLC {
1315513159
htlc_id: _init_tlv_based_struct_field!(htlc_id, required),
1315613160
failure_code,
@@ -13159,7 +13163,10 @@ impl Readable for HTLCForwardInfo {
1315913163
} else {
1316013164
Self::FailHTLC {
1316113165
htlc_id: _init_tlv_based_struct_field!(htlc_id, required),
13162-
err_packet: _init_tlv_based_struct_field!(err_packet, required),
13166+
err_packet: crate::ln::msgs::OnionErrorPacket {
13167+
data: _init_tlv_based_struct_field!(err_packet, required),
13168+
attribution_data: _init_tlv_based_struct_field!(attribution_data, option),
13169+
},
1316313170
}
1316413171
}
1316513172
},

lightning/src/ln/msgs.rs

-8
Original file line numberDiff line numberDiff line change
@@ -2700,14 +2700,6 @@ impl_writeable_msg!(PeerStorageRetrieval, {
27002700
data
27012701
}, {});
27022702

2703-
// Note that this is written as a part of ChannelManager objects, and thus cannot change its
2704-
// serialization format in a way which assumes we know the total serialized length/message end
2705-
// position.
2706-
impl_writeable!(OnionErrorPacket, {
2707-
data,
2708-
attribution_data
2709-
});
2710-
27112703
// Note that this is written as a part of ChannelManager objects, and thus cannot change its
27122704
// serialization format in a way which assumes we know the total serialized length/message end
27132705
// position.

lightning/src/ln/onion_utils.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -1371,7 +1371,21 @@ impl Readable for HTLCFailReason {
13711371

13721372
impl_writeable_tlv_based_enum!(HTLCFailReasonRepr,
13731373
(0, LightningError) => {
1374-
(0, err, required),
1374+
(0, data, (legacy, Vec<u8>, |us|
1375+
if let &HTLCFailReasonRepr::LightningError { err: msgs::OnionErrorPacket { ref data, .. } } = us {
1376+
Some(data)
1377+
} else {
1378+
None
1379+
})
1380+
),
1381+
(1, attribution_data, (legacy, [u8; ATTRIBUTION_DATA_LEN], |us|
1382+
if let &HTLCFailReasonRepr::LightningError { err: msgs::OnionErrorPacket { ref attribution_data, .. } } = us {
1383+
Some(attribution_data)
1384+
} else {
1385+
None
1386+
})
1387+
),
1388+
(_unused, err, (static_value, msgs::OnionErrorPacket { data: data.ok_or(DecodeError::InvalidValue)?, attribution_data })),
13751389
},
13761390
(1, Reason) => {
13771391
(0, failure_code, required),

lightning/src/util/ser.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,7 @@ impl_for_vec!((A, B), A, B);
10651065
impl_writeable_for_vec!(&crate::routing::router::BlindedTail);
10661066
impl_readable_for_vec!(crate::routing::router::BlindedTail);
10671067
impl_for_vec!(crate::routing::router::TrampolineHop);
1068+
impl_for_vec!(Option<[u8; 920]>);
10681069
impl_for_vec_with_element_length_prefix!(crate::ln::msgs::UpdateAddHTLC);
10691070
impl_writeable_for_vec_with_element_length_prefix!(&crate::ln::msgs::UpdateAddHTLC);
10701071

0 commit comments

Comments
 (0)