dashboard
This commit is contained in:
Binary file not shown.
1
MINE/rin/miner/readme.md
Normal file
1
MINE/rin/miner/readme.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from https://github.com/StickyFingaz420/CPUminer-opt-rinhash
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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...")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user