@@ -98,13 +98,22 @@ mod channel_held_info {
9898 pub ( super ) incoming_packet_shared_secret : SharedSecret ,
9999 }
100100
101+ /// First hop payment data. This can be used to reconstruct amt_to_forward
102+ /// and outgoing_cltv_value for each hop combined with data from RouteHope
103+ #[ derive( Clone ) ]
104+ pub struct PaymentData {
105+ pub ( super ) htlc_msat : u64 ,
106+ pub ( super ) block_height : u32 ,
107+ }
108+
101109 /// Tracks the inbound corresponding to an outbound HTLC
102110 #[ derive( Clone ) ]
103111 pub enum HTLCSource {
104112 PreviousHopData ( HTLCPreviousHopData ) ,
105113 OutboundRoute {
106114 route : Route ,
107115 session_priv : SecretKey ,
116+ payment_data : PaymentData ,
108117 } ,
109118 }
110119 #[ cfg( test) ]
@@ -113,6 +122,7 @@ mod channel_held_info {
113122 HTLCSource :: OutboundRoute {
114123 route : Route { hops : Vec :: new ( ) } ,
115124 session_priv : SecretKey :: from_slice ( & :: secp256k1:: Secp256k1 :: without_caps ( ) , & [ 1 ; 32 ] ) . unwrap ( ) ,
125+ payment_data : PaymentData { htlc_msat : 0 , block_height : 0 } ,
116126 }
117127 }
118128 }
@@ -1087,6 +1097,10 @@ impl ChannelManager {
10871097 chan. send_htlc_and_commit ( htlc_msat, payment_hash. clone ( ) , htlc_cltv, HTLCSource :: OutboundRoute {
10881098 route : route. clone ( ) ,
10891099 session_priv : session_priv. clone ( ) ,
1100+ payment_data : PaymentData {
1101+ htlc_msat : htlc_msat,
1102+ block_height : cur_height,
1103+ }
10901104 } , onion_packet) . map_err ( |he| APIError :: RouteError { err : he. err } ) ?
10911105 } ;
10921106
@@ -1768,7 +1782,210 @@ impl ChannelManager {
17681782 Ok ( ( ) )
17691783 }
17701784
1785+ // Process onion peacket processed in only in the origin node. Returns update
1786+ // for router and boolean flag indicating if payment can be retried
1787+ fn process_onion_failure ( & self , route : & Route , mut packet_decrypted : Vec < u8 > , session_priv : & SecretKey , payment_data : & PaymentData ) -> Result < ( Option < msgs:: HTLCFailChannelUpdate > , bool ) , secp256k1:: Error > {
1788+
1789+ macro_rules! onion_failure_log {
1790+ ( $error_code_textual: expr, $error_code: expr, $reported_name: expr, $reported_value: expr ) => {
1791+ log_trace!( self , "{}({}) {}({})" , $error_code_textual, $error_code, $reported_name, $reported_value) ;
1792+ } ;
1793+ ( $error_code_textual: expr, $error_code: expr ) => {
1794+ log_trace!( self , "{}({})" , $error_code_textual, $error_code) ;
1795+ } ;
1796+ }
1797+
1798+ const PERM : u16 = 0x4000 ;
1799+ const UPDATE : u16 = 0x1000 ;
1800+
1801+ let mut res = None ;
1802+ let mut htlc_msat = payment_data. htlc_msat ;
1803+ let mut outgoing_cltv_value = payment_data. block_height ;
1804+
1805+ // Handle packed channel/node updates for passing back for the route handler
1806+ Self :: construct_onion_keys_callback ( & self . secp_ctx , & route, & session_priv, |shared_secret, _, _, route_hop| {
1807+ if res. is_some ( ) { return ; }
1808+
1809+ let incoming_htlc_msat = htlc_msat;
1810+ let amt_to_forward = htlc_msat - route_hop. fee_msat ;
1811+ htlc_msat = amt_to_forward;
1812+ outgoing_cltv_value += route_hop. cltv_expiry_delta ;
1813+
1814+ let ammag = ChannelManager :: gen_ammag_from_shared_secret ( & shared_secret) ;
1815+
1816+ let mut decryption_tmp = Vec :: with_capacity ( packet_decrypted. len ( ) ) ;
1817+ decryption_tmp. resize ( packet_decrypted. len ( ) , 0 ) ;
1818+ let mut chacha = ChaCha20 :: new ( & ammag, & [ 0u8 ; 8 ] ) ;
1819+ chacha. process ( & packet_decrypted, & mut decryption_tmp[ ..] ) ;
1820+ packet_decrypted = decryption_tmp;
1821+
1822+ let is_from_final_node = route. hops . last ( ) . unwrap ( ) . pubkey == route_hop. pubkey ;
1823+
1824+ match msgs:: DecodedOnionErrorPacket :: read ( & mut Cursor :: new ( & packet_decrypted) ) {
1825+ Err ( _e) => {
1826+ res = Some ( ( None , false ) ) ;
1827+ } ,
1828+ Ok ( ref err_packet) if err_packet. failuremsg . len ( ) < 2 => {
1829+ res = Some ( ( None , false ) ) ;
1830+ // can't blaim anybody
1831+ } ,
1832+ Ok ( ref err_packet) if err_packet. failuremsg . len ( ) >= 2 => {
1833+ let um = ChannelManager :: gen_um_from_shared_secret ( & shared_secret) ;
1834+
1835+ let mut hmac = Hmac :: new ( Sha256 :: new ( ) , & um) ;
1836+ hmac. input ( & err_packet. encode ( ) [ 32 ..] ) ;
1837+ let mut calc_tag = [ 0u8 ; 32 ] ;
1838+ hmac. raw_result ( & mut calc_tag) ;
1839+
1840+ if crypto:: util:: fixed_time_eq ( & calc_tag, & err_packet. hmac ) {
1841+ let error_code = byte_utils:: slice_to_be16 ( & err_packet. failuremsg [ 0 ..2 ] ) ;
1842+
1843+ match error_code & 0xff {
1844+ 1 |2 |3 => {
1845+ // either from an intermediate or final node
1846+ // invalid_realm(PERM|1),
1847+ // temporary_node_failure(NODE|2)
1848+ // permanent_node_failure(PERM|NODE|2)
1849+ // required_node_feature_mssing(PERM|NODE|3)
1850+ res = Some ( ( Some ( msgs:: HTLCFailChannelUpdate :: NodeFailure {
1851+ node_id : route_hop. pubkey ,
1852+ is_permanent : error_code & PERM == PERM ,
1853+ } ) , !( error_code & PERM == PERM && is_from_final_node) ) ) ;
1854+ // node returning invalid_realm is removed from network_map,
1855+ // although NODE flag is not set, TODO: or remove channel only?
1856+ // retry payment when removed node is not a final node
1857+ return ;
1858+ } ,
1859+ _ => { }
1860+ }
1861+
1862+ if is_from_final_node {
1863+ let payment_retryable = match error_code {
1864+ c if c == PERM |15 => false , // unknown_payment_hash
1865+ c if c == PERM |16 => false , // incorrect_payment_amount
1866+ 17 => true , // final_expiry_too_soon
1867+ 18 if err_packet. failuremsg . len ( ) == 6 => { // final_incorrect_cltv_expiry
1868+ let _reported_cltv_expiry = byte_utils:: slice_to_be16 ( & err_packet. failuremsg [ 2 ..2 +4 ] ) ;
1869+ true
1870+ } ,
1871+ 19 if err_packet. failuremsg . len ( ) == 6 => { // final_incorrect_htlc_amount
1872+ let _reported_incoming_htlc_msat = byte_utils:: slice_to_be16 ( & err_packet. failuremsg [ 2 ..2 +4 ] ) ;
1873+ true
1874+ } ,
1875+ _ => {
1876+ // A final node has sent us either an invalid code or an error_code that
1877+ // MUST be sent from the processing node, or the formmat of failuremsg
1878+ // does not coform to the spec.
1879+ // Remove it from the network map and don't may retry payment
1880+ res = Some ( ( Some ( msgs:: HTLCFailChannelUpdate :: NodeFailure {
1881+ node_id : route_hop. pubkey ,
1882+ is_permanent : true ,
1883+ } ) , false ) ) ;
1884+ return ;
1885+ }
1886+ } ;
1887+ debug_assert_eq ! ( payment_retryable, error_code& PERM != PERM ) ;
1888+ res = Some ( ( None , payment_retryable) ) ;
1889+ return ;
1890+ }
1891+
1892+ // now, error_code should be only from the intermediate nodes
1893+ match error_code {
1894+ _c if error_code & PERM == PERM => {
1895+ res = Some ( ( Some ( msgs:: HTLCFailChannelUpdate :: ChannelClosed {
1896+ short_channel_id : route_hop. short_channel_id ,
1897+ is_permanent : true ,
1898+ } ) , false ) ) ;
1899+ } ,
1900+ _c if error_code & UPDATE == UPDATE => {
1901+ let mut pos = 2 ;
1902+ pos += match error_code {
1903+ c if c == UPDATE |7 => 0 , // temporary_channel_failure
1904+ c if c == UPDATE |11 => 8 , // amount_below_minimum
1905+ c if c == UPDATE |12 => 8 , // fee_insufficient
1906+ c if c == UPDATE |13 => 4 , // incorrect_cltv_expiry
1907+ c if c == UPDATE |20 => 2 , // channel_disabled
1908+ c if c == UPDATE |21 => 0 , // expiry_too_far
1909+ _ => {
1910+ // node sending unknown code
1911+ res = Some ( ( Some ( msgs:: HTLCFailChannelUpdate :: NodeFailure {
1912+ node_id : route_hop. pubkey ,
1913+ is_permanent : true ,
1914+ } ) , false ) ) ;
1915+ return ;
1916+ }
1917+ } ;
1918+
1919+ if err_packet. failuremsg . len ( ) >= pos+2 {
1920+ let update_len = byte_utils:: slice_to_be16 ( & err_packet. failuremsg [ pos+2 ..pos+4 ] ) as usize ;
1921+ if err_packet. failuremsg . len ( ) >= pos+4 + update_len {
1922+ if let Ok ( chan_update) = msgs:: ChannelUpdate :: read ( & mut Cursor :: new ( & err_packet. failuremsg [ pos+4 ..pos+4 +update_len] ) ) {
1923+ if chan_update. contents . timestamp <= route_hop. channel_update_timestamp {
1924+ res = Some ( ( None , true ) ) ;
1925+ return ;
1926+ }
1927+ // if channel_update should NOT have caused the failure:
1928+ // MAY treat the channel_update as invalid.
1929+ let is_chan_update_invalid = match error_code {
1930+ c if c == UPDATE |11 => { // amount_below_minimum
1931+ let reported_htlc_msat = byte_utils:: slice_to_be16 ( & err_packet. failuremsg [ 2 ..2 +8 ] ) ;
1932+ onion_failure_log ! ( "amount_below_minimum" , UPDATE |11 , "htlc_msat" , reported_htlc_msat) ;
1933+ incoming_htlc_msat > chan_update. contents . htlc_minimum_msat
1934+ } ,
1935+ c if c == UPDATE |12 => { // fee_insufficient
1936+ let reported_htlc_msat = byte_utils:: slice_to_be16 ( & err_packet. failuremsg [ 2 ..2 +8 ] ) ;
1937+ let new_fee = amt_to_forward. checked_mul ( chan_update. contents . fee_proportional_millionths as u64 ) . and_then ( |prop_fee| { ( prop_fee / 1000000 ) . checked_add ( chan_update. contents . fee_base_msat as u64 ) } ) ;
1938+ onion_failure_log ! ( "fee_insufficient" , UPDATE |12 , "htlc_msat" , reported_htlc_msat) ;
1939+ new_fee. is_none ( ) || incoming_htlc_msat >= new_fee. unwrap ( ) && incoming_htlc_msat >= amt_to_forward + new_fee. unwrap ( )
1940+ }
1941+ c if c == UPDATE |13 => { // incorrect_cltv_expiry
1942+ let reported_cltv_expiry = byte_utils:: slice_to_be16 ( & err_packet. failuremsg [ 2 ..2 +4 ] ) ;
1943+ onion_failure_log ! ( "incorrect_cltv_expiry" , UPDATE |13 , "cltv_expiry" , reported_cltv_expiry) ;
1944+ route_hop. cltv_expiry_delta as u16 >= chan_update. contents . cltv_expiry_delta
1945+ } ,
1946+ c if c == UPDATE |20 => { // channel_disabled
1947+ let reported_flags = byte_utils:: slice_to_be16 ( & err_packet. failuremsg [ 2 ..2 +2 ] ) ;
1948+ onion_failure_log ! ( "channel_disabled" , UPDATE |20 , "flags" , reported_flags) ;
1949+ chan_update. contents . flags & 0x01 == 0x01
1950+ } ,
1951+ c if c == UPDATE |21 => true , // expiry_too_far
1952+ _ => { unreachable ! ( ) ; } ,
1953+ } ;
1954+
1955+ let msg = if is_chan_update_invalid { None } else {
1956+ Some ( msgs:: HTLCFailChannelUpdate :: ChannelUpdateMessage {
1957+ msg : chan_update,
1958+ } )
1959+ } ;
1960+ res = Some ( ( msg, true ) ) ;
1961+ return ;
1962+ }
1963+ }
1964+ }
1965+ } ,
1966+ 14 => { // expiry_too_soon
1967+ res = Some ( ( None , true ) ) ;
1968+ return ;
1969+ }
1970+ _ => {
1971+ // node sending unknown code
1972+ res = Some ( ( Some ( msgs:: HTLCFailChannelUpdate :: NodeFailure {
1973+ node_id : route_hop. pubkey ,
1974+ is_permanent : true ,
1975+ } ) , false ) ) ;
1976+ return ;
1977+ }
1978+ }
1979+ }
1980+ } ,
1981+ _ => { unreachable ! ( ) }
1982+ }
1983+ } ) ?;
1984+ Ok ( res. unwrap ( ) )
1985+ }
1986+
17711987 fn internal_update_fail_htlc ( & self , their_node_id : & PublicKey , msg : & msgs:: UpdateFailHTLC ) -> Result < Option < msgs:: HTLCFailChannelUpdate > , MsgHandleErrInternal > {
1988+
17721989 let mut channel_state = self . channel_state . lock ( ) . unwrap ( ) ;
17731990 let htlc_source = match channel_state. by_id . get_mut ( & msg. channel_id ) {
17741991 Some ( chan) => {
@@ -1782,63 +1999,15 @@ impl ChannelManager {
17821999 None => return Err ( MsgHandleErrInternal :: send_err_msg_no_close ( "Failed to find corresponding channel" , msg. channel_id ) )
17832000 } ?;
17842001
1785- match htlc_source {
1786- & HTLCSource :: OutboundRoute { ref route, ref session_priv, .. } => {
1787- // Handle packed channel/node updates for passing back for the route handler
1788- let mut packet_decrypted = msg. reason . data . clone ( ) ;
1789- let mut res = None ;
1790- Self :: construct_onion_keys_callback ( & self . secp_ctx , & route, & session_priv, |shared_secret, _, _, route_hop| {
1791- if res. is_some ( ) { return ; }
1792-
1793- let ammag = ChannelManager :: gen_ammag_from_shared_secret ( & shared_secret) ;
1794-
1795- let mut decryption_tmp = Vec :: with_capacity ( packet_decrypted. len ( ) ) ;
1796- decryption_tmp. resize ( packet_decrypted. len ( ) , 0 ) ;
1797- let mut chacha = ChaCha20 :: new ( & ammag, & [ 0u8 ; 8 ] ) ;
1798- chacha. process ( & packet_decrypted, & mut decryption_tmp[ ..] ) ;
1799- packet_decrypted = decryption_tmp;
1800-
1801- if let Ok ( err_packet) = msgs:: DecodedOnionErrorPacket :: read ( & mut Cursor :: new ( & packet_decrypted) ) {
1802- if err_packet. failuremsg . len ( ) >= 2 {
1803- let um = ChannelManager :: gen_um_from_shared_secret ( & shared_secret) ;
1804-
1805- let mut hmac = Hmac :: new ( Sha256 :: new ( ) , & um) ;
1806- hmac. input ( & err_packet. encode ( ) [ 32 ..] ) ;
1807- let mut calc_tag = [ 0u8 ; 32 ] ;
1808- hmac. raw_result ( & mut calc_tag) ;
1809- if crypto:: util:: fixed_time_eq ( & calc_tag, & err_packet. hmac ) {
1810- const UNKNOWN_CHAN : u16 = 0x4000 |10 ;
1811- const TEMP_CHAN_FAILURE : u16 = 0x4000 |7 ;
1812- match byte_utils:: slice_to_be16 ( & err_packet. failuremsg [ 0 ..2 ] ) {
1813- TEMP_CHAN_FAILURE => {
1814- if err_packet. failuremsg . len ( ) >= 4 {
1815- let update_len = byte_utils:: slice_to_be16 ( & err_packet. failuremsg [ 2 ..4 ] ) as usize ;
1816- if err_packet. failuremsg . len ( ) >= 4 + update_len {
1817- if let Ok ( chan_update) = msgs:: ChannelUpdate :: read ( & mut Cursor :: new ( & err_packet. failuremsg [ 4 ..4 + update_len] ) ) {
1818- res = Some ( msgs:: HTLCFailChannelUpdate :: ChannelUpdateMessage {
1819- msg : chan_update,
1820- } ) ;
1821- }
1822- }
1823- }
1824- } ,
1825- UNKNOWN_CHAN => {
1826- // No such next-hop. We know this came from the
1827- // current node as the HMAC validated.
1828- res = Some ( msgs:: HTLCFailChannelUpdate :: ChannelClosed {
1829- short_channel_id : route_hop. short_channel_id ,
1830- is_permanent : true ,
1831- } ) ;
1832- } ,
1833- _ => { } , //TODO: Enumerate all of these!
1834- }
1835- }
1836- }
1837- }
1838- } ) . unwrap ( ) ;
1839- Ok ( res)
1840- } ,
1841- _ => { Ok ( None ) } ,
2002+ // we are the origin node and update route information
2003+ // also determine if the payment is retryable
2004+ if let & HTLCSource :: OutboundRoute { ref route, ref session_priv, ref payment_data} = htlc_source {
2005+ let ( channel_update, _payment_retry) = self . process_onion_failure ( route, msg. reason . data . clone ( ) , session_priv, payment_data) . unwrap ( ) ;
2006+ Ok ( channel_update)
2007+ // TODO: include pyament_retry info in PaymentFailed event that will be
2008+ // fired when receiving revoke_and_ack
2009+ } else {
2010+ Ok ( None )
18422011 }
18432012 }
18442013
0 commit comments