@@ -1140,10 +1140,22 @@ impl Channel {
1140
1140
for ( idx, htlc) in self . pending_inbound_htlcs . iter ( ) . enumerate ( ) {
1141
1141
if htlc. htlc_id == htlc_id_arg {
1142
1142
assert_eq ! ( htlc. payment_hash, payment_hash_calc) ;
1143
- if let InboundHTLCState :: Committed = htlc. state {
1144
- } else {
1145
- debug_assert ! ( false , "Have an inbound HTLC we tried to claim before it was fully committed to" ) ;
1146
- // Don't return in release mode here so that we can update channel_monitor
1143
+ match htlc. state {
1144
+ InboundHTLCState :: Committed => { } ,
1145
+ InboundHTLCState :: LocalRemoved ( ref reason) => {
1146
+ // ChannelManager may generate duplicate claims due to HTLC update events from on-chain
1147
+ // ChannelsMonitors during block rescan
1148
+ // TODO: Ideally we'd just drop these
1149
+ if let & InboundHTLCRemovalReason :: Fulfill ( _) = reason {
1150
+ return Ok ( ( None , None ) ) ;
1151
+ } else {
1152
+ assert ! ( false , "Got an update_fulfill for previously-failed HTLC!" ) ;
1153
+ }
1154
+ } ,
1155
+ _ => {
1156
+ debug_assert ! ( false , "Have an inbound HTLC we tried to claim before it was fully committed to" ) ;
1157
+ // Don't return in release mode here so that we can update channel_monitor
1158
+ }
1147
1159
}
1148
1160
pending_idx = idx;
1149
1161
break ;
@@ -1226,10 +1238,22 @@ impl Channel {
1226
1238
let mut pending_idx = std:: usize:: MAX ;
1227
1239
for ( idx, htlc) in self . pending_inbound_htlcs . iter ( ) . enumerate ( ) {
1228
1240
if htlc. htlc_id == htlc_id_arg {
1229
- if let InboundHTLCState :: Committed = htlc. state {
1230
- } else {
1231
- debug_assert ! ( false , "Have an inbound HTLC we tried to fail before it was fully committed to" ) ;
1232
- return Err ( ChannelError :: Ignore ( "Unable to find a pending HTLC which matched the given HTLC ID" ) ) ;
1241
+ match htlc. state {
1242
+ InboundHTLCState :: Committed => { } ,
1243
+ InboundHTLCState :: LocalRemoved ( ref reason) => {
1244
+ // ChannelManager may generate duplicate claims due to HTLC update events from on-chain
1245
+ // ChannelsMonitors during block rescan
1246
+ // TODO: Ideally we'd just drop these
1247
+ if let & InboundHTLCRemovalReason :: Fulfill ( _) = reason {
1248
+ assert ! ( false , "Got an update_fail for previously-fulfilled HTLC!" ) ;
1249
+ } else {
1250
+ return Ok ( None ) ;
1251
+ }
1252
+ } ,
1253
+ _ => {
1254
+ debug_assert ! ( false , "Have an inbound HTLC we tried to claim before it was fully committed to" ) ;
1255
+ return Err ( ChannelError :: Ignore ( "Unable to find a pending HTLC which matchd the given HTLC ID" ) ) ;
1256
+ }
1233
1257
}
1234
1258
pending_idx = idx;
1235
1259
}
@@ -1251,7 +1275,9 @@ impl Channel {
1251
1275
} ,
1252
1276
& HTLCUpdateAwaitingACK :: FailHTLC { htlc_id, .. } => {
1253
1277
if htlc_id_arg == htlc_id {
1254
- debug_assert ! ( false , "Tried to fail an HTLC that we already had a pending failure for" ) ;
1278
+ // ChannelManager may generate duplicate claims due to HTLC update events from on-chain
1279
+ // ChannelsMonitors during block rescan
1280
+ // TODO: Ideally we'd just drop these
1255
1281
return Ok ( None ) ;
1256
1282
}
1257
1283
} ,
0 commit comments