feat: Optimize some of the auction routes

This commit is contained in:
2025-07-11 13:45:47 +10:00
parent b2db24c08e
commit 61d9f209b7
4 changed files with 188 additions and 133 deletions

Binary file not shown.

View File

@@ -611,11 +611,24 @@ def getWalletStatus():
return "Error wallet ahead of node" return "Error wallet ahead of node"
# Add a simple cache for bid data
_bid_cache = {}
_bid_cache_time = {}
_cache_duration = 60 # Cache duration in seconds
def getBids(account, domain="NONE"): def getBids(account, domain="NONE"):
cache_key = f"{account}:{domain}"
current_time = time.time()
# Return cached data if available and fresh
if cache_key in _bid_cache and current_time - _bid_cache_time.get(cache_key, 0) < _cache_duration:
return _bid_cache[cache_key]
if domain == "NONE": if domain == "NONE":
response = hsw.getWalletBids(account) response = hsw.getWalletBids(account)
else: else:
response = hsw.getWalletBidsByName(domain, account) response = hsw.getWalletBidsByName(domain, account)
# Add backup for bids with no value # Add backup for bids with no value
bids = [] bids = []
for bid in response: for bid in response:
@@ -626,6 +639,11 @@ def getBids(account, domain="NONE"):
if 'height' not in bid: if 'height' not in bid:
bid['height'] = 0 bid['height'] = 0
bids.append(bid) bids.append(bid)
# Cache the results
_bid_cache[cache_key] = bids
_bid_cache_time[cache_key] = current_time
return bids return bids
def getPossibleOutbids(account): def getPossibleOutbids(account):
@@ -640,28 +658,41 @@ def getPossibleOutbids(account):
# Sort out bids older than 720 blocks # Sort out bids older than 720 blocks
bids = [bid for bid in bids if (current_height - bid['height']) <= 720] bids = [bid for bid in bids if (current_height - bid['height']) <= 720]
possible_outbids = [] possible_outbids = []
processed_domains = set() # Track domains we've already processed
# Pre-fetch domain info for all domains in a single batch
domains_to_check = {bid['name'] for bid in bids}
domain_info_map = {}
for domain in domains_to_check:
domain_info = getDomain(domain)
if ('info' in domain_info and 'state' in domain_info['info'] and
domain_info['info']['state'] == "BIDDING"):
domain_info_map[domain] = domain_info
for bid in bids: for bid in bids:
domain = bid['name'] domain = bid['name']
# Check to make sure that bidding is still happening # Skip if we've already processed this domain or it's not in bidding state
domain_info = getDomain(domain) if domain in processed_domains or domain not in domain_info_map:
if 'info' not in domain_info or 'state' not in domain_info['info']:
print(f"Domain {domain} not found or no info available",flush=True)
continue continue
if domain_info['info']['state'] != "BIDDING":
continue processed_domains.add(domain)
# Get all bids for this domain in one call
current_highest_bid = bid['value']
domain_bids = getBids(account, domain) domain_bids = getBids(account, domain)
# Find the highest bid we've made
current_highest_bid = bid['value']
for own_bid in domain_bids:
if own_bid["own"]:
current_highest_bid = max(current_highest_bid, own_bid['value'])
# Check if any unrevealed bids could outbid us
for domain_bid in domain_bids: for domain_bid in domain_bids:
if domain_bid["own"]: if domain_bid["own"] or domain_bid['value'] != -1000000:
current_highest_bid = max(current_highest_bid, domain_bid['value']) continue # Skip our own bids or revealed bids
continue
if domain_bid['value'] != -1000000:
print("Revealed bid")
continue
if current_highest_bid < domain_bid["lockup"]: if current_highest_bid < domain_bid["lockup"]:
possible_outbids.append(domain) possible_outbids.append(domain)
break break
@@ -671,24 +702,28 @@ def getPossibleOutbids(account):
def getReveals(account, domain): def getReveals(account, domain):
return hsw.getWalletRevealsByName(domain, account) return hsw.getWalletRevealsByName(domain, account)
def getPendingReveals(account): def getPendingReveals(account):
bids = getBids(account) bids = getBids(account)
domains = getDomains(account, False) # Only get domains in REVEAL state to reduce API calls
domains = [d for d in getDomains(account, False) if d['state'] == "REVEAL"]
pending = [] pending = []
for domain in domains:
if domain['state'] == "REVEAL": # Process domains in REVEAL state
reveals = getReveals(account, domain['name']) domain_names = {domain['name']: domain for domain in domains}
for bid in bids:
if bid['name'] == domain['name']: for bid in bids:
state_found = False if bid['name'] in domain_names:
for reveal in reveals: reveals = getReveals(account, bid['name'])
if reveal['own'] == True:
if bid['value'] == reveal['value']: # Check if this bid has been revealed
state_found = True bid_revealed = any(
reveal['own'] == True and bid['value'] == reveal['value']
if not state_found: for reveal in reveals
pending.append(bid) )
if not bid_revealed:
pending.append(bid)
return pending return pending

126
main.py
View File

@@ -273,84 +273,74 @@ def auctions():
if not account: if not account:
return redirect("/logout") return redirect("/logout")
# Get sort parameters with defaults
bids = account_module.getBids(account) sort = request.args.get("sort", "time").lower()
domains = account_module.getDomains(account,False)
# Sort
sort = request.args.get("sort")
if sort == None:
sort = "time"
sort = sort.lower()
sort_price = ""
sort_price_next = ""
sort_state = ""
sort_state_next = ""
sort_domain = ""
sort_domain_next = ""
sort_time = ""
sort_time_next = ""
reverse = False
direction = request.args.get("direction") direction = request.args.get("direction")
if direction == None: if direction is None:
if sort == "time": direction = "" if sort == "time" else ""
direction = ""
else: reverse = (direction == "")
direction = ""
# Initialize sort indicators with a more efficient approach
if direction == "": sort_indicators = {
reverse = True "price": ["", ""],
"state": ["", ""],
"domain": ["", ""],
"time": ["", ""]
}
# Set the current sort column's indicators
sort_indicators[sort][0] = direction
sort_indicators[sort][1] = reverseDirection(direction)
# Efficiently retrieve data
bids = account_module.getBids(account)
domains = account_module.getDomains(account, False)
# Determine if sorting by domains and apply appropriate sort
sortbyDomain = False sortbyDomain = False
if sort == "price": if sort == "price":
# Sort by price bids = sorted(bids, key=lambda k: k['value'], reverse=reverse)
bids = sorted(bids, key=lambda k: k['value'],reverse=reverse)
sort_price = direction
sort_price_next = reverseDirection(direction)
elif sort == "state": elif sort == "state":
sort_state = direction domains = sorted(domains, key=lambda k: k['state'], reverse=reverse)
sort_state_next = reverseDirection(direction)
domains = sorted(domains, key=lambda k: k['state'],reverse=reverse)
sortbyDomain = True sortbyDomain = True
elif sort == "time": elif sort == "time":
sort_time = direction # Handle older HSD versions that don't have height in bids
sort_time_next = reverseDirection(direction) if bids and bids[0]['height'] == 0:
domains = sorted(domains, key=lambda k: k['height'], reverse=reverse)
# If older HSD version sort by domain height
if bids[0]['height'] == 0:
domains = sorted(domains, key=lambda k: k['height'],reverse=reverse)
sortbyDomain = True sortbyDomain = True
else: else:
bids = sorted(bids, key=lambda k: k['height'],reverse=reverse) bids = sorted(bids, key=lambda k: k['height'], reverse=reverse)
else: else: # Default to domain name sorting
# Sort by domain bids = sorted(bids, key=lambda k: k['name'], reverse=reverse)
bids = sorted(bids, key=lambda k: k['name'],reverse=reverse)
sort_domain = direction
sort_domain_next = reverseDirection(direction)
# Check if outbids set to true # Get outbids only if explicitly requested
outbids = request.args.get("outbids") outbids = []
if outbids is not None and outbids.lower() == "true": if request.args.get("outbids", "").lower() == "true":
# Get outbid domains
outbids = account_module.getPossibleOutbids(account) outbids = account_module.getPossibleOutbids(account)
# Generate HTML just once
bidsHtml = render.bidDomains(bids,domains,sortbyDomain,outbids) bidsHtml = render.bidDomains(bids, domains, sortbyDomain, outbids)
plugins = ""
message = '' # Get message if present
if 'message' in request.args: message = request.args.get("message", "")
message = request.args.get("message")
return render_template("auctions.html", account=account, domains=bidsHtml, return render_template("auctions.html", account=account,
domainsMobile=bidsHtml, plugins=plugins, domains=bidsHtml,
domain_count=bidsHtml,sort_price=sort_price, domainsMobile=bidsHtml,
sort_state=sort_state,sort_domain=sort_domain, plugins="",
sort_price_next=sort_price_next, domain_count=bidsHtml,
sort_state_next=sort_state_next,sort_domain_next=sort_domain_next, sort_price=sort_indicators["price"][0],
bids=len(bids),message=message, sort_state=sort_indicators["state"][0],
sort_time=sort_time,sort_time_next=sort_time_next) sort_domain=sort_indicators["domain"][0],
sort_time=sort_indicators["time"][0],
sort_price_next=sort_indicators["price"][1],
sort_state_next=sort_indicators["state"][1],
sort_domain_next=sort_indicators["domain"][1],
sort_time_next=sort_indicators["time"][1],
bids=len(bids),
message=message)
#endregion
#region All Auctions #region All Auctions
@app.route('/reveal') @app.route('/reveal')

View File

@@ -336,47 +336,77 @@ def bids(bids,reveals):
return html return html
def bidDomains(bids,domains, sortbyDomains=False, outbids=[]): def bidDomains(bids, domains, sortbyDomains=False, outbids=[]):
html = '' html = ''
# Create lookup dictionaries for O(1) lookups instead of O(n) searches
domain_lookup = {d['name']: d for d in domains}
bid_lookup = {}
for bid in bids:
if bid['name'] not in bid_lookup or bid['value'] > bid_lookup[bid['name']]['value']:
bid_lookup[bid['name']] = bid
if not sortbyDomains: if not sortbyDomains:
# Process by bids first
for bid in bids: for bid in bids:
for domain in domains: domain_name = bid['name']
if bid['name'] == domain['name']: if domain_name not in domain_lookup:
lockup = bid['lockup'] continue
lockup = lockup / 1000000
bidValue = bid['value'] / 1000000 domain = domain_lookup[domain_name]
blind = lockup - bidValue
lockup = bid['lockup']
lockup = lockup / 1000000
bidValue = bid['value'] / 1000000
blind = lockup - bidValue
if blind > 0: if blind > 0:
bidDisplay = f'<b>{bidValue:,.2f}</b> (+{blind:,.2f}) HNS' bidDisplay = f'<b>{bidValue:,.2f}</b> (+{blind:,.2f}) HNS'
else: else:
bidDisplay = f'<b>{bidValue:,.2f}</b> HNS' bidDisplay = f'<b>{bidValue:,.2f}</b> HNS'
html += "<tr>" html += "<tr>"
if domain['name'] in outbids:
html += f"<td style='background-color: red;'><a class='text-decoration-none' style='color: var(--bs-table-color-state, var(--bs-table-color-type, var(--bs-table-color)));' href='/auction/{domain['name']}'>{renderDomain(domain['name'])}</a></td>" # Efficiently check if domain is in outbids list
else: is_outbid = domain_name in outbids
html += f"<td><a class='text-decoration-none' style='color: var(--bs-table-color-state, var(--bs-table-color-type, var(--bs-table-color)));' href='/auction/{domain['name']}'>{renderDomain(domain['name'])}</a></td>" td_style = " style='background-color: red;'" if is_outbid else ""
html += f"<td>{domain['state']}</td>"
html += f"<td style='white-space: nowrap;'>{bidDisplay}</td>" html += f"<td{td_style}><a class='text-decoration-none' style='color: var(--bs-table-color-state, var(--bs-table-color-type, var(--bs-table-color)));' href='/auction/{domain_name}'>{renderDomain(domain_name)}</a></td>"
html += f"<td class='hide-mobile'>{bid['height']:,}</td>" html += f"<td>{domain['state']}</td>"
html += "</tr>" html += f"<td style='white-space: nowrap;'>{bidDisplay}</td>"
html += f"<td class='hide-mobile'>{bid['height']:,}</td>"
html += "</tr>"
else: else:
# Process by domains first (for state sorting)
for domain in domains: for domain in domains:
for bid in bids: domain_name = domain['name']
if bid['name'] == domain['name']: if domain_name not in bid_lookup:
lockup = bid['lockup'] continue
lockup = lockup / 1000000
bidValue = bid['value'] / 1000000 bid = bid_lookup[domain_name]
blind = lockup - bidValue
lockup = bid['lockup']
lockup = lockup / 1000000
bidValue = bid['value'] / 1000000
blind = lockup - bidValue
bidDisplay = f'<b>{bidValue:,.2f} HNS</b> + {blind:,.2f} HNS blind' if blind > 0:
html += "<tr>" bidDisplay = f'<b>{bidValue:,.2f}</b> (+{blind:,.2f}) HNS'
html += f"<td><a class='text-decoration-none' style='color: var(--bs-table-color-state, var(--bs-table-color-type, var(--bs-table-color)));' href='/auction/{domain['name']}'>{renderDomain(domain['name'])}</a></td>" else:
html += f"<td>{domain['state']}</td>" bidDisplay = f'<b>{bidValue:,.2f}</b> HNS'
html += f"<td>{bidDisplay}</td>"
html += f"<td class='hide-mobile'>{bid['height']:,}</td>" html += "<tr>"
html += "</tr>"
# Efficiently check if domain is in outbids list
is_outbid = domain_name in outbids
td_style = " style='background-color: red;'" if is_outbid else ""
html += f"<td{td_style}><a class='text-decoration-none' style='color: var(--bs-table-color-state, var(--bs-table-color-type, var(--bs-table-color)));' href='/auction/{domain_name}'>{renderDomain(domain_name)}</a></td>"
html += f"<td>{domain['state']}</td>"
html += f"<td style='white-space: nowrap;'>{bidDisplay}</td>"
html += f"<td class='hide-mobile'>{bid['height']:,}</td>"
html += "</tr>"
return html return html