# 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, pub outputs: Vec, pub kernels: Vec, } // 挖矿消息结构 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 { 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. ✅ **构建脚本**:跨平台构建支持 所有功能都已实现并通过测试,可以直接使用。