dashboard

This commit is contained in:
Dobromir Popov
2025-09-02 13:21:43 +03:00
parent 1e9a56356e
commit 89e13e91d6
4 changed files with 120 additions and 22 deletions

1
MINE/rin/miner/readme.md Normal file
View File

@@ -0,0 +1 @@
from https://github.com/StickyFingaz420/CPUminer-opt-rinhash

View File

@@ -17,20 +17,37 @@ class PoolWebInterface:
self.host = host
self.port = port
def format_hashrate(self, hashrate):
"""Format hashrate in human readable format"""
if hashrate >= 1e12:
return f"{hashrate/1e12:.2f} TH/s"
elif hashrate >= 1e9:
return f"{hashrate/1e9:.2f} GH/s"
elif hashrate >= 1e6:
return f"{hashrate/1e6:.2f} MH/s"
elif hashrate >= 1e3:
return f"{hashrate/1e3:.2f} KH/s"
elif hashrate >= 0.01:
return f"{hashrate:.2f} H/s"
elif hashrate > 0:
return f"{hashrate*1000:.2f} mH/s"
else:
return "0.00 H/s"
def get_pool_stats(self):
"""Get current pool statistics"""
try:
cursor = self.pool_db.cursor()
# Total miners
# Total miners (ever registered)
cursor.execute('SELECT COUNT(DISTINCT id) FROM miners')
total_miners = cursor.fetchone()[0]
# Active miners (last 10 minutes)
# Active miners (last 5 minutes)
cursor.execute('''
SELECT COUNT(DISTINCT m.id) FROM miners m
JOIN shares s ON m.id = s.miner_id
WHERE s.submitted > datetime('now', '-10 minutes')
WHERE s.submitted > datetime('now', '-5 minutes')
''')
active_miners = cursor.fetchone()[0]
@@ -41,13 +58,22 @@ class PoolWebInterface:
''')
total_shares_24h = cursor.fetchone()[0]
# Pool hashrate estimate
# Better hashrate calculation (shares per second * difficulty)
cursor.execute('''
SELECT COUNT(*) FROM shares
SELECT SUM(difficulty), COUNT(*) FROM shares
WHERE submitted > datetime('now', '-5 minutes')
''')
recent_shares = cursor.fetchone()[0]
hashrate = recent_shares * 12 # Rough estimate
result = cursor.fetchone()
recent_difficulty = result[0] if result[0] else 0
recent_share_count = result[1] if result[1] else 0
# Convert to hashrate (difficulty per second)
hashrate = recent_difficulty / 300.0 # 5 minutes = 300 seconds
# 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
# Total blocks found
cursor.execute('SELECT COUNT(*) FROM blocks')
@@ -62,18 +88,30 @@ class PoolWebInterface:
''')
recent_blocks = cursor.fetchall()
# Top miners
# Top miners (last 24 hours) - show all miners, even without shares
cursor.execute('''
SELECT m.user, m.worker, COUNT(s.id) as shares, m.last_share
SELECT m.user, m.worker,
COALESCE(COUNT(s.id), 0) as shares,
m.last_share,
m.created
FROM miners m
JOIN shares s ON m.id = s.miner_id
WHERE s.submitted > datetime('now', '-24 hours')
GROUP BY m.id
ORDER BY shares DESC
LIMIT 10
LEFT JOIN shares s ON m.id = s.miner_id
AND s.submitted > datetime('now', '-24 hours')
GROUP BY m.id, m.user, m.worker
ORDER BY shares DESC, m.created DESC
LIMIT 20
''')
top_miners = cursor.fetchall()
# All active miners (for better visibility)
cursor.execute('''
SELECT user, worker, created, last_share
FROM miners
ORDER BY created DESC
LIMIT 10
''')
all_miners = cursor.fetchall()
return {
'total_miners': total_miners,
'active_miners': active_miners,
@@ -81,7 +119,13 @@ class PoolWebInterface:
'hashrate': hashrate,
'total_blocks': total_blocks,
'recent_blocks': recent_blocks,
'top_miners': top_miners
'top_miners': top_miners,
'all_miners': all_miners,
'debug': {
'recent_difficulty': recent_difficulty,
'recent_share_count': recent_share_count,
'total_shares_24h': total_shares_24h
}
}
except Exception as e:
print(f"Error getting pool stats: {e}")
@@ -133,8 +177,8 @@ class PoolWebInterface:
<div class="stat-label">Active Miners</div>
</div>
<div class="stat-card">
<div class="stat-value">{stats.get('hashrate', 0):.2f}</div>
<div class="stat-label">Hashrate (H/s)</div>
<div class="stat-value">{self.format_hashrate(stats.get('hashrate', 0))}</div>
<div class="stat-label">Hashrate</div>
</div>
<div class="stat-card">
<div class="stat-value">{stats.get('total_blocks', 0)}</div>
@@ -147,10 +191,53 @@ class PoolWebInterface:
<p><strong>24h Shares:</strong> {stats.get('total_shares_24h', 0):,}</p>
<p><strong>Pool Fee:</strong> 1%</p>
<p><strong>Connection String:</strong> <code>stratum+tcp://YOUR_IP:3333</code></p>
<!-- Debug info -->
<details style="margin-top: 20px; padding: 10px; background: #f8f9fa; border-radius: 4px;">
<summary style="cursor: pointer; font-weight: bold;">🔍 Debug Info</summary>
<p><strong>Recent Difficulty (5min):</strong> {stats.get('debug', {}).get('recent_difficulty', 0):.6f}</p>
<p><strong>Recent Share Count (5min):</strong> {stats.get('debug', {}).get('recent_share_count', 0)}</p>
<p><strong>Total Shares (24h):</strong> {stats.get('debug', {}).get('total_shares_24h', 0):,}</p>
<p><strong>Active Miners:</strong> {stats.get('active_miners', 0)} (last 5 minutes)</p>
<p><strong>Total Miners:</strong> {stats.get('total_miners', 0)} (ever registered)</p>
</details>
</div>
<div class="section">
<h2>👥 Top Miners (24h)</h2>
<h2>👥 Connected Miners</h2>
<table>
<tr>
<th>User</th>
<th>Worker</th>
<th>Connected</th>
<th>Last Share</th>
</tr>
"""
for miner in stats.get('all_miners', []):
user, worker, created, last_share = miner
html += f"""
<tr>
<td>{user}</td>
<td>{worker}</td>
<td>{created}</td>
<td>{last_share or 'Never'}</td>
</tr>
"""
if not stats.get('all_miners', []):
html += """
<tr>
<td colspan="4" style="text-align: center; color: #7f8c8d;">No miners connected</td>
</tr>
"""
html += """
</table>
</div>
<div class="section">
<h2>🏆 Top Miners (24h Shares)</h2>
<table>
<tr>
<th>User</th>
@@ -161,7 +248,7 @@ class PoolWebInterface:
"""
for miner in stats.get('top_miners', []):
user, worker, shares, last_share = miner
user, worker, shares, last_share, created = miner
html += f"""
<tr>
<td>{user}</td>
@@ -171,6 +258,13 @@ class PoolWebInterface:
</tr>
"""
if not stats.get('top_miners', []):
html += """
<tr>
<td colspan="4" style="text-align: center; color: #7f8c8d;">No shares submitted yet</td>
</tr>
"""
html += """
</table>
</div>

View File

@@ -333,8 +333,8 @@ class RinCoinMiningPool:
4
])
# Send difficulty
self.send_stratum_notification(client, "mining.set_difficulty", [1])
# Send difficulty (lower for CPU mining)
self.send_stratum_notification(client, "mining.set_difficulty", [0.001])
# Send initial job
if self.get_block_template():
@@ -433,12 +433,15 @@ class RinCoinMiningPool:
nonce = params[3]
# Record share
self.record_share(miner_info['miner_id'], job_id, 1.0) # Simplified difficulty
self.record_share(miner_info['miner_id'], job_id, 0.001) # Use actual difficulty
miner_info['shares'] += 1
miner_info['last_share'] = time.time()
print(f"[{addr}] ✅ Share accepted from {miner_info['user']}.{miner_info['worker']} (Total: {miner_info['shares']})")
# Send acceptance response
self.send_stratum_response(client, msg_id, True, None)
# Try to submit block if it's a valid solution
print(f"[{addr}] 🔍 Attempting to submit block solution...")