按显卡世代和创世编号结算回本,机房批量接入需审核网段并用硬件指纹防克隆。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-11 00:30:46 +08:00
parent 7d29be8b17
commit 0740016ad8
22 changed files with 1554 additions and 96 deletions
+23 -1
View File
@@ -5,7 +5,7 @@ from __future__ import annotations
from decimal import Decimal
from urllib.parse import urlparse
from sqlalchemy import select
from sqlalchemy import func, select
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import Session
@@ -15,6 +15,14 @@ from app.errors import AppError
from app.models import ComputeNode, NodeStatus, User, UserRole
from app.money import money
from app.services.common import get_user_by_wallet
from app.services.ip_guard import assert_ip_available
from app.services.hardware import (
DEFAULT_WEIGHT,
GENERATION_10,
GENESIS_RECOVERY_DAYS,
RECOVERY_10_DAYS,
is_genesis,
)
def register_user(
@@ -52,16 +60,23 @@ def register_node(
purchase_amount: Decimal,
callback_url: str | None = None,
node_token: str | None = None,
client_ip: str | None = None,
) -> ComputeNode:
user = get_user_by_wallet(session, wallet_address.strip())
serial = sn.strip()
if session.scalar(select(ComputeNode).where(ComputeNode.sn == serial)) is not None:
raise AppError("节点序列号已存在", 409)
bound_ip = (client_ip or "").strip() or None
if bound_ip:
assert_ip_available(session, bound_ip)
callback = _normalize_callback(callback_url)
started = utcnow()
node_index = int(session.scalar(select(func.max(ComputeNode.node_index))) or 0) + 1
recovery_days = GENESIS_RECOVERY_DAYS if is_genesis(node_index) else RECOVERY_10_DAYS
node = ComputeNode(
user_id=user.id,
sn=serial,
node_index=node_index,
purchase_amount=money(purchase_amount),
license_months=settings.license_months,
licensed_at=started,
@@ -69,6 +84,13 @@ def register_node(
status=NodeStatus.OFFLINE,
callback_url=callback,
node_token=node_token,
hardware_weight=float(DEFAULT_WEIGHT),
gpu_generation=GENERATION_10,
recovery_days=recovery_days,
generation_locked=False,
recoverable_stake_amount=money(purchase_amount),
is_whitelist=False,
client_ip=bound_ip,
created_at=started,
updated_at=started,
)