wallet: make labels private, and access to need lock
e.g. labels plugin iterated over wallet.labels on asyncio thread while user could trigger an edit from Qt thread
This commit is contained in:
@@ -36,18 +36,18 @@ class LabelsPlugin(BasePlugin):
|
||||
self.target_host = 'labels.electrum.org'
|
||||
self.wallets = {}
|
||||
|
||||
def encode(self, wallet, msg):
|
||||
def encode(self, wallet: 'Abstract_Wallet', msg: str) -> str:
|
||||
password, iv, wallet_id = self.wallets[wallet]
|
||||
encrypted = aes_encrypt_with_iv(password, iv, msg.encode('utf8'))
|
||||
return base64.b64encode(encrypted).decode()
|
||||
|
||||
def decode(self, wallet, message):
|
||||
def decode(self, wallet: 'Abstract_Wallet', message: str) -> str:
|
||||
password, iv, wallet_id = self.wallets[wallet]
|
||||
decoded = base64.b64decode(message)
|
||||
decrypted = aes_decrypt_with_iv(password, iv, decoded)
|
||||
return decrypted.decode('utf8')
|
||||
|
||||
def get_nonce(self, wallet):
|
||||
def get_nonce(self, wallet: 'Abstract_Wallet'):
|
||||
# nonce is the nonce to be used with the next change
|
||||
nonce = wallet.db.get('wallet_nonce')
|
||||
if nonce is None:
|
||||
@@ -55,12 +55,12 @@ class LabelsPlugin(BasePlugin):
|
||||
self.set_nonce(wallet, nonce)
|
||||
return nonce
|
||||
|
||||
def set_nonce(self, wallet, nonce):
|
||||
def set_nonce(self, wallet: 'Abstract_Wallet', nonce):
|
||||
self.logger.info(f"set {wallet.basename()} nonce to {nonce}")
|
||||
wallet.db.put("wallet_nonce", nonce)
|
||||
|
||||
@hook
|
||||
def set_label(self, wallet, item, label):
|
||||
def set_label(self, wallet: 'Abstract_Wallet', item, label):
|
||||
if wallet not in self.wallets:
|
||||
return
|
||||
if not item:
|
||||
@@ -99,7 +99,7 @@ class LabelsPlugin(BasePlugin):
|
||||
except Exception as e:
|
||||
raise Exception('Could not decode: ' + await result.text()) from e
|
||||
|
||||
async def push_thread(self, wallet):
|
||||
async def push_thread(self, wallet: 'Abstract_Wallet'):
|
||||
wallet_data = self.wallets.get(wallet, None)
|
||||
if not wallet_data:
|
||||
raise Exception('Wallet {} not loaded'.format(wallet))
|
||||
@@ -107,7 +107,7 @@ class LabelsPlugin(BasePlugin):
|
||||
bundle = {"labels": [],
|
||||
"walletId": wallet_id,
|
||||
"walletNonce": self.get_nonce(wallet)}
|
||||
for key, value in wallet.labels.items():
|
||||
for key, value in wallet.get_all_labels().items():
|
||||
try:
|
||||
encoded_key = self.encode(wallet, key)
|
||||
encoded_value = self.encode(wallet, value)
|
||||
@@ -118,7 +118,7 @@ class LabelsPlugin(BasePlugin):
|
||||
'externalId': encoded_key})
|
||||
await self.do_post("/labels", bundle)
|
||||
|
||||
async def pull_thread(self, wallet, force):
|
||||
async def pull_thread(self, wallet: 'Abstract_Wallet', force: bool):
|
||||
wallet_data = self.wallets.get(wallet, None)
|
||||
if not wallet_data:
|
||||
raise Exception('Wallet {} not loaded'.format(wallet))
|
||||
@@ -148,8 +148,8 @@ class LabelsPlugin(BasePlugin):
|
||||
result[key] = value
|
||||
|
||||
for key, value in result.items():
|
||||
if force or not wallet.labels.get(key):
|
||||
wallet.labels[key] = value
|
||||
if force or not wallet.get_label(key):
|
||||
wallet._set_label(key, value)
|
||||
|
||||
self.logger.info(f"received {len(response)} labels")
|
||||
self.set_nonce(wallet, response["nonce"] + 1)
|
||||
@@ -160,21 +160,21 @@ class LabelsPlugin(BasePlugin):
|
||||
|
||||
@ignore_exceptions
|
||||
@log_exceptions
|
||||
async def pull_safe_thread(self, wallet, force):
|
||||
async def pull_safe_thread(self, wallet: 'Abstract_Wallet', force: bool):
|
||||
try:
|
||||
await self.pull_thread(wallet, force)
|
||||
except ErrorConnectingServer as e:
|
||||
self.logger.info(repr(e))
|
||||
|
||||
def pull(self, wallet, force):
|
||||
def pull(self, wallet: 'Abstract_Wallet', force: bool):
|
||||
if not wallet.network: raise Exception(_('You are offline.'))
|
||||
return asyncio.run_coroutine_threadsafe(self.pull_thread(wallet, force), wallet.network.asyncio_loop).result()
|
||||
|
||||
def push(self, wallet):
|
||||
def push(self, wallet: 'Abstract_Wallet'):
|
||||
if not wallet.network: raise Exception(_('You are offline.'))
|
||||
return asyncio.run_coroutine_threadsafe(self.push_thread(wallet), wallet.network.asyncio_loop).result()
|
||||
|
||||
def start_wallet(self, wallet):
|
||||
def start_wallet(self, wallet: 'Abstract_Wallet'):
|
||||
if not wallet.network: return # 'offline' mode
|
||||
nonce = self.get_nonce(wallet)
|
||||
self.logger.info(f"wallet {wallet.basename()} nonce is {nonce}")
|
||||
|
||||
Reference in New Issue
Block a user