@@ -68,12 +68,20 @@ use std::ops::Deref;
68
68
// Alternatively, we can fill an outbound HTLC with a HTLCSource::OutboundRoute indicating this is
69
69
// our payment, which we can use to decode errors or inform the user that the payment was sent.
70
70
71
+ #[ derive( Clone ) ] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
72
+ enum PendingHTLCRouting {
73
+ Forward {
74
+ onion_packet : msgs:: OnionPacket ,
75
+ short_channel_id : u64 , // This should be NonZero<u64> eventually when we bump MSRV
76
+ } ,
77
+ Receive { } ,
78
+ }
79
+
71
80
#[ derive( Clone ) ] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
72
81
pub ( super ) struct PendingHTLCInfo {
73
- onion_packet : Option < msgs :: OnionPacket > ,
82
+ routing : PendingHTLCRouting ,
74
83
incoming_shared_secret : [ u8 ; 32 ] ,
75
84
payment_hash : PaymentHash ,
76
- short_channel_id : u64 ,
77
85
pub ( super ) amt_to_forward : u64 ,
78
86
pub ( super ) outgoing_cltv_value : u32 ,
79
87
}
@@ -1005,9 +1013,8 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1005
1013
// delay) once they've send us a commitment_signed!
1006
1014
1007
1015
PendingHTLCStatus :: Forward ( PendingHTLCInfo {
1008
- onion_packet : None ,
1016
+ routing : PendingHTLCRouting :: Receive { } ,
1009
1017
payment_hash : msg. payment_hash . clone ( ) ,
1010
- short_channel_id : 0 ,
1011
1018
incoming_shared_secret : shared_secret,
1012
1019
amt_to_forward : next_hop_data. amt_to_forward ,
1013
1020
outgoing_cltv_value : next_hop_data. outgoing_cltv_value ,
@@ -1051,24 +1058,29 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1051
1058
let short_channel_id = match next_hop_data. format {
1052
1059
msgs:: OnionHopDataFormat :: Legacy { short_channel_id } => short_channel_id,
1053
1060
msgs:: OnionHopDataFormat :: NonFinalNode { short_channel_id } => short_channel_id,
1054
- msgs:: OnionHopDataFormat :: FinalNode => {
1061
+ msgs:: OnionHopDataFormat :: FinalNode { .. } => {
1055
1062
return_err ! ( "Final Node OnionHopData provided for us as an intermediary node" , 0x4000 | 22 , & [ 0 ; 0 ] ) ;
1056
1063
} ,
1057
1064
} ;
1058
1065
1059
1066
PendingHTLCStatus :: Forward ( PendingHTLCInfo {
1060
- onion_packet : Some ( outgoing_packet) ,
1067
+ routing : PendingHTLCRouting :: Forward {
1068
+ onion_packet : outgoing_packet,
1069
+ short_channel_id : short_channel_id,
1070
+ } ,
1061
1071
payment_hash : msg. payment_hash . clone ( ) ,
1062
- short_channel_id : short_channel_id,
1063
1072
incoming_shared_secret : shared_secret,
1064
1073
amt_to_forward : next_hop_data. amt_to_forward ,
1065
1074
outgoing_cltv_value : next_hop_data. outgoing_cltv_value ,
1066
1075
} )
1067
1076
} ;
1068
1077
1069
1078
channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ;
1070
- if let & PendingHTLCStatus :: Forward ( PendingHTLCInfo { ref onion_packet, ref short_channel_id, ref amt_to_forward, ref outgoing_cltv_value, .. } ) = & pending_forward_info {
1071
- if onion_packet. is_some ( ) { // If short_channel_id is 0 here, we'll reject them in the body here
1079
+ if let & PendingHTLCStatus :: Forward ( PendingHTLCInfo { ref routing, ref amt_to_forward, ref outgoing_cltv_value, .. } ) = & pending_forward_info {
1080
+ // If short_channel_id is 0 here, we'll reject the HTLC as there cannot be a channel
1081
+ // with a short_channel_id of 0. This is important as various things later assume
1082
+ // short_channel_id is non-0 in any ::Forward.
1083
+ if let & PendingHTLCRouting :: Forward { ref short_channel_id, .. } = routing {
1072
1084
let id_option = channel_state. as_ref ( ) . unwrap ( ) . short_to_id . get ( & short_channel_id) . cloned ( ) ;
1073
1085
let forwarding_id = match id_option {
1074
1086
None => { // unknown_next_peer
@@ -1450,22 +1462,25 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1450
1462
let mut fail_htlc_msgs = Vec :: new ( ) ;
1451
1463
for forward_info in pending_forwards. drain ( ..) {
1452
1464
match forward_info {
1453
- HTLCForwardInfo :: AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info } => {
1454
- log_trace ! ( self , "Adding HTLC from short id {} with payment_hash {} to channel with short id {} after delay" , log_bytes!( forward_info. payment_hash. 0 ) , prev_short_channel_id, short_chan_id) ;
1465
+ HTLCForwardInfo :: AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info : PendingHTLCInfo {
1466
+ routing : PendingHTLCRouting :: Forward {
1467
+ onion_packet, ..
1468
+ } , incoming_shared_secret, payment_hash, amt_to_forward, outgoing_cltv_value } , } => {
1469
+ log_trace ! ( self , "Adding HTLC from short id {} with payment_hash {} to channel with short id {} after delay" , log_bytes!( payment_hash. 0 ) , prev_short_channel_id, short_chan_id) ;
1455
1470
let htlc_source = HTLCSource :: PreviousHopData ( HTLCPreviousHopData {
1456
1471
short_channel_id : prev_short_channel_id,
1457
1472
htlc_id : prev_htlc_id,
1458
- incoming_packet_shared_secret : forward_info . incoming_shared_secret ,
1473
+ incoming_packet_shared_secret : incoming_shared_secret,
1459
1474
} ) ;
1460
- match chan. get_mut ( ) . send_htlc ( forward_info . amt_to_forward , forward_info . payment_hash , forward_info . outgoing_cltv_value , htlc_source. clone ( ) , forward_info . onion_packet . unwrap ( ) ) {
1475
+ match chan. get_mut ( ) . send_htlc ( amt_to_forward, payment_hash, outgoing_cltv_value, htlc_source. clone ( ) , onion_packet) {
1461
1476
Err ( e) => {
1462
1477
if let ChannelError :: Ignore ( msg) = e {
1463
- log_trace ! ( self , "Failed to forward HTLC with payment_hash {}: {}" , log_bytes!( forward_info . payment_hash. 0 ) , msg) ;
1478
+ log_trace ! ( self , "Failed to forward HTLC with payment_hash {}: {}" , log_bytes!( payment_hash. 0 ) , msg) ;
1464
1479
} else {
1465
1480
panic ! ( "Stated return value requirements in send_htlc() were not met" ) ;
1466
1481
}
1467
1482
let chan_update = self . get_channel_update ( chan. get ( ) ) . unwrap ( ) ;
1468
- failed_forwards. push ( ( htlc_source, forward_info . payment_hash , 0x1000 | 7 , Some ( chan_update) ) ) ;
1483
+ failed_forwards. push ( ( htlc_source, payment_hash, 0x1000 | 7 , Some ( chan_update) ) ) ;
1469
1484
continue ;
1470
1485
} ,
1471
1486
Ok ( update_add) => {
@@ -1484,6 +1499,9 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1484
1499
}
1485
1500
}
1486
1501
} ,
1502
+ HTLCForwardInfo :: AddHTLC { .. } => {
1503
+ panic ! ( "short_channel_id != 0 should imply any pending_forward entries are of type Forward" ) ;
1504
+ } ,
1487
1505
HTLCForwardInfo :: FailHTLC { htlc_id, err_packet } => {
1488
1506
log_trace ! ( self , "Failing HTLC back to channel with short id {} after delay" , short_chan_id) ;
1489
1507
match chan. get_mut ( ) . get_update_fail_htlc ( htlc_id, err_packet) {
@@ -1561,21 +1579,26 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1561
1579
} else {
1562
1580
for forward_info in pending_forwards. drain ( ..) {
1563
1581
match forward_info {
1564
- HTLCForwardInfo :: AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info } => {
1582
+ HTLCForwardInfo :: AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info : PendingHTLCInfo {
1583
+ routing : PendingHTLCRouting :: Receive { } ,
1584
+ incoming_shared_secret, payment_hash, amt_to_forward, .. } , } => {
1565
1585
let prev_hop_data = HTLCPreviousHopData {
1566
1586
short_channel_id : prev_short_channel_id,
1567
1587
htlc_id : prev_htlc_id,
1568
- incoming_packet_shared_secret : forward_info . incoming_shared_secret ,
1588
+ incoming_packet_shared_secret : incoming_shared_secret,
1569
1589
} ;
1570
- match channel_state. claimable_htlcs . entry ( forward_info . payment_hash ) {
1571
- hash_map:: Entry :: Occupied ( mut entry) => entry. get_mut ( ) . push ( ( forward_info . amt_to_forward , prev_hop_data) ) ,
1572
- hash_map:: Entry :: Vacant ( entry) => { entry. insert ( vec ! [ ( forward_info . amt_to_forward, prev_hop_data) ] ) ; } ,
1590
+ match channel_state. claimable_htlcs . entry ( payment_hash) {
1591
+ hash_map:: Entry :: Occupied ( mut entry) => entry. get_mut ( ) . push ( ( amt_to_forward, prev_hop_data) ) ,
1592
+ hash_map:: Entry :: Vacant ( entry) => { entry. insert ( vec ! [ ( amt_to_forward, prev_hop_data) ] ) ; } ,
1573
1593
} ;
1574
1594
new_events. push ( events:: Event :: PaymentReceived {
1575
- payment_hash : forward_info . payment_hash ,
1576
- amt : forward_info . amt_to_forward ,
1595
+ payment_hash : payment_hash,
1596
+ amt : amt_to_forward,
1577
1597
} ) ;
1578
1598
} ,
1599
+ HTLCForwardInfo :: AddHTLC { .. } => {
1600
+ panic ! ( "short_channel_id == 0 should imply any pending_forward entries are of type Receive" ) ;
1601
+ } ,
1579
1602
HTLCForwardInfo :: FailHTLC { .. } => {
1580
1603
panic ! ( "Got pending fail of our own HTLC" ) ;
1581
1604
}
@@ -2388,7 +2411,10 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
2388
2411
forward_event = Some ( Duration :: from_millis ( MIN_HTLC_RELAY_HOLDING_CELL_MILLIS ) )
2389
2412
}
2390
2413
for ( forward_info, prev_htlc_id) in pending_forwards. drain ( ..) {
2391
- match channel_state. forward_htlcs . entry ( forward_info. short_channel_id ) {
2414
+ match channel_state. forward_htlcs . entry ( match forward_info. routing {
2415
+ PendingHTLCRouting :: Forward { short_channel_id, .. } => short_channel_id,
2416
+ PendingHTLCRouting :: Receive { .. } => 0 ,
2417
+ } ) {
2392
2418
hash_map:: Entry :: Occupied ( mut entry) => {
2393
2419
entry. get_mut ( ) . push ( HTLCForwardInfo :: AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info } ) ;
2394
2420
} ,
@@ -3066,10 +3092,18 @@ const MIN_SERIALIZATION_VERSION: u8 = 1;
3066
3092
3067
3093
impl Writeable for PendingHTLCInfo {
3068
3094
fn write < W : Writer > ( & self , writer : & mut W ) -> Result < ( ) , :: std:: io:: Error > {
3069
- self . onion_packet . write ( writer) ?;
3095
+ match & self . routing {
3096
+ & PendingHTLCRouting :: Forward { ref onion_packet, ref short_channel_id } => {
3097
+ 0u8 . write ( writer) ?;
3098
+ onion_packet. write ( writer) ?;
3099
+ short_channel_id. write ( writer) ?;
3100
+ } ,
3101
+ & PendingHTLCRouting :: Receive { } => {
3102
+ 1u8 . write ( writer) ?;
3103
+ } ,
3104
+ }
3070
3105
self . incoming_shared_secret . write ( writer) ?;
3071
3106
self . payment_hash . write ( writer) ?;
3072
- self . short_channel_id . write ( writer) ?;
3073
3107
self . amt_to_forward . write ( writer) ?;
3074
3108
self . outgoing_cltv_value . write ( writer) ?;
3075
3109
Ok ( ( ) )
@@ -3079,10 +3113,16 @@ impl Writeable for PendingHTLCInfo {
3079
3113
impl Readable for PendingHTLCInfo {
3080
3114
fn read < R : :: std:: io:: Read > ( reader : & mut R ) -> Result < PendingHTLCInfo , DecodeError > {
3081
3115
Ok ( PendingHTLCInfo {
3082
- onion_packet : Readable :: read ( reader) ?,
3116
+ routing : match Readable :: read ( reader) ? {
3117
+ 0u8 => PendingHTLCRouting :: Forward {
3118
+ onion_packet : Readable :: read ( reader) ?,
3119
+ short_channel_id : Readable :: read ( reader) ?,
3120
+ } ,
3121
+ 1u8 => PendingHTLCRouting :: Receive { } ,
3122
+ _ => return Err ( DecodeError :: InvalidValue ) ,
3123
+ } ,
3083
3124
incoming_shared_secret : Readable :: read ( reader) ?,
3084
3125
payment_hash : Readable :: read ( reader) ?,
3085
- short_channel_id : Readable :: read ( reader) ?,
3086
3126
amt_to_forward : Readable :: read ( reader) ?,
3087
3127
outgoing_cltv_value : Readable :: read ( reader) ?,
3088
3128
} )
0 commit comments