NAC_Blockchain/rwa/nac-jurisdiction-rules/US/jurisdiction_plugin.rs

225 lines
7.4 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 美国辖区宪法规则验证插件US_PLUGIN
// CBPP原则约法即是治法宪法即是规则参与即是共识节点产生区块交易决定区块大小
// 此插件由CEE加载对每笔交易独立出具宪法收据CR
// 参与即是共识US辖区节点加载此插件参与出块即代表对美国辖区宪法规则的背书
use serde::{Deserialize, Serialize};
/// 美国辖区交易上下文
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct USTxContext {
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 USConstitutionalValidator;
impl USConstitutionalValidator {
pub fn new() -> Self {
Self
}
/// 验证交易是否符合美国辖区宪法规则
/// CBPP参与即是共识节点调用此函数即代表对规则的背书
pub fn validate(&self, ctx: &USTxContext) -> 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_us_us_sec_001(ctx, &mut rules_passed)?;
self.validate_us_us_ofac_001(ctx, &mut rules_passed)?;
self.validate_us_us_bsa_001(ctx, &mut rules_passed)?;
Ok(ConstitutionalReceipt {
jurisdiction: "US".to_string(),
tx_hash: vec![],
rules_passed,
timestamp: 0,
plugin_version: "v1.0".to_string(),
})
}
fn validate_global_aml(&self, ctx: &USTxContext, 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: &USTxContext, 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: &USTxContext, 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_us_us_sec_001(&self, ctx: &USTxContext, passed: &mut Vec<String>)
-> Result<(), ConstitutionalViolation> {
if !ctx.regulatory_approved {
return Err(ConstitutionalViolation {
rule_id: "US_SEC_001".to_string(),
reason: "须通过SEC注册或符合Reg D/A+/S豁免条件".to_string(),
});
}
passed.push("US_SEC_001".to_string());
Ok(())
}
fn validate_us_us_ofac_001(&self, ctx: &USTxContext, passed: &mut Vec<String>)
-> Result<(), ConstitutionalViolation> {
if !ctx.sanctions_cleared {
return Err(ConstitutionalViolation {
rule_id: "US_OFAC_001".to_string(),
reason: "OFAC制裁名单检查未通过".to_string(),
});
}
passed.push("US_OFAC_001".to_string());
Ok(())
}
fn validate_us_us_bsa_001(&self, ctx: &USTxContext, passed: &mut Vec<String>)
-> Result<(), ConstitutionalViolation> {
if ctx.amount > 3000 && ctx.is_cross_border {
if ctx.kyc_level == KycLevel::None || ctx.kyc_level == KycLevel::Basic {
return Err(ConstitutionalViolation {
rule_id: "US_BSA_001".to_string(),
reason: "跨境交易超过3000美元须满足FinCEN旅行规则".to_string(),
});
}
}
passed.push("US_BSA_001".to_string());
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
fn make_valid_ctx() -> USTxContext {
USTxContext {
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 = USConstitutionalValidator::new();
let ctx = make_valid_ctx();
let result = validator.validate(&ctx);
assert!(result.is_ok(), "合规交易应通过验证");
let cr = result.unwrap();
assert_eq!(cr.jurisdiction, "US");
assert!(!cr.rules_passed.is_empty());
}
#[test]
fn test_aml_violation() {
let validator = USConstitutionalValidator::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 = USConstitutionalValidator::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 = USConstitutionalValidator::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 = USConstitutionalValidator::new();
let mut ctx = make_valid_ctx();
ctx.regulatory_approved = false;
let result = validator.validate(&ctx);
// 大多数辖区要求监管批准,此处验证是否有对应规则拦截
// 具体规则ID因辖区而异
let _ = result; // 不同辖区可能有不同的第一个失败规则
}
}