NAC_Blockchain/nac-bridge-ethereum/src/spv.rs

202 lines
5.3 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! SPV (Simplified Payment Verification) 证明验证模块
//!
//! 实现以太坊交易的SPV证明生成和验证
use sha3::{Digest, Keccak256};
use serde::{Deserialize, Serialize};
/// SPV证明验证器
pub struct SPVProofVerifier;
/// Merkle证明
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MerkleProof {
/// 交易索引
pub tx_index: u64,
/// Merkle路径
pub proof: Vec<Vec<u8>>,
/// 根哈希
pub root: Vec<u8>,
}
impl SPVProofVerifier {
/// 创建新的SPV证明验证器
pub fn new() -> Self {
Self
}
/// 验证Merkle证明
///
/// # 参数
/// - `tx_hash`: 交易哈希
/// - `proof`: Merkle证明
///
/// # 返回
/// - `true`: 证明有效
/// - `false`: 证明无效
pub fn verify_merkle_proof(
&self,
tx_hash: &[u8],
proof: &MerkleProof,
) -> bool {
let mut current_hash = tx_hash.to_vec();
let mut index = proof.tx_index;
// 沿着Merkle树向上验证
for sibling in &proof.proof {
let mut hasher = Keccak256::new();
if index % 2 == 0 {
// 当前节点在左边
hasher.update(&current_hash);
hasher.update(sibling);
} else {
// 当前节点在右边
hasher.update(sibling);
hasher.update(&current_hash);
}
current_hash = hasher.finalize().to_vec();
index /= 2;
}
// 检查是否等于根哈希
current_hash == proof.root
}
/// 生成Merkle证明简化版
///
/// # 参数
/// - `tx_hashes`: 区块中的所有交易哈希
/// - `tx_index`: 目标交易的索引
///
/// # 返回
/// Merkle证明
pub fn generate_merkle_proof(
&self,
tx_hashes: &[Vec<u8>],
tx_index: usize,
) -> Option<MerkleProof> {
if tx_index >= tx_hashes.len() {
return None;
}
let mut proof = Vec::new();
let mut current_level = tx_hashes.to_vec();
let mut index = tx_index;
// 构建Merkle树
while current_level.len() > 1 {
let mut next_level = Vec::new();
// 记录当前层的兄弟节点
let sibling_index = if index % 2 == 0 { index + 1 } else { index - 1 };
if sibling_index < current_level.len() {
proof.push(current_level[sibling_index].clone());
}
// 计算下一层
for i in (0..current_level.len()).step_by(2) {
let mut hasher = Keccak256::new();
hasher.update(&current_level[i]);
if i + 1 < current_level.len() {
hasher.update(&current_level[i + 1]);
} else {
// 奇数个节点,复制最后一个
hasher.update(&current_level[i]);
}
next_level.push(hasher.finalize().to_vec());
}
current_level = next_level;
index /= 2;
}
let root = current_level[0].clone();
Some(MerkleProof {
tx_index: tx_index as u64,
proof,
root,
})
}
/// 验证区块头
///
/// # 参数
/// - `block_header`: 区块头数据
/// - `expected_hash`: 期望的区块哈希
///
/// # 返回
/// - `true`: 区块头有效
/// - `false`: 区块头无效
pub fn verify_block_header(
&self,
block_header: &[u8],
expected_hash: &[u8],
) -> bool {
let mut hasher = Keccak256::new();
hasher.update(block_header);
let hash = hasher.finalize();
hash.as_slice() == expected_hash
}
}
impl Default for SPVProofVerifier {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_merkle_proof_generation_and_verification() {
let verifier = SPVProofVerifier::new();
// 创建4个交易哈希
let tx_hashes: Vec<Vec<u8>> = vec![
vec![1, 2, 3, 4],
vec![5, 6, 7, 8],
vec![9, 10, 11, 12],
vec![13, 14, 15, 16],
];
// 为第2个交易生成证明
let proof = verifier.generate_merkle_proof(&tx_hashes, 1);
assert!(proof.is_some());
let proof = proof.unwrap();
// 验证证明
let is_valid = verifier.verify_merkle_proof(&tx_hashes[1], &proof);
assert!(is_valid);
}
#[test]
fn test_block_header_verification() {
let verifier = SPVProofVerifier::new();
let block_header = b"test block header";
// 计算期望的哈希
let mut hasher = Keccak256::new();
hasher.update(block_header);
let expected_hash = hasher.finalize();
// 验证
let is_valid = verifier.verify_block_header(block_header, &expected_hash);
assert!(is_valid);
// 错误的哈希
let wrong_hash = vec![0u8; 32];
let is_valid = verifier.verify_block_header(block_header, &wrong_hash);
assert!(!is_valid);
}
}