Hexagonal Architecture Implementation¶
Overview¶
Anya Core implements a comprehensive hexagonal architecture pattern, emphasizing clean separation of concerns, domain-driven design, and modularity. This document details the implementation of the hexagonal architecture across the system, with a focus on Bitcoin Layer 2 integrations.
Core Architecture¶
Domain Layer¶
The domain layer contains the core business logic and rules, independent of external concerns:
// Core domain models
pub struct Transaction {
id: TransactionId,
inputs: Vec<Input>,
outputs: Vec<Output>,
witnesses: Vec<Witness>,
metadata: TransactionMetadata
}
// Domain services
pub trait TransactionService {
async fn validate(&self, tx: &Transaction) -> Result<ValidationResult>;
async fn process(&self, tx: &Transaction) -> Result<ProcessingResult>;
async fn verify(&self, tx: &Transaction) -> Result<VerificationResult>;
}
Application Layer (Ports)¶
The application layer defines the interfaces (ports) that the domain layer uses to interact with external systems:
// Input ports (primary/driving)
pub trait TransactionPort {
async fn submit_transaction(&self, tx: Transaction) -> Result<TransactionId>;
async fn get_transaction(&self, id: TransactionId) -> Result<Transaction>;
async fn validate_transaction(&self, tx: &Transaction) -> Result<ValidationResult>;
}
// Output ports (secondary/driven)
pub trait BlockchainPort {
async fn broadcast_transaction(&self, tx: &Transaction) -> Result<BroadcastResult>;
async fn get_block(&self, hash: BlockHash) -> Result<Block>;
async fn verify_proof(&self, proof: &Proof) -> Result<VerificationResult>;
}
Infrastructure Layer (Adapters)¶
The infrastructure layer implements the ports defined in the application layer:
// Bitcoin adapter implementation
pub struct BitcoinAdapter {
rpc_client: BitcoinRpcClient,
network: Network,
config: BitcoinConfig
}
impl BlockchainPort for BitcoinAdapter {
async fn broadcast_transaction(&self, tx: &Transaction) -> Result<BroadcastResult> {
// Implementation
}
async fn get_block(&self, hash: BlockHash) -> Result<Block> {
// Implementation
}
async fn verify_proof(&self, proof: &Proof) -> Result<VerificationResult> {
// Implementation
}
}
Layer 2 Protocol Integration¶
Protocol Adapters¶
Each Layer 2 protocol has its own adapter implementation:
// Protocol adapter trait
pub trait ProtocolAdapter {
async fn submit_transaction(&self, tx: ProtocolTransaction) -> Result<TransactionId>;
async fn verify_state(&self, state: &ProtocolState) -> Result<VerificationResult>;
async fn sync_state(&self) -> Result<SyncResult>;
}
// BOB Protocol adapter
pub struct BobAdapter {
rpc_client: BobRpcClient,
state_manager: BobStateManager,
verification: BobVerification
}
// RGB Protocol adapter
pub struct RgbAdapter {
taproot_client: TaprootClient,
asset_manager: RgbAssetManager,
state_tracker: RgbStateTracker
}
// RSK Protocol adapter
pub struct RskAdapter {
sidechain_client: RskClient,
bridge_manager: RskBridgeManager,
verification: RskVerification
}
Protocol Ports¶
Protocol-specific ports define the interfaces for each Layer 2 protocol:
// Protocol ports
pub trait ProtocolPort {
async fn submit_protocol_tx(&self, tx: ProtocolTransaction) -> Result<TransactionId>;
async fn verify_protocol_state(&self, state: &ProtocolState) -> Result<VerificationResult>;
async fn sync_protocol_state(&self) -> Result<SyncResult>;
}
// Asset management ports
pub trait AssetPort {
async fn issue_asset(&self, params: AssetParams) -> Result<AssetId>;
async fn transfer_asset(&self, transfer: AssetTransfer) -> Result<TransferResult>;
async fn get_asset_state(&self, asset_id: AssetId) -> Result<AssetState>;
}
Dependency Injection¶
The system uses dependency injection to wire up the hexagonal architecture:
// Dependency container
pub struct Container {
bitcoin_adapter: Arc<BitcoinAdapter>,
bob_adapter: Arc<BobAdapter>,
rgb_adapter: Arc<RgbAdapter>,
rsk_adapter: Arc<RskAdapter>
}
impl Container {
pub fn new(config: Config) -> Self {
// Initialize adapters
let bitcoin_adapter = Arc::new(BitcoinAdapter::new(config.bitcoin.clone()));
let bob_adapter = Arc::new(BobAdapter::new(config.bob.clone()));
let rgb_adapter = Arc::new(RgbAdapter::new(config.rgb.clone()));
let rsk_adapter = Arc::new(RskAdapter::new(config.rsk.clone()));
Self {
bitcoin_adapter,
bob_adapter,
rgb_adapter,
rsk_adapter
}
}
}
Testing Strategy¶
The hexagonal architecture enables comprehensive testing at each layer:
#[cfg(test)]
mod tests {
use super::*;
// Domain layer tests
#[tokio::test]
async fn test_transaction_validation() {
// Test implementation
}
// Port tests
#[tokio::test]
async fn test_protocol_port() {
// Test implementation
}
// Adapter tests
#[tokio::test]
async fn test_bitcoin_adapter() {
// Test implementation
}
}
Monitoring and Metrics¶
The system includes comprehensive monitoring and metrics collection:
// Metrics collection
pub struct MetricsCollector {
prometheus_client: PrometheusClient,
metrics: Arc<RwLock<Metrics>>,
}
impl MetricsCollector {
pub fn record_transaction(&self, tx: &Transaction) {
// Record transaction metrics
}
pub fn record_protocol_state(&self, protocol: &str, state: &ProtocolState) {
// Record protocol state metrics
}
}
Error Handling¶
Error handling is implemented consistently across all layers:
// Error types
#[derive(Debug, Error)]
pub enum HexagonalError {
#[error("Domain error: {0}")]
Domain(String),
#[error("Protocol error: {0}")]
Protocol(String),
#[error("Infrastructure error: {0}")]
Infrastructure(String),
}
// Error context
pub struct ErrorContext {
error: HexagonalError,
severity: ErrorSeverity,
trace_id: Option<String>,
retry_count: u32,
metrics: ErrorMetrics
}
Security Considerations¶
The hexagonal architecture ensures security at each layer:
- Domain Layer
- Business rule validation
- State transition verification
-
Access control enforcement
-
Application Layer
- Input validation
- Output sanitization
-
Rate limiting
-
Infrastructure Layer
- Secure communication
- Authentication
- Authorization
Performance Optimization¶
Performance optimizations are implemented at each layer:
- Domain Layer
- Efficient data structures
- Caching strategies
-
Batch processing
-
Application Layer
- Connection pooling
- Request batching
-
Response caching
-
Infrastructure Layer
- Load balancing
- Circuit breaking
- Retry strategies
Future Extensions¶
The hexagonal architecture supports easy extension for new protocols and features:
- New Protocol Integration
- Implement ProtocolPort
- Create ProtocolAdapter
-
Add to dependency container
-
New Feature Addition
- Define domain models
- Create ports
-
Implement adapters
-
System Evolution
- Version ports
- Migrate adapters
- Update dependencies
Bitcoin Layer 2 Integration¶
Protocol Compliance¶
The hexagonal architecture ensures compliance with Bitcoin standards and protocols:
// BIP compliance validation
pub trait BipCompliance {
async fn validate_bip341(&self, tx: &Transaction) -> Result<ValidationResult>;
async fn validate_bip342(&self, tx: &Transaction) -> Result<ValidationResult>;
async fn validate_bip174(&self, psbt: &PartiallySignedTransaction) -> Result<ValidationResult>;
}
// Miniscript support
pub trait MiniscriptSupport {
async fn compile_script(&self, policy: &Policy) -> Result<Script>;
async fn analyze_script(&self, script: &Script) -> Result<ScriptAnalysis>;
}
Layer 2 Protocol Integration¶
Each Layer 2 protocol is integrated through dedicated adapters:
// BOB Protocol
impl ProtocolAdapter for BobAdapter {
async fn submit_transaction(&self, tx: ProtocolTransaction) -> Result<TransactionId> {
// Validate against BIP standards
self.validate_bip341(&tx).await?;
self.validate_bip342(&tx).await?;
// Process transaction
let result = self.process_transaction(tx).await?;
// Record metrics
self.metrics.record_transaction(&result);
Ok(result.id)
}
}
// RGB Protocol
impl ProtocolAdapter for RgbAdapter {
async fn submit_transaction(&self, tx: ProtocolTransaction) -> Result<TransactionId> {
// Validate Taproot requirements
self.validate_taproot(&tx).await?;
// Process asset transaction
let result = self.process_asset_tx(tx).await?;
// Update asset state
self.update_asset_state(&result).await?;
Ok(result.id)
}
}
// RSK Protocol
impl ProtocolAdapter for RskAdapter {
async fn submit_transaction(&self, tx: ProtocolTransaction) -> Result<TransactionId> {
// Verify Bitcoin-backed state
self.verify_bitcoin_backing(&tx).await?;
// Process sidechain transaction
let result = self.process_sidechain_tx(tx).await?;
// Update bridge state
self.update_bridge_state(&result).await?;
Ok(result.id)
}
}
Cross-Layer State Management¶
The system maintains consistent state across layers:
// Cross-layer state manager
pub struct CrossLayerStateManager {
bitcoin_state: Arc<BitcoinState>,
l2_states: Arc<RwLock<HashMap<ProtocolId, ProtocolState>>>,
bridge_states: Arc<RwLock<HashMap<BridgeId, BridgeState>>>
}
impl CrossLayerStateManager {
pub async fn sync_states(&self) -> Result<SyncResult> {
// Sync Bitcoin state
let bitcoin_state = self.sync_bitcoin_state().await?;
// Sync Layer 2 states
for (protocol_id, state) in self.l2_states.read().await.iter() {
self.sync_protocol_state(protocol_id, state).await?;
}
// Sync bridge states
for (bridge_id, state) in self.bridge_states.read().await.iter() {
self.sync_bridge_state(bridge_id, state).await?;
}
Ok(SyncResult::Success)
}
}
Compliance Requirements¶
BIP Standards¶
The system implements comprehensive BIP compliance:
- BIP 341/342 (Taproot)
- Taproot key path spending
- Taproot script path spending
- Taproot key aggregation
-
Taproot script verification
-
BIP 174 (PSBT)
- PSBT creation and modification
- PSBT validation
- PSBT signing
-
PSBT finalization
-
Miniscript
- Policy compilation
- Script analysis
- Witness generation
- Script verification
Security Requirements¶
Security is enforced at each layer:
- Transaction Security
- Input validation
- Output verification
- Witness validation
-
Script verification
-
State Security
- State transition validation
- State consistency checks
- State recovery mechanisms
-
State backup procedures
-
Protocol Security
- Protocol-specific validation
- Cross-layer verification
- Bridge security
- Fraud proof handling
Performance Requirements¶
Performance is optimized across layers:
- Transaction Processing
- Batch processing
- Parallel validation
- Caching strategies
-
Rate limiting
-
State Management
- Efficient state storage
- State synchronization
- State recovery
-
State pruning
-
Protocol Operations
- Protocol-specific optimizations
- Cross-layer batching
- Resource management
- Load balancing
Monitoring and Alerts¶
The system includes comprehensive monitoring:
- Protocol Metrics
- Transaction throughput
- State synchronization time
- Validation latency
-
Error rates
-
Security Metrics
- Validation failures
- Security incidents
- Fraud attempts
-
State inconsistencies
-
Performance Metrics
- Resource utilization
- Operation latency
- Queue depths
- Cache hit rates
Future Extensions¶
The architecture supports future protocol additions:
- New Protocol Integration
- Implement ProtocolAdapter
- Add protocol-specific ports
- Update dependency container
-
Add monitoring
-
Protocol Evolution
- Version protocol adapters
- Update validation rules
- Enhance security measures
-
Optimize performance
-
System Enhancement
- Add new features
- Improve monitoring
- Enhance security
- Optimize performance
Last updated: 2025-06-02