URI: 
       tadd CPFP (child pays for parent) dialog to the Qt GUI - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 15b404b9de8d0a992f9f07b6c599e1fb1f2e6310
   DIR parent 9e1931587d52d67108f0ec6c3a81b7474a763f7d
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Wed,  1 Feb 2017 12:26:30 +0100
       
       add CPFP (child pays for parent) dialog to the Qt GUI
       
       Diffstat:
         M gui/qt/history_list.py              |      12 +++++++++---
         M gui/qt/main_window.py               |      27 +++++++++++++++++++++++++++
         M lib/wallet.py                       |      19 +++++++++++++++++++
       
       3 files changed, 55 insertions(+), 3 deletions(-)
       ---
   DIR diff --git a/gui/qt/history_list.py b/gui/qt/history_list.py
       t@@ -142,7 +142,7 @@ class HistoryList(MyTreeWidget):
                height, conf, timestamp = self.wallet.get_tx_height(tx_hash)
                tx = self.wallet.transactions.get(tx_hash)
                is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(tx)
       -        rbf = is_mine and height <=0 and tx and not tx.is_final()
       +        is_unconfirmed = height <= 0
                menu = QMenu()
        
                menu.addAction(_("Copy %s")%column_title, lambda: self.parent.app.clipboard().setText(column_data))
       t@@ -150,8 +150,14 @@ class HistoryList(MyTreeWidget):
                    menu.addAction(_("Edit %s")%column_title, lambda: self.editItem(item, column))
        
                menu.addAction(_("Details"), lambda: self.parent.show_transaction(tx))
       -        if rbf:
       -            menu.addAction(_("Increase fee"), lambda: self.parent.bump_fee_dialog(tx))
       +        if is_unconfirmed and tx:
       +            rbf = is_mine and not tx.is_final()
       +            if rbf:
       +                menu.addAction(_("Increase fee"), lambda: self.parent.bump_fee_dialog(tx))
       +            else:
       +                child_tx = self.wallet.cpfp(tx, 0)
       +                if child_tx:
       +                    menu.addAction(_("Child pays for parent"), lambda: self.parent.cpfp(tx, child_tx))
                if tx_URL:
                    menu.addAction(_("View on block explorer"), lambda: webbrowser.open(tx_URL))
                menu.exec_(self.viewport().mapToGlobal(position))
   DIR diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py
       t@@ -2767,6 +2767,33 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
                vbox.addLayout(Buttons(CloseButton(d)))
                d.exec_()
        
       +    def cpfp(self, parent_tx, new_tx):
       +        total_size = parent_tx.estimated_size() + new_tx.estimated_size()
       +        d = WindowModalDialog(self, _('Child Pays for Parent'))
       +        vbox = QVBoxLayout(d)
       +        vbox.addWidget(QLabel(_('Total size') + ': %d bytes'% total_size))
       +        max_fee = new_tx.output_value()
       +        vbox.addWidget(QLabel(_('Max fee') + ': %s'% self.format_amount(max_fee) + ' ' + self.base_unit()))
       +        vbox.addWidget(QLabel(_('Child fee' + ':')))
       +        fee_e = BTCAmountEdit(self.get_decimal_point)
       +        fee = self.config.fee_per_kb() * total_size / 1000
       +        fee_e.setAmount(fee)
       +        vbox.addWidget(fee_e)
       +        def on_rate(dyn, pos, fee_rate):
       +            fee = fee_rate * total_size / 1000
       +            fee_e.setAmount(min(max_fee, fee))
       +        fee_slider = FeeSlider(self, self.config, on_rate)
       +        vbox.addWidget(fee_slider)
       +        vbox.addLayout(Buttons(CancelButton(d), OkButton(d)))
       +        if not d.exec_():
       +            return
       +        fee = fee_e.get_amount()
       +        if fee > max_fee:
       +            self.show_error(_('Max fee exceeded'))
       +            return
       +        new_tx = self.wallet.cpfp(parent_tx, fee)
       +        new_tx.set_sequence(0)
       +        self.show_transaction(new_tx)
        
            def bump_fee_dialog(self, tx):
                is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(tx)
   DIR diff --git a/lib/wallet.py b/lib/wallet.py
       t@@ -1042,6 +1042,25 @@ class Abstract_Wallet(PrintError):
                    raise BaseException(_('Cannot bump fee: cound not find suitable outputs'))
                return Transaction.from_io(inputs, outputs)
        
       +    def cpfp(self, tx, fee):
       +        txid = tx.txid()
       +        for i, o in enumerate(tx.outputs()):
       +            otype, address, value = o
       +            if otype == TYPE_ADDRESS and self.is_mine(address):
       +                break
       +        else:
       +            return
       +        coins = self.get_addr_utxo(address)
       +        for item in coins:
       +            if item['prevout_hash'] == txid and item['prevout_n'] == i:
       +                break
       +        else:
       +            return
       +        self.add_input_info(item)
       +        inputs = [item]
       +        outputs = [(TYPE_ADDRESS, address, value - fee)]
       +        return Transaction.from_io(inputs, outputs)
       +
            def add_input_info(self, txin):
                # Add address for utxo that are in wallet
                if txin.get('scriptSig') == '':