Allow import of Prysm keystores (#1535)
## Issue Addressed - Resolves #1361 ## Proposed Changes Loosens the constraints imposed by EIP-2335 so we can import keys from Prysm. ## Additional Info NA
This commit is contained in:
parent
8311074d68
commit
46dd530476
@ -310,6 +310,15 @@ fn is_voting_keystore(file_name: &str) -> bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The format exported by Prysm. I don't have a reference for this, but it was shared via
|
||||||
|
// Discord to Paul H.
|
||||||
|
if Regex::new("keystore-[0-9]+.json")
|
||||||
|
.expect("regex is valid")
|
||||||
|
.is_match(file_name)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,8 +327,12 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn voting_keystore_filename() {
|
fn voting_keystore_filename_lighthouse() {
|
||||||
assert!(is_voting_keystore(VOTING_KEYSTORE_FILE));
|
assert!(is_voting_keystore(VOTING_KEYSTORE_FILE));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn voting_keystore_filename_launchpad() {
|
||||||
assert!(!is_voting_keystore("cats"));
|
assert!(!is_voting_keystore("cats"));
|
||||||
assert!(!is_voting_keystore(&format!("a{}", VOTING_KEYSTORE_FILE)));
|
assert!(!is_voting_keystore(&format!("a{}", VOTING_KEYSTORE_FILE)));
|
||||||
assert!(!is_voting_keystore(&format!("{}b", VOTING_KEYSTORE_FILE)));
|
assert!(!is_voting_keystore(&format!("{}b", VOTING_KEYSTORE_FILE)));
|
||||||
@ -337,4 +350,14 @@ mod tests {
|
|||||||
"keystore-m_12381_3600_1_0-1593476250.json"
|
"keystore-m_12381_3600_1_0-1593476250.json"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn voting_keystore_filename_prysm() {
|
||||||
|
assert!(is_voting_keystore("keystore-0.json"));
|
||||||
|
assert!(is_voting_keystore("keystore-1.json"));
|
||||||
|
assert!(is_voting_keystore("keystore-101238259.json"));
|
||||||
|
assert!(!is_voting_keystore("keystore-.json"));
|
||||||
|
assert!(!is_voting_keystore("keystore-0a.json"));
|
||||||
|
assert!(!is_voting_keystore("keystore-cats.json"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,10 +24,14 @@ use serde_repr::*;
|
|||||||
pub struct JsonKeystore {
|
pub struct JsonKeystore {
|
||||||
pub crypto: Crypto,
|
pub crypto: Crypto,
|
||||||
pub uuid: Uuid,
|
pub uuid: Uuid,
|
||||||
pub path: String,
|
/// EIP-2335 does not declare this field as optional, but Prysm is omitting it so we must
|
||||||
|
/// support it.
|
||||||
|
pub path: Option<String>,
|
||||||
pub pubkey: String,
|
pub pubkey: String,
|
||||||
pub version: Version,
|
pub version: Version,
|
||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
|
/// Not part of EIP-2335, but `ethdo` and Prysm have adopted it anyway so we must support it.
|
||||||
|
pub name: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Version for `JsonKeystore`.
|
/// Version for `JsonKeystore`.
|
||||||
|
@ -172,10 +172,11 @@ impl Keystore {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
uuid,
|
uuid,
|
||||||
path,
|
path: Some(path),
|
||||||
pubkey: keypair.pk.to_hex_string()[2..].to_string(),
|
pubkey: keypair.pk.to_hex_string()[2..].to_string(),
|
||||||
version: Version::four(),
|
version: Version::four(),
|
||||||
description: None,
|
description: None,
|
||||||
|
name: None,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -218,8 +219,8 @@ impl Keystore {
|
|||||||
/// Returns the path for the keystore.
|
/// Returns the path for the keystore.
|
||||||
///
|
///
|
||||||
/// Note: the path is not validated, it is simply whatever string the keystore provided.
|
/// Note: the path is not validated, it is simply whatever string the keystore provided.
|
||||||
pub fn path(&self) -> &str {
|
pub fn path(&self) -> Option<String> {
|
||||||
&self.json.path
|
self.json.path.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the pubkey for the keystore.
|
/// Returns the pubkey for the keystore.
|
||||||
|
@ -64,7 +64,7 @@ fn eip2335_test_vector_scrypt() {
|
|||||||
Uuid::parse_str("1d85ae20-35c5-4611-98e8-aa14a633906f").unwrap(),
|
Uuid::parse_str("1d85ae20-35c5-4611-98e8-aa14a633906f").unwrap(),
|
||||||
"uuid"
|
"uuid"
|
||||||
);
|
);
|
||||||
assert_eq!(keystore.path(), "", "path");
|
assert_eq!(keystore.path().unwrap(), "", "path");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -108,5 +108,5 @@ fn eip2335_test_vector_pbkdf() {
|
|||||||
Uuid::parse_str("64625def-3331-4eea-ab6f-782f3ed16a83").unwrap(),
|
Uuid::parse_str("64625def-3331-4eea-ab6f-782f3ed16a83").unwrap(),
|
||||||
"uuid"
|
"uuid"
|
||||||
);
|
);
|
||||||
assert_eq!(keystore.path(), "m/12381/60/0/0", "path");
|
assert_eq!(keystore.path().unwrap(), "m/12381/60/0/0", "path");
|
||||||
}
|
}
|
||||||
|
@ -841,10 +841,7 @@ fn missing_path() {
|
|||||||
}
|
}
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
match Keystore::from_json_str(&vector) {
|
assert!(Keystore::from_json_str(&vector).is_ok());
|
||||||
Err(Error::InvalidJson(_)) => {}
|
|
||||||
_ => panic!("expected invalid json error"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1010,3 +1007,43 @@ fn pbkdf2_missing_parameter() {
|
|||||||
_ => panic!("expected invalid json error"),
|
_ => panic!("expected invalid json error"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn name_field() {
|
||||||
|
let vector = r#"
|
||||||
|
{
|
||||||
|
"crypto": {
|
||||||
|
"kdf": {
|
||||||
|
"function": "scrypt",
|
||||||
|
"params": {
|
||||||
|
"dklen": 32,
|
||||||
|
"n": 262144,
|
||||||
|
"p": 1,
|
||||||
|
"r": 8,
|
||||||
|
"salt": "d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3"
|
||||||
|
},
|
||||||
|
"message": ""
|
||||||
|
},
|
||||||
|
"checksum": {
|
||||||
|
"function": "sha256",
|
||||||
|
"params": {},
|
||||||
|
"message": "149aafa27b041f3523c53d7acba1905fa6b1c90f9fef137568101f44b531a3cb"
|
||||||
|
},
|
||||||
|
"cipher": {
|
||||||
|
"function": "aes-128-ctr",
|
||||||
|
"params": {
|
||||||
|
"iv": "264daa3f303d7259501c93d997d84fe6"
|
||||||
|
},
|
||||||
|
"message": "54ecc8863c0550351eee5720f3be6a5d4a016025aa91cd6436cfec938d6a8d30"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pubkey": "9612d7a727c9d0a22e185a1c768478dfe919cada9266988cb32359c11f2b7b27f4ae4040902382ae2910c15e2b420d07",
|
||||||
|
"uuid": "1d85ae20-35c5-4611-98e8-aa14a633906f",
|
||||||
|
"path": "",
|
||||||
|
"version": 4,
|
||||||
|
"name": "cats"
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
|
||||||
|
assert!(Keystore::from_json_str(&vector).is_ok());
|
||||||
|
}
|
||||||
|
@ -225,13 +225,13 @@ fn key_derivation_from_seed() {
|
|||||||
.expect("should generate keystores");
|
.expect("should generate keystores");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
keystores.voting.path(),
|
keystores.voting.path().unwrap(),
|
||||||
format!("m/12381/3600/{}/0/0", i),
|
format!("m/12381/3600/{}/0/0", i),
|
||||||
"voting path should match"
|
"voting path should match"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
keystores.withdrawal.path(),
|
keystores.withdrawal.path().unwrap(),
|
||||||
format!("m/12381/3600/{}/0", i),
|
format!("m/12381/3600/{}/0", i),
|
||||||
"withdrawal path should match"
|
"withdrawal path should match"
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user