diff --git a/config.example.toml b/config.example.toml index ae69c3ff..bd3653f9 100644 --- a/config.example.toml +++ b/config.example.toml @@ -171,13 +171,13 @@ url = "http://0xa119589bb33ef52acbb8116832bec2b58fca590fe5c85eac5d3230b44d5bc09f # server_name = "localhost-1" # Complete URL of a Dirk gateway # url = "https://localhost:8881" -# Accounts to use as consensus keys -# accounts = ["Wallet1/Account1", "DistributedWallet/Account1"] +# Wallets to load consensus keys from +# accounts = ["Wallet1", "DistributedWallet"] # [[signer.dirk.hosts]] # server_name = "localhost-2" # url = "https://localhost:8882" -# accounts = ["Wallet2/Account2", "DistributedWallet/Account1"] +# accounts = ["Wallet2", "DistributedWallet"] # Configuration for how the Signer module should store proxy delegations. # OPTIONAL diff --git a/crates/common/src/config/signer.rs b/crates/common/src/config/signer.rs index 9df6b948..6a055036 100644 --- a/crates/common/src/config/signer.rs +++ b/crates/common/src/config/signer.rs @@ -37,8 +37,8 @@ pub struct DirkHostConfig { pub server_name: Option, /// Complete URL of the Dirk server pub url: Url, - /// Accounts used as consensus keys - pub accounts: Vec, + /// Wallets to load consensus keys from + pub wallets: Vec, } #[derive(Debug, Serialize, Deserialize, Clone)] diff --git a/crates/signer/src/manager/dirk.rs b/crates/signer/src/manager/dirk.rs index f23f9f3e..4c2d909f 100644 --- a/crates/signer/src/manager/dirk.rs +++ b/crates/signer/src/manager/dirk.rs @@ -1,8 +1,4 @@ -use std::{ - collections::{HashMap, HashSet}, - io::Write, - path::PathBuf, -}; +use std::{collections::HashMap, io::Write, path::PathBuf}; use alloy::{hex, rpc::types::beacon::constants::BLS_SIGNATURE_BYTES_LEN}; use blsful::inner_types::{Field, G2Affine, G2Projective, Group, Scalar}; @@ -37,10 +33,10 @@ enum Account { } impl Account { - pub fn full_name(&self) -> String { + pub fn name(&self) -> &str { match self { - Account::Simple(account) => format!("{}/{}", account.wallet, account.name), - Account::Distributed(account) => format!("{}/{}", account.wallet, account.name), + Account::Simple(account) => &account.name, + Account::Distributed(account) => &account.name, } } } @@ -49,7 +45,6 @@ impl Account { struct SimpleAccount { public_key: BlsPublicKey, connection: Channel, - wallet: String, name: String, } @@ -58,7 +53,6 @@ struct DistributedAccount { composite_public_key: BlsPublicKey, participants: HashMap, threshold: u32, - wallet: String, name: String, } @@ -107,14 +101,8 @@ impl DirkManager { } }; - let wallets: HashSet = host - .accounts - .iter() - .map(|account| decompose_name(account).unwrap_or_default().0) - .collect(); - let accounts_response = match ListerClient::new(channel.clone()) - .list_accounts(ListAccountsRequest { paths: wallets.into_iter().collect() }) + .list_accounts(ListAccountsRequest { paths: host.wallets.clone() }) .await { Ok(res) => res, @@ -130,12 +118,7 @@ impl DirkManager { } let accounts_response = accounts_response.into_inner(); - load_simple_accounts( - accounts_response.accounts, - &host, - &channel, - &mut consensus_accounts, - ); + load_simple_accounts(accounts_response.accounts, &channel, &mut consensus_accounts); load_distributed_accounts( accounts_response.distributed_accounts, &host, @@ -144,15 +127,6 @@ impl DirkManager { ) .map_err(|error| warn!("{error}")) .ok(); - - for account in host.accounts { - if !consensus_accounts - .values() - .any(|account| account.full_name() == account.full_name()) - { - warn!("Account {account} not found in server {}", host.url); - } - } } debug!( @@ -293,10 +267,7 @@ impl DirkManager { .sign(SignRequest { data: object_root.to_vec(), domain: compute_domain(self.chain, COMMIT_BOOST_DOMAIN).to_vec(), - id: Some(sign_request::Id::Account(format!( - "{}/{}", - account.wallet, account.name - ))), + id: Some(sign_request::Id::Account(account.name.clone())), }) .map(|res| (res, *id)) .await @@ -392,7 +363,7 @@ impl DirkManager { let response = AccountManagerClient::new(consensus.connection.clone()) .generate(GenerateRequest { - account: format!("{}/{}/{module}/{uuid}", consensus.wallet, consensus.name), + account: format!("{}/{module}/{uuid}", consensus.name), passphrase: password.as_bytes().to_vec(), participants: 1, signing_threshold: 1, @@ -418,7 +389,6 @@ impl DirkManager { inner: Account::Simple(SimpleAccount { public_key: proxy_key, connection: consensus.connection.clone(), - wallet: consensus.wallet.clone(), name: format!("{}/{module}/{uuid}", consensus.name), }), }; @@ -450,7 +420,7 @@ impl DirkManager { for (id, channel) in consensus.participants.iter() { let Ok(response) = AccountManagerClient::new(channel.clone()) .generate(GenerateRequest { - account: format!("{}/{}/{module}/{uuid}", consensus.wallet, consensus.name), + account: format!("{}/{module}/{uuid}", consensus.name), passphrase: password.as_bytes().to_vec(), participants: consensus.participants.len() as u32, signing_threshold: consensus.threshold, @@ -479,7 +449,6 @@ impl DirkManager { composite_public_key: proxy_key, participants: consensus.participants.clone(), threshold: consensus.threshold, - wallet: consensus.wallet.clone(), name: format!("{}/{module}/{uuid}", consensus.name), }), }; @@ -506,8 +475,8 @@ impl DirkManager { /// Store the password for a proxy account in disk fn store_password(&self, account: &ProxyAccount, password: String) -> eyre::Result<()> { - let full_name = account.inner.full_name(); - let (parent, name) = full_name.rsplit_once('/').ok_or_eyre("Invalid account name")?; + let name = account.inner.name(); + let (parent, name) = name.rsplit_once('/').ok_or_eyre("Invalid account name")?; let parent_path = self.secrets_path.join(parent); std::fs::create_dir_all(parent_path.clone())?; @@ -530,7 +499,7 @@ impl DirkManager { let request = async move { let response = AccountManagerClient::new(channel.clone()) .unlock(UnlockAccountRequest { - account: account.full_name(), + account: account.name().to_string(), passphrase: password.as_bytes().to_vec(), }) .await; @@ -584,31 +553,18 @@ async fn connect( .map_err(eyre::Error::from) } -/// Decompose a full account name into wallet and name -fn decompose_name(full_name: &str) -> eyre::Result<(String, String)> { - full_name - .split_once('/') - .map(|(wallet, name)| (wallet.to_string(), name.to_string())) - .ok_or_else(|| eyre::eyre!("Invalid account name")) -} - /// Load `SimpleAccount`s into the consensus accounts map fn load_simple_accounts( accounts: Vec, - host: &DirkHostConfig, channel: &Channel, consensus_accounts: &mut HashMap, ) { for account in accounts { - if !host.accounts.contains(&account.name) { + if name_matches_proxy(&account.name) { + debug!(account = account.name, "Ignoring account assuming it's a proxy key"); continue; } - let Ok((wallet, name)) = decompose_name(&account.name) else { - warn!("Invalid account name {}", account.name); - continue; - }; - match BlsPublicKey::try_from(account.public_key.as_slice()) { Ok(public_key) => { consensus_accounts.insert( @@ -616,8 +572,7 @@ fn load_simple_accounts( Account::Simple(SimpleAccount { public_key, connection: channel.clone(), - wallet, - name, + name: account.name, }), ); } @@ -643,7 +598,8 @@ fn load_distributed_accounts( .ok_or(eyre::eyre!("Host name not found for server {}", host.url))?; for account in accounts { - if !host.accounts.contains(&account.name) { + if name_matches_proxy(&account.name) { + debug!(account = account.name, "Ignoring account assuming it's a proxy key"); continue; } @@ -677,11 +633,6 @@ fn load_distributed_accounts( } } None => { - let Ok((wallet, name)) = decompose_name(&account.name) else { - warn!("Invalid account name {}", account.name); - continue; - }; - let mut participants = HashMap::with_capacity(account.participants.len()); participants.insert(participant_id as u32, channel.clone()); @@ -691,8 +642,7 @@ fn load_distributed_accounts( composite_public_key: public_key, participants, threshold: account.signing_threshold, - wallet, - name, + name: account.name, }), ); } @@ -752,6 +702,14 @@ fn random_password() -> String { hex::encode(password_bytes) } +/// Returns whether the name of an account has a proxy name format. +/// +/// i.e., `{wallet}/{consensus_proxy}/{module}/{uuid}` +fn name_matches_proxy(name: &str) -> bool { + name.split("/").count() > 3 && + name.rsplit_once("/").is_some_and(|(_, name)| uuid::Uuid::parse_str(name).is_ok()) +} + mod test { #[test] diff --git a/docs/docs/get_started/configuration.md b/docs/docs/get_started/configuration.md index 4e642205..361822cc 100644 --- a/docs/docs/get_started/configuration.md +++ b/docs/docs/get_started/configuration.md @@ -256,16 +256,16 @@ ca_cert_path = "/path/to/ca.crt" [[signer.dirk.hosts]] server_name = "localhost-1" url = "https://localhost-1:8081" -accounts = ["SomeWallet/SomeAccount", "DistributedWallet/Account1"] +wallets = ["SomeWallet", "DistributedWallet"] [[signer.dirk.hosts]] server_name = "localhost-2" url = "https://localhost-2:8082" -accounts = ["AnotherWallet/AnotherAccount", "DistributedWallet/Account1"] +wallets = ["AnotherWallet", "DistributedWallet"] ``` - `cert_path` and `key_path` are the paths to the client certificate and key used to authenticate with Dirk. -- `accounts` is a list of accounts that the Signer module will consider as the consensus keys. Each account has the format `/`. Accounts can be from different wallets. Generated proxy keys will have format `///`. +- `wallets` is a list of wallets from which the Signer module will load all accounts as consensus keys. Generated proxy keys will have format `///`, so accounts found with that pattern will be ignored. - `secrets_path` is the path to the folder containing the passwords of the generated proxy accounts, which will be stored in `////.pass`. Additionally, you can set a proxy store so that the delegation signatures for generated proxy keys are stored locally. As these signatures are not sensitive, the only supported store type is `File`: diff --git a/examples/configs/dirk_signer.toml b/examples/configs/dirk_signer.toml index 5dd1c9d3..237f0a22 100644 --- a/examples/configs/dirk_signer.toml +++ b/examples/configs/dirk_signer.toml @@ -18,7 +18,7 @@ ca_cert_path = "/path/to/ca.crt" # Example of a single Dirk host [[signer.dirk.hosts]] url = "https://gateway.dirk.url" -accounts = ["wallet1/accountX", "wallet2/accountY"] +wallets = ["wallet1", "wallet2"] [signer.dirk.store] proxy_dir = "/path/to/proxies" diff --git a/justfile b/justfile index ee5f4c2d..5263aaa1 100644 --- a/justfile +++ b/justfile @@ -194,4 +194,4 @@ clean: # Runs the suite of tests for all commit-boost crates. test: - cargo test --all-features \ No newline at end of file + cargo test --all-features