feat: Do some more optimization from AI
All checks were successful
Build Docker / Build Image (push) Successful in 2m48s
All checks were successful
Build Docker / Build Image (push) Successful in 2m48s
Double check this all works
This commit is contained in:
401
account.py
401
account.py
@@ -7,6 +7,7 @@ import re
|
|||||||
import domainLookup
|
import domainLookup
|
||||||
import json
|
import json
|
||||||
import time
|
import time
|
||||||
|
import concurrent.futures
|
||||||
|
|
||||||
dotenv.load_dotenv()
|
dotenv.load_dotenv()
|
||||||
|
|
||||||
@@ -620,7 +621,17 @@ def getWalletStatus():
|
|||||||
# Add a simple cache for bid data
|
# Add a simple cache for bid data
|
||||||
_bid_cache = {}
|
_bid_cache = {}
|
||||||
_bid_cache_time = {}
|
_bid_cache_time = {}
|
||||||
_cache_duration = 60 # Cache duration in seconds
|
_cache_duration = 300 # Increased cache duration to 5 minutes for bids
|
||||||
|
|
||||||
|
# Add domain info cache
|
||||||
|
_domain_info_cache = {}
|
||||||
|
_domain_info_time = {}
|
||||||
|
_domain_info_duration = 600 # Cache domain info for 10 minutes
|
||||||
|
|
||||||
|
# Add wallet authentication cache
|
||||||
|
_wallet_auth_cache = {}
|
||||||
|
_wallet_auth_time = {}
|
||||||
|
_wallet_auth_duration = 300 # Increased to 5 minutes for wallet auth
|
||||||
|
|
||||||
def getBids(account, domain="NONE"):
|
def getBids(account, domain="NONE"):
|
||||||
cache_key = f"{account}:{domain}"
|
cache_key = f"{account}:{domain}"
|
||||||
@@ -630,79 +641,135 @@ def getBids(account, domain="NONE"):
|
|||||||
if cache_key in _bid_cache and current_time - _bid_cache_time.get(cache_key, 0) < _cache_duration:
|
if cache_key in _bid_cache and current_time - _bid_cache_time.get(cache_key, 0) < _cache_duration:
|
||||||
return _bid_cache[cache_key]
|
return _bid_cache[cache_key]
|
||||||
|
|
||||||
if domain == "NONE":
|
try:
|
||||||
response = hsw.getWalletBids(account)
|
if domain == "NONE":
|
||||||
else:
|
response = hsw.getWalletBids(account)
|
||||||
response = hsw.getWalletBidsByName(domain, account)
|
else:
|
||||||
|
response = hsw.getWalletBidsByName(domain, account)
|
||||||
# Add backup for bids with no value
|
|
||||||
bids = []
|
# Add backup for bids with no value
|
||||||
for bid in response:
|
bids = []
|
||||||
if 'value' not in bid:
|
for bid in response:
|
||||||
bid['value'] = -1000000
|
if 'value' not in bid:
|
||||||
|
bid['value'] = -1000000
|
||||||
|
|
||||||
|
# Backup for older HSD versions
|
||||||
|
if 'height' not in bid:
|
||||||
|
bid['height'] = 0
|
||||||
|
bids.append(bid)
|
||||||
|
|
||||||
|
# Cache the results
|
||||||
|
_bid_cache[cache_key] = bids
|
||||||
|
_bid_cache_time[cache_key] = current_time
|
||||||
|
|
||||||
|
return bids
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error fetching bids: {str(e)}")
|
||||||
|
return []
|
||||||
|
|
||||||
# Backup for older HSD versions
|
def _fetch_domain_info(domain):
|
||||||
if 'height' not in bid:
|
"""Helper function to fetch domain info with caching"""
|
||||||
bid['height'] = 0
|
current_time = time.time()
|
||||||
bids.append(bid)
|
|
||||||
|
|
||||||
# Cache the results
|
# Check cache first
|
||||||
_bid_cache[cache_key] = bids
|
if (domain in _domain_info_cache and
|
||||||
_bid_cache_time[cache_key] = current_time
|
current_time - _domain_info_time.get(domain, 0) < _domain_info_duration):
|
||||||
|
return _domain_info_cache[domain]
|
||||||
|
|
||||||
return bids
|
# Fetch domain info
|
||||||
|
domain_info = getDomain(domain)
|
||||||
|
|
||||||
|
# Store in cache
|
||||||
|
_domain_info_cache[domain] = domain_info
|
||||||
|
_domain_info_time[domain] = current_time
|
||||||
|
|
||||||
|
return domain_info
|
||||||
|
|
||||||
|
def _fetch_domain_batch(domains, max_workers=10):
|
||||||
|
"""Fetch multiple domains in parallel"""
|
||||||
|
results = {}
|
||||||
|
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
|
||||||
|
# Create a mapping of futures to domains
|
||||||
|
future_to_domain = {executor.submit(_fetch_domain_info, domain): domain for domain in domains}
|
||||||
|
|
||||||
|
# Process as they complete
|
||||||
|
for future in concurrent.futures.as_completed(future_to_domain):
|
||||||
|
domain = future_to_domain[future]
|
||||||
|
try:
|
||||||
|
results[domain] = future.result()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error fetching domain {domain}: {str(e)}")
|
||||||
|
results[domain] = {"error": str(e)}
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
def getPossibleOutbids(account):
|
def getPossibleOutbids(account):
|
||||||
# Get all bids
|
# Get all bids
|
||||||
bids = getBids(account)
|
bids = getBids(account)
|
||||||
if 'error' in bids:
|
if not bids or 'error' in bids:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
# Get current height
|
# Get current height
|
||||||
current_height = getBlockHeight()
|
current_height = getBlockHeight()
|
||||||
|
|
||||||
# Sort out bids older than 720 blocks
|
# Sort out bids older than 720 blocks and extract domain names
|
||||||
bids = [bid for bid in bids if (current_height - bid['height']) <= 720]
|
filtered_bids = []
|
||||||
possible_outbids = []
|
domains_to_check = set()
|
||||||
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:
|
||||||
|
if (current_height - bid['height']) <= 720:
|
||||||
|
filtered_bids.append(bid)
|
||||||
|
domains_to_check.add(bid['name'])
|
||||||
|
|
||||||
|
if not domains_to_check:
|
||||||
|
return []
|
||||||
|
|
||||||
|
# Fetch all domain info in parallel
|
||||||
|
domain_info_map = _fetch_domain_batch(domains_to_check)
|
||||||
|
|
||||||
|
# Pre-filter domains in bidding state
|
||||||
|
bidding_domains = {
|
||||||
|
domain: info for domain, info in domain_info_map.items()
|
||||||
|
if ('info' in info and 'state' in info['info'] and
|
||||||
|
info['info']['state'] == "BIDDING")
|
||||||
|
}
|
||||||
|
|
||||||
|
# Process the results
|
||||||
|
possible_outbids = []
|
||||||
|
processed_domains = set()
|
||||||
|
|
||||||
|
# Group bids by domain name for efficient processing
|
||||||
|
bids_by_domain = {}
|
||||||
|
for bid in filtered_bids:
|
||||||
domain = bid['name']
|
domain = bid['name']
|
||||||
|
if domain not in bids_by_domain:
|
||||||
# Skip if we've already processed this domain or it's not in bidding state
|
bids_by_domain[domain] = []
|
||||||
if domain in processed_domains or domain not in domain_info_map:
|
bids_by_domain[domain].append(bid)
|
||||||
|
|
||||||
|
# Analyze each domain in bidding state
|
||||||
|
for domain, info in bidding_domains.items():
|
||||||
|
if domain in processed_domains or domain not in bids_by_domain:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
processed_domains.add(domain)
|
processed_domains.add(domain)
|
||||||
|
|
||||||
# Get all bids for this domain in one call
|
# Get all bids for this domain in one call
|
||||||
domain_bids = getBids(account, domain)
|
domain_bids = getBids(account, domain)
|
||||||
|
|
||||||
# Find the highest bid we've made
|
# Find the highest bid we've made
|
||||||
current_highest_bid = bid['value']
|
our_highest_bid = max(
|
||||||
for own_bid in domain_bids:
|
(bid['value'] for bid in domain_bids if bid.get("own", False)),
|
||||||
if own_bid["own"]:
|
default=0
|
||||||
current_highest_bid = max(current_highest_bid, own_bid['value'])
|
)
|
||||||
|
|
||||||
# Check if any unrevealed bids could outbid us
|
# Quick check if any unrevealed bids could outbid us
|
||||||
for domain_bid in domain_bids:
|
if any(
|
||||||
if domain_bid["own"] or domain_bid['value'] != -1000000:
|
bid["lockup"] > our_highest_bid
|
||||||
continue # Skip our own bids or revealed bids
|
for bid in domain_bids
|
||||||
|
if not bid.get("own", False) and bid.get('value', 0) == -1000000
|
||||||
if current_highest_bid < domain_bid["lockup"]:
|
):
|
||||||
possible_outbids.append(domain)
|
possible_outbids.append(domain)
|
||||||
break
|
|
||||||
|
|
||||||
return possible_outbids
|
return possible_outbids
|
||||||
|
|
||||||
def getReveals(account, domain):
|
def getReveals(account, domain):
|
||||||
@@ -712,19 +779,36 @@ def getPendingReveals(account):
|
|||||||
bids = getBids(account)
|
bids = getBids(account)
|
||||||
# Only get domains in REVEAL state to reduce API calls
|
# Only get domains in REVEAL state to reduce API calls
|
||||||
domains = [d for d in getDomains(account, False) if d['state'] == "REVEAL"]
|
domains = [d for d in getDomains(account, False) if d['state'] == "REVEAL"]
|
||||||
|
|
||||||
|
if not domains: # Early return if no domains in REVEAL state
|
||||||
|
return []
|
||||||
|
|
||||||
pending = []
|
pending = []
|
||||||
|
|
||||||
# Process domains in REVEAL state
|
# Create a dictionary for O(1) lookups
|
||||||
domain_names = {domain['name']: domain for domain in domains}
|
domain_names = {domain['name']: domain for domain in domains}
|
||||||
|
|
||||||
|
# Group bids by name to batch process reveals
|
||||||
|
bids_by_name = {}
|
||||||
for bid in bids:
|
for bid in bids:
|
||||||
if bid['name'] in domain_names:
|
if bid['name'] in domain_names:
|
||||||
reveals = getReveals(account, bid['name'])
|
if bid['name'] not in bids_by_name:
|
||||||
|
bids_by_name[bid['name']] = []
|
||||||
|
bids_by_name[bid['name']].append(bid)
|
||||||
|
|
||||||
|
# Fetch reveals for each domain once
|
||||||
|
reveals_by_name = {}
|
||||||
|
for domain_name in bids_by_name:
|
||||||
|
reveals_by_name[domain_name] = getReveals(account, domain_name)
|
||||||
|
|
||||||
|
# Check each bid against the reveals
|
||||||
|
for domain_name, domain_bids in bids_by_name.items():
|
||||||
|
domain_reveals = reveals_by_name[domain_name]
|
||||||
|
for bid in domain_bids:
|
||||||
# Check if this bid has been revealed
|
# Check if this bid has been revealed
|
||||||
bid_revealed = any(
|
bid_revealed = any(
|
||||||
reveal['own'] == True and bid['value'] == reveal['value']
|
reveal['own'] == True and bid['value'] == reveal['value']
|
||||||
for reveal in reveals
|
for reveal in domain_reveals
|
||||||
)
|
)
|
||||||
|
|
||||||
if not bid_revealed:
|
if not bid_revealed:
|
||||||
@@ -742,20 +826,27 @@ def getPendingRedeems(account, password):
|
|||||||
|
|
||||||
pending = []
|
pending = []
|
||||||
try:
|
try:
|
||||||
|
# Collect all nameHashes first
|
||||||
|
name_hashes = []
|
||||||
for output in tx['result']['outputs']:
|
for output in tx['result']['outputs']:
|
||||||
if output['covenant']['type'] != 5:
|
if output['covenant']['type'] != 5:
|
||||||
continue
|
continue
|
||||||
if output['covenant']['action'] != "REDEEM":
|
if output['covenant']['action'] != "REDEEM":
|
||||||
continue
|
continue
|
||||||
nameHash = output['covenant']['items'][0]
|
name_hashes.append(output['covenant']['items'][0])
|
||||||
# Try to get the name from hash
|
|
||||||
name = hsd.rpc_getNameByHash(nameHash)
|
# Batch processing name hashes
|
||||||
|
name_lookup = {}
|
||||||
|
for name_hash in name_hashes:
|
||||||
|
name = hsd.rpc_getNameByHash(name_hash)
|
||||||
if name['error']:
|
if name['error']:
|
||||||
pending.append(nameHash)
|
pending.append(name_hash)
|
||||||
else:
|
else:
|
||||||
pending.append(name['result'])
|
pending.append(name['result'])
|
||||||
except:
|
name_lookup[name_hash] = name['result']
|
||||||
print("Failed to parse redeems")
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Failed to parse redeems: {str(e)}")
|
||||||
|
|
||||||
return pending
|
return pending
|
||||||
|
|
||||||
@@ -763,13 +854,22 @@ def getPendingRedeems(account, password):
|
|||||||
def getPendingRegisters(account):
|
def getPendingRegisters(account):
|
||||||
bids = getBids(account)
|
bids = getBids(account)
|
||||||
domains = getDomains(account, False)
|
domains = getDomains(account, False)
|
||||||
|
|
||||||
|
# Create dictionaries for O(1) lookups
|
||||||
|
bids_by_name = {}
|
||||||
|
for bid in bids:
|
||||||
|
if bid['name'] not in bids_by_name:
|
||||||
|
bids_by_name[bid['name']] = []
|
||||||
|
bids_by_name[bid['name']].append(bid)
|
||||||
|
|
||||||
pending = []
|
pending = []
|
||||||
for domain in domains:
|
for domain in domains:
|
||||||
if domain['state'] == "CLOSED" and domain['registered'] == False:
|
if domain['state'] == "CLOSED" and domain['registered'] == False:
|
||||||
for bid in bids:
|
if domain['name'] in bids_by_name:
|
||||||
if bid['name'] == domain['name']:
|
for bid in bids_by_name[domain['name']]:
|
||||||
if bid['value'] == domain['highest']:
|
if bid['value'] == domain['highest']:
|
||||||
pending.append(bid)
|
pending.append(bid)
|
||||||
|
|
||||||
return pending
|
return pending
|
||||||
|
|
||||||
|
|
||||||
@@ -780,20 +880,26 @@ def getPendingFinalizes(account, password):
|
|||||||
|
|
||||||
pending = []
|
pending = []
|
||||||
try:
|
try:
|
||||||
|
# Collect all nameHashes first
|
||||||
|
name_hashes = []
|
||||||
for output in tx['outputs']:
|
for output in tx['outputs']:
|
||||||
if output['covenant']['type'] != 10:
|
if output['covenant']['type'] != 10:
|
||||||
continue
|
continue
|
||||||
if output['covenant']['action'] != "FINALIZE":
|
if output['covenant']['action'] != "FINALIZE":
|
||||||
continue
|
continue
|
||||||
nameHash = output['covenant']['items'][0]
|
name_hashes.append(output['covenant']['items'][0])
|
||||||
# Try to get the name from hash
|
|
||||||
name = hsd.rpc_getNameByHash(nameHash)
|
# Batch lookup for name hashes
|
||||||
|
for name_hash in name_hashes:
|
||||||
|
name = hsd.rpc_getNameByHash(name_hash)
|
||||||
if name['error']:
|
if name['error']:
|
||||||
pending.append(nameHash)
|
pending.append(name_hash)
|
||||||
else:
|
else:
|
||||||
pending.append(name['result'])
|
pending.append(name['result'])
|
||||||
except:
|
|
||||||
print("Failed to parse finalizes")
|
except Exception as e:
|
||||||
|
print(f"Failed to parse finalizes: {str(e)}")
|
||||||
|
|
||||||
return pending
|
return pending
|
||||||
|
|
||||||
|
|
||||||
@@ -1136,102 +1242,89 @@ def revoke(account, domain):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def sendBatch(account, batch):
|
def _prepare_wallet_for_batch(account_name, password):
|
||||||
account_name = check_account(account)
|
"""Helper function to prepare wallet for batch operations with caching"""
|
||||||
password = ":".join(account.split(":")[1:])
|
cache_key = f"{account_name}:{password}"
|
||||||
|
current_time = time.time()
|
||||||
if account_name == False:
|
|
||||||
return {
|
# Return cached authentication if available and fresh
|
||||||
"error": {
|
if (cache_key in _wallet_auth_cache and
|
||||||
"message": "Invalid account"
|
current_time - _wallet_auth_time.get(cache_key, 0) < _wallet_auth_duration):
|
||||||
}
|
return _wallet_auth_cache[cache_key]
|
||||||
}
|
|
||||||
|
# Select and unlock wallet
|
||||||
|
result = {'success': False, 'error': None}
|
||||||
|
|
||||||
|
# Try to select the wallet
|
||||||
|
select_response = hsw.rpc_selectWallet(account_name)
|
||||||
|
if select_response['error'] is not None:
|
||||||
|
result['error'] = {"message": select_response['error']['message']}
|
||||||
|
return result
|
||||||
|
|
||||||
|
# Try to unlock the wallet
|
||||||
|
unlock_response = hsw.rpc_walletPassphrase(password, 30) # Increased timeout to reduce future unlocks
|
||||||
|
if (unlock_response['error'] is not None and
|
||||||
|
unlock_response['error']['message'] != "Wallet is not encrypted."):
|
||||||
|
result['error'] = {"message": unlock_response['error']['message']}
|
||||||
|
return result
|
||||||
|
|
||||||
|
# Authentication successful
|
||||||
|
result['success'] = True
|
||||||
|
|
||||||
|
# Cache the authentication result
|
||||||
|
_wallet_auth_cache[cache_key] = result
|
||||||
|
_wallet_auth_time[cache_key] = current_time
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def _execute_batch_operation(account_name, batch, operation_type="sendbatch"):
|
||||||
|
"""Execute a batch operation with the specified wallet"""
|
||||||
|
# Make the batch request
|
||||||
try:
|
try:
|
||||||
response = hsw.rpc_selectWallet(account_name)
|
response = requests.post(
|
||||||
if response['error'] is not None:
|
f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}",
|
||||||
return {
|
json={"method": operation_type, "params": [batch]},
|
||||||
"error": {
|
timeout=30 # Add timeout to prevent hanging
|
||||||
"message": response['error']['message']
|
).json()
|
||||||
}
|
|
||||||
}
|
|
||||||
response = hsw.rpc_walletPassphrase(password, 10)
|
|
||||||
if response['error'] is not None:
|
|
||||||
if response['error']['message'] != "Wallet is not encrypted.":
|
|
||||||
return {
|
|
||||||
"error": {
|
|
||||||
"message": response['error']['message']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
response = requests.post(f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}", json={
|
|
||||||
"method": "sendbatch",
|
|
||||||
"params": [batch]
|
|
||||||
}).json()
|
|
||||||
if response['error'] is not None:
|
if response['error'] is not None:
|
||||||
return response
|
return response
|
||||||
if 'result' not in response:
|
if 'result' not in response:
|
||||||
return {
|
return {"error": {"message": "No result"}}
|
||||||
"error": {
|
|
||||||
"message": "No result"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return response['result']
|
return response['result']
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return {
|
return {"error": {"message": str(e)}}
|
||||||
"error": {
|
|
||||||
"message": str(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
def sendBatch(account, batch):
|
||||||
|
account_name = check_account(account)
|
||||||
|
if account_name == False:
|
||||||
|
return {"error": {"message": "Invalid account"}}
|
||||||
|
|
||||||
|
password = ":".join(account.split(":")[1:])
|
||||||
|
|
||||||
|
# Prepare the wallet (this uses caching)
|
||||||
|
auth_result = _prepare_wallet_for_batch(account_name, password)
|
||||||
|
if not auth_result['success']:
|
||||||
|
return auth_result['error']
|
||||||
|
|
||||||
|
# Execute the batch operation
|
||||||
|
return _execute_batch_operation(account_name, batch, "sendbatch")
|
||||||
|
|
||||||
def createBatch(account, batch):
|
def createBatch(account, batch):
|
||||||
account_name = check_account(account)
|
account_name = check_account(account)
|
||||||
password = ":".join(account.split(":")[1:])
|
|
||||||
|
|
||||||
if account_name == False:
|
if account_name == False:
|
||||||
return {
|
return {"error": {"message": "Invalid account"}}
|
||||||
"error": {
|
|
||||||
"message": "Invalid account"
|
password = ":".join(account.split(":")[1:])
|
||||||
}
|
|
||||||
}
|
# Prepare the wallet (this uses caching)
|
||||||
|
auth_result = _prepare_wallet_for_batch(account_name, password)
|
||||||
try:
|
if not auth_result['success']:
|
||||||
response = hsw.rpc_selectWallet(account_name)
|
return auth_result['error']
|
||||||
if response['error'] is not None:
|
|
||||||
return {
|
# Execute the batch operation
|
||||||
"error": {
|
return _execute_batch_operation(account_name, batch, "createbatch")
|
||||||
"message": response['error']['message']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
response = hsw.rpc_walletPassphrase(password, 10)
|
|
||||||
if response['error'] is not None:
|
|
||||||
if response['error']['message'] != "Wallet is not encrypted.":
|
|
||||||
return {
|
|
||||||
"error": {
|
|
||||||
"message": response['error']['message']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
response = requests.post(f"http://x:{HSD_API}@{HSD_IP}:{HSD_WALLET_PORT}", json={
|
|
||||||
"method": "createbatch",
|
|
||||||
"params": [batch]
|
|
||||||
}).json()
|
|
||||||
if response['error'] is not None:
|
|
||||||
return response
|
|
||||||
if 'result' not in response:
|
|
||||||
return {
|
|
||||||
"error": {
|
|
||||||
"message": "No result"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return response['result']
|
|
||||||
except Exception as e:
|
|
||||||
return {
|
|
||||||
"error": {
|
|
||||||
"message": str(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# region settingsAPIs
|
# region settingsAPIs
|
||||||
@@ -1400,4 +1493,4 @@ def generateReport(account, format="{name},{expiry},{value},{maxBid}"):
|
|||||||
|
|
||||||
|
|
||||||
def convertHNS(value: int):
|
def convertHNS(value: int):
|
||||||
return value/1000000
|
return value/1000000
|
||||||
45
main.py
45
main.py
@@ -32,6 +32,14 @@ revokeCheck = random.randint(100000,999999)
|
|||||||
|
|
||||||
THEME = os.getenv("THEME")
|
THEME = os.getenv("THEME")
|
||||||
|
|
||||||
|
# Add a cache for transactions with a timeout
|
||||||
|
tx_cache = {}
|
||||||
|
TX_CACHE_TIMEOUT = 60*5 # Cache timeout in seconds
|
||||||
|
|
||||||
|
# Add a cache for outbids with a timeout
|
||||||
|
outbids_cache = {}
|
||||||
|
OUTBIDS_CACHE_TIMEOUT = 60*2 # Cache timeout in seconds
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def index():
|
def index():
|
||||||
# Check if the user is logged in
|
# Check if the user is logged in
|
||||||
@@ -70,10 +78,6 @@ def reverseDirection(direction: str):
|
|||||||
|
|
||||||
|
|
||||||
#region Transactions
|
#region Transactions
|
||||||
# Add a cache for transactions with a timeout
|
|
||||||
tx_cache = {}
|
|
||||||
TX_CACHE_TIMEOUT = 60*5 # Cache timeout in seconds
|
|
||||||
|
|
||||||
@app.route('/tx')
|
@app.route('/tx')
|
||||||
def transactions():
|
def transactions():
|
||||||
# Check if the user is logged in
|
# Check if the user is logged in
|
||||||
@@ -294,8 +298,12 @@ def auctions():
|
|||||||
sort_time = direction
|
sort_time = direction
|
||||||
sort_time_next = reverseDirection(direction)
|
sort_time_next = reverseDirection(direction)
|
||||||
|
|
||||||
|
# Check if bids list is empty to avoid IndexError
|
||||||
|
if not bids:
|
||||||
|
domains = sorted(domains, key=lambda k: k['height'],reverse=reverse)
|
||||||
|
sortbyDomain = True
|
||||||
# If older HSD version sort by domain height
|
# If older HSD version sort by domain height
|
||||||
if bids[0]['height'] == 0:
|
elif bids[0]['height'] == 0:
|
||||||
domains = sorted(domains, key=lambda k: k['height'],reverse=reverse)
|
domains = sorted(domains, key=lambda k: k['height'],reverse=reverse)
|
||||||
sortbyDomain = True
|
sortbyDomain = True
|
||||||
else:
|
else:
|
||||||
@@ -309,8 +317,20 @@ def auctions():
|
|||||||
# Check if outbids set to true
|
# Check if outbids set to true
|
||||||
outbids = request.args.get("outbids")
|
outbids = request.args.get("outbids")
|
||||||
if outbids is not None and outbids.lower() == "true":
|
if outbids is not None and outbids.lower() == "true":
|
||||||
# Get outbid domains
|
# Check cache before making expensive call
|
||||||
outbids = account_module.getPossibleOutbids(account)
|
cache_key = f"outbids_{account}"
|
||||||
|
current_time = time.time()
|
||||||
|
|
||||||
|
if cache_key in outbids_cache and (current_time - outbids_cache[cache_key]['time'] < OUTBIDS_CACHE_TIMEOUT):
|
||||||
|
outbids = outbids_cache[cache_key]['data']
|
||||||
|
else:
|
||||||
|
# Get outbid domains
|
||||||
|
outbids = account_module.getPossibleOutbids(account)
|
||||||
|
# Store in cache
|
||||||
|
outbids_cache[cache_key] = {
|
||||||
|
'data': outbids,
|
||||||
|
'time': current_time
|
||||||
|
}
|
||||||
else:
|
else:
|
||||||
outbids = []
|
outbids = []
|
||||||
|
|
||||||
@@ -342,11 +362,12 @@ def revealAllBids():
|
|||||||
return redirect("/logout")
|
return redirect("/logout")
|
||||||
|
|
||||||
response = account_module.revealAll(request.cookies.get("account"))
|
response = account_module.revealAll(request.cookies.get("account"))
|
||||||
if 'error' in response:
|
# Simplified error handling
|
||||||
if response['error'] != None:
|
if 'error' in response and response['error']:
|
||||||
if response['error']['message'] == "Nothing to do.":
|
error_msg = response['error'].get('message', str(response['error']))
|
||||||
return redirect("/auctions?message=No reveals pending")
|
if error_msg == "Nothing to do.":
|
||||||
return redirect("/auctions?message=" + response['error']['message'])
|
return redirect("/auctions?message=No reveals pending")
|
||||||
|
return redirect("/auctions?message=" + error_msg)
|
||||||
|
|
||||||
return redirect("/success?tx=" + response['result']['hash'])
|
return redirect("/success?tx=" + response['result']['hash'])
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user