@@ -1627,6 +1627,34 @@ impl From<u16> for LocalHTLCFailureReason {
1627
1627
}
1628
1628
}
1629
1629
1630
+ impl_writeable_tlv_based_enum ! ( LocalHTLCFailureReason ,
1631
+ ( 1 , TemporaryNodeFailure ) => { } ,
1632
+ ( 3 , PermanentNodeFailure ) => { } ,
1633
+ ( 5 , RequiredNodeFeature ) => { } ,
1634
+ ( 7 , InvalidOnionVersion ) => { } ,
1635
+ ( 9 , InvalidOnionHMAC ) => { } ,
1636
+ ( 11 , InvalidOnionKey ) => { } ,
1637
+ ( 13 , TemporaryChannelFailure ) => { } ,
1638
+ ( 15 , PermanentChannelFailure ) => { } ,
1639
+ ( 17 , RequiredChannelFeature ) => { } ,
1640
+ ( 19 , UnknownNextPeer ) => { } ,
1641
+ ( 21 , AmountBelowMinimum ) => { } ,
1642
+ ( 23 , FeeInsufficient ) => { } ,
1643
+ ( 25 , IncorrectCLTVExpiry ) => { } ,
1644
+ ( 27 , CLTVExpiryTooSoon ) => { } ,
1645
+ ( 29 , IncorrectPaymentDetails ) => { } ,
1646
+ ( 31 , FinalIncorrectCLTVExpiry ) => { } ,
1647
+ ( 33 , FinalIncorrectHTLCAmount ) => { } ,
1648
+ ( 35 , ChannelDisabled ) => { } ,
1649
+ ( 37 , CLTVExpiryTooFar ) => { } ,
1650
+ ( 39 , InvalidOnionPayload ) => { } ,
1651
+ ( 41 , MPPTimeout ) => { } ,
1652
+ ( 43 , InvalidOnionBlinding ) => { } ,
1653
+ ( 45 , UnknownFailureCode ) => {
1654
+ ( 0 , code, required) ,
1655
+ } ,
1656
+ ) ;
1657
+
1630
1658
#[ derive( Clone ) ] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
1631
1659
#[ cfg_attr( test, derive( PartialEq ) ) ]
1632
1660
pub ( super ) struct HTLCFailReason ( HTLCFailReasonRepr ) ;
@@ -1635,7 +1663,7 @@ pub(super) struct HTLCFailReason(HTLCFailReasonRepr);
1635
1663
#[ cfg_attr( test, derive( PartialEq ) ) ]
1636
1664
enum HTLCFailReasonRepr {
1637
1665
LightningError { err : msgs:: OnionErrorPacket , hold_time : Option < u32 > } ,
1638
- Reason { failure_code : u16 , data : Vec < u8 > } ,
1666
+ Reason { data : Vec < u8 > , failure_reason : LocalHTLCFailureReason } ,
1639
1667
}
1640
1668
1641
1669
impl HTLCFailReason {
@@ -1652,8 +1680,13 @@ impl HTLCFailReason {
1652
1680
impl core:: fmt:: Debug for HTLCFailReason {
1653
1681
fn fmt ( & self , f : & mut core:: fmt:: Formatter ) -> Result < ( ) , core:: fmt:: Error > {
1654
1682
match self . 0 {
1655
- HTLCFailReasonRepr :: Reason { ref failure_code, .. } => {
1656
- write ! ( f, "HTLC error code {}" , failure_code)
1683
+ HTLCFailReasonRepr :: Reason { ref failure_reason, .. } => {
1684
+ write ! (
1685
+ f,
1686
+ "HTLC failure {:?} error code {}" ,
1687
+ failure_reason,
1688
+ failure_reason. failure_code( )
1689
+ )
1657
1690
} ,
1658
1691
HTLCFailReasonRepr :: LightningError { .. } => {
1659
1692
write ! ( f, "pre-built LightningError" )
@@ -1693,7 +1726,14 @@ impl_writeable_tlv_based_enum!(HTLCFailReasonRepr,
1693
1726
( _unused, err, ( static_value, msgs:: OnionErrorPacket { data: data. ok_or( DecodeError :: InvalidValue ) ?, attribution_data } ) ) ,
1694
1727
} ,
1695
1728
( 1 , Reason ) => {
1696
- ( 0 , failure_code, required) ,
1729
+ ( 0 , _failure_code, ( legacy, u16 ,
1730
+ |r: & HTLCFailReasonRepr | match r {
1731
+ HTLCFailReasonRepr :: LightningError { .. } => None ,
1732
+ HTLCFailReasonRepr :: Reason { failure_reason, .. } => Some ( failure_reason. failure_code( ) )
1733
+ } ) ) ,
1734
+ // failure_code was required, and is replaced by reason in 0.2 so any time we do not have a
1735
+ // reason available failure_code will be Some and can be expressed as a reason.
1736
+ ( 1 , failure_reason, ( default_value, LocalHTLCFailureReason :: from( _failure_code. ok_or( DecodeError :: InvalidValue ) ?) ) ) ,
1697
1737
( 2 , data, required_vec) ,
1698
1738
} ,
1699
1739
) ;
@@ -1749,7 +1789,7 @@ impl HTLCFailReason {
1749
1789
} ,
1750
1790
}
1751
1791
1752
- Self ( HTLCFailReasonRepr :: Reason { failure_code : failure_reason . failure_code ( ) , data } )
1792
+ Self ( HTLCFailReasonRepr :: Reason { data , failure_reason } )
1753
1793
}
1754
1794
1755
1795
pub ( super ) fn from_failure_code ( failure_reason : LocalHTLCFailureReason ) -> Self {
@@ -1775,15 +1815,15 @@ impl HTLCFailReason {
1775
1815
& self , incoming_packet_shared_secret : & [ u8 ; 32 ] , secondary_shared_secret : & Option < [ u8 ; 32 ] > ,
1776
1816
) -> msgs:: OnionErrorPacket {
1777
1817
match self . 0 {
1778
- HTLCFailReasonRepr :: Reason { ref failure_code , ref data } => {
1818
+ HTLCFailReasonRepr :: Reason { ref data , ref failure_reason } => {
1779
1819
// Final hop always reports zero hold time.
1780
1820
let hold_time: u32 = 0 ;
1781
1821
1782
1822
if let Some ( secondary_shared_secret) = secondary_shared_secret {
1783
1823
// Phantom hop always reports zero hold time too.
1784
1824
let mut packet = build_failure_packet (
1785
1825
secondary_shared_secret,
1786
- u16 :: into ( * failure_code ) ,
1826
+ * failure_reason ,
1787
1827
& data[ ..] ,
1788
1828
hold_time,
1789
1829
) ;
@@ -1795,7 +1835,7 @@ impl HTLCFailReason {
1795
1835
} else {
1796
1836
build_failure_packet (
1797
1837
incoming_packet_shared_secret,
1798
- u16 :: into ( * failure_code ) ,
1838
+ * failure_reason ,
1799
1839
& data[ ..] ,
1800
1840
hold_time,
1801
1841
)
@@ -1824,7 +1864,7 @@ impl HTLCFailReason {
1824
1864
process_onion_failure ( secp_ctx, logger, & htlc_source, err. clone ( ) )
1825
1865
} ,
1826
1866
#[ allow( unused) ]
1827
- HTLCFailReasonRepr :: Reason { ref failure_code , ref data , .. } => {
1867
+ HTLCFailReasonRepr :: Reason { ref data , ref failure_reason } => {
1828
1868
// we get a fail_malformed_htlc from the first hop
1829
1869
// TODO: We'd like to generate a NetworkUpdate for temporary
1830
1870
// failures here, but that would be insufficient as find_route
@@ -1838,7 +1878,7 @@ impl HTLCFailReason {
1838
1878
failed_within_blinded_path : false ,
1839
1879
hold_times : Vec :: new ( ) ,
1840
1880
#[ cfg( any( test, feature = "_test_utils" ) ) ]
1841
- onion_error_code : Some ( * failure_code) ,
1881
+ onion_error_code : Some ( failure_reason . failure_code ( ) ) ,
1842
1882
#[ cfg( any( test, feature = "_test_utils" ) ) ]
1843
1883
onion_error_data : Some ( data. clone ( ) ) ,
1844
1884
}
0 commit comments