diff --git a/django/background_task/tasks.py b/django/background_task/tasks.py index 80a1248..409cea6 100644 --- a/django/background_task/tasks.py +++ b/django/background_task/tasks.py @@ -38,7 +38,6 @@ def bg_runner(proxy_task, task=None, loop=None, *args, **kwargs): task = task_qs[0] if func is None: raise BackgroundTaskError("Function is None, can't execute!") - print("bg_runner, loop {}".format(loop)) kwargs['loop'] = loop func(*args, **kwargs) @@ -96,8 +95,6 @@ class Tasks(object): return _decorator def run_task(self, task_name, loop, args=None, kwargs=None): - print("run_task loop {}".format(loop)) - # task_name can be either the name of a task or a Task instance. if isinstance(task_name, Task): task = task_name task_name = task.task_name diff --git a/django/finances/electrum.py b/django/finances/electrum.py index 454b007..ea417fc 100644 --- a/django/finances/electrum.py +++ b/django/finances/electrum.py @@ -9,11 +9,10 @@ from finances.models import OutputStat, HistoricalPrice import logging logger = logging.getLogger('labelbase') - async def interact(conn, server_info, method, utxo): try: await conn.connect(server_info, "s", use_tor=server_info.is_onion, - disable_cert_verify=True, short_term=True) + disable_cert_verify=True, short_term=True) txid, index = utxo.split(":") try: txn = await conn.RPC(method, txid, True) @@ -43,10 +42,8 @@ async def interact_addr(conn, server_info, method, addr): hextx = await conn.RPC(method, addr) if hextx is not None: return hextx - else: - print("Failed to fetch transaction.") except ElectrumErrorResponse as ex: - print(ex) + logger.error(ex) finally: conn.close() @@ -58,167 +55,92 @@ def is_valid_output_ref(ref): return False -def checkup_label(label_id, loop): +def checkup_label(label_id, loop): if label_id and loop: try: elem = Label.objects.get(id=label_id) - output = OutputStat.objects.filter(user=elem.labelbase.user, - type_ref_hash=elem.type_ref_hash, - network=elem.labelbase.network).last() - if not output: - output = OutputStat(user=elem.labelbase.user, - type_ref_hash=elem.type_ref_hash, - network=elem.labelbase.network, value=0) + output = OutputStat.objects.filter( + user=elem.labelbase.user, + type_ref_hash=elem.type_ref_hash, + network=elem.labelbase.network + ).last() - if elem.type == "output" and is_valid_output_ref(elem.ref) and \ - (output.spent is not True or output.confirmed_at_block_time == 0): + if not output: + output = OutputStat( + user=elem.labelbase.user, + type_ref_hash=elem.type_ref_hash, + network=elem.labelbase.network, + value=0, + spent=None, + confirmed_at_block_height=0, + confirmed_at_block_time=0 + ) + logger.debug(f"Output before processing: {output.output_metrics_dict()}") + + if elem.type == "output" and is_valid_output_ref(elem.ref) and ( + output.spent is not True or output.confirmed_at_block_time == 0 + ): + # Determine server info based on network if elem.labelbase.is_mainnet: - electrum_hostname = elem.labelbase.user.profile.electrum_hostname or "electrum.emzy.de" + electrum_hostname = elem.labelbase.user.profile.electrum_hostname or "fulcrum.sethforprivacy.com" electrum_ports = elem.labelbase.user.profile.electrum_ports or "s50002" elif elem.labelbase.is_testnet: electrum_hostname = elem.labelbase.user.profile.electrum_hostname_test or "testnet.qtornado.com" electrum_ports = elem.labelbase.user.profile.electrum_ports_test or "s51002" - server_info = ServerInfo(electrum_hostname, electrum_hostname, ports=(electrum_ports)) + else: + raise ValueError("Unknown network type.") + server_info = ServerInfo(electrum_hostname, electrum_hostname, ports=(electrum_ports)) conn = StratumClient() utxo = elem.ref - utxo_data = {} + + # Fetch transaction details utxo_resp = loop.run_until_complete(interact(conn, server_info, "blockchain.transaction.get", utxo)) if utxo_resp: txid, index, address, value, blocktime, utxo_data = utxo_resp - if utxo_data: - #output.next_input_attributes = utxo_data - output.set_next_input_attributes(utxo_data) + logger.debug(f"Transaction {txid} fetched with blocktime {blocktime}") if blocktime: - HistoricalPrice.get_or_create_from_api(None, timestamp=blocktime) + output.confirmed_at_block_time = blocktime + output.confirmed_at_block_height = txn.get('height', 0) + # Fetch all unspents for the address try: unspents = loop.run_until_complete(interact_addr(conn, server_info, "blockchain.address.listunspent", address)) except: - conn.last_error = None # reset error if needed + conn.last_error = None unspents = loop.run_until_complete(interact_addr(conn, server_info, "blockchain.scripthash.listunspent", address)) - utxo_value = 0 - utxo_height = 0 + logger.debug(f"Unspents for address {address}: {unspents}") - if unspents: - for unspent in unspents: - if unspent.get('tx_hash') == txid and \ - unspent.get('tx_pos') == int(index) and \ - unspent.get('height') > 0 and \ - unspent.get('value') > 0: # Output is confirmed, but not spent yet - output.spent = False - utxo_value = unspent.get('value') - utxo_height = unspent.get('height') + utxo_found = False + for unspent in unspents: + if unspent.get('tx_hash') == txid and unspent.get('tx_pos') == int(index): + output.spent = False + output.value = unspent.get('value', 0) + output.confirmed_at_block_height = unspent.get('height', 0) + utxo_found = True + break + + if not utxo_found: + output.spent = True + logger.warning(f"UTXO {txid}:{index} not found in unspent outputs.") + else: + logger.error(f"Failed to fetch transaction details for {utxo}") - output.network = elem.labelbase.network - if utxo_height: - output.confirmed_at_block_height = utxo_height - if blocktime: - output.confirmed_at_block_time = blocktime - if utxo_value: - output.value = utxo_value - elif value: - output.value = value - break - # elif conn.last_error: output.last_error = conn.last_error else: - output.last_error = {} + logger.warning(f"Unknown error occurred for UTXO {utxo}") + output.last_error = {"error": "Unknown issue"} + + logger.debug(f"Output after processing (before save): {output.output_metrics_dict()}") output.save() - try: - conn.close() - except: - pass + output.refresh_from_db() + logger.debug(f"Output after saving: {output.output_metrics_dict()}") + conn.close() except Exception as e: - logger.error("Error processing label {}: {}".format(label_id, e)) + logger.error(f"Error processing label {label_id}: {e}") else: - if not label_id: - logger.error("Can't get label_id! {}".format(label_id)) - if not loop: - logger.error("Can't get loop!") - - -def checkup_label_buggy(label_id, loop): - if label_id and loop: - elem = Label.objects.get(id=label_id) - output = OutputStat.objects.filter(user=elem.labelbase.user, - type_ref_hash=elem.type_ref_hash, - network=elem.labelbase.network).last() - if not output: - output = OutputStat(user=elem.labelbase.user, - type_ref_hash=elem.type_ref_hash, - network=elem.labelbase.network, value=0) - #print("Using OutputStat id {}".format(output)) - #print("elem.type {} {} {} {}".format(elem.type, is_valid_output_ref(elem.ref), elem.ref, output.spent)) - if elem.type == "output" and is_valid_output_ref(elem.ref) and \ - (output.spent is not True or output.confirmed_at_block_time == 0): - electrum_hostname = elem.labelbase.user.profile.electrum_hostname - if not electrum_hostname: - electrum_hostname = "electrum.emzy.de" - electrum_ports = elem.labelbase.user.profile.electrum_ports - if not electrum_ports: - electrum_ports = "s50002" - server_info = ServerInfo(electrum_hostname, electrum_hostname, ports=((electrum_ports))) - conn = StratumClient() - assert elem.type_ref_hash - utxo = elem.ref - tx_hash, tx_pos = elem.ref.split(":") - utxo_resp = loop.run_until_complete(interact(conn, server_info, "blockchain.transaction.get", utxo)) - blocktime = 0 - if utxo_resp: - txid, index, address, value, blocktime = utxo_resp - if blocktime: - #print("Found blocktime {} for label id {}.".format(blocktime, label_id)) - HistoricalPrice.get_or_create_from_api(None, timestamp=blocktime) - try: - unspents = loop.run_until_complete(interact_addr(conn, server_info, "blockchain.address.listunspent", address)) - except: - conn.last_error = None # reset error if needed - unspents = loop.run_until_complete(interact_addr(conn, server_info, "blockchain.scripthash.listunspent", address)) - unspent_utxo = False - utxo_value = 0 - utxo_height = 0 - if unspents: - for unspent in unspents: - if unspent.get('tx_hash') == tx_hash and \ - unspent.get('tx_pos') == int(tx_pos) and \ - unspent.get('height') > 0 and \ - unspent.get('value') > 0: - unspent_utxo = True - utxo_value = unspent.get('value') - utxo_height = unspent.get('height') - break - if output: - output.network = elem.labelbase.network - if utxo_height: - output.confirmed_at_block_height = utxo_height - if blocktime: - output.confirmed_at_block_time = blocktime - if utxo_value: - output.value = utxo_value - elif value: # take value from TX - output.value = value - if unspent_utxo: - output.spent = False - else: - output.spent = True - output.last_error = {} - elif conn.last_error: - # Damn... - output.last_error = conn.last_error - else: - output.last_error = {} - output.save() - try: - conn.close() - except: - pass - else: - if not label_id: - logger.error("Can't get label_id! {}".format(label_id)) - if not loop: - logger.error("Can't get loop!") + logger.error(f"Invalid input: label_id={label_id}, loop={loop}") diff --git a/django/finances/models.py b/django/finances/models.py index 89cd0ab..9c89365 100644 --- a/django/finances/models.py +++ b/django/finances/models.py @@ -11,9 +11,6 @@ from jsonfield import JSONField import json from django.contrib.auth.models import User from shared.encryption import get_fernet_key, cipher_suite - - - import logging logger = logging.getLogger('labelbase') @@ -54,9 +51,11 @@ class OutputStat(models.Model): self.next_enc_input_attrs = encrypted_data.decode('utf-8') def next_input_attributes(self): - encrypted_data = self.next_enc_input_attrs.encode('utf-8') - decrypted_data = cipher_suite.decrypt(encrypted_data) - return json.loads(decrypted_data.decode('utf-8')) + if self.next_enc_input_attrs: + encrypted_data = self.next_enc_input_attrs.encode('utf-8') + decrypted_data = cipher_suite.decrypt(encrypted_data) + return json.loads(decrypted_data.decode('utf-8')) + return json.loads("{}") MAINNET = 'mainnet' TESTNET = 'testnet' @@ -207,13 +206,11 @@ class OutputStat(models.Model): network=network).last() if cached_data: - print("found cached data {} for type_ref_hash {}, created {}".format(cached_data, type_ref_hash, created)) return cached_data, False def get_value_and_spent(txid, vout): mempool_api = MempoolAPI() res0 = mempool_api.get_transaction(txid) - print("res0 {}".format(res0)) vouts = res0.get("vout", []) if vouts: value = vouts[int(vout)].get("value", 0) @@ -291,17 +288,18 @@ class HistoricalPrice(models.Model): mempool_endpoint = user.profile.mempool_endpoint else: mempool_endpoint = "https://mempool.space" - url = f"{mempool_endpoints}/api/v1/historical-price?timestamp={timestamp}" + url = f"{mempool_endpoint}/api/v1/historical-price?timestamp={timestamp}" response = requests.get(url) api_response = response.json() except Exception as ex: + logger.error(ex, exc_info=True) try: from threadlocals.threadlocals import get_current_request request = get_current_request() if request: messages.error(request, "Connection Error: Could not connect to Mempool to retrieve historical price.") except Exception as ex2: - logger.error(ex, exc_info=True) + logger.error(ex2, exc_info=True) return None, None try: obj, created = cls.objects.get_or_create(timestamp=timestamp, defaults={ diff --git a/django/labellabor/views.py b/django/labellabor/views.py index 441b877..3c4ced7 100644 --- a/django/labellabor/views.py +++ b/django/labellabor/views.py @@ -833,7 +833,6 @@ class LabelUpdateView(UpdateView): return "label_derive_addresses.html" elif action == 'output-details': return "label_edit_output_details.html" - return "label_edit_update.html" def get_context_data(self, **kwargs): diff --git a/django/notifications/utils.py b/django/notifications/utils.py index 2f4c698..066b34d 100644 --- a/django/notifications/utils.py +++ b/django/notifications/utils.py @@ -1,8 +1,5 @@ from django.contrib.auth.models import User - from messages_extends.models import Message - - from messages_extends import constants """ DEBUG = 10 @@ -40,14 +37,3 @@ def notify_error_persistent(username, message): def notify_error(username, message): notify_user(username, message, level=constants.ERROR) - - -""" -{% for message in messages %} -
-{% endfor %} -""" diff --git a/django/templates/_base.html b/django/templates/_base.html index d3d02e8..206739a 100644 --- a/django/templates/_base.html +++ b/django/templates/_base.html @@ -255,7 +255,7 @@