# HyperNode-AI 说明 HyperNode-AI 是算力节点的控制面。节点程序部署在各处,本服务负责登记节点、接收心跳、下发模拟任务、按天计算积分,并记录提现。 时间全部使用 UTC。每日清算的触发时刻是北京时间 00:05,入账的是上一个已经结束的 UTC 日。 本地开发直接启动时监听 8000。服务器按 [部署.md](部署.md) 安装后监听 33333。 ```bash pip install -r requirements.txt python -m app ``` ## 目录 | 路径 | 内容 | |---|---| | `app/models.py` | 数据表 | | `app/api.py` | HTTP 接口 | | `app/services/heartbeat.py` | 心跳与离线判断 | | `app/services/tasks.py` | 任务下发与 nonce 校验 | | `app/services/yield_engine.py` | 产出公式与按日入账 | | `app/jobs/daily_yield.py` | 凌晨清算入口 | | `app/scheduler.py` | 进程内定时任务 | | `app/settle.py` | 可单独执行的清算命令 | | `web/` | 控制台页面,服务启动后打开 `/` | | `deploy/manage.sh` | Ubuntu 22.04 交互式部署,支持 `curl \| bash` | ## 数据表 业务表: - `users`:钱包地址、注册时间。 - `compute_nodes`:节点 SN、购买金额、12 个月授权、`online` / `offline`、最后心跳。可选 `callback_url` 用来推送任务。 - `node_yields`:每日算力产出和积分。同一节点同一天只有一条。 - `withdrawal_logs`:提现金额、资产符号、链上哈希、状态。 计算用的表: - `uptime_intervals`:一段连续在线时间。 - `compute_tasks`:下发的模拟任务和回传结果。 - `scheduler_locks`:多台服务实例同时跑定时任务时互斥。 ## 产出公式 授权金额按授权起止日期的天数线性释放,再乘当天表现系数。单节点累计积分不超过购买金额。 - 在线率 = 当天授权窗口内的在线秒数 / 当天授权有效秒数 - 任务响应率 = 校验通过且执行成功的任务数 / 当天下发任务数 - 当天没有下发任务时,表现系数 = 在线率 - 有任务时,表现系数 = `0.7 × 在线率 + 0.3 × 响应率` - 算力产出 = 购买金额 × 表现系数 - 当日积分 = 算力产出 / 授权天数 开放的在线区间如果最后心跳已超过 15 分钟,只计算到最后一次心跳。 权重可用环境变量 `ONLINE_WEIGHT`、`TASK_WEIGHT` 修改,默认 `0.7` 和 `0.3`。 ## 运行中的三件事 服务进程里有三个定时任务: 1. 每 5 分钟检查心跳。超过 15 分钟没有心跳,或授权到期,节点改为 `offline`,在线区间结束在最后一次心跳。 2. 每 5 分钟向在线、授权仍有效、且没有未完成任务的节点随机下发任务,每轮最多 20 台。任务带 `task_id` 和一次性 `nonce`。节点若配置了 `callback_url`,会额外 POST 一次;否则节点用拉取接口领取。 3. 北京时间 00:05 结算上一个已结束的 UTC 日,写入 `node_yields`。同一天已有记录则跳过。 回传必须带上任务里的 `nonce`。超时、重复回传、nonce 不匹配都不算成功。 ## 接口 前缀都是 `/api/v1`。金额在 JSON 里是字符串。 | 方法 | 路径 | 作用 | |---|---|---| | POST | `/users` | 注册钱包 | | POST | `/nodes` | 登记节点 | | GET | `/nodes/{sn}` | 查看节点 | | POST | `/node/heartbeat` | 心跳,请求体 `{"sn":"..."}` | | GET | `/node/{sn}/tasks` | 拉取未完成任务 | | POST | `/node/task/report` | 回传 `sn`、`task_id`、`success`、`nonce` | | GET | `/nodes/{sn}/contribution?yield_date=YYYY-MM-DD` | 预览某日产出,不入账 | | POST | `/yield/settle?yield_date=YYYY-MM-DD` | 手动清算,不传日期则清算昨天 | | GET | `/nodes/{sn}/yields` | 节点流水 | | GET | `/users/{wallet}/balance` | 可用积分 | | POST | `/withdrawals` | 申请提现 | | POST | `/withdrawals/{id}/confirm` | 写入 `tx_hash` 并完成 | | POST | `/withdrawals/{id}/reject` | 拒绝并释放占用的积分 | 可用积分 = 已入账积分 − 待处理提现 − 已完成提现。 健康检查是 `/health`,不在 `/api/v1` 下面。 ## 配置 生产环境的配置在 `/opt/hypernode/.env`。也可以在启动前用同名环境变量覆盖。 | 变量 | 默认值 | 含义 | |---|---|---| | `DATABASE_URL` | 部署后指向 `/var/lib/hypernode/hypernode.db` | 数据库。可改为 PostgreSQL 连接串 | | `HEARTBEAT_TIMEOUT_MINUTES` | `15` | 心跳超时 | | `OFFLINE_CHECK_MINUTES` | `5` | 离线巡检间隔 | | `TASK_DISPATCH_MINUTES` | `5` | 任务下发间隔 | | `DISPATCH_BATCH_SIZE` | `20` | 每轮最多下发数量 | | `TASK_DEADLINE_MINUTES` | `10` | 任务回传时限 | | `ONLINE_WEIGHT` / `TASK_WEIGHT` | `0.7` / `0.3` | 有任务时的表现系数权重 | | `YIELD_TIMEZONE` | `Asia/Shanghai` | 清算触发时区 | | `YIELD_HOUR` / `YIELD_MINUTE` | `0` / `5` | 清算时刻 | | `LICENSE_MONTHS` | `12` | 新节点授权月数 | | `DISABLE_SCHEDULER` | `false` | 设为 `true` 时不启动定时任务 | 修改 `.env` 后执行 `systemctl restart hypernode`。