Remove outdated GPU marketplace endpoint and fix staking service logic

- Remove duplicate `/marketplace/gpu/{gpu_id}` endpoint from marketplace_gpu.py
- Remove marketplace_gpu router inclusion from main.py (already included elsewhere)
- Fix staking service staker_count logic to check existing stakes before increment/decrement
- Add minimum stake amount validation (100 AITBC)
- Add proper error handling for stake not found cases
- Fix staking pool update to commit and refresh after modifications
- Update CLI send_transaction to use chain
This commit is contained in:
aitbc
2026-04-13 22:07:51 +02:00
parent da630386cf
commit 7c51f3490b
140 changed files with 42080 additions and 267 deletions

View File

@@ -4,7 +4,7 @@ Database models for AI agent bounty system with ZK-proof verification
"""
import uuid
from datetime import datetime
from datetime import datetime, timedelta
from enum import StrEnum
from typing import Any

View File

@@ -301,7 +301,6 @@ def create_app() -> FastAPI:
app.include_router(edge_gpu)
# Add standalone routers for tasks and payments
app.include_router(marketplace_gpu, prefix="/v1")
if ml_zk_proofs:
app.include_router(ml_zk_proofs)

View File

@@ -4,6 +4,7 @@ from typing import Annotated
GPU marketplace endpoints backed by persistent SQLModel tables.
"""
import logging
import statistics
from datetime import datetime, timedelta
from typing import Any
@@ -20,6 +21,8 @@ from ..services.dynamic_pricing_engine import DynamicPricingEngine, PricingStrat
from ..services.market_data_collector import MarketDataCollector
from ..storage import get_session
logger = logging.getLogger(__name__)
router = APIRouter(tags=["marketplace-gpu"])
# Global instances (in production, these would be dependency injected)
@@ -716,21 +719,3 @@ async def bid_gpu(request: dict[str, Any], session: Session = Depends(get_sessio
"duration_hours": request.get("duration_hours"),
"timestamp": datetime.utcnow().isoformat() + "Z",
}
@router.get("/marketplace/gpu/{gpu_id}")
async def get_gpu_details(gpu_id: str, session: Session = Depends(get_session)) -> dict[str, Any]:
"""Get GPU details"""
# Simple implementation
return {
"gpu_id": gpu_id,
"name": "Test GPU",
"memory_gb": 8,
"cuda_cores": 2560,
"compute_capability": "8.6",
"price_per_hour": 10.0,
"status": "available",
"miner_id": "test-miner",
"region": "us-east",
"created_at": datetime.utcnow().isoformat() + "Z",
}

View File

@@ -3,6 +3,7 @@ Staking Management Service
Business logic for AI agent staking system with reputation-based yield farming
"""
import logging
from datetime import datetime, timedelta
from typing import Any
@@ -11,6 +12,8 @@ from sqlalchemy.orm import Session
from ..domain.bounty import AgentMetrics, AgentStake, PerformanceTier, StakeStatus, StakingPool
logger = logging.getLogger(__name__)
class StakingService:
"""Service for managing AI agent staking"""
@@ -28,6 +31,10 @@ class StakingService:
if not agent_metrics:
raise ValueError("Agent not supported for staking")
# Validate stake amount
if amount < 100:
raise ValueError("Stake amount must be at least 100 AITBC")
# Calculate APY
current_apy = await self.calculate_apy(agent_wallet, lock_period)
@@ -49,9 +56,9 @@ class StakingService:
# Update agent metrics
agent_metrics.total_staked += amount
if agent_metrics.total_staked == amount:
agent_metrics.staker_count = 1
else:
# Check if this is the first stake from this staker
existing_stakes = await self.get_user_stakes(staker_address, agent_wallet=agent_wallet)
if not existing_stakes:
agent_metrics.staker_count += 1
# Update staking pool
@@ -68,13 +75,17 @@ class StakingService:
self.session.rollback()
raise
async def get_stake(self, stake_id: str) -> AgentStake | None:
async def get_stake(self, stake_id: str) -> AgentStake:
"""Get stake by ID"""
try:
stmt = select(AgentStake).where(AgentStake.stake_id == stake_id)
result = self.session.execute(stmt).scalar_one_or_none()
if not result:
raise ValueError("Stake not found")
return result
except ValueError:
raise
except Exception as e:
logger.error(f"Failed to get stake {stake_id}: {e}")
raise
@@ -213,9 +224,9 @@ class StakingService:
agent_metrics = await self.get_agent_metrics(stake.agent_wallet)
if agent_metrics:
agent_metrics.total_staked -= stake.amount
if agent_metrics.total_staked <= 0:
agent_metrics.staker_count = 0
else:
# Check if this is the last stake from this staker
remaining_stakes = await self.get_user_stakes(stake.staker_address, agent_wallet=stake.agent_wallet, status=StakeStatus.ACTIVE)
if not remaining_stakes:
agent_metrics.staker_count -= 1
# Update staking pool
@@ -704,6 +715,10 @@ class StakingService:
if not pool:
pool = StakingPool(agent_wallet=agent_wallet)
self.session.add(pool)
self.session.commit()
self.session.refresh(pool)
else:
self.session.refresh(pool)
if is_stake:
if staker_address not in pool.active_stakers:
@@ -718,6 +733,9 @@ class StakingService:
if pool.total_staked > 0:
pool.pool_apy = await self.calculate_apy(agent_wallet, 30)
self.session.commit()
self.session.refresh(pool)
except Exception as e:
logger.error(f"Failed to update staking pool: {e}")
raise