@@ -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 PendingForwardReceiveHTLCInfo {
73
+ Forward {
74
+ onion_packet : msgs:: OnionPacket ,
75
+ short_channel_id : u64 , // This should be NonZero<u64> eventually
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
+ forward_or_receive : PendingForwardReceiveHTLCInfo ,
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
}
@@ -985,9 +993,8 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
985
993
// delay) once they've send us a commitment_signed!
986
994
987
995
PendingHTLCStatus :: Forward ( PendingHTLCInfo {
988
- onion_packet : None ,
996
+ forward_or_receive : PendingForwardReceiveHTLCInfo :: Receive { } ,
989
997
payment_hash : msg. payment_hash . clone ( ) ,
990
- short_channel_id : 0 ,
991
998
incoming_shared_secret : shared_secret,
992
999
amt_to_forward : next_hop_data. amt_to_forward ,
993
1000
outgoing_cltv_value : next_hop_data. outgoing_cltv_value ,
@@ -1031,24 +1038,29 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1031
1038
let short_channel_id = match next_hop_data. format {
1032
1039
msgs:: OnionHopDataFormat :: Legacy { short_channel_id } => short_channel_id,
1033
1040
msgs:: OnionHopDataFormat :: NonFinalNode { short_channel_id } => short_channel_id,
1034
- msgs:: OnionHopDataFormat :: FinalNode => {
1041
+ msgs:: OnionHopDataFormat :: FinalNode { .. } => {
1035
1042
return_err ! ( "Final Node OnionHopData provided for us as an intermediary node" , 0x4000 | 22 , & [ 0 ; 0 ] ) ;
1036
1043
} ,
1037
1044
} ;
1038
1045
1039
1046
PendingHTLCStatus :: Forward ( PendingHTLCInfo {
1040
- onion_packet : Some ( outgoing_packet) ,
1047
+ forward_or_receive : PendingForwardReceiveHTLCInfo :: Forward {
1048
+ onion_packet : outgoing_packet,
1049
+ short_channel_id : short_channel_id,
1050
+ } ,
1041
1051
payment_hash : msg. payment_hash . clone ( ) ,
1042
- short_channel_id : short_channel_id,
1043
1052
incoming_shared_secret : shared_secret,
1044
1053
amt_to_forward : next_hop_data. amt_to_forward ,
1045
1054
outgoing_cltv_value : next_hop_data. outgoing_cltv_value ,
1046
1055
} )
1047
1056
} ;
1048
1057
1049
1058
channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ;
1050
- if let & PendingHTLCStatus :: Forward ( PendingHTLCInfo { ref onion_packet, ref short_channel_id, ref amt_to_forward, ref outgoing_cltv_value, .. } ) = & pending_forward_info {
1051
- if onion_packet. is_some ( ) { // If short_channel_id is 0 here, we'll reject them in the body here
1059
+ if let & PendingHTLCStatus :: Forward ( PendingHTLCInfo { ref forward_or_receive, ref amt_to_forward, ref outgoing_cltv_value, .. } ) = & pending_forward_info {
1060
+ // If short_channel_id is 0 here, we'll reject them in the body here (which is
1061
+ // important as various things later assume we are a ::Receive if short_channel_id is
1062
+ // non-0.
1063
+ if let & PendingForwardReceiveHTLCInfo :: Forward { ref short_channel_id, .. } = forward_or_receive {
1052
1064
let id_option = channel_state. as_ref ( ) . unwrap ( ) . short_to_id . get ( & short_channel_id) . cloned ( ) ;
1053
1065
let forwarding_id = match id_option {
1054
1066
None => { // unknown_next_peer
@@ -1435,22 +1447,25 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1435
1447
let mut fail_htlc_msgs = Vec :: new ( ) ;
1436
1448
for forward_info in pending_forwards. drain ( ..) {
1437
1449
match forward_info {
1438
- HTLCForwardInfo :: AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info } => {
1439
- 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) ;
1450
+ HTLCForwardInfo :: AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info : PendingHTLCInfo {
1451
+ forward_or_receive : PendingForwardReceiveHTLCInfo :: Forward {
1452
+ onion_packet, ..
1453
+ } , incoming_shared_secret, payment_hash, amt_to_forward, outgoing_cltv_value } , } => {
1454
+ 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) ;
1440
1455
let htlc_source = HTLCSource :: PreviousHopData ( HTLCPreviousHopData {
1441
1456
short_channel_id : prev_short_channel_id,
1442
1457
htlc_id : prev_htlc_id,
1443
- incoming_packet_shared_secret : forward_info . incoming_shared_secret ,
1458
+ incoming_packet_shared_secret : incoming_shared_secret,
1444
1459
} ) ;
1445
- 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 ( ) ) {
1460
+ match chan. get_mut ( ) . send_htlc ( amt_to_forward, payment_hash, outgoing_cltv_value, htlc_source. clone ( ) , onion_packet) {
1446
1461
Err ( e) => {
1447
1462
if let ChannelError :: Ignore ( msg) = e {
1448
- log_trace ! ( self , "Failed to forward HTLC with payment_hash {}: {}" , log_bytes!( forward_info . payment_hash. 0 ) , msg) ;
1463
+ log_trace ! ( self , "Failed to forward HTLC with payment_hash {}: {}" , log_bytes!( payment_hash. 0 ) , msg) ;
1449
1464
} else {
1450
1465
panic ! ( "Stated return value requirements in send_htlc() were not met" ) ;
1451
1466
}
1452
1467
let chan_update = self . get_channel_update ( chan. get ( ) ) . unwrap ( ) ;
1453
- failed_forwards. push ( ( htlc_source, forward_info . payment_hash , 0x1000 | 7 , Some ( chan_update) ) ) ;
1468
+ failed_forwards. push ( ( htlc_source, payment_hash, 0x1000 | 7 , Some ( chan_update) ) ) ;
1454
1469
continue ;
1455
1470
} ,
1456
1471
Ok ( update_add) => {
@@ -1469,6 +1484,9 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1469
1484
}
1470
1485
}
1471
1486
} ,
1487
+ HTLCForwardInfo :: AddHTLC { .. } => {
1488
+ panic ! ( "short_channel_id != 0 should imply any pending_forward entries are of type Forward" ) ;
1489
+ } ,
1472
1490
HTLCForwardInfo :: FailHTLC { htlc_id, err_packet } => {
1473
1491
log_trace ! ( self , "Failing HTLC back to channel with short id {} after delay" , short_chan_id) ;
1474
1492
match chan. get_mut ( ) . get_update_fail_htlc ( htlc_id, err_packet) {
@@ -1548,21 +1566,26 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1548
1566
} else {
1549
1567
for forward_info in pending_forwards. drain ( ..) {
1550
1568
match forward_info {
1551
- HTLCForwardInfo :: AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info } => {
1569
+ HTLCForwardInfo :: AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info : PendingHTLCInfo {
1570
+ forward_or_receive : PendingForwardReceiveHTLCInfo :: Receive { } ,
1571
+ incoming_shared_secret, payment_hash, amt_to_forward, .. } , } => {
1552
1572
let prev_hop_data = HTLCPreviousHopData {
1553
1573
short_channel_id : prev_short_channel_id,
1554
1574
htlc_id : prev_htlc_id,
1555
- incoming_packet_shared_secret : forward_info . incoming_shared_secret ,
1575
+ incoming_packet_shared_secret : incoming_shared_secret,
1556
1576
} ;
1557
- match channel_state. claimable_htlcs . entry ( forward_info . payment_hash ) {
1558
- hash_map:: Entry :: Occupied ( mut entry) => entry. get_mut ( ) . push ( ( forward_info . amt_to_forward , prev_hop_data) ) ,
1559
- hash_map:: Entry :: Vacant ( entry) => { entry. insert ( vec ! [ ( forward_info . amt_to_forward, prev_hop_data) ] ) ; } ,
1577
+ match channel_state. claimable_htlcs . entry ( payment_hash) {
1578
+ hash_map:: Entry :: Occupied ( mut entry) => entry. get_mut ( ) . push ( ( amt_to_forward, prev_hop_data) ) ,
1579
+ hash_map:: Entry :: Vacant ( entry) => { entry. insert ( vec ! [ ( amt_to_forward, prev_hop_data) ] ) ; } ,
1560
1580
} ;
1561
1581
new_events. push ( events:: Event :: PaymentReceived {
1562
- payment_hash : forward_info . payment_hash ,
1563
- amt : forward_info . amt_to_forward ,
1582
+ payment_hash : payment_hash,
1583
+ amt : amt_to_forward,
1564
1584
} ) ;
1565
1585
} ,
1586
+ HTLCForwardInfo :: AddHTLC { .. } => {
1587
+ panic ! ( "short_channel_id == 0 should imply any pending_forward entries are of type Receive" ) ;
1588
+ } ,
1566
1589
HTLCForwardInfo :: FailHTLC { .. } => {
1567
1590
panic ! ( "Got pending fail of our own HTLC" ) ;
1568
1591
}
@@ -2377,7 +2400,10 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
2377
2400
forward_event = Some ( Duration :: from_millis ( MIN_HTLC_RELAY_HOLDING_CELL_MILLIS ) )
2378
2401
}
2379
2402
for ( forward_info, prev_htlc_id) in pending_forwards. drain ( ..) {
2380
- match channel_state. forward_htlcs . entry ( forward_info. short_channel_id ) {
2403
+ match channel_state. forward_htlcs . entry ( match forward_info. forward_or_receive {
2404
+ PendingForwardReceiveHTLCInfo :: Forward { short_channel_id, .. } => short_channel_id,
2405
+ PendingForwardReceiveHTLCInfo :: Receive { .. } => 0 ,
2406
+ } ) {
2381
2407
hash_map:: Entry :: Occupied ( mut entry) => {
2382
2408
entry. get_mut ( ) . push ( HTLCForwardInfo :: AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info } ) ;
2383
2409
} ,
@@ -3119,10 +3145,18 @@ const MIN_SERIALIZATION_VERSION: u8 = 1;
3119
3145
3120
3146
impl Writeable for PendingHTLCInfo {
3121
3147
fn write < W : Writer > ( & self , writer : & mut W ) -> Result < ( ) , :: std:: io:: Error > {
3122
- self . onion_packet . write ( writer) ?;
3148
+ match & self . forward_or_receive {
3149
+ & PendingForwardReceiveHTLCInfo :: Forward { ref onion_packet, ref short_channel_id } => {
3150
+ 0u8 . write ( writer) ?;
3151
+ onion_packet. write ( writer) ?;
3152
+ short_channel_id. write ( writer) ?;
3153
+ } ,
3154
+ & PendingForwardReceiveHTLCInfo :: Receive { } => {
3155
+ 1u8 . write ( writer) ?;
3156
+ } ,
3157
+ }
3123
3158
self . incoming_shared_secret . write ( writer) ?;
3124
3159
self . payment_hash . write ( writer) ?;
3125
- self . short_channel_id . write ( writer) ?;
3126
3160
self . amt_to_forward . write ( writer) ?;
3127
3161
self . outgoing_cltv_value . write ( writer) ?;
3128
3162
Ok ( ( ) )
@@ -3132,10 +3166,16 @@ impl Writeable for PendingHTLCInfo {
3132
3166
impl Readable for PendingHTLCInfo {
3133
3167
fn read < R : :: std:: io:: Read > ( reader : & mut R ) -> Result < PendingHTLCInfo , DecodeError > {
3134
3168
Ok ( PendingHTLCInfo {
3135
- onion_packet : Readable :: read ( reader) ?,
3169
+ forward_or_receive : match Readable :: read ( reader) ? {
3170
+ 0u8 => PendingForwardReceiveHTLCInfo :: Forward {
3171
+ onion_packet : Readable :: read ( reader) ?,
3172
+ short_channel_id : Readable :: read ( reader) ?,
3173
+ } ,
3174
+ 1u8 => PendingForwardReceiveHTLCInfo :: Receive { } ,
3175
+ _ => return Err ( DecodeError :: InvalidValue ) ,
3176
+ } ,
3136
3177
incoming_shared_secret : Readable :: read ( reader) ?,
3137
3178
payment_hash : Readable :: read ( reader) ?,
3138
- short_channel_id : Readable :: read ( reader) ?,
3139
3179
amt_to_forward : Readable :: read ( reader) ?,
3140
3180
outgoing_cltv_value : Readable :: read ( reader) ?,
3141
3181
} )
0 commit comments