Skip to content

Commit 92e39b2

Browse files
Add attribution_data field to data structures
This commit does not yet introduce attribution data, but just adds the field and required serialization logic to the relevant types. Co-authored-by: Matt Corallo <git@bluematt.me>
1 parent e300843 commit 92e39b2

File tree

10 files changed

+159
-27
lines changed

10 files changed

+159
-27
lines changed

fuzz/src/process_onion_failure.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
118118
HTLCSource::OutboundRoute { path, session_priv, first_hop_htlc_msat: 0, payment_id };
119119

120120
let failure_len = get_u16!();
121-
let encrypted_packet = OnionErrorPacket { data: get_slice!(failure_len).into() };
121+
let encrypted_packet =
122+
OnionErrorPacket { data: get_slice!(failure_len).into(), attribution_data: None };
122123

123124
lightning::ln::process_onion_failure(&secp_ctx, &logger, &htlc_source, encrypted_packet);
124125
}

lightning/src/ln/channel.rs

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ use crate::ln::chan_utils::{
5050
#[cfg(splicing)]
5151
use crate::ln::chan_utils::FUNDING_TRANSACTION_WITNESS_WEIGHT;
5252
use crate::ln::chan_utils;
53-
use crate::ln::onion_utils::{HTLCFailReason};
53+
use crate::ln::onion_utils::{HTLCFailReason, AttributionData};
5454
use crate::chain::BestBlock;
5555
use crate::chain::chaininterface::{FeeEstimator, ConfirmationTarget, LowerBoundedFeeEstimator, fee_for_weight};
5656
use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, LATENCY_GRACE_PERIOD_BLOCKS};
@@ -4907,7 +4907,7 @@ trait FailHTLCContents {
49074907
impl FailHTLCContents for msgs::OnionErrorPacket {
49084908
type Message = msgs::UpdateFailHTLC;
49094909
fn to_message(self, htlc_id: u64, channel_id: ChannelId) -> Self::Message {
4910-
msgs::UpdateFailHTLC { htlc_id, channel_id, reason: self.data }
4910+
msgs::UpdateFailHTLC { htlc_id, channel_id, reason: self.data, attribution_data: self.attribution_data }
49114911
}
49124912
fn to_inbound_htlc_state(self) -> InboundHTLCState {
49134913
InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::FailRelay(self))
@@ -6821,6 +6821,7 @@ impl<SP: Deref> FundedChannel<SP> where
68216821
channel_id: self.context.channel_id(),
68226822
htlc_id: htlc.htlc_id,
68236823
reason: err_packet.data.clone(),
6824+
attribution_data: err_packet.attribution_data.clone(),
68246825
});
68256826
},
68266827
&InboundHTLCRemovalReason::FailMalformed((ref sha256_of_onion, ref failure_code)) => {
@@ -10225,6 +10226,7 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1022510226
dropped_inbound_htlcs += 1;
1022610227
}
1022710228
}
10229+
let mut removed_htlc_failure_attribution_data: Vec<&Option<AttributionData>> = Vec::new();
1022810230
(self.context.pending_inbound_htlcs.len() as u64 - dropped_inbound_htlcs).write(writer)?;
1022910231
for htlc in self.context.pending_inbound_htlcs.iter() {
1023010232
if let &InboundHTLCState::RemoteAnnounced(_) = &htlc.state {
@@ -10250,9 +10252,10 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1025010252
&InboundHTLCState::LocalRemoved(ref removal_reason) => {
1025110253
4u8.write(writer)?;
1025210254
match removal_reason {
10253-
InboundHTLCRemovalReason::FailRelay(msgs::OnionErrorPacket { data }) => {
10255+
InboundHTLCRemovalReason::FailRelay(msgs::OnionErrorPacket { data, attribution_data }) => {
1025410256
0u8.write(writer)?;
1025510257
data.write(writer)?;
10258+
removed_htlc_failure_attribution_data.push(&attribution_data);
1025610259
},
1025710260
InboundHTLCRemovalReason::FailMalformed((hash, code)) => {
1025810261
1u8.write(writer)?;
@@ -10312,11 +10315,13 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1031210315
pending_outbound_blinding_points.push(htlc.blinding_point);
1031310316
}
1031410317

10315-
let mut holding_cell_skimmed_fees: Vec<Option<u64>> = Vec::new();
10316-
let mut holding_cell_blinding_points: Vec<Option<PublicKey>> = Vec::new();
10318+
let holding_cell_htlc_update_count = self.context.holding_cell_htlc_updates.len();
10319+
let mut holding_cell_skimmed_fees: Vec<Option<u64>> = Vec::with_capacity(holding_cell_htlc_update_count);
10320+
let mut holding_cell_blinding_points: Vec<Option<PublicKey>> = Vec::with_capacity(holding_cell_htlc_update_count);
10321+
let mut holding_cell_failure_attribution_data: Vec<Option<&AttributionData>> = Vec::with_capacity(holding_cell_htlc_update_count);
1031710322
// Vec of (htlc_id, failure_code, sha256_of_onion)
1031810323
let mut malformed_htlcs: Vec<(u64, u16, [u8; 32])> = Vec::new();
10319-
(self.context.holding_cell_htlc_updates.len() as u64).write(writer)?;
10324+
(holding_cell_htlc_update_count as u64).write(writer)?;
1032010325
for update in self.context.holding_cell_htlc_updates.iter() {
1032110326
match update {
1032210327
&HTLCUpdateAwaitingACK::AddHTLC {
@@ -10342,6 +10347,9 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1034210347
2u8.write(writer)?;
1034310348
htlc_id.write(writer)?;
1034410349
err_packet.data.write(writer)?;
10350+
10351+
// Store the attribution data for later writing.
10352+
holding_cell_failure_attribution_data.push(err_packet.attribution_data.as_ref());
1034510353
}
1034610354
&HTLCUpdateAwaitingACK::FailMalformedHTLC {
1034710355
htlc_id, failure_code, sha256_of_onion
@@ -10353,6 +10361,10 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1035310361
2u8.write(writer)?;
1035410362
htlc_id.write(writer)?;
1035510363
Vec::<u8>::new().write(writer)?;
10364+
10365+
// Push 'None' attribution data for FailMalformedHTLC, because FailMalformedHTLC uses the same
10366+
// type 2 and is deserialized as a FailHTLC.
10367+
holding_cell_failure_attribution_data.push(None);
1035610368
}
1035710369
}
1035810370
}
@@ -10525,6 +10537,8 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1052510537
(49, self.context.local_initiated_shutdown, option), // Added in 0.0.122
1052610538
(51, is_manual_broadcast, option), // Added in 0.0.124
1052710539
(53, funding_tx_broadcast_safe_event_emitted, option), // Added in 0.0.124
10540+
(55, removed_htlc_failure_attribution_data, optional_vec), // Added in 0.2
10541+
(57, holding_cell_failure_attribution_data, optional_vec), // Added in 0.2
1052810542
});
1052910543

1053010544
Ok(())
@@ -10602,6 +10616,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1060210616
let reason = match <u8 as Readable>::read(reader)? {
1060310617
0 => InboundHTLCRemovalReason::FailRelay(msgs::OnionErrorPacket {
1060410618
data: Readable::read(reader)?,
10619+
attribution_data: None,
1060510620
}),
1060610621
1 => InboundHTLCRemovalReason::FailMalformed(Readable::read(reader)?),
1060710622
2 => InboundHTLCRemovalReason::Fulfill(Readable::read(reader)?),
@@ -10666,6 +10681,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1066610681
htlc_id: Readable::read(reader)?,
1066710682
err_packet: OnionErrorPacket {
1066810683
data: Readable::read(reader)?,
10684+
attribution_data: None,
1066910685
},
1067010686
},
1067110687
_ => return Err(DecodeError::InvalidValue),
@@ -10809,6 +10825,9 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1080910825
let mut pending_outbound_blinding_points_opt: Option<Vec<Option<PublicKey>>> = None;
1081010826
let mut holding_cell_blinding_points_opt: Option<Vec<Option<PublicKey>>> = None;
1081110827

10828+
let mut removed_htlc_failure_attribution_data: Option<Vec<Option<AttributionData>>> = None;
10829+
let mut holding_cell_failure_attribution_data: Option<Vec<Option<AttributionData>>> = None;
10830+
1081210831
let mut malformed_htlcs: Option<Vec<(u64, u16, [u8; 32])>> = None;
1081310832
let mut monitor_pending_update_adds: Option<Vec<msgs::UpdateAddHTLC>> = None;
1081410833

@@ -10851,6 +10870,8 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1085110870
(49, local_initiated_shutdown, option),
1085210871
(51, is_manual_broadcast, option),
1085310872
(53, funding_tx_broadcast_safe_event_emitted, option),
10873+
(55, removed_htlc_failure_attribution_data, optional_vec),
10874+
(57, holding_cell_failure_attribution_data, optional_vec),
1085410875
});
1085510876

1085610877
let holder_signer = signer_provider.derive_channel_signer(channel_keys_id);
@@ -10932,6 +10953,38 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1093210953
if iter.next().is_some() { return Err(DecodeError::InvalidValue) }
1093310954
}
1093410955

10956+
if let Some(attribution_data_list) = removed_htlc_failure_attribution_data {
10957+
let mut removed_htlc_relay_failures =
10958+
pending_inbound_htlcs.iter_mut().filter_map(|status|
10959+
if let InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::FailRelay(ref mut packet)) = &mut status.state {
10960+
Some(&mut packet.attribution_data)
10961+
} else {
10962+
None
10963+
}
10964+
);
10965+
10966+
for attribution_data in attribution_data_list {
10967+
*removed_htlc_relay_failures.next().ok_or(DecodeError::InvalidValue)? = attribution_data;
10968+
}
10969+
if removed_htlc_relay_failures.next().is_some() { return Err(DecodeError::InvalidValue); }
10970+
}
10971+
10972+
if let Some(attribution_data_list) = holding_cell_failure_attribution_data {
10973+
let mut holding_cell_failures =
10974+
holding_cell_htlc_updates.iter_mut().filter_map(|upd|
10975+
if let HTLCUpdateAwaitingACK::FailHTLC { err_packet: OnionErrorPacket { ref mut attribution_data, .. }, .. } = upd {
10976+
Some(attribution_data)
10977+
} else {
10978+
None
10979+
}
10980+
);
10981+
10982+
for attribution_data in attribution_data_list {
10983+
*holding_cell_failures.next().ok_or(DecodeError::InvalidValue)? = attribution_data;
10984+
}
10985+
if holding_cell_failures.next().is_some() { return Err(DecodeError::InvalidValue); }
10986+
}
10987+
1093510988
if let Some(malformed_htlcs) = malformed_htlcs {
1093610989
for (malformed_htlc_id, failure_code, sha256_of_onion) in malformed_htlcs {
1093710990
let htlc_idx = holding_cell_htlc_updates.iter().position(|htlc| {
@@ -11135,7 +11188,7 @@ mod tests {
1113511188
use bitcoin::network::Network;
1113611189
#[cfg(splicing)]
1113711190
use bitcoin::Weight;
11138-
use crate::ln::onion_utils::INVALID_ONION_BLINDING;
11191+
use crate::ln::onion_utils::{AttributionData, INVALID_ONION_BLINDING};
1113911192
use crate::types::payment::{PaymentHash, PaymentPreimage};
1114011193
use crate::ln::channel_keys::{RevocationKey, RevocationBasepoint};
1114111194
use crate::ln::channelmanager::{self, HTLCSource, PaymentId};
@@ -11772,7 +11825,7 @@ mod tests {
1177211825
htlc_id: 0,
1177311826
};
1177411827
let dummy_holding_cell_failed_htlc = |htlc_id| HTLCUpdateAwaitingACK::FailHTLC {
11775-
htlc_id, err_packet: msgs::OnionErrorPacket { data: vec![42] }
11828+
htlc_id, err_packet: msgs::OnionErrorPacket { data: vec![42], attribution_data: Some(AttributionData::new()) }
1177611829
};
1177711830
let dummy_holding_cell_malformed_htlc = |htlc_id| HTLCUpdateAwaitingACK::FailMalformedHTLC {
1177811831
htlc_id, failure_code: INVALID_ONION_BLINDING, sha256_of_onion: [0; 32],

lightning/src/ln/channelmanager.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ use crate::types::features::Bolt11InvoiceFeatures;
5959
use crate::routing::router::{BlindedTail, InFlightHtlcs, Path, Payee, PaymentParameters, RouteParameters, RouteParametersConfig, Router, FixedRouter, Route};
6060
use crate::ln::onion_payment::{check_incoming_htlc_cltv, create_recv_pending_htlc_info, create_fwd_pending_htlc_info, decode_incoming_update_add_htlc_onion, HopConnector, InboundHTLCErr, NextPacketDetails};
6161
use crate::ln::msgs;
62-
use crate::ln::onion_utils;
62+
use crate::ln::onion_utils::{self};
6363
use crate::ln::onion_utils::{HTLCFailReason, INVALID_ONION_BLINDING};
6464
use crate::ln::msgs::{BaseMessageHandler, ChannelMessageHandler, CommitmentUpdate, DecodeError, LightningError, MessageSendEvent};
6565
#[cfg(test)]
@@ -4481,6 +4481,7 @@ where
44814481
channel_id: msg.channel_id,
44824482
htlc_id: msg.htlc_id,
44834483
reason: failure.data,
4484+
attribution_data: failure.attribution_data,
44844485
})
44854486
}
44864487

@@ -4510,6 +4511,7 @@ where
45104511
channel_id: msg.channel_id,
45114512
htlc_id: msg.htlc_id,
45124513
reason: failure.data,
4514+
attribution_data: failure.attribution_data,
45134515
}));
45144516
}
45154517
}
@@ -12924,11 +12926,15 @@ impl_writeable_tlv_based!(PendingHTLCInfo, {
1292412926
impl Writeable for HTLCFailureMsg {
1292512927
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
1292612928
match self {
12927-
HTLCFailureMsg::Relay(msgs::UpdateFailHTLC { channel_id, htlc_id, reason }) => {
12929+
HTLCFailureMsg::Relay(msgs::UpdateFailHTLC { channel_id, htlc_id, reason, attribution_data }) => {
1292812930
0u8.write(writer)?;
1292912931
channel_id.write(writer)?;
1293012932
htlc_id.write(writer)?;
1293112933
reason.write(writer)?;
12934+
12935+
// This code will only ever be hit for legacy data that is re-serialized. It isn't necessary to try
12936+
// writing out attribution data, because it can never be present.
12937+
debug_assert!(attribution_data.is_none());
1293212938
},
1293312939
HTLCFailureMsg::Malformed(msgs::UpdateFailMalformedHTLC {
1293412940
channel_id, htlc_id, sha256_of_onion, failure_code
@@ -12953,6 +12959,7 @@ impl Readable for HTLCFailureMsg {
1295312959
channel_id: Readable::read(reader)?,
1295412960
htlc_id: Readable::read(reader)?,
1295512961
reason: Readable::read(reader)?,
12962+
attribution_data: None,
1295612963
}))
1295712964
},
1295812965
1 => {
@@ -13183,6 +13190,7 @@ impl Writeable for HTLCForwardInfo {
1318313190
write_tlv_fields!(w, {
1318413191
(0, htlc_id, required),
1318513192
(2, err_packet.data, required),
13193+
(5, err_packet.attribution_data, option),
1318613194
});
1318713195
},
1318813196
Self::FailMalformedHTLC { htlc_id, failure_code, sha256_of_onion } => {
@@ -13213,8 +13221,12 @@ impl Readable for HTLCForwardInfo {
1321313221
(1, malformed_htlc_failure_code, option),
1321413222
(2, err_packet, required),
1321513223
(3, sha256_of_onion, option),
13224+
(5, attribution_data, option),
1321613225
});
1321713226
if let Some(failure_code) = malformed_htlc_failure_code {
13227+
if attribution_data.is_some() {
13228+
return Err(DecodeError::InvalidValue);
13229+
}
1321813230
Self::FailMalformedHTLC {
1321913231
htlc_id: _init_tlv_based_struct_field!(htlc_id, required),
1322013232
failure_code,
@@ -13225,6 +13237,7 @@ impl Readable for HTLCForwardInfo {
1322513237
htlc_id: _init_tlv_based_struct_field!(htlc_id, required),
1322613238
err_packet: crate::ln::msgs::OnionErrorPacket {
1322713239
data: _init_tlv_based_struct_field!(err_packet, required),
13240+
attribution_data: _init_tlv_based_struct_field!(attribution_data, option),
1322813241
},
1322913242
}
1323013243
}
@@ -14910,6 +14923,7 @@ mod tests {
1491014923
use bitcoin::secp256k1::ecdh::SharedSecret;
1491114924
use core::sync::atomic::Ordering;
1491214925
use crate::events::{Event, HTLCDestination, ClosureReason};
14926+
use crate::ln::onion_utils::AttributionData;
1491314927
use crate::ln::types::ChannelId;
1491414928
use crate::types::payment::{PaymentPreimage, PaymentHash, PaymentSecret};
1491514929
use crate::ln::channelmanager::{create_recv_pending_htlc_info, inbound_payment, ChannelConfigOverrides, HTLCForwardInfo, InterceptId, PaymentId, RecipientOnionFields};
@@ -16232,7 +16246,7 @@ mod tests {
1623216246
let mut nodes = create_network(1, &node_cfg, &chanmgrs);
1623316247

1623416248
let dummy_failed_htlc = |htlc_id| {
16235-
HTLCForwardInfo::FailHTLC { htlc_id, err_packet: msgs::OnionErrorPacket { data: vec![42] } }
16249+
HTLCForwardInfo::FailHTLC { htlc_id, err_packet: msgs::OnionErrorPacket { data: vec![42], attribution_data: Some(AttributionData::new()) } }
1623616250
};
1623716251
let dummy_malformed_htlc = |htlc_id| {
1623816252
HTLCForwardInfo::FailMalformedHTLC { htlc_id, failure_code: 0x4000, sha256_of_onion: [0; 32] }

lightning/src/ln/functional_tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7114,6 +7114,7 @@ pub fn test_update_fulfill_htlc_bolt2_update_fail_htlc_before_commitment() {
71147114
channel_id: chan.2,
71157115
htlc_id: 0,
71167116
reason: Vec::new(),
7117+
attribution_data: None,
71177118
};
71187119

71197120
nodes[0].node.handle_update_fail_htlc(nodes[1].node.get_our_node_id(), &update_msg);

lightning/src/ln/msgs.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -766,8 +766,10 @@ pub struct UpdateFailHTLC {
766766
/// The HTLC ID
767767
pub htlc_id: u64,
768768
pub(crate) reason: Vec<u8>,
769-
}
770769

770+
/// Optional field for the attribution data that allows the sender to pinpoint the failing node under all conditions
771+
pub attribution_data: Option<AttributionData>
772+
}
771773
/// An [`update_fail_malformed_htlc`] message to be sent to or received from a peer.
772774
///
773775
/// [`update_fail_malformed_htlc`]: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#removing-an-htlc-update_fulfill_htlc-update_fail_htlc-and-update_fail_malformed_htlc
@@ -2056,6 +2058,7 @@ pub struct FinalOnionHopData {
20562058
mod fuzzy_internal_msgs {
20572059
use bitcoin::secp256k1::PublicKey;
20582060
use crate::blinded_path::payment::{BlindedPaymentPath, PaymentConstraints, PaymentContext, PaymentRelay};
2061+
use crate::ln::onion_utils::AttributionData;
20592062
use crate::offers::invoice_request::InvoiceRequest;
20602063
use crate::types::payment::{PaymentPreimage, PaymentSecret};
20612064
use crate::types::features::{BlindedHopFeatures, Bolt12InvoiceFeatures};
@@ -2249,13 +2252,16 @@ mod fuzzy_internal_msgs {
22492252
// This really should be a constant size slice, but the spec lets these things be up to 128KB?
22502253
// (TODO) We limit it in decode to much lower...
22512254
pub data: Vec<u8>,
2255+
pub attribution_data: Option<AttributionData>,
22522256
}
22532257
}
22542258
#[cfg(fuzzing)]
22552259
pub use self::fuzzy_internal_msgs::*;
22562260
#[cfg(not(fuzzing))]
22572261
pub(crate) use self::fuzzy_internal_msgs::*;
22582262

2263+
use super::onion_utils::AttributionData;
2264+
22592265
/// BOLT 4 onion packet including hop data for the next peer.
22602266
#[derive(Clone, Hash, PartialEq, Eq)]
22612267
pub struct OnionPacket {
@@ -2362,6 +2368,7 @@ impl From<UpdateFailHTLC> for OnionErrorPacket {
23622368
fn from(msg: UpdateFailHTLC) -> Self {
23632369
OnionErrorPacket {
23642370
data: msg.reason,
2371+
attribution_data: msg.attribution_data,
23652372
}
23662373
}
23672374
}
@@ -2984,7 +2991,10 @@ impl_writeable_msg!(UpdateFailHTLC, {
29842991
channel_id,
29852992
htlc_id,
29862993
reason
2987-
}, {});
2994+
}, {
2995+
// Specified TLV key 1 plus 100 during testing phase.
2996+
(101, attribution_data, option)
2997+
});
29882998

29892999
impl_writeable_msg!(UpdateFailMalformedHTLC, {
29903000
channel_id,
@@ -3959,6 +3969,7 @@ impl_writeable_msg!(GossipTimestampFilter, {
39593969
mod tests {
39603970
use bitcoin::{Amount, Transaction, TxIn, ScriptBuf, Sequence, Witness, TxOut};
39613971
use bitcoin::hex::DisplayHex;
3972+
use crate::ln::onion_utils::{AttributionData, HMAC_COUNT, HMAC_LEN, HOLD_TIME_LEN, MAX_HOPS};
39623973
use crate::ln::types::ChannelId;
39633974
use crate::types::payment::{PaymentPreimage, PaymentHash, PaymentSecret};
39643975
use crate::types::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
@@ -4964,10 +4975,14 @@ mod tests {
49644975
let update_fail_htlc = msgs::UpdateFailHTLC {
49654976
channel_id: ChannelId::from_bytes([2; 32]),
49664977
htlc_id: 2316138423780173,
4967-
reason: [1; 32].to_vec()
4978+
reason: [1; 32].to_vec(),
4979+
attribution_data: Some(AttributionData {
4980+
hold_times: [3; MAX_HOPS * HOLD_TIME_LEN],
4981+
hmacs: [3; HMAC_LEN * HMAC_COUNT],
4982+
})
49684983
};
49694984
let encoded_value = update_fail_htlc.encode();
4970-
let target_value = <Vec<u8>>::from_hex("020202020202020202020202020202020202020202020202020202020202020200083a840000034d00200101010101010101010101010101010101010101010101010101010101010101").unwrap();
4985+
let target_value = <Vec<u8>>::from_hex("020202020202020202020202020202020202020202020202020202020202020200083a840000034d0020010101010101010101010101010101010101010101010101010101010101010165fd03980303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303").unwrap();
49714986
assert_eq!(encoded_value, target_value);
49724987
}
49734988

lightning/src/ln/onion_payment.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,7 @@ where
534534
channel_id: msg.channel_id,
535535
htlc_id: msg.htlc_id,
536536
reason: failure.data,
537+
attribution_data: failure.attribution_data,
537538
}));
538539
};
539540

0 commit comments

Comments
 (0)