feat: Only convert namehash to name via cache to make loading quicker
All checks were successful
Build Docker / Build Image (push) Successful in 1m3s
All checks were successful
Build Docker / Build Image (push) Successful in 1m3s
This commit is contained in:
2
main.py
2
main.py
@@ -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
108
render.py
@@ -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"
|
||||||
Reference in New Issue
Block a user