Merge pull request #10591 from SomberNight/202604_fix_wallet_mktx_base_tx
wallet: make_unsigned_tx: fix base_tx for GUI simple-send batching
This commit is contained in:
@@ -26,7 +26,7 @@
|
||||
import asyncio
|
||||
from decimal import Decimal
|
||||
from functools import partial
|
||||
from typing import TYPE_CHECKING, Optional, Union
|
||||
from typing import TYPE_CHECKING, Optional, Union, Sequence
|
||||
from concurrent.futures import Future
|
||||
from enum import Enum, auto
|
||||
|
||||
@@ -39,7 +39,7 @@ from electrum.i18n import _
|
||||
from electrum.util import (UserCancelled, quantize_feerate, profiler, NotEnoughFunds, NoDynamicFeeEstimates,
|
||||
get_asyncio_loop, wait_for2, UserFacingException)
|
||||
from electrum.plugin import run_hook
|
||||
from electrum.transaction import PartialTransaction, PartialTxOutput
|
||||
from electrum.transaction import PartialTransaction, PartialTxOutput, Transaction
|
||||
from electrum.wallet import InternalAddressCorruption
|
||||
from electrum.bitcoin import DummyAddress
|
||||
from electrum.fee_policy import FeePolicy, FixedFeePolicy, FeeMethod
|
||||
@@ -82,7 +82,7 @@ class TxEditor(WindowModalDialog, QtEventListener, Logger):
|
||||
output_value: Union[int, str],
|
||||
payee_outputs: Optional[list[PartialTxOutput]] = None,
|
||||
context: TxEditorContext = TxEditorContext.PAYMENT,
|
||||
batching_candidates=None,
|
||||
batching_candidates: Sequence[Transaction] = None,
|
||||
):
|
||||
|
||||
WindowModalDialog.__init__(self, window, title=title)
|
||||
@@ -106,7 +106,7 @@ class TxEditor(WindowModalDialog, QtEventListener, Logger):
|
||||
self.needs_update = False
|
||||
self.context = context
|
||||
self.is_preview = False
|
||||
self._base_tx = None # for batching
|
||||
self._base_tx = None # type: Optional[Transaction] # for batching
|
||||
self.batching_candidates = batching_candidates
|
||||
|
||||
self.swap_manager = self.wallet.lnworker.swap_manager if self.wallet.has_lightning() else None
|
||||
@@ -1123,7 +1123,7 @@ class ConfirmTxDialog(TxEditor):
|
||||
output_value: Union[int, str],
|
||||
payee_outputs: Optional[list[PartialTxOutput]] = None,
|
||||
context: TxEditorContext = TxEditorContext.PAYMENT,
|
||||
batching_candidates=None,
|
||||
batching_candidates: Sequence[Transaction] = None,
|
||||
):
|
||||
|
||||
TxEditor.__init__(
|
||||
|
||||
@@ -1507,7 +1507,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger, QtEventListener):
|
||||
output_value, *,
|
||||
payee_outputs: Optional[list[TxOutput]] = None,
|
||||
context: TxEditorContext = TxEditorContext.PAYMENT,
|
||||
batching_candidates=None,
|
||||
batching_candidates: Sequence[Transaction] = None,
|
||||
) -> tuple[Optional[PartialTransaction], bool, bool]:
|
||||
d = ConfirmTxDialog(
|
||||
window=self,
|
||||
|
||||
+7
-5
@@ -1803,6 +1803,7 @@ class Abstract_Wallet(ABC, Logger, EventListener):
|
||||
domain = self.get_addresses()
|
||||
for hist_item in self.adb.get_history(domain):
|
||||
# tx should not be mined yet
|
||||
if hist_item.tx_mined_status.conf is None: continue
|
||||
if hist_item.tx_mined_status.conf > 0: continue
|
||||
# conservative future proofing of code: only allow known unconfirmed types
|
||||
if hist_item.tx_mined_status.height() not in (
|
||||
@@ -2008,20 +2009,21 @@ class Abstract_Wallet(ABC, Logger, EventListener):
|
||||
coin_chooser = coinchooser.get_coin_chooser(self.config)
|
||||
# If there is an unconfirmed RBF tx, merge with it
|
||||
if base_tx:
|
||||
assert base_tx.txid() is not None # pre-segwit and incomplete?
|
||||
# make sure we don't try to spend change from the tx-to-be-replaced:
|
||||
coins = [c for c in coins if c.prevout.txid.hex() != base_tx.txid()]
|
||||
is_local = self.adb.get_tx_height(base_tx.txid()).height() == TX_HEIGHT_LOCAL
|
||||
# estimate base tx fee before stripping tx for more accurate estimate
|
||||
base_tx_fee = base_tx.get_fee()
|
||||
base_feerate = Decimal(base_tx_fee)/base_tx.estimated_size()
|
||||
relayfeerate = Decimal(self.relayfee()) / 1000
|
||||
original_fee_estimator = fee_estimator
|
||||
base_tx_size = base_tx.estimated_size() # estimate before stripping tx for more accurate estimate
|
||||
if not isinstance(base_tx, PartialTransaction):
|
||||
base_tx = PartialTransaction.from_tx(base_tx)
|
||||
base_tx.add_info_from_wallet(self)
|
||||
else:
|
||||
# don't cast PartialTransaction, because it removes make_witness
|
||||
base_tx.remove_signatures()
|
||||
base_tx_fee = base_tx.get_fee() # FIXME could be None if some inputs are non-ismine
|
||||
base_feerate = Decimal(base_tx_fee) / base_tx_size
|
||||
relayfeerate = Decimal(self.relayfee()) / 1000
|
||||
original_fee_estimator = fee_estimator
|
||||
def fee_estimator(size: Union[int, float, Decimal]) -> int:
|
||||
size = Decimal(size)
|
||||
lower_bound_relayfee = int(base_tx_fee + round(size * relayfeerate)) if not is_local else 0
|
||||
|
||||
Reference in New Issue
Block a user