1
0

qml: don't initialize instance variables on class scope for non-singletons

(this somehow escaped attention before, as most objects usually don't have multiple instances,
unless multiple wallets are open at the same time.)
Also, move all signal declarations, class constants and variables to the top of class definitions.
This commit is contained in:
Sander van Grieken
2023-01-12 13:09:21 +01:00
parent 58d25d4a5d
commit 0bc8460005
22 changed files with 250 additions and 240 deletions

View File

@@ -10,10 +10,11 @@ class PluginQObject(QObject):
busyChanged = pyqtSignal()
pluginEnabledChanged = pyqtSignal()
_busy = False
def __init__(self, plugin, parent):
super().__init__(parent)
self._busy = False
self.plugin = plugin
self.app = parent

View File

@@ -8,27 +8,27 @@ from .qewallet import QEWallet
class QEAddressDetails(QObject):
_logger = get_logger(__name__)
detailsChanged = pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
_logger = get_logger(__name__)
self._wallet = None
self._address = None
_wallet = None
_address = None
self._label = None
self._frozen = False
self._scriptType = None
self._status = None
self._balance = QEAmount()
self._pubkeys = None
self._privkey = None
self._derivationPath = None
self._numtx = 0
_label = None
_frozen = False
_scriptType = None
_status = None
_balance = QEAmount()
_pubkeys = None
_privkey = None
_derivationPath = None
_numtx = 0
_historyModel = None
detailsChanged = pyqtSignal()
self._historyModel = None
walletChanged = pyqtSignal()
@pyqtProperty(QEWallet, notify=walletChanged)

View File

@@ -13,12 +13,6 @@ if TYPE_CHECKING:
class QEAddressListModel(QAbstractListModel):
def __init__(self, wallet: 'Abstract_Wallet', parent=None):
super().__init__(parent)
self.wallet = wallet
self.setDirty()
self.init_model()
_logger = get_logger(__name__)
# define listmodel rolemap
@@ -26,6 +20,12 @@ class QEAddressListModel(QAbstractListModel):
_ROLE_KEYS = range(Qt.UserRole, Qt.UserRole + len(_ROLE_NAMES))
_ROLE_MAP = dict(zip(_ROLE_KEYS, [bytearray(x.encode()) for x in _ROLE_NAMES]))
def __init__(self, wallet: 'Abstract_Wallet', parent=None):
super().__init__(parent)
self.wallet = wallet
self.setDirty()
self.init_model()
def rowCount(self, index):
return len(self.receive_addresses) + len(self.change_addresses)

View File

@@ -15,10 +15,6 @@ from electrum.mnemonic import is_any_2fa_seed_type
from .qetypes import QEAmount
class QEBitcoin(QObject):
def __init__(self, config, parent=None):
super().__init__(parent)
self.config = config
_logger = get_logger(__name__)
generatedSeedChanged = pyqtSignal()
@@ -30,6 +26,10 @@ class QEBitcoin(QObject):
validationMessageChanged = pyqtSignal()
_validationMessage = ''
def __init__(self, config, parent=None):
super().__init__(parent)
self.config = config
@pyqtProperty('QString', notify=generatedSeedChanged)
def generated_seed(self):
return self.generatedSeed

View File

@@ -21,16 +21,17 @@ class QEChannelDetails(QObject, QtEventListener):
Q_ENUMS(State)
_wallet = None
_channelid = None
_channel = None
channelChanged = pyqtSignal()
channelCloseSuccess = pyqtSignal()
channelCloseFailed = pyqtSignal([str], arguments=['message'])
def __init__(self, parent=None):
super().__init__(parent)
self._wallet = None
self._channelid = None
self._channel = None
self.register_callbacks()
self.destroyed.connect(lambda: self.on_destroy())

View File

@@ -19,18 +19,8 @@ from .qewallet import QEWallet
class QEChannelOpener(QObject, AuthMixin):
def __init__(self, parent=None):
super().__init__(parent)
_logger = get_logger(__name__)
_wallet = None
_nodeid = None
_amount = QEAmount()
_valid = False
_opentx = None
_txdetails = None
validationError = pyqtSignal([str,str], arguments=['code','message'])
conflictingBackup = pyqtSignal([str], arguments=['message'])
channelOpening = pyqtSignal([str], arguments=['peer'])
@@ -39,6 +29,16 @@ class QEChannelOpener(QObject, AuthMixin):
dataChanged = pyqtSignal() # generic notify signal
def __init__(self, parent=None):
super().__init__(parent)
self._wallet = None
self._nodeid = None
self._amount = QEAmount()
self._valid = False
self._opentx = None
self._txdetails = None
walletChanged = pyqtSignal()
@pyqtProperty(QEWallet, notify=walletChanged)
def wallet(self):

View File

@@ -10,12 +10,12 @@ from .qetypes import QEAmount
from .auth import AuthMixin, auth_protect
class QEConfig(AuthMixin, QObject):
_logger = get_logger(__name__)
def __init__(self, config, parent=None):
super().__init__(parent)
self.config = config
_logger = get_logger(__name__)
autoConnectChanged = pyqtSignal()
@pyqtProperty(bool, notify=autoConnectChanged)
def autoConnect(self):

View File

@@ -107,14 +107,8 @@ class QEWalletListModel(QAbstractListModel):
i += 1
class QEDaemon(AuthMixin, QObject):
def __init__(self, daemon, parent=None):
super().__init__(parent)
self.daemon = daemon
self.qefx = QEFX(daemon.fx, daemon.config)
self._walletdb = QEWalletDB()
self._walletdb.validPasswordChanged.connect(self.passwordValidityCheck)
_logger = get_logger(__name__)
_available_wallets = None
_current_wallet = None
_new_wallet_wizard = None
@@ -133,6 +127,13 @@ class QEDaemon(AuthMixin, QObject):
walletOpenError = pyqtSignal([str], arguments=["error"])
walletDeleteError = pyqtSignal([str,str], arguments=['code', 'message'])
def __init__(self, daemon, parent=None):
super().__init__(parent)
self.daemon = daemon
self.qefx = QEFX(daemon.fx, daemon.config)
self._walletdb = QEWalletDB()
self._walletdb.validPasswordChanged.connect(self.passwordValidityCheck)
@pyqtSlot()
def passwordValidityCheck(self):
if not self._walletdb._validPassword:

View File

@@ -12,6 +12,10 @@ from .qetypes import QEAmount
from .util import QtEventListener, event_listener
class QEFX(QObject, QtEventListener):
_logger = get_logger(__name__)
quotesUpdated = pyqtSignal()
def __init__(self, fxthread: FxThread, config: SimpleConfig, parent=None):
super().__init__(parent)
self.fx = fxthread
@@ -19,10 +23,6 @@ class QEFX(QObject, QtEventListener):
self.register_callbacks()
self.destroyed.connect(lambda: self.on_destroy())
_logger = get_logger(__name__)
quotesUpdated = pyqtSignal()
def on_destroy(self):
self.unregister_callbacks()

View File

@@ -44,14 +44,14 @@ class QEInvoice(QObject):
_logger = get_logger(__name__)
_wallet = None
_canSave = False
_canPay = False
_key = None
def __init__(self, parent=None):
super().__init__(parent)
self._wallet = None
self._canSave = False
self._canPay = False
self._key = None
walletChanged = pyqtSignal()
@pyqtProperty(QEWallet, notify=walletChanged)
def wallet(self):
@@ -117,15 +117,8 @@ class QEInvoice(QObject):
return self._wallet.wallet.lnworker.num_sats_can_send()
class QEInvoiceParser(QEInvoice):
_logger = get_logger(__name__)
_invoiceType = QEInvoice.Type.Invalid
_recipient = ''
_effectiveInvoice = None
_amount = QEAmount()
_userinfo = ''
invoiceChanged = pyqtSignal()
invoiceSaved = pyqtSignal([str], arguments=['key'])
@@ -140,6 +133,13 @@ class QEInvoiceParser(QEInvoice):
def __init__(self, parent=None):
super().__init__(parent)
self._invoiceType = QEInvoice.Type.Invalid
self._recipient = ''
self._effectiveInvoice = None
self._amount = QEAmount()
self._userinfo = ''
self.clear()
@pyqtProperty(int, notify=invoiceChanged)

View File

@@ -13,11 +13,6 @@ from .qetypes import QEAmount
class QEAbstractInvoiceListModel(QAbstractListModel):
_logger = get_logger(__name__)
def __init__(self, wallet, parent=None):
super().__init__(parent)
self.wallet = wallet
self.init_model()
# define listmodel rolemap
_ROLE_NAMES=('key', 'is_lightning', 'timestamp', 'date', 'message', 'amount',
'status', 'status_str', 'address', 'expiration', 'type', 'onchain_fallback',
@@ -26,6 +21,11 @@ class QEAbstractInvoiceListModel(QAbstractListModel):
_ROLE_MAP = dict(zip(_ROLE_KEYS, [bytearray(x.encode()) for x in _ROLE_NAMES]))
_ROLE_RMAP = dict(zip(_ROLE_NAMES, _ROLE_KEYS))
def __init__(self, wallet, parent=None):
super().__init__(parent)
self.wallet = wallet
self.init_model()
def rowCount(self, index):
return len(self.invoices)

View File

@@ -7,16 +7,16 @@ from .qetypes import QEAmount
from .qewallet import QEWallet
class QELnPaymentDetails(QObject):
_logger = get_logger(__name__)
detailsChanged = pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
_logger = get_logger(__name__)
_wallet = None
_key = None
_date = None
detailsChanged = pyqtSignal()
self._wallet = None
self._key = None
self._date = None
walletChanged = pyqtSignal()
@pyqtProperty(QEWallet, notify=walletChanged)

View File

@@ -8,17 +8,6 @@ from .util import QtEventListener, event_listener
from .qeserverlistmodel import QEServerListModel
class QENetwork(QObject, QtEventListener):
def __init__(self, network, qeconfig, parent=None):
super().__init__(parent)
self.network = network
self._qeconfig = qeconfig
self._serverListModel = None
self._height = network.get_local_height() # init here, update event can take a while
self.register_callbacks()
self._qeconfig.useGossipChanged.connect(self.on_gossip_setting_changed)
_logger = get_logger(__name__)
networkUpdated = pyqtSignal()
@@ -47,6 +36,16 @@ class QENetwork(QObject, QtEventListener):
_gossipDbChannels = 0
_gossipDbPolicies = 0
def __init__(self, network, qeconfig, parent=None):
super().__init__(parent)
self.network = network
self._qeconfig = qeconfig
self._serverListModel = None
self._height = network.get_local_height() # init here, update event can take a while
self.register_callbacks()
self._qeconfig.useGossipChanged.connect(self.on_gossip_setting_changed)
@event_listener
def on_event_network_updated(self, *args):
self.networkUpdated.emit()

View File

@@ -15,21 +15,22 @@ from electrum.i18n import _
from electrum.util import profiler, get_asyncio_loop
class QEQRParser(QObject):
def __init__(self, text=None, parent=None):
super().__init__(parent)
self._text = text
self.qrreader = get_qr_reader()
if not self.qrreader:
raise Exception(_("The platform QR detection library is not available."))
_logger = get_logger(__name__)
busyChanged = pyqtSignal()
dataChanged = pyqtSignal()
imageChanged = pyqtSignal()
_busy = False
_image = None
def __init__(self, text=None, parent=None):
super().__init__(parent)
self._busy = False
self._image = None
self._text = text
self.qrreader = get_qr_reader()
if not self.qrreader:
raise Exception(_("The platform QR detection library is not available."))
@pyqtSlot('QImage')
def scanImage(self, image=None):

View File

@@ -26,17 +26,18 @@ class QERequestDetails(QObject, QtEventListener):
_logger = get_logger(__name__)
_wallet = None
_key = None
_req = None
_timer = None
_amount = None
detailsChanged = pyqtSignal() # generic request properties changed signal
statusChanged = pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
self._wallet = None
self._key = None
self._req = None
self._timer = None
self._amount = None
self.register_callbacks()
self.destroyed.connect(lambda: self.on_destroy())

View File

@@ -13,7 +13,6 @@ from .util import QtEventListener, qt_event_listener, event_listener
class QEServerListModel(QAbstractListModel, QtEventListener):
_logger = get_logger(__name__)
_chaintips = 0
# define listmodel rolemap
_ROLE_NAMES=('name', 'address', 'is_connected', 'is_primary', 'is_tor', 'chain', 'height')
@@ -23,6 +22,9 @@ class QEServerListModel(QAbstractListModel, QtEventListener):
def __init__(self, network, parent=None):
super().__init__(parent)
self._chaintips = 0
self.network = network
self.init_model()
self.register_callbacks()

View File

@@ -18,30 +18,30 @@ from .qewallet import QEWallet
class QESwapHelper(AuthMixin, QObject):
_logger = get_logger(__name__)
_wallet = None
_sliderPos = 0
_rangeMin = 0
_rangeMax = 0
_tx = None
_valid = False
_userinfo = ''
_tosend = QEAmount()
_toreceive = QEAmount()
_serverfeeperc = ''
_serverfee = QEAmount()
_miningfee = QEAmount()
_isReverse = False
_service_available = False
_send_amount = 0
_receive_amount = 0
error = pyqtSignal([str], arguments=['message'])
confirm = pyqtSignal([str], arguments=['message'])
def __init__(self, parent=None):
super().__init__(parent)
self._wallet = None
self._sliderPos = 0
self._rangeMin = 0
self._rangeMax = 0
self._tx = None
self._valid = False
self._userinfo = ''
self._tosend = QEAmount()
self._toreceive = QEAmount()
self._serverfeeperc = ''
self._serverfee = QEAmount()
self._miningfee = QEAmount()
self._isReverse = False
self._service_available = False
self._send_amount = 0
self._receive_amount = 0
walletChanged = pyqtSignal()
@pyqtProperty(QEWallet, notify=walletChanged)
def wallet(self):

View File

@@ -10,18 +10,6 @@ from .qetypes import QEAmount
from .util import QtEventListener, qt_event_listener
class QETransactionListModel(QAbstractListModel, QtEventListener):
def __init__(self, wallet, parent=None, *, onchain_domain=None, include_lightning=True):
super().__init__(parent)
self.wallet = wallet
self.onchain_domain = onchain_domain
self.include_lightning = include_lightning
self.register_callbacks()
self.destroyed.connect(lambda: self.on_destroy())
self.requestRefresh.connect(lambda: self.init_model())
self.init_model()
_logger = get_logger(__name__)
# define listmodel rolemap
@@ -34,6 +22,18 @@ class QETransactionListModel(QAbstractListModel, QtEventListener):
requestRefresh = pyqtSignal()
def __init__(self, wallet, parent=None, *, onchain_domain=None, include_lightning=True):
super().__init__(parent)
self.wallet = wallet
self.onchain_domain = onchain_domain
self.include_lightning = include_lightning
self.register_callbacks()
self.destroyed.connect(lambda: self.on_destroy())
self.requestRefresh.connect(lambda: self.init_model())
self.init_model()
def on_destroy(self):
self.unregister_callbacks()

View File

@@ -12,41 +12,6 @@ from .util import QtEventListener, event_listener
class QETxDetails(QObject, QtEventListener):
_logger = get_logger(__name__)
_wallet = None
_txid = ''
_rawtx = ''
_label = ''
_tx = None
_status = ''
_amount = QEAmount()
_lnamount = QEAmount()
_fee = QEAmount()
_inputs = []
_outputs = []
_is_lightning_funding_tx = False
_can_bump = False
_can_dscancel = False
_can_broadcast = False
_can_cpfp = False
_can_save_as_local = False
_can_remove = False
_can_sign = False
_is_unrelated = False
_is_complete = False
_is_mined = False
_is_final = False
_mempool_depth = ''
_date = ''
_height = 0
_confirmations = 0
_txpos = -1
_header_hash = ''
confirmRemoveLocalTx = pyqtSignal([str], arguments=['message'])
saveTxError = pyqtSignal([str,str], arguments=['code', 'message'])
saveTxSuccess = pyqtSignal()
@@ -58,6 +23,41 @@ class QETxDetails(QObject, QtEventListener):
self.register_callbacks()
self.destroyed.connect(lambda: self.on_destroy())
self._wallet = None
self._txid = ''
self._rawtx = ''
self._label = ''
self._tx = None
self._status = ''
self._amount = QEAmount()
self._lnamount = QEAmount()
self._fee = QEAmount()
self._inputs = []
self._outputs = []
self._is_lightning_funding_tx = False
self._can_bump = False
self._can_dscancel = False
self._can_broadcast = False
self._can_cpfp = False
self._can_save_as_local = False
self._can_remove = False
self._can_sign = False
self._is_unrelated = False
self._is_complete = False
self._is_mined = False
self._is_final = False
self._mempool_depth = ''
self._date = ''
self._height = 0
self._confirmations = 0
self._txpos = -1
self._header_hash = ''
def on_destroy(self):
self.unregister_callbacks()

View File

@@ -16,16 +16,16 @@ from .qetypes import QEAmount
from .util import QtEventListener, event_listener
class FeeSlider(QObject):
_wallet = None
_sliderSteps = 0
_sliderPos = 0
_method = -1
_target = ''
_config = None
def __init__(self, parent=None):
super().__init__(parent)
self._wallet = None
self._sliderSteps = 0
self._sliderPos = 0
self._method = -1
self._target = ''
self._config = None
walletChanged = pyqtSignal()
@pyqtProperty(QEWallet, notify=walletChanged)
def wallet(self):
@@ -125,17 +125,17 @@ class FeeSlider(QObject):
raise NotImplementedError()
class TxFeeSlider(FeeSlider):
_fee = QEAmount()
_feeRate = ''
_rbf = False
_tx = None
_outputs = []
_valid = False
_warning = ''
def __init__(self, parent=None):
super().__init__(parent)
self._fee = QEAmount()
self._feeRate = ''
self._rbf = False
self._tx = None
self._outputs = []
self._valid = False
self._warning = ''
feeChanged = pyqtSignal()
@pyqtProperty(QEAmount, notify=feeChanged)
def fee(self):
@@ -223,13 +223,13 @@ class QETxFinalizer(TxFeeSlider):
self.f_make_tx = make_tx
self.f_accept = accept
_logger = get_logger(__name__)
self._address = ''
self._amount = QEAmount()
self._effectiveAmount = QEAmount()
self._extraFee = QEAmount()
self._canRbf = False
_address = ''
_amount = QEAmount()
_effectiveAmount = QEAmount()
_extraFee = QEAmount()
_canRbf = False
_logger = get_logger(__name__)
addressChanged = pyqtSignal()
@pyqtProperty(str, notify=addressChanged)
@@ -394,12 +394,13 @@ class QETxFinalizer(TxFeeSlider):
# calls get_tx() once txid is set
# calls tx_verified and emits txMined signal once tx is verified
class TxMonMixin(QtEventListener):
_txid = ''
txMined = pyqtSignal()
def __init__(self, parent=None):
self._logger.debug('TxMonMixin.__init__')
self._txid = ''
self.register_callbacks()
self.destroyed.connect(lambda: self.on_destroy())
@@ -436,14 +437,14 @@ class TxMonMixin(QtEventListener):
class QETxRbfFeeBumper(TxFeeSlider, TxMonMixin):
_logger = get_logger(__name__)
_oldfee = QEAmount()
_oldfee_rate = 0
_orig_tx = None
_rbf = True
def __init__(self, parent=None):
super().__init__(parent)
self._oldfee = QEAmount()
self._oldfee_rate = 0
self._orig_tx = None
self._rbf = True
oldfeeChanged = pyqtSignal()
@pyqtProperty(QEAmount, notify=oldfeeChanged)
def oldfee(self):
@@ -552,15 +553,15 @@ class QETxRbfFeeBumper(TxFeeSlider, TxMonMixin):
class QETxCanceller(TxFeeSlider, TxMonMixin):
_logger = get_logger(__name__)
_oldfee = QEAmount()
_oldfee_rate = 0
_orig_tx = None
_txid = ''
_rbf = True
def __init__(self, parent=None):
super().__init__(parent)
self._oldfee = QEAmount()
self._oldfee_rate = 0
self._orig_tx = None
self._txid = ''
self._rbf = True
oldfeeChanged = pyqtSignal()
@pyqtProperty(QEAmount, notify=oldfeeChanged)
def oldfee(self):
@@ -658,24 +659,24 @@ class QETxCanceller(TxFeeSlider, TxMonMixin):
class QETxCpfpFeeBumper(TxFeeSlider, TxMonMixin):
_logger = get_logger(__name__)
_input_amount = QEAmount()
_output_amount = QEAmount()
_fee_for_child = QEAmount()
_total_fee = QEAmount()
_total_fee_rate = 0
_total_size = 0
_parent_tx = None
_new_tx = None
_parent_tx_size = 0
_parent_fee = 0
_max_fee = 0
_txid = ''
_rbf = True
def __init__(self, parent=None):
super().__init__(parent)
self._input_amount = QEAmount()
self._output_amount = QEAmount()
self._fee_for_child = QEAmount()
self._total_fee = QEAmount()
self._total_fee_rate = 0
self._total_size = 0
self._parent_tx = None
self._new_tx = None
self._parent_tx_size = 0
self._parent_fee = 0
self._max_fee = 0
self._txid = ''
self._rbf = True
totalFeeChanged = pyqtSignal()
@pyqtProperty(QEAmount, notify=totalFeeChanged)
def totalFee(self):

View File

@@ -74,28 +74,29 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
_network_signal = pyqtSignal(str, object)
_isUpToDate = False
_synchronizing = False
_synchronizing_progress = ''
_lightningbalance = QEAmount()
_confirmedbalance = QEAmount()
_unconfirmedbalance = QEAmount()
_frozenbalance = QEAmount()
_totalbalance = QEAmount()
_lightningcanreceive = QEAmount()
_lightningcansend = QEAmount()
def __init__(self, wallet: 'Abstract_Wallet', parent=None):
super().__init__(parent)
self.wallet = wallet
self._isUpToDate = False
self._synchronizing = False
self._synchronizing_progress = ''
self._historyModel = None
self._addressModel = None
self._requestModel = None
self._invoiceModel = None
self._channelModel = None
self._lightningbalance = QEAmount()
self._confirmedbalance = QEAmount()
self._unconfirmedbalance = QEAmount()
self._frozenbalance = QEAmount()
self._totalbalance = QEAmount()
self._lightningcanreceive = QEAmount()
self._lightningcansend = QEAmount()
self.tx_notification_queue = queue.Queue()
self.tx_notification_last_time = 0
@@ -420,6 +421,8 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
def lightningBalance(self):
if self.isLightning:
self._lightningbalance.satsInt = int(self.wallet.lnworker.get_balance())
# else:
# self._lightningbalance.satsInt = 0
return self._lightningbalance
@pyqtProperty(QEAmount, notify=balanceChanged)

View File

@@ -10,14 +10,6 @@ from electrum.util import InvalidPassword
from electrum import keystore
class QEWalletDB(QObject):
def __init__(self, parent=None):
super().__init__(parent)
from .qeapp import ElectrumQmlApplication
self.daemon = ElectrumQmlApplication._daemon
self.reset()
_logger = get_logger(__name__)
fileNotFound = pyqtSignal()
@@ -31,6 +23,14 @@ class QEWalletDB(QObject):
readyChanged = pyqtSignal()
invalidPassword = pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
from .qeapp import ElectrumQmlApplication
self.daemon = ElectrumQmlApplication._daemon
self.reset()
def reset(self):
self._path = None
self._needsPassword = False