@@ -14,7 +14,7 @@ use std::sync::Arc;
1414use bitcoin:: address:: NetworkUnchecked ;
1515use bitcoin:: hashes:: sha256:: Hash as Sha256Hash ;
1616use bitcoin:: hashes:: Hash ;
17- use bitcoin:: { Address , Amount , ScriptBuf } ;
17+ use bitcoin:: { Address , Amount , ScriptBuf , Txid } ;
1818use common:: logging:: { init_log_logger, validate_log_entry, MultiNodeLogger , TestLogWriter } ;
1919use common:: {
2020 bump_fee_and_broadcast, distribute_funds_unconfirmed, do_channel_full_cycle,
@@ -685,8 +685,111 @@ async fn onchain_wallet_recovery() {
685685}
686686
687687#[ tokio:: test( flavor = "multi_thread" , worker_threads = 1 ) ]
688- async fn test_rbf_via_mempool ( ) {
689- run_rbf_test ( false ) . await ;
688+ async fn onchain_fee_bump_rbf ( ) {
689+ let ( bitcoind, electrsd) = setup_bitcoind_and_electrsd ( ) ;
690+ let chain_source = TestChainSource :: Esplora ( & electrsd) ;
691+ let ( node_a, node_b) = setup_two_nodes ( & chain_source, false , true , false ) ;
692+
693+ // Fund both nodes
694+ let addr_a = node_a. onchain_payment ( ) . new_address ( ) . unwrap ( ) ;
695+ let addr_b = node_b. onchain_payment ( ) . new_address ( ) . unwrap ( ) ;
696+
697+ let premine_amount_sat = 500_000 ;
698+ premine_and_distribute_funds (
699+ & bitcoind. client ,
700+ & electrsd. client ,
701+ vec ! [ addr_a. clone( ) , addr_b. clone( ) ] ,
702+ Amount :: from_sat ( premine_amount_sat) ,
703+ )
704+ . await ;
705+
706+ node_a. sync_wallets ( ) . unwrap ( ) ;
707+ node_b. sync_wallets ( ) . unwrap ( ) ;
708+
709+ // Send a transaction from node_b to node_a that we'll later bump
710+ let amount_to_send_sats = 100_000 ;
711+ let txid =
712+ node_b. onchain_payment ( ) . send_to_address ( & addr_a, amount_to_send_sats, None ) . unwrap ( ) ;
713+ wait_for_tx ( & electrsd. client , txid) . await ;
714+ node_a. sync_wallets ( ) . unwrap ( ) ;
715+ node_b. sync_wallets ( ) . unwrap ( ) ;
716+
717+ let payment_id = PaymentId ( txid. to_byte_array ( ) ) ;
718+ let original_payment = node_b. payment ( & payment_id) . unwrap ( ) ;
719+ let original_fee = original_payment. fee_paid_msat . unwrap ( ) ;
720+
721+ // Non-existent payment id
722+ let fake_txid =
723+ Txid :: from_str ( "0000000000000000000000000000000000000000000000000000000000000000" ) . unwrap ( ) ;
724+ let invalid_payment_id = PaymentId ( fake_txid. to_byte_array ( ) ) ;
725+ assert_eq ! (
726+ Err ( NodeError :: InvalidPaymentId ) ,
727+ node_b. onchain_payment( ) . bump_fee_rbf( invalid_payment_id)
728+ ) ;
729+
730+ // Bump an inbound payment
731+ assert_eq ! ( Err ( NodeError :: InvalidPaymentId ) , node_a. onchain_payment( ) . bump_fee_rbf( payment_id) ) ;
732+
733+ // Successful fee bump
734+ let new_txid = node_b. onchain_payment ( ) . bump_fee_rbf ( payment_id) . unwrap ( ) ;
735+ wait_for_tx ( & electrsd. client , new_txid) . await ;
736+
737+ // Sleep to allow for transaction propagation
738+ tokio:: time:: sleep ( std:: time:: Duration :: from_secs ( 5 ) ) . await ;
739+
740+ node_a. sync_wallets ( ) . unwrap ( ) ;
741+ node_b. sync_wallets ( ) . unwrap ( ) ;
742+
743+ // Verify fee increased
744+ let new_payment = node_b. payment ( & payment_id) . unwrap ( ) ;
745+ assert ! (
746+ new_payment. fee_paid_msat > Some ( original_fee) ,
747+ "Fee should increase after RBF bump. Original: {}, New: {}" ,
748+ original_fee,
749+ new_payment. fee_paid_msat. unwrap( )
750+ ) ;
751+
752+ // Multiple consecutive bumps
753+ let second_bump_txid = node_b. onchain_payment ( ) . bump_fee_rbf ( payment_id) . unwrap ( ) ;
754+ wait_for_tx ( & electrsd. client , second_bump_txid) . await ;
755+
756+ // Sleep to allow for transaction propagation
757+ tokio:: time:: sleep ( std:: time:: Duration :: from_secs ( 5 ) ) . await ;
758+
759+ node_a. sync_wallets ( ) . unwrap ( ) ;
760+ node_b. sync_wallets ( ) . unwrap ( ) ;
761+
762+ // Verify second bump payment exists
763+ let second_payment = node_b. payment ( & payment_id) . unwrap ( ) ;
764+ assert ! (
765+ second_payment. fee_paid_msat > new_payment. fee_paid_msat,
766+ "Second bump should have higher fee than first bump"
767+ ) ;
768+
769+ // Confirm the transaction and try to bump again (should fail)
770+ generate_blocks_and_wait ( & bitcoind. client , & electrsd. client , 6 ) . await ;
771+ node_a. sync_wallets ( ) . unwrap ( ) ;
772+ node_b. sync_wallets ( ) . unwrap ( ) ;
773+
774+ assert_eq ! ( Err ( NodeError :: InvalidPaymentId ) , node_b. onchain_payment( ) . bump_fee_rbf( payment_id) ) ;
775+
776+ // Verify final payment is confirmed
777+ let final_payment = node_b. payment ( & payment_id) . unwrap ( ) ;
778+ assert_eq ! ( final_payment. status, PaymentStatus :: Succeeded ) ;
779+ match final_payment. kind {
780+ PaymentKind :: Onchain { status, .. } => {
781+ assert ! ( matches!( status, ConfirmationStatus :: Confirmed { .. } ) ) ;
782+ } ,
783+ _ => panic ! ( "Unexpected payment kind" ) ,
784+ }
785+
786+ // Verify node A received the funds correctly
787+ let node_a_received_payment = node_a. list_payments_with_filter (
788+ |p| matches ! ( p. kind, PaymentKind :: Onchain { txid, .. } if txid == second_bump_txid) ,
789+ ) ;
790+ assert_eq ! ( node_a_received_payment. len( ) , 1 ) ;
791+ assert_eq ! ( node_a_received_payment[ 0 ] . amount_msat, Some ( amount_to_send_sats * 1000 ) ) ;
792+ assert_eq ! ( node_a_received_payment[ 0 ] . status, PaymentStatus :: Succeeded ) ;
690793}
691794
692795#[ tokio:: test( flavor = "multi_thread" , worker_threads = 1 ) ]
0 commit comments