Skip to content

Transition network key to hex format #7665

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: unstable
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 44 additions & 17 deletions beacon_node/lighthouse_network/src/service/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Keypair, String> {
let hex_bytes = if let Some(stripped) = hex_bytes.strip_prefix("0x") {
stripped.to_string()
Expand All @@ -92,7 +90,6 @@ fn keypair_from_hex(hex_bytes: &str) -> Result<Keypair, String> {
.and_then(keypair_from_bytes)
}

#[allow(dead_code)]
fn keypair_from_bytes(mut bytes: Vec<u8>) -> Result<Keypair, String> {
secp256k1::SecretKey::try_from_bytes(&mut bytes)
.map(|secret| {
Expand All @@ -106,21 +103,52 @@ fn keypair_from_bytes(mut bytes: Vec<u8>) -> Result<Keypair, String> {
/// 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<u8> = 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<u8> = 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");
}
}
}
}
Expand All @@ -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");
}
Expand Down