Browse Source

wallet: (fix) "batch_rbf" must not mutate LN funding txs

The "Batch RBF transactions" feature mutates existing "local" and "unconfirmed RBF"
transactions when creating new transactions: it simply adds the new outputs to the
existing txs (and updates the change).
The "RBF" flag is only enforced for unconfirmed txs, not for local txs.
The bug was that given a local LN funding tx, when creating a new channel
with "batch_rbf" enabled, we would modify the existing local tx, and
broadcast that.

related: #7298
master
SomberNight 5 years ago
parent
commit
b2169b745e
No known key found for this signature in database
GPG Key ID: B33B5F232C6271E9
  1. 10
      electrum/wallet.py

10
electrum/wallet.py

@ -586,6 +586,10 @@ class Abstract_Wallet(AddressSynchronizer, ABC):
"""Returns a map: pubkey -> (keystore, derivation_suffix)""" """Returns a map: pubkey -> (keystore, derivation_suffix)"""
return {} return {}
def is_lightning_funding_tx(self, txid: str) -> bool:
return any([chan.funding_outpoint.txid == txid
for chan in self.lnworker.channels.values()])
def get_tx_info(self, tx: Transaction) -> TxWalletDetails: def get_tx_info(self, tx: Transaction) -> TxWalletDetails:
tx_wallet_delta = self.get_wallet_delta(tx) tx_wallet_delta = self.get_wallet_delta(tx)
is_relevant = tx_wallet_delta.is_relevant is_relevant = tx_wallet_delta.is_relevant
@ -598,8 +602,7 @@ class Abstract_Wallet(AddressSynchronizer, ABC):
tx_hash = tx.txid() # note: txid can be None! e.g. when called from GUI tx dialog tx_hash = tx.txid() # note: txid can be None! e.g. when called from GUI tx dialog
is_lightning_funding_tx = False is_lightning_funding_tx = False
if self.has_lightning() and tx_hash is not None: if self.has_lightning() and tx_hash is not None:
is_lightning_funding_tx = any([chan.funding_outpoint.txid == tx_hash is_lightning_funding_tx = self.is_lightning_funding_tx(tx_hash)
for chan in self.lnworker.channels.values()])
tx_we_already_have_in_db = self.db.get_transaction(tx_hash) tx_we_already_have_in_db = self.db.get_transaction(tx_hash)
can_save_as_local = (is_relevant and tx.txid() is not None can_save_as_local = (is_relevant and tx.txid() is not None
and (tx_we_already_have_in_db is None or not tx_we_already_have_in_db.is_complete())) and (tx_we_already_have_in_db is None or not tx_we_already_have_in_db.is_complete()))
@ -1241,6 +1244,9 @@ class Abstract_Wallet(AddressSynchronizer, ABC):
# all inputs should be is_mine # all inputs should be is_mine
if not all([self.is_mine(self.get_txin_address(txin)) for txin in tx.inputs()]): if not all([self.is_mine(self.get_txin_address(txin)) for txin in tx.inputs()]):
continue continue
# do not mutate LN funding txs, as that would change their txid
if self.is_lightning_funding_tx(txid):
continue
# prefer txns already in mempool (vs local) # prefer txns already in mempool (vs local)
if hist_item.tx_mined_status.height == TX_HEIGHT_LOCAL: if hist_item.tx_mined_status.height == TX_HEIGHT_LOCAL:
candidate = tx candidate = tx

Loading…
Cancel
Save