@@ -1764,7 +1764,10 @@ fn decode_next_hop<T, R: ReadableArgs<T>, N: NextPacketBytes>(
17641764
17651765#[ cfg( test) ]
17661766mod tests {
1767+ use std:: sync:: Arc ;
1768+
17671769 use crate :: io;
1770+ use crate :: ln:: channelmanager:: PaymentId ;
17681771 use crate :: ln:: msgs;
17691772 use crate :: routing:: router:: { Path , PaymentParameters , Route , RouteHop } ;
17701773 use crate :: types:: features:: { ChannelFeatures , NodeFeatures } ;
@@ -1773,6 +1776,7 @@ mod tests {
17731776
17741777 #[ allow( unused_imports) ]
17751778 use crate :: prelude:: * ;
1779+ use crate :: util:: test_utils:: TestLogger ;
17761780
17771781 use bitcoin:: hex:: FromHex ;
17781782 use bitcoin:: secp256k1:: Secp256k1 ;
@@ -1785,40 +1789,95 @@ mod tests {
17851789 SecretKey :: from_slice ( & <Vec < u8 > >:: from_hex ( hex) . unwrap ( ) [ ..] ) . unwrap ( )
17861790 }
17871791
1792+ fn build_test_path ( ) -> Path {
1793+ Path {
1794+ hops : vec ! [
1795+ RouteHop {
1796+ pubkey: PublicKey :: from_slice(
1797+ & <Vec <u8 >>:: from_hex(
1798+ "02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619" ,
1799+ )
1800+ . unwrap( ) [ ..] ,
1801+ )
1802+ . unwrap( ) ,
1803+ channel_features: ChannelFeatures :: empty( ) ,
1804+ node_features: NodeFeatures :: empty( ) ,
1805+ short_channel_id: 0 ,
1806+ fee_msat: 0 ,
1807+ cltv_expiry_delta: 0 ,
1808+ maybe_announced_channel: true , // We fill in the payloads manually instead of generating them from RouteHops.
1809+ } ,
1810+ RouteHop {
1811+ pubkey: PublicKey :: from_slice(
1812+ & <Vec <u8 >>:: from_hex(
1813+ "0324653eac434488002cc06bbfb7f10fe18991e35f9fe4302dbea6d2353dc0ab1c" ,
1814+ )
1815+ . unwrap( ) [ ..] ,
1816+ )
1817+ . unwrap( ) ,
1818+ channel_features: ChannelFeatures :: empty( ) ,
1819+ node_features: NodeFeatures :: empty( ) ,
1820+ short_channel_id: 1 ,
1821+ fee_msat: 0 ,
1822+ cltv_expiry_delta: 0 ,
1823+ maybe_announced_channel: true , // We fill in the payloads manually instead of generating them from RouteHops.
1824+ } ,
1825+ RouteHop {
1826+ pubkey: PublicKey :: from_slice(
1827+ & <Vec <u8 >>:: from_hex(
1828+ "027f31ebc5462c1fdce1b737ecff52d37d75dea43ce11c74d25aa297165faa2007" ,
1829+ )
1830+ . unwrap( ) [ ..] ,
1831+ )
1832+ . unwrap( ) ,
1833+ channel_features: ChannelFeatures :: empty( ) ,
1834+ node_features: NodeFeatures :: empty( ) ,
1835+ short_channel_id: 2 ,
1836+ fee_msat: 0 ,
1837+ cltv_expiry_delta: 0 ,
1838+ maybe_announced_channel: true , // We fill in the payloads manually instead of generating them from RouteHops.
1839+ } ,
1840+ RouteHop {
1841+ pubkey: PublicKey :: from_slice(
1842+ & <Vec <u8 >>:: from_hex(
1843+ "032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991" ,
1844+ )
1845+ . unwrap( ) [ ..] ,
1846+ )
1847+ . unwrap( ) ,
1848+ channel_features: ChannelFeatures :: empty( ) ,
1849+ node_features: NodeFeatures :: empty( ) ,
1850+ short_channel_id: 3 ,
1851+ fee_msat: 0 ,
1852+ cltv_expiry_delta: 0 ,
1853+ maybe_announced_channel: true , // We fill in the payloads manually instead of generating them from RouteHops.
1854+ } ,
1855+ RouteHop {
1856+ pubkey: PublicKey :: from_slice(
1857+ & <Vec <u8 >>:: from_hex(
1858+ "02edabbd16b41c8371b92ef2f04c1185b4f03b6dcd52ba9b78d9d7c89c8f221145" ,
1859+ )
1860+ . unwrap( ) [ ..] ,
1861+ )
1862+ . unwrap( ) ,
1863+ channel_features: ChannelFeatures :: empty( ) ,
1864+ node_features: NodeFeatures :: empty( ) ,
1865+ short_channel_id: 4 ,
1866+ fee_msat: 0 ,
1867+ cltv_expiry_delta: 0 ,
1868+ maybe_announced_channel: true , // We fill in the payloads manually instead of generating them from RouteHops.
1869+ } ,
1870+ ] ,
1871+ blinded_tail : None ,
1872+ }
1873+ }
1874+
17881875 fn build_test_onion_keys ( ) -> Vec < OnionKeys > {
17891876 // Keys from BOLT 4, used in both test vector tests
17901877 let secp_ctx = Secp256k1 :: new ( ) ;
17911878
1792- let route = Route {
1793- paths : vec ! [ Path { hops: vec![
1794- RouteHop {
1795- pubkey: PublicKey :: from_slice( & <Vec <u8 >>:: from_hex( "02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619" ) . unwrap( ) [ ..] ) . unwrap( ) ,
1796- channel_features: ChannelFeatures :: empty( ) , node_features: NodeFeatures :: empty( ) ,
1797- short_channel_id: 0 , fee_msat: 0 , cltv_expiry_delta: 0 , maybe_announced_channel: true , // We fill in the payloads manually instead of generating them from RouteHops.
1798- } ,
1799- RouteHop {
1800- pubkey: PublicKey :: from_slice( & <Vec <u8 >>:: from_hex( "0324653eac434488002cc06bbfb7f10fe18991e35f9fe4302dbea6d2353dc0ab1c" ) . unwrap( ) [ ..] ) . unwrap( ) ,
1801- channel_features: ChannelFeatures :: empty( ) , node_features: NodeFeatures :: empty( ) ,
1802- short_channel_id: 0 , fee_msat: 0 , cltv_expiry_delta: 0 , maybe_announced_channel: true , // We fill in the payloads manually instead of generating them from RouteHops.
1803- } ,
1804- RouteHop {
1805- pubkey: PublicKey :: from_slice( & <Vec <u8 >>:: from_hex( "027f31ebc5462c1fdce1b737ecff52d37d75dea43ce11c74d25aa297165faa2007" ) . unwrap( ) [ ..] ) . unwrap( ) ,
1806- channel_features: ChannelFeatures :: empty( ) , node_features: NodeFeatures :: empty( ) ,
1807- short_channel_id: 0 , fee_msat: 0 , cltv_expiry_delta: 0 , maybe_announced_channel: true , // We fill in the payloads manually instead of generating them from RouteHops.
1808- } ,
1809- RouteHop {
1810- pubkey: PublicKey :: from_slice( & <Vec <u8 >>:: from_hex( "032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991" ) . unwrap( ) [ ..] ) . unwrap( ) ,
1811- channel_features: ChannelFeatures :: empty( ) , node_features: NodeFeatures :: empty( ) ,
1812- short_channel_id: 0 , fee_msat: 0 , cltv_expiry_delta: 0 , maybe_announced_channel: true , // We fill in the payloads manually instead of generating them from RouteHops.
1813- } ,
1814- RouteHop {
1815- pubkey: PublicKey :: from_slice( & <Vec <u8 >>:: from_hex( "02edabbd16b41c8371b92ef2f04c1185b4f03b6dcd52ba9b78d9d7c89c8f221145" ) . unwrap( ) [ ..] ) . unwrap( ) ,
1816- channel_features: ChannelFeatures :: empty( ) , node_features: NodeFeatures :: empty( ) ,
1817- short_channel_id: 0 , fee_msat: 0 , cltv_expiry_delta: 0 , maybe_announced_channel: true , // We fill in the payloads manually instead of generating them from RouteHops.
1818- } ,
1819- ] , blinded_tail: None } ] ,
1820- route_params : None ,
1821- } ;
1879+ let path = build_test_path ( ) ;
1880+ let route = Route { paths : vec ! [ path] , route_params : None } ;
18221881
18231882 let onion_keys =
18241883 super :: construct_onion_keys ( & secp_ctx, & route. paths [ 0 ] , & get_test_session_key ( ) )
@@ -2078,6 +2137,22 @@ mod tests {
20782137 ) ;
20792138 let hex = "9c5add3963fc7f6ed7f148623c84134b5647e1306419dbe2174e523fa9e2fbed3a06a19f899145610741c83ad40b7712aefaddec8c6baf7325d92ea4ca4d1df8bce517f7e54554608bf2bd8071a4f52a7a2f7ffbb1413edad81eeea5785aa9d990f2865dc23b4bc3c301a94eec4eabebca66be5cf638f693ec256aec514620cc28ee4a94bd9565bc4d4962b9d3641d4278fb319ed2b84de5b665f307a2db0f7fbb757366067d88c50f7e829138fde4f78d39b5b5802f1b92a8a820865af5cc79f9f30bc3f461c66af95d13e5e1f0381c184572a91dee1c849048a647a1158cf884064deddbf1b0b88dfe2f791428d0ba0f6fb2f04e14081f69165ae66d9297c118f0907705c9c4954a199bae0bb96fad763d690e7daa6cfda59ba7f2c8d11448b604d12d" ;
20802139 assert_eq ! ( onion_packet_5. data, <Vec <u8 >>:: from_hex( hex) . unwrap( ) ) ;
2140+
2141+ let logger: Arc < TestLogger > = Arc :: new ( TestLogger :: new ( ) ) ;
2142+ let ctx_full = Secp256k1 :: new ( ) ;
2143+ let path = build_test_path ( ) ;
2144+ let htlc_source = HTLCSource :: OutboundRoute {
2145+ path,
2146+ session_priv : get_test_session_key ( ) ,
2147+ first_hop_htlc_msat : 0 ,
2148+ payment_id : PaymentId ( [ 1 ; 32 ] ) ,
2149+ } ;
2150+
2151+ // Assert that the original failure can be retrieved and that all hmacs check out.
2152+ let decrypted_failure =
2153+ process_onion_failure ( & ctx_full, & logger, & htlc_source, onion_packet_5. data ) ;
2154+
2155+ assert_eq ! ( decrypted_failure. onion_error_code, Some ( 0x2002 ) ) ;
20812156 }
20822157
20832158 struct RawOnionHopData {
0 commit comments