290 lines
7.3 KiB
Markdown
290 lines
7.3 KiB
Markdown
|
# GBT项目修改实现总结
|
|||
|
|
|||
|
## 概述
|
|||
|
|
|||
|
根据您的要求,对GBT项目进行了全面的重构和功能增强,实现了以下核心功能:
|
|||
|
|
|||
|
1. **HTTP API集成**:通过HTTP请求获取上一个区块的`output_smt_size`
|
|||
|
2. **任务ID生成**:生成16位16进制任务ID
|
|||
|
3. **简化的output_smt_size计算**:使用`outputs长度 - inputs长度`的差值计算
|
|||
|
4. **新的数据结构**:重新设计了MiningTask、MiningMsg等结构
|
|||
|
5. **ZMQ通信优化**:改进了消息格式和通信流程
|
|||
|
|
|||
|
## 主要修改
|
|||
|
|
|||
|
### 1. 依赖项更新 (`Cargo.toml`)
|
|||
|
|
|||
|
新增依赖:
|
|||
|
- `reqwest = { version = "0.11", features = ["json"] }` - HTTP客户端
|
|||
|
- `uuid = { version = "1.0", features = ["v4"] }` - 任务ID生成
|
|||
|
|
|||
|
### 2. 数据结构重新设计
|
|||
|
|
|||
|
#### 原结构 → 新结构
|
|||
|
|
|||
|
**MiningTask**:
|
|||
|
```rust
|
|||
|
// 旧结构
|
|||
|
pub struct MiningTask {
|
|||
|
pub coinbase_hash: String,
|
|||
|
pub height: u64,
|
|||
|
pub target: u64,
|
|||
|
pub output_smt_size: u64,
|
|||
|
pub block_template: String,
|
|||
|
}
|
|||
|
|
|||
|
// 新结构
|
|||
|
pub struct MiningTask {
|
|||
|
pub job_id: String, // 新增:16位16进制任务ID
|
|||
|
pub block_header: BlockHeader, // 新增:完整的区块头
|
|||
|
pub block_body: BlockBody, // 新增:完整的区块体
|
|||
|
pub output_smt_size: u64, // 保留:当前output_smt_size
|
|||
|
pub coinbase_hash: String, // 保留:coinbase哈希
|
|||
|
pub target: u64, // 保留:目标难度(从gRPC获取)
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
**新增结构**:
|
|||
|
```rust
|
|||
|
// 区块头结构
|
|||
|
pub struct BlockHeader {
|
|||
|
pub hash: String,
|
|||
|
pub version: u32,
|
|||
|
pub height: u64,
|
|||
|
pub prev_hash: String,
|
|||
|
pub timestamp: u64,
|
|||
|
pub output_mr: String,
|
|||
|
pub block_output_mr: String,
|
|||
|
pub kernel_mr: String,
|
|||
|
pub input_mr: String,
|
|||
|
pub total_kernel_offset: String,
|
|||
|
pub nonce: u64, // 初始为0,等待后续修改
|
|||
|
pub pow: ProofOfWork,
|
|||
|
pub kernel_mmr_size: u64,
|
|||
|
pub output_mmr_size: u64,
|
|||
|
pub total_script_offset: String,
|
|||
|
pub validator_node_mr: String,
|
|||
|
pub validator_node_size: u64,
|
|||
|
}
|
|||
|
|
|||
|
// 区块体结构
|
|||
|
pub struct BlockBody {
|
|||
|
pub inputs: Vec<String>,
|
|||
|
pub outputs: Vec<String>,
|
|||
|
pub kernels: Vec<String>,
|
|||
|
}
|
|||
|
|
|||
|
// 挖矿消息结构
|
|||
|
pub struct MiningMsg {
|
|||
|
pub job_id: String,
|
|||
|
pub block_header: BlockHeader,
|
|||
|
pub output_smt_size: u64,
|
|||
|
pub coinbase_hash: String,
|
|||
|
pub target: u64, // 新增:目标难度
|
|||
|
}
|
|||
|
|
|||
|
// 提交请求结构
|
|||
|
pub struct SubmitRequest {
|
|||
|
pub job_id: String, // 改为任务ID
|
|||
|
pub nonce: u64,
|
|||
|
pub solution: String,
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
### 3. 核心功能实现
|
|||
|
|
|||
|
#### 3.1 HTTP API集成
|
|||
|
|
|||
|
```rust
|
|||
|
// 通过HTTP获取上一个区块的output_smt_size
|
|||
|
async fn get_prev_output_smt_size(&self, height: u64) -> Result<u64> {
|
|||
|
let prev_height = height - 1;
|
|||
|
|
|||
|
// 检查缓存
|
|||
|
{
|
|||
|
let cache = self.prev_output_smt_size_cache.lock().await;
|
|||
|
if let Some(&size) = cache.get(&prev_height) {
|
|||
|
return Ok(size);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 通过HTTP请求获取
|
|||
|
let url = format!("http://{}/get_header_by_height?height={}",
|
|||
|
self.config.base_node_http_address, prev_height);
|
|||
|
|
|||
|
let response = self.http_client.get(&url).send().await?;
|
|||
|
let header_data: serde_json::Value = response.json().await?;
|
|||
|
|
|||
|
let output_smt_size = header_data["output_smt_size"]
|
|||
|
.as_u64()
|
|||
|
.ok_or_else(|| anyhow!("Missing output_smt_size in response"))?;
|
|||
|
|
|||
|
// 更新缓存
|
|||
|
{
|
|||
|
let mut cache = self.prev_output_smt_size_cache.lock().await;
|
|||
|
cache.insert(prev_height, output_smt_size);
|
|||
|
}
|
|||
|
|
|||
|
Ok(output_smt_size)
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
#### 3.2 任务ID生成
|
|||
|
|
|||
|
```rust
|
|||
|
// 生成16位16进制任务ID
|
|||
|
fn generate_job_id() -> String {
|
|||
|
let uuid = Uuid::new_v4();
|
|||
|
uuid.to_string().replace("-", "")[..16].to_string()
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
#### 3.3 简化的output_smt_size计算
|
|||
|
|
|||
|
```rust
|
|||
|
// 计算当前output_smt_size
|
|||
|
let current_output_smt_size = prev_output_smt_size +
|
|||
|
block_body.outputs.len() as u64 -
|
|||
|
block_body.inputs.len() as u64;
|
|||
|
```
|
|||
|
|
|||
|
#### 3.4 ZMQ消息格式
|
|||
|
|
|||
|
**发送挖矿消息**:
|
|||
|
```rust
|
|||
|
let mining_msg = MiningMsg {
|
|||
|
job_id: mining_task.job_id.clone(),
|
|||
|
block_header: mining_task.block_header.clone(),
|
|||
|
output_smt_size: mining_task.output_smt_size,
|
|||
|
coinbase_hash: mining_task.coinbase_hash.clone(),
|
|||
|
target: mining_task.target,
|
|||
|
};
|
|||
|
|
|||
|
let msg_json = serde_json::to_string(&mining_msg)?;
|
|||
|
self.publisher_socket.send_multipart(&["mining_msg".as_bytes(), msg_json.as_bytes()], 0)?;
|
|||
|
```
|
|||
|
|
|||
|
**接收提交请求**:
|
|||
|
```rust
|
|||
|
// 消息格式: "submit {json_data}"
|
|||
|
let submit_json = &message_str[7..]; // 去掉"submit "前缀
|
|||
|
let submit_request: SubmitRequest = serde_json::from_str(submit_json)?;
|
|||
|
```
|
|||
|
|
|||
|
### 4. 工作流程
|
|||
|
|
|||
|
#### 4.1 获取区块模板流程
|
|||
|
|
|||
|
1. **获取区块模板**:通过gRPC从BaseNode获取
|
|||
|
2. **生成coinbase**:自动生成coinbase交易
|
|||
|
3. **获取target**:从`miner_data.target_difficulty`获取目标难度
|
|||
|
4. **HTTP请求**:获取上一个区块的`output_smt_size`
|
|||
|
5. **计算output_smt_size**:`当前 = 上一个 + outputs长度 - inputs长度`
|
|||
|
6. **生成任务ID**:16位16进制字符串
|
|||
|
7. **构造MiningTask**:包含完整信息(包括target)
|
|||
|
8. **发送ZMQ消息**:发布挖矿任务
|
|||
|
|
|||
|
#### 4.2 提交处理流程
|
|||
|
|
|||
|
1. **接收ZMQ消息**:监听submit主题
|
|||
|
2. **验证任务ID**:查找对应的MiningTask
|
|||
|
3. **构造区块**:使用提交的nonce和solution
|
|||
|
4. **提交到BaseNode**:通过gRPC提交
|
|||
|
5. **返回结果**:发送submit_result消息
|
|||
|
|
|||
|
### 5. 配置参数
|
|||
|
|
|||
|
新增配置:
|
|||
|
- `--base-node-http`:BaseNode HTTP地址(默认:127.0.0.1:9000)
|
|||
|
|
|||
|
### 6. 缓存机制
|
|||
|
|
|||
|
- **任务缓存**:按height保存,最多3个区块
|
|||
|
- **output_smt_size缓存**:避免重复HTTP请求
|
|||
|
|
|||
|
## 测试工具
|
|||
|
|
|||
|
### Python测试脚本 (`test_gbt.py`)
|
|||
|
|
|||
|
功能:
|
|||
|
- 模拟ZMQ客户端
|
|||
|
- 接收挖矿任务
|
|||
|
- 自动提交模拟结果
|
|||
|
- 统计信息显示
|
|||
|
|
|||
|
使用方法:
|
|||
|
```bash
|
|||
|
python3 test_gbt.py
|
|||
|
```
|
|||
|
|
|||
|
## 构建脚本
|
|||
|
|
|||
|
### Linux/macOS (`build.sh`)
|
|||
|
- 检查Rust环境
|
|||
|
- 检查系统依赖
|
|||
|
- 自动构建release版本
|
|||
|
|
|||
|
### Windows (`build.bat`)
|
|||
|
- 检查Rust环境
|
|||
|
- 检查Windows依赖
|
|||
|
- 自动构建release版本
|
|||
|
|
|||
|
## 使用示例
|
|||
|
|
|||
|
### 基本运行
|
|||
|
```bash
|
|||
|
./target/release/gbt
|
|||
|
```
|
|||
|
|
|||
|
### 自定义配置
|
|||
|
```bash
|
|||
|
./target/release/gbt \
|
|||
|
--base-node 127.0.0.1:18102 \
|
|||
|
--base-node-http 127.0.0.1:9000 \
|
|||
|
--network mainnet \
|
|||
|
--wallet-address YOUR_WALLET_ADDRESS \
|
|||
|
--coinbase-extra "your_pool_name"
|
|||
|
```
|
|||
|
|
|||
|
## 消息格式示例
|
|||
|
|
|||
|
### 挖矿任务消息
|
|||
|
```json
|
|||
|
{
|
|||
|
"job_id": "a1b2c3d4e5f67890",
|
|||
|
"block_header": {
|
|||
|
"hash": "hash_here",
|
|||
|
"height": 12345,
|
|||
|
"nonce": 0,
|
|||
|
// ... 其他字段
|
|||
|
},
|
|||
|
"output_smt_size": 1000,
|
|||
|
"coinbase_hash": "coinbase_hash_here",
|
|||
|
"target": 1000000
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
### 提交请求消息
|
|||
|
```json
|
|||
|
{
|
|||
|
"job_id": "a1b2c3d4e5f67890",
|
|||
|
"nonce": 123456789,
|
|||
|
"solution": "solution_hash_here"
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
## 总结
|
|||
|
|
|||
|
本次修改完全实现了您要求的功能:
|
|||
|
|
|||
|
1. ✅ **HTTP API集成**:通过HTTP获取上一个区块的output_smt_size
|
|||
|
2. ✅ **任务ID生成**:16位16进制随机ID
|
|||
|
3. ✅ **简化的计算**:output_smt_size = 上一个 + outputs - inputs
|
|||
|
4. ✅ **新的数据结构**:完整的MiningTask、MiningMsg等
|
|||
|
5. ✅ **ZMQ通信**:优化的消息格式和流程
|
|||
|
6. ✅ **任务管理**:基于job_id的任务跟踪
|
|||
|
7. ✅ **缓存机制**:避免重复HTTP请求
|
|||
|
8. ✅ **测试工具**:Python测试脚本
|
|||
|
9. ✅ **构建脚本**:跨平台构建支持
|
|||
|
|
|||
|
所有功能都已实现并通过测试,可以直接使用。
|