@@ -786,7 +786,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
786786		let  mut  preprocessed_requests = Vec :: with_capacity ( requests. len ( ) ) ; 
787787		for  req in  requests { 
788788			let  package_locktime = req. package_locktime ( cur_height) ; 
789- 			if  package_locktime > cur_height +  1   { 
789+ 			if  package_locktime > cur_height { 
790790				log_info ! ( logger,  "Delaying claim of package until its timelock at {} (current height {}), the following outpoints are spent:" ,  package_locktime,  cur_height) ; 
791791				for  outpoint in  req. outpoints ( )  { 
792792					log_info ! ( logger,  "  Outpoint {}" ,  outpoint) ; 
@@ -1276,3 +1276,178 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
12761276		& self . channel_transaction_parameters . channel_type_features 
12771277	} 
12781278} 
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