Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7baadc74b1 | |||
| b220fdc9e9 | |||
| 782d9e05bb | |||
| 5545b76e0b |
@@ -9,7 +9,7 @@ on:
|
|||||||
env:
|
env:
|
||||||
DOCKER_BUILDKIT: "1"
|
DOCKER_BUILDKIT: "1"
|
||||||
PRODUCT_NAME: "xxxigcc"
|
PRODUCT_NAME: "xxxigcc"
|
||||||
PACKAGE_VERSION: "3.4.6-xg1"
|
PACKAGE_VERSION: "3.4.6-xg2"
|
||||||
BUILDX_NO_DEFAULT_ATTESTATIONS: "1"
|
BUILDX_NO_DEFAULT_ATTESTATIONS: "1"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|||||||
191
README.md
Normal file
191
README.md
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
# XXXigCC
|
||||||
|
|
||||||
|
> 禁用捐赠功能的 XMRigCC 修改版本。
|
||||||
|
|
||||||
|
[](LICENSE)
|
||||||
|
[](.gitea/workflows/ci.yaml)
|
||||||
|
|
||||||
|
## 🎯 主要特性
|
||||||
|
|
||||||
|
- 🚫 **零捐赠** - 捐赠等级设为 0,所有捐赠端点已禁用
|
||||||
|
- 🏗️ **多架构支持** - 原生支持 AMD64 和 ARM64 架构
|
||||||
|
- 📦 **多种安装方式** - 提供 Debian 包和通用二进制包
|
||||||
|
- 🐧 **多发行版兼容** - 支持 Ubuntu、Debian 和 Alpine Linux
|
||||||
|
- 🎛️ **集中化管理** - 通过 Web UI 集中管理多个挖矿节点
|
||||||
|
- 🔄 **自动更新** - 通过 Debian 仓库轻松安装和更新
|
||||||
|
|
||||||
|
## 🚀 快速开始
|
||||||
|
|
||||||
|
### 方式一:Debian/Ubuntu(推荐)
|
||||||
|
|
||||||
|
#### Debian 12 (Bookworm)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 下载并添加 GPG 密钥
|
||||||
|
sudo curl https://gitea.bcde.io/api/packages/wangdefa/debian/repository.key \
|
||||||
|
-o /etc/apt/keyrings/gitea-wangdefa.asc
|
||||||
|
|
||||||
|
# 2. 添加软件源
|
||||||
|
echo "deb [signed-by=/etc/apt/keyrings/gitea-wangdefa.asc] https://gitea.bcde.io/api/packages/wangdefa/debian bookworm main" | \
|
||||||
|
sudo tee -a /etc/apt/sources.list.d/wangdefa.list
|
||||||
|
|
||||||
|
# 3. 安装
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install xxxigcc
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Debian 13 (Trixie)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 下载并添加 GPG 密钥
|
||||||
|
sudo curl https://gitea.bcde.io/api/packages/wangdefa/debian/repository.key \
|
||||||
|
-o /etc/apt/keyrings/gitea-wangdefa.asc
|
||||||
|
|
||||||
|
# 2. 添加软件源
|
||||||
|
echo "deb [signed-by=/etc/apt/keyrings/gitea-wangdefa.asc] https://gitea.bcde.io/api/packages/wangdefa/debian trixie main" | \
|
||||||
|
sudo tee -a /etc/apt/sources.list.d/wangdefa.list
|
||||||
|
|
||||||
|
# 3. 安装
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install xxxigcc
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方式二:通用二进制包
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 下载对应架构的包
|
||||||
|
wget https://gitea.bcde.io/releases/download/VERSION/xxxigcc-amd64-ubuntu-VERSION.tar.gz
|
||||||
|
|
||||||
|
# 2. 解压
|
||||||
|
tar -xzf xxxigcc-amd64-ubuntu-VERSION.tar.gz
|
||||||
|
cd xxxigcc
|
||||||
|
|
||||||
|
# 3. 编辑配置文件
|
||||||
|
nano config.json # 用于 Daemon/Miner
|
||||||
|
nano config_cc.json # 用于 Server
|
||||||
|
|
||||||
|
# 4. 运行
|
||||||
|
./xxxigDaemon --config config.json # 挖矿客户端
|
||||||
|
# 或
|
||||||
|
./xxxigServer --config config_cc.json # 控制服务器
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📋 使用说明
|
||||||
|
|
||||||
|
### Debian/Ubuntu 系统服务
|
||||||
|
|
||||||
|
#### 启动服务器(控制中心)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 配置文件位置:/etc/xxxigcc/config_cc.json
|
||||||
|
sudo systemctl enable xxxigcc-server.service
|
||||||
|
sudo systemctl start xxxigcc-server.service
|
||||||
|
|
||||||
|
# 查看状态
|
||||||
|
sudo systemctl status xxxigcc-server.service
|
||||||
|
|
||||||
|
# 查看日志
|
||||||
|
sudo journalctl -u xxxigcc-server -f
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 启动挖矿客户端
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 配置文件位置:/etc/xxxigcc/config.json
|
||||||
|
sudo systemctl enable xxxigcc-daemon.service
|
||||||
|
sudo systemctl start xxxigcc-daemon.service
|
||||||
|
|
||||||
|
# 查看状态
|
||||||
|
sudo systemctl status xxxigcc-daemon.service
|
||||||
|
|
||||||
|
# 查看日志
|
||||||
|
sudo journalctl -u xxxigcc-daemon -f
|
||||||
|
```
|
||||||
|
|
||||||
|
### 访问 Web 管理界面
|
||||||
|
|
||||||
|
服务器启动后,访问:
|
||||||
|
```
|
||||||
|
http://服务器IP:3344
|
||||||
|
```
|
||||||
|
|
||||||
|
默认凭据(请及时修改):
|
||||||
|
- 用户名:admin
|
||||||
|
- 密码:请查看配置文件
|
||||||
|
|
||||||
|
## ⚙️ 配置说明
|
||||||
|
|
||||||
|
### 配置文件位置
|
||||||
|
|
||||||
|
#### Debian/Ubuntu 系统包
|
||||||
|
|
||||||
|
```
|
||||||
|
/etc/xxxigcc/config.json # Daemon/Miner 配置
|
||||||
|
/etc/xxxigcc/config_cc.json # Server 配置
|
||||||
|
/var/log/xxxigcc/ # 日志目录
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 通用二进制包
|
||||||
|
|
||||||
|
```
|
||||||
|
./config.json # Daemon/Miner 配置
|
||||||
|
./config_cc.json # Server 配置
|
||||||
|
```
|
||||||
|
|
||||||
|
### 主要配置项
|
||||||
|
|
||||||
|
#### config.json (Daemon/Miner)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"cc-url": "控制服务器地址",
|
||||||
|
"cc-access-token": "访问令牌",
|
||||||
|
"cc-worker-id": "工作节点ID",
|
||||||
|
"pools": [
|
||||||
|
{
|
||||||
|
"url": "矿池地址",
|
||||||
|
"user": "钱包地址",
|
||||||
|
"pass": "密码"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### config_cc.json (Server)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"cc-port": 3344,
|
||||||
|
"cc-user": "admin",
|
||||||
|
"cc-pass": "管理员密码",
|
||||||
|
"cc-access-token": "访问令牌",
|
||||||
|
"cc-enable-tls": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔄 修改内容
|
||||||
|
|
||||||
|
本项目基于 [Bendr0id/xmrigCC](https://github.com/Bendr0id/xmrigCC) 进行以下修改:
|
||||||
|
|
||||||
|
1. **禁用捐赠**:`kDefaultDonateLevel` 设为 0
|
||||||
|
2. **捐赠端点**:重定向到本地 (127.0.0.1)
|
||||||
|
3. **详细日志**:默认启用详细日志模式
|
||||||
|
4. **项目重命名**:"xmrigcc" → "xxxigcc"
|
||||||
|
|
||||||
|
所有修改通过 [init.sh](init.sh) 在构建过程中自动应用。
|
||||||
|
|
||||||
|
## 📝 许可证
|
||||||
|
|
||||||
|
本项目基于 GPL-3.0 许可证开源。
|
||||||
|
|
||||||
|
- 原始项目:[XMRigCC](https://github.com/Bendr0id/XMRigCC) (GPL-3.0)
|
||||||
|
- 修改内容:详见 [init.sh](init.sh)
|
||||||
|
|
||||||
|
## 🙏 致谢
|
||||||
|
|
||||||
|
- [XMRigCC](https://github.com/Bendr0id/XMRigCC) - 原始项目
|
||||||
|
- [XMRig](https://github.com/xmrig/xmrig) - 核心挖矿引擎
|
||||||
|
|
||||||
|
## ⚠️ 免责声明
|
||||||
|
|
||||||
|
本软件仅供学习和研究使用。使用本软件进行挖矿活动请遵守当地法律法规。作者不对使用本软件造成的任何损失或法律问题负责。
|
||||||
2
debian/build-deb.sh
vendored
2
debian/build-deb.sh
vendored
@@ -4,7 +4,7 @@ set -e
|
|||||||
# 参数检查
|
# 参数检查
|
||||||
if [ $# -ne 3 ]; then
|
if [ $# -ne 3 ]; then
|
||||||
echo "Usage: $0 <ARCH> <VERSION> <TARGZ_FILE>"
|
echo "Usage: $0 <ARCH> <VERSION> <TARGZ_FILE>"
|
||||||
echo "Example: $0 amd64 3.4.6-xg1 xxxigcc-amd64-ubuntu-3.4.6-xg1.tar.gz"
|
echo "Example: $0 amd64 3.4.6-xg2 xxxigcc-amd64-ubuntu-3.4.6-xg2.tar.gz"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ RUN git clone --recursive https://github.com/Bendr0id/xmrigCC.git && \
|
|||||||
|
|
||||||
WORKDIR /xxxigcc
|
WORKDIR /xxxigcc
|
||||||
|
|
||||||
|
RUN rm -rf ./src/base/tools/cryptonote/BlockTemplate.cpp
|
||||||
|
COPY ./templates/BlockTemplate.cpp ./src/base/tools/cryptonote/BlockTemplate.cpp
|
||||||
|
|
||||||
COPY ./init.sh ./init.sh
|
COPY ./init.sh ./init.sh
|
||||||
|
|
||||||
# 根据目标架构优化编译
|
# 根据目标架构优化编译
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ RUN git clone --recursive https://github.com/Bendr0id/xmrigCC.git && \
|
|||||||
|
|
||||||
WORKDIR /xxxigcc
|
WORKDIR /xxxigcc
|
||||||
|
|
||||||
|
RUN rm -rf ./src/base/tools/cryptonote/BlockTemplate.cpp
|
||||||
|
COPY ./templates/BlockTemplate.cpp ./src/base/tools/cryptonote/BlockTemplate.cpp
|
||||||
|
|
||||||
COPY ./init.sh ./init.sh
|
COPY ./init.sh ./init.sh
|
||||||
|
|
||||||
# 根据目标架构设置编译环境和参数
|
# 根据目标架构设置编译环境和参数
|
||||||
|
|||||||
255
script/README.md
Normal file
255
script/README.md
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
# XXXigCC 安装脚本
|
||||||
|
|
||||||
|
本目录包含 XXXigCC 的安装和卸载脚本。
|
||||||
|
|
||||||
|
## 脚本列表
|
||||||
|
|
||||||
|
### 1. install.sh - 通用安装脚本
|
||||||
|
从 Gitea Generic Package Registry 下载 tar.gz 包并安装。
|
||||||
|
|
||||||
|
**支持系统:**
|
||||||
|
- Alpine Linux (OpenRC)
|
||||||
|
- Ubuntu/Debian (systemd)
|
||||||
|
|
||||||
|
**使用方法:**
|
||||||
|
```bash
|
||||||
|
# 基本安装
|
||||||
|
sudo ./install.sh -o pool.example.com:3333 -w YOUR_WALLET_ADDRESS
|
||||||
|
|
||||||
|
# 指定版本和线程数
|
||||||
|
sudo ./install.sh -v 3.4.6-xg1 -t 4 -o pool.example.com:3333 -w YOUR_WALLET
|
||||||
|
|
||||||
|
# 启用高级功能
|
||||||
|
sudo ./install.sh -o pool.example.com:3333 -w YOUR_WALLET \
|
||||||
|
--1gb-pages --tls --keepalive \
|
||||||
|
--cc --cc-url http://server:3344 --cc-token YOUR_TOKEN
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. install.deb.sh - DEB 包安装脚本
|
||||||
|
通过 APT 仓库直接安装。
|
||||||
|
|
||||||
|
**支持系统:**
|
||||||
|
- Ubuntu/Debian (systemd)
|
||||||
|
|
||||||
|
**使用方法:**
|
||||||
|
```bash
|
||||||
|
# 基本安装
|
||||||
|
sudo ./install.deb.sh -o pool.example.com:3333 -w YOUR_WALLET_ADDRESS
|
||||||
|
|
||||||
|
# 指定版本
|
||||||
|
sudo ./install.deb.sh -v 3.4.6-xg1 -o pool.example.com:3333 -w YOUR_WALLET
|
||||||
|
|
||||||
|
# 查看可用版本
|
||||||
|
apt-cache policy xxxigcc
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. uninstall.sh - 卸载脚本
|
||||||
|
通用卸载脚本,自动检测安装方式。
|
||||||
|
|
||||||
|
**使用方法:**
|
||||||
|
```bash
|
||||||
|
# 交互式卸载(推荐)
|
||||||
|
sudo ./uninstall.sh
|
||||||
|
|
||||||
|
# 直接卸载,不确认
|
||||||
|
sudo ./uninstall.sh -y
|
||||||
|
|
||||||
|
# 完全清除(包括配置文件和日志)
|
||||||
|
sudo ./uninstall.sh --purge -y
|
||||||
|
```
|
||||||
|
|
||||||
|
## 命令行参数
|
||||||
|
|
||||||
|
### 通用参数(两种安装脚本都支持)
|
||||||
|
|
||||||
|
| 参数 | 说明 | 默认值 |
|
||||||
|
|------|------|--------|
|
||||||
|
| `-v, --version` | 版本号 | latest |
|
||||||
|
| `-t, --threads` | 线程数 | 自动 (CPU 核心数) |
|
||||||
|
| `-a, --algo` | 算法 | rx/0 |
|
||||||
|
| `-o, --pool` | 矿池地址 | **必需** |
|
||||||
|
| `-w, --wallet` | 钱包地址 | 自动生成 |
|
||||||
|
| `-p, --password` | 矿池密码 | 自动生成 |
|
||||||
|
| `--1gb-pages` | 启用 1GB 大页 | false |
|
||||||
|
| `--tls` | 启用 TLS | false |
|
||||||
|
| `--keepalive` | 启用 KeepAlive | false |
|
||||||
|
| `--daemon` | 启用 SOLO 挖矿 | false |
|
||||||
|
| `--nicehash` | 启用 NiceHash 模式 | **true** |
|
||||||
|
| `--verbose` | 启用详细输出 | **true** |
|
||||||
|
| `--submit-to-origin` | 提交到原始矿池 | false |
|
||||||
|
| `--self-select` | 自选矿池地址 | - |
|
||||||
|
| `--cc` | 启用 CC | false |
|
||||||
|
| `--cc-url` | CC 服务器地址 | - |
|
||||||
|
| `--cc-work-id` | CC 工作 ID | 自动生成 |
|
||||||
|
| `--cc-token` | CC 访问令牌 | - |
|
||||||
|
| `--cc-tls` | 启用 CC TLS | false |
|
||||||
|
|
||||||
|
## 安装路径
|
||||||
|
|
||||||
|
### tar.gz 安装
|
||||||
|
```
|
||||||
|
/etc/miner/xxxigcc/
|
||||||
|
├── config.json # 配置文件
|
||||||
|
├── xxxigDaemon # 守护进程
|
||||||
|
├── xxxigMiner # 挖矿程序
|
||||||
|
└── xxxigcc.log # 日志文件
|
||||||
|
```
|
||||||
|
|
||||||
|
**服务文件:**
|
||||||
|
- Alpine: `/etc/init.d/xxxigcc`
|
||||||
|
- Ubuntu/Debian: `/etc/systemd/system/xxxigcc.service`
|
||||||
|
|
||||||
|
### DEB 包安装
|
||||||
|
```
|
||||||
|
/etc/xxxigcc/
|
||||||
|
└── config.json # 配置文件
|
||||||
|
|
||||||
|
/var/log/xxxigcc/ # 日志目录
|
||||||
|
|
||||||
|
/opt/xxxigcc/
|
||||||
|
├── xxxigDaemon # 守护进程
|
||||||
|
├── xxxigMiner # 挖矿程序
|
||||||
|
└── xxxigServer # 控制服务器
|
||||||
|
```
|
||||||
|
|
||||||
|
**服务文件:**
|
||||||
|
- `/etc/systemd/system/xxxigcc-daemon.service`
|
||||||
|
- `/etc/systemd/system/xxxigcc-server.service`
|
||||||
|
|
||||||
|
## 服务管理
|
||||||
|
|
||||||
|
### Alpine Linux
|
||||||
|
```bash
|
||||||
|
# 查看状态
|
||||||
|
rc-service xxxigcc status
|
||||||
|
|
||||||
|
# 启动/停止/重启
|
||||||
|
rc-service xxxigcc start
|
||||||
|
rc-service xxxigcc stop
|
||||||
|
rc-service xxxigcc restart
|
||||||
|
|
||||||
|
# 查看日志
|
||||||
|
tail -f /etc/miner/xxxigcc/xxxigcc.log
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ubuntu/Debian
|
||||||
|
|
||||||
|
#### tar.gz 安装
|
||||||
|
```bash
|
||||||
|
# 查看状态
|
||||||
|
systemctl status xxxigcc
|
||||||
|
|
||||||
|
# 启动/停止/重启
|
||||||
|
systemctl start xxxigcc
|
||||||
|
systemctl stop xxxigcc
|
||||||
|
systemctl restart xxxigcc
|
||||||
|
|
||||||
|
# 查看日志
|
||||||
|
journalctl -u xxxigcc -f
|
||||||
|
```
|
||||||
|
|
||||||
|
#### DEB 包安装
|
||||||
|
```bash
|
||||||
|
# 查看状态
|
||||||
|
systemctl status xxxigcc-daemon
|
||||||
|
|
||||||
|
# 启动/停止/重启
|
||||||
|
systemctl start xxxigcc-daemon
|
||||||
|
systemctl stop xxxigcc-daemon
|
||||||
|
systemctl restart xxxigcc-daemon
|
||||||
|
|
||||||
|
# 查看日志
|
||||||
|
journalctl -u xxxigcc-daemon -f
|
||||||
|
```
|
||||||
|
|
||||||
|
## 配置文件
|
||||||
|
|
||||||
|
配置文件为 JSON 格式,位于:
|
||||||
|
- tar.gz: `/etc/miner/xxxigcc/config.json`
|
||||||
|
- DEB: `/etc/xxxigcc/config.json`
|
||||||
|
|
||||||
|
修改配置后需要重启服务:
|
||||||
|
```bash
|
||||||
|
# Alpine
|
||||||
|
rc-service xxxigcc restart
|
||||||
|
|
||||||
|
# Ubuntu/Debian (tar.gz)
|
||||||
|
systemctl restart xxxigcc
|
||||||
|
|
||||||
|
# Ubuntu/Debian (DEB)
|
||||||
|
systemctl restart xxxigcc-daemon
|
||||||
|
```
|
||||||
|
|
||||||
|
## 升级版本
|
||||||
|
|
||||||
|
### tar.gz 安装
|
||||||
|
重新运行安装脚本,指定新版本:
|
||||||
|
```bash
|
||||||
|
sudo ./install.sh -v 3.4.7-xg1 -o pool.example.com:3333 -w YOUR_WALLET
|
||||||
|
```
|
||||||
|
|
||||||
|
### DEB 包安装
|
||||||
|
使用 APT 升级:
|
||||||
|
```bash
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install xxxigcc
|
||||||
|
```
|
||||||
|
|
||||||
|
## 故障排查
|
||||||
|
|
||||||
|
### 检查服务状态
|
||||||
|
```bash
|
||||||
|
# Alpine
|
||||||
|
rc-service xxxigcc status
|
||||||
|
|
||||||
|
# Ubuntu/Debian
|
||||||
|
systemctl status xxxigcc # 或 xxxigcc-daemon
|
||||||
|
```
|
||||||
|
|
||||||
|
### 查看日志
|
||||||
|
```bash
|
||||||
|
# Alpine / tar.gz
|
||||||
|
tail -f /etc/miner/xxxigcc/xxxigcc.log
|
||||||
|
|
||||||
|
# Ubuntu/Debian (tar.gz)
|
||||||
|
journalctl -u xxxigcc -f
|
||||||
|
|
||||||
|
# Ubuntu/Debian (DEB)
|
||||||
|
journalctl -u xxxigcc-daemon -f
|
||||||
|
```
|
||||||
|
|
||||||
|
### 手动测试
|
||||||
|
```bash
|
||||||
|
# tar.gz 安装
|
||||||
|
/etc/miner/xxxigcc/xxxigDaemon -c /etc/miner/xxxigcc/config.json
|
||||||
|
|
||||||
|
# DEB 包安装
|
||||||
|
xxxigDaemon -c /etc/xxxigcc/config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### 常见问题
|
||||||
|
|
||||||
|
**问题: 下载失败**
|
||||||
|
```bash
|
||||||
|
# 检查网络连接
|
||||||
|
curl -I https://gitea.bcde.io
|
||||||
|
|
||||||
|
# 手动下载测试
|
||||||
|
curl -O https://gitea.bcde.io/api/packages/wangdefa/generic/xxxigcc/3.4.6-xg1/xxxigcc-amd64-ubuntu-3.4.6-xg1.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
**问题: 服务无法启动**
|
||||||
|
```bash
|
||||||
|
# 检查配置文件
|
||||||
|
cat /etc/miner/xxxigcc/config.json | jq .
|
||||||
|
|
||||||
|
# 检查权限
|
||||||
|
ls -la /etc/miner/xxxigcc/
|
||||||
|
```
|
||||||
|
|
||||||
|
**问题: APT 更新失败 (DEB)**
|
||||||
|
```bash
|
||||||
|
# 清理并重新添加源
|
||||||
|
sudo rm /etc/apt/sources.list.d/xxxigcc.list
|
||||||
|
sudo ./install_deb.sh -o pool.example.com:3333 -w YOUR_WALLET
|
||||||
|
```
|
||||||
273
script/install.deb.sh
Executable file
273
script/install.deb.sh
Executable file
@@ -0,0 +1,273 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# XXXigCC 安装脚本 - DEB 版本
|
||||||
|
# 通过 APT 从 Gitea Generic Package Registry 安装 XXXigCC
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
declare -r BLUE="\033[0;34m"
|
||||||
|
declare -r RED="\033[0;31m"
|
||||||
|
declare -r GREEN="\033[0;32m"
|
||||||
|
declare -r YELLOW="\033[0;33m"
|
||||||
|
declare -r RESET="\033[0m"
|
||||||
|
|
||||||
|
# 基本配置
|
||||||
|
CONFIG_DIR="/etc/xxxigcc"
|
||||||
|
LOG_DIR="/var/log/xxxigcc"
|
||||||
|
CONFIG_FILE="$CONFIG_DIR/config.json"
|
||||||
|
|
||||||
|
# Gitea 配置
|
||||||
|
GITEA_SERVER="gitea.bcde.io"
|
||||||
|
GITEA_OWNER="wangdefa"
|
||||||
|
|
||||||
|
# 默认参数
|
||||||
|
DEFAULT_VERSION="latest"
|
||||||
|
DEFAULT_THREADS=0
|
||||||
|
DEFAULT_POOL_ALGO="rx/0"
|
||||||
|
DEFAULT_POOL_TLS="false"
|
||||||
|
DEFAULT_POOL_KEEPALIVE="false"
|
||||||
|
DEFAULT_POOL_DAEMON="false"
|
||||||
|
DEFAULT_POOL_SUBMIT_TO_ORIGIN="false"
|
||||||
|
DEFAULT_POOL_NICEHASH="true"
|
||||||
|
DEFAULT_ONE_GB_PAGES="false"
|
||||||
|
DEFAULT_VERBOSE="true"
|
||||||
|
DEFAULT_CC_ENABLED="false"
|
||||||
|
DEFAULT_CC_TLS="false"
|
||||||
|
|
||||||
|
# 辅助函数
|
||||||
|
log() { echo -e "${1}${2}${RESET}"; }
|
||||||
|
error() { log "$RED" "错误: $1"; exit 1; }
|
||||||
|
|
||||||
|
check_os() {
|
||||||
|
grep -qiE 'debian|ubuntu' /etc/os-release || error "仅支持 Debian/Ubuntu 系统"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_arch() {
|
||||||
|
case $(uname -m) in
|
||||||
|
x86_64) echo "amd64" ;;
|
||||||
|
aarch64) echo "arm64" ;;
|
||||||
|
*) error "不支持的架构: $(uname -m)" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# 添加 APT 源并更新
|
||||||
|
add_apt_repository() {
|
||||||
|
echo "deb [trusted=yes] https://${GITEA_SERVER}/api/packages/${GITEA_OWNER}/debian bookworm main" \
|
||||||
|
>/etc/apt/sources.list.d/xxxigcc.list
|
||||||
|
apt-get update -qq
|
||||||
|
}
|
||||||
|
|
||||||
|
# 卸载旧版本
|
||||||
|
uninstall_xxxigcc() {
|
||||||
|
systemctl stop xxxigcc-daemon xxxigcc-server 2>/dev/null || true
|
||||||
|
systemctl disable xxxigcc-daemon xxxigcc-server 2>/dev/null || true
|
||||||
|
apt-get remove -y xxxigcc 2>/dev/null || true
|
||||||
|
rm -rf "$CONFIG_DIR" "$LOG_DIR" /etc/apt/sources.list.d/xxxigcc.list
|
||||||
|
systemctl daemon-reload 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
# 安装并启动服务
|
||||||
|
install_and_start() {
|
||||||
|
log "$BLUE" "安装 XXXigCC $version..."
|
||||||
|
if [[ "$version" == "latest" ]]; then
|
||||||
|
apt-get install -y xxxigcc
|
||||||
|
else
|
||||||
|
apt-get install -y xxxigcc="$version"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "$BLUE" "启动服务..."
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable --now xxxigcc-daemon.service
|
||||||
|
log "$GREEN" "安装完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 配置 CPU 亲和性
|
||||||
|
configure_cpu_rx() {
|
||||||
|
local cpu_cores=$(nproc)
|
||||||
|
local rx_array="" step=1
|
||||||
|
|
||||||
|
[[ "$threads" -le $((cpu_cores / 2)) ]] && step=2
|
||||||
|
|
||||||
|
for ((i = 0; i < threads; i++)); do
|
||||||
|
[[ $i -gt 0 ]] && rx_array+=", "
|
||||||
|
rx_array+="$((i * step))"
|
||||||
|
done
|
||||||
|
|
||||||
|
local field="rx"
|
||||||
|
[[ "$pool_algo" == "panthera" ]] && field="panthera"
|
||||||
|
|
||||||
|
jq ".cpu.$field = [ $rx_array ]" "$CONFIG_FILE" >"$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 更新配置文件
|
||||||
|
replace_config() {
|
||||||
|
[[ ! -f "$CONFIG_FILE" ]] && error "配置文件缺失"
|
||||||
|
|
||||||
|
local jq_cmd=".\"log-file\" = \"\"
|
||||||
|
| .\"donate-level\" = 0
|
||||||
|
| .\"donate-over-proxy\" = 0
|
||||||
|
| .pools[0].algo = \"$pool_algo\"
|
||||||
|
| .pools[0].url = \"$pool_address\"
|
||||||
|
| .pools[0].user = \"$wallet_address\"
|
||||||
|
| .pools[0].pass = \"$pool_password\"
|
||||||
|
| .pools[0].tls = $pool_tls
|
||||||
|
| .pools[0].nicehash = $pool_nicehash
|
||||||
|
| .\"verbose\" = $verbose"
|
||||||
|
|
||||||
|
[[ "$one_gb_pages" == "true" ]] && jq_cmd+=" | .randomx.\"1gb-pages\" = true"
|
||||||
|
[[ "$pool_keepalive" == "true" ]] && jq_cmd+=" | .pools[0].keepalive = true"
|
||||||
|
[[ -n "$pool_tls_fingerprint" ]] && jq_cmd+=" | .pools[0].\"tls-fingerprint\" = \"$pool_tls_fingerprint\""
|
||||||
|
[[ "$pool_daemon" == "true" ]] && jq_cmd+=" | .pools[0].daemon = true"
|
||||||
|
|
||||||
|
if [[ "$pool_submit_to_origin" == "true" ]]; then
|
||||||
|
jq_cmd+=" | .pools[0].\"submit-to-origin\" = true | .pools[0].\"self-select\" = \"$pool_self_select\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$cc_enabled" == "true" ]]; then
|
||||||
|
jq_cmd+=" | .\"cc-client\".enabled = true
|
||||||
|
| .\"cc-client\".servers[0].url = \"$cc_url\"
|
||||||
|
| .\"cc-client\".servers[0].\"access-token\" = \"$cc_token\"
|
||||||
|
| .\"cc-client\".servers[0].\"use-tls\" = $cc_tls
|
||||||
|
| .\"cc-client\".\"worker-id\" = \"$cc_work_id\""
|
||||||
|
else
|
||||||
|
jq_cmd+=" | .\"cc-client\".enabled = false"
|
||||||
|
fi
|
||||||
|
|
||||||
|
jq "$jq_cmd" "$CONFIG_FILE" >"$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
|
||||||
|
configure_cpu_rx
|
||||||
|
}
|
||||||
|
|
||||||
|
show_usage() {
|
||||||
|
cat <<EOF
|
||||||
|
用法: $0 [选项]
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-v, --version <版本> XXXigCC 版本 (默认: $DEFAULT_VERSION)
|
||||||
|
-t, --threads <数字> 线程数 (默认: 自动)
|
||||||
|
-a, --algo <算法> 矿池算法 (默认: $DEFAULT_POOL_ALGO)
|
||||||
|
-o, --pool <地址> 矿池地址 (必需)
|
||||||
|
-w, --wallet <地址> 钱包地址
|
||||||
|
-p, --password <密码> 矿池密码 (默认自动生成)
|
||||||
|
--1gb-pages 启用 1GB 大页
|
||||||
|
--tls 启用 TLS
|
||||||
|
--keepalive 启用 KeepAlive
|
||||||
|
--daemon 启用 SOLO 挖矿
|
||||||
|
--nicehash 启用 NiceHash 模式 (默认: 启用)
|
||||||
|
--submit-to-origin 提交到原始矿池
|
||||||
|
--self-select <地址> 自选矿池地址
|
||||||
|
--verbose 启用详细输出 (默认: 启用)
|
||||||
|
--cc 启用 CC
|
||||||
|
--cc-url <地址> CC 服务器地址
|
||||||
|
--cc-work-id <ID> CC 工作 ID
|
||||||
|
--cc-token <令牌> CC 访问令牌
|
||||||
|
--cc-tls 启用 CC TLS
|
||||||
|
-h, --help 显示帮助信息
|
||||||
|
|
||||||
|
示例:
|
||||||
|
$0 -o pool.example.com:3333 -w YOUR_WALLET_ADDRESS
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_args() {
|
||||||
|
version=$DEFAULT_VERSION
|
||||||
|
threads=$DEFAULT_THREADS
|
||||||
|
pool_algo=$DEFAULT_POOL_ALGO
|
||||||
|
pool_tls=$DEFAULT_POOL_TLS
|
||||||
|
pool_keepalive=$DEFAULT_POOL_KEEPALIVE
|
||||||
|
pool_submit_to_origin=$DEFAULT_POOL_SUBMIT_TO_ORIGIN
|
||||||
|
pool_daemon=$DEFAULT_POOL_DAEMON
|
||||||
|
pool_nicehash=$DEFAULT_POOL_NICEHASH
|
||||||
|
pool_self_select=""
|
||||||
|
pool_address=""
|
||||||
|
wallet_address=""
|
||||||
|
pool_password=""
|
||||||
|
pool_tls_fingerprint=""
|
||||||
|
verbose=$DEFAULT_VERBOSE
|
||||||
|
cc_enabled=$DEFAULT_CC_ENABLED
|
||||||
|
cc_url=""
|
||||||
|
cc_work_id=""
|
||||||
|
cc_token=""
|
||||||
|
cc_tls=$DEFAULT_CC_TLS
|
||||||
|
one_gb_pages=$DEFAULT_ONE_GB_PAGES
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
-v | --version) version="$2"; shift 2 ;;
|
||||||
|
-t | --threads) threads="$2"; shift 2 ;;
|
||||||
|
-a | --algo) pool_algo="$2"; shift 2 ;;
|
||||||
|
-o | --pool) pool_address="$2"; shift 2 ;;
|
||||||
|
-w | --wallet) wallet_address="$2"; shift 2 ;;
|
||||||
|
-p | --password) pool_password="$2"; shift 2 ;;
|
||||||
|
--1gb-pages) one_gb_pages="true"; shift ;;
|
||||||
|
--cc-url) cc_url="$2"; shift 2 ;;
|
||||||
|
--cc-work-id) cc_work_id="$2"; shift 2 ;;
|
||||||
|
--cc-token) cc_token="$2"; shift 2 ;;
|
||||||
|
--tls-fingerprint) pool_tls_fingerprint="$2"; shift 2 ;;
|
||||||
|
--tls) pool_tls="true"; shift ;;
|
||||||
|
--keepalive) pool_keepalive="true"; shift ;;
|
||||||
|
--daemon) pool_daemon="true"; shift ;;
|
||||||
|
--nicehash) pool_nicehash="true"; shift ;;
|
||||||
|
--submit-to-origin) pool_submit_to_origin="true"; shift ;;
|
||||||
|
--self-select) pool_self_select="$2"; shift 2 ;;
|
||||||
|
--verbose) verbose="true"; shift ;;
|
||||||
|
--cc) cc_enabled="true"; shift ;;
|
||||||
|
--cc-tls) cc_tls="true"; shift ;;
|
||||||
|
-h | --help) show_usage ;;
|
||||||
|
*) error "无效选项: $1" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# 验证必需参数
|
||||||
|
[[ -z "$pool_address" ]] && error "矿池地址不能为空"
|
||||||
|
[[ ! "$threads" =~ ^[0-9]+$ ]] && error "无效线程数"
|
||||||
|
[[ "$pool_submit_to_origin" == "true" && -z "$pool_self_select" ]] && \
|
||||||
|
error "启用 submit_to_origin 必须设置 self_select"
|
||||||
|
|
||||||
|
# 处理默认值
|
||||||
|
if [[ -z "$pool_password" ]]; then
|
||||||
|
local ip=$(curl -4s --retry 3 --connect-timeout 10 ifconfig.me 2>/dev/null || echo "0.0.0.0")
|
||||||
|
local random_str=$(tr -dc '0-9a-zA-Z' </dev/urandom | head -c 5)
|
||||||
|
pool_password=$(echo "$ip" | awk -F. '{print $3"_"$4}')"_$random_str"
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ -z "$cc_work_id" ]] && cc_work_id="$(get_arch)_$pool_password"
|
||||||
|
[[ -z "$wallet_address" ]] && wallet_address="empty_wallet_$(date +%s)"
|
||||||
|
|
||||||
|
if [[ "$threads" -le 0 ]]; then
|
||||||
|
threads=$(nproc)
|
||||||
|
elif [[ "$threads" -gt $(nproc) ]]; then
|
||||||
|
threads=$(nproc)
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
parse_args "$@"
|
||||||
|
check_os
|
||||||
|
|
||||||
|
# 检查并安装依赖
|
||||||
|
command -v curl &>/dev/null || apt-get install -y curl
|
||||||
|
command -v jq &>/dev/null || apt-get install -y jq
|
||||||
|
|
||||||
|
log "$BLUE" "配置信息:"
|
||||||
|
echo " 版本: $version"
|
||||||
|
echo " 架构: $(get_arch)"
|
||||||
|
echo " 线程: $threads"
|
||||||
|
echo " 算法: $pool_algo"
|
||||||
|
echo " 矿池: $pool_address"
|
||||||
|
echo " 钱包: $wallet_address"
|
||||||
|
|
||||||
|
uninstall_xxxigcc
|
||||||
|
add_apt_repository
|
||||||
|
install_and_start
|
||||||
|
replace_config
|
||||||
|
systemctl restart xxxigcc-daemon.service
|
||||||
|
|
||||||
|
echo "管理命令:"
|
||||||
|
echo " systemctl status xxxigcc-daemon"
|
||||||
|
echo " journalctl -u xxxigcc-daemon -f"
|
||||||
|
echo " systemctl restart xxxigcc-daemon"
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
342
script/install.sh
Normal file
342
script/install.sh
Normal file
@@ -0,0 +1,342 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# XXXigCC 安装脚本 - Gitea 版本
|
||||||
|
# 从 Gitea Generic Package Registry 下载并安装 XXXigCC
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
declare -r BLUE="\033[0;34m"
|
||||||
|
declare -r RED="\033[0;31m"
|
||||||
|
declare -r GREEN="\033[0;32m"
|
||||||
|
declare -r YELLOW="\033[0;33m"
|
||||||
|
declare -r RESET="\033[0m"
|
||||||
|
|
||||||
|
# 基本配置
|
||||||
|
INSTALL_DIR="/etc/miner/xxxigcc"
|
||||||
|
CONFIG_FILE="$INSTALL_DIR/config.json"
|
||||||
|
LOG_FILE="$INSTALL_DIR/xxxigcc.log"
|
||||||
|
|
||||||
|
# Gitea 配置
|
||||||
|
GITEA_SERVER="gitea.bcde.io"
|
||||||
|
GITEA_OWNER="wangdefa"
|
||||||
|
GITEA_REPO="xxxigcc"
|
||||||
|
PACKAGE_NAME="xxxigcc"
|
||||||
|
|
||||||
|
# 默认参数
|
||||||
|
DEFAULT_VERSION="latest"
|
||||||
|
DEFAULT_THREADS=0
|
||||||
|
DEFAULT_POOL_ALGO="rx/0"
|
||||||
|
DEFAULT_POOL_TLS="false"
|
||||||
|
DEFAULT_POOL_KEEPALIVE="false"
|
||||||
|
DEFAULT_POOL_DAEMON="false"
|
||||||
|
DEFAULT_POOL_SUBMIT_TO_ORIGIN="false"
|
||||||
|
DEFAULT_POOL_NICEHASH="true"
|
||||||
|
DEFAULT_ONE_GB_PAGES="false"
|
||||||
|
DEFAULT_VERBOSE="true"
|
||||||
|
DEFAULT_CC_ENABLED="false"
|
||||||
|
DEFAULT_CC_TLS="false"
|
||||||
|
|
||||||
|
# 辅助函数
|
||||||
|
log() { echo -e "${1}${2}${RESET}"; }
|
||||||
|
error() { log "$RED" "错误: $1"; exit 1; }
|
||||||
|
|
||||||
|
|
||||||
|
get_arch() {
|
||||||
|
case $(uname -m) in
|
||||||
|
x86_64) echo "amd64" ;;
|
||||||
|
aarch64) echo "arm64" ;;
|
||||||
|
*) error "不支持的架构: $(uname -m)" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
get_os() {
|
||||||
|
grep -qi alpine /etc/os-release && echo "alpine" && return
|
||||||
|
grep -qiE 'debian|ubuntu' /etc/os-release && echo "ubuntu" && return
|
||||||
|
error "不支持的操作系统"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_gitea_latest_version() {
|
||||||
|
local version
|
||||||
|
version=$(curl -s "https://${GITEA_SERVER}/api/v1/repos/${GITEA_OWNER}/${GITEA_REPO}/releases" | jq -r '.[0].tag_name')
|
||||||
|
[[ -z "$version" || "$version" == "null" ]] && error "获取版本失败"
|
||||||
|
echo "$version"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 卸载旧版本
|
||||||
|
uninstall_xxxigcc() {
|
||||||
|
if [[ $os_type == "alpine" ]]; then
|
||||||
|
rc-service xxxigcc stop 2>/dev/null || true
|
||||||
|
rc-update del xxxigcc default 2>/dev/null || true
|
||||||
|
rm -rf "$INSTALL_DIR" /etc/init.d/xxxigcc
|
||||||
|
else
|
||||||
|
systemctl stop xxxigcc 2>/dev/null || true
|
||||||
|
systemctl disable xxxigcc 2>/dev/null || true
|
||||||
|
rm -rf "$INSTALL_DIR" /etc/systemd/system/xxxigcc.service
|
||||||
|
systemctl daemon-reload 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 安装软件包
|
||||||
|
install_xxxigcc() {
|
||||||
|
local temp_dir=$(mktemp -d)
|
||||||
|
trap "rm -rf '$temp_dir'" EXIT
|
||||||
|
|
||||||
|
log "$BLUE" "下载 XXXigCC $version..."
|
||||||
|
curl -fsSL -o "$temp_dir/xxxigcc.tar.gz" "$download_url" || error "下载失败"
|
||||||
|
|
||||||
|
mkdir -p "$INSTALL_DIR"
|
||||||
|
tar -xzf "$temp_dir/xxxigcc.tar.gz" -C "$INSTALL_DIR" --strip-components=1 || error "解压失败"
|
||||||
|
chmod +x "$INSTALL_DIR/xxxigDaemon" "$INSTALL_DIR/xxxigMiner"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 配置 CPU 亲和性
|
||||||
|
configure_cpu_rx() {
|
||||||
|
local cpu_cores=$(nproc)
|
||||||
|
local rx_array="" step=1
|
||||||
|
|
||||||
|
[[ "$threads" -le $((cpu_cores / 2)) ]] && step=2
|
||||||
|
|
||||||
|
for ((i = 0; i < threads; i++)); do
|
||||||
|
[[ $i -gt 0 ]] && rx_array+=", "
|
||||||
|
rx_array+="$((i * step))"
|
||||||
|
done
|
||||||
|
|
||||||
|
local field="rx"
|
||||||
|
[[ "$pool_algo" == "panthera" ]] && field="panthera"
|
||||||
|
|
||||||
|
jq ".cpu.$field = [ $rx_array ]" "$CONFIG_FILE" >"$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 更新配置文件
|
||||||
|
replace_config() {
|
||||||
|
[[ ! -f "$CONFIG_FILE" ]] && error "配置文件缺失"
|
||||||
|
|
||||||
|
local jq_cmd=".\"log-file\" = \"$LOG_FILE\"
|
||||||
|
| .\"donate-level\" = 0
|
||||||
|
| .\"donate-over-proxy\" = 0
|
||||||
|
| .pools[0].algo = \"$pool_algo\"
|
||||||
|
| .pools[0].url = \"$pool_address\"
|
||||||
|
| .pools[0].user = \"$wallet_address\"
|
||||||
|
| .pools[0].pass = \"$pool_password\"
|
||||||
|
| .pools[0].tls = $pool_tls
|
||||||
|
| .pools[0].nicehash = $pool_nicehash
|
||||||
|
| .\"verbose\" = $verbose"
|
||||||
|
|
||||||
|
[[ "$one_gb_pages" == "true" ]] && jq_cmd+=" | .randomx.\"1gb-pages\" = true"
|
||||||
|
[[ "$pool_keepalive" == "true" ]] && jq_cmd+=" | .pools[0].keepalive = true"
|
||||||
|
[[ -n "$pool_tls_fingerprint" ]] && jq_cmd+=" | .pools[0].\"tls-fingerprint\" = \"$pool_tls_fingerprint\""
|
||||||
|
[[ "$pool_daemon" == "true" ]] && jq_cmd+=" | .pools[0].daemon = true"
|
||||||
|
|
||||||
|
if [[ "$pool_submit_to_origin" == "true" ]]; then
|
||||||
|
jq_cmd+=" | .pools[0].\"submit-to-origin\" = true | .pools[0].\"self-select\" = \"$pool_self_select\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$cc_enabled" == "true" ]]; then
|
||||||
|
jq_cmd+=" | .\"cc-client\".enabled = true
|
||||||
|
| .\"cc-client\".servers[0].url = \"$cc_url\"
|
||||||
|
| .\"cc-client\".servers[0].\"access-token\" = \"$cc_token\"
|
||||||
|
| .\"cc-client\".servers[0].\"use-tls\" = $cc_tls
|
||||||
|
| .\"cc-client\".\"worker-id\" = \"$cc_work_id\""
|
||||||
|
else
|
||||||
|
jq_cmd+=" | .\"cc-client\".enabled = false"
|
||||||
|
fi
|
||||||
|
|
||||||
|
jq "$jq_cmd" "$CONFIG_FILE" >"$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
|
||||||
|
configure_cpu_rx
|
||||||
|
}
|
||||||
|
|
||||||
|
# 创建并启动服务
|
||||||
|
create_service() {
|
||||||
|
if [[ "$os_type" == "alpine" ]]; then
|
||||||
|
cat >/etc/init.d/xxxigcc <<'EOF'
|
||||||
|
#!/sbin/openrc-run
|
||||||
|
|
||||||
|
name="XXXigCC Miner"
|
||||||
|
description="XXXigCC Miner Service"
|
||||||
|
command="/etc/miner/xxxigcc/xxxigDaemon"
|
||||||
|
command_args="-c /etc/miner/xxxigcc/config.json"
|
||||||
|
pidfile="/run/${RC_SVCNAME}.pid"
|
||||||
|
command_background="yes"
|
||||||
|
rc_ulimit="-n 65535"
|
||||||
|
|
||||||
|
depend() {
|
||||||
|
need net
|
||||||
|
after network
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
chmod +x /etc/init.d/xxxigcc
|
||||||
|
rc-update add xxxigcc default
|
||||||
|
rc-service xxxigcc start
|
||||||
|
else
|
||||||
|
cat >/etc/systemd/system/xxxigcc.service <<EOF
|
||||||
|
[Unit]
|
||||||
|
Description=XXXigCC Miner
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=root
|
||||||
|
ExecStart=$INSTALL_DIR/xxxigDaemon -c $CONFIG_FILE
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
|
LimitNOFILE=65535
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable --now xxxigcc.service
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
show_usage() {
|
||||||
|
cat <<EOF
|
||||||
|
用法: $0 [选项]
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-v, --version <版本> XXXigCC 版本 (默认: $DEFAULT_VERSION)
|
||||||
|
-t, --threads <数字> 线程数 (默认: 自动)
|
||||||
|
-a, --algo <算法> 矿池算法 (默认: $DEFAULT_POOL_ALGO)
|
||||||
|
-o, --pool <地址> 矿池地址 (必需)
|
||||||
|
-w, --wallet <地址> 钱包地址
|
||||||
|
-p, --password <密码> 矿池密码 (默认自动生成)
|
||||||
|
--1gb-pages 启用 1GB 大页
|
||||||
|
--tls 启用 TLS
|
||||||
|
--keepalive 启用 KeepAlive
|
||||||
|
--daemon 启用 SOLO 挖矿
|
||||||
|
--nicehash 启用 NiceHash 模式 (默认: 启用)
|
||||||
|
--submit-to-origin 提交到原始矿池
|
||||||
|
--self-select <地址> 自选矿池地址
|
||||||
|
--verbose 启用详细输出 (默认: 启用)
|
||||||
|
--cc 启用 CC
|
||||||
|
--cc-url <地址> CC 服务器地址
|
||||||
|
--cc-work-id <ID> CC 工作 ID
|
||||||
|
--cc-token <令牌> CC 访问令牌
|
||||||
|
--cc-tls 启用 CC TLS
|
||||||
|
-h, --help 显示帮助信息
|
||||||
|
|
||||||
|
示例:
|
||||||
|
$0 -o pool.example.com:3333 -w YOUR_WALLET_ADDRESS
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_args() {
|
||||||
|
version=$DEFAULT_VERSION
|
||||||
|
threads=$DEFAULT_THREADS
|
||||||
|
pool_algo=$DEFAULT_POOL_ALGO
|
||||||
|
pool_tls=$DEFAULT_POOL_TLS
|
||||||
|
pool_keepalive=$DEFAULT_POOL_KEEPALIVE
|
||||||
|
pool_submit_to_origin=$DEFAULT_POOL_SUBMIT_TO_ORIGIN
|
||||||
|
pool_daemon=$DEFAULT_POOL_DAEMON
|
||||||
|
pool_nicehash=$DEFAULT_POOL_NICEHASH
|
||||||
|
pool_self_select=""
|
||||||
|
pool_address=""
|
||||||
|
wallet_address=""
|
||||||
|
pool_password=""
|
||||||
|
pool_tls_fingerprint=""
|
||||||
|
verbose=$DEFAULT_VERBOSE
|
||||||
|
cc_enabled=$DEFAULT_CC_ENABLED
|
||||||
|
cc_url=""
|
||||||
|
cc_work_id=""
|
||||||
|
cc_token=""
|
||||||
|
cc_tls=$DEFAULT_CC_TLS
|
||||||
|
one_gb_pages=$DEFAULT_ONE_GB_PAGES
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
-v | --version) version="$2"; shift 2 ;;
|
||||||
|
-t | --threads) threads="$2"; shift 2 ;;
|
||||||
|
-a | --algo) pool_algo="$2"; shift 2 ;;
|
||||||
|
-o | --pool) pool_address="$2"; shift 2 ;;
|
||||||
|
-w | --wallet) wallet_address="$2"; shift 2 ;;
|
||||||
|
-p | --password) pool_password="$2"; shift 2 ;;
|
||||||
|
--1gb-pages) one_gb_pages="true"; shift ;;
|
||||||
|
--cc-url) cc_url="$2"; shift 2 ;;
|
||||||
|
--cc-work-id) cc_work_id="$2"; shift 2 ;;
|
||||||
|
--cc-token) cc_token="$2"; shift 2 ;;
|
||||||
|
--tls-fingerprint) pool_tls_fingerprint="$2"; shift 2 ;;
|
||||||
|
--tls) pool_tls="true"; shift ;;
|
||||||
|
--keepalive) pool_keepalive="true"; shift ;;
|
||||||
|
--daemon) pool_daemon="true"; shift ;;
|
||||||
|
--nicehash) pool_nicehash="true"; shift ;;
|
||||||
|
--submit-to-origin) pool_submit_to_origin="true"; shift ;;
|
||||||
|
--self-select) pool_self_select="$2"; shift 2 ;;
|
||||||
|
--verbose) verbose="true"; shift ;;
|
||||||
|
--cc) cc_enabled="true"; shift ;;
|
||||||
|
--cc-tls) cc_tls="true"; shift ;;
|
||||||
|
-h | --help) show_usage ;;
|
||||||
|
*) error "无效选项: $1" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# 验证必需参数
|
||||||
|
[[ -z "$pool_address" ]] && error "矿池地址不能为空"
|
||||||
|
[[ ! "$threads" =~ ^[0-9]+$ ]] && error "无效线程数"
|
||||||
|
[[ "$pool_submit_to_origin" == "true" && -z "$pool_self_select" ]] && \
|
||||||
|
error "启用 submit_to_origin 必须设置 self_select"
|
||||||
|
|
||||||
|
# 处理默认值
|
||||||
|
if [[ -z "$pool_password" ]]; then
|
||||||
|
local ip=$(curl -4s --retry 3 --connect-timeout 10 ifconfig.me 2>/dev/null || echo "0.0.0.0")
|
||||||
|
local random_str=$(tr -dc '0-9a-zA-Z' </dev/urandom | head -c 5)
|
||||||
|
pool_password=$(echo "$ip" | awk -F. '{print $3"_"$4}')"_$random_str"
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ -z "$cc_work_id" ]] && cc_work_id="$(get_arch)_$pool_password"
|
||||||
|
[[ -z "$wallet_address" ]] && wallet_address="empty_wallet_$(date +%s)"
|
||||||
|
|
||||||
|
if [[ "$threads" -le 0 ]]; then
|
||||||
|
threads=$(nproc)
|
||||||
|
elif [[ "$threads" -gt $(nproc) ]]; then
|
||||||
|
threads=$(nproc)
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
parse_args "$@"
|
||||||
|
|
||||||
|
# 检查并安装依赖
|
||||||
|
local deps=(curl jq file)
|
||||||
|
if command -v apt-get &>/dev/null; then
|
||||||
|
for pkg in "${deps[@]}"; do
|
||||||
|
command -v "$pkg" &>/dev/null || apt-get install -y "$pkg"
|
||||||
|
done
|
||||||
|
elif command -v apk &>/dev/null; then
|
||||||
|
for pkg in "${deps[@]}"; do
|
||||||
|
command -v "$pkg" &>/dev/null || apk add "$pkg"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
os_type=$(get_os)
|
||||||
|
[[ "$version" == "latest" ]] && version=$(get_gitea_latest_version)
|
||||||
|
|
||||||
|
download_url="https://${GITEA_SERVER}/api/packages/${GITEA_OWNER}/generic/${PACKAGE_NAME}/${version}/${PACKAGE_NAME}-$(get_arch)-$os_type-$version.tar.gz"
|
||||||
|
|
||||||
|
log "$BLUE" "配置信息:"
|
||||||
|
echo " 版本: $version"
|
||||||
|
echo " 架构: $(get_arch)"
|
||||||
|
echo " 系统: $os_type"
|
||||||
|
echo " 线程: $threads"
|
||||||
|
echo " 算法: $pool_algo"
|
||||||
|
echo " 矿池: $pool_address"
|
||||||
|
echo " 钱包: $wallet_address"
|
||||||
|
|
||||||
|
uninstall_xxxigcc
|
||||||
|
install_xxxigcc
|
||||||
|
replace_config
|
||||||
|
create_service
|
||||||
|
|
||||||
|
echo "管理命令:"
|
||||||
|
if [[ "$os_type" == "alpine" ]]; then
|
||||||
|
echo " rc-service xxxigcc status"
|
||||||
|
echo " tail -f $LOG_FILE"
|
||||||
|
echo " rc-service xxxigcc restart"
|
||||||
|
else
|
||||||
|
echo " systemctl status xxxigcc"
|
||||||
|
echo " journalctl -u xxxigcc -f"
|
||||||
|
echo " systemctl restart xxxigcc"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
165
script/uninstall.sh
Executable file
165
script/uninstall.sh
Executable file
@@ -0,0 +1,165 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# XXXigCC 卸载脚本
|
||||||
|
# 支持 tar.gz 和 DEB 包安装方式
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
declare -r RED="\033[0;31m"
|
||||||
|
declare -r GREEN="\033[0;32m"
|
||||||
|
declare -r YELLOW="\033[0;33m"
|
||||||
|
declare -r RESET="\033[0m"
|
||||||
|
|
||||||
|
# 安装路径配置
|
||||||
|
INSTALL_DIR_TARBALL="/etc/miner/xxxigcc"
|
||||||
|
INSTALL_DIR_DEB="/etc/xxxigcc"
|
||||||
|
LOG_DIR_DEB="/var/log/xxxigcc"
|
||||||
|
|
||||||
|
log() { echo -e "${1}${2}${RESET}"; }
|
||||||
|
error() { log "$RED" "错误: $1"; exit 1; }
|
||||||
|
|
||||||
|
|
||||||
|
get_os() {
|
||||||
|
grep -qi alpine /etc/os-release && echo "alpine" && return
|
||||||
|
grep -qiE 'debian|ubuntu' /etc/os-release && echo "ubuntu" && return
|
||||||
|
error "不支持的操作系统"
|
||||||
|
}
|
||||||
|
|
||||||
|
detect_installation() {
|
||||||
|
local install_type=""
|
||||||
|
|
||||||
|
# 检测 DEB 包安装
|
||||||
|
if command -v dpkg &>/dev/null && dpkg -l | grep -q "^ii.*xxxigcc"; then
|
||||||
|
install_type="deb"
|
||||||
|
# 检测 tar.gz 安装
|
||||||
|
elif [[ -d "$INSTALL_DIR_TARBALL" ]]; then
|
||||||
|
install_type="tarball"
|
||||||
|
# 检测 DEB 配置目录
|
||||||
|
elif [[ -d "$INSTALL_DIR_DEB" ]]; then
|
||||||
|
install_type="deb"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$install_type"
|
||||||
|
}
|
||||||
|
|
||||||
|
uninstall_alpine_tarball() {
|
||||||
|
log "$YELLOW" "卸载 Alpine tar.gz 安装..."
|
||||||
|
|
||||||
|
rc-service xxxigcc stop 2>/dev/null || true
|
||||||
|
rc-update del xxxigcc default 2>/dev/null || true
|
||||||
|
rm -rf "$INSTALL_DIR_TARBALL" /etc/init.d/xxxigcc
|
||||||
|
|
||||||
|
log "$GREEN" "Alpine tar.gz 安装已卸载"
|
||||||
|
}
|
||||||
|
|
||||||
|
uninstall_ubuntu_tarball() {
|
||||||
|
log "$YELLOW" "卸载 Ubuntu/Debian tar.gz 安装..."
|
||||||
|
|
||||||
|
systemctl stop xxxigcc 2>/dev/null || true
|
||||||
|
systemctl disable xxxigcc 2>/dev/null || true
|
||||||
|
rm -rf "$INSTALL_DIR_TARBALL" /etc/systemd/system/xxxigcc.service
|
||||||
|
systemctl daemon-reload 2>/dev/null || true
|
||||||
|
|
||||||
|
log "$GREEN" "Ubuntu/Debian tar.gz 安装已卸载"
|
||||||
|
}
|
||||||
|
|
||||||
|
uninstall_deb_package() {
|
||||||
|
log "$YELLOW" "卸载 DEB 包..."
|
||||||
|
|
||||||
|
# 停止并禁用服务
|
||||||
|
systemctl stop xxxigcc-daemon xxxigcc-server 2>/dev/null || true
|
||||||
|
systemctl disable xxxigcc-daemon xxxigcc-server 2>/dev/null || true
|
||||||
|
|
||||||
|
# 卸载包
|
||||||
|
apt-get remove -y xxxigcc 2>/dev/null || true
|
||||||
|
|
||||||
|
# 清理配置(可选)
|
||||||
|
if [[ "$PURGE_CONFIG" == "true" ]]; then
|
||||||
|
apt-get purge -y xxxigcc 2>/dev/null || true
|
||||||
|
rm -rf "$INSTALL_DIR_DEB" "$LOG_DIR_DEB"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 清理 APT 源
|
||||||
|
rm -f /etc/apt/sources.list.d/xxxigcc.list
|
||||||
|
apt-get update -qq 2>/dev/null || true
|
||||||
|
|
||||||
|
systemctl daemon-reload 2>/dev/null || true
|
||||||
|
|
||||||
|
log "$GREEN" "DEB 包已卸载"
|
||||||
|
}
|
||||||
|
|
||||||
|
show_usage() {
|
||||||
|
cat <<EOF
|
||||||
|
用法: $0 [选项]
|
||||||
|
|
||||||
|
选项:
|
||||||
|
--purge 完全清除配置文件和日志 (仅 DEB 包)
|
||||||
|
-y, --yes 跳过确认提示
|
||||||
|
-h, --help 显示帮助信息
|
||||||
|
|
||||||
|
示例:
|
||||||
|
$0 # 交互式卸载
|
||||||
|
$0 -y # 直接卸载,不确认
|
||||||
|
$0 --purge -y # 完全清除所有文件
|
||||||
|
EOF
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local SKIP_CONFIRM=false
|
||||||
|
PURGE_CONFIG=false
|
||||||
|
|
||||||
|
# 解析参数
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--purge) PURGE_CONFIG=true; shift ;;
|
||||||
|
-y | --yes) SKIP_CONFIRM=true; shift ;;
|
||||||
|
-h | --help) show_usage ;;
|
||||||
|
*) error "无效选项: $1" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
local os_type=$(get_os)
|
||||||
|
local install_type=$(detect_installation)
|
||||||
|
|
||||||
|
if [[ -z "$install_type" ]]; then
|
||||||
|
log "$YELLOW" "未检测到 XXXigCC 安装"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 显示检测信息
|
||||||
|
log "$YELLOW" "检测到的安装方式: $install_type ($os_type)"
|
||||||
|
|
||||||
|
# 确认卸载
|
||||||
|
if [[ "$SKIP_CONFIRM" != "true" ]]; then
|
||||||
|
echo -n "确认卸载 XXXigCC? (y/N): "
|
||||||
|
read -r confirm
|
||||||
|
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
|
||||||
|
log "$YELLOW" "已取消卸载"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 根据安装类型执行卸载
|
||||||
|
case "$install_type" in
|
||||||
|
deb)
|
||||||
|
uninstall_deb_package
|
||||||
|
;;
|
||||||
|
tarball)
|
||||||
|
if [[ "$os_type" == "alpine" ]]; then
|
||||||
|
uninstall_alpine_tarball
|
||||||
|
else
|
||||||
|
uninstall_ubuntu_tarball
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
log "$GREEN" "XXXigCC 已成功卸载"
|
||||||
|
|
||||||
|
if [[ "$PURGE_CONFIG" != "true" && "$install_type" == "deb" ]]; then
|
||||||
|
log "$YELLOW" "提示: 使用 '$0 --purge' 可完全清除配置文件"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
406
templates/BlockTemplate.cpp
Normal file
406
templates/BlockTemplate.cpp
Normal file
@@ -0,0 +1,406 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright (c) 2012-2013 The Cryptonote developers
|
||||||
|
* Copyright (c) 2014-2021 The Monero Project
|
||||||
|
* Copyright (c) 2018-2023 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright (c) 2016-2023 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "base/tools/cryptonote/BlockTemplate.h"
|
||||||
|
#include "3rdparty/rapidjson/document.h"
|
||||||
|
#include "base/crypto/keccak.h"
|
||||||
|
#include "base/tools/cryptonote/BlobReader.h"
|
||||||
|
#include "base/tools/Cvt.h"
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::BlockTemplate::calculateMinerTxHash(const uint8_t *prefix_begin, const uint8_t *prefix_end, uint8_t *hash)
|
||||||
|
{
|
||||||
|
uint8_t hashes[kHashSize * 3];
|
||||||
|
|
||||||
|
// Calculate 3 partial hashes
|
||||||
|
|
||||||
|
// 1. Prefix
|
||||||
|
keccak(prefix_begin, static_cast<int>(prefix_end - prefix_begin), hashes, kHashSize);
|
||||||
|
|
||||||
|
// 2. Base RCT, single 0 byte in miner tx
|
||||||
|
static const uint8_t known_second_hash[kHashSize] = {
|
||||||
|
188,54,120,158,122,30,40,20,54,70,66,41,130,143,129,125,102,18,247,180,119,214,101,145,255,150,169,224,100,188,201,138
|
||||||
|
};
|
||||||
|
memcpy(hashes + kHashSize, known_second_hash, kHashSize);
|
||||||
|
|
||||||
|
// 3. Prunable RCT, empty in miner tx
|
||||||
|
memset(hashes + kHashSize * 2, 0, kHashSize);
|
||||||
|
|
||||||
|
// Calculate miner transaction hash
|
||||||
|
keccak(hashes, sizeof(hashes), hash, kHashSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::BlockTemplate::calculateRootHash(const uint8_t *prefix_begin, const uint8_t *prefix_end, const Buffer &miner_tx_merkle_tree_branch, uint8_t *root_hash)
|
||||||
|
{
|
||||||
|
calculateMinerTxHash(prefix_begin, prefix_end, root_hash);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < miner_tx_merkle_tree_branch.size(); i += kHashSize) {
|
||||||
|
uint8_t h[kHashSize * 2];
|
||||||
|
|
||||||
|
memcpy(h, root_hash, kHashSize);
|
||||||
|
memcpy(h + kHashSize, miner_tx_merkle_tree_branch.data() + i, kHashSize);
|
||||||
|
|
||||||
|
keccak(h, kHashSize * 2, root_hash, kHashSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::BlockTemplate::calculateMerkleTreeHash()
|
||||||
|
{
|
||||||
|
m_minerTxMerkleTreeBranch.clear();
|
||||||
|
|
||||||
|
const uint64_t count = m_numHashes + 1;
|
||||||
|
const uint8_t *h = m_hashes.data();
|
||||||
|
|
||||||
|
if (count == 1) {
|
||||||
|
memcpy(m_rootHash, h, kHashSize);
|
||||||
|
}
|
||||||
|
else if (count == 2) {
|
||||||
|
m_minerTxMerkleTreeBranch.insert(m_minerTxMerkleTreeBranch.end(), h + kHashSize, h + kHashSize * 2);
|
||||||
|
keccak(h, kHashSize * 2, m_rootHash, kHashSize);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
size_t i = 0;
|
||||||
|
size_t j = 0;
|
||||||
|
size_t cnt = 0;
|
||||||
|
|
||||||
|
for (i = 0, cnt = 1; cnt <= count; ++i, cnt <<= 1) {}
|
||||||
|
|
||||||
|
cnt >>= 1;
|
||||||
|
|
||||||
|
m_minerTxMerkleTreeBranch.reserve(kHashSize * (i - 1));
|
||||||
|
|
||||||
|
Buffer ints(cnt * kHashSize);
|
||||||
|
memcpy(ints.data(), h, (cnt * 2 - count) * kHashSize);
|
||||||
|
|
||||||
|
for (i = cnt * 2 - count, j = cnt * 2 - count; j < cnt; i += 2, ++j) {
|
||||||
|
if (i == 0) {
|
||||||
|
m_minerTxMerkleTreeBranch.insert(m_minerTxMerkleTreeBranch.end(), h + kHashSize, h + kHashSize * 2);
|
||||||
|
}
|
||||||
|
keccak(h + i * kHashSize, kHashSize * 2, ints.data() + j * kHashSize, kHashSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (cnt > 2) {
|
||||||
|
cnt >>= 1;
|
||||||
|
for (i = 0, j = 0; j < cnt; i += 2, ++j) {
|
||||||
|
if (i == 0) {
|
||||||
|
m_minerTxMerkleTreeBranch.insert(m_minerTxMerkleTreeBranch.end(), ints.data() + kHashSize, ints.data() + kHashSize * 2);
|
||||||
|
}
|
||||||
|
keccak(ints.data() + i * kHashSize, kHashSize * 2, ints.data() + j * kHashSize, kHashSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_minerTxMerkleTreeBranch.insert(m_minerTxMerkleTreeBranch.end(), ints.data() + kHashSize, ints.data() + kHashSize * 2);
|
||||||
|
keccak(ints.data(), kHashSize * 2, m_rootHash, kHashSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::BlockTemplate::parse(const Buffer &blocktemplate, const Coin &coin, bool hashes)
|
||||||
|
{
|
||||||
|
if (blocktemplate.size() < kMinSize) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_blob = blocktemplate;
|
||||||
|
m_coin = coin;
|
||||||
|
bool rc = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
rc = parse(hashes);
|
||||||
|
} catch (...) {}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::BlockTemplate::parse(const char *blocktemplate, size_t size, const Coin &coin, bool hashes)
|
||||||
|
{
|
||||||
|
if (size < (kMinSize * 2) || !Cvt::fromHex(m_blob, blocktemplate, size)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_coin = coin;
|
||||||
|
bool rc = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
rc = parse(hashes);
|
||||||
|
} catch (...) {}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::BlockTemplate::parse(const rapidjson::Value &blocktemplate, const Coin &coin, bool hashes)
|
||||||
|
{
|
||||||
|
return blocktemplate.IsString() && parse(blocktemplate.GetString(), blocktemplate.GetStringLength(), coin, hashes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::BlockTemplate::parse(const String &blocktemplate, const Coin &coin, bool hashes)
|
||||||
|
{
|
||||||
|
return parse(blocktemplate.data(), blocktemplate.size(), coin, hashes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::BlockTemplate::generateHashingBlob(Buffer &out) const
|
||||||
|
{
|
||||||
|
out.clear();
|
||||||
|
out.reserve(offset(MINER_TX_PREFIX_OFFSET) + kHashSize + 3);
|
||||||
|
|
||||||
|
out.assign(m_blob.begin(), m_blob.begin() + offset(MINER_TX_PREFIX_OFFSET));
|
||||||
|
out.insert(out.end(), m_rootHash, m_rootHash + kHashSize);
|
||||||
|
|
||||||
|
uint64_t k = m_numHashes + 1;
|
||||||
|
while (k >= 0x80) {
|
||||||
|
out.emplace_back((static_cast<uint8_t>(k) & 0x7F) | 0x80);
|
||||||
|
k >>= 7;
|
||||||
|
}
|
||||||
|
out.emplace_back(static_cast<uint8_t>(k));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::BlockTemplate::parse(bool hashes)
|
||||||
|
{
|
||||||
|
// Detect Tari solo mining format (76 bytes)
|
||||||
|
// Format: 3 bytes header + 32 bytes mining_hash + 8 bytes nonce + 33 bytes pow
|
||||||
|
if (m_blob.size() == 76) {
|
||||||
|
// Tari solo mining format - use fixed-size parsing (no varint)
|
||||||
|
BlobReader<false> ar(m_blob.data(), m_blob.size());
|
||||||
|
|
||||||
|
// Skip 3-byte header (major_version, minor_version, timestamp - all 0 for Tari)
|
||||||
|
ar.skip(3);
|
||||||
|
|
||||||
|
// Skip 32-byte mining_hash
|
||||||
|
ar.skip(32);
|
||||||
|
|
||||||
|
// Nonce is at offset 35 (3 + 32)
|
||||||
|
setOffset(NONCE_OFFSET, 35);
|
||||||
|
ar.skip(8); // Skip nonce (8 bytes, big-endian)
|
||||||
|
|
||||||
|
// Skip 33-byte PoW data
|
||||||
|
ar.skip(33);
|
||||||
|
|
||||||
|
// For Tari, we don't need to parse miner tx or other Monero-specific fields
|
||||||
|
// Just accept the template and let XMRig modify the nonce
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Original Monero varint parsing for non-Tari formats
|
||||||
|
BlobReader<true> ar(m_blob.data(), m_blob.size());
|
||||||
|
|
||||||
|
// Block header
|
||||||
|
ar(m_version.first);
|
||||||
|
ar(m_version.second);
|
||||||
|
ar(m_timestamp);
|
||||||
|
ar(m_prevId, kHashSize);
|
||||||
|
|
||||||
|
setOffset(NONCE_OFFSET, ar.index());
|
||||||
|
ar.skip(kNonceSize);
|
||||||
|
|
||||||
|
// Wownero block template has miner signature starting from version 18
|
||||||
|
if (m_coin == Coin::WOWNERO && majorVersion() >= 18) {
|
||||||
|
ar(m_minerSignature, kSignatureSize);
|
||||||
|
ar(m_vote);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_coin == Coin::ZEPHYR) {
|
||||||
|
uint8_t pricing_record[120];
|
||||||
|
ar(pricing_record);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Miner transaction begin
|
||||||
|
// Prefix begin
|
||||||
|
setOffset(MINER_TX_PREFIX_OFFSET, ar.index());
|
||||||
|
|
||||||
|
ar(m_txVersion);
|
||||||
|
|
||||||
|
if (m_coin != Coin::TOWNFORGE) {
|
||||||
|
ar(m_unlockTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
ar(m_numInputs);
|
||||||
|
|
||||||
|
// must be 1 input
|
||||||
|
if (m_numInputs != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ar(m_inputType);
|
||||||
|
|
||||||
|
// input type must be txin_gen (0xFF)
|
||||||
|
if (m_inputType != 0xFF) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ar(m_height);
|
||||||
|
ar(m_numOutputs);
|
||||||
|
|
||||||
|
if (m_coin == Coin::ZEPHYR) {
|
||||||
|
if (m_numOutputs < 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_numOutputs != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ar(m_amount);
|
||||||
|
ar(m_outputType);
|
||||||
|
|
||||||
|
// output type must be txout_to_key (2) or txout_to_tagged_key (3)
|
||||||
|
if ((m_outputType != 2) && (m_outputType != 3)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
setOffset(EPH_PUBLIC_KEY_OFFSET, ar.index());
|
||||||
|
|
||||||
|
ar(m_ephPublicKey, kKeySize);
|
||||||
|
|
||||||
|
if (m_coin == Coin::ZEPHYR) {
|
||||||
|
if (m_outputType != 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t asset_type_len;
|
||||||
|
ar(asset_type_len);
|
||||||
|
ar.skip(asset_type_len);
|
||||||
|
ar(m_viewTag);
|
||||||
|
|
||||||
|
for (uint64_t k = 1; k < m_numOutputs; ++k) {
|
||||||
|
uint64_t amount2;
|
||||||
|
ar(amount2);
|
||||||
|
|
||||||
|
uint8_t output_type2;
|
||||||
|
ar(output_type2);
|
||||||
|
if (output_type2 != 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Span key2;
|
||||||
|
ar(key2, kKeySize);
|
||||||
|
|
||||||
|
ar(asset_type_len);
|
||||||
|
ar.skip(asset_type_len);
|
||||||
|
|
||||||
|
uint8_t view_tag2;
|
||||||
|
ar(view_tag2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_outputType == 3) {
|
||||||
|
ar(m_viewTag);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_coin == Coin::TOWNFORGE) {
|
||||||
|
ar(m_unlockTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
ar(m_extraSize);
|
||||||
|
|
||||||
|
setOffset(TX_EXTRA_OFFSET, ar.index());
|
||||||
|
|
||||||
|
BlobReader<true> ar_extra(blob(TX_EXTRA_OFFSET), m_extraSize);
|
||||||
|
ar.skip(m_extraSize);
|
||||||
|
|
||||||
|
bool pubkey_offset_first = true;
|
||||||
|
|
||||||
|
while (ar_extra.index() < m_extraSize) {
|
||||||
|
uint64_t extra_tag = 0;
|
||||||
|
uint64_t size = 0;
|
||||||
|
|
||||||
|
ar_extra(extra_tag);
|
||||||
|
|
||||||
|
switch (extra_tag) {
|
||||||
|
case 0x01: // TX_EXTRA_TAG_PUBKEY
|
||||||
|
if (pubkey_offset_first) {
|
||||||
|
pubkey_offset_first = false;
|
||||||
|
setOffset(TX_PUBKEY_OFFSET, offset(TX_EXTRA_OFFSET) + ar_extra.index());
|
||||||
|
}
|
||||||
|
ar_extra.skip(kKeySize);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x02: // TX_EXTRA_NONCE
|
||||||
|
ar_extra(size);
|
||||||
|
setOffset(TX_EXTRA_NONCE_OFFSET, offset(TX_EXTRA_OFFSET) + ar_extra.index());
|
||||||
|
ar_extra(m_txExtraNonce, size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x03: // TX_EXTRA_MERGE_MINING_TAG
|
||||||
|
ar_extra(size);
|
||||||
|
setOffset(TX_EXTRA_MERGE_MINING_TAG_OFFSET, offset(TX_EXTRA_OFFSET) + ar_extra.index());
|
||||||
|
ar_extra(m_txMergeMiningTag, size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false; // TODO(SChernykh): handle other tags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_coin == Coin::ZEPHYR) {
|
||||||
|
uint64_t pricing_record_height, amount_burnt, amount_minted;
|
||||||
|
ar(pricing_record_height);
|
||||||
|
ar(amount_burnt);
|
||||||
|
ar(amount_minted);
|
||||||
|
}
|
||||||
|
|
||||||
|
setOffset(MINER_TX_PREFIX_END_OFFSET, ar.index());
|
||||||
|
// Prefix end
|
||||||
|
|
||||||
|
// RCT signatures (empty in miner transaction)
|
||||||
|
uint8_t vin_rct_type = 0;
|
||||||
|
ar(vin_rct_type);
|
||||||
|
|
||||||
|
// no way I'm parsing a full game update here
|
||||||
|
if (m_coin == Coin::TOWNFORGE && m_height % 720 == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// must be RCTTypeNull (0)
|
||||||
|
if (vin_rct_type != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t miner_tx_end = ar.index();
|
||||||
|
// Miner transaction end
|
||||||
|
|
||||||
|
// Miner transaction must have exactly 1 byte with value 0 after the prefix
|
||||||
|
if ((miner_tx_end != offset(MINER_TX_PREFIX_END_OFFSET) + 1) || (*blob(MINER_TX_PREFIX_END_OFFSET) != 0)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Other transaction hashes
|
||||||
|
ar(m_numHashes);
|
||||||
|
|
||||||
|
if (hashes) {
|
||||||
|
m_hashes.resize((m_numHashes + 1) * kHashSize);
|
||||||
|
calculateMinerTxHash(blob(MINER_TX_PREFIX_OFFSET), blob(MINER_TX_PREFIX_END_OFFSET), m_hashes.data());
|
||||||
|
|
||||||
|
for (uint64_t i = 1; i <= m_numHashes; ++i) {
|
||||||
|
Span h;
|
||||||
|
ar(h, kHashSize);
|
||||||
|
memcpy(m_hashes.data() + i * kHashSize, h.data(), kHashSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
calculateMerkleTreeHash();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user