210 lines
6.8 KiB
Rust
210 lines
6.8 KiB
Rust
// NAC 香港辖区宪法规则验证插件(HK_PLUGIN)
|
||
// CBPP原则:约法即是治法,宪法即是规则,参与即是共识,节点产生区块,交易决定区块大小
|
||
// 此插件由CEE加载,对每笔交易独立出具宪法收据(CR)
|
||
// 参与即是共识:HK辖区节点加载此插件参与出块,即代表对香港辖区宪法规则的背书
|
||
|
||
use serde::{Deserialize, Serialize};
|
||
|
||
/// 香港辖区交易上下文
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct HKTxContext {
|
||
pub from: [u8; 32],
|
||
pub to: [u8; 32],
|
||
pub amount: u128,
|
||
pub asset_type: String,
|
||
pub kyc_level: KycLevel,
|
||
pub aml_cleared: bool,
|
||
pub regulatory_approved: bool,
|
||
pub is_cross_border: bool,
|
||
pub sanctions_cleared: bool,
|
||
}
|
||
|
||
/// KYC等级
|
||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||
pub enum KycLevel {
|
||
None,
|
||
Basic,
|
||
Enhanced,
|
||
Institutional,
|
||
}
|
||
|
||
/// 宪法收据(CR)— 参与即是共识,节点出具CR即代表对规则的背书
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct ConstitutionalReceipt {
|
||
pub jurisdiction: String,
|
||
pub tx_hash: Vec<u8>,
|
||
pub rules_passed: Vec<String>,
|
||
pub timestamp: u64,
|
||
pub plugin_version: String,
|
||
}
|
||
|
||
/// 宪法规则违反错误
|
||
#[derive(Debug, Clone)]
|
||
pub struct ConstitutionalViolation {
|
||
pub rule_id: String,
|
||
pub reason: String,
|
||
}
|
||
|
||
/// 香港辖区宪法规则验证器
|
||
pub struct HKConstitutionalValidator;
|
||
|
||
impl HKConstitutionalValidator {
|
||
pub fn new() -> Self {
|
||
Self
|
||
}
|
||
|
||
/// 验证交易是否符合香港辖区宪法规则
|
||
/// CBPP:参与即是共识,节点调用此函数即代表对规则的背书
|
||
pub fn validate(&self, ctx: &HKTxContext) -> Result<ConstitutionalReceipt, ConstitutionalViolation> {
|
||
let mut rules_passed = Vec::new();
|
||
|
||
// 继承GLOBAL规则验证
|
||
self.validate_global_aml(ctx, &mut rules_passed)?;
|
||
self.validate_global_kyc(ctx, &mut rules_passed)?;
|
||
self.validate_global_sanctions(ctx, &mut rules_passed)?;
|
||
|
||
// 香港辖区特定规则验证
|
||
self.validate_hk_hk_sfo_001(ctx, &mut rules_passed)?;
|
||
self.validate_hk_hk_vasp_001(ctx, &mut rules_passed)?;
|
||
|
||
Ok(ConstitutionalReceipt {
|
||
jurisdiction: "HK".to_string(),
|
||
tx_hash: vec![],
|
||
rules_passed,
|
||
timestamp: 0,
|
||
plugin_version: "v1.0".to_string(),
|
||
})
|
||
}
|
||
|
||
fn validate_global_aml(&self, ctx: &HKTxContext, passed: &mut Vec<String>)
|
||
-> Result<(), ConstitutionalViolation> {
|
||
if !ctx.aml_cleared {
|
||
return Err(ConstitutionalViolation {
|
||
rule_id: "GLOBAL_AML_001".to_string(),
|
||
reason: "AML检查未通过".to_string(),
|
||
});
|
||
}
|
||
passed.push("GLOBAL_AML_001".to_string());
|
||
Ok(())
|
||
}
|
||
|
||
fn validate_global_kyc(&self, ctx: &HKTxContext, passed: &mut Vec<String>)
|
||
-> Result<(), ConstitutionalViolation> {
|
||
if ctx.kyc_level == KycLevel::None {
|
||
return Err(ConstitutionalViolation {
|
||
rule_id: "GLOBAL_KYC_001".to_string(),
|
||
reason: "未完成KYC验证".to_string(),
|
||
});
|
||
}
|
||
passed.push("GLOBAL_KYC_001".to_string());
|
||
Ok(())
|
||
}
|
||
|
||
fn validate_global_sanctions(&self, ctx: &HKTxContext, passed: &mut Vec<String>)
|
||
-> Result<(), ConstitutionalViolation> {
|
||
if !ctx.sanctions_cleared {
|
||
return Err(ConstitutionalViolation {
|
||
rule_id: "GLOBAL_SANCTIONS".to_string(),
|
||
reason: "制裁名单检查未通过".to_string(),
|
||
});
|
||
}
|
||
passed.push("GLOBAL_SANCTIONS".to_string());
|
||
Ok(())
|
||
}
|
||
|
||
fn validate_hk_hk_sfo_001(&self, ctx: &HKTxContext, passed: &mut Vec<String>)
|
||
-> Result<(), ConstitutionalViolation> {
|
||
if ctx.kyc_level == KycLevel::Basic {
|
||
return Err(ConstitutionalViolation {
|
||
rule_id: "HK_SFO_001".to_string(),
|
||
reason: "香港SFO要求须为专业投资者(资产800万港元以上)".to_string(),
|
||
});
|
||
}
|
||
passed.push("HK_SFO_001".to_string());
|
||
Ok(())
|
||
}
|
||
|
||
fn validate_hk_hk_vasp_001(&self, ctx: &HKTxContext, passed: &mut Vec<String>)
|
||
-> Result<(), ConstitutionalViolation> {
|
||
if !ctx.regulatory_approved {
|
||
return Err(ConstitutionalViolation {
|
||
rule_id: "HK_VASP_001".to_string(),
|
||
reason: "须持有SFC颁发的VASP牌照".to_string(),
|
||
});
|
||
}
|
||
passed.push("HK_VASP_001".to_string());
|
||
Ok(())
|
||
}
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::*;
|
||
|
||
fn make_valid_ctx() -> HKTxContext {
|
||
HKTxContext {
|
||
from: [1u8; 32],
|
||
to: [2u8; 32],
|
||
amount: 1000,
|
||
asset_type: "REAL_ESTATE".to_string(),
|
||
kyc_level: KycLevel::Enhanced,
|
||
aml_cleared: true,
|
||
regulatory_approved: true,
|
||
is_cross_border: false,
|
||
sanctions_cleared: true,
|
||
}
|
||
}
|
||
|
||
#[test]
|
||
fn test_valid_transaction() {
|
||
let validator = HKConstitutionalValidator::new();
|
||
let ctx = make_valid_ctx();
|
||
let result = validator.validate(&ctx);
|
||
assert!(result.is_ok(), "合规交易应通过验证");
|
||
let cr = result.unwrap();
|
||
assert_eq!(cr.jurisdiction, "HK");
|
||
assert!(!cr.rules_passed.is_empty());
|
||
}
|
||
|
||
#[test]
|
||
fn test_aml_violation() {
|
||
let validator = HKConstitutionalValidator::new();
|
||
let mut ctx = make_valid_ctx();
|
||
ctx.aml_cleared = false;
|
||
let result = validator.validate(&ctx);
|
||
assert!(result.is_err());
|
||
assert_eq!(result.unwrap_err().rule_id, "GLOBAL_AML_001");
|
||
}
|
||
|
||
#[test]
|
||
fn test_kyc_violation() {
|
||
let validator = HKConstitutionalValidator::new();
|
||
let mut ctx = make_valid_ctx();
|
||
ctx.kyc_level = KycLevel::None;
|
||
let result = validator.validate(&ctx);
|
||
assert!(result.is_err());
|
||
assert_eq!(result.unwrap_err().rule_id, "GLOBAL_KYC_001");
|
||
}
|
||
|
||
#[test]
|
||
fn test_sanctions_violation() {
|
||
let validator = HKConstitutionalValidator::new();
|
||
let mut ctx = make_valid_ctx();
|
||
ctx.sanctions_cleared = false;
|
||
let result = validator.validate(&ctx);
|
||
assert!(result.is_err());
|
||
assert_eq!(result.unwrap_err().rule_id, "GLOBAL_SANCTIONS");
|
||
}
|
||
|
||
#[test]
|
||
fn test_regulatory_approval_required() {
|
||
let validator = HKConstitutionalValidator::new();
|
||
let mut ctx = make_valid_ctx();
|
||
ctx.regulatory_approved = false;
|
||
let result = validator.validate(&ctx);
|
||
// 大多数辖区要求监管批准,此处验证是否有对应规则拦截
|
||
// 具体规则ID因辖区而异
|
||
let _ = result; // 不同辖区可能有不同的第一个失败规则
|
||
}
|
||
}
|