async def test_rbf_batching__merge_duplicate_outputs(self):
        """txos paying to the same address might be merged into a single output with a larger value"""
        wallet = self.create_standard_wallet_from_seed('response era cable net spike again observe dumb wage wonder sail tortoise',
                                                       config=self.config)

        # bootstrap wallet (incoming funding_tx0): for 500k sat
        funding_tx = Transaction('02000000000101013548c9019890e27ce9e58766de05f18ea40ede70751fb6cd7a3a1715ece0a30100000000fdffffff0220a1070000000000160014542266519a44eb9b903761d40c6fe1055d33fa05485a080000000000160014bc69f7d82c403a9f35dfb6d1a4531d6b19cab0e3024730440220346b200f21c3024e1d51fb4ecddbdbd68bd24ae7b9dfd501519f6dcbeb7c052402200617e3ce7b0eb308e30caf23894fb0388b68fb1c15dd0681dd13ae5e735f148101210360d0c9ef15b8b6a16912d341ad218a4e4e4e07e9347f4a2dbc7ca8d974f8bc9ec1ad2600')
        funding_txid = funding_tx.txid()
        wallet.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)

        dest_addr = "tb1qtzhwpufqr5dwztdaysfqnwlf9m29uwdkq8zm9w"
        # first payment to dest_addr
        outputs1 = [PartialTxOutput.from_address_and_value(dest_addr, 200_000)]
        coins = wallet.get_spendable_coins(domain=None)
        tx1 = wallet.make_unsigned_transaction(coins=coins, outputs=outputs1, fee_policy=FixedFeePolicy(2000))
        tx1.set_rbf(True)
        tx1.locktime = 2534850
        tx1.version = 2
        wallet.sign_transaction(tx1, password=None)
        self.assertEqual(2, len(tx1.outputs()))
        self.assertEqual('020000000001019264597cffcce8f0c17b16a02adca7a95ae90f2ea51bd4b4df60c76dfe86686e0000000000fdffffff02400d03000000000016001458aee0f1201d1ae12dbd241209bbe92ed45e39b6108c0400000000001600144e1b662f616fe134430054e29295ea6e5c18f1730247304402205ea932303bb89bfe07c1e4c28117cb84f613e09dd51464aa2ed2b184c2f2b76902202968280003b0e7d4098bf9adc47246db7b84c83f718e70a609de05f3b2ae64e80121029b1a61d66896486ab893741b38dbafb9673b91a82237d6e4ca0da3cda7cbeb7cc2ad2600',
                         str(tx1))
        wallet.adb.receive_tx_callback(tx1, tx_height=TX_HEIGHT_UNCONFIRMED)
        self.assertEqual((0, 298_000, 0), wallet.get_balance())

        # second payment to dest_addr  (merged)
        outputs2 = [PartialTxOutput.from_address_and_value(dest_addr, 100_000)]
        coins = wallet.get_spendable_coins(domain=None)
        tx2 = wallet.make_unsigned_transaction(coins=coins, outputs=outputs2, fee_policy=FixedFeePolicy(3000), base_tx=tx1, merge_duplicate_outputs=True)
        tx2.set_rbf(True)
        tx2.locktime = 2534850
        tx2.version = 2
        wallet.sign_transaction(tx2, password=None)
        self.assertEqual(2, len(tx2.outputs()))
        self.assertEqual('020000000001019264597cffcce8f0c17b16a02adca7a95ae90f2ea51bd4b4df60c76dfe86686e0000000000fdffffff0288010300000000001600144e1b662f616fe134430054e29295ea6e5c18f173e09304000000000016001458aee0f1201d1ae12dbd241209bbe92ed45e39b60247304402201b5856f572a70f667392f000780044a6c6677eadadd5b56d2b15d1f90a8bf4b7022046566836d7e1e1a099ff72b4ecb09d6b24e701e12c0fb4c5667172d47d9b54520121029b1a61d66896486ab893741b38dbafb9673b91a82237d6e4ca0da3cda7cbeb7cc2ad2600',
                         str(tx2))
        wallet.adb.receive_tx_callback(tx2, tx_height=TX_HEIGHT_UNCONFIRMED)
        self.assertEqual((0, 197_000, 0), wallet.get_balance())

        # remove tx2 from wallet, by replacing it with tx1
        wallet.adb.receive_tx_callback(tx1, tx_height=TX_HEIGHT_UNCONFIRMED)
        self.assertEqual((0, 298_000, 0), wallet.get_balance())

        # second payment to dest_addr  (not merged, just duplicate outputs)
        outputs2 = [PartialTxOutput.from_address_and_value(dest_addr, 100_000)]
        coins = wallet.get_spendable_coins(domain=None)
        tx3 = wallet.make_unsigned_transaction(coins=coins, outputs=outputs2, fee_policy=FixedFeePolicy(3000), base_tx=tx1)
        tx3.set_rbf(True)
        tx3.locktime = 2534850
        tx3.version = 2
        wallet.sign_transaction(tx3, password=None)
        self.assertEqual(3, len(tx3.outputs()))
        self.assertEqual('020000000001019264597cffcce8f0c17b16a02adca7a95ae90f2ea51bd4b4df60c76dfe86686e0000000000fdffffff03a08601000000000016001458aee0f1201d1ae12dbd241209bbe92ed45e39b688010300000000001600144e1b662f616fe134430054e29295ea6e5c18f173400d03000000000016001458aee0f1201d1ae12dbd241209bbe92ed45e39b602473044022061386129ebefda19e22ab9e2c06642a2a5eb7637e1b492d5c164591ff0fb27c9022006129d5d0c780d6830fb6cf924e3eeef03b8a349a9ebb36969cae410d9ff0fa50121029b1a61d66896486ab893741b38dbafb9673b91a82237d6e4ca0da3cda7cbeb7cc2ad2600',
                         str(tx3))
        wallet.adb.receive_tx_callback(tx3, tx_height=TX_HEIGHT_UNCONFIRMED)
        self.assertEqual((0, 197_000, 0), wallet.get_balance())
txos paying to the same address might be merged into a single output with a larger value
tests/test_wallet_vertical.py