@@ -366,7 +366,7 @@ fn test_onion_failure() {
366366 let onion_keys = onion_utils:: construct_onion_keys ( & Secp256k1 :: new ( ) , & route. paths [ 0 ] , & session_priv) . unwrap ( ) ;
367367 let recipient_onion_fields = RecipientOnionFields :: spontaneous_empty ( ) ;
368368 let ( mut onion_payloads, _htlc_msat, _htlc_cltv) = onion_utils:: build_onion_payloads (
369- & route. paths [ 0 ] , 40000 , & recipient_onion_fields, cur_height, & None , None ) . unwrap ( ) ;
369+ & route. paths [ 0 ] , 40000 , & recipient_onion_fields, cur_height, & None , None , None ) . unwrap ( ) ;
370370 let mut new_payloads = Vec :: new ( ) ;
371371 for payload in onion_payloads. drain ( ..) {
372372 new_payloads. push ( BogusOnionHopData :: new ( payload) ) ;
@@ -385,7 +385,7 @@ fn test_onion_failure() {
385385 let onion_keys = onion_utils:: construct_onion_keys ( & Secp256k1 :: new ( ) , & route. paths [ 0 ] , & session_priv) . unwrap ( ) ;
386386 let recipient_onion_fields = RecipientOnionFields :: spontaneous_empty ( ) ;
387387 let ( mut onion_payloads, _htlc_msat, _htlc_cltv) = onion_utils:: build_onion_payloads (
388- & route. paths [ 0 ] , 40000 , & recipient_onion_fields, cur_height, & None , None ) . unwrap ( ) ;
388+ & route. paths [ 0 ] , 40000 , & recipient_onion_fields, cur_height, & None , None , None ) . unwrap ( ) ;
389389 let mut new_payloads = Vec :: new ( ) ;
390390 for payload in onion_payloads. drain ( ..) {
391391 new_payloads. push ( BogusOnionHopData :: new ( payload) ) ;
@@ -639,7 +639,7 @@ fn test_onion_failure() {
639639 let onion_keys = onion_utils:: construct_onion_keys ( & Secp256k1 :: new ( ) , & route. paths [ 0 ] , & session_priv) . unwrap ( ) ;
640640 let recipient_onion_fields = RecipientOnionFields :: spontaneous_empty ( ) ;
641641 let ( onion_payloads, _, htlc_cltv) = onion_utils:: build_onion_payloads (
642- & route. paths [ 0 ] , 40000 , & recipient_onion_fields, height, & None , None ) . unwrap ( ) ;
642+ & route. paths [ 0 ] , 40000 , & recipient_onion_fields, height, & None , None , None ) . unwrap ( ) ;
643643 let onion_packet = onion_utils:: construct_onion_packet ( onion_payloads, onion_keys, [ 0 ; 32 ] , & payment_hash) . unwrap ( ) ;
644644 msg. cltv_expiry = htlc_cltv;
645645 msg. onion_routing_packet = onion_packet;
@@ -977,7 +977,7 @@ fn test_always_create_tlv_format_onion_payloads() {
977977 let cur_height = nodes[ 0 ] . best_block_info ( ) . 1 + 1 ;
978978 let recipient_onion_fields = RecipientOnionFields :: spontaneous_empty ( ) ;
979979 let ( onion_payloads, _htlc_msat, _htlc_cltv) = onion_utils:: build_onion_payloads (
980- & route. paths [ 0 ] , 40000 , & recipient_onion_fields, cur_height, & None , None ) . unwrap ( ) ;
980+ & route. paths [ 0 ] , 40000 , & recipient_onion_fields, cur_height, & None , None , None ) . unwrap ( ) ;
981981
982982 match onion_payloads[ 0 ] {
983983 msgs:: OutboundOnionPayload :: Forward { ..} => { } ,
@@ -1014,6 +1014,138 @@ fn test_trampoline_onion_payload_serialization() {
10141014 assert_eq ! ( carol_payload_hex, "2e020405f5e10004030c35000e2102edabbd16b41c8371b92ef2f04c1185b4f03b6dcd52ba9b78d9d7c89c8f221145" ) ;
10151015}
10161016
1017+ #[ test]
1018+ fn test_trampoline_onion_payload_assembly_values ( ) {
1019+ let amt_msat = 150_000_000 ;
1020+ let cur_height = 800_000 ;
1021+
1022+ let path = Path {
1023+ hops : vec ! [
1024+ // Bob
1025+ RouteHop {
1026+ pubkey: PublicKey :: from_slice( & <Vec <u8 >>:: from_hex( "0324653eac434488002cc06bbfb7f10fe18991e35f9fe4302dbea6d2353dc0ab1c" ) . unwrap( ) ) . unwrap( ) ,
1027+ node_features: NodeFeatures :: empty( ) ,
1028+ short_channel_id: 0 ,
1029+ channel_features: ChannelFeatures :: empty( ) ,
1030+ fee_msat: 3000 ,
1031+ cltv_expiry_delta: 24 ,
1032+ maybe_announced_channel: false ,
1033+ } ,
1034+
1035+ // Carol
1036+ RouteHop {
1037+ pubkey: PublicKey :: from_slice( & <Vec <u8 >>:: from_hex( "027f31ebc5462c1fdce1b737ecff52d37d75dea43ce11c74d25aa297165faa2007" ) . unwrap( ) ) . unwrap( ) ,
1038+ node_features: NodeFeatures :: empty( ) ,
1039+ short_channel_id: ( 572330 << 40 ) + ( 42 << 16 ) + 2821 ,
1040+ channel_features: ChannelFeatures :: empty( ) ,
1041+ fee_msat: 150_153_000 ,
1042+ cltv_expiry_delta: 0 ,
1043+ maybe_announced_channel: false ,
1044+ } ,
1045+ ] ,
1046+ trampoline_hops : vec ! [
1047+ // Carol's pubkey
1048+ TrampolineHop {
1049+ pubkey: PublicKey :: from_slice( & <Vec <u8 >>:: from_hex( "027f31ebc5462c1fdce1b737ecff52d37d75dea43ce11c74d25aa297165faa2007" ) . unwrap( ) ) . unwrap( ) ,
1050+ node_features: Features :: empty( ) ,
1051+ fee_msat: 2_500 ,
1052+ cltv_expiry_delta: 24 ,
1053+ } ,
1054+ // Dave's pubkey (the intro node needs to be duplicated)
1055+ TrampolineHop {
1056+ pubkey: PublicKey :: from_slice( & <Vec <u8 >>:: from_hex( "032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991" ) . unwrap( ) ) . unwrap( ) ,
1057+ node_features: Features :: empty( ) ,
1058+ fee_msat: 150_500 ,
1059+ cltv_expiry_delta: 36 ,
1060+ }
1061+ ] ,
1062+ blinded_tail : Some ( BlindedTail {
1063+ hops : vec ! [
1064+ // Dave's blinded node id
1065+ BlindedHop {
1066+ blinded_node_id: PublicKey :: from_slice( & <Vec <u8 >>:: from_hex( "0295d40514096a8be54859e7dfe947b376eaafea8afe5cb4eb2c13ff857ed0b4be" ) . unwrap( ) ) . unwrap( ) ,
1067+ encrypted_payload: vec![ ] ,
1068+ } ,
1069+ // Eve's blinded node id
1070+ BlindedHop {
1071+ blinded_node_id: PublicKey :: from_slice( & <Vec <u8 >>:: from_hex( "020e2dbadcc2005e859819ddebbe88a834ae8a6d2b049233c07335f15cd1dc5f22" ) . unwrap( ) ) . unwrap( ) ,
1072+ encrypted_payload: vec![ ] ,
1073+ }
1074+ ] ,
1075+ blinding_point : PublicKey :: from_slice ( & <Vec < u8 > >:: from_hex ( "02988face71e92c345a068f740191fd8e53be14f0bb957ef730d3c5f76087b960e" ) . unwrap ( ) ) . unwrap ( ) ,
1076+ excess_final_cltv_expiry_delta : 0 ,
1077+ final_value_msat : amt_msat
1078+ } ) ,
1079+ } ;
1080+ assert_eq ! ( path. fee_msat( ) , 156_000 ) ;
1081+ assert_eq ! ( path. final_value_msat( ) , amt_msat) ;
1082+ assert_eq ! ( path. final_cltv_expiry_delta( ) , None ) ;
1083+
1084+ let payment_secret = PaymentSecret ( SecretKey :: from_slice ( & <Vec < u8 > >:: from_hex ( "7494b65bc092b48a75465e43e29be807eb2cc535ce8aaba31012b8ff1ceac5da" ) . unwrap ( ) ) . unwrap ( ) . secret_bytes ( ) ) ;
1085+ let recipient_onion_fields = RecipientOnionFields :: secret_only ( payment_secret) ;
1086+ let ( trampoline_payloads, outer_total_msat, outer_starting_htlc_offset) = onion_utils:: build_trampoline_onion_payloads ( & path, amt_msat, & recipient_onion_fields, cur_height, & None ) . unwrap ( ) ;
1087+ assert_eq ! ( trampoline_payloads. len( ) , 3 ) ;
1088+ assert_eq ! ( outer_total_msat, 150_153_000 ) ;
1089+ assert_eq ! ( outer_starting_htlc_offset, 800_060 ) ;
1090+
1091+ let trampoline_carol_payload = & trampoline_payloads[ 0 ] ;
1092+ let trampoline_dave_payload = & trampoline_payloads[ 1 ] ;
1093+ let trampoline_eve_payload = & trampoline_payloads[ 2 ] ;
1094+ if let OutboundTrampolinePayload :: BlindedReceive { sender_intended_htlc_amt_msat, total_msat, cltv_expiry_height, .. } = trampoline_eve_payload {
1095+ assert_eq ! ( sender_intended_htlc_amt_msat, & 150_000_000 ) ;
1096+ assert_eq ! ( total_msat, & 150_000_000 ) ;
1097+ assert_eq ! ( cltv_expiry_height, & 800_000 ) ;
1098+ } else {
1099+ panic ! ( "Eve Trampoline payload must be BlindedReceive" ) ;
1100+ }
1101+
1102+ if let OutboundTrampolinePayload :: BlindedForward { .. } = trampoline_dave_payload { } else {
1103+ panic ! ( "Dave Trampoline payload must be BlindedForward" ) ;
1104+ }
1105+
1106+ if let OutboundTrampolinePayload :: Forward { amt_to_forward, outgoing_cltv_value, .. } = trampoline_carol_payload {
1107+ assert_eq ! ( amt_to_forward, & 150_150_500 ) ;
1108+ assert_eq ! ( outgoing_cltv_value, & 800_036 ) ;
1109+ } else {
1110+ panic ! ( "Carol Trampoline payload must be Forward" ) ;
1111+ }
1112+
1113+ // all dummy values
1114+ let secp_ctx = Secp256k1 :: new ( ) ;
1115+ let session_priv = SecretKey :: from_slice ( & <Vec < u8 > >:: from_hex ( "a64feb81abd58e473df290e9e1c07dc3e56114495cadf33191f44ba5448ebe99" ) . unwrap ( ) ) . unwrap ( ) ;
1116+ let prng_seed = onion_utils:: gen_pad_from_shared_secret ( & session_priv. secret_bytes ( ) ) ;
1117+ let payment_hash = PaymentHash ( session_priv. secret_bytes ( ) ) ;
1118+
1119+ let onion_keys = construct_trampoline_onion_keys ( & secp_ctx, & path, & session_priv) . unwrap ( ) ;
1120+ let trampoline_packet = construct_trampoline_onion_packet (
1121+ trampoline_payloads,
1122+ onion_keys,
1123+ prng_seed,
1124+ & payment_hash,
1125+ None ,
1126+ ) . unwrap ( ) ;
1127+
1128+ let ( outer_payloads, total_msat, total_htlc_offset) = onion_utils:: build_onion_payloads ( & path, outer_total_msat, & recipient_onion_fields, outer_starting_htlc_offset, & None , None , Some ( trampoline_packet) ) . unwrap ( ) ;
1129+ assert_eq ! ( outer_payloads. len( ) , 2 ) ;
1130+ assert_eq ! ( total_msat, 150_156_000 ) ;
1131+ assert_eq ! ( total_htlc_offset, 800_084 ) ;
1132+
1133+ let outer_bob_payload = & outer_payloads[ 0 ] ;
1134+ let outer_carol_payload = & outer_payloads[ 1 ] ;
1135+ if let OutboundOnionPayload :: TrampolineEntrypoint { amt_to_forward, outgoing_cltv_value, .. } = outer_carol_payload {
1136+ assert_eq ! ( amt_to_forward, & 150_153_000 ) ;
1137+ assert_eq ! ( outgoing_cltv_value, & 800_060 ) ;
1138+ } else {
1139+ panic ! ( "Carol payload must be TrampolineEntrypoint" ) ;
1140+ }
1141+ if let OutboundOnionPayload :: Forward { amt_to_forward, outgoing_cltv_value, .. } = outer_bob_payload {
1142+ assert_eq ! ( amt_to_forward, & 150_153_000 ) ;
1143+ assert_eq ! ( outgoing_cltv_value, & 800_084 ) ;
1144+ } else {
1145+ panic ! ( "Bob payload must be Forward" ) ;
1146+ }
1147+ }
1148+
10171149#[ test]
10181150fn test_trampoline_onion_payload_construction_vectors ( ) {
10191151 // As per https://github.com/lightning/bolts/blob/fa0594ac2af3531d734f1d707a146d6e13679451/bolt04/trampoline-to-blinded-path-payment-onion-test.json#L251
@@ -1378,7 +1510,7 @@ fn test_phantom_invalid_onion_payload() {
13781510 let recipient_onion_fields = RecipientOnionFields :: secret_only ( payment_secret) ;
13791511 let ( mut onion_payloads, _, _) = onion_utils:: build_onion_payloads (
13801512 & route. paths [ 0 ] , msgs:: MAX_VALUE_MSAT + 1 ,
1381- & recipient_onion_fields, height + 1 , & None , None ) . unwrap ( ) ;
1513+ & recipient_onion_fields, height + 1 , & None , None , None ) . unwrap ( ) ;
13821514 // We only want to construct the onion packet for the last hop, not the entire route, so
13831515 // remove the first hop's payload and its keys.
13841516 onion_keys. remove ( 0 ) ;
0 commit comments