File size: 4,843 Bytes
5673b19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9dfa941
f7e1ac1
 
 
 
 
 
 
 
 
9dfa941
 
f2aa0cf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
"""
FastAPI server for Bitcoin mining dashboard
"""
from fastapi import FastAPI, HTTPException
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
import uvicorn
from parallel_miner_v3 import ParallelMiner
import threading
from typing import Dict, Optional
import logging

# Configure logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)

app = FastAPI(title="Bitcoin Mining Dashboard")

# Mount static files
app.mount("/static", StaticFiles(directory="static"), name="static")
app.mount("/css", StaticFiles(directory="static/css"), name="css")
app.mount("/js", StaticFiles(directory="static/js"), name="js")

# Global state
miner_instance: Optional[ParallelMiner] = None
mining_thread: Optional[threading.Thread] = None
is_mining: bool = False

@app.get("/")
async def get_index():
    """Serve the dashboard HTML"""
    return FileResponse("static/index.html")

@app.post("/start_mining")
async def start_mining():
    """Start the mining process"""
    global miner_instance, mining_thread, is_mining
    
    if is_mining:
        raise HTTPException(status_code=400, detail="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 {"message": "Mining started successfully"}
    except Exception as e:
        logging.error(f"Error starting mining: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@app.post("/stop_mining")
async def stop_mining():
    """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:
            # Log final stats
            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 {"message": "Mining stopped successfully"}
            
        raise HTTPException(status_code=400, detail="No active mining instance")
    except Exception as e:
        logging.error(f"Error stopping mining: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@app.get("/get_stats")
async 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",
            "block_alert": "Mining stopped"
        }
    
    # Create block alert message
    if miner_instance.blocks_found > 0:
        block_alert = f"πŸŽ‰ FOUND {miner_instance.blocks_found} BLOCK(S)! Last block hash: {miner_instance.best_hash.hex() if miner_instance.best_hash else 'None'}"
    else:
        progress = miner_instance.best_hash_difficulty * 100 if miner_instance.best_hash_difficulty else 0
        block_alert = f"Mining in progress... Best hash difficulty: {progress:.8f}%"
    
    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:,}",
        "block_alert": block_alert
    }

processing_thread = None

@app.on_event("startup")
async def startup_event():
    global processing_thread
    if not (processing_thread and processing_thread.is_alive()): 
        processing_thread = threading.Thread(target=get_index())
        processing_thread.daemon = True
        processing_thread.start()

if __name__ == "__main__":
    uvicorn.run("app", host="0.0.0.0", port=7868, reload=False)