Skip to content
Merged
Show file tree
Hide file tree
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
8 changes: 5 additions & 3 deletions config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -212,19 +212,21 @@ jwt_auth_fail_timeout_seconds = 300
[signer.local.loader]
# File: path to the keys file
key_path = "./tests/data/keys.example.json"
# ValidatorsDir: format of the keystore (lighthouse, prysm, teku or lodestar)
# ValidatorsDir: format of the keystore (lighthouse, prysm, teku, lodestar, or nimbus)
# format = "lighthouse"
# ValidatorsDir: full path to the keys directory
# For lighthouse, it's de path to the directory where the `<pubkey>/voting-keystore.json` directories are located.
# For lighthouse, it's the path to the directory where the `<pubkey>` directories are located, under each of which is a `voting-keystore.json` file.
# For prysm, it's the path to the `all-accounts.keystore.json` file.
# For teku, it's the path to the directory where all `<pubkey>.json` files are located.
# For lodestar, it's the path to the directory where all `<pubkey>.json` files are located.
# For nimbus, it's the path to the directory where the `<pubkey>` directories are located, under each of which is a `keystore.json` file.
# keys_path = ""
# ValidatorsDir: full path to the secrets file/directory
# For lighthouse, it's de path to the directory where the `<pubkey>.json` files are located.
# For lighthouse, it's the path to the directory where the `<pubkey>` files are located.
# For prysm, it's the path to the file containing the wallet decryption password.
# For teku, it's the path to the directory where all `<pubkey>.txt` files are located.
# For lodestar, it's the path to the file containing the decryption password.
# For nimbus, it's the path to the directory where the `<pubkey>` files are located.
# secrets_path = ""
# Configuration for how the Signer module should store proxy delegations. Supported types of store are:
# - File: store keys and delegations from a plain text file (unsafe, use only for testing purposes)
Expand Down
53 changes: 52 additions & 1 deletion crates/common/src/signer/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ pub enum ValidatorKeysFormat {
Lodestar,
#[serde(alias = "prysm")]
Prysm,
#[serde(alias = "nimbus")]
Nimbus,
}

impl SignerLoader {
Expand Down Expand Up @@ -85,6 +87,7 @@ impl SignerLoader {
load_from_lodestar_format(keys_path, secrets_path)
}
ValidatorKeysFormat::Prysm => load_from_prysm_format(keys_path, secrets_path),
ValidatorKeysFormat::Nimbus => load_from_nimbus_format(keys_path, secrets_path),
};
}
})
Expand Down Expand Up @@ -272,6 +275,42 @@ fn load_from_prysm_format(
Ok(signers)
}

fn load_from_nimbus_format(
keys_path: PathBuf,
secrets_path: PathBuf,
) -> eyre::Result<Vec<ConsensusSigner>> {
let paths: Vec<_> =
fs::read_dir(&keys_path)?.map(|res| res.map(|e| e.path())).collect::<Result<_, _>>()?;

let signers = paths
.into_par_iter()
.filter_map(|path| {
if !path.is_dir() {
return None
}

let maybe_pubkey = path.file_name().and_then(|d| d.to_str())?;
let Ok(pubkey) = BlsPublicKey::from_hex(maybe_pubkey) else {
warn!("Invalid pubkey: {}", maybe_pubkey);
return None
};

let ks_path = keys_path.join(maybe_pubkey).join("keystore.json");
let pw_path = secrets_path.join(pubkey.to_string());

match load_one(ks_path, pw_path) {
Ok(signer) => Some(signer),
Err(e) => {
warn!("Failed to load signer for pubkey: {}, err: {}", pubkey, e);
None
}
}
})
.collect();

Ok(signers)
}

fn load_one(ks_path: PathBuf, pw_path: PathBuf) -> eyre::Result<ConsensusSigner> {
let keystore = Keystore::from_json_file(ks_path).map_err(|_| eyre!("failed reading json"))?;
let password = fs::read(pw_path.clone())
Expand Down Expand Up @@ -303,7 +342,7 @@ mod tests {

use super::{load_from_lighthouse_format, load_from_lodestar_format, FileKey};
use crate::signer::{
loader::{load_from_prysm_format, load_from_teku_format},
loader::{load_from_nimbus_format, load_from_prysm_format, load_from_teku_format},
BlsPublicKey, BlsSigner,
};

Expand Down Expand Up @@ -399,4 +438,16 @@ mod tests {
hex!("b3a22e4a673ac7a153ab5b3c17a4dbef55f7e47210b20c0cbb0e66df5b36bb49ef808577610b034172e955d2312a61b9")
)));
}

#[test]
fn test_load_nimbus() {
let result = load_from_nimbus_format(
"../../tests/data/keystores/nimbus-keys".into(),
"../../tests/data/keystores/secrets".into(),
);

assert!(result.is_ok());

test_correct_load(result.unwrap());
}
}
33 changes: 32 additions & 1 deletion docs/docs/get_started/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ keys_path = "/path/to/keys"
secrets_path = "/path/to.secrets"
```

We currently support Lighthouse, Prysm, Teku and Lodestar's keystores so it's easier to load the keys. We're working on adding support for additional keystores. These are the expected file structures for each format:
We currently support Lighthouse, Prysm, Teku, Lodestar, and Nimbus's keystores so it's easier to load the keys. We're working on adding support for additional keystores. These are the expected file structures for each format:

<details>
<summary>Lighthouse</summary>
Expand Down Expand Up @@ -175,6 +175,37 @@ We currently support Lighthouse, Prysm, Teku and Lodestar's keystores so it's ea
:::
</details>

<details>
<summary>Nimbus</summary>

#### File structure:
```
├── keys
│   ├── <PUBLIC_KEY_1>
│   │   └── keystore.json
│   └── <PUBLIC_KEY_2>
│   └── keystore.json
└── secrets
   ├── <PUBLIC_KEY_1>
   └── <PUBLIC_KEY_2>
```

#### Config:
```toml
[pbs]
...
with_signer = true

[signer]
port = 20000

[signer.local.loader]
format = "nimbus"
keys_path = "keys"
secrets_path = "secrets"
```
</details>

### Proxy keys store

Proxy keys can be used to sign transactions with a different key than the one used to sign the block. Proxy keys are generated by the Signer module and authorized by the validator key. Each module have their own proxy keys, that can be BLS or ECDSA.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"0ded1a0ed9d0d5aa9c41ac1a6be6d9943835f9ccbe1081869af74925611a4687"},"message":""},"checksum":{"function":"sha256","params":{},"message":"b1de458543b0532666e8f24e679f93ed6f168fd09de1da7c3f4f79b7fa2f2412"},"cipher":{"function":"aes-128-ctr","params":{"iv":"3ca34eb318e53a4c7e545571d8d0c7af"},"message":"acc6c222eea80974107b5a9bf824c8156edaad944f0d444a1aab4cc2118cecc5"}},"description":"0x883827193f7627cd04e621e1e8d56498362a52b2a30c9a1c72036eb935c4278dee23d38a24d2f7dda62689886f0c39f4","pubkey":"883827193f7627cd04e621e1e8d56498362a52b2a30c9a1c72036eb935c4278dee23d38a24d2f7dda62689886f0c39f4","path":"","uuid":"61c06c9c-b0bc-4022-9bf8-a2f250d4e751","version":4}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"crypto":{"kdf":{"function":"pbkdf2","params":{"dklen":32,"c":262144,"prf":"hmac-sha256","salt":"2154bba4d5999c6069442db5b499b2b27b6c2f54f36490e51163934dd4fb412e"},"message":""},"checksum":{"function":"sha256","params":{},"message":"1db4975098c97905f1dd9a9207cab0a9af7e16bebdab700ee08efb51e068017f"},"cipher":{"function":"aes-128-ctr","params":{"iv":"2265a3b57110b46c08295e53379165b5"},"message":"3bd312cc34cebfdd890c9704752191ed93ecd562bb62d2d8ceb4ff945b58b790"}},"description":"0xb3a22e4a673ac7a153ab5b3c17a4dbef55f7e47210b20c0cbb0e66df5b36bb49ef808577610b034172e955d2312a61b9","pubkey":"b3a22e4a673ac7a153ab5b3c17a4dbef55f7e47210b20c0cbb0e66df5b36bb49ef808577610b034172e955d2312a61b9","path":"","uuid":"a8457299-739d-42fb-a0f6-961020f22b8e","version":4}