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