feat: Only convert namehash to name via cache to make loading quicker

This commit is contained in:
2025-06-27 14:34:46 +10:00
parent df09a32280
commit 0e7a72a136
2 changed files with 86 additions and 24 deletions

View File

@@ -1605,7 +1605,7 @@ def api_wallet(function):
if not force_refresh and cache_key in tx_cache and (current_time - tx_cache[cache_key]['time'] < TX_CACHE_TIMEOUT): if not force_refresh and cache_key in tx_cache and (current_time - tx_cache[cache_key]['time'] < TX_CACHE_TIMEOUT):
transactions = tx_cache[cache_key]['data'] transactions = tx_cache[cache_key]['data']
txCount = len(transactions) txCount = len(transactions)
transactions_html = tx_cache[cache_key]['html'] transactions_html = render.transactions(transactions)
else: else:
# Fetch transactions from account module # Fetch transactions from account module
transactions = account_module.getTransactions(account, page) transactions = account_module.getTransactions(account, page)

108
render.py
View File

@@ -5,6 +5,7 @@ from flask import render_template
from domainLookup import punycode_to_emoji from domainLookup import punycode_to_emoji
import os import os
from handywrapper import api from handywrapper import api
import threading
HSD_API = os.getenv("HSD_API") HSD_API = os.getenv("HSD_API")
HSD_IP = os.getenv("HSD_IP") HSD_IP = os.getenv("HSD_IP")
@@ -30,8 +31,6 @@ elif HSD_NETWORK == "regtest":
HSD_WALLET_PORT = 14039 HSD_WALLET_PORT = 14039
HSD_NODE_PORT = 14037 HSD_NODE_PORT = 14037
CONVERT_NAME = False
hsd = api.hsd(HSD_API, HSD_IP, HSD_NODE_PORT) hsd = api.hsd(HSD_API, HSD_IP, HSD_NODE_PORT)
# Get Explorer URL # Get Explorer URL
@@ -40,6 +39,8 @@ if TX_EXPLORER_URL is None:
TX_EXPLORER_URL = "https://shakeshift.com/transaction/" TX_EXPLORER_URL = "https://shakeshift.com/transaction/"
NAMEHASH_CACHE = 'user_data/namehash_cache.json'
CACHE_LOCK = threading.Lock()
def domains(domains, mobile=False): def domains(domains, mobile=False):
html = '' html = ''
@@ -156,36 +157,37 @@ def transactions(txs):
humanAction = f"Sent {(amount*-1):,.2f} HNS" humanAction = f"Sent {(amount*-1):,.2f} HNS"
elif action == "FINALIZE": elif action == "FINALIZE":
if incomming and not isMulti: if incomming and not isMulti:
humanAction = "Received Domain" # humanAction = "Received Domain"
if CONVERT_NAME: # if CONVERT_NAME:
name = hsd.rpc_getNameByHash(nameHashes[0]) # name = hsd.rpc_getNameByHash(nameHashes[0])
if name["error"] is None: # if name["error"] is None:
name = name["result"] # name = name["result"]
humanAction = f"Received {renderDomain(name)}" humanAction = f"Received {renderFromNameHash(nameHashes[0])}"
elif incomming and isMulti: elif incomming and isMulti:
humanAction = "Received Multiple Domains" humanAction = "Received Multiple Domains"
elif not isMulti: elif not isMulti:
humanAction = "Finalized Domain Transfer" humanAction = f"Finalized {renderFromNameHash(nameHashes[0])}"
if CONVERT_NAME: # if CONVERT_NAME:
name = hsd.rpc_getNameByHash(nameHashes[0]) # name = hsd.rpc_getNameByHash(nameHashes[0])
if name["error"] is None: # if name["error"] is None:
name = name["result"] # name = name["result"]
humanAction = f"Finalized {renderDomain(name)}" # humanAction = f"Finalized {renderDomain(name)}"
else: else:
humanAction = "Finalized Multiple Domain Transfers" humanAction = "Finalized Multiple Domain Transfers"
elif isMulti: elif isMulti:
humanAction = actionMapPlural.get(action, "Unknown Action") humanAction = actionMapPlural.get(action, "Unknown Action")
else: else:
humanAction = actionMap.get(action, "Unknown Action") humanAction = actionMap.get(action, "Unknown Action")
if CONVERT_NAME: humanAction += renderFromNameHash(nameHashes[0])
name = hsd.rpc_getNameByHash(nameHashes[0]) # if CONVERT_NAME:
if name["error"] is None: # name = hsd.rpc_getNameByHash(nameHashes[0])
name = name["result"] # if name["error"] is None:
else: # name = name["result"]
name = None # else:
humanAction += renderDomain(name) if name else "domain" # name = None
else: # humanAction += renderDomain(name) if name else "domain"
humanAction += "domain" # else:
# humanAction += "domain"
if amount < 0: if amount < 0:
amount = f"<span style='color: red;'>{amount:,.2f}</span>" amount = f"<span style='color: red;'>{amount:,.2f}</span>"
elif amount > 0: elif amount > 0:
@@ -497,3 +499,63 @@ def renderDomain(name: str) -> str:
except Exception as e: except Exception as e:
return f"{name}/" return f"{name}/"
def renderDomainAsync(namehash: str) -> None:
"""
Get the domain name from HSD using its name hash and store it in the cache.
This function is meant to be run in the background.
"""
try:
with CACHE_LOCK:
if not os.path.exists(NAMEHASH_CACHE):
with open(NAMEHASH_CACHE, 'w') as f:
json.dump({}, f)
with open(NAMEHASH_CACHE, 'r') as f:
cache = json.load(f)
if namehash in cache:
return
# Fetch the name outside the lock (network call)
name = hsd.rpc_getNameByHash(namehash)
if name["error"] is None:
name = name["result"]
rendered = renderDomain(name)
with CACHE_LOCK:
with open(NAMEHASH_CACHE, 'r') as f:
cache = json.load(f)
cache[namehash] = rendered
with open(NAMEHASH_CACHE, 'w') as f:
json.dump(cache, f)
return rendered
else:
print(f"Error fetching name for hash {namehash}: {name['error']}", flush=True)
except Exception as e:
print(f"Exception fetching name for hash {namehash}: {e}", flush=True)
def renderFromNameHash(nameHash: str) -> str:
"""
Render a domain name from its name hash.
Try to retrieve the name from the cache. If not, create a background task to fetch it.
"""
try:
with CACHE_LOCK:
if not os.path.exists(NAMEHASH_CACHE):
with open(NAMEHASH_CACHE, 'w') as f:
json.dump({}, f)
with open(NAMEHASH_CACHE, 'r') as f:
cache = json.load(f)
if nameHash in cache:
return cache[nameHash]
thread = threading.Thread(target=renderDomainAsync, args=(nameHash,))
thread.start()
return "domain"
except Exception as e:
print(f"Exception in renderFromNameHash: {e}", flush=True)
return "domain"