Transition network key to hex format (#7665)

#7181


  Instead of storing the network key as binary data we store it as hex, allowing users to modify it via the file.

We can read old-binary forms, however we will migrate binary to hex as it will be the new standard.
This commit is contained in:
Age Manning
2025-08-15 17:12:19 +10:00
committed by GitHub
parent 317dc0f56c
commit 9200042910

View File

@@ -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()
@@ -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| {
@@ -106,21 +103,54 @@ 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");
}
}
}
}
@@ -129,9 +159,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");
}