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.host = host
self.port = port 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): def get_pool_stats(self):
"""Get current pool statistics""" """Get current pool statistics"""
try: try:
cursor = self.pool_db.cursor() cursor = self.pool_db.cursor()
# Total miners # Total miners (ever registered)
cursor.execute('SELECT COUNT(DISTINCT id) FROM miners') cursor.execute('SELECT COUNT(DISTINCT id) FROM miners')
total_miners = cursor.fetchone()[0] total_miners = cursor.fetchone()[0]
# Active miners (last 10 minutes) # Active miners (last 5 minutes)
cursor.execute(''' cursor.execute('''
SELECT COUNT(DISTINCT m.id) FROM miners m SELECT COUNT(DISTINCT m.id) FROM miners m
JOIN shares s ON m.id = s.miner_id 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] active_miners = cursor.fetchone()[0]
@@ -41,13 +58,22 @@ class PoolWebInterface:
''') ''')
total_shares_24h = cursor.fetchone()[0] total_shares_24h = cursor.fetchone()[0]
# Pool hashrate estimate # Better hashrate calculation (shares per second * difficulty)
cursor.execute(''' cursor.execute('''
SELECT COUNT(*) FROM shares SELECT SUM(difficulty), COUNT(*) FROM shares
WHERE submitted > datetime('now', '-5 minutes') WHERE submitted > datetime('now', '-5 minutes')
''') ''')
recent_shares = cursor.fetchone()[0] result = cursor.fetchone()
hashrate = recent_shares * 12 # Rough estimate 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 # Total blocks found
cursor.execute('SELECT COUNT(*) FROM blocks') cursor.execute('SELECT COUNT(*) FROM blocks')
@@ -62,18 +88,30 @@ class PoolWebInterface:
''') ''')
recent_blocks = cursor.fetchall() recent_blocks = cursor.fetchall()
# Top miners # Top miners (last 24 hours) - show all miners, even without shares
cursor.execute(''' 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 FROM miners m
JOIN shares s ON m.id = s.miner_id LEFT JOIN shares s ON m.id = s.miner_id
WHERE s.submitted > datetime('now', '-24 hours') AND s.submitted > datetime('now', '-24 hours')
GROUP BY m.id GROUP BY m.id, m.user, m.worker
ORDER BY shares DESC ORDER BY shares DESC, m.created DESC
LIMIT 10 LIMIT 20
''') ''')
top_miners = cursor.fetchall() 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 { return {
'total_miners': total_miners, 'total_miners': total_miners,
'active_miners': active_miners, 'active_miners': active_miners,
@@ -81,7 +119,13 @@ class PoolWebInterface:
'hashrate': hashrate, 'hashrate': hashrate,
'total_blocks': total_blocks, 'total_blocks': total_blocks,
'recent_blocks': recent_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: except Exception as e:
print(f"Error getting pool stats: {e}") print(f"Error getting pool stats: {e}")
@@ -133,8 +177,8 @@ class PoolWebInterface:
<div class="stat-label">Active Miners</div> <div class="stat-label">Active Miners</div>
</div> </div>
<div class="stat-card"> <div class="stat-card">
<div class="stat-value">{stats.get('hashrate', 0):.2f}</div> <div class="stat-value">{self.format_hashrate(stats.get('hashrate', 0))}</div>
<div class="stat-label">Hashrate (H/s)</div> <div class="stat-label">Hashrate</div>
</div> </div>
<div class="stat-card"> <div class="stat-card">
<div class="stat-value">{stats.get('total_blocks', 0)}</div> <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>24h Shares:</strong> {stats.get('total_shares_24h', 0):,}</p>
<p><strong>Pool Fee:</strong> 1%</p> <p><strong>Pool Fee:</strong> 1%</p>
<p><strong>Connection String:</strong> <code>stratum+tcp://YOUR_IP:3333</code></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>
<div class="section"> <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> <table>
<tr> <tr>
<th>User</th> <th>User</th>
@@ -161,7 +248,7 @@ class PoolWebInterface:
""" """
for miner in stats.get('top_miners', []): for miner in stats.get('top_miners', []):
user, worker, shares, last_share = miner user, worker, shares, last_share, created = miner
html += f""" html += f"""
<tr> <tr>
<td>{user}</td> <td>{user}</td>
@@ -171,6 +258,13 @@ class PoolWebInterface:
</tr> </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 += """ html += """
</table> </table>
</div> </div>

View File

@@ -333,8 +333,8 @@ class RinCoinMiningPool:
4 4
]) ])
# Send difficulty # Send difficulty (lower for CPU mining)
self.send_stratum_notification(client, "mining.set_difficulty", [1]) self.send_stratum_notification(client, "mining.set_difficulty", [0.001])
# Send initial job # Send initial job
if self.get_block_template(): if self.get_block_template():
@@ -433,12 +433,15 @@ class RinCoinMiningPool:
nonce = params[3] nonce = params[3]
# Record share # 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['shares'] += 1
miner_info['last_share'] = time.time() miner_info['last_share'] = time.time()
print(f"[{addr}] ✅ Share accepted from {miner_info['user']}.{miner_info['worker']} (Total: {miner_info['shares']})") 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 # Try to submit block if it's a valid solution
print(f"[{addr}] 🔍 Attempting to submit block solution...") print(f"[{addr}] 🔍 Attempting to submit block solution...")