1
0

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:
SomberNight
2020-10-13 18:30:24 +02:00
parent da4f11dbd3
commit 4b6c86ecbe
13 changed files with 71 additions and 54 deletions

View File

@@ -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}")