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. ✅ **构建脚本**:跨平台构建支持
|
||
|
||
所有功能都已实现并通过测试,可以直接使用。 |