458 lines
11 KiB
Rust
458 lines
11 KiB
Rust
//! L3存储层适配器
|
||
//!
|
||
//! 提供NAC公链L3层的核心功能:
|
||
//! - 状态数据库:账户状态和合约存储
|
||
//! - 区块存储:区块、交易和收据的持久化
|
||
//! - IPFS集成:分布式文件存储
|
||
//!
|
||
//! # 示例
|
||
//!
|
||
//! ```rust
|
||
//! use nac_sdk::adapters::{L3StorageAdapter, config::L3Config};
|
||
//!
|
||
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
|
||
//! // 创建L3适配器
|
||
//! let config = L3Config {
|
||
//! state_db_path: "/var/lib/nac/state".to_string(),
|
||
//! block_db_path: "/var/lib/nac/blocks".to_string(),
|
||
//! ipfs_url: Some("http://localhost:5001".to_string()),
|
||
//! };
|
||
//! let l3 = L3StorageAdapter::new(&config).await?;
|
||
//!
|
||
//! // 获取账户状态
|
||
//! let state = l3.get_account_state(&address).await?;
|
||
//! println!("Account balance: {}", state.balance);
|
||
//!
|
||
//! # Ok(())
|
||
//! # }
|
||
//! ```
|
||
|
||
use crate::error::{NACError, Result};
|
||
use super::config::L3Config;
|
||
use nac_udm::primitives::{Address, Hash};
|
||
use super::{
|
||
Block, Transaction, TransactionReceipt, AccountState,
|
||
};
|
||
use std::path::PathBuf;
|
||
use std::sync::Arc;
|
||
use tokio::sync::RwLock;
|
||
|
||
/// 状态数据库(简化实现)
|
||
#[derive(Debug, Clone)]
|
||
struct StateDatabase {
|
||
path: PathBuf,
|
||
}
|
||
|
||
impl StateDatabase {
|
||
async fn new(path: &str) -> Result<Self> {
|
||
Ok(Self {
|
||
path: PathBuf::from(path),
|
||
})
|
||
}
|
||
|
||
async fn get_account_state(&self, _address: &Address) -> Result<AccountState> {
|
||
// 实际实现应该从数据库读取
|
||
Ok(AccountState { address: [0u8; 32], balance: 0, nonce: 0, code_hash: None })
|
||
}
|
||
|
||
async fn set_account_state(&self, _address: &Address, _state: &AccountState) -> Result<()> {
|
||
// 实际实现应该写入数据库
|
||
Ok(())
|
||
}
|
||
|
||
async fn get_contract_storage(&self, _contract_addr: &Address, _key: &[u8]) -> Result<Vec<u8>> {
|
||
// 实际实现应该从数据库读取
|
||
Ok(Vec::new())
|
||
}
|
||
|
||
async fn set_contract_storage(&self, _contract_addr: &Address, _key: &[u8], _value: &[u8]) -> Result<()> {
|
||
// 实际实现应该写入数据库
|
||
Ok(())
|
||
}
|
||
|
||
async fn get_state_root(&self) -> Result<Hash> {
|
||
// 实际实现应该计算Merkle根
|
||
Ok(Hash::default())
|
||
}
|
||
}
|
||
|
||
/// 区块数据库(简化实现)
|
||
#[derive(Debug, Clone)]
|
||
struct BlockDatabase {
|
||
path: PathBuf,
|
||
}
|
||
|
||
impl BlockDatabase {
|
||
async fn new(path: &str) -> Result<Self> {
|
||
Ok(Self {
|
||
path: PathBuf::from(path),
|
||
})
|
||
}
|
||
|
||
async fn store_block(&self, _block: &Block) -> Result<()> {
|
||
// 实际实现应该写入数据库
|
||
Ok(())
|
||
}
|
||
|
||
async fn get_block_by_height(&self, _height: u64) -> Result<Block> {
|
||
// 实际实现应该从数据库读取
|
||
Err(NACError::NotFound("Block not found".to_string()))
|
||
}
|
||
|
||
async fn get_block_by_hash(&self, _hash: &Hash) -> Result<Block> {
|
||
// 实际实现应该从数据库读取
|
||
Err(NACError::NotFound("Block not found".to_string()))
|
||
}
|
||
|
||
async fn store_transaction(&self, _tx: &Transaction) -> Result<()> {
|
||
// 实际实现应该写入数据库
|
||
Ok(())
|
||
}
|
||
|
||
async fn get_transaction(&self, _tx_hash: &Hash) -> Result<Transaction> {
|
||
// 实际实现应该从数据库读取
|
||
Err(NACError::NotFound("Transaction not found".to_string()))
|
||
}
|
||
|
||
async fn store_receipt(&self, _receipt: &TransactionReceipt) -> Result<()> {
|
||
// 实际实现应该写入数据库
|
||
Ok(())
|
||
}
|
||
|
||
async fn get_receipt(&self, _tx_hash: &Hash) -> Result<TransactionReceipt> {
|
||
// 实际实现应该从数据库读取
|
||
Err(NACError::NotFound("Receipt not found".to_string()))
|
||
}
|
||
}
|
||
|
||
/// IPFS客户端(简化实现)
|
||
#[derive(Debug, Clone)]
|
||
struct IPFSClient {
|
||
url: String,
|
||
}
|
||
|
||
impl IPFSClient {
|
||
async fn new(url: &str) -> Result<Self> {
|
||
Ok(Self {
|
||
url: url.to_string(),
|
||
})
|
||
}
|
||
|
||
async fn upload(&self, _data: &[u8]) -> Result<String> {
|
||
// 实际实现应该上传到IPFS
|
||
Ok("Qm...".to_string())
|
||
}
|
||
|
||
async fn download(&self, _cid: &str) -> Result<Vec<u8>> {
|
||
// 实际实现应该从IPFS下载
|
||
Ok(Vec::new())
|
||
}
|
||
|
||
async fn pin(&self, _cid: &str) -> Result<()> {
|
||
// 实际实现应该固定IPFS文件
|
||
Ok(())
|
||
}
|
||
}
|
||
|
||
/// L3存储层适配器
|
||
///
|
||
/// 统一封装状态数据库、区块存储、IPFS三个子系统
|
||
#[derive(Debug, Clone)]
|
||
pub struct L3StorageAdapter {
|
||
/// 状态数据库
|
||
state_db: Arc<RwLock<StateDatabase>>,
|
||
/// 区块数据库
|
||
block_db: Arc<RwLock<BlockDatabase>>,
|
||
/// IPFS客户端(可选)
|
||
ipfs_client: Option<Arc<IPFSClient>>,
|
||
}
|
||
|
||
impl L3StorageAdapter {
|
||
/// 创建新的L3适配器
|
||
///
|
||
/// # 参数
|
||
///
|
||
/// * `config` - L3层配置
|
||
///
|
||
/// # 返回
|
||
///
|
||
/// 返回初始化完成的L3适配器实例
|
||
pub async fn new(config: &L3Config) -> Result<Self> {
|
||
let state_db = Arc::new(RwLock::new(
|
||
StateDatabase::new(&config.state_db_path).await?
|
||
));
|
||
|
||
let block_db = Arc::new(RwLock::new(
|
||
BlockDatabase::new(&config.block_db_path).await?
|
||
));
|
||
|
||
let ipfs_client = if let Some(ref url) = config.ipfs_url {
|
||
Some(Arc::new(IPFSClient::new(url).await?))
|
||
} else {
|
||
None
|
||
};
|
||
|
||
Ok(Self {
|
||
state_db,
|
||
block_db,
|
||
ipfs_client,
|
||
})
|
||
}
|
||
|
||
// ===== 状态数据库 =====
|
||
|
||
/// 获取账户状态
|
||
///
|
||
/// # 参数
|
||
///
|
||
/// * `address` - 账户地址
|
||
///
|
||
/// # 返回
|
||
///
|
||
/// 返回账户状态
|
||
pub async fn get_account_state(
|
||
&self,
|
||
address: &Address,
|
||
) -> Result<AccountState> {
|
||
self.state_db.read().await.get_account_state(address).await
|
||
}
|
||
|
||
/// 设置账户状态
|
||
///
|
||
/// # 参数
|
||
///
|
||
/// * `address` - 账户地址
|
||
/// * `state` - 账户状态
|
||
///
|
||
/// # 返回
|
||
///
|
||
/// 成功返回Ok(())
|
||
pub async fn set_account_state(
|
||
&self,
|
||
address: &Address,
|
||
state: &AccountState,
|
||
) -> Result<()> {
|
||
self.state_db.write().await.set_account_state(address, state).await
|
||
}
|
||
|
||
/// 获取合约存储
|
||
///
|
||
/// # 参数
|
||
///
|
||
/// * `contract_addr` - 合约地址
|
||
/// * `key` - 存储键
|
||
///
|
||
/// # 返回
|
||
///
|
||
/// 返回存储值
|
||
pub async fn get_contract_storage(
|
||
&self,
|
||
contract_addr: &Address,
|
||
key: &[u8],
|
||
) -> Result<Vec<u8>> {
|
||
self.state_db.read().await.get_contract_storage(contract_addr, key).await
|
||
}
|
||
|
||
/// 设置合约存储
|
||
///
|
||
/// # 参数
|
||
///
|
||
/// * `contract_addr` - 合约地址
|
||
/// * `key` - 存储键
|
||
/// * `value` - 存储值
|
||
///
|
||
/// # 返回
|
||
///
|
||
/// 成功返回Ok(())
|
||
pub async fn set_contract_storage(
|
||
&self,
|
||
contract_addr: &Address,
|
||
key: &[u8],
|
||
value: &[u8],
|
||
) -> Result<()> {
|
||
self.state_db.write().await.set_contract_storage(contract_addr, key, value).await
|
||
}
|
||
|
||
/// 获取状态根哈希
|
||
///
|
||
/// # 返回
|
||
///
|
||
/// 返回状态根哈希
|
||
pub async fn get_state_root(&self) -> Result<Hash> {
|
||
self.state_db.read().await.get_state_root().await
|
||
}
|
||
|
||
// ===== 区块存储 =====
|
||
|
||
/// 存储区块
|
||
///
|
||
/// # 参数
|
||
///
|
||
/// * `block` - 区块对象
|
||
///
|
||
/// # 返回
|
||
///
|
||
/// 成功返回Ok(())
|
||
pub async fn store_block(
|
||
&self,
|
||
block: &Block,
|
||
) -> Result<()> {
|
||
self.block_db.write().await.store_block(block).await
|
||
}
|
||
|
||
/// 获取区块(按高度)
|
||
///
|
||
/// # 参数
|
||
///
|
||
/// * `height` - 区块高度
|
||
///
|
||
/// # 返回
|
||
///
|
||
/// 返回区块对象
|
||
pub async fn get_block_by_height(
|
||
&self,
|
||
height: u64,
|
||
) -> Result<Block> {
|
||
self.block_db.read().await.get_block_by_height(height).await
|
||
}
|
||
|
||
/// 获取区块(按哈希)
|
||
///
|
||
/// # 参数
|
||
///
|
||
/// * `hash` - 区块哈希
|
||
///
|
||
/// # 返回
|
||
///
|
||
/// 返回区块对象
|
||
pub async fn get_block_by_hash(
|
||
&self,
|
||
hash: &Hash,
|
||
) -> Result<Block> {
|
||
self.block_db.read().await.get_block_by_hash(hash).await
|
||
}
|
||
|
||
/// 存储交易
|
||
///
|
||
/// # 参数
|
||
///
|
||
/// * `tx` - 交易对象
|
||
///
|
||
/// # 返回
|
||
///
|
||
/// 成功返回Ok(())
|
||
pub async fn store_transaction(
|
||
&self,
|
||
tx: &Transaction,
|
||
) -> Result<()> {
|
||
self.block_db.write().await.store_transaction(tx).await
|
||
}
|
||
|
||
/// 获取交易
|
||
///
|
||
/// # 参数
|
||
///
|
||
/// * `tx_hash` - 交易哈希
|
||
///
|
||
/// # 返回
|
||
///
|
||
/// 返回交易对象
|
||
pub async fn get_transaction(
|
||
&self,
|
||
tx_hash: &Hash,
|
||
) -> Result<Transaction> {
|
||
self.block_db.read().await.get_transaction(tx_hash).await
|
||
}
|
||
|
||
/// 存储交易收据
|
||
///
|
||
/// # 参数
|
||
///
|
||
/// * `receipt` - 交易收据
|
||
///
|
||
/// # 返回
|
||
///
|
||
/// 成功返回Ok(())
|
||
pub async fn store_receipt(
|
||
&self,
|
||
receipt: &TransactionReceipt,
|
||
) -> Result<()> {
|
||
self.block_db.write().await.store_receipt(receipt).await
|
||
}
|
||
|
||
/// 获取交易收据
|
||
///
|
||
/// # 参数
|
||
///
|
||
/// * `tx_hash` - 交易哈希
|
||
///
|
||
/// # 返回
|
||
///
|
||
/// 返回交易收据
|
||
pub async fn get_receipt(
|
||
&self,
|
||
tx_hash: &Hash,
|
||
) -> Result<TransactionReceipt> {
|
||
self.block_db.read().await.get_receipt(tx_hash).await
|
||
}
|
||
|
||
// ===== IPFS集成 =====
|
||
|
||
/// 上传文件到IPFS
|
||
///
|
||
/// # 参数
|
||
///
|
||
/// * `data` - 文件数据
|
||
///
|
||
/// # 返回
|
||
///
|
||
/// 返回IPFS CID
|
||
pub async fn upload_to_ipfs(
|
||
&self,
|
||
data: &[u8],
|
||
) -> Result<String> {
|
||
match &self.ipfs_client {
|
||
Some(client) => client.upload(data).await,
|
||
None => Err(NACError::ConfigError("IPFS not configured".to_string())),
|
||
}
|
||
}
|
||
|
||
/// 从IPFS下载文件
|
||
///
|
||
/// # 参数
|
||
///
|
||
/// * `cid` - IPFS CID
|
||
///
|
||
/// # 返回
|
||
///
|
||
/// 返回文件数据
|
||
pub async fn download_from_ipfs(
|
||
&self,
|
||
cid: &str,
|
||
) -> Result<Vec<u8>> {
|
||
match &self.ipfs_client {
|
||
Some(client) => client.download(cid).await,
|
||
None => Err(NACError::ConfigError("IPFS not configured".to_string())),
|
||
}
|
||
}
|
||
|
||
/// 固定IPFS文件
|
||
///
|
||
/// # 参数
|
||
///
|
||
/// * `cid` - IPFS CID
|
||
///
|
||
/// # 返回
|
||
///
|
||
/// 成功返回Ok(())
|
||
pub async fn pin_ipfs_file(
|
||
&self,
|
||
cid: &str,
|
||
) -> Result<()> {
|
||
match &self.ipfs_client {
|
||
Some(client) => client.pin(cid).await,
|
||
None => Err(NACError::ConfigError("IPFS not configured".to_string())),
|
||
}
|
||
}
|
||
}
|