diff --git a/bolt-sidecar/src/signer/keystore.rs b/bolt-sidecar/src/signer/keystore.rs index 00c0dcc16..6513fcba9 100644 --- a/bolt-sidecar/src/signer/keystore.rs +++ b/bolt-sidecar/src/signer/keystore.rs @@ -119,3 +119,120 @@ fn keystore_paths(keys_path: Option<&str>) -> Result, eyre::Error> Ok(keystores_paths) } + +#[cfg(test)] +mod tests { + use std::{fs::File, io::Write}; + + use blst::min_pk::SecretKey; + + use crate::{signer::local::LocalSigner, ChainConfig}; + + use super::{KeystoreSigner, KEYSTORES_DEFAULT_PATH}; + /// The str path of the root of the project + pub const CARGO_MANIFEST_DIR: &str = env!("CARGO_MANIFEST_DIR"); + + #[test] + fn test_keystore_signer() { + // 0. Test data setup + + // Reference: https://eips.ethereum.org/EIPS/eip-2335#test-cases + let test_keystore_json = r#" + { + "crypto": { + "kdf": { + "function": "scrypt", + "params": { + "dklen": 32, + "n": 262144, + "p": 1, + "r": 8, + "salt": "d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" + }, + "message": "" + }, + "checksum": { + "function": "sha256", + "params": {}, + "message": "d2217fe5f3e9a1e34581ef8a78f7c9928e436d36dacc5e846690a5581e8ea484" + }, + "cipher": { + "function": "aes-128-ctr", + "params": { + "iv": "264daa3f303d7259501c93d997d84fe6" + }, + "message": "06ae90d55fe0a6e9c5c3bc5b170827b2e5cce3929ed3f116c2811e6366dfe20f" + } + }, + "description": "This is a test keystore that uses scrypt to secure the secret.", + "pubkey": "9612d7a727c9d0a22e185a1c768478dfe919cada9266988cb32359c11f2b7b27f4ae4040902382ae2910c15e2b420d07", + "path": "m/12381/60/3141592653/589793238", + "uuid": "1d85ae20-35c5-4611-98e8-aa14a633906f", + "version": 4 + } + "#; + // Reference: https://eips.ethereum.org/EIPS/eip-2335#test-cases + let keystore_password = r#"𝔱𝔢𝔰𝔱𝔭𝔞𝔰𝔰𝔴𝔬𝔯𝔡🔑"#; + let keystore_public_key = "0x9612d7a727c9d0a22e185a1c768478dfe919cada9266988cb32359c11f2b7b27f4ae4040902382ae2910c15e2b420d07"; + let keystore_publlc_key_bytes: [u8; 48] = [ + 0x96, 0x12, 0xd7, 0xa7, 0x27, 0xc9, 0xd0, 0xa2, 0x2e, 0x18, 0x5a, 0x1c, 0x76, 0x84, + 0x78, 0xdf, 0xe9, 0x19, 0xca, 0xda, 0x92, 0x66, 0x98, 0x8c, 0xb3, 0x23, 0x59, 0xc1, + 0x1f, 0x2b, 0x7b, 0x27, 0xf4, 0xae, 0x40, 0x40, 0x90, 0x23, 0x82, 0xae, 0x29, 0x10, + 0xc1, 0x5e, 0x2b, 0x42, 0x0d, 0x07, + ]; + let keystore_secret_key = + "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"; + let chain_config = ChainConfig::mainnet(); + + // 1. Create a temp directory with the keystore and create a signer from it + + let path_str = format!("{}/{}", CARGO_MANIFEST_DIR, KEYSTORES_DEFAULT_PATH); + let tmp_dir = + tempfile::TempDir::with_prefix_in("0xdeadbeefdeadbeefdeadbeefdeadbeef", path_str) + .expect("to create temp dir"); + + // NOTE: it is sufficient to create a temp dir, then we can create a file as usual and it + // will be dropped correctly + let mut tmp_file = File::create_new(tmp_dir.path().join("voting-keystore.json")) + .expect("to create new file"); + + tmp_file.write_all(test_keystore_json.as_bytes()).expect("to write to temp file"); + + for entry in tmp_dir.path().read_dir().expect("to read tmp dir") { + let mut path = entry.expect("to read entry").path(); + println!("inside loop: {:?}", path); + let extenstion = + path.extension().expect("to get extension").to_str().expect("to convert to str"); + + if extenstion.contains("tmp") { + path.set_extension("json"); + println!("path: {:?}", path); + break; + } + } + + let keystore_signer = KeystoreSigner::new(None, keystore_password.as_bytes(), chain_config) + .expect("to create keystore signer"); + + assert_eq!(keystore_signer.keypairs.len(), 1); + assert_eq!( + keystore_signer.keypairs.first().expect("to get keypair").pk.to_string(), + keystore_public_key + ); + + // 2. Sign a message with the signer and check the signature + + let keystore_sk_bls = SecretKey::from_bytes( + hex::decode(keystore_secret_key).expect("to decode secret key").as_slice(), + ) + .expect("to create secret key"); + + let local_signer = LocalSigner::new(keystore_sk_bls, chain_config); + + let sig_local = local_signer.sign_commit_boost_root([0; 32]).expect("to sign message"); + let sig_keystore = keystore_signer + .sign_commit_boost_root([0; 32], keystore_publlc_key_bytes) + .expect("to sign message"); + assert_eq!(sig_local, sig_keystore); + } +}