@@ -11,7 +11,7 @@ use common::{
1111 bump_fee_and_broadcast, distribute_funds_unconfirmed, do_channel_full_cycle,
1212 expect_channel_pending_event, expect_channel_ready_event, expect_event,
1313 expect_payment_claimable_event, expect_payment_received_event, expect_payment_successful_event,
14- generate_blocks_and_wait,
14+ generate_block_and_insert_transactions , generate_blocks_and_wait,
1515 logging:: { init_log_logger, validate_log_entry, TestLogWriter } ,
1616 new_node, open_channel, premine_and_distribute_funds, premine_blocks, prepare_rbf,
1717 random_config, random_listening_addresses, setup_bitcoind_and_electrsd, setup_builder,
@@ -672,19 +672,24 @@ fn onchain_wallet_recovery() {
672672}
673673
674674#[ test]
675- fn test_rbf_via_mempool ( ) {
676- run_rbf_test ( false ) ;
675+ fn test_rbf_only_in_mempool ( ) {
676+ run_rbf_test ( false , false ) ;
677677}
678678
679679#[ test]
680- fn test_rbf_via_direct_block_insertion ( ) {
681- run_rbf_test ( true ) ;
680+ fn test_rbf_direct_block_insertion_rbf_tx ( ) {
681+ run_rbf_test ( true , false ) ;
682+ }
683+
684+ #[ test]
685+ fn test_rbf_direct_block_insertion_original_tx ( ) {
686+ run_rbf_test ( false , true ) ;
682687}
683688
684689// `is_insert_block`:
685690// - `true`: transaction is mined immediately (no mempool), testing confirmed-Tx handling.
686691// - `false`: transaction stays in mempool until confirmation, testing unconfirmed-Tx handling.
687- fn run_rbf_test ( is_insert_block : bool ) {
692+ fn run_rbf_test ( is_insert_block : bool , is_insertion_original_tx : bool ) {
688693 let ( bitcoind, electrsd) = setup_bitcoind_and_electrsd ( ) ;
689694 let chain_source_bitcoind = TestChainSource :: BitcoindRpcSync ( & bitcoind) ;
690695 let chain_source_electrsd = TestChainSource :: Electrum ( & electrsd) ;
@@ -727,58 +732,98 @@ fn run_rbf_test(is_insert_block: bool) {
727732 } ;
728733 }
729734
735+ macro_rules! validate_total_onchain_balance {
736+ ( $expected_balance_sat: expr) => {
737+ for node in & nodes {
738+ node. sync_wallets( ) . unwrap( ) ;
739+ let balances = node. list_balances( ) ;
740+ assert_eq!( balances. total_onchain_balance_sats, $expected_balance_sat) ;
741+ }
742+ } ;
743+ }
744+
730745 let scripts_buf: HashSet < ScriptBuf > =
731746 all_addrs. iter ( ) . map ( |addr| addr. script_pubkey ( ) ) . collect ( ) ;
732747 let mut tx;
733748 let mut fee_output_index;
734749
735- // Modify the output to the nodes
750+ let mut final_amount_sat = 0 ;
751+ let mut original_tx;
752+
753+ // Step 1: Bump fee and change output address
736754 distribute_funds_all_nodes ! ( ) ;
737755 validate_balances ! ( amount_sat, false ) ;
738756 ( tx, fee_output_index) = prepare_rbf ( electrs, txid, & scripts_buf) ;
757+ original_tx = tx. clone ( ) ;
739758 tx. output . iter_mut ( ) . for_each ( |output| {
740759 if scripts_buf. contains ( & output. script_pubkey ) {
741760 let new_addr = bitcoind. new_address ( ) . unwrap ( ) ;
742761 output. script_pubkey = new_addr. script_pubkey ( ) ;
743762 }
744763 } ) ;
745764 bump_fee_and_broadcast ( bitcoind, electrs, tx, fee_output_index, is_insert_block) ;
746- validate_balances ! ( 0 , is_insert_block) ;
765+ if is_insertion_original_tx {
766+ generate_block_and_insert_transactions ( bitcoind, electrs, & [ original_tx. clone ( ) ] ) ;
767+ }
768+ if is_insertion_original_tx {
769+ final_amount_sat += amount_sat;
770+ }
771+ validate_balances ! ( final_amount_sat, is_insert_block || is_insertion_original_tx) ;
747772
748- // Not modifying the output scripts, but still bumping the fee.
773+ // Step 2: Bump fee only
749774 distribute_funds_all_nodes ! ( ) ;
750- validate_balances ! ( amount_sat, false ) ;
775+ validate_total_onchain_balance ! ( amount_sat + final_amount_sat ) ;
751776 ( tx, fee_output_index) = prepare_rbf ( electrs, txid, & scripts_buf) ;
777+ original_tx = tx. clone ( ) ;
752778 bump_fee_and_broadcast ( bitcoind, electrs, tx, fee_output_index, is_insert_block) ;
753- validate_balances ! ( amount_sat, is_insert_block) ;
779+ if is_insertion_original_tx {
780+ generate_block_and_insert_transactions ( bitcoind, electrs, & [ original_tx. clone ( ) ] ) ;
781+ }
782+ final_amount_sat += amount_sat;
783+ validate_balances ! ( final_amount_sat, is_insert_block || is_insertion_original_tx) ;
754784
755- let mut final_amount_sat = amount_sat * 2 ;
785+ // Step 3: Increase output value
756786 let value_sat = 21_000 ;
757-
758- // Increase the value of the nodes' outputs
759787 distribute_funds_all_nodes ! ( ) ;
788+ validate_total_onchain_balance ! ( amount_sat + final_amount_sat) ;
760789 ( tx, fee_output_index) = prepare_rbf ( electrs, txid, & scripts_buf) ;
790+ original_tx = tx. clone ( ) ;
761791 tx. output . iter_mut ( ) . for_each ( |output| {
762792 if scripts_buf. contains ( & output. script_pubkey ) {
763793 output. value = Amount :: from_sat ( output. value . to_sat ( ) + value_sat) ;
764794 }
765795 } ) ;
796+ tx. output [ fee_output_index] . value -= Amount :: from_sat ( scripts_buf. len ( ) as u64 * value_sat) ;
766797 bump_fee_and_broadcast ( bitcoind, electrs, tx, fee_output_index, is_insert_block) ;
767- final_amount_sat += value_sat;
768- validate_balances ! ( final_amount_sat, is_insert_block) ;
798+ if is_insertion_original_tx {
799+ generate_block_and_insert_transactions ( bitcoind, electrs, & [ original_tx. clone ( ) ] ) ;
800+ }
801+ final_amount_sat += amount_sat;
802+ if !is_insertion_original_tx {
803+ final_amount_sat += value_sat;
804+ }
805+ validate_balances ! ( final_amount_sat, is_insert_block || is_insertion_original_tx) ;
769806
770- // Decreases the value of the nodes' outputs
807+ // Step 4: Decrease output value
771808 distribute_funds_all_nodes ! ( ) ;
772- final_amount_sat += amount_sat ;
809+ validate_total_onchain_balance ! ( amount_sat + final_amount_sat ) ;
773810 ( tx, fee_output_index) = prepare_rbf ( electrs, txid, & scripts_buf) ;
811+ original_tx = tx. clone ( ) ;
774812 tx. output . iter_mut ( ) . for_each ( |output| {
775813 if scripts_buf. contains ( & output. script_pubkey ) {
776814 output. value = Amount :: from_sat ( output. value . to_sat ( ) - value_sat) ;
777815 }
778816 } ) ;
817+ tx. output [ fee_output_index] . value += Amount :: from_sat ( scripts_buf. len ( ) as u64 * value_sat) ;
779818 bump_fee_and_broadcast ( bitcoind, electrs, tx, fee_output_index, is_insert_block) ;
780- final_amount_sat -= value_sat;
781- validate_balances ! ( final_amount_sat, is_insert_block) ;
819+ if is_insertion_original_tx {
820+ generate_block_and_insert_transactions ( bitcoind, electrs, & [ original_tx. clone ( ) ] ) ;
821+ }
822+ final_amount_sat += amount_sat;
823+ if !is_insertion_original_tx {
824+ final_amount_sat -= value_sat;
825+ }
826+ validate_balances ! ( final_amount_sat, is_insert_block || is_insertion_original_tx) ;
782827
783828 if !is_insert_block {
784829 generate_blocks_and_wait ( bitcoind, electrs, 1 ) ;
0 commit comments