Skip to content

Commit 9f48858

Browse files
committed
wip
1 parent db6aa28 commit 9f48858

7 files changed

Lines changed: 46 additions & 19 deletions

File tree

lightning/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ _externalize_tests = ["inventory", "_test_utils"]
2323
# Allow signing of local transactions that may have been revoked or will be revoked, for functional testing (e.g. justice tx handling).
2424
# This is unsafe to use in production because it may result in the counterparty publishing taking our funds.
2525
unsafe_revoked_tx_signing = []
26+
backtrace = []
2627

2728
std = []
2829

@@ -46,7 +47,7 @@ hashbrown = { version = "0.13", default-features = false }
4647
possiblyrandom = { version = "0.2", path = "../possiblyrandom", default-features = false }
4748

4849
regex = { version = "1.5.6", optional = true }
49-
backtrace = { version = "0.3", optional = true }
50+
backtrace = { version = "0.3"}
5051

5152
libm = { version = "0.2", default-features = false }
5253
inventory = { version = "0.3", optional = true }

lightning/src/ln/blinded_payment_tests.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1857,7 +1857,7 @@ fn test_combined_trampoline_onion_creation_vectors() {
18571857
short_channel_id: (572330 << 40) + (42 << 16) + 2821,
18581858
channel_features: ChannelFeatures::empty(),
18591859
fee_msat: 153_000,
1860-
cltv_expiry_delta: 0,
1860+
cltv_expiry_delta: 24 + 36,
18611861
maybe_announced_channel: false,
18621862
},
18631863
],
@@ -1952,7 +1952,7 @@ fn test_trampoline_inbound_payment_decoding() {
19521952
short_channel_id: (572330 << 40) + (42 << 16) + 2821,
19531953
channel_features: ChannelFeatures::empty(),
19541954
fee_msat: 150_153_000,
1955-
cltv_expiry_delta: 0,
1955+
cltv_expiry_delta: 24 + 36,
19561956
maybe_announced_channel: false,
19571957
},
19581958
],
@@ -2120,7 +2120,7 @@ fn test_trampoline_forward_payload_encoded_as_receive() {
21202120
blinded_path::utils::construct_blinded_hops(
21212121
&secp_ctx, path.into_iter(), &trampoline_session_priv,
21222122
)
2123-
};
2123+
};
21242124

21252125
let route = Route {
21262126
paths: vec![Path {
@@ -2143,7 +2143,7 @@ fn test_trampoline_forward_payload_encoded_as_receive() {
21432143
short_channel_id: bob_carol_scid,
21442144
channel_features: ChannelFeatures::empty(),
21452145
fee_msat: 0,
2146-
cltv_expiry_delta: 48,
2146+
cltv_expiry_delta: 24 + 39,
21472147
maybe_announced_channel: false,
21482148
}
21492149
],
@@ -2309,7 +2309,7 @@ fn do_test_trampoline_single_hop_receive(success: bool) {
23092309
short_channel_id: bob_carol_scid,
23102310
channel_features: ChannelFeatures::empty(),
23112311
fee_msat: 0,
2312-
cltv_expiry_delta: 48,
2312+
cltv_expiry_delta: 104 + 39,
23132313
maybe_announced_channel: false,
23142314
}
23152315
],
@@ -2797,7 +2797,7 @@ fn test_trampoline_forward_rejection() {
27972797
short_channel_id: bob_carol_scid,
27982798
channel_features: ChannelFeatures::empty(),
27992799
fee_msat: 0,
2800-
cltv_expiry_delta: 48,
2800+
cltv_expiry_delta: 24 + 24 + 39,
28012801
maybe_announced_channel: false,
28022802
}
28032803
],

lightning/src/ln/htlc_reserve_unit_tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,6 +1421,7 @@ pub fn test_update_add_htlc_bolt2_sender_cltv_expiry_too_high() {
14211421
.unwrap();
14221422
let (mut route, our_payment_hash, _, our_payment_secret) =
14231423
get_route_and_payment_hash!(nodes[0], nodes[1], payment_params, 100000000);
1424+
route.route_params.as_mut().unwrap().payment_params.max_total_cltv_expiry_delta = 500000001;
14241425
route.paths[0].hops.last_mut().unwrap().cltv_expiry_delta = 500000001;
14251426

14261427
let onion = RecipientOnionFields::secret_only(our_payment_secret, 100000000);

lightning/src/ln/onion_payment.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ fn check_trampoline_payment_constraints(
7777
trampoline_amount: u64,
7878
) -> Result<(), InboundHTLCErr> {
7979
if outer_hop_data.outgoing_cltv_value < trampoline_cltv_value {
80+
eprintln!("\n\n{} < {}\n", outer_hop_data.outgoing_cltv_value, trampoline_cltv_value);
8081
return Err(InboundHTLCErr {
8182
reason: LocalHTLCFailureReason::FinalIncorrectCLTVExpiry,
8283
err_data: outer_hop_data.outgoing_cltv_value.to_be_bytes().to_vec(),

lightning/src/ln/onion_route_tests.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1918,7 +1918,7 @@ fn test_trampoline_onion_payload_assembly_values() {
19181918
short_channel_id: (572330 << 40) + (42 << 16) + 2821,
19191919
channel_features: ChannelFeatures::empty(),
19201920
fee_msat: 153_000,
1921-
cltv_expiry_delta: 0,
1921+
cltv_expiry_delta: 36 + 24, // Last hop should include the CLTV of the trampoline hops
19221922
maybe_announced_channel: false,
19231923
},
19241924
],
@@ -1974,7 +1974,7 @@ fn test_trampoline_onion_payload_assembly_values() {
19741974
SecretKey::from_slice(&<Vec<u8>>::from_hex(SECRET_HEX).unwrap()).unwrap().secret_bytes(),
19751975
);
19761976
let recipient_onion_fields = RecipientOnionFields::secret_only(payment_secret, amt_msat);
1977-
let (trampoline_payloads, outer_total_msat, outer_starting_htlc_offset) =
1977+
let (trampoline_payloads, outer_total_msat, outer_starting_htlc) =
19781978
onion_utils::build_trampoline_onion_payloads(
19791979
&path.blinded_tail.as_ref().unwrap(),
19801980
&recipient_onion_fields,
@@ -1984,7 +1984,7 @@ fn test_trampoline_onion_payload_assembly_values() {
19841984
.unwrap();
19851985
assert_eq!(trampoline_payloads.len(), 3);
19861986
assert_eq!(outer_total_msat, 150_153_000);
1987-
assert_eq!(outer_starting_htlc_offset, 800_060);
1987+
assert_eq!(outer_starting_htlc, 800_060);
19881988

19891989
let trampoline_carol_payload = &trampoline_payloads[0];
19901990
let trampoline_dave_payload = &trampoline_payloads[1];
@@ -2042,7 +2042,7 @@ fn test_trampoline_onion_payload_assembly_values() {
20422042
let (outer_payloads, total_msat, total_htlc_offset) = test_build_onion_payloads(
20432043
&path,
20442044
&recipient_onion_fields,
2045-
outer_starting_htlc_offset,
2045+
cur_height,
20462046
&None,
20472047
None,
20482048
Some(trampoline_packet),

lightning/src/ln/onion_utils.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ impl<'a> PathHop for &'a RouteHop {
158158
}
159159

160160
fn cltv_expiry_delta(&self) -> u32 {
161+
eprintln!("cltv for hop is {}", self.cltv_expiry_delta);
161162
self.cltv_expiry_delta
162163
}
163164
}
@@ -180,6 +181,7 @@ impl<'a> PathHop for &'a TrampolineHop {
180181
}
181182

182183
fn cltv_expiry_delta(&self) -> u32 {
184+
eprintln!("trampoline hop cltv is {}", self.cltv_expiry_delta);
183185
self.cltv_expiry_delta
184186
}
185187
}
@@ -532,18 +534,16 @@ where
532534
{
533535
let mut cur_value_msat = 0u64;
534536
let mut cur_cltv = starting_htlc_offset;
537+
eprintln!("\n{:?}init'd cltv to {starting_htlc_offset}", ::backtrace::Backtrace::new());
535538
let mut last_hop_id = None;
536539

537540
for (idx, hop) in hops.rev().enumerate() {
541+
eprintln!("\nloop idx {idx}. starting cltv {cur_cltv}");
538542
// First hop gets special values so that it can check, on receipt, that everything is
539543
// exactly as it should be (and the next hop isn't trying to probe to find out if we're
540544
// the intended recipient).
541545
let value_msat = if cur_value_msat == 0 { hop.fee_msat() } else { cur_value_msat };
542-
let cltv = if cur_cltv == starting_htlc_offset {
543-
hop.cltv_expiry_delta().saturating_add(starting_htlc_offset)
544-
} else {
545-
cur_cltv
546-
};
546+
let cltv = hop.cltv_expiry_delta().saturating_add(starting_htlc_offset);
547547
if idx == 0 {
548548
match blinded_tail.take() {
549549
Some(BlindedTailDetails::DirectEntry {
@@ -553,6 +553,7 @@ where
553553
excess_final_cltv_expiry_delta,
554554
..
555555
}) => {
556+
eprintln!("first hop is bp");
556557
let mut blinding_point = Some(blinding_point);
557558
let hops_len = hops.len();
558559
for (i, blinded_hop) in hops.enumerate() {
@@ -586,18 +587,20 @@ where
586587
trampoline_packet,
587588
final_value_msat,
588589
}) => {
590+
eprintln!("first hop is tramp");
589591
cur_value_msat += final_value_msat;
590592
callback(
591593
PayloadCallbackAction::PushBack,
592594
OP::new_trampoline_entry(
593595
final_value_msat + hop.fee_msat(),
594-
cur_cltv,
596+
cltv,
595597
&recipient_onion,
596598
trampoline_packet,
597599
)?,
598600
);
599601
},
600602
None => {
603+
eprintln!("pushing regular first hop with cltv {cltv}");
601604
callback(
602605
PayloadCallbackAction::PushBack,
603606
OP::new_receive(&recipient_onion, *keysend_preimage, value_msat, cltv)?,
@@ -610,14 +613,15 @@ where
610613
err: "Next hop ID must be known for non-final hops".to_string(),
611614
})?,
612615
value_msat,
613-
cltv,
616+
cur_cltv,
614617
);
615618
callback(PayloadCallbackAction::PushFront, payload);
616619
}
617620
cur_value_msat += hop.fee_msat();
618621
if cur_value_msat >= 21000000 * 100000000 * 1000 {
619622
return Err(APIError::InvalidRoute { err: "Channel fees overflowed?".to_owned() });
620623
}
624+
eprintln!("cur cltv added {}", hop.cltv_expiry_delta());
621625
cur_cltv = cur_cltv.saturating_add(hop.cltv_expiry_delta() as u32);
622626
if cur_cltv >= 500000000 {
623627
return Err(APIError::InvalidRoute { err: "Channel CLTV overflowed?".to_owned() });
@@ -2652,6 +2656,7 @@ pub(crate) fn create_payment_onion_internal<T: secp256k1::Signing>(
26522656
if !blinded_tail.trampoline_hops.is_empty() {
26532657
let trampoline_payloads;
26542658
let outer_total_msat;
2659+
eprintln!("building trampoline onion.......");
26552660
(trampoline_payloads, outer_total_msat, outer_starting_htlc_offset) =
26562661
build_trampoline_onion_payloads(
26572662
&blinded_tail,
@@ -2683,14 +2688,16 @@ pub(crate) fn create_payment_onion_internal<T: secp256k1::Signing>(
26832688
}
26842689
}
26852690

2691+
eprintln!("building real onion.......");
26862692
let (onion_payloads, htlc_msat, htlc_cltv) = build_onion_payloads(
26872693
&path,
26882694
outer_onion,
2689-
outer_starting_htlc_offset,
2695+
cur_block_height,
26902696
keysend_preimage,
26912697
invoice_request,
26922698
trampoline_packet_option,
26932699
)?;
2700+
debug_assert_eq!(htlc_cltv - cur_block_height, path.total_cltv_expiry_delta());
26942701

26952702
let onion_keys = construct_onion_keys(&secp_ctx, &path, session_priv);
26962703
let onion_packet = construct_onion_packet(onion_payloads, onion_keys, prng_seed, payment_hash)

lightning/src/routing/router.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,12 @@ impl Path {
642642
}
643643
}
644644

645+
/// Gets the total CLTV expiry delta which will be added to the current block height (plus some
646+
/// extra headroom) when sending the HTLC
647+
pub fn total_cltv_expiry_delta(&self) -> u32 {
648+
self.hops.iter().map(|hop| hop.cltv_expiry_delta).sum()
649+
}
650+
645651
/// True if this [`Path`] has at least one Trampoline hop.
646652
pub fn has_trampoline_hops(&self) -> bool {
647653
self.blinded_tail.as_ref().is_some_and(|bt| !bt.trampoline_hops.is_empty())
@@ -731,6 +737,17 @@ impl Route {
731737
return Err(());
732738
}
733739

740+
let total_cltv_delta = path.total_cltv_expiry_delta();
741+
if total_cltv_delta > route_params.payment_params.max_total_cltv_expiry_delta {
742+
let err = format!(
743+
"Path had a total CLTV of {total_cltv_delta} which is greater than the maximum we're allowed {}",
744+
route_params.payment_params.max_total_cltv_expiry_delta,
745+
);
746+
debug_assert!(false, "{}", err);
747+
log_error!(logger, "{}", err);
748+
return Err(());
749+
}
750+
734751
if path.hops.len() > route_params.payment_params.max_path_length.into() {
735752
let err = format!(
736753
"Path had a length of {}, which is greater than the maximum we're allowed ({})",

0 commit comments

Comments
 (0)