@@ -786,7 +786,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
786
786
let mut preprocessed_requests = Vec :: with_capacity ( requests. len ( ) ) ;
787
787
for req in requests {
788
788
let package_locktime = req. package_locktime ( cur_height) ;
789
- if package_locktime > cur_height + 1 {
789
+ if package_locktime > cur_height {
790
790
log_info ! ( logger, "Delaying claim of package until its timelock at {} (current height {}), the following outpoints are spent:" , package_locktime, cur_height) ;
791
791
for outpoint in req. outpoints ( ) {
792
792
log_info ! ( logger, " Outpoint {}" , outpoint) ;
@@ -1276,3 +1276,178 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
1276
1276
& self . channel_transaction_parameters . channel_type_features
1277
1277
}
1278
1278
}
1279
+
1280
+ #[ cfg( test) ]
1281
+ mod tests {
1282
+ use bitcoin:: hash_types:: Txid ;
1283
+ use bitcoin:: hashes:: sha256:: Hash as Sha256 ;
1284
+ use bitcoin:: hashes:: Hash ;
1285
+ use bitcoin:: Network ;
1286
+ use bitcoin:: { key:: Secp256k1 , secp256k1:: PublicKey , secp256k1:: SecretKey , ScriptBuf } ;
1287
+ use types:: features:: ChannelTypeFeatures ;
1288
+
1289
+ use crate :: chain:: chaininterface:: { ConfirmationTarget , LowerBoundedFeeEstimator } ;
1290
+ use crate :: chain:: package:: { HolderHTLCOutput , PackageSolvingData , PackageTemplate } ;
1291
+ use crate :: chain:: transaction:: OutPoint ;
1292
+ use crate :: ln:: chan_utils:: {
1293
+ ChannelPublicKeys , ChannelTransactionParameters , CounterpartyChannelTransactionParameters ,
1294
+ HTLCOutputInCommitment , HolderCommitmentTransaction ,
1295
+ } ;
1296
+ use crate :: ln:: channel_keys:: { DelayedPaymentBasepoint , HtlcBasepoint , RevocationBasepoint } ;
1297
+ use crate :: ln:: functional_test_utils:: create_dummy_block;
1298
+ use crate :: sign:: InMemorySigner ;
1299
+ use crate :: types:: payment:: { PaymentHash , PaymentPreimage } ;
1300
+ use crate :: util:: test_utils:: { TestBroadcaster , TestFeeEstimator , TestLogger } ;
1301
+
1302
+ use super :: OnchainTxHandler ;
1303
+
1304
+ // Test that all claims with locktime equal to or less than the current height are broadcast
1305
+ // immediately while claims with locktime greater than the current height are only broadcast
1306
+ // once the locktime is reached.
1307
+ #[ test]
1308
+ fn test_broadcast_height ( ) {
1309
+ let secp_ctx = Secp256k1 :: new ( ) ;
1310
+ let signer = InMemorySigner :: new (
1311
+ & secp_ctx,
1312
+ SecretKey :: from_slice ( & [ 41 ; 32 ] ) . unwrap ( ) ,
1313
+ SecretKey :: from_slice ( & [ 41 ; 32 ] ) . unwrap ( ) ,
1314
+ SecretKey :: from_slice ( & [ 41 ; 32 ] ) . unwrap ( ) ,
1315
+ SecretKey :: from_slice ( & [ 41 ; 32 ] ) . unwrap ( ) ,
1316
+ SecretKey :: from_slice ( & [ 41 ; 32 ] ) . unwrap ( ) ,
1317
+ [ 41 ; 32 ] ,
1318
+ 0 ,
1319
+ [ 0 ; 32 ] ,
1320
+ [ 0 ; 32 ] ,
1321
+ ) ;
1322
+ let counterparty_pubkeys = ChannelPublicKeys {
1323
+ funding_pubkey : PublicKey :: from_secret_key (
1324
+ & secp_ctx,
1325
+ & SecretKey :: from_slice ( & [ 44 ; 32 ] ) . unwrap ( ) ,
1326
+ ) ,
1327
+ revocation_basepoint : RevocationBasepoint :: from ( PublicKey :: from_secret_key (
1328
+ & secp_ctx,
1329
+ & SecretKey :: from_slice ( & [ 45 ; 32 ] ) . unwrap ( ) ,
1330
+ ) ) ,
1331
+ payment_point : PublicKey :: from_secret_key (
1332
+ & secp_ctx,
1333
+ & SecretKey :: from_slice ( & [ 46 ; 32 ] ) . unwrap ( ) ,
1334
+ ) ,
1335
+ delayed_payment_basepoint : DelayedPaymentBasepoint :: from ( PublicKey :: from_secret_key (
1336
+ & secp_ctx,
1337
+ & SecretKey :: from_slice ( & [ 47 ; 32 ] ) . unwrap ( ) ,
1338
+ ) ) ,
1339
+ htlc_basepoint : HtlcBasepoint :: from ( PublicKey :: from_secret_key (
1340
+ & secp_ctx,
1341
+ & SecretKey :: from_slice ( & [ 48 ; 32 ] ) . unwrap ( ) ,
1342
+ ) ) ,
1343
+ } ;
1344
+ let funding_outpoint = OutPoint { txid : Txid :: all_zeros ( ) , index : u16:: MAX } ;
1345
+
1346
+ // Use non-anchor channels so that HTLC-Timeouts are broadcast immediately instead of sent
1347
+ // to the user for external funding.
1348
+ let chan_params = ChannelTransactionParameters {
1349
+ holder_pubkeys : signer. holder_channel_pubkeys . clone ( ) ,
1350
+ holder_selected_contest_delay : 66 ,
1351
+ is_outbound_from_holder : true ,
1352
+ counterparty_parameters : Some ( CounterpartyChannelTransactionParameters {
1353
+ pubkeys : counterparty_pubkeys,
1354
+ selected_contest_delay : 67 ,
1355
+ } ) ,
1356
+ funding_outpoint : Some ( funding_outpoint) ,
1357
+ channel_type_features : ChannelTypeFeatures :: only_static_remote_key ( ) ,
1358
+ } ;
1359
+
1360
+ // Create an OnchainTxHandler for a commitment containing HTLCs with CLTV expiries of 0, 1,
1361
+ // and 2 blocks.
1362
+ let mut htlcs = Vec :: new ( ) ;
1363
+ for i in 0 ..3 {
1364
+ let preimage = PaymentPreimage ( [ i; 32 ] ) ;
1365
+ let hash = PaymentHash ( Sha256 :: hash ( & preimage. 0 [ ..] ) . to_byte_array ( ) ) ;
1366
+ htlcs. push ( (
1367
+ HTLCOutputInCommitment {
1368
+ offered : true ,
1369
+ amount_msat : 10000 ,
1370
+ cltv_expiry : i as u32 ,
1371
+ payment_hash : hash,
1372
+ transaction_output_index : Some ( i as u32 ) ,
1373
+ } ,
1374
+ ( ) ,
1375
+ ) ) ;
1376
+ }
1377
+ let holder_commit = HolderCommitmentTransaction :: dummy ( & mut htlcs) ;
1378
+ let mut tx_handler = OnchainTxHandler :: new (
1379
+ 1000000 ,
1380
+ [ 0 ; 32 ] ,
1381
+ ScriptBuf :: new ( ) ,
1382
+ signer,
1383
+ chan_params,
1384
+ holder_commit,
1385
+ secp_ctx,
1386
+ ) ;
1387
+
1388
+ // Create a broadcaster with current block height 1.
1389
+ let broadcaster = TestBroadcaster :: new ( Network :: Testnet ) ;
1390
+ {
1391
+ let mut blocks = broadcaster. blocks . lock ( ) . unwrap ( ) ;
1392
+ let genesis_hash = blocks[ 0 ] . 0 . block_hash ( ) ;
1393
+ blocks. push ( ( create_dummy_block ( genesis_hash, 0 , Vec :: new ( ) ) , 1 ) ) ;
1394
+ }
1395
+
1396
+ let fee_estimator = TestFeeEstimator :: new ( 253 ) ;
1397
+ let fee_estimator = LowerBoundedFeeEstimator :: new ( & fee_estimator) ;
1398
+ let logger = TestLogger :: new ( ) ;
1399
+
1400
+ // Request claiming of each HTLC on the holder's commitment, with current block height 1.
1401
+ let holder_commit_txid = tx_handler. get_unsigned_holder_commitment_tx ( ) . compute_txid ( ) ;
1402
+ let mut requests = Vec :: new ( ) ;
1403
+ for ( htlc, _) in htlcs {
1404
+ requests. push ( PackageTemplate :: build_package (
1405
+ holder_commit_txid,
1406
+ htlc. transaction_output_index . unwrap ( ) ,
1407
+ PackageSolvingData :: HolderHTLCOutput ( HolderHTLCOutput :: build_offered (
1408
+ htlc. amount_msat ,
1409
+ htlc. cltv_expiry ,
1410
+ ChannelTypeFeatures :: only_static_remote_key ( ) ,
1411
+ ) ) ,
1412
+ 0 ,
1413
+ ) ) ;
1414
+ }
1415
+ tx_handler. update_claims_view_from_requests (
1416
+ requests,
1417
+ 1 ,
1418
+ 1 ,
1419
+ & & broadcaster,
1420
+ ConfirmationTarget :: UrgentOnChainSweep ,
1421
+ & fee_estimator,
1422
+ & logger,
1423
+ ) ;
1424
+
1425
+ // HTLC-Timeouts should be broadcast for the HTLCs with expiries at heights 0 and 1. The
1426
+ // HTLC with expiry at height 2 should not be claimed yet.
1427
+ let txs_broadcasted = broadcaster. txn_broadcast ( ) ;
1428
+ assert_eq ! ( txs_broadcasted. len( ) , 2 ) ;
1429
+ assert ! ( txs_broadcasted[ 0 ] . lock_time. to_consensus_u32( ) <= 1 ) ;
1430
+ assert ! ( txs_broadcasted[ 1 ] . lock_time. to_consensus_u32( ) <= 1 ) ;
1431
+
1432
+ // Advance to block height 2, and reprocess pending claims.
1433
+ {
1434
+ let mut blocks = broadcaster. blocks . lock ( ) . unwrap ( ) ;
1435
+ let block1_hash = blocks[ 1 ] . 0 . block_hash ( ) ;
1436
+ blocks. push ( ( create_dummy_block ( block1_hash, 0 , Vec :: new ( ) ) , 2 ) ) ;
1437
+ }
1438
+ tx_handler. update_claims_view_from_requests (
1439
+ Vec :: new ( ) ,
1440
+ 2 ,
1441
+ 2 ,
1442
+ & & broadcaster,
1443
+ ConfirmationTarget :: UrgentOnChainSweep ,
1444
+ & fee_estimator,
1445
+ & logger,
1446
+ ) ;
1447
+
1448
+ // The final HTLC-Timeout should now be broadcast.
1449
+ let txs_broadcasted = broadcaster. txn_broadcast ( ) ;
1450
+ assert_eq ! ( txs_broadcasted. len( ) , 1 ) ;
1451
+ assert_eq ! ( txs_broadcasted[ 0 ] . lock_time. to_consensus_u32( ) , 2 ) ;
1452
+ }
1453
+ }
0 commit comments