wallet.bump_fee: the glorious return of BumpFeeStrategy :D
gui/qt/rbf_dialog.py (old) lines 57-64 were implementing logic that should not be part of GUI code. Case in point, gui/qml/qetxfinalizer.py (old) lines 511-513 duplicated half of that logic but not the other half. That logic is now moved to wallet.get_bumpfee_strategies_for_tx(). More context: a user on irc got confused when using the qml gui. They were sending "max" and wanted to bump_fee. The qml gui selected the "preserve_payment" strategy by default, using which there was no solution, and the user did not notice that the strategy can be altered (via the "method" dropdown). The qt gui had logic to select "decrease_payment" by default in such a case (which does find a solution to bump) but this logic was not duplicated in the qml gui. Instead of duplicating the logic, this commit moves it to shared lib code.
This commit is contained in:
@@ -52,7 +52,7 @@ from .transaction import (Transaction, multisig_script, TxOutput, PartialTransac
|
|||||||
from . import transaction
|
from . import transaction
|
||||||
from .invoices import PR_PAID, PR_UNPAID, PR_UNKNOWN, PR_EXPIRED
|
from .invoices import PR_PAID, PR_UNPAID, PR_UNKNOWN, PR_EXPIRED
|
||||||
from .synchronizer import Notifier
|
from .synchronizer import Notifier
|
||||||
from .wallet import Abstract_Wallet, create_new_wallet, restore_wallet_from_text, Deterministic_Wallet
|
from .wallet import Abstract_Wallet, create_new_wallet, restore_wallet_from_text, Deterministic_Wallet, BumpFeeStrategy
|
||||||
from .address_synchronizer import TX_HEIGHT_LOCAL
|
from .address_synchronizer import TX_HEIGHT_LOCAL
|
||||||
from .mnemonic import Mnemonic
|
from .mnemonic import Mnemonic
|
||||||
from .lnutil import SENT, RECEIVED
|
from .lnutil import SENT, RECEIVED
|
||||||
@@ -819,7 +819,7 @@ class Commands:
|
|||||||
tx=tx,
|
tx=tx,
|
||||||
txid=tx.txid(),
|
txid=tx.txid(),
|
||||||
coins=coins,
|
coins=coins,
|
||||||
decrease_payment=decrease_payment,
|
strategy=BumpFeeStrategy.DECREASE_PAYMENT if decrease_payment else BumpFeeStrategy.PRESERVE_PAYMENT,
|
||||||
new_fee_rate=new_fee_rate)
|
new_fee_rate=new_fee_rate)
|
||||||
if not unsigned:
|
if not unsigned:
|
||||||
wallet.sign_transaction(new_tx, password)
|
wallet.sign_transaction(new_tx, password)
|
||||||
|
|||||||
@@ -62,15 +62,11 @@ ElDialog {
|
|||||||
|
|
||||||
ElComboBox {
|
ElComboBox {
|
||||||
id: bumpMethodComboBox
|
id: bumpMethodComboBox
|
||||||
enabled: rbffeebumper.canChangeBumpMethod
|
|
||||||
|
|
||||||
textRole: 'text'
|
textRole: 'text'
|
||||||
valueRole: 'value'
|
valueRole: 'value'
|
||||||
|
|
||||||
model: [
|
model: rbffeebumper.bumpMethodsAvailable
|
||||||
{ text: qsTr('Preserve payment'), value: 'preserve_payment' },
|
|
||||||
{ text: qsTr('Decrease payment'), value: 'decrease_payment' }
|
|
||||||
]
|
|
||||||
onCurrentValueChanged: {
|
onCurrentValueChanged: {
|
||||||
if (activeFocus)
|
if (activeFocus)
|
||||||
rbffeebumper.bumpMethod = currentValue
|
rbffeebumper.bumpMethod = currentValue
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from electrum.logging import get_logger
|
|||||||
from electrum.i18n import _
|
from electrum.i18n import _
|
||||||
from electrum.transaction import PartialTxOutput, PartialTransaction, Transaction
|
from electrum.transaction import PartialTxOutput, PartialTransaction, Transaction
|
||||||
from electrum.util import NotEnoughFunds, profiler
|
from electrum.util import NotEnoughFunds, profiler
|
||||||
from electrum.wallet import CannotBumpFee, CannotDoubleSpendTx, CannotCPFP
|
from electrum.wallet import CannotBumpFee, CannotDoubleSpendTx, CannotCPFP, BumpFeeStrategy
|
||||||
from electrum.plugin import run_hook
|
from electrum.plugin import run_hook
|
||||||
|
|
||||||
from .qewallet import QEWallet
|
from .qewallet import QEWallet
|
||||||
@@ -460,13 +460,8 @@ class QETxRbfFeeBumper(TxFeeSlider, TxMonMixin):
|
|||||||
self._oldfee_rate = 0
|
self._oldfee_rate = 0
|
||||||
self._orig_tx = None
|
self._orig_tx = None
|
||||||
self._rbf = True
|
self._rbf = True
|
||||||
self._bump_method = 'preserve_payment'
|
self._bump_method = BumpFeeStrategy.PRESERVE_PAYMENT.name
|
||||||
self._can_change_bump_method = True
|
self._bump_methods_available = []
|
||||||
|
|
||||||
canChangeBumpMethodChanged = pyqtSignal()
|
|
||||||
@pyqtProperty(bool, notify=canChangeBumpMethodChanged)
|
|
||||||
def canChangeBumpMethod(self):
|
|
||||||
return self._can_change_bump_method
|
|
||||||
|
|
||||||
oldfeeChanged = pyqtSignal()
|
oldfeeChanged = pyqtSignal()
|
||||||
@pyqtProperty(QEAmount, notify=oldfeeChanged)
|
@pyqtProperty(QEAmount, notify=oldfeeChanged)
|
||||||
@@ -496,21 +491,26 @@ class QETxRbfFeeBumper(TxFeeSlider, TxMonMixin):
|
|||||||
return self._bump_method
|
return self._bump_method
|
||||||
|
|
||||||
@bumpMethod.setter
|
@bumpMethod.setter
|
||||||
def bumpMethod(self, bumpmethod):
|
def bumpMethod(self, bumpmethod: str) -> None:
|
||||||
assert self._can_change_bump_method
|
|
||||||
if self._bump_method != bumpmethod:
|
if self._bump_method != bumpmethod:
|
||||||
self._bump_method = bumpmethod
|
self._bump_method = bumpmethod
|
||||||
self.bumpMethodChanged.emit()
|
self.bumpMethodChanged.emit()
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
|
bumpMethodsAvailableChanged = pyqtSignal()
|
||||||
|
@pyqtProperty('QVariantList', notify=bumpMethodsAvailableChanged)
|
||||||
|
def bumpMethodsAvailable(self):
|
||||||
|
return self._bump_methods_available
|
||||||
|
|
||||||
def get_tx(self):
|
def get_tx(self):
|
||||||
assert self._txid
|
assert self._txid
|
||||||
self._orig_tx = self._wallet.wallet.db.get_transaction(self._txid)
|
self._orig_tx = self._wallet.wallet.db.get_transaction(self._txid)
|
||||||
assert self._orig_tx
|
assert self._orig_tx
|
||||||
|
|
||||||
if self._wallet.wallet.get_swap_by_funding_tx(self._orig_tx):
|
strategies, def_strat_idx = self._wallet.wallet.get_bumpfee_strategies_for_tx(tx=self._orig_tx, txid=self._txid)
|
||||||
self._can_change_bump_method = False
|
self._bump_methods_available = [{'value': strat.name, 'text': strat.text()} for strat in strategies]
|
||||||
self.canChangeBumpMethodChanged.emit()
|
self.bumpMethodsAvailableChanged.emit()
|
||||||
|
self.bumpMethod = strategies[def_strat_idx].name
|
||||||
|
|
||||||
if not isinstance(self._orig_tx, PartialTransaction):
|
if not isinstance(self._orig_tx, PartialTransaction):
|
||||||
self._orig_tx = PartialTransaction.from_tx(self._orig_tx)
|
self._orig_tx = PartialTransaction.from_tx(self._orig_tx)
|
||||||
@@ -547,7 +547,7 @@ class QETxRbfFeeBumper(TxFeeSlider, TxMonMixin):
|
|||||||
tx=self._orig_tx,
|
tx=self._orig_tx,
|
||||||
txid=self._txid,
|
txid=self._txid,
|
||||||
new_fee_rate=new_fee_rate,
|
new_fee_rate=new_fee_rate,
|
||||||
decrease_payment=self._bump_method=='decrease_payment'
|
strategy=BumpFeeStrategy[self._bump_method],
|
||||||
)
|
)
|
||||||
except CannotBumpFee as e:
|
except CannotBumpFee as e:
|
||||||
self._valid = False
|
self._valid = False
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ from .util import (ColorScheme, WindowModalDialog, Buttons,
|
|||||||
|
|
||||||
from electrum.i18n import _
|
from electrum.i18n import _
|
||||||
from electrum.transaction import PartialTransaction
|
from electrum.transaction import PartialTransaction
|
||||||
from electrum.wallet import CannotRBFTx
|
from electrum.wallet import CannotRBFTx, BumpFeeStrategy
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .main_window import ElectrumWindow
|
from .main_window import ElectrumWindow
|
||||||
@@ -54,19 +54,13 @@ class _BaseRBFDialog(TxEditor):
|
|||||||
self.feerate_e.setAmount(new_fee_rate)
|
self.feerate_e.setAmount(new_fee_rate)
|
||||||
self.update()
|
self.update()
|
||||||
self.fee_slider.deactivate()
|
self.fee_slider.deactivate()
|
||||||
# are we paying max?
|
|
||||||
invoices = self.wallet.get_relevant_invoices_for_tx(txid)
|
|
||||||
if len(invoices) == 1 and len(invoices[0].outputs) == 1:
|
|
||||||
if invoices[0].outputs[0].value == '!':
|
|
||||||
self.set_decrease_payment()
|
|
||||||
# do not decrease payment if it is a swap
|
|
||||||
if self.wallet.get_swap_by_funding_tx(self.old_tx):
|
|
||||||
self.method_combo.setEnabled(False)
|
|
||||||
|
|
||||||
def create_grid(self):
|
def create_grid(self):
|
||||||
self.method_label = QLabel(_('Method') + ':')
|
self.method_label = QLabel(_('Method') + ':')
|
||||||
self.method_combo = QComboBox()
|
self.method_combo = QComboBox()
|
||||||
self.method_combo.addItems([_('Preserve payment'), _('Decrease payment')])
|
self._strategies, def_strat_idx = self.wallet.get_bumpfee_strategies_for_tx(tx=self.old_tx, txid=self.old_txid)
|
||||||
|
self.method_combo.addItems([strat.text() for strat in self._strategies])
|
||||||
|
self.method_combo.setCurrentIndex(def_strat_idx)
|
||||||
self.method_combo.currentIndexChanged.connect(self.trigger_update)
|
self.method_combo.currentIndexChanged.connect(self.trigger_update)
|
||||||
self.method_combo.setFocusPolicy(Qt.NoFocus)
|
self.method_combo.setFocusPolicy(Qt.NoFocus)
|
||||||
old_size_label = TxSizeLabel()
|
old_size_label = TxSizeLabel()
|
||||||
@@ -93,12 +87,6 @@ class _BaseRBFDialog(TxEditor):
|
|||||||
grid.addWidget(self.locktime_e, 5, 1, 1, 2)
|
grid.addWidget(self.locktime_e, 5, 1, 1, 2)
|
||||||
return grid
|
return grid
|
||||||
|
|
||||||
def is_decrease_payment(self):
|
|
||||||
return self.method_combo.currentIndex() == 1
|
|
||||||
|
|
||||||
def set_decrease_payment(self):
|
|
||||||
self.method_combo.setCurrentIndex(1)
|
|
||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
if not self.exec_():
|
if not self.exec_():
|
||||||
return
|
return
|
||||||
@@ -133,10 +121,12 @@ class _BaseRBFDialog(TxEditor):
|
|||||||
if not self.tx:
|
if not self.tx:
|
||||||
return
|
return
|
||||||
delta = self.tx.get_fee() - self.old_tx.get_fee()
|
delta = self.tx.get_fee() - self.old_tx.get_fee()
|
||||||
if not self.is_decrease_payment():
|
if self._strategies[self.method_combo.currentIndex()] == BumpFeeStrategy.PRESERVE_PAYMENT:
|
||||||
msg = _("You will pay {} more.").format(self.main_window.format_amount_and_units(delta))
|
msg = _("You will pay {} more.").format(self.main_window.format_amount_and_units(delta))
|
||||||
else:
|
elif self._strategies[self.method_combo.currentIndex()] == BumpFeeStrategy.DECREASE_PAYMENT:
|
||||||
msg = _("The recipient will receive {} less.").format(self.main_window.format_amount_and_units(delta))
|
msg = _("The recipient will receive {} less.").format(self.main_window.format_amount_and_units(delta))
|
||||||
|
else:
|
||||||
|
raise Exception(f"unknown strategy: {self=}")
|
||||||
messages.insert(0, msg)
|
messages.insert(0, msg)
|
||||||
return messages
|
return messages
|
||||||
|
|
||||||
@@ -164,7 +154,8 @@ class BumpFeeDialog(_BaseRBFDialog):
|
|||||||
txid=self.old_txid,
|
txid=self.old_txid,
|
||||||
new_fee_rate=fee_rate,
|
new_fee_rate=fee_rate,
|
||||||
coins=self.main_window.get_coins(nonlocal_only=True, confirmed_only=confirmed_only),
|
coins=self.main_window.get_coins(nonlocal_only=True, confirmed_only=confirmed_only),
|
||||||
decrease_payment=self.is_decrease_payment())
|
strategy=self._strategies[self.method_combo.currentIndex()],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class DSCancelDialog(_BaseRBFDialog):
|
class DSCancelDialog(_BaseRBFDialog):
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ from electrum import SimpleConfig
|
|||||||
from electrum import util
|
from electrum import util
|
||||||
from electrum.address_synchronizer import TX_HEIGHT_UNCONFIRMED, TX_HEIGHT_UNCONF_PARENT
|
from electrum.address_synchronizer import TX_HEIGHT_UNCONFIRMED, TX_HEIGHT_UNCONF_PARENT
|
||||||
from electrum.wallet import (sweep, Multisig_Wallet, Standard_Wallet, Imported_Wallet,
|
from electrum.wallet import (sweep, Multisig_Wallet, Standard_Wallet, Imported_Wallet,
|
||||||
restore_wallet_from_text, Abstract_Wallet, CannotBumpFee)
|
restore_wallet_from_text, Abstract_Wallet, CannotBumpFee, BumpFeeStrategy)
|
||||||
from electrum.util import (
|
from electrum.util import (
|
||||||
bfh, NotEnoughFunds, UnrelatedTransactionException,
|
bfh, NotEnoughFunds, UnrelatedTransactionException,
|
||||||
UserFacingException)
|
UserFacingException)
|
||||||
@@ -1229,7 +1229,7 @@ class TestWalletSending(ElectrumTestCase):
|
|||||||
tx = wallet.bump_fee(
|
tx = wallet.bump_fee(
|
||||||
tx=tx_from_any(orig_rbf_tx.serialize()),
|
tx=tx_from_any(orig_rbf_tx.serialize()),
|
||||||
new_fee_rate=60,
|
new_fee_rate=60,
|
||||||
decrease_payment=True,
|
strategy=BumpFeeStrategy.DECREASE_PAYMENT,
|
||||||
)
|
)
|
||||||
tx.locktime = 1936085
|
tx.locktime = 1936085
|
||||||
tx.version = 2
|
tx.version = 2
|
||||||
@@ -1271,7 +1271,7 @@ class TestWalletSending(ElectrumTestCase):
|
|||||||
tx = wallet.bump_fee(
|
tx = wallet.bump_fee(
|
||||||
tx=tx_from_any(orig_rbf_tx.serialize()),
|
tx=tx_from_any(orig_rbf_tx.serialize()),
|
||||||
new_fee_rate=60,
|
new_fee_rate=60,
|
||||||
decrease_payment=True,
|
strategy=BumpFeeStrategy.DECREASE_PAYMENT,
|
||||||
)
|
)
|
||||||
tx.locktime = 1936095
|
tx.locktime = 1936095
|
||||||
tx.version = 2
|
tx.version = 2
|
||||||
@@ -1313,19 +1313,19 @@ class TestWalletSending(ElectrumTestCase):
|
|||||||
tx = wallet.bump_fee(
|
tx = wallet.bump_fee(
|
||||||
tx=tx_from_any(orig_rbf_tx.serialize()),
|
tx=tx_from_any(orig_rbf_tx.serialize()),
|
||||||
new_fee_rate=99999,
|
new_fee_rate=99999,
|
||||||
decrease_payment=True,
|
strategy=BumpFeeStrategy.DECREASE_PAYMENT,
|
||||||
)
|
)
|
||||||
with self.assertRaises(CannotBumpFee):
|
with self.assertRaises(CannotBumpFee):
|
||||||
tx = wallet.bump_fee(
|
tx = wallet.bump_fee(
|
||||||
tx=tx_from_any(orig_rbf_tx.serialize()),
|
tx=tx_from_any(orig_rbf_tx.serialize()),
|
||||||
new_fee_rate=99999,
|
new_fee_rate=99999,
|
||||||
decrease_payment=False,
|
strategy=BumpFeeStrategy.PRESERVE_PAYMENT,
|
||||||
)
|
)
|
||||||
|
|
||||||
tx = wallet.bump_fee(
|
tx = wallet.bump_fee(
|
||||||
tx=tx_from_any(orig_rbf_tx.serialize()),
|
tx=tx_from_any(orig_rbf_tx.serialize()),
|
||||||
new_fee_rate=60,
|
new_fee_rate=60,
|
||||||
decrease_payment=True,
|
strategy=BumpFeeStrategy.DECREASE_PAYMENT,
|
||||||
)
|
)
|
||||||
tx.locktime = 1936085
|
tx.locktime = 1936085
|
||||||
tx.version = 2
|
tx.version = 2
|
||||||
@@ -1647,7 +1647,7 @@ class TestWalletSending(ElectrumTestCase):
|
|||||||
self.assertEqual((0, 0, 0), wallet.get_balance())
|
self.assertEqual((0, 0, 0), wallet.get_balance())
|
||||||
|
|
||||||
# bump tx
|
# bump tx
|
||||||
tx = wallet.bump_fee(tx=tx_from_any(tx.serialize()), new_fee_rate=70.0, decrease_payment=True)
|
tx = wallet.bump_fee(tx=tx_from_any(tx.serialize()), new_fee_rate=70.0, strategy=BumpFeeStrategy.DECREASE_PAYMENT)
|
||||||
tx.locktime = 1325500
|
tx.locktime = 1325500
|
||||||
tx.version = 1
|
tx.version = 1
|
||||||
if simulate_moving_txs:
|
if simulate_moving_txs:
|
||||||
|
|||||||
@@ -247,6 +247,23 @@ class InternalAddressCorruption(Exception):
|
|||||||
"Please restore your wallet from seed, and compare the addresses in both files")
|
"Please restore your wallet from seed, and compare the addresses in both files")
|
||||||
|
|
||||||
|
|
||||||
|
class BumpFeeStrategy(enum.Enum):
|
||||||
|
PRESERVE_PAYMENT = enum.auto()
|
||||||
|
DECREASE_PAYMENT = enum.auto()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def all(cls) -> Sequence['BumpFeeStrategy']:
|
||||||
|
return list(BumpFeeStrategy.__members__.values())
|
||||||
|
|
||||||
|
def text(self) -> str:
|
||||||
|
if self == self.PRESERVE_PAYMENT:
|
||||||
|
return _('Preserve payment')
|
||||||
|
elif self == self.DECREASE_PAYMENT:
|
||||||
|
return _('Decrease payment')
|
||||||
|
else:
|
||||||
|
raise Exception(f"unknown strategy: {self=}")
|
||||||
|
|
||||||
|
|
||||||
class ReceiveRequestHelp(NamedTuple):
|
class ReceiveRequestHelp(NamedTuple):
|
||||||
# help texts (warnings/errors):
|
# help texts (warnings/errors):
|
||||||
address_help: str
|
address_help: str
|
||||||
@@ -1955,6 +1972,28 @@ class Abstract_Wallet(ABC, Logger, EventListener):
|
|||||||
def can_export(self):
|
def can_export(self):
|
||||||
return not self.is_watching_only() and hasattr(self.keystore, 'get_private_key')
|
return not self.is_watching_only() and hasattr(self.keystore, 'get_private_key')
|
||||||
|
|
||||||
|
def get_bumpfee_strategies_for_tx(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
tx: Transaction,
|
||||||
|
txid: str = None,
|
||||||
|
) -> Tuple[Sequence[BumpFeeStrategy], int]:
|
||||||
|
"""Returns tuple(list of available strategies, idx of recommended option among those)."""
|
||||||
|
txid = txid or tx.txid()
|
||||||
|
assert txid
|
||||||
|
assert tx.txid() in (None, txid)
|
||||||
|
all_strats = BumpFeeStrategy.all()
|
||||||
|
# are we paying max?
|
||||||
|
invoices = self.get_relevant_invoices_for_tx(txid)
|
||||||
|
if len(invoices) == 1 and len(invoices[0].outputs) == 1:
|
||||||
|
if invoices[0].outputs[0].value == '!':
|
||||||
|
return all_strats, all_strats.index(BumpFeeStrategy.DECREASE_PAYMENT)
|
||||||
|
# do not decrease payment if it is a swap
|
||||||
|
if self.get_swap_by_funding_tx(tx):
|
||||||
|
return [BumpFeeStrategy.PRESERVE_PAYMENT], 0
|
||||||
|
# default
|
||||||
|
return all_strats, all_strats.index(BumpFeeStrategy.PRESERVE_PAYMENT)
|
||||||
|
|
||||||
def bump_fee(
|
def bump_fee(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
@@ -1962,7 +2001,7 @@ class Abstract_Wallet(ABC, Logger, EventListener):
|
|||||||
txid: str = None,
|
txid: str = None,
|
||||||
new_fee_rate: Union[int, float, Decimal],
|
new_fee_rate: Union[int, float, Decimal],
|
||||||
coins: Sequence[PartialTxInput] = None,
|
coins: Sequence[PartialTxInput] = None,
|
||||||
decrease_payment=False,
|
strategy: BumpFeeStrategy = BumpFeeStrategy.PRESERVE_PAYMENT,
|
||||||
) -> PartialTransaction:
|
) -> PartialTransaction:
|
||||||
"""Increase the miner fee of 'tx'.
|
"""Increase the miner fee of 'tx'.
|
||||||
'new_fee_rate' is the target min rate in sat/vbyte
|
'new_fee_rate' is the target min rate in sat/vbyte
|
||||||
@@ -1991,7 +2030,7 @@ class Abstract_Wallet(ABC, Logger, EventListener):
|
|||||||
if new_fee_rate <= old_fee_rate:
|
if new_fee_rate <= old_fee_rate:
|
||||||
raise CannotBumpFee(_("The new fee rate needs to be higher than the old fee rate."))
|
raise CannotBumpFee(_("The new fee rate needs to be higher than the old fee rate."))
|
||||||
|
|
||||||
if not decrease_payment:
|
if strategy == BumpFeeStrategy.PRESERVE_PAYMENT:
|
||||||
# FIXME: we should try decreasing change first,
|
# FIXME: we should try decreasing change first,
|
||||||
# but it requires updating a bunch of unit tests
|
# but it requires updating a bunch of unit tests
|
||||||
try:
|
try:
|
||||||
@@ -2004,9 +2043,11 @@ class Abstract_Wallet(ABC, Logger, EventListener):
|
|||||||
except CannotBumpFee as e:
|
except CannotBumpFee as e:
|
||||||
tx_new = self._bump_fee_through_decreasing_change(
|
tx_new = self._bump_fee_through_decreasing_change(
|
||||||
tx=tx, new_fee_rate=new_fee_rate)
|
tx=tx, new_fee_rate=new_fee_rate)
|
||||||
else:
|
elif strategy == BumpFeeStrategy.DECREASE_PAYMENT:
|
||||||
tx_new = self._bump_fee_through_decreasing_payment(
|
tx_new = self._bump_fee_through_decreasing_payment(
|
||||||
tx=tx, new_fee_rate=new_fee_rate)
|
tx=tx, new_fee_rate=new_fee_rate)
|
||||||
|
else:
|
||||||
|
raise Exception(f"unknown strategy: {strategy=}")
|
||||||
|
|
||||||
target_min_fee = new_fee_rate * tx_new.estimated_size()
|
target_min_fee = new_fee_rate * tx_new.estimated_size()
|
||||||
actual_fee = tx_new.get_fee()
|
actual_fee = tx_new.get_fee()
|
||||||
|
|||||||
Reference in New Issue
Block a user