tRBF batching: smarter fee handling - electrum - Electrum Bitcoin wallet
 (HTM) git clone https://git.parazyd.org/electrum
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Submodules
       ---
 (DIR) commit 2ab8234e9c08b5d35f6bf8d07ba587975cf86e53
 (DIR) parent d905f0e55ef95e321f5e986dbdc62be50c629181
 (HTM) Author: SomberNight <somber.night@protonmail.com>
       Date:   Fri,  9 Nov 2018 20:04:06 +0100
       
       RBF batching: smarter fee handling
       
       Diffstat:
         M electrum/gui/qt/main_window.py      |       3 ++-
         M electrum/wallet.py                  |      11 +++++++++++
       
       2 files changed, 13 insertions(+), 1 deletion(-)
       ---
 (DIR) diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py
       t@@ -1203,7 +1203,8 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
                            _('To somewhat protect your privacy, Electrum tries to create change with similar precision to other outputs.') + ' ' +
                            _('At most 100 satoshis might be lost due to this rounding.') + ' ' +
                            _("You can disable this setting in '{}'.").format(_('Preferences')) + '\n' +
       -                    _('Also, dust is not kept as change, but added to the fee.'))
       +                    _('Also, dust is not kept as change, but added to the fee.')  + '\n' +
       +                    _('Also, when batching RBF transactions, BIP 125 imposes a lower bound on the fee.'))
                    QMessageBox.information(self, 'Fee rounding', text)
        
                self.feerounding_icon = QPushButton(QIcon(':icons/info.png'), '')
 (DIR) diff --git a/electrum/wallet.py b/electrum/wallet.py
       t@@ -550,6 +550,9 @@ class Abstract_Wallet(AddressSynchronizer):
                    for output_idx, o in enumerate(tx.outputs()):
                        if self.is_mine(o.address) and self.spent_outpoints[tx.txid()].get(output_idx):
                            continue
       +            # all inputs should be is_mine
       +            if not all([self.is_mine(self.get_txin_address(txin)) for txin in tx.inputs()]):
       +                continue
                    # prefer txns already in mempool (vs local)
                    if tx_mined_status.height == TX_HEIGHT_LOCAL:
                        candidate = tx
       t@@ -613,10 +616,18 @@ class Abstract_Wallet(AddressSynchronizer):
                    # If there is an unconfirmed RBF tx, merge with it
                    base_tx = self.get_unconfirmed_base_tx_for_batching()
                    if config.get('batch_rbf', False) and base_tx:
       +                is_local = self.get_tx_height(base_tx.txid()).height == TX_HEIGHT_LOCAL
                        base_tx = Transaction(base_tx.serialize())
                        base_tx.deserialize(force_full_parse=True)
                        base_tx.remove_signatures()
                        base_tx.add_inputs_info(self)
       +                base_tx_fee = base_tx.get_fee()
       +                relayfeerate = self.relayfee() / 1000
       +                original_fee_estimator = fee_estimator
       +                def fee_estimator(size: int) -> int:
       +                    lower_bound = base_tx_fee + round(size * relayfeerate)
       +                    lower_bound = lower_bound if not is_local else 0
       +                    return max(lower_bound, original_fee_estimator(size))
                        txi = base_tx.inputs()
                        txo = list(filter(lambda o: not self.is_change(o.address), base_tx.outputs()))
                    else: