@@ -1650,6 +1650,34 @@ impl From<u16> for LocalHTLCFailureReason {
1650
1650
}
1651
1651
}
1652
1652
1653
+ impl_writeable_tlv_based_enum ! ( LocalHTLCFailureReason ,
1654
+ ( 1 , TemporaryNodeFailure ) => { } ,
1655
+ ( 3 , PermanentNodeFailure ) => { } ,
1656
+ ( 5 , RequiredNodeFeature ) => { } ,
1657
+ ( 7 , InvalidOnionVersion ) => { } ,
1658
+ ( 9 , InvalidOnionHMAC ) => { } ,
1659
+ ( 11 , InvalidOnionKey ) => { } ,
1660
+ ( 13 , TemporaryChannelFailure ) => { } ,
1661
+ ( 15 , PermanentChannelFailure ) => { } ,
1662
+ ( 17 , RequiredChannelFeature ) => { } ,
1663
+ ( 19 , UnknownNextPeer ) => { } ,
1664
+ ( 21 , AmountBelowMinimum ) => { } ,
1665
+ ( 23 , FeeInsufficient ) => { } ,
1666
+ ( 25 , IncorrectCLTVExpiry ) => { } ,
1667
+ ( 27 , CLTVExpiryTooSoon ) => { } ,
1668
+ ( 29 , IncorrectPaymentDetails ) => { } ,
1669
+ ( 31 , FinalIncorrectCLTVExpiry ) => { } ,
1670
+ ( 33 , FinalIncorrectHTLCAmount ) => { } ,
1671
+ ( 35 , ChannelDisabled ) => { } ,
1672
+ ( 37 , CLTVExpiryTooFar ) => { } ,
1673
+ ( 39 , InvalidOnionPayload ) => { } ,
1674
+ ( 41 , MPPTimeout ) => { } ,
1675
+ ( 43 , InvalidOnionBlinding ) => { } ,
1676
+ ( 45 , UnknownFailureCode ) => {
1677
+ ( 0 , code, required) ,
1678
+ } ,
1679
+ ) ;
1680
+
1653
1681
#[ derive( Clone ) ] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
1654
1682
#[ cfg_attr( test, derive( PartialEq ) ) ]
1655
1683
pub ( super ) struct HTLCFailReason ( HTLCFailReasonRepr ) ;
@@ -1658,7 +1686,7 @@ pub(super) struct HTLCFailReason(HTLCFailReasonRepr);
1658
1686
#[ cfg_attr( test, derive( PartialEq ) ) ]
1659
1687
enum HTLCFailReasonRepr {
1660
1688
LightningError { err : msgs:: OnionErrorPacket , hold_time : Option < u32 > } ,
1661
- Reason { failure_code : u16 , data : Vec < u8 > } ,
1689
+ Reason { data : Vec < u8 > , failure_reason : LocalHTLCFailureReason } ,
1662
1690
}
1663
1691
1664
1692
impl HTLCFailReason {
@@ -1675,8 +1703,8 @@ impl HTLCFailReason {
1675
1703
impl core:: fmt:: Debug for HTLCFailReason {
1676
1704
fn fmt ( & self , f : & mut core:: fmt:: Formatter ) -> Result < ( ) , core:: fmt:: Error > {
1677
1705
match self . 0 {
1678
- HTLCFailReasonRepr :: Reason { ref failure_code , .. } => {
1679
- write ! ( f, "HTLC error code {}" , failure_code)
1706
+ HTLCFailReasonRepr :: Reason { ref failure_reason , .. } => {
1707
+ write ! ( f, "HTLC error code {}" , failure_reason . failure_code( ) )
1680
1708
} ,
1681
1709
HTLCFailReasonRepr :: LightningError { .. } => {
1682
1710
write ! ( f, "pre-built LightningError" )
@@ -1716,8 +1744,15 @@ impl_writeable_tlv_based_enum!(HTLCFailReasonRepr,
1716
1744
( _unused, err, ( static_value, msgs:: OnionErrorPacket { data: data. ok_or( DecodeError :: InvalidValue ) ?, attribution_data } ) ) ,
1717
1745
} ,
1718
1746
( 1 , Reason ) => {
1719
- ( 0 , failure_code, required) ,
1747
+ ( 0 , _failure_code, ( legacy, u16 ,
1748
+ |r: & HTLCFailReasonRepr | match r {
1749
+ HTLCFailReasonRepr :: LightningError { .. } => None ,
1750
+ HTLCFailReasonRepr :: Reason { failure_reason, .. } => Some ( failure_reason. failure_code( ) )
1751
+ } ) ) ,
1720
1752
( 2 , data, required_vec) ,
1753
+ // failure_code was required, and is replaced by reason in 0.2 so any time we do not have a
1754
+ // reason available failure_code will be Some and can be expressed as a reason.
1755
+ ( 4 , failure_reason, ( default_value, LocalHTLCFailureReason :: from( _failure_code. ok_or( DecodeError :: InvalidValue ) ?) ) ) ,
1721
1756
} ,
1722
1757
) ;
1723
1758
@@ -1772,7 +1807,7 @@ impl HTLCFailReason {
1772
1807
} ,
1773
1808
}
1774
1809
1775
- Self ( HTLCFailReasonRepr :: Reason { failure_code : failure_reason . failure_code ( ) , data } )
1810
+ Self ( HTLCFailReasonRepr :: Reason { data , failure_reason } )
1776
1811
}
1777
1812
1778
1813
pub ( super ) fn from_failure_code ( failure_reason : LocalHTLCFailureReason ) -> Self {
@@ -1798,15 +1833,15 @@ impl HTLCFailReason {
1798
1833
& self , incoming_packet_shared_secret : & [ u8 ; 32 ] , secondary_shared_secret : & Option < [ u8 ; 32 ] > ,
1799
1834
) -> msgs:: OnionErrorPacket {
1800
1835
match self . 0 {
1801
- HTLCFailReasonRepr :: Reason { ref failure_code , ref data } => {
1836
+ HTLCFailReasonRepr :: Reason { ref data , ref failure_reason } => {
1802
1837
// Final hop always reports zero hold time.
1803
1838
let hold_time: u32 = 0 ;
1804
1839
1805
1840
if let Some ( secondary_shared_secret) = secondary_shared_secret {
1806
1841
// Phantom hop always reports zero hold time too.
1807
1842
let mut packet = build_failure_packet (
1808
1843
secondary_shared_secret,
1809
- u16 :: into ( * failure_code ) ,
1844
+ * failure_reason ,
1810
1845
& data[ ..] ,
1811
1846
hold_time,
1812
1847
) ;
@@ -1818,7 +1853,7 @@ impl HTLCFailReason {
1818
1853
} else {
1819
1854
build_failure_packet (
1820
1855
incoming_packet_shared_secret,
1821
- u16 :: into ( * failure_code ) ,
1856
+ * failure_reason ,
1822
1857
& data[ ..] ,
1823
1858
hold_time,
1824
1859
)
@@ -1847,7 +1882,7 @@ impl HTLCFailReason {
1847
1882
process_onion_failure ( secp_ctx, logger, & htlc_source, err. clone ( ) )
1848
1883
} ,
1849
1884
#[ allow( unused) ]
1850
- HTLCFailReasonRepr :: Reason { ref failure_code , ref data , .. } => {
1885
+ HTLCFailReasonRepr :: Reason { ref data , ref failure_reason } => {
1851
1886
// we get a fail_malformed_htlc from the first hop
1852
1887
// TODO: We'd like to generate a NetworkUpdate for temporary
1853
1888
// failures here, but that would be insufficient as find_route
@@ -1861,7 +1896,7 @@ impl HTLCFailReason {
1861
1896
failed_within_blinded_path : false ,
1862
1897
hold_times : Vec :: new ( ) ,
1863
1898
#[ cfg( any( test, feature = "_test_utils" ) ) ]
1864
- onion_error_code : Some ( * failure_code) ,
1899
+ onion_error_code : Some ( failure_reason . failure_code ( ) ) ,
1865
1900
#[ cfg( any( test, feature = "_test_utils" ) ) ]
1866
1901
onion_error_data : Some ( data. clone ( ) ) ,
1867
1902
}
0 commit comments