@@ -111,6 +111,7 @@ use crate::ln::script::ShutdownScript;
111
111
112
112
/// Information about where a received HTLC('s onion) has indicated the HTLC should go.
113
113
#[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
114
+ #[cfg_attr(test, derive(Debug, PartialEq))]
114
115
pub enum PendingHTLCRouting {
115
116
/// An HTLC which should be forwarded on to another node.
116
117
Forward {
@@ -189,7 +190,7 @@ pub enum PendingHTLCRouting {
189
190
}
190
191
191
192
/// Information used to forward or fail this HTLC that is being forwarded within a blinded path.
192
- #[derive(Clone, Copy, Hash, PartialEq, Eq)]
193
+ #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
193
194
pub struct BlindedForward {
194
195
/// The `blinding_point` that was set in the inbound [`msgs::UpdateAddHTLC`], or in the inbound
195
196
/// onion payload if we're the introduction node. Useful for calculating the next hop's
@@ -213,6 +214,7 @@ impl PendingHTLCRouting {
213
214
/// Information about an incoming HTLC, including the [`PendingHTLCRouting`] describing where it
214
215
/// should go next.
215
216
#[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
217
+ #[cfg_attr(test, derive(Debug, PartialEq))]
216
218
pub struct PendingHTLCInfo {
217
219
/// Further routing details based on whether the HTLC is being forwarded or received.
218
220
pub routing: PendingHTLCRouting,
@@ -267,6 +269,7 @@ pub(super) enum PendingHTLCStatus {
267
269
Fail(HTLCFailureMsg),
268
270
}
269
271
272
+ #[cfg_attr(test, derive(Clone, Debug, PartialEq))]
270
273
pub(super) struct PendingAddHTLCInfo {
271
274
pub(super) forward_info: PendingHTLCInfo,
272
275
@@ -282,6 +285,7 @@ pub(super) struct PendingAddHTLCInfo {
282
285
prev_user_channel_id: u128,
283
286
}
284
287
288
+ #[cfg_attr(test, derive(Clone, Debug, PartialEq))]
285
289
pub(super) enum HTLCForwardInfo {
286
290
AddHTLC(PendingAddHTLCInfo),
287
291
FailHTLC {
@@ -11064,12 +11068,14 @@ mod tests {
11064
11068
use crate::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, ClosureReason};
11065
11069
use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
11066
11070
use crate::ln::ChannelId;
11067
- use crate::ln::channelmanager::{create_recv_pending_htlc_info, inbound_payment, PaymentId, PaymentSendFailure, RecipientOnionFields, InterceptId};
11071
+ use crate::ln::channelmanager::{create_recv_pending_htlc_info, HTLCForwardInfo, inbound_payment, PaymentId, PaymentSendFailure, RecipientOnionFields, InterceptId};
11068
11072
use crate::ln::functional_test_utils::*;
11069
11073
use crate::ln::msgs::{self, ErrorAction};
11070
11074
use crate::ln::msgs::ChannelMessageHandler;
11075
+ use crate::prelude::*;
11071
11076
use crate::routing::router::{PaymentParameters, RouteParameters, find_route};
11072
11077
use crate::util::errors::APIError;
11078
+ use crate::util::ser::Writeable;
11073
11079
use crate::util::test_utils;
11074
11080
use crate::util::config::{ChannelConfig, ChannelConfigUpdate};
11075
11081
use crate::sign::EntropySource;
@@ -12344,6 +12350,69 @@ mod tests {
12344
12350
check_spends!(txn[0], funding_tx);
12345
12351
}
12346
12352
}
12353
+
12354
+ #[test]
12355
+ fn test_malformed_forward_htlcs_ser() {
12356
+ // Ensure that `HTLCForwardInfo::FailMalformedHTLC`s are (de)serialized properly.
12357
+ let chanmon_cfg = create_chanmon_cfgs(1);
12358
+ let node_cfg = create_node_cfgs(1, &chanmon_cfg);
12359
+ let persister;
12360
+ let chain_monitor;
12361
+ let chanmgrs = create_node_chanmgrs(1, &node_cfg, &[None]);
12362
+ let deserialized_chanmgr;
12363
+ let mut nodes = create_network(1, &node_cfg, &chanmgrs);
12364
+
12365
+ let dummy_failed_htlc = HTLCForwardInfo::FailHTLC {
12366
+ htlc_id: 0, err_packet: msgs::OnionErrorPacket { data: vec![0] },
12367
+ };
12368
+
12369
+ let dummy_malformed_htlc = HTLCForwardInfo::FailMalformedHTLC {
12370
+ htlc_id: 0, failure_code: 0x4000, sha256_of_onion: [0; 32]
12371
+ };
12372
+
12373
+ let dummy_htlcs_1 = vec![
12374
+ dummy_failed_htlc.clone(), dummy_failed_htlc.clone(), dummy_malformed_htlc.clone(),
12375
+ dummy_malformed_htlc.clone(), dummy_failed_htlc.clone(), dummy_malformed_htlc.clone()
12376
+ ];
12377
+ let dummy_htlcs_2 = vec![
12378
+ dummy_malformed_htlc.clone(), dummy_failed_htlc.clone(), dummy_malformed_htlc.clone(),
12379
+ dummy_failed_htlc.clone()
12380
+ ];
12381
+
12382
+ let (scid_1, scid_2) = (42, 43);
12383
+ let mut forward_htlcs = HashMap::new();
12384
+ forward_htlcs.insert(scid_1, dummy_htlcs_1.clone());
12385
+ forward_htlcs.insert(scid_2, dummy_htlcs_2.clone());
12386
+
12387
+ let mut chanmgr_fwd_htlcs = nodes[0].node.forward_htlcs.lock().unwrap();
12388
+ *chanmgr_fwd_htlcs = forward_htlcs.clone();
12389
+ core::mem::drop(chanmgr_fwd_htlcs);
12390
+
12391
+ reload_node!(nodes[0], nodes[0].node.encode(), &[], persister, chain_monitor, deserialized_chanmgr);
12392
+
12393
+ // As part of maintaining support for downgrades, malformed HTLCs are serialized in TLVs and
12394
+ // thus will be shuffled to the end in `forward_htlcs` on read.
12395
+ let sort_htlcs: fn(&HTLCForwardInfo, &HTLCForwardInfo) -> _ = |a, b| {
12396
+ let a_is_malformed = if let HTLCForwardInfo::FailMalformedHTLC { .. } = a { true } else { false };
12397
+ let b_is_malformed = if let HTLCForwardInfo::FailMalformedHTLC { .. } = b { true } else { false };
12398
+ if a_is_malformed && !b_is_malformed { return core::cmp::Ordering::Greater }
12399
+ else if !a_is_malformed && b_is_malformed { return core::cmp::Ordering::Less }
12400
+ core::cmp::Ordering::Equal
12401
+ };
12402
+ for htlcs in forward_htlcs.values_mut() {
12403
+ htlcs.sort_by(sort_htlcs);
12404
+ }
12405
+
12406
+ let mut deserialized_fwd_htlcs = nodes[0].node.forward_htlcs.lock().unwrap();
12407
+ for scid in [scid_1, scid_2].iter() {
12408
+ let deserialized_htlcs = deserialized_fwd_htlcs.remove(scid).unwrap();
12409
+ assert_eq!(forward_htlcs.remove(scid).unwrap(), deserialized_htlcs);
12410
+ }
12411
+ assert!(deserialized_fwd_htlcs.is_empty());
12412
+ core::mem::drop(deserialized_fwd_htlcs);
12413
+
12414
+ expect_pending_htlcs_forwardable!(nodes[0]);
12415
+ }
12347
12416
}
12348
12417
12349
12418
#[cfg(ldk_bench)]
0 commit comments