From 8bec974a39a7692475db85b94c227b21a57bab31 Mon Sep 17 00:00:00 2001 From: ThomasV Date: Sun, 8 Dec 2024 09:53:56 +0100 Subject: [PATCH] wallet: add inputs and base_tx parameters to make_unsigned_transaction --- electrum/wallet.py | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/electrum/wallet.py b/electrum/wallet.py index 43eae2a39..ecbe649d4 100644 --- a/electrum/wallet.py +++ b/electrum/wallet.py @@ -1813,11 +1813,13 @@ class Abstract_Wallet(ABC, Logger, EventListener): self, *, coins: Sequence[PartialTxInput], outputs: List[PartialTxOutput], + inputs: Optional[List[PartialTxInput]] = None, fee=None, change_addr: str = None, is_sweep: bool = False, # used by Wallet_2fa subclass - rbf: bool = True, - batch_rbf: Optional[bool] = None, + rbf: Optional[bool] = True, + BIP69_sort: Optional[bool] = True, + base_tx: Optional[PartialTransaction] = None, send_change_to_lightning: Optional[bool] = None, ) -> PartialTransaction: """Can raise NotEnoughFunds or NoDynamicFeeEstimates.""" @@ -1826,8 +1828,10 @@ class Abstract_Wallet(ABC, Logger, EventListener): raise NotEnoughFunds() if any([c.already_has_some_signatures() for c in coins]): raise Exception("Some inputs already contain signatures!") - if batch_rbf is None: - batch_rbf = self.config.WALLET_BATCH_RBF + if inputs is None: + inputs = [] + if base_tx is None and self.config.WALLET_BATCH_RBF: + base_tx = self.get_unconfirmed_base_tx_for_batching(outputs, coins) if send_change_to_lightning is None: send_change_to_lightning = self.config.WALLET_SEND_CHANGE_TO_LIGHTNING @@ -1846,8 +1850,10 @@ class Abstract_Wallet(ABC, Logger, EventListener): if fee is None and self.config.fee_per_kb() is None: raise NoDynamicFeeEstimates() - for item in coins: - self.add_input_info(item) + for txin in coins: + self.add_input_info(txin) + nSequence = 0xffffffff - (2 if rbf else 1) + txin.nsequence = nSequence # Fee estimator if fee is None: @@ -1866,7 +1872,6 @@ class Abstract_Wallet(ABC, Logger, EventListener): # Let the coin chooser select the coins to spend coin_chooser = coinchooser.get_coin_chooser(self.config) # If there is an unconfirmed RBF tx, merge with it - base_tx = self.get_unconfirmed_base_tx_for_batching(outputs, coins) if batch_rbf else None if base_tx: # 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()] @@ -1883,12 +1888,12 @@ class Abstract_Wallet(ABC, Logger, EventListener): lower_bound_feerate = int(base_feerate * size) + 1 lower_bound = max(lower_bound_feerate, lower_bound_relayfee) return max(lower_bound, original_fee_estimator(size)) - txi = base_tx.inputs() + txi = base_tx.inputs() + list(inputs) txo = list(filter(lambda o: not self.is_change(o.address), base_tx.outputs())) + list(outputs) old_change_addrs = [o.address for o in base_tx.outputs() if self.is_change(o.address)] rbf_merge_txid = base_tx.txid() else: - txi = [] + txi = list(inputs) txo = list(outputs) old_change_addrs = [] # change address. if empty, coin_chooser will set it @@ -1901,7 +1906,8 @@ class Abstract_Wallet(ABC, Logger, EventListener): outputs=txo, change_addrs=change_addrs, fee_estimator_vb=fee_estimator, - dust_threshold=self.dust_threshold()) + dust_threshold=self.dust_threshold(), + BIP69_sort=BIP69_sort) if self.lnworker and send_change_to_lightning: change = tx.get_change_outputs() # do not use multiple change addresses @@ -1938,7 +1944,6 @@ class Abstract_Wallet(ABC, Logger, EventListener): # Timelock tx to current height. tx.locktime = get_locktime_for_new_transaction(self.network) tx.rbf_merge_txid = rbf_merge_txid - tx.set_rbf(rbf) tx.add_info_from_wallet(self) run_hook('make_unsigned_transaction', self, tx) return tx @@ -3065,9 +3070,11 @@ class Abstract_Wallet(ABC, Logger, EventListener): password=None, locktime=None, tx_version: Optional[int] = None, - batch_rbf: Optional[bool] = None, + base_tx: Optional[PartialTransaction] = None, + inputs: Optional[List[PartialTxInput]] = None, send_change_to_lightning: Optional[bool] = None, nonlocal_only: bool = False, + BIP69_sort: bool = True, ) -> PartialTransaction: """Helper function for make_unsigned_transaction.""" if fee is not None and feerate is not None: @@ -3082,12 +3089,14 @@ class Abstract_Wallet(ABC, Logger, EventListener): fee_estimator = fee tx = self.make_unsigned_transaction( coins=coins, + inputs=inputs, outputs=outputs, fee=fee_estimator, change_addr=change_addr, - batch_rbf=batch_rbf, + base_tx=base_tx, send_change_to_lightning=send_change_to_lightning, rbf=rbf, + BIP69_sort=BIP69_sort, ) if locktime is not None: tx.locktime = locktime