From 309c45d2be889e90c2599178ef2a98fec6c2ff3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20I=C3=B1aki=20Bilbao?= Date: Thu, 15 May 2025 19:06:13 -0300 Subject: [PATCH 1/7] Replace accounts with wallets in Dirk config --- config.example.toml | 6 ++--- crates/common/src/config/signer.rs | 4 +-- crates/signer/src/manager/dirk.rs | 39 +++--------------------------- 3 files changed, 8 insertions(+), 41 deletions(-) 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 0b9c9855..63e1b215 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}; @@ -107,14 +103,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 +120,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 +129,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!( @@ -595,15 +571,10 @@ fn decompose_name(full_name: &str) -> eyre::Result<(String, String)> { /// 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) { - continue; - } - let Ok((wallet, name)) = decompose_name(&account.name) else { warn!("Invalid account name {}", account.name); continue; @@ -643,10 +614,6 @@ 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) { - continue; - } - let Ok(public_key) = BlsPublicKey::try_from(account.composite_public_key.as_slice()) else { warn!("Failed to parse composite public key for account {}", account.name); continue; From 67eb22acbe790ac5801da2f90efae3a440b6cd81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20I=C3=B1aki=20Bilbao?= Date: Fri, 16 May 2025 11:00:06 -0300 Subject: [PATCH 2/7] Remove unneeded separation of wallet and name --- crates/signer/src/manager/dirk.rs | 49 +++++++------------------------ 1 file changed, 11 insertions(+), 38 deletions(-) diff --git a/crates/signer/src/manager/dirk.rs b/crates/signer/src/manager/dirk.rs index 63e1b215..fb5adecf 100644 --- a/crates/signer/src/manager/dirk.rs +++ b/crates/signer/src/manager/dirk.rs @@ -33,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, } } } @@ -45,7 +45,6 @@ impl Account { struct SimpleAccount { public_key: BlsPublicKey, connection: Channel, - wallet: String, name: String, } @@ -54,7 +53,6 @@ struct DistributedAccount { composite_public_key: BlsPublicKey, participants: HashMap, threshold: u32, - wallet: String, name: String, } @@ -269,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 @@ -368,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, @@ -394,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), }), }; @@ -426,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, @@ -455,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), }), }; @@ -482,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())?; @@ -506,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; @@ -560,14 +553,6 @@ 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, @@ -575,11 +560,6 @@ fn load_simple_accounts( consensus_accounts: &mut HashMap, ) { for account in accounts { - 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( @@ -587,8 +567,7 @@ fn load_simple_accounts( Account::Simple(SimpleAccount { public_key, connection: channel.clone(), - wallet, - name, + name: account.name, }), ); } @@ -631,11 +610,6 @@ fn load_distributed_accounts( participants.insert(participant_id as u32, channel.clone()); } 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()); @@ -645,8 +619,7 @@ fn load_distributed_accounts( composite_public_key: public_key, participants, threshold: account.signing_threshold, - wallet, - name, + name: account.name, }), ); } From 9efd1ebd3995d8108d12eb8eb734d72a73a04d69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20I=C3=B1aki=20Bilbao?= Date: Fri, 16 May 2025 12:01:32 -0300 Subject: [PATCH 3/7] Ignore proxy accounts on load --- crates/signer/src/manager/dirk.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/crates/signer/src/manager/dirk.rs b/crates/signer/src/manager/dirk.rs index fb5adecf..6eb9888a 100644 --- a/crates/signer/src/manager/dirk.rs +++ b/crates/signer/src/manager/dirk.rs @@ -560,6 +560,11 @@ fn load_simple_accounts( consensus_accounts: &mut HashMap, ) { for account in accounts { + if name_matches_proxy(&account.name) { + debug!(account = account.name, "Ignoring account assuming it's a proxy key"); + continue; + } + match BlsPublicKey::try_from(account.public_key.as_slice()) { Ok(public_key) => { consensus_accounts.insert( @@ -593,6 +598,11 @@ fn load_distributed_accounts( .ok_or(eyre::eyre!("Host name not found for server {}", host.url))?; for account in accounts { + if name_matches_proxy(&account.name) { + debug!(account = account.name, "Ignoring account assuming it's a proxy key"); + continue; + } + let Ok(public_key) = BlsPublicKey::try_from(account.composite_public_key.as_slice()) else { warn!("Failed to parse composite public key for account {}", account.name); continue; @@ -679,6 +689,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] From 40dca068112082b4ee5380ebbfe9a53efb8f5ed5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20I=C3=B1aki=20Bilbao?= Date: Fri, 16 May 2025 12:11:17 -0300 Subject: [PATCH 4/7] Update docs --- docs/docs/get_started/configuration.md | 6 +++--- examples/configs/dirk_signer.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) 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" From c0705b9ed12c201a781e3ecd8683fda15b450bf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20I=C3=B1aki=20Bilbao?= Date: Fri, 16 May 2025 14:01:36 -0300 Subject: [PATCH 5/7] Add toolchain version to clippy --- justfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/justfile b/justfile index e6d11f62..924183d7 100644 --- a/justfile +++ b/justfile @@ -10,7 +10,7 @@ fmt-check: cargo +{{toolchain}} fmt --check clippy: - cargo clippy --all-features --no-deps -- -D warnings + cargo +{{toolchain}} clippy --all-features --no-deps -- -D warnings docker-build-pbs: docker build -t commitboost_pbs_default . -f ./provisioning/pbs.Dockerfile @@ -24,4 +24,4 @@ docker-build-test-modules: docker build -t test_status_api . -f examples/status_api/Dockerfile test: - cargo test --all-features \ No newline at end of file + cargo test --all-features From 2c365c05244b1ef41ec6c05b40cdf9e82f9c2629 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20I=C3=B1aki=20Bilbao?= Date: Thu, 29 May 2025 18:25:30 -0300 Subject: [PATCH 6/7] Build docker image --- .github/workflows/build.yml | 44 +++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..1fd74711 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,44 @@ +name: Build Signer Docker Image + +on: + push: + branches: + - "mb/remove_accounts" + +permissions: + contents: read + packages: write + +jobs: + build-and-push-signer-docker: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: true + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push signer Docker image + uses: docker/build-push-action@v6 + with: + context: . + push: true + platforms: linux/amd64,linux/arm64 + tags: ghcr.io/commit-boost/signer:dirk-easier-config + cache-from: type=registry,ref=ghcr.io/commit-boost/signer:buildcache + cache-to: type=registry,ref=ghcr.io/commit-boost/signer:buildcache,mode=max + file: provisioning/signer.Dockerfile From 8087bb1576234c3a333a7bcb6a918a81bc210f71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20I=C3=B1aki=20Bilbao?= Date: Mon, 9 Jun 2025 12:34:52 -0300 Subject: [PATCH 7/7] Remove GH workflow --- .github/workflows/build.yml | 44 ------------------------------------- 1 file changed, 44 deletions(-) delete mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 1fd74711..00000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: Build Signer Docker Image - -on: - push: - branches: - - "mb/remove_accounts" - -permissions: - contents: read - packages: write - -jobs: - build-and-push-signer-docker: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - submodules: true - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Build and push signer Docker image - uses: docker/build-push-action@v6 - with: - context: . - push: true - platforms: linux/amd64,linux/arm64 - tags: ghcr.io/commit-boost/signer:dirk-easier-config - cache-from: type=registry,ref=ghcr.io/commit-boost/signer:buildcache - cache-to: type=registry,ref=ghcr.io/commit-boost/signer:buildcache,mode=max - file: provisioning/signer.Dockerfile