@@ -5964,3 +5964,51 @@ fn test_bump_penalty_txn_on_revoked_htlc() {
5964
5964
}
5965
5965
}
5966
5966
}
5967
+
5968
+ #[ test]
5969
+ fn test_bump_claim_tx_on_htlc_outputs ( ) {
5970
+ // In case of claim txn with too low feerates for getting into mempools, RBF-bump them to be sure
5971
+ // we're able to claim htlc outputs on commitment txn before timelock expiration
5972
+
5973
+ let nodes = create_network ( 2 ) ;
5974
+
5975
+ let chan = create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1000000 , 59000000 ) ;
5976
+ let payment_preimage = route_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , 3000000 ) . 0 ;
5977
+
5978
+ let local_txn;
5979
+ {
5980
+ local_txn = nodes[ 0 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan. 2 ) . unwrap ( ) . last_local_commitment_txn . clone ( ) ;
5981
+ assert_eq ! ( local_txn[ 0 ] . output. len( ) , 3 ) ;
5982
+ assert_eq ! ( local_txn[ 0 ] . input. len( ) , 1 ) ;
5983
+ assert_eq ! ( local_txn[ 0 ] . input[ 0 ] . previous_output. txid, chan. 3 . txid( ) ) ;
5984
+ }
5985
+ let header = BlockHeader { version : 0x20000000 , prev_blockhash : Default :: default ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
5986
+ assert ! ( nodes[ 1 ] . node. claim_funds( payment_preimage) ) ;
5987
+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
5988
+ nodes[ 1 ] . chain_monitor . block_connected_with_filtering ( & Block { header, txdata : vec ! [ local_txn[ 0 ] . clone( ) ] } , 1 ) ;
5989
+ nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
5990
+
5991
+ let mut fee: u64 = 0 ;
5992
+ let mut txid = Default :: default ( ) ;
5993
+ {
5994
+ let mut node_txn = nodes[ 1 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) ;
5995
+ assert_eq ! ( node_txn. len( ) , 2 ) ;
5996
+ assert_eq ! ( node_txn[ 0 ] , node_txn[ 1 ] ) ;
5997
+ assert_eq ! ( node_txn[ 0 ] . input[ 0 ] . witness. last( ) . unwrap( ) . len( ) , OFFERED_HTLC_SCRIPT_WEIGHT ) ;
5998
+ check_spends ! ( node_txn[ 0 ] , local_txn[ 0 ] . clone( ) ) ;
5999
+ txid = node_txn[ 0 ] . txid ( ) ;
6000
+ fee = local_txn[ 0 ] . output [ node_txn[ 0 ] . input [ 0 ] . previous_output . vout as usize ] . value - node_txn[ 0 ] . output [ 0 ] . value ;
6001
+ node_txn. clear ( ) ;
6002
+ }
6003
+ assert_ne ! ( fee, 0 ) ;
6004
+ connect_blocks ( & nodes[ 1 ] . chain_monitor , 3 , 1 , true , header. bitcoin_hash ( ) ) ;
6005
+ {
6006
+ let node_txn = nodes[ 1 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) ;
6007
+ assert_eq ! ( node_txn. len( ) , 1 ) ;
6008
+ check_spends ! ( node_txn[ 0 ] , local_txn[ 0 ] . clone( ) ) ;
6009
+ assert_ne ! ( txid, node_txn[ 0 ] . txid( ) ) ;
6010
+ let new_fee = local_txn[ 0 ] . output [ node_txn[ 0 ] . input [ 0 ] . previous_output . vout as usize ] . value - node_txn[ 0 ] . output [ 0 ] . value ;
6011
+ assert ! ( new_fee > fee) ;
6012
+ }
6013
+ //TODO: timeout tx case (maybe need to change its broadcast height first)
6014
+ }
0 commit comments