Spaces:
Paused
Paused
| import gradio as gr | |
| import time | |
| 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 | |
| # Global variables for mining state | |
| 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) | |
| # Keep only last 100 data points | |
| 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 | |
| ) | |
| # Hashrate plot | |
| 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 | |
| ) | |
| # Total hashes plot | |
| 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 | |
| # Start mining in background thread | |
| 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: | |
| miner_instance.mining = False | |
| is_mining = False | |
| return "Mining stopped successfully!" | |
| 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 historical stats | |
| update_stats_history( | |
| miner_instance.current_hashrate, | |
| miner_instance.total_hashes, | |
| miner_instance.blocks_found | |
| ) | |
| # Create performance plot | |
| 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 | |
| } | |
| # Create the Gradio interface | |
| 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") | |
| # Setup event handlers | |
| start_btn.click( | |
| fn=start_mining, | |
| outputs=[status_label] | |
| ) | |
| stop_btn.click( | |
| fn=stop_mining, | |
| outputs=[status_label] | |
| ) | |
| # Instead of automatic updates, add a refresh button | |
| 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, # Enable sharing | |
| server_name="0.0.0.0", | |
| server_port=7860 | |
| ) |