@@ -98,13 +98,22 @@ mod channel_held_info {
98
98
pub ( super ) incoming_packet_shared_secret : SharedSecret ,
99
99
}
100
100
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
+
101
109
/// Tracks the inbound corresponding to an outbound HTLC
102
110
#[ derive( Clone ) ]
103
111
pub enum HTLCSource {
104
112
PreviousHopData ( HTLCPreviousHopData ) ,
105
113
OutboundRoute {
106
114
route : Route ,
107
115
session_priv : SecretKey ,
116
+ payment_data : PaymentData ,
108
117
} ,
109
118
}
110
119
#[ cfg( test) ]
@@ -113,6 +122,7 @@ mod channel_held_info {
113
122
HTLCSource :: OutboundRoute {
114
123
route : Route { hops : Vec :: new ( ) } ,
115
124
session_priv : SecretKey :: from_slice ( & :: secp256k1:: Secp256k1 :: without_caps ( ) , & [ 1 ; 32 ] ) . unwrap ( ) ,
125
+ payment_data : PaymentData { htlc_msat : 0 , block_height : 0 } ,
116
126
}
117
127
}
118
128
}
@@ -1087,6 +1097,10 @@ impl ChannelManager {
1087
1097
chan. send_htlc_and_commit ( htlc_msat, payment_hash. clone ( ) , htlc_cltv, HTLCSource :: OutboundRoute {
1088
1098
route : route. clone ( ) ,
1089
1099
session_priv : session_priv. clone ( ) ,
1100
+ payment_data : PaymentData {
1101
+ htlc_msat : htlc_msat,
1102
+ block_height : cur_height,
1103
+ }
1090
1104
} , onion_packet) . map_err ( |he| APIError :: RouteError { err : he. err } ) ?
1091
1105
} ;
1092
1106
@@ -1768,7 +1782,210 @@ impl ChannelManager {
1768
1782
Ok ( ( ) )
1769
1783
}
1770
1784
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
+
1771
1987
fn internal_update_fail_htlc ( & self , their_node_id : & PublicKey , msg : & msgs:: UpdateFailHTLC ) -> Result < Option < msgs:: HTLCFailChannelUpdate > , MsgHandleErrInternal > {
1988
+
1772
1989
let mut channel_state = self . channel_state . lock ( ) . unwrap ( ) ;
1773
1990
let htlc_source = match channel_state. by_id . get_mut ( & msg. channel_id ) {
1774
1991
Some ( chan) => {
@@ -1782,63 +1999,15 @@ impl ChannelManager {
1782
1999
None => return Err ( MsgHandleErrInternal :: send_err_msg_no_close ( "Failed to find corresponding channel" , msg. channel_id ) )
1783
2000
} ?;
1784
2001
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 )
1842
2011
}
1843
2012
}
1844
2013
0 commit comments