416 lines
14 KiB
Rust
416 lines
14 KiB
Rust
// 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 {
|
||
/// 裁决 ID(SHA3-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); // 无关辖区
|
||
}
|
||
}
|