diff --git a/.gitignore b/.gitignore index fdd210b4..e290b985 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ # AITBC Monorepo ignore rules +# Updated: 2026-03-03 - Project organization workflow completed +# Development files organized into dev/ subdirectories # =================== # Python @@ -30,6 +32,20 @@ htmlcov/ .env.local .env.*.local +# =================== +# Development Environment (organized) +# =================== +dev/env/.venv/ +dev/env/node_modules/ +dev/env/cli_env/ +dev/cache/.pytest_cache/ +dev/cache/.ruff_cache/ +dev/cache/.vscode/ +dev/cache/logs/ +dev/scripts/__pycache__/ +dev/scripts/*.pyc +dev/scripts/*.pyo + # =================== # Databases # =================== @@ -58,7 +74,7 @@ pnpm-lock.yaml .cache/ # =================== -# Development Tests +# Development Tests (organized) # =================== dev/tests/__pycache__/ dev/tests/*.pyc @@ -66,11 +82,15 @@ dev/tests/test_results/ dev/tests/simple_test_results.json dev/tests/data/ dev/tests/*.db +dev/multi-chain/__pycache__/ +dev/multi-chain/*.pyc +dev/multi-chain/test_results/ # =================== -# Logs & Runtime +# Logs & Runtime (organized) # =================== logs/ +dev/cache/logs/ *.log *.log.* npm-debug.log* @@ -130,6 +150,14 @@ secrets/ credentials/ .secrets +# =================== +# Backup Files (organized) +# =================== +backup/**/*.tmp +backup/**/*.temp +backup/**/.DS_Store +backup/updates/*.log + # =================== # Temporary Files # =================== diff --git a/coordinator_working.py b/coordinator_working.py deleted file mode 100755 index e857c9ed..00000000 --- a/coordinator_working.py +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/env python3 -""" -Simple working coordinator API for GPU miner -""" - -import logging -from fastapi import FastAPI, HTTPException, Header -from fastapi.middleware.cors import CORSMiddleware -from typing import Optional, Dict, Any -from pydantic import BaseModel -import time - -# Setup logging -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - -# Create FastAPI app -app = FastAPI( - title="AITBC Coordinator API - Working", - version="0.1.0", - description="Simple working coordinator service for GPU miner", -) - -# Add CORS middleware -app.add_middleware( - CORSMiddleware, - allow_origins=["*"], - allow_credentials=True, - allow_methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"], - allow_headers=["*"] -) - -# Simple in-memory storage -miners: Dict[str, Dict[str, Any]] = {} -jobs: Dict[str, Dict[str, Any]] = {} - -# Pydantic models -class MinerRegister(BaseModel): - miner_id: str - capabilities: list[str] = [] - region: str = "default" - concurrency: int = 1 - -class MinerHeartbeat(BaseModel): - miner_id: str - status: str = "online" - inflight: int = 0 - -class JobSubmit(BaseModel): - prompt: str - model: str = "gemma3:1b" - priority: str = "normal" - -# Basic auth (simple for testing) -API_KEY = "miner_test" - -def verify_api_key(api_key: Optional[str] = Header(None), x_api_key: Optional[str] = Header(None)): - key = api_key or x_api_key - if key != API_KEY: - raise HTTPException(status_code=401, detail="invalid api key") - return key - -@app.get("/health", tags=["health"], summary="Service healthcheck") -async def health() -> dict[str, str]: - """Health check endpoint""" - return {"status": "ok", "service": "coordinator-api"} - -@app.get("/v1/health", tags=["health"], summary="Service healthcheck") -async def health_v1() -> dict[str, str]: - """Health check endpoint v1""" - return {"status": "ok", "service": "coordinator-api"} - -@app.post("/v1/miners/register", tags=["miner"], summary="Register or update miner") -async def register_miner( - request: dict, - api_key: Optional[str] = Header(None), - x_api_key: Optional[str] = Header(None), - miner_id: Optional[str] = None -) -> dict[str, str]: - """Register a miner""" - key = api_key or x_api_key - if key != API_KEY: - raise HTTPException(status_code=401, detail="invalid api key") - - # Get miner_id from query parameter or request body - mid = miner_id or request.get("miner_id", "miner_test") - - # Register the miner with simple data - miners[mid] = { - "id": mid, - "capabilities": ["gpu"], - "region": request.get("region", "localhost"), - "concurrency": request.get("concurrency", 1), - "status": "online", - "inflight": 0, - "last_heartbeat": time.time(), - "session_token": f"token_{mid}_{int(time.time())}" - } - - logger.info(f"Miner {mid} registered") - return {"status": "ok", "session_token": miners[mid]["session_token"]} - -@app.post("/v1/miners/heartbeat", tags=["miner"], summary="Send miner heartbeat") -async def miner_heartbeat( - request: dict, - api_key: Optional[str] = Header(None), - x_api_key: Optional[str] = Header(None), - miner_id: Optional[str] = None -) -> dict[str, str]: - """Receive miner heartbeat""" - key = api_key or x_api_key - if key != API_KEY: - raise HTTPException(status_code=401, detail="invalid api key") - - # Get miner_id from query parameter or request body - mid = miner_id or request.get("miner_id", "miner_test") - - if mid not in miners: - raise HTTPException(status_code=404, detail="miner not registered") - - miners[mid].update({ - "status": request.get("status", "online"), - "inflight": request.get("current_jobs", 0), - "last_heartbeat": time.time() - }) - - return {"status": "ok"} - -@app.post("/v1/miners/poll", tags=["miner"], summary="Poll for next job") -async def poll_for_job( - request: dict, - api_key: Optional[str] = Header(None), - x_api_key: Optional[str] = Header(None), - miner_id: Optional[str] = None -) -> Dict[str, Any]: - """Poll for next job""" - key = api_key or x_api_key - if key != API_KEY: - raise HTTPException(status_code=401, detail="invalid api key") - - # For now, return no jobs (empty response) - return {"status": "no_jobs"} - -@app.get("/", tags=["root"], summary="Root endpoint") -async def root() -> dict[str, str]: - """Root endpoint""" - return {"service": "AITBC Coordinator API", "status": "running"} - -if __name__ == "__main__": - import uvicorn - logger.info("Starting working coordinator API on port 9080") - uvicorn.run(app, host="127.0.0.1", port=9080) diff --git a/fix_gossip.patch b/fix_gossip.patch deleted file mode 100644 index 92ed2abd..00000000 --- a/fix_gossip.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/apps/blockchain-node/src/aitbc_chain/consensus/poa.py -+++ b/apps/blockchain-node/src/aitbc_chain/consensus/poa.py -@@ -171,7 +171,7 @@ - ) - - # Broadcast the new block -- gossip_broker.publish( -+ await gossip_broker.publish( - "blocks", - { - "height": block.height, -@@ -207,7 +207,7 @@ - session.commit() - - # Broadcast genesis block for initial sync -- gossip_broker.publish( -+ await gossip_broker.publish( - "blocks", - { - "height": genesis.height, diff --git a/fix_gossip2.patch b/fix_gossip2.patch deleted file mode 100644 index 1deb67b7..00000000 --- a/fix_gossip2.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/apps/blockchain-node/src/aitbc_chain/consensus/poa.py -+++ b/apps/blockchain-node/src/aitbc_chain/consensus/poa.py -@@ -194,7 +194,7 @@ - except Exception as e: - logger.error(f"Failed to propose block: {e}") - -- def _ensure_genesis_block(self) -> None: -+ async def _ensure_genesis_block(self) -> None: - """Ensure genesis block exists""" - with self.session_factory() as session: - if session.exec(select(Block).where(Block.height == 0)).first(): diff --git a/fix_gossip3.patch b/fix_gossip3.patch deleted file mode 100644 index be894571..00000000 --- a/fix_gossip3.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/apps/blockchain-node/src/aitbc_chain/consensus/poa.py -+++ b/apps/blockchain-node/src/aitbc_chain/consensus/poa.py -@@ -101,7 +101,7 @@ - # Wait for interval before proposing next block - await asyncio.sleep(self.config.interval_seconds) - -- self._propose_block() -+ await self._propose_block() - - except asyncio.CancelledError: - pass diff --git a/fix_gossip4.patch b/fix_gossip4.patch deleted file mode 100644 index 035950d2..00000000 --- a/fix_gossip4.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/apps/blockchain-node/src/aitbc_chain/consensus/poa.py -+++ b/apps/blockchain-node/src/aitbc_chain/consensus/poa.py -@@ -81,7 +81,7 @@ - if self._task is not None: - return - self._logger.info("Starting PoA proposer loop", extra={"interval": self._config.interval_seconds}) -- self._ensure_genesis_block() -+ await self._ensure_genesis_block() - self._stop_event.clear() - self._task = asyncio.create_task(self._run_loop()) -