NAC_Blockchain/nac-csnp-l0/src/gids_jurisdiction_proof.rs

416 lines
14 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.

// nac-csnp-l0/src/gids_jurisdiction_proof.rs
// GIDS 辖区证明增强 + 宪法法院链上裁决
//
// 核心原则:
// 约法即是治法 — 宪法法院裁决依据辖区真实法律文件哈希,裁决即生效
// 宪法即是规则 — 辖区规则来自政府授权 CA 签名的真实法律,不是链上投票
// 链上投票不能改变国家法律 — 宪法法院是法律执行机构,不是立法机构
// 参与即是共识 — 节点将裁决记录打包进区块即是对裁决合法性的背书
use serde::{Deserialize, Serialize};
use sha3::{Digest, Sha3_384};
pub type JurisdictionId = u32;
/// 辖区证明GIDS 增强版)
///
/// 节点身份绑定辖区证明 + 插件哈希,
/// 证明来自辖区政府授权 CA 签名,不是链上治理决定。
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct JurisdictionProof {
/// 节点 DID全局身份标识符
pub node_did: Vec<u8>,
/// 所属辖区
pub jurisdiction: JurisdictionId,
/// 辖区政府授权 CA 签名(证明节点合法注册于该辖区)
pub jurisdiction_ca_signature: Vec<u8>,
/// 当前加载的辖区插件哈希SHA3-384
pub plugin_hash: Vec<u8>,
/// 插件版本
pub plugin_version: u32,
/// 辖区政府对插件版本的授权签名
/// 插件更新必须经辖区监管机构授权,不是链上治理决定
pub plugin_authorization_signature: Vec<u8>,
/// 证明生效时间戳
pub effective_timestamp: u64,
/// 证明过期时间戳(辖区政府设定,不是链上投票决定)
pub expiry_timestamp: u64,
}
impl JurisdictionProof {
/// 验证辖区证明的基本合法性
pub fn is_valid(&self, current_timestamp: u64) -> ProofValidation {
if self.jurisdiction_ca_signature.is_empty() {
return ProofValidation::Invalid("缺少辖区 CA 签名".to_string());
}
if self.plugin_authorization_signature.is_empty() {
return ProofValidation::Invalid("缺少插件授权签名".to_string());
}
if self.plugin_hash.is_empty() {
return ProofValidation::Invalid("缺少插件哈希".to_string());
}
if current_timestamp > self.expiry_timestamp {
return ProofValidation::Expired {
expired_at: self.expiry_timestamp,
};
}
if current_timestamp < self.effective_timestamp {
return ProofValidation::NotYetEffective {
effective_at: self.effective_timestamp,
};
}
ProofValidation::Valid
}
/// 计算证明哈希(用于链上存证)
pub fn compute_hash(&self) -> Vec<u8> {
let mut hasher = Sha3_384::new();
hasher.update(&self.node_did);
hasher.update(&self.jurisdiction.to_be_bytes());
hasher.update(&self.plugin_hash);
hasher.update(&self.plugin_version.to_be_bytes());
hasher.update(&self.effective_timestamp.to_be_bytes());
hasher.update(&self.expiry_timestamp.to_be_bytes());
hasher.finalize().to_vec()
}
}
/// 辖区证明验证结果
#[derive(Debug, PartialEq)]
pub enum ProofValidation {
Valid,
Invalid(String),
Expired { expired_at: u64 },
NotYetEffective { effective_at: u64 },
}
/// 宪法法院裁决
///
/// 宪法法院是链上的法律执行机构,不是立法机构。
/// 裁决依据:辖区已注册的真实法律文件哈希(链上存证)。
/// 裁决即生效:无需链上投票确认(约法即是治法)。
/// 链上投票不能改变国家法律,因此裁决不经过投票。
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConstitutionalCourtRuling {
/// 裁决 IDSHA3-384
pub ruling_id: Vec<u8>,
/// 案件类型
pub case_type: CourtCaseType,
/// 涉及辖区
pub jurisdictions: Vec<JurisdictionId>,
/// 裁决依据的法律文件哈希列表(链上存证的真实法规)
/// 这些哈希对应辖区政府授权 CA 签名的真实法律文件
pub legal_basis_hashes: Vec<Vec<u8>>,
/// 裁决结论
pub conclusion: RulingConclusion,
/// 裁决理由(引用具体法律条款)
pub reasoning: String,
/// 裁决生效时间戳(裁决即生效,无需等待投票)
pub effective_timestamp: u64,
/// 执行截止时间戳(由宪法条款规定,不是链上投票决定)
pub execution_deadline: u64,
/// 裁决机构签名(宪法法院节点的私钥签名)
pub court_signature: Vec<u8>,
}
/// 宪法法院案件类型
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum CourtCaseType {
/// 辖区规则冲突(不同辖区法律对同一资产类型有互斥要求)
JurisdictionRuleConflict,
/// 节点违规(节点行为违反宪法条款)
NodeViolation,
/// 插件合法性争议(插件规则是否符合辖区真实法律)
PluginLegalityDispute,
/// 跨辖区资产合规争议
CrossJurisdictionComplianceDispute,
}
/// 裁决结论
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum RulingConclusion {
/// 支持(申请方合规)
Upheld,
/// 驳回(申请方违规)
Dismissed,
/// 辖区规则冲突:按优先级辖区规则执行
ConflictResolved {
/// 优先适用的辖区(通常为资产注册辖区)
primary_jurisdiction: JurisdictionId,
},
/// 要求辖区更新插件(辖区法律已变更,插件需同步)
PluginUpdateRequired {
jurisdiction: JurisdictionId,
/// 新插件必须经辖区政府重新授权签名
required_by: u64,
},
}
/// 宪法法院
///
/// 负责解决跨辖区法律冲突,裁决依据辖区真实法律文件。
/// 裁决即生效,无需链上投票(链上投票不能改变国家法律)。
pub struct ConstitutionalCourt {
/// 已注册的辖区法律文件哈希(辖区 → 法律文件哈希列表)
/// 这些哈希对应辖区政府授权 CA 签名的真实法律文件
registered_law_hashes: std::collections::HashMap<JurisdictionId, Vec<Vec<u8>>>,
/// 已生效的裁决记录
rulings: Vec<ConstitutionalCourtRuling>,
}
impl ConstitutionalCourt {
pub fn new() -> Self {
Self {
registered_law_hashes: std::collections::HashMap::new(),
rulings: Vec::new(),
}
}
/// 注册辖区法律文件哈希
///
/// 法律文件由辖区政府授权 CA 签名后上传,哈希存证于链上。
/// 这是宪法法院裁决的唯一依据。
pub fn register_law_documents(
&mut self,
jurisdiction: JurisdictionId,
law_hashes: Vec<Vec<u8>>,
ca_signature: &[u8],
) -> Result<(), String> {
if ca_signature.is_empty() {
return Err("法律文件注册必须提供辖区政府授权 CA 签名".to_string());
}
if law_hashes.is_empty() {
return Err("法律文件哈希列表不可为空".to_string());
}
self.registered_law_hashes.insert(jurisdiction, law_hashes);
Ok(())
}
/// 发布裁决
///
/// 裁决依据已注册的辖区法律文件哈希。
/// 裁决即生效,无需链上投票(约法即是治法)。
pub fn issue_ruling(
&mut self,
case_type: CourtCaseType,
jurisdictions: Vec<JurisdictionId>,
conclusion: RulingConclusion,
reasoning: String,
effective_timestamp: u64,
execution_deadline: u64,
court_signature: Vec<u8>,
) -> Result<Vec<u8>, String> {
if court_signature.is_empty() {
return Err("裁决必须有宪法法院节点签名".to_string());
}
// 验证裁决依据的法律文件是否已注册
let mut legal_basis_hashes = Vec::new();
for &jid in &jurisdictions {
if let Some(hashes) = self.registered_law_hashes.get(&jid) {
legal_basis_hashes.extend(hashes.clone());
}
// 注意:即使辖区未注册法律文件,裁决仍可发布
// 但裁决理由中必须说明(宪法即是规则)
}
// 计算裁决 ID
let mut hasher = Sha3_384::new();
hasher.update(&(case_type == CourtCaseType::JurisdictionRuleConflict).to_string().as_bytes());
for &jid in &jurisdictions {
hasher.update(&jid.to_be_bytes());
}
hasher.update(&effective_timestamp.to_be_bytes());
hasher.update(reasoning.as_bytes());
let ruling_id = hasher.finalize().to_vec();
let ruling = ConstitutionalCourtRuling {
ruling_id: ruling_id.clone(),
case_type,
jurisdictions,
legal_basis_hashes,
conclusion,
reasoning,
effective_timestamp,
execution_deadline,
court_signature,
};
self.rulings.push(ruling);
Ok(ruling_id)
}
/// 查询裁决(按裁决 ID
pub fn get_ruling(&self, ruling_id: &[u8]) -> Option<&ConstitutionalCourtRuling> {
self.rulings.iter().find(|r| r.ruling_id == ruling_id)
}
/// 查询辖区的所有相关裁决
pub fn get_rulings_for_jurisdiction(
&self,
jurisdiction: JurisdictionId,
) -> Vec<&ConstitutionalCourtRuling> {
self.rulings
.iter()
.filter(|r| r.jurisdictions.contains(&jurisdiction))
.collect()
}
/// 获取裁决总数
pub fn ruling_count(&self) -> usize {
self.rulings.len()
}
/// 检查辖区是否有已注册的法律文件
pub fn has_registered_laws(&self, jurisdiction: JurisdictionId) -> bool {
self.registered_law_hashes.contains_key(&jurisdiction)
}
}
impl Default for ConstitutionalCourt {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
fn make_proof(jurisdiction: JurisdictionId, ts: u64) -> JurisdictionProof {
JurisdictionProof {
node_did: vec![0x01; 32],
jurisdiction,
jurisdiction_ca_signature: vec![0xCA; 64],
plugin_hash: vec![0xAB; 48],
plugin_version: 100,
plugin_authorization_signature: vec![0xAU; 64],
effective_timestamp: ts,
expiry_timestamp: ts + 86400 * 365, // 1年有效期
}
}
#[test]
fn test_jurisdiction_proof_valid() {
let proof = make_proof(784, 1700000000);
assert_eq!(proof.is_valid(1700000000), ProofValidation::Valid);
}
#[test]
fn test_jurisdiction_proof_expired() {
let proof = make_proof(784, 1700000000);
// 超过过期时间
let result = proof.is_valid(1700000000 + 86400 * 365 + 1);
assert!(matches!(result, ProofValidation::Expired { .. }));
}
#[test]
fn test_jurisdiction_proof_missing_ca_signature() {
let mut proof = make_proof(784, 1700000000);
proof.jurisdiction_ca_signature = vec![];
assert!(matches!(proof.is_valid(1700000000), ProofValidation::Invalid(_)));
}
#[test]
fn test_court_ruling_no_vote_required() {
// 约法即是治法:裁决即生效,无需投票
let mut court = ConstitutionalCourt::new();
// 注册法律文件(辖区政府授权 CA 签名)
court.register_law_documents(
784,
vec![vec![0xAB; 48]],
&[0xCA; 64],
).unwrap();
// 发布裁决(直接生效,无需投票)
let ruling_id = court.issue_ruling(
CourtCaseType::JurisdictionRuleConflict,
vec![784, 156],
RulingConclusion::ConflictResolved { primary_jurisdiction: 784 },
"依据 UAE VARA 法规第3条资产注册辖区规则优先".to_string(),
1700000000,
1700000000 + 86400 * 30, // 30天执行期
vec![0xCC; 64],
);
assert!(ruling_id.is_ok());
let id = ruling_id.unwrap();
// 裁决立即可查询(无需等待投票)
let ruling = court.get_ruling(&id);
assert!(ruling.is_some());
assert_eq!(court.ruling_count(), 1);
}
#[test]
fn test_court_ruling_requires_court_signature() {
// 裁决必须有宪法法院节点签名
let mut court = ConstitutionalCourt::new();
let result = court.issue_ruling(
CourtCaseType::NodeViolation,
vec![784],
RulingConclusion::Dismissed,
"节点违规".to_string(),
1700000000,
1700000000 + 86400,
vec![], // 无签名
);
assert!(result.is_err());
}
#[test]
fn test_law_registration_requires_ca_signature() {
// 法律文件注册必须有 CA 签名(来自辖区政府授权)
let mut court = ConstitutionalCourt::new();
let result = court.register_law_documents(
784,
vec![vec![0xAB; 48]],
&[], // 无 CA 签名
);
assert!(result.is_err());
}
#[test]
fn test_ruling_references_real_law_hashes() {
// 裁决依据真实法律文件哈希,不是链上投票结果
let mut court = ConstitutionalCourt::new();
let law_hash = vec![0xDE; 48];
court.register_law_documents(784, vec![law_hash.clone()], &[0xCA; 64]).unwrap();
let ruling_id = court.issue_ruling(
CourtCaseType::PluginLegalityDispute,
vec![784],
RulingConclusion::Upheld,
"依据已注册法律文件验证".to_string(),
1700000000,
1700000000 + 86400,
vec![0xCC; 64],
).unwrap();
let ruling = court.get_ruling(&ruling_id).unwrap();
// 裁决中包含真实法律文件哈希作为依据
assert!(ruling.legal_basis_hashes.contains(&law_hash));
}
#[test]
fn test_jurisdiction_query_rulings() {
let mut court = ConstitutionalCourt::new();
court.register_law_documents(784, vec![vec![0xAB; 48]], &[0xCA; 64]).unwrap();
court.register_law_documents(156, vec![vec![0xCD; 48]], &[0xCA; 64]).unwrap();
court.issue_ruling(
CourtCaseType::JurisdictionRuleConflict,
vec![784, 156],
RulingConclusion::ConflictResolved { primary_jurisdiction: 784 },
"辖区冲突裁决".to_string(),
1700000000, 1700000000 + 86400, vec![0xCC; 64],
).unwrap();
// 两个辖区都能查到相关裁决
assert_eq!(court.get_rulings_for_jurisdiction(784).len(), 1);
assert_eq!(court.get_rulings_for_jurisdiction(156).len(), 1);
assert_eq!(court.get_rulings_for_jurisdiction(840).len(), 0); // 无关辖区
}
}