tari-rust/IMPLEMENTATION_SUMMARY.md

7.3 KiB
Raw Blame History

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:

// 旧结构
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 获取区块模板流程

  1. 获取区块模板通过gRPC从BaseNode获取
  2. 生成coinbase自动生成coinbase交易
  3. 获取target:从miner_data.target_difficulty获取目标难度
  4. HTTP请求:获取上一个区块的output_smt_size
  5. 计算output_smt_size当前 = 上一个 + outputs长度 - inputs长度
  6. 生成任务ID16位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-httpBaseNode 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"
}

总结

本次修改完全实现了您要求的功能:

  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. 构建脚本:跨平台构建支持

所有功能都已实现并通过测试,可以直接使用。