@@ -1778,6 +1778,157 @@ fn test_restored_packages_retry() {
1778
1778
do_test_restored_packages_retry ( true ) ;
1779
1779
}
1780
1780
1781
+ fn do_test_monitor_rebroadcast_pending_claims ( anchors : bool ) {
1782
+ // Test that we will retry broadcasting pending claims for a force-closed channel on every
1783
+ // `ChainMonitor::rebroadcast_pending_claims` call.
1784
+ if anchors {
1785
+ assert ! ( cfg!( anchors) ) ;
1786
+ }
1787
+ let secp = Secp256k1 :: new ( ) ;
1788
+ let mut chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
1789
+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
1790
+ let mut config = test_default_channel_config ( ) ;
1791
+ if anchors {
1792
+ #[ cfg( anchors) ] {
1793
+ config. channel_handshake_config . negotiate_anchors_zero_fee_htlc_tx = true ;
1794
+ }
1795
+ }
1796
+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ Some ( config) , Some ( config) ] ) ;
1797
+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
1798
+
1799
+ let ( _, _, _, chan_id, funding_tx) = create_chan_between_nodes_with_value (
1800
+ & nodes[ 0 ] , & nodes[ 1 ] , 1_000_000 , 500_000_000
1801
+ ) ;
1802
+ const HTLC_AMT_MSAT : u64 = 1_000_000 ;
1803
+ const HTLC_AMT_SAT : u64 = HTLC_AMT_MSAT / 1000 ;
1804
+ route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , HTLC_AMT_MSAT ) ;
1805
+
1806
+ let htlc_expiry = nodes[ 0 ] . best_block_info ( ) . 1 + TEST_FINAL_CLTV + 1 ;
1807
+
1808
+ let commitment_txn = get_local_commitment_txn ! ( & nodes[ 0 ] , & chan_id) ;
1809
+ assert_eq ! ( commitment_txn. len( ) , if anchors { 1 /* commitment tx only */ } else { 2 /* commitment and htlc timeout tx */ } ) ;
1810
+ check_spends ! ( & commitment_txn[ 0 ] , & funding_tx) ;
1811
+ mine_transaction ( & nodes[ 0 ] , & commitment_txn[ 0 ] ) ;
1812
+ check_closed_broadcast ! ( & nodes[ 0 ] , true ) ;
1813
+ check_closed_event ( & nodes[ 0 ] , 1 , ClosureReason :: CommitmentTxConfirmed , false ) ;
1814
+ check_added_monitors ( & nodes[ 0 ] , 1 ) ;
1815
+
1816
+ // Set up a helper closure we'll use throughout our test. We should only expect retries without
1817
+ // bumps if fees have not increased after a block has been connected (assuming the height timer
1818
+ // re-evaluates at every block) or after `ChainMonitor::rebroadcast_pending_claims` is called.
1819
+ let mut prev_htlc_tx_feerate = None ;
1820
+ let mut check_htlc_retry = |should_retry : bool , should_bump : bool | -> Option < Transaction > {
1821
+ let ( htlc_tx, htlc_tx_feerate) = if anchors {
1822
+ assert ! ( nodes[ 0 ] . tx_broadcaster. txn_broadcast( ) . is_empty( ) ) ;
1823
+ let mut events = nodes[ 0 ] . chain_monitor . chain_monitor . get_and_clear_pending_events ( ) ;
1824
+ assert_eq ! ( events. len( ) , if should_retry { 1 } else { 0 } ) ;
1825
+ if !should_retry {
1826
+ return None ;
1827
+ }
1828
+ #[ allow( unused_assignments) ]
1829
+ let mut tx = Transaction {
1830
+ version : 2 ,
1831
+ lock_time : bitcoin:: PackedLockTime :: ZERO ,
1832
+ input : vec ! [ ] ,
1833
+ output : vec ! [ ] ,
1834
+ } ;
1835
+ #[ allow( unused_assignments) ]
1836
+ let mut feerate = 0 ;
1837
+ #[ cfg( anchors) ] {
1838
+ feerate = if let Event :: BumpTransaction ( BumpTransactionEvent :: HTLCResolution {
1839
+ target_feerate_sat_per_1000_weight, mut htlc_descriptors, tx_lock_time,
1840
+ } ) = events. pop ( ) . unwrap ( ) {
1841
+ assert_eq ! ( htlc_descriptors. len( ) , 1 ) ;
1842
+ let descriptor = htlc_descriptors. pop ( ) . unwrap ( ) ;
1843
+ assert_eq ! ( descriptor. commitment_txid, commitment_txn[ 0 ] . txid( ) ) ;
1844
+ let htlc_output_idx = descriptor. htlc . transaction_output_index . unwrap ( ) as usize ;
1845
+ assert ! ( htlc_output_idx < commitment_txn[ 0 ] . output. len( ) ) ;
1846
+ tx. lock_time = tx_lock_time;
1847
+ // Note that we don't care about actually making the HTLC transaction meet the
1848
+ // feerate for the test, we just want to make sure the feerates we receive from
1849
+ // the events never decrease.
1850
+ tx. input . push ( descriptor. unsigned_tx_input ( ) ) ;
1851
+ let signer = nodes[ 0 ] . keys_manager . derive_channel_keys (
1852
+ descriptor. channel_value_satoshis , & descriptor. channel_keys_id ,
1853
+ ) ;
1854
+ let per_commitment_point = signer. get_per_commitment_point (
1855
+ descriptor. per_commitment_number , & secp
1856
+ ) ;
1857
+ tx. output . push ( descriptor. tx_output ( & per_commitment_point, & secp) ) ;
1858
+ let our_sig = signer. sign_holder_htlc_transaction ( & mut tx, 0 , & descriptor, & secp) . unwrap ( ) ;
1859
+ let witness_script = descriptor. witness_script ( & per_commitment_point, & secp) ;
1860
+ tx. input [ 0 ] . witness = descriptor. tx_input_witness ( & our_sig, & witness_script) ;
1861
+ target_feerate_sat_per_1000_weight as u64
1862
+ } else { panic ! ( "unexpected event" ) ; } ;
1863
+ }
1864
+ ( tx, feerate)
1865
+ } else {
1866
+ assert ! ( nodes[ 0 ] . chain_monitor. chain_monitor. get_and_clear_pending_events( ) . is_empty( ) ) ;
1867
+ let mut txn = nodes[ 0 ] . tx_broadcaster . txn_broadcast ( ) ;
1868
+ assert_eq ! ( txn. len( ) , if should_retry { 1 } else { 0 } ) ;
1869
+ if !should_retry {
1870
+ return None ;
1871
+ }
1872
+ let htlc_tx = txn. pop ( ) . unwrap ( ) ;
1873
+ check_spends ! ( htlc_tx, commitment_txn[ 0 ] ) ;
1874
+ let htlc_tx_fee = HTLC_AMT_SAT - htlc_tx. output [ 0 ] . value ;
1875
+ let htlc_tx_feerate = htlc_tx_fee * 1000 / htlc_tx. weight ( ) as u64 ;
1876
+ ( htlc_tx, htlc_tx_feerate)
1877
+ } ;
1878
+ if should_bump {
1879
+ assert ! ( htlc_tx_feerate > prev_htlc_tx_feerate. take( ) . unwrap( ) ) ;
1880
+ } else if let Some ( prev_feerate) = prev_htlc_tx_feerate. take ( ) {
1881
+ assert_eq ! ( htlc_tx_feerate, prev_feerate) ;
1882
+ }
1883
+ prev_htlc_tx_feerate = Some ( htlc_tx_feerate) ;
1884
+ Some ( htlc_tx)
1885
+ } ;
1886
+
1887
+ // Connect blocks up to one before the HTLC expires. This should not result in a claim/retry.
1888
+ connect_blocks ( & nodes[ 0 ] , htlc_expiry - nodes[ 0 ] . best_block_info ( ) . 1 - 2 ) ;
1889
+ check_htlc_retry ( false , false ) ;
1890
+
1891
+ // Connect one more block, producing our first claim.
1892
+ connect_blocks ( & nodes[ 0 ] , 1 ) ;
1893
+ check_htlc_retry ( true , false ) ;
1894
+
1895
+ // Connect one more block, expecting a retry with a fee bump. Unfortunately, we cannot bump HTLC
1896
+ // transactions pre-anchors.
1897
+ connect_blocks ( & nodes[ 0 ] , 1 ) ;
1898
+ check_htlc_retry ( true , anchors) ;
1899
+
1900
+ // Trigger a call and we should have another retry, but without a bump.
1901
+ nodes[ 0 ] . chain_monitor . chain_monitor . rebroadcast_pending_claims ( ) ;
1902
+ check_htlc_retry ( true , false ) ;
1903
+
1904
+ // Double the feerate and trigger a call, expecting a fee-bumped retry.
1905
+ * nodes[ 0 ] . fee_estimator . sat_per_kw . lock ( ) . unwrap ( ) *= 2 ;
1906
+ nodes[ 0 ] . chain_monitor . chain_monitor . rebroadcast_pending_claims ( ) ;
1907
+ check_htlc_retry ( true , anchors) ;
1908
+
1909
+ // Connect one more block, expecting a retry with a fee bump. Unfortunately, we cannot bump HTLC
1910
+ // transactions pre-anchors.
1911
+ connect_blocks ( & nodes[ 0 ] , 1 ) ;
1912
+ let htlc_tx = check_htlc_retry ( true , anchors) . unwrap ( ) ;
1913
+
1914
+ // Mine the HTLC transaction to ensure we don't retry claims while they're confirmed.
1915
+ mine_transaction ( & nodes[ 0 ] , & htlc_tx) ;
1916
+ // If we have a `ConnectStyle` that advertises the new block first without the transasctions,
1917
+ // we'll receive an extra bumped claim.
1918
+ if nodes[ 0 ] . connect_style . borrow ( ) . updates_best_block_first ( ) {
1919
+ check_htlc_retry ( true , anchors) ;
1920
+ }
1921
+ nodes[ 0 ] . chain_monitor . chain_monitor . rebroadcast_pending_claims ( ) ;
1922
+ check_htlc_retry ( false , false ) ;
1923
+ }
1924
+
1925
+ #[ test]
1926
+ fn test_monitor_timer_based_claim ( ) {
1927
+ do_test_monitor_rebroadcast_pending_claims ( false ) ;
1928
+ #[ cfg( anchors) ]
1929
+ do_test_monitor_rebroadcast_pending_claims ( true ) ;
1930
+ }
1931
+
1781
1932
#[ cfg( anchors) ]
1782
1933
#[ test]
1783
1934
fn test_yield_anchors_events ( ) {
0 commit comments