// 调试脚本:测试GBT项目的output_smt_size计算 // 使用实际的区块数据来验证计算是否正确 use serde_json::Value; // 模拟GBT项目中的calculate_output_smt_size函数 fn calculate_output_smt_size( prev_output_smt_size: u64, outputs: &[String], // JSON字符串格式 inputs: &[String], // JSON字符串格式 ) -> u64 { let mut size = prev_output_smt_size; let mut new_leaves = 0u64; let mut stale_leaves = 0u64; println!("=== 计算新叶子数量(排除销毁输出) ==="); // 计算新叶子数量(排除销毁输出) for (i, output_json) in outputs.iter().enumerate() { match serde_json::from_str::(output_json) { Ok(output) => { // 尝试多种可能的JSON结构 let is_burned = if let Some(features) = output.get("features") { if let Some(output_type) = features.get("output_type") { let burned = output_type.as_u64() == Some(2); // Burn = 2 println!("Output {}: features.output_type = {:?}, burned = {}", i, output_type, burned); burned } else { println!("Output {}: features.output_type not found, assuming not burned", i); false } } else if let Some(output_type) = output.get("output_type") { let burned = output_type.as_u64() == Some(2); // Burn = 2 println!("Output {}: output_type = {:?}, burned = {}", i, output_type, burned); burned } else { println!("Output {}: no output_type found, assuming not burned", i); false }; if !is_burned { new_leaves += 1; println!("Output {}: not burned, adding leaf (new_leaves = {})", i, new_leaves); } else { println!("Output {}: burned, skipping", i); } }, Err(e) => { println!("Failed to parse output {} JSON: {}, assuming not burned", i, e); new_leaves += 1; // 保守策略:假设不是销毁输出 } } } println!("\n=== 计算移除叶子数量(排除销毁输入) ==="); // 计算移除叶子数量(排除销毁输入) for (i, input_json) in inputs.iter().enumerate() { match serde_json::from_str::(input_json) { Ok(input) => { // 尝试多种可能的JSON结构 let is_burned = if let Some(features) = input.get("features") { if let Some(output_type) = features.get("output_type") { let burned = output_type.as_u64() == Some(2); // Burn = 2 println!("Input {}: features.output_type = {:?}, burned = {}", i, output_type, burned); burned } else { println!("Input {}: features.output_type not found, assuming not burned", i); false } } else if let Some(output_type) = input.get("output_type") { let burned = output_type.as_u64() == Some(2); // Burn = 2 println!("Input {}: output_type = {:?}, burned = {}", i, output_type, burned); burned } else { println!("Input {}: no output_type found, assuming not burned", i); false }; if !is_burned { stale_leaves += 1; println!("Input {}: not burned, removing leaf (stale_leaves = {})", i, stale_leaves); } else { println!("Input {}: burned, skipping", i); } }, Err(e) => { println!("Failed to parse input {} JSON: {}, assuming not burned", i, e); stale_leaves += 1; // 保守策略:假设不是销毁输入 } } } size += new_leaves; size = size.saturating_sub(stale_leaves); println!("\n=== 计算结果 ==="); println!("output_smt_size calculation: {} (prev) + {} (new_leaves) - {} (stale_leaves) = {} (current)", prev_output_smt_size, new_leaves, stale_leaves, size); size } fn main() { println!("GBT项目 output_smt_size 计算调试"); println!("================================\n"); // 使用你提供的实际数据 let prev_output_smt_size = 809326; // 区块链上的实际值 // 这里需要实际的outputs和inputs JSON数据 // 由于你没有提供具体的outputs和inputs数据,我们创建一个示例 println!("测试用例1: 基本计算"); println!("prev_output_smt_size = {}", prev_output_smt_size); // 示例数据(你需要用实际的数据替换) let outputs = vec![ r#"{"features": {"output_type": 0}}"#.to_string(), // Standard output r#"{"features": {"output_type": 1}}"#.to_string(), // Coinbase output r#"{"features": {"output_type": 2}}"#.to_string(), // Burned output ]; let inputs = vec![ r#"{"features": {"output_type": 0}}"#.to_string(), // Standard input r#"{"features": {"output_type": 2}}"#.to_string(), // Burned input ]; let calculated_size = calculate_output_smt_size(prev_output_smt_size, &outputs, &inputs); println!("\n=== 最终结果 ==="); println!("期望值: 809326"); println!("计算值: {}", calculated_size); println!("差异: {}", 809326i64 - calculated_size as i64); if calculated_size == 809326 { println!("✅ 计算正确!"); } else { println!("❌ 计算错误!需要调试JSON数据结构"); } println!("\n=== 调试建议 ==="); println!("1. 检查实际的outputs和inputs JSON结构"); println!("2. 确认output_type字段的位置和值"); println!("3. 验证销毁输出的识别逻辑"); println!("4. 检查是否有其他影响SMT大小的因素"); }