Skip to content

Commit beef584

Browse files
authoredMar 27, 2024
Merge pull request #2906 from arik-so/arik/trampoline/2024-02-trampoline-onion-construction-vectors
Trampoline onion construction vectors
2 parents 68d5e88 + 52039a2 commit beef584

File tree

3 files changed

+68
-3
lines changed

3 files changed

+68
-3
lines changed
 

‎lightning/src/ln/msgs.rs

+28-1
Original file line numberDiff line numberDiff line change
@@ -1740,6 +1740,17 @@ mod fuzzy_internal_msgs {
17401740
}
17411741
}
17421742

1743+
pub(crate) enum OutboundTrampolinePayload {
1744+
#[allow(unused)]
1745+
Forward {
1746+
/// The value, in msat, of the payment after this hop's fee is deducted.
1747+
amt_to_forward: u64,
1748+
outgoing_cltv_value: u32,
1749+
/// The node id to which the trampoline node must find a route
1750+
outgoing_node_id: PublicKey,
1751+
}
1752+
}
1753+
17431754
pub struct DecodedOnionErrorPacket {
17441755
pub(crate) hmac: [u8; 32],
17451756
pub(crate) failuremsg: Vec<u8>,
@@ -1798,7 +1809,7 @@ pub struct TrampolineOnionPacket {
17981809
// Unlike the onion packets used for payments, Trampoline onion packets have to be shorter than
17991810
// 1300 bytes. The expected default is 650 bytes.
18001811
// TODO: if 650 ends up being the most common size, optimize this to be:
1801-
// enum { ThirteenHundred([u8; 650]), VarLen(Vec<u8>) }
1812+
// enum { SixFifty([u8; 650]), VarLen(Vec<u8>) }
18021813
pub hop_data: Vec<u8>,
18031814
/// HMAC to verify the integrity of hop_data
18041815
pub hmac: [u8; 32],
@@ -2597,6 +2608,22 @@ impl Writeable for OutboundOnionPayload {
25972608
}
25982609
}
25992610

2611+
impl Writeable for OutboundTrampolinePayload {
2612+
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
2613+
match self {
2614+
Self::Forward { amt_to_forward, outgoing_cltv_value, outgoing_node_id } => {
2615+
_encode_varint_length_prefixed_tlv!(w, {
2616+
(2, HighZeroBytesDroppedBigSize(*amt_to_forward), required),
2617+
(4, HighZeroBytesDroppedBigSize(*outgoing_cltv_value), required),
2618+
(14, outgoing_node_id, required)
2619+
});
2620+
}
2621+
}
2622+
Ok(())
2623+
}
2624+
}
2625+
2626+
26002627
impl<NS: Deref> ReadableArgs<(Option<PublicKey>, &NS)> for InboundOnionPayload where NS::Target: NodeSigner {
26012628
fn read<R: Read>(r: &mut R, args: (Option<PublicKey>, &NS)) -> Result<Self, DecodeError> {
26022629
let (update_add_blinding_point, node_signer) = args;

‎lightning/src/ln/onion_route_tests.rs

+22-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::routing::gossip::{NetworkUpdate, RoutingFees};
2222
use crate::routing::router::{get_route, PaymentParameters, Route, RouteParameters, RouteHint, RouteHintHop};
2323
use crate::ln::features::{InitFeatures, Bolt11InvoiceFeatures};
2424
use crate::ln::msgs;
25-
use crate::ln::msgs::{ChannelMessageHandler, ChannelUpdate};
25+
use crate::ln::msgs::{ChannelMessageHandler, ChannelUpdate, OutboundTrampolinePayload};
2626
use crate::ln::wire::Encode;
2727
use crate::util::ser::{Writeable, Writer, BigSize};
2828
use crate::util::test_utils;
@@ -35,11 +35,12 @@ use bitcoin::hashes::hmac::{Hmac, HmacEngine};
3535
use bitcoin::hashes::sha256::Hash as Sha256;
3636

3737
use bitcoin::secp256k1;
38-
use bitcoin::secp256k1::{Secp256k1, SecretKey};
38+
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
3939

4040
use crate::io;
4141
use crate::prelude::*;
4242
use core::default::Default;
43+
use bitcoin::hashes::hex::FromHex;
4344

4445
use crate::ln::functional_test_utils::*;
4546

@@ -966,6 +967,25 @@ fn test_always_create_tlv_format_onion_payloads() {
966967
}
967968
}
968969

970+
#[test]
971+
fn test_trampoline_onion_payload_serialization() {
972+
// As per https://github.com/lightning/bolts/blob/c01d2e6267d4a8d1095f0f1188970055a9a22d29/bolt04/trampoline-payment-onion-test.json#L3
973+
let trampoline_payload = OutboundTrampolinePayload::Forward {
974+
amt_to_forward: 100000000,
975+
outgoing_cltv_value: 800000,
976+
outgoing_node_id: PublicKey::from_slice(&<Vec<u8>>::from_hex("02edabbd16b41c8371b92ef2f04c1185b4f03b6dcd52ba9b78d9d7c89c8f221145").unwrap()).unwrap(),
977+
};
978+
979+
let slice_to_hex = |slice: &[u8]| {
980+
slice.iter()
981+
.map(|b| format!("{:02x}", b).to_string())
982+
.collect::<String>()
983+
};
984+
985+
let carol_payload_hex = slice_to_hex(&trampoline_payload.encode());
986+
assert_eq!(carol_payload_hex, "2e020405f5e10004030c35000e2102edabbd16b41c8371b92ef2f04c1185b4f03b6dcd52ba9b78d9d7c89c8f221145");
987+
}
988+
969989
fn do_test_fail_htlc_backwards_with_reason(failure_code: FailureCode) {
970990

971991
let chanmon_cfgs = create_chanmon_cfgs(2);

‎lightning/src/ln/onion_utils.rs

+18
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,24 @@ pub(super) fn construct_onion_packet(
291291
)
292292
}
293293

294+
#[allow(unused)]
295+
pub(super) fn construct_trampoline_onion_packet(
296+
payloads: Vec<msgs::OutboundTrampolinePayload>, onion_keys: Vec<OnionKeys>,
297+
prng_seed: [u8; 32], associated_data: &PaymentHash, length: u16,
298+
) -> Result<msgs::TrampolineOnionPacket, ()> {
299+
let mut packet_data = vec![0u8; length as usize];
300+
301+
let mut chacha = ChaCha20::new(&prng_seed, &[0; 8]);
302+
chacha.process(&vec![0u8; length as usize], &mut packet_data);
303+
304+
construct_onion_packet_with_init_noise::<_, _>(
305+
payloads,
306+
onion_keys,
307+
packet_data,
308+
Some(associated_data),
309+
)
310+
}
311+
294312
#[cfg(test)]
295313
/// Used in testing to write bogus `BogusOnionHopData` as well as `RawOnionHopData`, which is
296314
/// otherwise not representable in `msgs::OnionHopData`.

0 commit comments

Comments
 (0)