334 lines
10 KiB
Rust
334 lines
10 KiB
Rust
// Constitutional Receipt (CR) System
|
||
// 宪法收据系统 - CBPP核心组件
|
||
|
||
use serde::{Deserialize, Serialize};
|
||
use serde_big_array::BigArray;
|
||
use sha2::Digest;
|
||
use std::time::{SystemTime, UNIX_EPOCH};
|
||
|
||
/// 宪法收据 - 交易进入区块链的唯一凭证
|
||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||
pub struct ConstitutionalReceipt {
|
||
/// 对应交易的哈希 (NAC使用SHA3-384, 48字节)
|
||
#[serde(with = "BigArray")]
|
||
pub transaction_hash: [u8; 48],
|
||
|
||
/// 当前宪法版本哈希(确保收据只在特定宪法版本下有效)
|
||
#[serde(with = "BigArray")]
|
||
pub constitutional_hash: [u8; 48],
|
||
|
||
/// 触发的主要宪法条款索引
|
||
pub clause_index: u64,
|
||
|
||
/// AI引擎执行结果的Merkle根(允许验证结果但不泄露细节)
|
||
#[serde(with = "BigArray")]
|
||
pub execution_result_hash: [u8; 48],
|
||
|
||
/// 收据生成时间(Unix时间戳,毫秒)
|
||
pub timestamp: u64,
|
||
|
||
/// 收据有效期(区块高度数量,如120个区块)
|
||
pub validity_window: u64,
|
||
|
||
/// 宪法执行引擎(或指定验证组)的签名
|
||
pub validator_signature: Vec<u8>,
|
||
|
||
/// ReceiptID = Hash(上述所有字段) (NAC使用SHA3-384, 48字节)
|
||
#[serde(with = "BigArray")]
|
||
pub receipt_id: [u8; 48],
|
||
}
|
||
|
||
impl ConstitutionalReceipt {
|
||
/// 创建新的宪法收据
|
||
pub fn new(
|
||
transaction_hash: [u8; 48],
|
||
constitutional_hash: [u8; 48],
|
||
clause_index: u64,
|
||
execution_result_hash: [u8; 48],
|
||
validity_window: u64,
|
||
validator_signature: Vec<u8>,
|
||
) -> Self {
|
||
let timestamp = SystemTime::now()
|
||
.duration_since(UNIX_EPOCH)
|
||
.unwrap()
|
||
.as_millis() as u64;
|
||
|
||
let mut receipt = Self {
|
||
transaction_hash,
|
||
constitutional_hash,
|
||
clause_index,
|
||
execution_result_hash,
|
||
timestamp,
|
||
validity_window,
|
||
validator_signature,
|
||
receipt_id: [0u8; 48],
|
||
};
|
||
|
||
// 计算receipt_id
|
||
receipt.receipt_id = receipt.calculate_id();
|
||
receipt
|
||
}
|
||
|
||
/// 计算收据ID(所有字段的哈希)
|
||
fn calculate_id(&self) -> [u8; 48] {
|
||
use sha3::Sha3_384;
|
||
let mut hasher = Sha3_384::new();
|
||
hasher.update(&self.transaction_hash);
|
||
hasher.update(&self.constitutional_hash);
|
||
hasher.update(&self.clause_index.to_le_bytes());
|
||
hasher.update(&self.execution_result_hash);
|
||
hasher.update(&self.timestamp.to_le_bytes());
|
||
hasher.update(&self.validity_window.to_le_bytes());
|
||
hasher.update(&self.validator_signature);
|
||
|
||
let result = hasher.finalize();
|
||
let mut id = [0u8; 48];
|
||
id.copy_from_slice(&result);
|
||
id
|
||
}
|
||
|
||
/// 验证收据ID是否正确
|
||
pub fn verify_id(&self) -> bool {
|
||
let calculated_id = self.calculate_id();
|
||
calculated_id == self.receipt_id
|
||
}
|
||
|
||
/// 检查收据是否在有效期内
|
||
pub fn is_valid_at_height(&self, current_height: u64, receipt_height: u64) -> bool {
|
||
current_height <= receipt_height + self.validity_window
|
||
}
|
||
|
||
/// 检查收据是否与指定的宪法版本匹配
|
||
pub fn matches_constitution(&self, constitutional_hash: [u8; 48]) -> bool {
|
||
self.constitutional_hash == constitutional_hash
|
||
}
|
||
|
||
/// 序列化为字节数组(使用NAC原生二进制格式)
|
||
pub fn to_bytes(&self) -> Vec<u8> {
|
||
bincode::serialize(self).expect("Failed to serialize ConstitutionalReceipt")
|
||
}
|
||
|
||
/// 从字节数组反序列化
|
||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, String> {
|
||
bincode::deserialize(bytes).map_err(|e| format!("Failed to deserialize: {}", e))
|
||
}
|
||
}
|
||
|
||
/// 宪法执行引擎接口
|
||
pub trait ConstitutionalExecutionEngine {
|
||
/// 验证交易并生成宪法收据
|
||
fn validate_and_issue_receipt(
|
||
&self,
|
||
transaction_hash: [u8; 48],
|
||
transaction_data: &[u8],
|
||
) -> Result<ConstitutionalReceipt, String>;
|
||
|
||
/// 获取当前宪法版本哈希
|
||
fn get_constitutional_hash(&self) -> [u8; 48];
|
||
|
||
/// 验证收据签名
|
||
fn verify_signature(&self, receipt: &ConstitutionalReceipt) -> bool;
|
||
}
|
||
|
||
/// 宪法收据管理器
|
||
pub struct ConstitutionalReceiptManager {
|
||
/// 当前宪法版本哈希
|
||
constitutional_hash: [u8; 48],
|
||
|
||
/// 收据缓存 (receipt_id -> receipt)
|
||
receipt_cache: std::collections::HashMap<[u8; 48], ConstitutionalReceipt>,
|
||
|
||
/// 收据高度映射 (receipt_id -> block_height)
|
||
receipt_heights: std::collections::HashMap<[u8; 48], u64>,
|
||
}
|
||
|
||
impl ConstitutionalReceiptManager {
|
||
/// 创建新的收据管理器
|
||
pub fn new(constitutional_hash: [u8; 48]) -> Self {
|
||
Self {
|
||
constitutional_hash,
|
||
receipt_cache: std::collections::HashMap::new(),
|
||
receipt_heights: std::collections::HashMap::new(),
|
||
}
|
||
}
|
||
|
||
/// 添加收据到缓存
|
||
pub fn add_receipt(&mut self, receipt: ConstitutionalReceipt, block_height: u64) {
|
||
self.receipt_cache.insert(receipt.receipt_id, receipt.clone());
|
||
self.receipt_heights.insert(receipt.receipt_id, block_height);
|
||
}
|
||
|
||
/// 获取收据
|
||
pub fn get_receipt(&self, receipt_id: &[u8; 48]) -> Option<&ConstitutionalReceipt> {
|
||
self.receipt_cache.get(receipt_id)
|
||
}
|
||
|
||
/// 验证收据
|
||
pub fn verify_receipt(
|
||
&self,
|
||
receipt: &ConstitutionalReceipt,
|
||
current_height: u64,
|
||
) -> Result<(), String> {
|
||
// 1. 验证receipt_id
|
||
if !receipt.verify_id() {
|
||
return Err("Invalid receipt ID".to_string());
|
||
}
|
||
|
||
// 2. 验证宪法版本
|
||
if !receipt.matches_constitution(self.constitutional_hash) {
|
||
return Err("Constitutional hash mismatch".to_string());
|
||
}
|
||
|
||
// 3. 验证有效期
|
||
if let Some(&receipt_height) = self.receipt_heights.get(&receipt.receipt_id) {
|
||
if !receipt.is_valid_at_height(current_height, receipt_height) {
|
||
return Err("Receipt expired".to_string());
|
||
}
|
||
} else {
|
||
return Err("Receipt not found in cache".to_string());
|
||
}
|
||
|
||
Ok(())
|
||
}
|
||
|
||
/// 清理过期的收据
|
||
pub fn cleanup_expired(&mut self, current_height: u64) {
|
||
let expired_ids: Vec<[u8; 48]> = self
|
||
.receipt_heights
|
||
.iter()
|
||
.filter(|(id, &height)| {
|
||
if let Some(receipt) = self.receipt_cache.get(*id) {
|
||
!receipt.is_valid_at_height(current_height, height)
|
||
} else {
|
||
true
|
||
}
|
||
})
|
||
.map(|(id, _)| *id)
|
||
.collect();
|
||
|
||
for id in expired_ids {
|
||
self.receipt_cache.remove(&id);
|
||
self.receipt_heights.remove(&id);
|
||
}
|
||
}
|
||
|
||
/// 更新宪法版本
|
||
pub fn update_constitution(&mut self, new_constitutional_hash: [u8; 48]) {
|
||
self.constitutional_hash = new_constitutional_hash;
|
||
// 清空所有旧收据(宪法升级后旧收据失效)
|
||
self.receipt_cache.clear();
|
||
self.receipt_heights.clear();
|
||
}
|
||
|
||
/// 获取缓存统计信息
|
||
pub fn get_stats(&self) -> (usize, usize) {
|
||
(self.receipt_cache.len(), self.receipt_heights.len())
|
||
}
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::*;
|
||
|
||
fn create_test_receipt() -> ConstitutionalReceipt {
|
||
ConstitutionalReceipt::new(
|
||
[1u8; 48],
|
||
[2u8; 48],
|
||
100,
|
||
[3u8; 48],
|
||
120,
|
||
vec![4u8; 64],
|
||
)
|
||
}
|
||
|
||
#[test]
|
||
fn test_receipt_creation() {
|
||
let receipt = create_test_receipt();
|
||
assert_eq!(receipt.transaction_hash, [1u8; 48]);
|
||
assert_eq!(receipt.constitutional_hash, [2u8; 48]);
|
||
assert_eq!(receipt.clause_index, 100);
|
||
assert_eq!(receipt.validity_window, 120);
|
||
}
|
||
|
||
#[test]
|
||
fn test_receipt_id_verification() {
|
||
let receipt = create_test_receipt();
|
||
assert!(receipt.verify_id());
|
||
}
|
||
|
||
#[test]
|
||
fn test_receipt_validity_window() {
|
||
let receipt = create_test_receipt();
|
||
assert!(receipt.is_valid_at_height(100, 0)); // 在有效期内
|
||
assert!(receipt.is_valid_at_height(120, 0)); // 边界情况
|
||
assert!(!receipt.is_valid_at_height(121, 0)); // 超出有效期
|
||
}
|
||
|
||
#[test]
|
||
fn test_receipt_constitution_matching() {
|
||
let receipt = create_test_receipt();
|
||
assert!(receipt.matches_constitution([2u8; 48]));
|
||
assert!(!receipt.matches_constitution([3u8; 48]));
|
||
}
|
||
|
||
#[test]
|
||
fn test_receipt_serialization() {
|
||
let receipt = create_test_receipt();
|
||
let bytes = receipt.to_bytes();
|
||
let deserialized = ConstitutionalReceipt::from_bytes(&bytes).unwrap();
|
||
assert_eq!(receipt, deserialized);
|
||
}
|
||
|
||
#[test]
|
||
fn test_receipt_manager() {
|
||
let mut manager = ConstitutionalReceiptManager::new([2u8; 48]);
|
||
let receipt = create_test_receipt();
|
||
|
||
manager.add_receipt(receipt.clone(), 0);
|
||
|
||
let retrieved = manager.get_receipt(&receipt.receipt_id);
|
||
assert!(retrieved.is_some());
|
||
assert_eq!(retrieved.unwrap(), &receipt);
|
||
}
|
||
|
||
#[test]
|
||
fn test_receipt_verification() {
|
||
let mut manager = ConstitutionalReceiptManager::new([2u8; 48]);
|
||
let receipt = create_test_receipt();
|
||
|
||
manager.add_receipt(receipt.clone(), 0);
|
||
|
||
// 应该验证通过
|
||
assert!(manager.verify_receipt(&receipt, 100).is_ok());
|
||
|
||
// 超出有效期应该失败
|
||
assert!(manager.verify_receipt(&receipt, 121).is_err());
|
||
}
|
||
|
||
#[test]
|
||
fn test_cleanup_expired() {
|
||
let mut manager = ConstitutionalReceiptManager::new([2u8; 48]);
|
||
let receipt = create_test_receipt();
|
||
|
||
manager.add_receipt(receipt.clone(), 0);
|
||
assert_eq!(manager.get_stats(), (1, 1));
|
||
|
||
// 清理过期收据
|
||
manager.cleanup_expired(121);
|
||
assert_eq!(manager.get_stats(), (0, 0));
|
||
}
|
||
|
||
#[test]
|
||
fn test_constitution_update() {
|
||
let mut manager = ConstitutionalReceiptManager::new([2u8; 48]);
|
||
let receipt = create_test_receipt();
|
||
|
||
manager.add_receipt(receipt.clone(), 0);
|
||
assert_eq!(manager.get_stats(), (1, 1));
|
||
|
||
// 更新宪法版本,所有旧收据失效
|
||
manager.update_constitution([3u8; 48]);
|
||
assert_eq!(manager.get_stats(), (0, 0));
|
||
}
|
||
}
|