commit 2ab8234e9c08b5d35f6bf8d07ba587975cf86e53
parent d905f0e55ef95e321f5e986dbdc62be50c629181
Author: SomberNight <somber.night@protonmail.com>
Date: Fri, 9 Nov 2018 20:04:06 +0100
RBF batching: smarter fee handling
Diffstat:
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py
@@ -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'), '')
diff --git a/electrum/wallet.py b/electrum/wallet.py
@@ -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
@@ -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: