|
|
from fastapi import FastAPI, HTTPException
|
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
|
from fastapi.responses import JSONResponse
|
|
|
from parallel_miner_v3 import ParallelMiner
|
|
|
import threading
|
|
|
from typing import Dict, Optional
|
|
|
import uvicorn
|
|
|
import logging
|
|
|
|
|
|
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
app = FastAPI(title="Mining Dashboard API")
|
|
|
|
|
|
|
|
|
app.add_middleware(
|
|
|
CORSMiddleware,
|
|
|
allow_origins=["*"],
|
|
|
allow_credentials=True,
|
|
|
allow_methods=["*"],
|
|
|
allow_headers=["*"],
|
|
|
)
|
|
|
|
|
|
|
|
|
miner_instance: Optional[ParallelMiner] = None
|
|
|
mining_thread: Optional[threading.Thread] = None
|
|
|
is_mining = False
|
|
|
|
|
|
@app.get("/status")
|
|
|
async def get_status() -> Dict:
|
|
|
"""Get current mining status and statistics"""
|
|
|
global miner_instance, is_mining
|
|
|
|
|
|
logger.info("Status endpoint called")
|
|
|
try:
|
|
|
if not miner_instance:
|
|
|
logger.info("No miner instance found, returning default values")
|
|
|
return {
|
|
|
"status": "Stopped",
|
|
|
"hashrate": 0,
|
|
|
"total_hashes": 0,
|
|
|
"blocks_found": 0,
|
|
|
"best_hash": None,
|
|
|
"difficulty": 0
|
|
|
}
|
|
|
|
|
|
stats = {
|
|
|
"status": "Running" if is_mining else "Stopped",
|
|
|
"hashrate": round(miner_instance.current_hashrate / 1000, 2),
|
|
|
"total_hashes": miner_instance.total_hashes,
|
|
|
"blocks_found": miner_instance.blocks_found,
|
|
|
"best_hash": miner_instance.best_hash.hex() if miner_instance.best_hash else None,
|
|
|
"difficulty": miner_instance.best_hash_difficulty
|
|
|
}
|
|
|
logger.info(f"Returning stats: {stats}")
|
|
|
return stats
|
|
|
except Exception as e:
|
|
|
logger.error(f"Error getting status: {str(e)}")
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
@app.post("/start")
|
|
|
async def start_mining() -> Dict:
|
|
|
"""Start the mining process"""
|
|
|
global miner_instance, mining_thread, is_mining
|
|
|
|
|
|
logger.info("Start mining endpoint called")
|
|
|
|
|
|
if is_mining:
|
|
|
logger.warning("Mining is already running")
|
|
|
raise HTTPException(status_code=400, detail="Mining is already running")
|
|
|
|
|
|
try:
|
|
|
logger.info("Initializing miner...")
|
|
|
miner_instance = ParallelMiner(num_cores=5)
|
|
|
miner_instance.mining = True
|
|
|
is_mining = True
|
|
|
|
|
|
|
|
|
logger.info("Starting mining thread...")
|
|
|
mining_thread = threading.Thread(
|
|
|
target=miner_instance.start_mining,
|
|
|
kwargs={"duration": None}
|
|
|
)
|
|
|
mining_thread.daemon = True
|
|
|
mining_thread.start()
|
|
|
|
|
|
logger.info("Mining started successfully")
|
|
|
return {"message": "Mining started successfully"}
|
|
|
except Exception as e:
|
|
|
logger.error(f"Error starting mining: {str(e)}")
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
@app.post("/api/stop")
|
|
|
async def stop_mining() -> Dict:
|
|
|
"""Stop the mining process"""
|
|
|
global miner_instance, is_mining
|
|
|
|
|
|
if not is_mining:
|
|
|
raise HTTPException(status_code=400, detail="Mining is not running")
|
|
|
|
|
|
try:
|
|
|
if miner_instance:
|
|
|
miner_instance.mining = False
|
|
|
is_mining = False
|
|
|
return {"message": "Mining stopped successfully"}
|
|
|
raise HTTPException(status_code=400, detail="No active mining instance found")
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
uvicorn.run(app, host="0.0.0.0", port=8000) |