395 lines
10 KiB
Rust
395 lines
10 KiB
Rust
// 流体区块模型 (Fluid Block Model, FBM)
|
||
// 三维坐标系统:(Epoch, Round, Branch)
|
||
|
||
use serde::{Deserialize, Serialize};
|
||
use sha2::{Sha256, Digest};
|
||
use super::constitutional_receipt::ConstitutionalReceipt;
|
||
|
||
/// 流体区块
|
||
/// 使用三维坐标而非简单的区块高度
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct FluidBlock {
|
||
/// 三维坐标
|
||
pub coordinates: BlockCoordinates,
|
||
|
||
/// 区块哈希
|
||
pub hash: Vec<u8>,
|
||
|
||
/// 父区块哈希列表(支持DAG)
|
||
pub parent_hashes: Vec<Vec<u8>>,
|
||
|
||
/// 宪法哈希
|
||
pub constitutional_hash: Vec<u8>,
|
||
|
||
/// 时间戳
|
||
pub timestamp: u64,
|
||
|
||
/// 交易列表(每个交易都带有宪法收据)
|
||
pub transactions: Vec<TransactionWithReceipt>,
|
||
|
||
/// 区块生产者(CBP节点)
|
||
pub producer_pubkey: Vec<u8>,
|
||
|
||
/// 区块签名
|
||
pub signature: Vec<u8>,
|
||
|
||
/// 区块大小(字节)
|
||
pub size: u64,
|
||
|
||
/// 区块权重(基于收据权重总和)
|
||
pub weight: u64,
|
||
}
|
||
|
||
/// 区块三维坐标
|
||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||
pub struct BlockCoordinates {
|
||
/// 纪元(Epoch):每N个区块或固定时间切换
|
||
pub epoch: u64,
|
||
|
||
/// 轮次(Round):纪元内的线性递增序号
|
||
pub round: u64,
|
||
|
||
/// 分支(Branch):同一轮次内可能有多个合法区块
|
||
pub branch: u32,
|
||
}
|
||
|
||
/// 带宪法收据的交易
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct TransactionWithReceipt {
|
||
/// 交易数据
|
||
pub transaction: Transaction,
|
||
|
||
/// 宪法收据
|
||
pub receipt: ConstitutionalReceipt,
|
||
}
|
||
|
||
/// 交易结构
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct Transaction {
|
||
/// 发送方
|
||
pub from: Vec<u8>,
|
||
|
||
/// 接收方
|
||
pub to: Vec<u8>,
|
||
|
||
/// 金额
|
||
pub value: u128,
|
||
|
||
/// Nonce
|
||
pub nonce: u64,
|
||
|
||
/// 数据
|
||
pub data: Vec<u8>,
|
||
|
||
/// 交易哈希
|
||
pub hash: Vec<u8>,
|
||
}
|
||
|
||
/// 区块配置
|
||
#[derive(Debug, Clone)]
|
||
pub struct BlockConfig {
|
||
/// 最小出块时间间隔(毫秒)
|
||
pub min_block_interval_ms: u64,
|
||
|
||
/// 最大出块时间间隔(毫秒)
|
||
pub max_block_interval_ms: u64,
|
||
|
||
/// 目标区块利用率
|
||
pub target_utilization: f64,
|
||
|
||
/// 软上限(字节)
|
||
pub soft_cap_bytes: u64,
|
||
|
||
/// 硬上限(字节)
|
||
pub hard_cap_bytes: u64,
|
||
|
||
/// 每个Epoch的区块数
|
||
pub blocks_per_epoch: u64,
|
||
}
|
||
|
||
impl Default for BlockConfig {
|
||
fn default() -> Self {
|
||
Self {
|
||
min_block_interval_ms: 100, // 100ms
|
||
max_block_interval_ms: 2000, // 2s
|
||
target_utilization: 0.70, // 70%
|
||
soft_cap_bytes: 1024 * 1024, // 1MB
|
||
hard_cap_bytes: 4 * 1024 * 1024, // 4MB
|
||
blocks_per_epoch: 1000,
|
||
}
|
||
}
|
||
}
|
||
|
||
impl FluidBlock {
|
||
/// 创建新的流体区块
|
||
pub fn new(
|
||
coordinates: BlockCoordinates,
|
||
parent_hashes: Vec<Vec<u8>>,
|
||
constitutional_hash: Vec<u8>,
|
||
producer_pubkey: Vec<u8>,
|
||
transactions: Vec<TransactionWithReceipt>,
|
||
) -> Self {
|
||
let timestamp = std::time::SystemTime::now()
|
||
.duration_since(std::time::UNIX_EPOCH)
|
||
.unwrap()
|
||
.as_secs();
|
||
|
||
// 计算区块权重
|
||
let weight = transactions.iter()
|
||
.map(|tx| tx.receipt.get_weight())
|
||
.sum();
|
||
|
||
// 计算区块大小
|
||
let size = Self::calculate_size(&transactions);
|
||
|
||
let mut block = Self {
|
||
coordinates,
|
||
hash: vec![],
|
||
parent_hashes,
|
||
constitutional_hash,
|
||
timestamp,
|
||
transactions,
|
||
producer_pubkey,
|
||
signature: vec![],
|
||
size,
|
||
weight,
|
||
};
|
||
|
||
// 计算区块哈希
|
||
block.hash = block.calculate_hash();
|
||
|
||
block
|
||
}
|
||
|
||
/// 计算区块哈希
|
||
fn calculate_hash(&self) -> Vec<u8> {
|
||
let mut hasher = Sha256::new();
|
||
|
||
// 坐标
|
||
hasher.update(self.coordinates.epoch.to_be_bytes());
|
||
hasher.update(self.coordinates.round.to_be_bytes());
|
||
hasher.update(self.coordinates.branch.to_be_bytes());
|
||
|
||
// 父区块哈希
|
||
for parent in &self.parent_hashes {
|
||
hasher.update(parent);
|
||
}
|
||
|
||
// 宪法哈希
|
||
hasher.update(&self.constitutional_hash);
|
||
|
||
// 时间戳
|
||
hasher.update(self.timestamp.to_be_bytes());
|
||
|
||
// 交易哈希
|
||
for tx in &self.transactions {
|
||
hasher.update(&tx.transaction.hash);
|
||
}
|
||
|
||
// 生产者
|
||
hasher.update(&self.producer_pubkey);
|
||
|
||
hasher.finalize().to_vec()
|
||
}
|
||
|
||
/// 计算区块大小
|
||
fn calculate_size(transactions: &[TransactionWithReceipt]) -> u64 {
|
||
// 简化版本:估算序列化后的大小
|
||
transactions.len() as u64 * 500 // 假设每个交易平均500字节
|
||
}
|
||
|
||
/// 签名区块
|
||
pub fn sign(&mut self, signature: Vec<u8>) {
|
||
self.signature = signature;
|
||
}
|
||
|
||
/// 验证区块
|
||
pub fn verify(&self, current_time: u64, valid_constitutional_hash: &[u8]) -> bool {
|
||
// 1. 验证宪法哈希
|
||
if self.constitutional_hash != valid_constitutional_hash {
|
||
return false;
|
||
}
|
||
|
||
// 2. 验证所有交易的收据
|
||
for tx_with_receipt in &self.transactions {
|
||
if !tx_with_receipt.receipt.verify(current_time, valid_constitutional_hash) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// 3. 验证区块哈希
|
||
let calculated_hash = self.calculate_hash();
|
||
if self.hash != calculated_hash {
|
||
return false;
|
||
}
|
||
|
||
// 4. 验证签名(简化版本)
|
||
if self.signature.is_empty() {
|
||
return false;
|
||
}
|
||
|
||
true
|
||
}
|
||
|
||
/// 检查是否应该出块
|
||
pub fn should_produce_block(
|
||
last_block_time: u64,
|
||
pending_tx_count: usize,
|
||
config: &BlockConfig,
|
||
) -> bool {
|
||
let current_time = std::time::SystemTime::now()
|
||
.duration_since(std::time::UNIX_EPOCH)
|
||
.unwrap()
|
||
.as_millis() as u64;
|
||
|
||
let elapsed = current_time - last_block_time;
|
||
|
||
// 最小时间间隔检查
|
||
if elapsed < config.min_block_interval_ms {
|
||
return false;
|
||
}
|
||
|
||
// 有交易或达到最大间隔
|
||
pending_tx_count > 0 || elapsed >= config.max_block_interval_ms
|
||
}
|
||
}
|
||
|
||
impl BlockCoordinates {
|
||
/// 创建新坐标
|
||
pub fn new(epoch: u64, round: u64, branch: u32) -> Self {
|
||
Self {
|
||
epoch,
|
||
round,
|
||
branch,
|
||
}
|
||
}
|
||
|
||
/// 创建创世区块坐标
|
||
pub fn genesis() -> Self {
|
||
Self {
|
||
epoch: 0,
|
||
round: 0,
|
||
branch: 0,
|
||
}
|
||
}
|
||
|
||
/// 下一个轮次
|
||
pub fn next_round(&self, blocks_per_epoch: u64) -> Self {
|
||
let next_round = self.round + 1;
|
||
if next_round >= blocks_per_epoch {
|
||
// 进入下一个纪元
|
||
Self {
|
||
epoch: self.epoch + 1,
|
||
round: 0,
|
||
branch: 0,
|
||
}
|
||
} else {
|
||
Self {
|
||
epoch: self.epoch,
|
||
round: next_round,
|
||
branch: 0,
|
||
}
|
||
}
|
||
}
|
||
|
||
/// 同一轮次的新分支
|
||
pub fn new_branch(&self) -> Self {
|
||
Self {
|
||
epoch: self.epoch,
|
||
round: self.round,
|
||
branch: self.branch + 1,
|
||
}
|
||
}
|
||
}
|
||
|
||
impl Transaction {
|
||
/// 创建新交易
|
||
pub fn new(from: Vec<u8>, to: Vec<u8>, value: u128, nonce: u64, data: Vec<u8>) -> Self {
|
||
let mut tx = Self {
|
||
from,
|
||
to,
|
||
value,
|
||
nonce,
|
||
data,
|
||
hash: vec![],
|
||
};
|
||
|
||
tx.hash = tx.calculate_hash();
|
||
tx
|
||
}
|
||
|
||
/// 计算交易哈希
|
||
fn calculate_hash(&self) -> Vec<u8> {
|
||
let mut hasher = Sha256::new();
|
||
hasher.update(&self.from);
|
||
hasher.update(&self.to);
|
||
hasher.update(self.value.to_be_bytes());
|
||
hasher.update(self.nonce.to_be_bytes());
|
||
hasher.update(&self.data);
|
||
hasher.finalize().to_vec()
|
||
}
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::*;
|
||
|
||
#[test]
|
||
fn test_block_coordinates() {
|
||
let coords = BlockCoordinates::new(1, 100, 0);
|
||
assert_eq!(coords.epoch, 1);
|
||
assert_eq!(coords.round, 100);
|
||
assert_eq!(coords.branch, 0);
|
||
|
||
// 测试下一轮次
|
||
let next = coords.next_round(1000);
|
||
assert_eq!(next.epoch, 1);
|
||
assert_eq!(next.round, 101);
|
||
|
||
// 测试新分支
|
||
let branch = coords.new_branch();
|
||
assert_eq!(branch.branch, 1);
|
||
}
|
||
|
||
#[test]
|
||
fn test_epoch_transition() {
|
||
let coords = BlockCoordinates::new(0, 999, 0);
|
||
let next = coords.next_round(1000);
|
||
|
||
assert_eq!(next.epoch, 1);
|
||
assert_eq!(next.round, 0);
|
||
assert_eq!(next.branch, 0);
|
||
}
|
||
|
||
#[test]
|
||
fn test_transaction_creation() {
|
||
let tx = Transaction::new(
|
||
vec![1u8; 20],
|
||
vec![2u8; 20],
|
||
1000,
|
||
1,
|
||
vec![],
|
||
);
|
||
|
||
assert!(!tx.hash.is_empty());
|
||
assert_eq!(tx.value, 1000);
|
||
assert_eq!(tx.nonce, 1);
|
||
}
|
||
|
||
#[test]
|
||
fn test_should_produce_block() {
|
||
let config = BlockConfig::default();
|
||
let last_time = 0;
|
||
|
||
// 有交易且超过最小间隔
|
||
assert!(FluidBlock::should_produce_block(last_time, 1, &config));
|
||
|
||
// 无交易但超过最大间隔
|
||
let old_time = std::time::SystemTime::now()
|
||
.duration_since(std::time::UNIX_EPOCH)
|
||
.unwrap()
|
||
.as_millis() as u64 - 3000;
|
||
assert!(FluidBlock::should_produce_block(old_time, 0, &config));
|
||
}
|
||
}
|