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:
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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",
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user