fix hashrates dash
This commit is contained in:
@@ -16,6 +16,11 @@ class PoolWebInterface:
|
||||
self.pool_db = pool_db
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.chart_time_window = 3600 # 1 hour default, adjustable
|
||||
|
||||
def set_chart_time_window(self, seconds):
|
||||
"""Set the chart time window"""
|
||||
self.chart_time_window = seconds
|
||||
|
||||
def format_hashrate(self, hashrate):
|
||||
"""Format hashrate in human readable format"""
|
||||
@@ -58,22 +63,55 @@ class PoolWebInterface:
|
||||
''')
|
||||
total_shares_24h = cursor.fetchone()[0]
|
||||
|
||||
# Better hashrate calculation (shares per second * difficulty)
|
||||
# Pool hashrate: sum of miners.last_hashrate (instantaneous)
|
||||
cursor.execute('SELECT COALESCE(SUM(last_hashrate), 0) FROM miners')
|
||||
hashrate = cursor.fetchone()[0] or 0.0
|
||||
|
||||
# Debug stats
|
||||
cursor.execute('''
|
||||
SELECT SUM(difficulty), COUNT(*) FROM shares
|
||||
WHERE submitted > datetime('now', '-5 minutes')
|
||||
''')
|
||||
result = cursor.fetchone()
|
||||
recent_difficulty = result[0] if result[0] else 0
|
||||
recent_share_count = result[1] if result[1] else 0
|
||||
rd = cursor.fetchone()
|
||||
recent_difficulty = rd[0] if rd and rd[0] else 0
|
||||
recent_share_count = rd[1] if rd and rd[1] else 0
|
||||
|
||||
# Convert to hashrate (difficulty per second)
|
||||
hashrate = recent_difficulty / 300.0 # 5 minutes = 300 seconds
|
||||
# Get historical hashrate data for chart
|
||||
cursor.execute('''
|
||||
SELECT
|
||||
strftime('%H:%M', submitted) as time,
|
||||
COUNT(*) as shares,
|
||||
SUM(difficulty) as total_difficulty
|
||||
FROM shares
|
||||
WHERE submitted > datetime('now', '-{} seconds')
|
||||
GROUP BY strftime('%Y-%m-%d %H:%M', submitted)
|
||||
ORDER BY submitted DESC
|
||||
LIMIT 60
|
||||
'''.format(self.chart_time_window))
|
||||
historical_data = cursor.fetchall()
|
||||
|
||||
# Alternative calculation if difficulty is 0 but we have shares
|
||||
if hashrate == 0 and recent_share_count > 0:
|
||||
# Estimate based on share count (assume difficulty 0.001)
|
||||
hashrate = (recent_share_count * 0.001) / 300.0
|
||||
# Calculate individual miner hashrates
|
||||
cursor.execute('''
|
||||
SELECT
|
||||
m.user, m.worker,
|
||||
COUNT(s.id) as shares,
|
||||
SUM(s.difficulty) as total_difficulty,
|
||||
m.last_share
|
||||
FROM miners m
|
||||
LEFT JOIN shares s ON m.id = s.miner_id
|
||||
AND s.submitted > datetime('now', '-5 minutes')
|
||||
GROUP BY m.id, m.user, m.worker
|
||||
ORDER BY shares DESC
|
||||
''')
|
||||
miner_stats = cursor.fetchall()
|
||||
|
||||
# Calculate individual hashrates (use miners.last_hashrate)
|
||||
miner_hashrates = []
|
||||
for user, worker, shares, difficulty, last_share in miner_stats:
|
||||
cursor.execute('SELECT last_hashrate FROM miners WHERE user = ? AND worker = ? LIMIT 1', (user, worker))
|
||||
row = cursor.fetchone()
|
||||
miner_hashrate = row[0] if row and row[0] else 0.0
|
||||
miner_hashrates.append((user, worker, shares, miner_hashrate, last_share))
|
||||
|
||||
# Total blocks found
|
||||
cursor.execute('SELECT COUNT(*) FROM blocks')
|
||||
@@ -121,6 +159,8 @@ class PoolWebInterface:
|
||||
'recent_blocks': recent_blocks,
|
||||
'top_miners': top_miners,
|
||||
'all_miners': all_miners,
|
||||
'miner_hashrates': miner_hashrates,
|
||||
'historical_data': historical_data,
|
||||
'debug': {
|
||||
'recent_difficulty': recent_difficulty,
|
||||
'recent_share_count': recent_share_count,
|
||||
@@ -203,6 +243,22 @@ class PoolWebInterface:
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>📈 Hashrate Chart</h2>
|
||||
<div class="chart-controls">
|
||||
<label>Time Window: </label>
|
||||
<select onchange="changeTimeWindow(this.value)">
|
||||
<option value="3600">1 Hour</option>
|
||||
<option value="7200">2 Hours</option>
|
||||
<option value="14400">4 Hours</option>
|
||||
<option value="86400">24 Hours</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="chart-container">
|
||||
<canvas id="hashrateChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>👥 Connected Miners</h2>
|
||||
<table>
|
||||
@@ -243,17 +299,19 @@ class PoolWebInterface:
|
||||
<th>User</th>
|
||||
<th>Worker</th>
|
||||
<th>Shares</th>
|
||||
<th>Hashrate</th>
|
||||
<th>Last Share</th>
|
||||
</tr>
|
||||
"""
|
||||
|
||||
for miner in stats.get('top_miners', []):
|
||||
user, worker, shares, last_share, created = miner
|
||||
for miner in stats.get('miner_hashrates', []):
|
||||
user, worker, shares, hashrate, last_share = miner
|
||||
html += f"""
|
||||
<tr>
|
||||
<td>{user}</td>
|
||||
<td>{worker}</td>
|
||||
<td>{shares:,}</td>
|
||||
<td>{self.format_hashrate(hashrate)}</td>
|
||||
<td>{last_share or 'Never'}</td>
|
||||
</tr>
|
||||
"""
|
||||
@@ -303,6 +361,58 @@ class PoolWebInterface:
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script>
|
||||
// Historical data for chart
|
||||
const historicalData = {json.dumps([{
|
||||
'time': row[0],
|
||||
'shares': row[1],
|
||||
'difficulty': row[2] or 0
|
||||
} for row in stats.get('historical_data', [])])};
|
||||
|
||||
// Create hashrate chart
|
||||
const ctx = document.getElementById('hashrateChart').getContext('2d');
|
||||
const chart = new Chart(ctx, {{
|
||||
type: 'line',
|
||||
data: {{
|
||||
labels: historicalData.map(d => d.time).reverse(),
|
||||
datasets: [{{
|
||||
label: 'Hashrate (H/s)',
|
||||
data: historicalData.map(d => (d.shares / 60.0) * 0.001).reverse(),
|
||||
borderColor: '#3498db',
|
||||
backgroundColor: 'rgba(52, 152, 219, 0.1)',
|
||||
tension: 0.4
|
||||
}}]
|
||||
}},
|
||||
options: {{
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
scales: {{
|
||||
y: {{
|
||||
beginAtZero: true,
|
||||
title: {{
|
||||
display: true,
|
||||
text: 'Hashrate (H/s)'
|
||||
}}
|
||||
}},
|
||||
x: {{
|
||||
title: {{
|
||||
display: true,
|
||||
text: 'Time'
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
}});
|
||||
|
||||
function changeTimeWindow(seconds) {{
|
||||
// Reload page with new time window
|
||||
const url = new URL(window.location);
|
||||
url.searchParams.set('window', seconds);
|
||||
window.location.href = url.toString();
|
||||
}}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
// Auto-refresh every 30 seconds
|
||||
setTimeout(() => location.reload(), 30000);
|
||||
|
||||
Reference in New Issue
Block a user