add base64 to hex
add output_smt_size but encording still is base64
This commit is contained in:
69
src/main.rs
69
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<u64> {
|
||||
// 创建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<MiningTask> {
|
||||
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(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user