7.3 KiB
7.3 KiB
GBT项目修改实现总结
概述
根据您的要求,对GBT项目进行了全面的重构和功能增强,实现了以下核心功能:
- HTTP API集成:通过HTTP请求获取上一个区块的
output_smt_size
- 任务ID生成:生成16位16进制任务ID
- 简化的output_smt_size计算:使用
outputs长度 - inputs长度
的差值计算 - 新的数据结构:重新设计了MiningTask、MiningMsg等结构
- ZMQ通信优化:改进了消息格式和通信流程
主要修改
1. 依赖项更新 (Cargo.toml
)
新增依赖:
reqwest = { version = "0.11", features = ["json"] }
- HTTP客户端uuid = { version = "1.0", features = ["v4"] }
- 任务ID生成
2. 数据结构重新设计
原结构 → 新结构
MiningTask:
// 旧结构
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获取)
}
新增结构:
// 区块头结构
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集成
// 通过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生成
// 生成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计算
// 计算当前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消息格式
发送挖矿消息:
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)?;
接收提交请求:
// 消息格式: "submit {json_data}"
let submit_json = &message_str[7..]; // 去掉"submit "前缀
let submit_request: SubmitRequest = serde_json::from_str(submit_json)?;
4. 工作流程
4.1 获取区块模板流程
- 获取区块模板:通过gRPC从BaseNode获取
- 生成coinbase:自动生成coinbase交易
- 获取target:从
miner_data.target_difficulty
获取目标难度 - HTTP请求:获取上一个区块的
output_smt_size
- 计算output_smt_size:
当前 = 上一个 + outputs长度 - inputs长度
- 生成任务ID:16位16进制字符串
- 构造MiningTask:包含完整信息(包括target)
- 发送ZMQ消息:发布挖矿任务
4.2 提交处理流程
- 接收ZMQ消息:监听submit主题
- 验证任务ID:查找对应的MiningTask
- 构造区块:使用提交的nonce和solution
- 提交到BaseNode:通过gRPC提交
- 返回结果:发送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客户端
- 接收挖矿任务
- 自动提交模拟结果
- 统计信息显示
使用方法:
python3 test_gbt.py
构建脚本
Linux/macOS (build.sh
)
- 检查Rust环境
- 检查系统依赖
- 自动构建release版本
Windows (build.bat
)
- 检查Rust环境
- 检查Windows依赖
- 自动构建release版本
使用示例
基本运行
./target/release/gbt
自定义配置
./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"
消息格式示例
挖矿任务消息
{
"job_id": "a1b2c3d4e5f67890",
"block_header": {
"hash": "hash_here",
"height": 12345,
"nonce": 0,
// ... 其他字段
},
"output_smt_size": 1000,
"coinbase_hash": "coinbase_hash_here",
"target": 1000000
}
提交请求消息
{
"job_id": "a1b2c3d4e5f67890",
"nonce": 123456789,
"solution": "solution_hash_here"
}
总结
本次修改完全实现了您要求的功能:
- ✅ HTTP API集成:通过HTTP获取上一个区块的output_smt_size
- ✅ 任务ID生成:16位16进制随机ID
- ✅ 简化的计算:output_smt_size = 上一个 + outputs - inputs
- ✅ 新的数据结构:完整的MiningTask、MiningMsg等
- ✅ ZMQ通信:优化的消息格式和流程
- ✅ 任务管理:基于job_id的任务跟踪
- ✅ 缓存机制:避免重复HTTP请求
- ✅ 测试工具:Python测试脚本
- ✅ 构建脚本:跨平台构建支持
所有功能都已实现并通过测试,可以直接使用。