@@ -301,6 +301,33 @@ pub struct CounterpartyForwardingInfo {
301
301
pub cltv_expiry_delta : u16 ,
302
302
}
303
303
304
+ /// A return value enum for get_update_fulfill_htlc. See UpdateFulfillCommitFetch variants for
305
+ /// description
306
+ enum UpdateFulfillFetch {
307
+ NewClaim {
308
+ monitor_update : ChannelMonitorUpdate ,
309
+ msg : Option < msgs:: UpdateFulfillHTLC > ,
310
+ } ,
311
+ DuplicateClaim { } ,
312
+ }
313
+
314
+ /// The return type of get_update_fulfill_htlc_and_commit.
315
+ pub enum UpdateFulfillCommitFetch {
316
+ /// Indicates the HTLC fulfill is new, and either generated an update_fulfill message, placed
317
+ /// it in the holding cell, or re-generated the update_fulfill message after the same claim was
318
+ /// previously placed in the holding cell (and has since been removed).
319
+ NewClaim {
320
+ /// The ChannelMonitorUpdate which places the new payment preimage in the channel monitor
321
+ monitor_update : ChannelMonitorUpdate ,
322
+ /// The update_fulfill message and commitment_signed message (if the claim was not placed
323
+ /// in the holding cell).
324
+ msgs : Option < ( msgs:: UpdateFulfillHTLC , msgs:: CommitmentSigned ) > ,
325
+ } ,
326
+ /// Indicates the HTLC fulfill is duplicative and already existed either in the holding cell
327
+ /// or has been forgotten (presumably previously claimed).
328
+ DuplicateClaim { } ,
329
+ }
330
+
304
331
// TODO: We should refactor this to be an Inbound/OutboundChannel until initial setup handshaking
305
332
// has been completed, and then turn into a Channel to get compiler-time enforcement of things like
306
333
// calling channel_id() before we're set up or things like get_outbound_funding_signed on an
@@ -1232,13 +1259,7 @@ impl<Signer: Sign> Channel<Signer> {
1232
1259
make_funding_redeemscript ( & self . get_holder_pubkeys ( ) . funding_pubkey , self . counterparty_funding_pubkey ( ) )
1233
1260
}
1234
1261
1235
- /// Per HTLC, only one get_update_fail_htlc or get_update_fulfill_htlc call may be made.
1236
- /// In such cases we debug_assert!(false) and return a ChannelError::Ignore. Thus, will always
1237
- /// return Ok(_) if debug assertions are turned on or preconditions are met.
1238
- ///
1239
- /// Note that it is still possible to hit these assertions in case we find a preimage on-chain
1240
- /// but then have a reorg which settles on an HTLC-failure on chain.
1241
- fn get_update_fulfill_htlc < L : Deref > ( & mut self , htlc_id_arg : u64 , payment_preimage_arg : PaymentPreimage , logger : & L ) -> Result < ( Option < msgs:: UpdateFulfillHTLC > , Option < ChannelMonitorUpdate > ) , ChannelError > where L :: Target : Logger {
1262
+ fn get_update_fulfill_htlc < L : Deref > ( & mut self , htlc_id_arg : u64 , payment_preimage_arg : PaymentPreimage , logger : & L ) -> UpdateFulfillFetch where L :: Target : Logger {
1242
1263
// Either ChannelFunded got set (which means it won't be unset) or there is no way any
1243
1264
// caller thought we could have something claimed (cause we wouldn't have accepted in an
1244
1265
// incoming HTLC anyway). If we got to ShutdownComplete, callers aren't allowed to call us,
@@ -1266,7 +1287,7 @@ impl<Signer: Sign> Channel<Signer> {
1266
1287
log_warn ! ( logger, "Have preimage and want to fulfill HTLC with payment hash {} we already failed against channel {}" , log_bytes!( htlc. payment_hash. 0 ) , log_bytes!( self . channel_id( ) ) ) ;
1267
1288
debug_assert ! ( false , "Tried to fulfill an HTLC that was already failed" ) ;
1268
1289
}
1269
- return Ok ( ( None , None ) ) ;
1290
+ return UpdateFulfillFetch :: DuplicateClaim { } ;
1270
1291
} ,
1271
1292
_ => {
1272
1293
debug_assert ! ( false , "Have an inbound HTLC we tried to claim before it was fully committed to" ) ;
@@ -1282,7 +1303,7 @@ impl<Signer: Sign> Channel<Signer> {
1282
1303
// If we failed to find an HTLC to fulfill, make sure it was previously fulfilled and
1283
1304
// this is simply a duplicate claim, not previously failed and we lost funds.
1284
1305
debug_assert ! ( self . historical_inbound_htlc_fulfills. contains( & htlc_id_arg) ) ;
1285
- return Ok ( ( None , None ) ) ;
1306
+ return UpdateFulfillFetch :: DuplicateClaim { } ;
1286
1307
}
1287
1308
1288
1309
// Now update local state:
@@ -1306,7 +1327,7 @@ impl<Signer: Sign> Channel<Signer> {
1306
1327
self . latest_monitor_update_id -= 1 ;
1307
1328
#[ cfg( any( test, feature = "fuzztarget" ) ) ]
1308
1329
debug_assert ! ( self . historical_inbound_htlc_fulfills. contains( & htlc_id_arg) ) ;
1309
- return Ok ( ( None , None ) ) ;
1330
+ return UpdateFulfillFetch :: DuplicateClaim { } ;
1310
1331
}
1311
1332
} ,
1312
1333
& HTLCUpdateAwaitingACK :: FailHTLC { htlc_id, .. } => {
@@ -1315,7 +1336,7 @@ impl<Signer: Sign> Channel<Signer> {
1315
1336
// TODO: We may actually be able to switch to a fulfill here, though its
1316
1337
// rare enough it may not be worth the complexity burden.
1317
1338
debug_assert ! ( false , "Tried to fulfill an HTLC that was already failed" ) ;
1318
- return Ok ( ( None , Some ( monitor_update) ) ) ;
1339
+ return UpdateFulfillFetch :: NewClaim { monitor_update, msg : None } ;
1319
1340
}
1320
1341
} ,
1321
1342
_ => { }
@@ -1327,7 +1348,7 @@ impl<Signer: Sign> Channel<Signer> {
1327
1348
} ) ;
1328
1349
#[ cfg( any( test, feature = "fuzztarget" ) ) ]
1329
1350
self . historical_inbound_htlc_fulfills . insert ( htlc_id_arg) ;
1330
- return Ok ( ( None , Some ( monitor_update) ) ) ;
1351
+ return UpdateFulfillFetch :: NewClaim { monitor_update, msg : None } ;
1331
1352
}
1332
1353
#[ cfg( any( test, feature = "fuzztarget" ) ) ]
1333
1354
self . historical_inbound_htlc_fulfills . insert ( htlc_id_arg) ;
@@ -1337,44 +1358,43 @@ impl<Signer: Sign> Channel<Signer> {
1337
1358
if let InboundHTLCState :: Committed = htlc. state {
1338
1359
} else {
1339
1360
debug_assert ! ( false , "Have an inbound HTLC we tried to claim before it was fully committed to" ) ;
1340
- return Ok ( ( None , Some ( monitor_update) ) ) ;
1361
+ return UpdateFulfillFetch :: NewClaim { monitor_update, msg : None } ;
1341
1362
}
1342
1363
log_trace ! ( logger, "Upgrading HTLC {} to LocalRemoved with a Fulfill in channel {}!" , log_bytes!( htlc. payment_hash. 0 ) , log_bytes!( self . channel_id) ) ;
1343
1364
htlc. state = InboundHTLCState :: LocalRemoved ( InboundHTLCRemovalReason :: Fulfill ( payment_preimage_arg. clone ( ) ) ) ;
1344
1365
}
1345
1366
1346
- Ok ( ( Some ( msgs:: UpdateFulfillHTLC {
1347
- channel_id : self . channel_id ( ) ,
1348
- htlc_id : htlc_id_arg,
1349
- payment_preimage : payment_preimage_arg,
1350
- } ) , Some ( monitor_update) ) )
1367
+ UpdateFulfillFetch :: NewClaim {
1368
+ monitor_update,
1369
+ msg : Some ( msgs:: UpdateFulfillHTLC {
1370
+ channel_id : self . channel_id ( ) ,
1371
+ htlc_id : htlc_id_arg,
1372
+ payment_preimage : payment_preimage_arg,
1373
+ } ) ,
1374
+ }
1351
1375
}
1352
1376
1353
- pub fn get_update_fulfill_htlc_and_commit < L : Deref > ( & mut self , htlc_id : u64 , payment_preimage : PaymentPreimage , logger : & L ) -> Result < ( Option < ( msgs :: UpdateFulfillHTLC , msgs :: CommitmentSigned ) > , Option < ChannelMonitorUpdate > ) , ChannelError > where L :: Target : Logger {
1354
- match self . get_update_fulfill_htlc ( htlc_id, payment_preimage, logger) ? {
1355
- ( Some ( update_fulfill_htlc ) , Some ( mut monitor_update) ) => {
1377
+ pub fn get_update_fulfill_htlc_and_commit < L : Deref > ( & mut self , htlc_id : u64 , payment_preimage : PaymentPreimage , logger : & L ) -> Result < UpdateFulfillCommitFetch , ChannelError > where L :: Target : Logger {
1378
+ match self . get_update_fulfill_htlc ( htlc_id, payment_preimage, logger) {
1379
+ UpdateFulfillFetch :: NewClaim { mut monitor_update, msg : Some ( update_fulfill_htlc ) } => {
1356
1380
let ( commitment, mut additional_update) = self . send_commitment_no_status_check ( logger) ?;
1357
1381
// send_commitment_no_status_check may bump latest_monitor_id but we want them to be
1358
1382
// strictly increasing by one, so decrement it here.
1359
1383
self . latest_monitor_update_id = monitor_update. update_id ;
1360
1384
monitor_update. updates . append ( & mut additional_update. updates ) ;
1361
- Ok ( ( Some ( ( update_fulfill_htlc, commitment) ) , Some ( monitor_update) ) )
1362
- } ,
1363
- ( Some ( update_fulfill_htlc) , None ) => {
1364
- let ( commitment, monitor_update) = self . send_commitment_no_status_check ( logger) ?;
1365
- Ok ( ( Some ( ( update_fulfill_htlc, commitment) ) , Some ( monitor_update) ) )
1385
+ Ok ( UpdateFulfillCommitFetch :: NewClaim { monitor_update, msgs : Some ( ( update_fulfill_htlc, commitment) ) } )
1366
1386
} ,
1367
- ( None , Some ( monitor_update) ) => Ok ( ( None , Some ( monitor_update) ) ) ,
1368
- ( None , None ) => Ok ( ( None , None ) )
1387
+ UpdateFulfillFetch :: NewClaim { monitor_update, msg : None } => Ok ( UpdateFulfillCommitFetch :: NewClaim { monitor_update, msgs : None } ) ,
1388
+ UpdateFulfillFetch :: DuplicateClaim { } => Ok ( UpdateFulfillCommitFetch :: DuplicateClaim { } ) ,
1369
1389
}
1370
1390
}
1371
1391
1372
- /// Per HTLC, only one get_update_fail_htlc or get_update_fulfill_htlc call may be made.
1373
- /// In such cases we debug_assert!(false) and return a ChannelError::Ignore. Thus, will always
1374
- /// return Ok(_) if debug assertions are turned on or preconditions are met.
1375
- ///
1376
- /// Note that it is still possible to hit these assertions in case we find a preimage on-chain
1377
- /// but then have a reorg which settles on an HTLC-failure on chain .
1392
+ /// We can only have one resolution per HTLC. In some cases around reconnect, we may fulfill
1393
+ /// an HTLC more than once or fulfill once and then attempt to fail after reconnect. We cannot,
1394
+ /// however, fail more than once as we wait for an upstream failure to be irrevocably committed
1395
+ /// before we fail backwards.
1396
+ /// If we do fail twice, we debug_assert!(false) and return Ok(None). Thus, will always return
1397
+ /// Ok(_) if debug assertions are turned on or preconditions are met .
1378
1398
pub fn get_update_fail_htlc < L : Deref > ( & mut self , htlc_id_arg : u64 , err_packet : msgs:: OnionErrorPacket , logger : & L ) -> Result < Option < msgs:: UpdateFailHTLC > , ChannelError > where L :: Target : Logger {
1379
1399
if ( self . channel_state & ( ChannelState :: ChannelFunded as u32 ) ) != ( ChannelState :: ChannelFunded as u32 ) {
1380
1400
panic ! ( "Was asked to fail an HTLC when channel was not in an operational state" ) ;
@@ -2468,20 +2488,17 @@ impl<Signer: Sign> Channel<Signer> {
2468
2488
}
2469
2489
} ,
2470
2490
& HTLCUpdateAwaitingACK :: ClaimHTLC { ref payment_preimage, htlc_id, .. } => {
2471
- match self . get_update_fulfill_htlc ( htlc_id, * payment_preimage, logger) {
2472
- Ok ( ( update_fulfill_msg_option, additional_monitor_update_opt) ) => {
2473
- update_fulfill_htlcs. push ( update_fulfill_msg_option. unwrap ( ) ) ;
2474
- if let Some ( mut additional_monitor_update) = additional_monitor_update_opt {
2475
- monitor_update. updates . append ( & mut additional_monitor_update. updates ) ;
2476
- }
2477
- } ,
2478
- Err ( e) => {
2479
- if let ChannelError :: Ignore ( _) = e { }
2480
- else {
2481
- panic ! ( "Got a non-IgnoreError action trying to fulfill holding cell HTLC" ) ;
2482
- }
2483
- }
2484
- }
2491
+ // If an HTLC claim was previously added to the holding cell (via
2492
+ // `get_update_fulfill_htlc`, then generating the claim message itself must
2493
+ // not fail - any in between attempts to claim the HTLC will have resulted
2494
+ // in it hitting the holding cell again and we cannot change the state of a
2495
+ // holding cell HTLC from fulfill to anything else.
2496
+ let ( update_fulfill_msg_option, mut additional_monitor_update) =
2497
+ if let UpdateFulfillFetch :: NewClaim { msg, monitor_update } = self . get_update_fulfill_htlc ( htlc_id, * payment_preimage, logger) {
2498
+ ( msg, monitor_update)
2499
+ } else { unreachable ! ( ) } ;
2500
+ update_fulfill_htlcs. push ( update_fulfill_msg_option. unwrap ( ) ) ;
2501
+ monitor_update. updates . append ( & mut additional_monitor_update. updates ) ;
2485
2502
} ,
2486
2503
& HTLCUpdateAwaitingACK :: FailHTLC { htlc_id, ref err_packet } => {
2487
2504
match self . get_update_fail_htlc ( htlc_id, err_packet. clone ( ) , logger) {
0 commit comments