Skip to content

Commit c180ba8

Browse files
CopilotSteake
andcommitted
Fix error handling in node initialization - return Result instead of panic
- Change ValidatorNode::with_key() and MinerNode::with_key() to return Result - Change ValidatorNode::new() and MinerNode::new() to return Result - Update all call sites in main.rs to handle errors gracefully - Update test cases to unwrap Results - Addresses PR review feedback about using .expect() causing panics Co-authored-by: Steake <530040+Steake@users.noreply.github.com>
1 parent e9ec102 commit c180ba8

3 files changed

Lines changed: 36 additions & 18 deletions

File tree

crates/bitcell-node/src/main.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,13 @@ async fn main() {
122122
// Or we can modify NodeConfig to hold the secret key? No, NodeConfig is serializable.
123123

124124
// Let's update ValidatorNode::new to take the secret key as an argument.
125-
let mut node = ValidatorNode::with_key(config, secret_key.clone());
125+
let mut node = match ValidatorNode::with_key(config, secret_key.clone()) {
126+
Ok(node) => node,
127+
Err(e) => {
128+
eprintln!("Error initializing validator node: {}", e);
129+
std::process::exit(1);
130+
}
131+
};
126132

127133
// Start metrics server on port + 2 to avoid conflict with P2P port (30333) and RPC port (30334)
128134
let metrics_port = port + 2;
@@ -191,7 +197,13 @@ async fn main() {
191197

192198
println!("Miner Public Key: {:?}", secret_key.public_key());
193199

194-
let mut node = MinerNode::with_key(config, secret_key.clone());
200+
let mut node = match MinerNode::with_key(config, secret_key.clone()) {
201+
Ok(node) => node,
202+
Err(e) => {
203+
eprintln!("Error initializing miner node: {}", e);
204+
std::process::exit(1);
205+
}
206+
};
195207

196208
let metrics_port = port + 2;
197209

@@ -259,7 +271,13 @@ async fn main() {
259271
println!("Full Node Public Key: {:?}", secret_key.public_key());
260272

261273
// Reuse ValidatorNode for now as FullNode logic is similar (just no voting)
262-
let mut node = ValidatorNode::with_key(config, secret_key.clone());
274+
let mut node = match ValidatorNode::with_key(config, secret_key.clone()) {
275+
Ok(node) => node,
276+
Err(e) => {
277+
eprintln!("Error initializing full node: {}", e);
278+
std::process::exit(1);
279+
}
280+
};
263281

264282
let metrics_port = port + 2;
265283

crates/bitcell-node/src/miner.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,30 @@ pub struct MinerNode {
2020
}
2121

2222
impl MinerNode {
23-
pub fn new(config: NodeConfig, secret_key: SecretKey) -> Self {
23+
pub fn new(config: NodeConfig, secret_key: SecretKey) -> crate::Result<Self> {
2424
Self::with_key(config, Arc::new(secret_key))
2525
}
2626

27-
pub fn with_key(config: NodeConfig, secret_key: Arc<SecretKey>) -> Self {
27+
pub fn with_key(config: NodeConfig, secret_key: Arc<SecretKey>) -> crate::Result<Self> {
2828
let metrics = MetricsRegistry::new();
2929

3030
// Create blockchain with or without persistent storage based on config
3131
let blockchain = if let Some(ref data_path) = config.data_dir {
3232
// Ensure data directory exists
3333
std::fs::create_dir_all(data_path)
34-
.expect("Failed to create data directory");
34+
.map_err(|e| crate::Error::Config(format!("Failed to create data directory: {}", e)))?;
3535

3636
println!("📦 Using persistent storage at: {}", data_path.display());
3737
Blockchain::with_storage(secret_key.clone(), metrics.clone(), data_path)
38-
.expect("Failed to initialize blockchain with storage")
38+
.map_err(|e| crate::Error::Config(format!("Failed to initialize blockchain with storage: {}", e)))?
3939
} else {
4040
println!("⚠️ Using in-memory storage (data will not persist)");
4141
Blockchain::new(secret_key.clone(), metrics.clone())
4242
};
4343

4444
let network = Arc::new(NetworkManager::new(secret_key.public_key(), metrics.clone()));
4545

46-
Self {
46+
Ok(Self {
4747
config,
4848
secret_key,
4949
state: StateManager::new(),
@@ -52,7 +52,7 @@ impl MinerNode {
5252
blockchain,
5353
tx_pool: TransactionPool::default(),
5454
network,
55-
}
55+
})
5656
}
5757

5858
pub async fn start(&mut self) -> Result<()> {
@@ -176,15 +176,15 @@ mod tests {
176176
fn test_miner_creation() {
177177
let config = NodeConfig::default();
178178
let sk = SecretKey::generate();
179-
let miner = MinerNode::new(config, sk);
179+
let miner = MinerNode::new(config, sk).unwrap();
180180
assert_eq!(miner.glider_strategy, GliderPattern::Standard);
181181
}
182182

183183
#[test]
184184
fn test_glider_generation() {
185185
let config = NodeConfig::default();
186186
let sk = SecretKey::generate();
187-
let miner = MinerNode::new(config, sk);
187+
let miner = MinerNode::new(config, sk).unwrap();
188188
let glider = miner.generate_glider();
189189
assert_eq!(glider.pattern, GliderPattern::Standard);
190190
}

crates/bitcell-node/src/validator.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub struct ValidatorNode {
2626
}
2727

2828
impl ValidatorNode {
29-
pub fn new(config: NodeConfig) -> Self {
29+
pub fn new(config: NodeConfig) -> crate::Result<Self> {
3030
let secret_key = if let Some(seed) = &config.key_seed {
3131
println!("Generating validator key from seed: {}", seed);
3232
let hash = bitcell_crypto::Hash256::hash(seed.as_bytes());
@@ -37,18 +37,18 @@ impl ValidatorNode {
3737
Self::with_key(config, secret_key)
3838
}
3939

40-
pub fn with_key(config: NodeConfig, secret_key: Arc<SecretKey>) -> Self {
40+
pub fn with_key(config: NodeConfig, secret_key: Arc<SecretKey>) -> crate::Result<Self> {
4141
let metrics = MetricsRegistry::new();
4242

4343
// Create blockchain with or without persistent storage based on config
4444
let blockchain = if let Some(ref data_path) = config.data_dir {
4545
// Ensure data directory exists
4646
std::fs::create_dir_all(data_path)
47-
.expect("Failed to create data directory");
47+
.map_err(|e| crate::Error::Config(format!("Failed to create data directory: {}", e)))?;
4848

4949
println!("📦 Using persistent storage at: {}", data_path.display());
5050
Blockchain::with_storage(secret_key.clone(), metrics.clone(), data_path)
51-
.expect("Failed to initialize blockchain with storage")
51+
.map_err(|e| crate::Error::Config(format!("Failed to initialize blockchain with storage: {}", e)))?
5252
} else {
5353
println!("⚠️ Using in-memory storage (data will not persist)");
5454
Blockchain::new(secret_key.clone(), metrics.clone())
@@ -57,7 +57,7 @@ impl ValidatorNode {
5757
let tournament_manager = Arc::new(crate::tournament::TournamentManager::new(metrics.clone()));
5858
let network = Arc::new(crate::network::NetworkManager::new(secret_key.public_key(), metrics.clone()));
5959

60-
Self {
60+
Ok(Self {
6161
config,
6262
state: StateManager::new(),
6363
peers: PeerManager::new(),
@@ -67,7 +67,7 @@ impl ValidatorNode {
6767
secret_key,
6868
tournament_manager,
6969
network,
70-
}
70+
})
7171
}
7272

7373
pub async fn start(&mut self) -> Result<()> {
@@ -290,7 +290,7 @@ mod tests {
290290
#[test]
291291
fn test_validator_creation() {
292292
let config = NodeConfig::default();
293-
let node = ValidatorNode::new(config);
293+
let node = ValidatorNode::new(config).unwrap();
294294
assert_eq!(node.state.accounts.len(), 0);
295295
}
296296
}

0 commit comments

Comments
 (0)