NAC_Blockchain/nac-udm/src/dividend_ai/oracle.rs

157 lines
4.3 KiB
Rust

//! # 收益数据源预言机
//!
//! Oracle for dividend data sources
use super::*;
use crate::primitives::{Address, Timestamp};
/// 收益数据源类型
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DataSourceType {
/// 租金收益
Rent,
/// 股息分红
Dividend,
/// 利息收益
Interest,
}
/// 预言机数据
#[derive(Debug, Clone)]
pub struct OracleData {
/// 数据源类型
pub source_type: DataSourceType,
/// 资产地址
pub asset_address: Address,
/// 收益金额
pub amount: u128,
/// 数据时间戳
pub timestamp: Timestamp,
/// 数据签名
pub signature: Vec<u8>,
}
/// 收益预言机
pub struct DividendOracle {
/// 预言机节点列表
pub oracle_nodes: Vec<Address>,
/// 最小共识节点数
pub min_consensus: usize,
}
impl DividendOracle {
/// 创建新的预言机
pub fn new(oracle_nodes: Vec<Address>, min_consensus: usize) -> Self {
DividendOracle {
oracle_nodes,
min_consensus,
}
}
/// 获取收益数据
pub fn fetch_dividend_data(
&self,
asset_address: Address,
source_type: DataSourceType,
) -> Result<OracleData, String> {
// 简化实现:模拟从多个预言机节点获取数据
if self.oracle_nodes.len() < self.min_consensus {
return Err("Insufficient oracle nodes".to_string());
}
// 模拟数据获取
Ok(OracleData {
source_type,
asset_address,
amount: 1000000, // 模拟金额
timestamp: Timestamp::now(),
signature: vec![0u8; 64],
})
}
/// 验证预言机数据
pub fn verify_data(&self, data: &OracleData) -> bool {
// 简化实现:验证签名和时间戳
!data.signature.is_empty() && data.amount > 0
}
/// 聚合多个预言机数据
pub fn aggregate_data(&self, data_list: Vec<OracleData>) -> Result<u128, String> {
if data_list.len() < self.min_consensus {
return Err("Insufficient data for consensus".to_string());
}
// 计算中位数
let mut amounts: Vec<u128> = data_list.iter().map(|d| d.amount).collect();
amounts.sort_unstable();
let median = if amounts.len() % 2 == 0 {
(amounts[amounts.len() / 2 - 1] + amounts[amounts.len() / 2]) / 2
} else {
amounts[amounts.len() / 2]
};
Ok(median)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_oracle_creation() {
let nodes = vec![Address::zero(), Address::zero(), Address::zero()];
let oracle = DividendOracle::new(nodes, 2);
assert_eq!(oracle.oracle_nodes.len(), 3);
assert_eq!(oracle.min_consensus, 2);
}
#[test]
fn test_fetch_dividend_data() {
let nodes = vec![Address::zero(), Address::zero(), Address::zero()];
let oracle = DividendOracle::new(nodes, 2);
let result = oracle.fetch_dividend_data(Address::zero(), DataSourceType::Rent);
assert!(result.is_ok());
let data = result.expect("FIX-006: unexpected None/Err");
assert!(data.amount > 0);
}
#[test]
fn test_data_aggregation() {
let nodes = vec![Address::zero(), Address::zero(), Address::zero()];
let oracle = DividendOracle::new(nodes, 2);
let data_list = vec![
OracleData {
source_type: DataSourceType::Rent,
asset_address: Address::zero(),
amount: 1000,
timestamp: Timestamp::now(),
signature: vec![0u8; 64],
},
OracleData {
source_type: DataSourceType::Rent,
asset_address: Address::zero(),
amount: 1200,
timestamp: Timestamp::now(),
signature: vec![0u8; 64],
},
OracleData {
source_type: DataSourceType::Rent,
asset_address: Address::zero(),
amount: 1100,
timestamp: Timestamp::now(),
signature: vec![0u8; 64],
},
];
let result = oracle.aggregate_data(data_list);
assert!(result.is_ok());
assert_eq!(result.expect("mainnet: handle error"), 1100); // 中位数
}
}