Skip to content

Commit 7c946f1

Browse files
committed
refactor: Restructure platform module and enhance error handling system
This comprehensive refactoring overhauls the bitvault-common library architecture with significant improvements to security, modularity, and cross-platform support: - Platform Module: * Replaced single platform.rs with modular, OS-specific implementations * Implemented proper abstraction layer with provider interface * Added platform capabilities detection for feature availability * Created secure memory management utilities * Enhanced platform-specific path handling - Error Handling: * Introduced BitVaultError system with standardized error types * Implemented context-aware error handling * Added security-focused error sanitization * Provided error conversion utilities - UTXO Management: * Reimplemented selection using modular strategy pattern * Removed deprecated implementations * Enhanced organization for better maintainability - Testing Framework: * Added comprehensive platform-specific tests * Implemented security boundary validation tests * Created diagnostic utilities for debugging * Enhanced test isolation with proper mocking - Documentation: * Added detailed documentation for security boundaries * Improved module-level documentation * Created technical design documentation This refactoring establishes a more robust foundation for the wallet's cross-platform development while enhancing security through proper boundary isolation and memory management.
1 parent f1e03c5 commit 7c946f1

File tree

112 files changed

+17234
-3594
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

112 files changed

+17234
-3594
lines changed

bitvault-common/Cargo.toml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ edition = "2021"
55
authors = ["BitVault Team"]
66
description = "Common types and utilities for the BitVault Bitcoin wallet"
77

8+
# Define the run_all_tests binary
9+
[[bin]]
10+
name = "run_all_tests"
11+
path = "tests/run_all_tests.rs"
12+
813
[dependencies]
914
lazy_static = { workspace = true }
1015

@@ -34,6 +39,9 @@ chrono = { version = "0.4", features = ["serde"] }
3439
# Memory security
3540
zeroize = { workspace = true, features = ["zeroize_derive"] } # Memory wiping to prevent key leakage
3641

42+
# Utilities
43+
once_cell = "1.19" # Thread-safe lazy initialization
44+
3745
# Cryptography
3846
argon2 = "0.5.0" # Password hashing/key derivation
3947
pbkdf2 = "0.12.0" # Key derivation
@@ -53,9 +61,6 @@ cfg-if = "1.0"
5361
hex = { workspace = true }
5462
rand = { workspace = true } # Secure random number generation
5563

56-
# Concurrency
57-
crossbeam-channel = { workspace = true } # Thread-safe channels for event handling
58-
5964
# Localization
6065
fluent = { workspace = true } # Mozilla's internationalization framework
6166
unic-langid = { workspace = true } # Language identifier handling
@@ -78,4 +83,6 @@ criterion = "0.3" # Benchmarking framework
7883
quickcheck = "1.0" # Property-based testing
7984
quickcheck_macros = "1.0" # Macros for property-based testing
8085
lazy_static = { workspace = true }
86+
ctor = "0.1.22" # Constructor attribute for test initialization
87+
log4rs = "1.2" # Structured logging for tests
8188

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
# Event-Driven Architecture in BitVault
2+
3+
This document describes the event-driven architecture used in the BitVault wallet, specifically focusing on the UTXO selection and management components.
4+
5+
## Overview
6+
7+
BitVault implements an event-driven architecture to provide:
8+
9+
- Loose coupling between components
10+
- Better observability of system state changes
11+
- Enhanced testability
12+
- Improved modularity
13+
- Security boundary management
14+
15+
The event system consists of two main components:
16+
17+
1. **General Message Bus** (`MessageBus`) - For system-wide events
18+
2. **Domain-Specific Event Buses** - For targeted functionality (e.g., `UtxoEventBus`, `KeyManagementBus`)
19+
20+
## Key Components
21+
22+
### MessageBus
23+
24+
The `MessageBus` is a general-purpose event bus that handles events of different types across the entire system. It provides:
25+
26+
- Event publishing with priority levels
27+
- Subscription to specific event types
28+
- Rate limiting for event flow control
29+
- Dead letter channel for failed event delivery
30+
- Event persistence for critical events
31+
32+
```rust
33+
// Create and start a message bus
34+
let mut message_bus = MessageBus::new();
35+
message_bus.start();
36+
37+
// Subscribe to specific events
38+
let receiver = message_bus.subscribe(EventType::TransactionReceived);
39+
40+
// Publish an event
41+
message_bus.publish(
42+
EventType::TransactionReceived,
43+
&json!({ "txid": "abc123", "amount": 10000 }).to_string(),
44+
MessagePriority::High
45+
);
46+
```
47+
48+
### Domain-Specific Event Buses
49+
50+
Domain-specific event buses provide more targeted functionality for specific domains:
51+
52+
- `UtxoEventBus` for UTXO-related events
53+
- `KeyManagementBus` for key management events
54+
55+
These buses can operate independently or connect to the general message bus:
56+
57+
```rust
58+
// Create a standalone UTXO event bus
59+
let utxo_bus = UtxoEventBus::new();
60+
61+
// Or connect to the general message bus
62+
let utxo_bus = UtxoEventBus::with_general_bus(Arc::new(message_bus));
63+
64+
// Subscribe to specific UTXO events
65+
let selected_receiver = utxo_bus.subscribe("selected");
66+
let all_receiver = utxo_bus.subscribe_all();
67+
68+
// Publish a domain-specific event
69+
utxo_bus.publish(UtxoEvent::Frozen {
70+
outpoint: OutPointInfo { txid: "abc123".to_string(), vout: 0 }
71+
});
72+
```
73+
74+
## Event Types
75+
76+
### General Events (EventType)
77+
78+
System-wide events are classified by the `EventType` enum:
79+
80+
- `WalletUpdate`, `TransactionReceived`, `TransactionSent`, etc. - General wallet events
81+
- `SecurityAlert` - Security-related events
82+
- `UtxoSelected`, `UtxoStatusChanged` - UTXO-related events
83+
- `ConfigUpdate` - Configuration changes
84+
- `CoreRequest`, `CoreResponse` - Events crossing security boundaries
85+
86+
### Domain-Specific Events
87+
88+
#### UTXO Events (UtxoEvent)
89+
90+
- `Selected` - When UTXOs are selected for a transaction
91+
- `Frozen` - When a UTXO is marked as unavailable for selection
92+
- `Unfrozen` - When a UTXO is marked as available for selection
93+
- `SelectionFailed` - When UTXO selection fails (e.g., insufficient funds)
94+
- `StatusChanged` - When a UTXO's status changes
95+
96+
#### Key Management Events (KeyManagementEvent)
97+
98+
- `KeyGenerated` - When a new key is generated
99+
- `KeyEncrypted` - When a key is encrypted
100+
- `KeyDecryptionFailed` - When key decryption fails
101+
102+
## Integration with UTXO Selection and Management
103+
104+
### UtxoSelector
105+
106+
The `UtxoSelector` uses the event system to publish events during UTXO selection:
107+
108+
```rust
109+
// Create a selector and event bus
110+
let (selector, event_bus) = UtxoSelector::with_event_bus(Arc::new(UtxoEventBus::new()));
111+
112+
// Select UTXOs with event publishing
113+
let result = selector.select_utxos(
114+
&utxos,
115+
amount,
116+
strategy,
117+
Some(&message_bus),
118+
Some(&event_bus)
119+
);
120+
121+
// Or use the simplified API
122+
let (result, created_bus) = selector.select_utxos_with_events(
123+
&utxos,
124+
amount,
125+
strategy,
126+
Some(&message_bus)
127+
);
128+
```
129+
130+
### UtxoManager
131+
132+
The `UtxoManager` uses the event system to publish events for all UTXO operations:
133+
134+
```rust
135+
// Create a manager with event bus
136+
let (manager, event_bus) = UtxoManager::with_new_event_bus();
137+
138+
// Subscribe to events
139+
let receiver = event_bus.subscribe_all();
140+
141+
// Add UTXOs, freeze/unfreeze, and select UTXOs
142+
// Events will be published automatically
143+
manager.add_utxo(utxo);
144+
manager.freeze_utxo(&outpoint);
145+
let result = manager.select_utxos(amount, strategy, Some(&message_bus));
146+
```
147+
148+
## Security Considerations
149+
150+
The event-driven architecture provides several security benefits but also introduces considerations:
151+
152+
- **Event Data Protection**: Events may contain sensitive information about wallet state
153+
- **Security Boundary Crossing**: Events marked as `CoreRequest` or `CoreResponse` cross security boundaries and require special handling
154+
- **Event Persistence**: Critical events are persisted and may contain sensitive data
155+
- **Rate Limiting**: Prevents excessive event flow that could lead to resource exhaustion
156+
157+
## Best Practices
158+
159+
1. **Always Subscribe Before Publishing**: Ensure subscribers are registered before events are published to avoid missing critical events
160+
161+
2. **Error Handling**: Use try/catch when processing events to prevent cascading failures
162+
163+
3. **Timeout Handling**: Always use timeouts when waiting for events to avoid blocking indefinitely
164+
165+
4. **Event Granularity**: Create specific, granular events rather than general-purpose ones
166+
167+
5. **Security-Aware Event Design**: Be mindful of what data is included in events, especially those crossing security boundaries
168+
169+
## Example: Complete Event Flow
170+
171+
```rust
172+
// 1. Create general message bus
173+
let mut message_bus = MessageBus::new();
174+
message_bus.start();
175+
176+
// 2. Create domain-specific event bus
177+
let utxo_bus = Arc::new(UtxoEventBus::with_general_bus(Arc::new(message_bus.clone())));
178+
179+
// 3. Create UTXO manager with event bus
180+
let mut manager = UtxoManager::with_event_bus(Arc::clone(&utxo_bus));
181+
182+
// 4. Subscribe to events
183+
let selected_receiver = utxo_bus.subscribe("selected");
184+
let general_receiver = message_bus.subscribe(EventType::UtxoSelected);
185+
186+
// 5. Add UTXOs and select them
187+
manager.add_utxo(utxo1);
188+
manager.add_utxo(utxo2);
189+
let result = manager.select_utxos(amount, strategy, Some(&message_bus));
190+
191+
// 6. Process the selection result and handle events
192+
match result {
193+
SelectionResult::Success { selected, fee_amount, change_amount } => {
194+
// Use selected UTXOs to build transaction
195+
},
196+
SelectionResult::InsufficientFunds { available, required } => {
197+
// Handle insufficient funds
198+
}
199+
}
200+
201+
// 7. Process events from receivers
202+
match selected_receiver.recv_timeout(Duration::from_millis(100)) {
203+
Ok(event) => {
204+
// Handle the event
205+
},
206+
Err(_) => {
207+
// Handle timeout
208+
}
209+
}
210+
```
211+
212+
## Conclusion
213+
214+
The event-driven architecture in BitVault provides a flexible and powerful foundation for building a secure, maintainable Bitcoin wallet. By separating concerns through domain-specific event buses and leveraging the publisher-subscriber pattern, components can communicate efficiently without tight coupling.
215+
216+
This design enhances testability, allows for better security isolation, and provides a clear path for extending functionality while maintaining the integrity of the system.
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# BitVault Architecture Overview
2+
3+
This document outlines the architecture of the BitVault wallet application, providing a high-level overview of its components and their interactions.
4+
5+
## Overview
6+
7+
The BitVault wallet architecture consists of several key components, each with specific responsibilities:
8+
9+
- **Core Components**
10+
- Key Management Module - Handles cryptographic operations and secrets
11+
- UTXO Management System - Manages Bitcoin UTXOs and transaction building
12+
- Platform Abstractions - Provides platform-specific functionality
13+
- Configuration System - Manages wallet settings and preferences
14+
15+
- **Cross-cutting Concerns**
16+
- Event System - Enables loose coupling between components
17+
- Logging Framework - Provides secure, contextual logging
18+
- Error Handling - Consistent error propagation and handling
19+
- Security Boundaries - Clear separation of security domains
20+
21+
## Component Interactions
22+
23+
Components interact primarily through a well-defined event system that respects security boundaries. The event-driven architecture (described in detail in [Event Architecture](event_architecture.md)) ensures:
24+
25+
1. Loose coupling between components
26+
2. Clear communication patterns
27+
3. Testability of component interactions
28+
4. Security boundary enforcement
29+
30+
### Communication Flow Example
31+
32+
A typical communication flow for a transaction:
33+
34+
1. User Interface → Event System: "Create Transaction" request
35+
2. Event System → UTXO Manager: Request for UTXO selection
36+
3. UTXO Manager → Event System: Selected UTXOs
37+
4. Event System → Key Manager: Request for transaction signing
38+
5. Key Manager → Event System: Signed transaction
39+
6. Event System → Network Module: Transaction broadcast
40+
41+
## Security Model
42+
43+
Security is a primary concern in the BitVault architecture. The wallet implements several security patterns:
44+
45+
- **Explicit Security Boundaries** - Clear demarcation between security domains
46+
- **Minimal Privilege** - Components only have access to what they need
47+
- **Memory Protection** - Secure handling of cryptographic secrets
48+
- **Defensive Coding** - Validation at trust boundaries
49+
- **Event Security** - Security-aware event propagation
50+
51+
See [Security Boundaries](../security/security_boundaries.md) for detailed information on security implementation.
52+
53+
## Module Structure
54+
55+
The codebase is organized into the following major modules:
56+
57+
- **bitvault-common** - Core functionality shared across platforms
58+
- `key_management.rs` - Cryptographic keys and secrets management
59+
- `utxo_management.rs` - UTXO handling and transaction building
60+
- `platform/` - Platform-specific abstractions
61+
- `events.rs` - Event system implementation
62+
- `types.rs` - Core data types
63+
- `error.rs` - Error types and handling
64+
65+
- **bitvault-ui** - User interface implementation
66+
- **bitvault-node** - Bitcoin node interaction
67+
- **bitvault-app** - Application entry points for different platforms
68+
69+
## Cross-platform Strategy
70+
71+
BitVault is designed for cross-platform compatibility:
72+
73+
- Core functionality in Rust for security and performance
74+
- Platform-specific code isolated in dedicated modules
75+
- UI adaptations for different platforms while maintaining core experience
76+
- Consistent security model across all platforms
77+
78+
## Future Directions
79+
80+
The architecture is designed to accommodate future enhancements:
81+
82+
1. Lightning Network integration
83+
2. Hardware wallet support
84+
3. Multi-signature wallet support
85+
4. Advanced privacy features
86+
87+
## Related Documentation
88+
89+
- [Event-Driven Architecture](event_architecture.md) - Detailed information on the event system
90+
- [Security Boundaries](../security/security_boundaries.md) - Security model implementation
91+
- [UTXO Management](../utxo/utxo_management.md) - UTXO handling details
92+
- [Key Management](../key_management/key_management_overview.md) - Cryptographic operations

0 commit comments

Comments
 (0)