diff --git a/beacon_node/lighthouse_network/src/service/utils.rs b/beacon_node/lighthouse_network/src/service/utils.rs index 9a939368743..d6b18b84b2d 100644 --- a/beacon_node/lighthouse_network/src/service/utils.rs +++ b/beacon_node/lighthouse_network/src/service/utils.rs @@ -78,8 +78,6 @@ pub fn build_transport( Ok(transport) } -// Useful helper functions for debugging. Currently not used in the client. -#[allow(dead_code)] fn keypair_from_hex(hex_bytes: &str) -> Result { let hex_bytes = if let Some(stripped) = hex_bytes.strip_prefix("0x") { stripped.to_string() @@ -92,7 +90,6 @@ fn keypair_from_hex(hex_bytes: &str) -> Result { .and_then(keypair_from_bytes) } -#[allow(dead_code)] fn keypair_from_bytes(mut bytes: Vec) -> Result { secp256k1::SecretKey::try_from_bytes(&mut bytes) .map(|secret| { @@ -106,21 +103,52 @@ fn keypair_from_bytes(mut bytes: Vec) -> Result { /// generated and is then saved to disk. /// /// Currently only secp256k1 keys are allowed, as these are the only keys supported by discv5. +/// Supports both hex format (with or without 0x prefix) and raw bytes format. pub fn load_private_key(config: &NetworkConfig) -> Keypair { // check for key from disk let network_key_f = config.network_dir.join(NETWORK_KEY_FILENAME); if let Ok(mut network_key_file) = File::open(network_key_f.clone()) { - let mut key_bytes: Vec = Vec::with_capacity(36); - match network_key_file.read_to_end(&mut key_bytes) { - Err(_) => debug!("Could not read network key file"), - Ok(_) => { - // only accept secp256k1 keys for now - if let Ok(secret_key) = secp256k1::SecretKey::try_from_bytes(&mut key_bytes) { - let kp: secp256k1::Keypair = secret_key.into(); - debug!("Loaded network key from disk."); - return kp.into(); - } else { - debug!("Network key file is not a valid secp256k1 key"); + // Limit read to reasonable hex key size: 32 bytes = 64 hex chars + "0x" prefix + whitespace + let mut buffer = vec![0u8; 70]; + match network_key_file.read(&mut buffer) { + Ok(bytes_read) => { + if let Ok(hex_string) = String::from_utf8(buffer[..bytes_read].to_vec()) { + // First try to parse as hex string + let hex_content = hex_string.trim(); + if let Ok(keypair) = keypair_from_hex(hex_content) { + debug!("Loaded network key from disk (hex format)."); + return keypair; + } + } + } + Err(_) => debug!("Could not read network key file as string, trying binary format"), + } + + // If hex parsing failed or file couldn't be read as string, try binary format + if let Ok(mut network_key_file) = File::open(network_key_f.clone()) { + let mut key_bytes: Vec = Vec::with_capacity(36); + match network_key_file.read_to_end(&mut key_bytes) { + Err(_) => debug!("Could not read network key file"), + Ok(_) => { + // only accept secp256k1 keys for now + if let Ok(secret_key) = secp256k1::SecretKey::try_from_bytes(&mut key_bytes) { + let kp: secp256k1::Keypair = secret_key.clone().into(); + debug!("Loaded network key from disk (binary format), migrating to hex format."); + + // Migrate binary key to hex format + let hex_key = hex::encode(secret_key.to_bytes()); + if let Err(e) = File::create(network_key_f.clone()) + .and_then(|mut f| f.write_all(hex_key.as_bytes())) + { + debug!("Failed to migrate key to hex format: {}", e); + } else { + debug!("Successfully migrated key to hex format."); + } + + return kp.into(); + } else { + debug!("Network key file is not a valid secp256k1 key"); + } } } } @@ -129,9 +157,8 @@ pub fn load_private_key(config: &NetworkConfig) -> Keypair { // if a key could not be loaded from disk, generate a new one and save it let local_private_key = secp256k1::Keypair::generate(); let _ = std::fs::create_dir_all(&config.network_dir); - match File::create(network_key_f.clone()) - .and_then(|mut f| f.write_all(&local_private_key.secret().to_bytes())) - { + let hex_key = hex::encode(local_private_key.secret().to_bytes()); + match File::create(network_key_f.clone()).and_then(|mut f| f.write_all(hex_key.as_bytes())) { Ok(_) => { debug!("New network key generated and written to disk"); }