1
0

add sanity checks we don't sign tx including dummy addr

Somewhat a follow-up to 649ce979ab.

This adds some safety belts so we don't accidentally sign a tx that
contains a dummy address.
Specifically we check that tx does not contain output for dummy addr:
- in wallet.sign_transaction
- in network.broadcast_transaction

The second one is perhaps redundant, but I think it does not hurt.
This commit is contained in:
SomberNight
2023-09-16 04:36:08 +00:00
parent 956b455954
commit 4c63d8729b
16 changed files with 94 additions and 41 deletions

View File

@@ -9,7 +9,7 @@ from electrum.i18n import _
from electrum.gui import messages
from electrum.util import bfh
from electrum.lnutil import extract_nodeid, ConnStringFormatError
from electrum.bitcoin import get_dummy_address
from electrum.bitcoin import DummyAddress
from electrum.lnworker import hardcoded_trampoline_nodes
from electrum.logging import get_logger
@@ -182,7 +182,7 @@ class QEChannelOpener(QObject, AuthMixin):
"""
self._logger.debug('opening channel')
# read funding_sat from tx; converts '!' to int value
funding_sat = funding_tx.output_value_for_address(get_dummy_address('channel'))
funding_sat = funding_tx.output_value_for_address(DummyAddress.CHANNEL)
lnworker = self._wallet.wallet.lnworker
def open_thread():

View File

@@ -6,7 +6,7 @@ from typing import Union
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer, Q_ENUMS
from electrum.i18n import _
from electrum.bitcoin import get_dummy_address
from electrum.bitcoin import DummyAddress
from electrum.logging import get_logger
from electrum.transaction import PartialTxOutput
from electrum.util import NotEnoughFunds, NoDynamicFeeEstimates, profiler, get_asyncio_loop
@@ -245,7 +245,7 @@ class QESwapHelper(AuthMixin, QObject, QtEventListener):
# this is just to estimate the maximal spendable onchain amount for HTLC
self.update_tx('!')
try:
max_onchain_spend = self._tx.output_value_for_address(get_dummy_address('swap'))
max_onchain_spend = self._tx.output_value_for_address(DummyAddress.SWAP)
except AttributeError: # happens if there are no utxos
max_onchain_spend = 0
reverse = int(min(lnworker.num_sats_can_send(),
@@ -283,7 +283,7 @@ class QESwapHelper(AuthMixin, QObject, QtEventListener):
self._tx = None
self.valid = False
return
outputs = [PartialTxOutput.from_address_and_value(get_dummy_address('swap'), onchain_amount)]
outputs = [PartialTxOutput.from_address_and_value(DummyAddress.SWAP, onchain_amount)]
coins = self._wallet.wallet.get_spendable_coins(None)
try:
self._tx = self._wallet.wallet.make_unsigned_transaction(

View File

@@ -39,6 +39,7 @@ from electrum.plugin import run_hook
from electrum.transaction import Transaction, PartialTransaction
from electrum.wallet import InternalAddressCorruption
from electrum.simple_config import SimpleConfig
from electrum.bitcoin import DummyAddress
from .util import (WindowModalDialog, ColorScheme, HelpLabel, Buttons, CancelButton,
BlockingWaitingDialog, PasswordLineEdit, WWLabel, read_QIcon)
@@ -574,7 +575,7 @@ class TxEditor(WindowModalDialog):
self.error = long_warning
else:
messages.append(long_warning)
if self.tx.has_dummy_output('swap'):
if self.tx.has_dummy_output(DummyAddress.SWAP):
messages.append(_('This transaction will send funds to a submarine swap.'))
# warn if spending unconf
if any((txin.block_height is not None and txin.block_height<=0) for txin in self.tx.inputs()):

View File

@@ -51,7 +51,7 @@ import electrum
from electrum.gui import messages
from electrum import (keystore, ecc, constants, util, bitcoin, commands,
paymentrequest, lnutil)
from electrum.bitcoin import COIN, is_address, get_dummy_address
from electrum.bitcoin import COIN, is_address, DummyAddress
from electrum.plugin import run_hook, BasePlugin
from electrum.i18n import _
from electrum.util import (format_time, UserCancelled, profiler, bfh, InvalidPassword,
@@ -1303,7 +1303,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger, QtEventListener):
@protected
def _open_channel(self, connect_str, funding_sat, push_amt, funding_tx, password):
# read funding_sat from tx; converts '!' to int value
funding_sat = funding_tx.output_value_for_address(get_dummy_address('channel'))
funding_sat = funding_tx.output_value_for_address(DummyAddress.CHANNEL)
def task():
return self.wallet.lnworker.open_channel(
connect_str=connect_str,

View File

@@ -11,7 +11,7 @@ from PyQt5.QtGui import QMovie, QColor
from electrum.i18n import _
from electrum.logging import Logger
from electrum.bitcoin import DummyAddress
from electrum.plugin import run_hook
from electrum.util import NotEnoughFunds, NoDynamicFeeEstimates, parse_max_spend
from electrum.invoices import PR_PAID, Invoice, PR_BROADCASTING, PR_BROADCAST
@@ -326,11 +326,11 @@ class SendTab(QWidget, MessageBoxMixin, Logger):
return
is_preview = conf_dlg.is_preview
if tx.has_dummy_output('swap'):
if tx.has_dummy_output(DummyAddress.SWAP):
sm = self.wallet.lnworker.swap_manager
coro = sm.request_swap_for_tx(tx)
swap, invoice, tx = self.network.run_from_another_thread(coro)
assert not tx.has_dummy_output('swap')
assert not tx.has_dummy_output(DummyAddress.SWAP)
tx.swap_invoice = invoice
tx.swap_payment_hash = swap.payment_hash

View File

@@ -5,7 +5,7 @@ from PyQt5.QtWidgets import QLabel, QVBoxLayout, QGridLayout, QPushButton
from electrum.i18n import _
from electrum.util import NotEnoughFunds, NoDynamicFeeEstimates
from electrum.bitcoin import get_dummy_address
from electrum.bitcoin import DummyAddress
from electrum.transaction import PartialTxOutput, PartialTransaction
from electrum.gui import messages
@@ -173,7 +173,7 @@ class SwapDialog(WindowModalDialog, QtEventListener):
def _spend_max_forward_swap(self, tx: Optional[PartialTransaction]) -> None:
if tx:
amount = tx.output_value_for_address(get_dummy_address('swap'))
amount = tx.output_value_for_address(DummyAddress.SWAP)
self.send_amount_e.setAmount(amount)
else:
self.send_amount_e.setAmount(None)
@@ -295,7 +295,7 @@ class SwapDialog(WindowModalDialog, QtEventListener):
if max_amount > max_swap_amount:
onchain_amount = max_swap_amount
self.config.WALLET_SEND_CHANGE_TO_LIGHTNING = False
outputs = [PartialTxOutput.from_address_and_value(get_dummy_address('swap'), onchain_amount)]
outputs = [PartialTxOutput.from_address_and_value(DummyAddress.SWAP, onchain_amount)]
try:
tx = self.window.wallet.make_unsigned_transaction(
coins=coins,

View File

@@ -46,7 +46,7 @@ from electrum.simple_config import SimpleConfig
from electrum.util import quantize_feerate
from electrum import bitcoin
from electrum.bitcoin import base_encode, NLOCKTIME_BLOCKHEIGHT_MAX, get_dummy_address
from electrum.bitcoin import base_encode, NLOCKTIME_BLOCKHEIGHT_MAX, DummyAddress
from electrum.i18n import _
from electrum.plugin import run_hook
from electrum import simple_config
@@ -183,7 +183,7 @@ class TxInOutWidget(QWidget):
fmt.setAnchor(True)
fmt.setUnderlineStyle(QTextCharFormat.SingleUnderline)
return fmt
elif sm and sm.is_lockup_address_for_a_swap(addr) or addr==get_dummy_address('swap'):
elif sm and sm.is_lockup_address_for_a_swap(addr) or addr == DummyAddress.SWAP:
tf_used_swap = True
return self.txo_color_swap.text_char_format
elif self.wallet.is_billing_address(addr):