|
|
import gradio as gr
|
|
|
import time
|
|
|
import logging
|
|
|
from parallel_miner_v3 import ParallelMiner
|
|
|
import threading
|
|
|
import json
|
|
|
from datetime import datetime
|
|
|
import numpy as np
|
|
|
import plotly.graph_objects as go
|
|
|
from plotly.subplots import make_subplots
|
|
|
|
|
|
|
|
|
miner_instance = None
|
|
|
mining_thread = None
|
|
|
is_mining = False
|
|
|
stats_history = {
|
|
|
"timestamps": [],
|
|
|
"hashrates": [],
|
|
|
"total_hashes": [],
|
|
|
"blocks_found": []
|
|
|
}
|
|
|
|
|
|
def update_stats_history(hashrate, total_hashes, blocks):
|
|
|
"""Update historical stats for plotting"""
|
|
|
current_time = datetime.now().strftime("%H:%M:%S")
|
|
|
stats_history["timestamps"].append(current_time)
|
|
|
stats_history["hashrates"].append(hashrate)
|
|
|
stats_history["total_hashes"].append(total_hashes)
|
|
|
stats_history["blocks_found"].append(blocks)
|
|
|
|
|
|
|
|
|
max_points = 100
|
|
|
if len(stats_history["timestamps"]) > max_points:
|
|
|
stats_history["timestamps"] = stats_history["timestamps"][-max_points:]
|
|
|
stats_history["hashrates"] = stats_history["hashrates"][-max_points:]
|
|
|
stats_history["total_hashes"] = stats_history["total_hashes"][-max_points:]
|
|
|
stats_history["blocks_found"] = stats_history["blocks_found"][-max_points:]
|
|
|
|
|
|
def create_performance_plots():
|
|
|
"""Create performance visualization plots"""
|
|
|
fig = make_subplots(
|
|
|
rows=2, cols=1,
|
|
|
subplot_titles=("Mining Hashrate (KH/s)", "Total Hashes"),
|
|
|
vertical_spacing=0.12
|
|
|
)
|
|
|
|
|
|
|
|
|
fig.add_trace(
|
|
|
go.Scatter(x=stats_history["timestamps"],
|
|
|
y=[h/1000 for h in stats_history["hashrates"]],
|
|
|
mode='lines+markers',
|
|
|
name='Hashrate',
|
|
|
line=dict(color='#2ecc71')),
|
|
|
row=1, col=1
|
|
|
)
|
|
|
|
|
|
|
|
|
fig.add_trace(
|
|
|
go.Scatter(x=stats_history["timestamps"],
|
|
|
y=stats_history["total_hashes"],
|
|
|
mode='lines',
|
|
|
name='Total Hashes',
|
|
|
line=dict(color='#3498db')),
|
|
|
row=2, col=1
|
|
|
)
|
|
|
|
|
|
fig.update_layout(
|
|
|
height=600,
|
|
|
showlegend=True,
|
|
|
title_text="Mining Performance Metrics",
|
|
|
template="plotly_dark"
|
|
|
)
|
|
|
|
|
|
return fig
|
|
|
|
|
|
def start_mining():
|
|
|
"""Start the mining process"""
|
|
|
global miner_instance, mining_thread, is_mining
|
|
|
|
|
|
if is_mining:
|
|
|
return "Mining is already running!"
|
|
|
|
|
|
try:
|
|
|
miner_instance = ParallelMiner(num_cores=5)
|
|
|
miner_instance.mining = True
|
|
|
is_mining = True
|
|
|
|
|
|
|
|
|
mining_thread = threading.Thread(
|
|
|
target=miner_instance.start_mining,
|
|
|
kwargs={"duration": None}
|
|
|
)
|
|
|
mining_thread.daemon = True
|
|
|
mining_thread.start()
|
|
|
|
|
|
return "Mining started successfully! Monitor the stats below."
|
|
|
except Exception as e:
|
|
|
return f"Error starting mining: {str(e)}"
|
|
|
|
|
|
def stop_mining():
|
|
|
"""Stop the mining process"""
|
|
|
global miner_instance, is_mining
|
|
|
|
|
|
if not is_mining:
|
|
|
return "Mining is not running!"
|
|
|
|
|
|
try:
|
|
|
if miner_instance:
|
|
|
|
|
|
logging.info("\n=== Final Mining Statistics ===")
|
|
|
grand_total = 0
|
|
|
for core_idx, core in enumerate(miner_instance.cores):
|
|
|
core_total = core.total_hashes
|
|
|
grand_total += core_total
|
|
|
logging.info(f"Core {core_idx}: {core_total:,} hashes")
|
|
|
logging.info(f"Grand Total: {grand_total:,} hashes")
|
|
|
logging.info(f"Overall Hashrate: {miner_instance.current_hashrate/1000:.2f} KH/s")
|
|
|
logging.info(f"Blocks Found: {miner_instance.blocks_found}")
|
|
|
logging.info("============================\n")
|
|
|
|
|
|
miner_instance.mining = False
|
|
|
is_mining = False
|
|
|
return "Mining stopped successfully! Check logs for final statistics."
|
|
|
return "No active mining instance found."
|
|
|
except Exception as e:
|
|
|
return f"Error stopping mining: {str(e)}"
|
|
|
|
|
|
def get_mining_stats():
|
|
|
"""Get current mining statistics"""
|
|
|
global miner_instance, is_mining
|
|
|
|
|
|
if not miner_instance or not is_mining:
|
|
|
return {
|
|
|
"status": "Stopped",
|
|
|
"hashrate": "0 H/s",
|
|
|
"total_hashes": "0",
|
|
|
"blocks_found": "0",
|
|
|
"best_hash": "None",
|
|
|
"difficulty": "0"
|
|
|
}
|
|
|
|
|
|
|
|
|
update_stats_history(
|
|
|
miner_instance.current_hashrate,
|
|
|
miner_instance.total_hashes,
|
|
|
miner_instance.blocks_found
|
|
|
)
|
|
|
|
|
|
|
|
|
performance_plot = create_performance_plots()
|
|
|
|
|
|
return {
|
|
|
"status": "Running" if is_mining else "Stopped",
|
|
|
"hashrate": f"{miner_instance.current_hashrate/1000:.2f} KH/s",
|
|
|
"total_hashes": f"{miner_instance.total_hashes:,}",
|
|
|
"blocks_found": str(miner_instance.blocks_found),
|
|
|
"best_hash": miner_instance.best_hash.hex() if miner_instance.best_hash else "None",
|
|
|
"difficulty": f"{miner_instance.best_hash_difficulty:,}",
|
|
|
"performance_plot": performance_plot
|
|
|
}
|
|
|
|
|
|
|
|
|
with gr.Blocks(theme=gr.themes.Monochrome()) as app:
|
|
|
gr.Markdown("# ⛏️ Bitcoin Mining Dashboard")
|
|
|
|
|
|
with gr.Row():
|
|
|
start_btn = gr.Button("▶️ Start Mining", variant="primary")
|
|
|
stop_btn = gr.Button("⏹️ Stop Mining", variant="secondary")
|
|
|
|
|
|
with gr.Row():
|
|
|
with gr.Column():
|
|
|
status_label = gr.Label(label="Status")
|
|
|
hashrate_label = gr.Label(label="Current Hashrate")
|
|
|
total_hashes_label = gr.Label(label="Total Hashes")
|
|
|
blocks_label = gr.Label(label="Blocks Found")
|
|
|
best_hash_label = gr.Label(label="Best Hash")
|
|
|
difficulty_label = gr.Label(label="Best Difficulty")
|
|
|
|
|
|
with gr.Row():
|
|
|
plot_output = gr.Plot(label="Performance Metrics")
|
|
|
|
|
|
|
|
|
start_btn.click(
|
|
|
fn=start_mining,
|
|
|
outputs=[status_label]
|
|
|
)
|
|
|
|
|
|
stop_btn.click(
|
|
|
fn=stop_mining,
|
|
|
outputs=[status_label]
|
|
|
)
|
|
|
|
|
|
|
|
|
refresh_btn = gr.Button("🔄 Refresh Stats")
|
|
|
refresh_btn.click(
|
|
|
fn=get_mining_stats,
|
|
|
outputs=[
|
|
|
status_label,
|
|
|
hashrate_label,
|
|
|
total_hashes_label,
|
|
|
blocks_label,
|
|
|
best_hash_label,
|
|
|
difficulty_label,
|
|
|
plot_output
|
|
|
]
|
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
app.launch(
|
|
|
share=True,
|
|
|
server_name="0.0.0.0",
|
|
|
server_port=7862
|
|
|
) |