From bc9ca3ece57a141dc8d1ee2be2012762ad53cb02 Mon Sep 17 00:00:00 2001 From: lzx <393768033@qq.com> Date: Thu, 26 Jun 2025 15:22:52 +0800 Subject: [PATCH] add base64 to hex add output_smt_size but encording still is base64 --- build.bat | 100 ---------------------------------------------------- src/main.rs | 69 ++++++++++++++++++++++++++++++++++-- 2 files changed, 67 insertions(+), 102 deletions(-) delete mode 100644 build.bat diff --git a/build.bat b/build.bat deleted file mode 100644 index c01d45d..0000000 --- a/build.bat +++ /dev/null @@ -1,100 +0,0 @@ -@echo off -setlocal enabledelayedexpansion - -REM GBT项目构建脚本 (Windows版本) - -echo 🚀 开始构建GBT项目... - -REM 检查Rust环境 -where cargo >nul 2>&1 -if %errorlevel% neq 0 ( - echo ❌ 错误: 未找到cargo,请先安装Rust - echo 访问: https://rustup.rs/ - pause - exit /b 1 -) - -REM 检查Rust版本 -for /f "tokens=2" %%i in ('rustc --version') do set RUST_VERSION=%%i -echo 📦 Rust版本: %RUST_VERSION% - -REM 检查是否在正确的目录 -if not exist "Cargo.toml" ( - echo ❌ 错误: 未找到Cargo.toml,请在gbt目录下运行此脚本 - pause - exit /b 1 -) - -REM 清理之前的构建 -echo 🧹 清理之前的构建... -cargo clean -if %errorlevel% neq 0 ( - echo ❌ 清理失败 - pause - exit /b 1 -) - -REM 更新依赖 -echo 📥 更新依赖... -cargo update -if %errorlevel% neq 0 ( - echo ❌ 更新依赖失败 - pause - exit /b 1 -) - -REM 检查代码 -echo 🔍 检查代码... -cargo check -if %errorlevel% neq 0 ( - echo ❌ 代码检查失败 - pause - exit /b 1 -) - -REM 运行测试 -echo 🧪 运行测试... -cargo test -if %errorlevel% neq 0 ( - echo ❌ 测试失败 - pause - exit /b 1 -) - -REM 构建发布版本 -echo 🔨 构建发布版本... -cargo build --release -if %errorlevel% neq 0 ( - echo ❌ 构建失败 - pause - exit /b 1 -) - -REM 检查构建结果 -if exist "target\release\gbt.exe" ( - echo ✅ 构建成功! - echo 📁 可执行文件位置: target\release\gbt.exe - - REM 显示文件信息 - echo 📊 文件信息: - dir target\release\gbt.exe - - REM 显示版本信息 - echo ℹ️ 版本信息: - target\release\gbt.exe --version 2>nul || echo 无法获取版本信息 - -) else ( - echo ❌ 构建失败! - pause - exit /b 1 -) - -echo 🎉 GBT项目构建完成! -echo. -echo 📖 使用方法: -echo target\release\gbt.exe --wallet-address ^ -echo. -echo 📖 更多选项: -echo target\release\gbt.exe --help -echo. -pause \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 3042c75..a5a6a1b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -56,6 +56,11 @@ use tari_core::{ }, }; use tari_utilities::hex::Hex; +use tari_utilities::ByteArray; +use jmt::{JellyfishMerkleTree, KeyHash}; +use jmt::mock::MockTreeStore; +use tari_core::chain_storage::SmtHasher; +use tari_core::blocks::Block as CoreBlock; const LOG_TARGET: &str = "gbt::main"; @@ -65,6 +70,7 @@ pub struct MiningTask { pub coinbase_hash: String, pub height: u64, pub target: u64, + pub output_smt_size: u64, // 新增:output_smt_size pub block_template: String, // 序列化的区块模板 } @@ -201,6 +207,46 @@ impl GbtClient { Ok(node_conn) } + /// 计算output_smt_size + fn calculate_output_smt_size(&self, block: &CoreBlock, prev_output_smt_size: u64) -> Result { + // 创建JellyfishMerkleTree用于计算 + let mock_store = MockTreeStore::new(true); + let output_smt = JellyfishMerkleTree::<_, SmtHasher>::new(&mock_store); + + let mut batch = Vec::new(); + + // 处理所有输出(添加新的叶子节点) + for output in block.body.outputs() { + if !output.is_burned() { + let smt_key = KeyHash( + output.commitment.as_bytes().try_into().expect("commitment is 32 bytes") + ); + let smt_value = output.smt_hash(block.header.height); + batch.push((smt_key, Some(smt_value.to_vec()))); + } + } + + // 处理所有输入(删除叶子节点) + for input in block.body.inputs() { + let smt_key = KeyHash( + input.commitment()?.as_bytes().try_into().expect("Commitment is 32 bytes") + ); + batch.push((smt_key, None)); + } + + // 计算SMT变化 + let (_, changes) = output_smt + .put_value_set(batch, block.header.height) + .map_err(|e| anyhow!("SMT calculation error: {}", e))?; + + // 计算新的output_smt_size + let mut size = prev_output_smt_size; + size += changes.node_stats.first().map(|s| s.new_leaves).unwrap_or(0) as u64; + size = size.saturating_sub(changes.node_stats.first().map(|s| s.stale_leaves).unwrap_or(0) as u64); + + Ok(size) + } + pub async fn get_block_template_and_coinbase(&mut self) -> Result { info!(target: LOG_TARGET, "Getting new block template"); @@ -274,12 +320,29 @@ impl GbtClient { body.kernels.push(coinbase_kernel.into()); // 获取完整的区块 - let block_result = self.base_node_client.get_new_block(block_template).await?.into_inner(); + let block_result = self.base_node_client.get_new_block(block_template.clone()).await?.into_inner(); let block = block_result.block.ok_or_else(|| anyhow!("No block in response"))?; // 计算coinbase哈希 let coinbase_hash = coinbase_output.hash().to_hex(); + // 将gRPC Block转换为CoreBlock以便计算output_smt_size + let core_block: CoreBlock = block.clone().try_into() + .map_err(|e| anyhow!("Block conversion error: {}", e))?; + + // 获取前一个区块的output_smt_size(从区块模板头中获取) + let prev_output_smt_size = block_template + .header + .as_ref() + .ok_or_else(|| anyhow!("No header in block template"))? + .output_smt_size; + + // 计算新的output_smt_size + let calculated_output_smt_size = self.calculate_output_smt_size(&core_block, prev_output_smt_size)?; + + info!(target: LOG_TARGET, "Calculated output_smt_size: {} (prev: {})", + calculated_output_smt_size, prev_output_smt_size); + // 序列化区块模板 let block_template_json = serde_json::to_string(&block).map_err(|e| anyhow!("Serialization error: {}", e))?; @@ -287,6 +350,7 @@ impl GbtClient { coinbase_hash, height, target: target_difficulty, + output_smt_size: calculated_output_smt_size, // 使用计算出的值 block_template: block_template_json, }; @@ -307,7 +371,8 @@ impl GbtClient { .send_multipart(&["mining_task".as_bytes(), task_json.as_bytes()], 0) .map_err(|e| anyhow!("ZMQ send error: {}", e))?; - info!(target: LOG_TARGET, "Sent mining task for height {} with target {}", task.height, task.target); + info!(target: LOG_TARGET, "Sent mining task for height {} with target {} and output_smt_size {}", + task.height, task.target, task.output_smt_size); Ok(()) }