@@ -22,7 +22,9 @@ use crate::types::features::{ChannelFeatures, NodeFeatures};
22
22
use crate :: types:: payment:: { PaymentHash , PaymentPreimage } ;
23
23
use crate :: util:: errors:: { self , APIError } ;
24
24
use crate :: util:: logger:: Logger ;
25
- use crate :: util:: ser:: { LengthCalculatingWriter , Readable , ReadableArgs , Writeable , Writer } ;
25
+ use crate :: util:: ser:: {
26
+ LengthCalculatingWriter , Readable , ReadableArgs , RequiredWrapper , Writeable , Writer ,
27
+ } ;
26
28
27
29
use bitcoin:: hashes:: cmp:: fixed_time_eq;
28
30
use bitcoin:: hashes:: hmac:: { Hmac , HmacEngine } ;
@@ -1595,6 +1597,49 @@ impl Into<LocalHTLCFailureReason> for u16 {
1595
1597
}
1596
1598
}
1597
1599
1600
+ impl_writeable_tlv_based_enum ! ( LocalHTLCFailureReason ,
1601
+ ( 0 , TemporaryNodeFailure ) => { } ,
1602
+ ( 1 , PermanentNodeFailure ) => { } ,
1603
+ ( 2 , RequiredNodeFeature ) => { } ,
1604
+ ( 3 , InvalidOnionVersion ) => { } ,
1605
+ ( 4 , InvalidOnionHMAC ) => { } ,
1606
+ ( 5 , InvalidOnionKey ) => { } ,
1607
+ ( 6 , TemporaryChannelFailure ) => { } ,
1608
+ ( 7 , PermanentChannelFailure ) => { } ,
1609
+ ( 8 , RequiredChannelFeature ) => { } ,
1610
+ ( 9 , UnknownNextPeer ) => { } ,
1611
+ ( 10 , AmountBelowMinimum ) => { } ,
1612
+ ( 11 , FeeInsufficient ) => { } ,
1613
+ ( 12 , IncorrectCLTVExpiry ) => { } ,
1614
+ ( 13 , CLTVExpiryTooSoon ) => { } ,
1615
+ ( 14 , IncorrectPaymentDetails ) => { } ,
1616
+ ( 15 , FinalIncorrectCLTVExpiry ) => { } ,
1617
+ ( 16 , FinalIncorrectHTLCAmount ) => { } ,
1618
+ ( 17 , ChannelDisabled ) => { } ,
1619
+ ( 18 , CLTVExpiryTooFar ) => { } ,
1620
+ ( 19 , InvalidOnionPayload ) => { } ,
1621
+ ( 20 , MPPTimeout ) => { } ,
1622
+ ( 21 , InvalidOnionBlinding ) => { } ,
1623
+ ( 22 , InvalidTrampolineForward ) => { } ,
1624
+ ( 23 , PaymentClaimBuffer ) => { } ,
1625
+ ( 24 , DustLimitHolder ) => { } ,
1626
+ ( 25 , DustLimitCounterparty ) => { } ,
1627
+ ( 26 , FeeSpikeBuffer ) => { } ,
1628
+ ( 27 , DroppedPending ) => { } ,
1629
+ ( 28 , PrivateChannelForward ) => { } ,
1630
+ ( 29 , RealSCIDForward ) => { } ,
1631
+ ( 30 , ChannelNotReady ) => { } ,
1632
+ ( 31 , InvalidKeysendPreimage ) => { } ,
1633
+ ( 32 , InvalidTrampolineHop ) => { } ,
1634
+ ( 33 , PaymentSecretRequired ) => { } ,
1635
+ ( 34 , ForwardExpiryBuffer ) => { } ,
1636
+ ( 35 , OutgoingCLTVTooSoon ) => { } ,
1637
+ ( 36 , ChannelClosed ) => { } ,
1638
+ ( 37 , UnknownFailureCode ) => {
1639
+ ( 0 , code, required) ,
1640
+ }
1641
+ ) ;
1642
+
1598
1643
#[ derive( Clone ) ] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
1599
1644
#[ cfg_attr( test, derive( PartialEq ) ) ]
1600
1645
pub ( super ) struct HTLCFailReason ( HTLCFailReasonRepr ) ;
@@ -1603,14 +1648,14 @@ pub(super) struct HTLCFailReason(HTLCFailReasonRepr);
1603
1648
#[ cfg_attr( test, derive( PartialEq ) ) ]
1604
1649
enum HTLCFailReasonRepr {
1605
1650
LightningError { err : msgs:: OnionErrorPacket } ,
1606
- Reason { failure_code : u16 , data : Vec < u8 > } ,
1651
+ Reason { data : Vec < u8 > , reason : LocalHTLCFailureReason } ,
1607
1652
}
1608
1653
1609
1654
impl core:: fmt:: Debug for HTLCFailReason {
1610
1655
fn fmt ( & self , f : & mut core:: fmt:: Formatter ) -> Result < ( ) , core:: fmt:: Error > {
1611
1656
match self . 0 {
1612
- HTLCFailReasonRepr :: Reason { ref failure_code , .. } => {
1613
- write ! ( f, "HTLC error code {}" , failure_code)
1657
+ HTLCFailReasonRepr :: Reason { ref reason , .. } => {
1658
+ write ! ( f, "HTLC error code {}" , reason . failure_code( ) )
1614
1659
} ,
1615
1660
HTLCFailReasonRepr :: LightningError { .. } => {
1616
1661
write ! ( f, "pre-built LightningError" )
@@ -1642,8 +1687,19 @@ impl_writeable_tlv_based_enum!(HTLCFailReasonRepr,
1642
1687
( _unused, err, ( static_value, msgs:: OnionErrorPacket { data: data. ok_or( DecodeError :: InvalidValue ) ? } ) ) ,
1643
1688
} ,
1644
1689
( 1 , Reason ) => {
1645
- ( 0 , failure_code, required) ,
1690
+ ( 0 , _failure_code, ( legacy, u16 ,
1691
+ |r: & HTLCFailReasonRepr | Some ( r. clone( ) ) ) ) ,
1646
1692
( 2 , data, required_vec) ,
1693
+ // failure_code was required, and is replaced by reason so any time we do not have a
1694
+ // reason available failure_code will be Some so we can require reason.
1695
+ ( 4 , reason, ( default_value,
1696
+ if let Some ( code) = _failure_code {
1697
+ let failure_reason: LocalHTLCFailureReason = code. into( ) ;
1698
+ RequiredWrapper :: from( failure_reason)
1699
+ } else {
1700
+ reason
1701
+ }
1702
+ ) ) ,
1647
1703
} ,
1648
1704
) ;
1649
1705
@@ -1715,7 +1771,7 @@ impl HTLCFailReason {
1715
1771
} ,
1716
1772
}
1717
1773
1718
- Self ( HTLCFailReasonRepr :: Reason { failure_code : failure_reason. failure_code ( ) , data } )
1774
+ Self ( HTLCFailReasonRepr :: Reason { data , reason : failure_reason } )
1719
1775
}
1720
1776
1721
1777
pub ( super ) fn from_failure_code ( failure_reason : LocalHTLCFailureReason ) -> Self {
@@ -1737,24 +1793,16 @@ impl HTLCFailReason {
1737
1793
& self , incoming_packet_shared_secret : & [ u8 ; 32 ] , secondary_shared_secret : & Option < [ u8 ; 32 ] > ,
1738
1794
) -> msgs:: OnionErrorPacket {
1739
1795
match self . 0 {
1740
- HTLCFailReasonRepr :: Reason { ref failure_code, ref data } => {
1741
- let failure_code = * failure_code;
1796
+ HTLCFailReasonRepr :: Reason { ref data, ref reason } => {
1742
1797
if let Some ( secondary_shared_secret) = secondary_shared_secret {
1743
- let mut packet = build_failure_packet (
1744
- secondary_shared_secret,
1745
- failure_code. into ( ) ,
1746
- & data[ ..] ,
1747
- ) ;
1798
+ let mut packet =
1799
+ build_failure_packet ( secondary_shared_secret, * reason, & data[ ..] ) ;
1748
1800
1749
1801
crypt_failure_packet ( incoming_packet_shared_secret, & mut packet) ;
1750
1802
1751
1803
packet
1752
1804
} else {
1753
- build_failure_packet (
1754
- incoming_packet_shared_secret,
1755
- failure_code. into ( ) ,
1756
- & data[ ..] ,
1757
- )
1805
+ build_failure_packet ( incoming_packet_shared_secret, * reason, & data[ ..] )
1758
1806
}
1759
1807
} ,
1760
1808
HTLCFailReasonRepr :: LightningError { ref err } => {
@@ -1778,7 +1826,7 @@ impl HTLCFailReason {
1778
1826
process_onion_failure ( secp_ctx, logger, & htlc_source, err. clone ( ) )
1779
1827
} ,
1780
1828
#[ allow( unused) ]
1781
- HTLCFailReasonRepr :: Reason { ref failure_code , ref data , .. } => {
1829
+ HTLCFailReasonRepr :: Reason { ref data , ref reason } => {
1782
1830
// we get a fail_malformed_htlc from the first hop
1783
1831
// TODO: We'd like to generate a NetworkUpdate for temporary
1784
1832
// failures here, but that would be insufficient as find_route
@@ -1791,7 +1839,7 @@ impl HTLCFailReason {
1791
1839
short_channel_id : Some ( path. hops [ 0 ] . short_channel_id ) ,
1792
1840
failed_within_blinded_path : false ,
1793
1841
#[ cfg( any( test, feature = "_test_utils" ) ) ]
1794
- onion_error_code : Some ( * failure_code) ,
1842
+ onion_error_code : Some ( reason . failure_code ( ) ) ,
1795
1843
#[ cfg( any( test, feature = "_test_utils" ) ) ]
1796
1844
onion_error_data : Some ( data. clone ( ) ) ,
1797
1845
}
0 commit comments