@@ -1021,6 +1021,8 @@ impl Channel {
1021
1021
Ok ( our_sig)
1022
1022
}
1023
1023
1024
+ /// May return an IgnoreError, but should not, and will always return Ok(_) when
1025
+ /// debug_assertions are turned on
1024
1026
fn get_update_fulfill_htlc ( & mut self , htlc_id_arg : u64 , payment_preimage_arg : [ u8 ; 32 ] ) -> Result < ( Option < msgs:: UpdateFulfillHTLC > , Option < ChannelMonitor > ) , HandleError > {
1025
1027
// Either ChannelFunded got set (which means it wont bet unset) or there is no way any
1026
1028
// caller thought we could have something claimed (cause we wouldn't have accepted in an
@@ -1040,14 +1042,17 @@ impl Channel {
1040
1042
for ( idx, htlc) in self . pending_inbound_htlcs . iter ( ) . enumerate ( ) {
1041
1043
if htlc. htlc_id == htlc_id_arg {
1042
1044
assert_eq ! ( htlc. payment_hash, payment_hash_calc) ;
1043
- if htlc. state != InboundHTLCState :: LocalRemoved {
1044
- pending_idx = idx ;
1045
- break ;
1045
+ if htlc. state != InboundHTLCState :: Committed {
1046
+ debug_assert ! ( false , "Have an inbound HTLC we tried to claim before it was fully committed to" ) ;
1047
+ // Don't return in release mode here so that we can update channel_monitor
1046
1048
}
1049
+ pending_idx = idx;
1050
+ break ;
1047
1051
}
1048
1052
}
1049
1053
if pending_idx == std:: usize:: MAX {
1050
- return Err ( HandleError { err : "Unable to find a pending HTLC which matched the given HTLC ID" , action : None } ) ;
1054
+ debug_assert ! ( false , "Unable to find a pending HTLC which matched the given HTLC ID" ) ;
1055
+ return Err ( HandleError { err : "Unable to find a pending HTLC which matched the given HTLC ID" , action : Some ( msgs:: ErrorAction :: IgnoreError ) } ) ;
1051
1056
}
1052
1057
1053
1058
// Now update local state:
@@ -1061,12 +1066,14 @@ impl Channel {
1061
1066
match pending_update {
1062
1067
& HTLCUpdateAwaitingACK :: ClaimHTLC { htlc_id, .. } => {
1063
1068
if htlc_id_arg == htlc_id {
1069
+ debug_assert ! ( false , "Tried to fulfill an HTLC we already had a pending fulfill for" ) ;
1064
1070
return Ok ( ( None , None ) ) ;
1065
1071
}
1066
1072
} ,
1067
1073
& HTLCUpdateAwaitingACK :: FailHTLC { htlc_id, .. } => {
1068
1074
if htlc_id_arg == htlc_id {
1069
- return Err ( HandleError { err : "Unable to find a pending HTLC which matched the given HTLC ID" , action : None } ) ;
1075
+ debug_assert ! ( false , "Tried to fulfill an HTLC we already had a holding-cell failure on" ) ;
1076
+ return Err ( HandleError { err : "Unable to find a pending HTLC which matched the given HTLC ID" , action : Some ( msgs:: ErrorAction :: IgnoreError ) } ) ;
1070
1077
}
1071
1078
} ,
1072
1079
_ => { }
@@ -1080,21 +1087,12 @@ impl Channel {
1080
1087
1081
1088
{
1082
1089
let htlc = & mut self . pending_inbound_htlcs [ pending_idx] ;
1083
- if htlc. state == InboundHTLCState :: Committed {
1084
- htlc. state = InboundHTLCState :: LocalRemoved ;
1085
- htlc. local_removed_fulfilled = true ;
1086
- } else if htlc. state == InboundHTLCState :: RemoteAnnounced || htlc. state == InboundHTLCState :: AwaitingRemoteRevokeToAnnounce || htlc. state == InboundHTLCState :: AwaitingAnnouncedRemoteRevoke {
1087
- // Theoretically we can hit this if we get the preimage on an HTLC prior to us
1088
- // having forwarded it to anyone. This implies that the sender is busted as someone
1089
- // else knows the preimage, but handling this case and implementing the logic to
1090
- // take their money would be a lot of (never-tested) code to handle a case that
1091
- // hopefully never happens. Instead, we make sure we get the preimage into the
1092
- // channel_monitor and pretend we didn't just see the preimage.
1090
+ if htlc. state != InboundHTLCState :: Committed {
1091
+ debug_assert ! ( false , "Have an inbound HTLC we tried to claim before it was fully committed to" ) ;
1093
1092
return Ok ( ( None , Some ( self . channel_monitor . clone ( ) ) ) ) ;
1094
- } else {
1095
- // LocalRemoved handled in the search loop
1096
- panic ! ( "Have an inbound HTLC when not awaiting remote revoke that had a garbage state" ) ;
1097
1093
}
1094
+ htlc. state = InboundHTLCState :: LocalRemoved ;
1095
+ htlc. local_removed_fulfilled = true ;
1098
1096
}
1099
1097
1100
1098
Ok ( ( Some ( msgs:: UpdateFulfillHTLC {
@@ -1115,23 +1113,42 @@ impl Channel {
1115
1113
}
1116
1114
}
1117
1115
1116
+ /// May return an IgnoreError, but should not, and will always return Ok(_) when
1117
+ /// debug_assertions are turned on
1118
1118
pub fn get_update_fail_htlc ( & mut self , htlc_id_arg : u64 , err_packet : msgs:: OnionErrorPacket ) -> Result < Option < msgs:: UpdateFailHTLC > , HandleError > {
1119
1119
if ( self . channel_state & ( ChannelState :: ChannelFunded as u32 ) ) != ( ChannelState :: ChannelFunded as u32 ) {
1120
1120
panic ! ( "Was asked to fail an HTLC when channel was not in an operational state" ) ;
1121
1121
}
1122
1122
assert_eq ! ( self . channel_state & ChannelState :: ShutdownComplete as u32 , 0 ) ;
1123
1123
1124
+ let mut pending_idx = std:: usize:: MAX ;
1125
+ for ( idx, htlc) in self . pending_inbound_htlcs . iter ( ) . enumerate ( ) {
1126
+ if htlc. htlc_id == htlc_id_arg {
1127
+ if htlc. state != InboundHTLCState :: Committed {
1128
+ debug_assert ! ( false , "Have an inbound HTLC we tried to claim before it was fully committed to" ) ;
1129
+ return Err ( HandleError { err : "Unable to find a pending HTLC which matched the given HTLC ID" , action : Some ( msgs:: ErrorAction :: IgnoreError ) } ) ;
1130
+ }
1131
+ pending_idx = idx;
1132
+ }
1133
+ }
1134
+ if pending_idx == std:: usize:: MAX {
1135
+ debug_assert ! ( false , "Unable to find a pending HTLC which matched the given HTLC ID" ) ;
1136
+ return Err ( HandleError { err : "Unable to find a pending HTLC which matched the given HTLC ID" , action : Some ( msgs:: ErrorAction :: IgnoreError ) } ) ;
1137
+ }
1138
+
1124
1139
// Now update local state:
1125
1140
if ( self . channel_state & ( ChannelState :: AwaitingRemoteRevoke as u32 ) ) == ( ChannelState :: AwaitingRemoteRevoke as u32 ) {
1126
1141
for pending_update in self . holding_cell_htlc_updates . iter ( ) {
1127
1142
match pending_update {
1128
1143
& HTLCUpdateAwaitingACK :: ClaimHTLC { htlc_id, .. } => {
1129
1144
if htlc_id_arg == htlc_id {
1130
- return Err ( HandleError { err : "Unable to find a pending HTLC which matched the given HTLC ID" , action : None } ) ;
1145
+ debug_assert ! ( false , "Unable to find a pending HTLC which matched the given HTLC ID" ) ;
1146
+ return Err ( HandleError { err : "Unable to find a pending HTLC which matched the given HTLC ID" , action : Some ( msgs:: ErrorAction :: IgnoreError ) } ) ;
1131
1147
}
1132
1148
} ,
1133
1149
& HTLCUpdateAwaitingACK :: FailHTLC { htlc_id, .. } => {
1134
1150
if htlc_id_arg == htlc_id {
1151
+ debug_assert ! ( false , "Tried to fail an HTLC that we already had a pending failure for" ) ;
1135
1152
return Ok ( None ) ;
1136
1153
}
1137
1154
} ,
@@ -1145,23 +1162,10 @@ impl Channel {
1145
1162
return Ok ( None ) ;
1146
1163
}
1147
1164
1148
- let mut htlc_amount_msat = 0 ;
1149
- for htlc in self . pending_inbound_htlcs . iter_mut ( ) {
1150
- if htlc. htlc_id == htlc_id_arg {
1151
- if htlc. state == InboundHTLCState :: Committed {
1152
- htlc. state = InboundHTLCState :: LocalRemoved ;
1153
- } else if htlc. state == InboundHTLCState :: RemoteAnnounced {
1154
- panic ! ( "Somehow forwarded HTLC prior to remote revocation!" ) ;
1155
- } else if htlc. state == InboundHTLCState :: LocalRemoved {
1156
- return Err ( HandleError { err : "Unable to find a pending HTLC which matched the given HTLC ID" , action : None } ) ;
1157
- } else {
1158
- panic ! ( "Have an inbound HTLC when not awaiting remote revoke that had a garbage state" ) ;
1159
- }
1160
- htlc_amount_msat += htlc. amount_msat ;
1161
- }
1162
- }
1163
- if htlc_amount_msat == 0 {
1164
- return Err ( HandleError { err : "Unable to find a pending HTLC which matched the given HTLC ID" , action : None } ) ;
1165
+ {
1166
+ let htlc = & mut self . pending_inbound_htlcs [ pending_idx] ;
1167
+ htlc. state = InboundHTLCState :: LocalRemoved ;
1168
+ htlc. local_removed_fulfilled = false ;
1165
1169
}
1166
1170
1167
1171
Ok ( Some ( msgs:: UpdateFailHTLC {
@@ -1617,15 +1621,21 @@ impl Channel {
1617
1621
match self . get_update_fulfill_htlc ( htlc_id, payment_preimage) {
1618
1622
Ok ( update_fulfill_msg_option) => update_fulfill_htlcs. push ( update_fulfill_msg_option. 0 . unwrap ( ) ) ,
1619
1623
Err ( e) => {
1620
- err = Some ( e) ;
1624
+ if let Some ( msgs:: ErrorAction :: IgnoreError ) = e. action { }
1625
+ else {
1626
+ panic ! ( "Got a non-IgnoreError action trying to fulfill holding cell HTLC" ) ;
1627
+ }
1621
1628
}
1622
1629
}
1623
1630
} ,
1624
1631
& HTLCUpdateAwaitingACK :: FailHTLC { htlc_id, ref err_packet } => {
1625
1632
match self . get_update_fail_htlc ( htlc_id, err_packet. clone ( ) ) {
1626
1633
Ok ( update_fail_msg_option) => update_fail_htlcs. push ( update_fail_msg_option. unwrap ( ) ) ,
1627
1634
Err ( e) => {
1628
- err = Some ( e) ;
1635
+ if let Some ( msgs:: ErrorAction :: IgnoreError ) = e. action { }
1636
+ else {
1637
+ panic ! ( "Got a non-IgnoreError action trying to fulfill holding cell HTLC" ) ;
1638
+ }
1629
1639
}
1630
1640
}
1631
1641
} ,
@@ -1639,6 +1649,12 @@ impl Channel {
1639
1649
//fail it back the route, if its a temporary issue we can ignore it...
1640
1650
match err {
1641
1651
None => {
1652
+ if update_add_htlcs. is_empty ( ) && update_fulfill_htlcs. is_empty ( ) && update_fail_htlcs. is_empty ( ) {
1653
+ // This should never actually happen and indicates we got some Errs back
1654
+ // from update_fulfill_htlc/update_fail_htlc, but we handle it anyway in
1655
+ // case there is some strange way to hit duplicate HTLC removes.
1656
+ return Ok ( None ) ;
1657
+ }
1642
1658
let ( commitment_signed, monitor_update) = self . send_commitment_no_status_check ( ) ?;
1643
1659
Ok ( Some ( ( msgs:: CommitmentUpdate {
1644
1660
update_add_htlcs,
0 commit comments