Browse Source

RBF batching: smarter fee handling

3.3.3.1
SomberNight 6 years ago
parent
commit
2ab8234e9c
No known key found for this signature in database GPG Key ID: B33B5F232C6271E9
  1. 3
      electrum/gui/qt/main_window.py
  2. 11
      electrum/wallet.py

3
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.') + ' ' + _('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.') + ' ' + _('At most 100 satoshis might be lost due to this rounding.') + ' ' +
_("You can disable this setting in '{}'.").format(_('Preferences')) + '\n' + _("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) QMessageBox.information(self, 'Fee rounding', text)
self.feerounding_icon = QPushButton(QIcon(':icons/info.png'), '') self.feerounding_icon = QPushButton(QIcon(':icons/info.png'), '')

11
electrum/wallet.py

@ -550,6 +550,9 @@ class Abstract_Wallet(AddressSynchronizer):
for output_idx, o in enumerate(tx.outputs()): for output_idx, o in enumerate(tx.outputs()):
if self.is_mine(o.address) and self.spent_outpoints[tx.txid()].get(output_idx): if self.is_mine(o.address) and self.spent_outpoints[tx.txid()].get(output_idx):
continue 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) # prefer txns already in mempool (vs local)
if tx_mined_status.height == TX_HEIGHT_LOCAL: if tx_mined_status.height == TX_HEIGHT_LOCAL:
candidate = tx candidate = tx
@ -613,10 +616,18 @@ class Abstract_Wallet(AddressSynchronizer):
# If there is an unconfirmed RBF tx, merge with it # If there is an unconfirmed RBF tx, merge with it
base_tx = self.get_unconfirmed_base_tx_for_batching() base_tx = self.get_unconfirmed_base_tx_for_batching()
if config.get('batch_rbf', False) and base_tx: 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 = Transaction(base_tx.serialize())
base_tx.deserialize(force_full_parse=True) base_tx.deserialize(force_full_parse=True)
base_tx.remove_signatures() base_tx.remove_signatures()
base_tx.add_inputs_info(self) 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() txi = base_tx.inputs()
txo = list(filter(lambda o: not self.is_change(o.address), base_tx.outputs())) txo = list(filter(lambda o: not self.is_change(o.address), base_tx.outputs()))
else: else:

Loading…
Cancel
Save