Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
c68125d
bump version
ltitanb Apr 2, 2025
d9979a2
Successful cross-compilation, but runtime has memory allocation issues
jclapis May 5, 2025
97ef653
Working with OpenSSL static-linked
jclapis May 6, 2025
91eefe2
Got dynamic linking working, added a feature flag to toggle dynamic v…
jclapis May 6, 2025
de09415
Fixed the vendored build arg
jclapis May 6, 2025
3aee63d
Reintroduced the cargo chef setup
jclapis May 6, 2025
c07c717
Ported the cross-compilation stuff into PBS
jclapis May 6, 2025
699b7ec
Split the dockerfiles into separate builder / image definitions
jclapis May 7, 2025
7165f12
Added a build guide
jclapis May 7, 2025
9438dae
Refactored the Github release action to use the Docker builder
jclapis May 13, 2025
12c020a
Fixed the Docker image binary filenames
jclapis May 13, 2025
53cafc0
Cleaned up the Darwin artifact step
jclapis May 13, 2025
58c6117
Made the CI workflow and justfile use the same toolchain as the source
jclapis May 14, 2025
45e581b
Revert "Made the CI workflow and justfile use the same toolchain as t…
jclapis May 14, 2025
24a10c5
Testing removal of OpenSSL vendored option
jclapis May 14, 2025
e36da54
Updating just in the CI workflow
jclapis May 14, 2025
843b110
Merge branch 'main' into cross-compile
jclapis May 28, 2025
e7c6d19
Refactored the signer to support host and port config settings
jclapis May 21, 2025
6117219
Updated docs
jclapis May 21, 2025
c0f591d
Fixing Clippy in CI workflow
jclapis May 21, 2025
adbd34a
Removed obviated CI setup
jclapis May 28, 2025
346eea4
Cleaned up the build Dockerfile and removed an extra dependency layer
jclapis May 28, 2025
7b20d2f
Ported the build script over to the justfile
jclapis May 29, 2025
cf3f0b1
Merge branch 'main' into cross-compile
jclapis May 29, 2025
ca9f4a1
Added a justfile recipe for installing protoc
jclapis May 29, 2025
3eed526
Merge branch 'cross-compile' into add-ip-bind-to-signer
jclapis May 29, 2025
fc872ac
Merge branch 'main' into add-ip-bind-to-signer
jclapis Jun 3, 2025
40d34aa
Merge branch 'main' into add-ip-bind-to-signer
jclapis Jun 9, 2025
d537288
Update crates/cli/src/docker_init.rs
jclapis Jun 9, 2025
7afb763
Added example signer config params
jclapis Jun 9, 2025
09ac821
Cleaned up signer config loading from feedback
jclapis Jun 9, 2025
cf39d86
Merge remote-tracking branch 'origin/add-ip-bind-to-signer' into add-…
jclapis Jun 9, 2025
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
7 changes: 7 additions & 0 deletions config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,13 @@ url = "http://0xa119589bb33ef52acbb8116832bec2b58fca590fe5c85eac5d3230b44d5bc09f
# Docker image to use for the Signer module.
# OPTIONAL, DEFAULT: ghcr.io/commit-boost/signer:latest
# docker_image = "ghcr.io/commit-boost/signer:latest"
# Host to bind the Signer API server to
# OPTIONAL, DEFAULT: 127.0.0.1
host = "127.0.0.1"
# Port to listen for Signer API calls on
# OPTIONAL, DEFAULT: 20000
port = 20000

# For Remote signer:
# [signer.remote]
# URL of the Web3Signer instance
Expand Down
28 changes: 21 additions & 7 deletions crates/cli/src/docker_init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ use cb_common::{
PBS_MODULE_NAME, PROXY_DIR_DEFAULT, PROXY_DIR_ENV, PROXY_DIR_KEYS_DEFAULT,
PROXY_DIR_KEYS_ENV, PROXY_DIR_SECRETS_DEFAULT, PROXY_DIR_SECRETS_ENV, SIGNER_DEFAULT,
SIGNER_DIR_KEYS_DEFAULT, SIGNER_DIR_KEYS_ENV, SIGNER_DIR_SECRETS_DEFAULT,
SIGNER_DIR_SECRETS_ENV, SIGNER_KEYS_ENV, SIGNER_MODULE_NAME, SIGNER_PORT_ENV,
SIGNER_DIR_SECRETS_ENV, SIGNER_ENDPOINT_ENV, SIGNER_KEYS_ENV, SIGNER_MODULE_NAME,
SIGNER_URL_ENV,
},
pbs::{BUILDER_API_PATH, GET_STATUS_PATH},
signer::{ProxyStore, SignerLoader},
signer::{ProxyStore, SignerLoader, DEFAULT_SIGNER_PORT},
types::ModuleId,
utils::random_jwt_secret,
};
Expand Down Expand Up @@ -73,7 +73,7 @@ pub async fn handle_docker_init(config_path: PathBuf, output_dir: PathBuf) -> Re
let mut targets = Vec::new();

// address for signer API communication
let signer_port = 20000;
let signer_port = cb_config.signer.as_ref().map(|s| s.port).unwrap_or(DEFAULT_SIGNER_PORT);
let signer_server =
if let Some(SignerConfig { inner: SignerType::Remote { url }, .. }) = &cb_config.signer {
url.to_string()
Expand Down Expand Up @@ -333,10 +333,17 @@ pub async fn handle_docker_init(config_path: PathBuf, output_dir: PathBuf) -> Re
let mut signer_envs = IndexMap::from([
get_env_val(CONFIG_ENV, CONFIG_DEFAULT),
get_env_same(JWTS_ENV),
get_env_uval(SIGNER_PORT_ENV, signer_port as u64),
]);

let mut ports = vec![];
// Bind the signer API to 0.0.0.0
let container_endpoint =
SocketAddr::from((Ipv4Addr::UNSPECIFIED, signer_config.port));
let (key, val) = get_env_val(SIGNER_ENDPOINT_ENV, &container_endpoint.to_string());
signer_envs.insert(key, val);

let host_endpoint = SocketAddr::from((signer_config.host, signer_config.port));
let mut ports = vec![format!("{}:{}", host_endpoint, signer_config.port)];
warnings.push(format!("cb_signer has an exported port on {}", signer_config.port));

if let Some((key, val)) = chain_spec_env.clone() {
signer_envs.insert(key, val);
Expand Down Expand Up @@ -458,13 +465,20 @@ pub async fn handle_docker_init(config_path: PathBuf, output_dir: PathBuf) -> Re
let mut signer_envs = IndexMap::from([
get_env_val(CONFIG_ENV, CONFIG_DEFAULT),
get_env_same(JWTS_ENV),
get_env_uval(SIGNER_PORT_ENV, signer_port as u64),
get_env_val(DIRK_CERT_ENV, DIRK_CERT_DEFAULT),
get_env_val(DIRK_KEY_ENV, DIRK_KEY_DEFAULT),
get_env_val(DIRK_DIR_SECRETS_ENV, DIRK_DIR_SECRETS_DEFAULT),
]);

let mut ports = vec![];
// Bind the signer API to 0.0.0.0
let container_endpoint =
SocketAddr::from((Ipv4Addr::UNSPECIFIED, signer_config.port));
let (key, val) = get_env_val(SIGNER_ENDPOINT_ENV, &container_endpoint.to_string());
signer_envs.insert(key, val);

let host_endpoint = SocketAddr::from((signer_config.host, signer_config.port));
let mut ports = vec![format!("{}:{}", host_endpoint, signer_config.port)];
warnings.push(format!("cb_signer has an exported port on {}", signer_config.port));

if let Some((key, val)) = chain_spec_env.clone() {
signer_envs.insert(key, val);
Expand Down
2 changes: 1 addition & 1 deletion crates/common/src/config/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub const SIGNER_IMAGE_DEFAULT: &str = "ghcr.io/commit-boost/signer:latest";
pub const SIGNER_MODULE_NAME: &str = "signer";

/// Where the signer module should open the server
pub const SIGNER_PORT_ENV: &str = "CB_SIGNER_PORT";
pub const SIGNER_ENDPOINT_ENV: &str = "CB_SIGNER_ENDPOINT";

/// Comma separated list module_id=jwt_secret
pub const JWTS_ENV: &str = "CB_JWTS";
Expand Down
38 changes: 28 additions & 10 deletions crates/common/src/config/signer.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
use std::{collections::HashMap, path::PathBuf};
use std::{
collections::HashMap,
net::{Ipv4Addr, SocketAddr},
path::PathBuf,
};

use eyre::{bail, OptionExt, Result};
use serde::{Deserialize, Serialize};
use tonic::transport::{Certificate, Identity};
use url::Url;

use super::{
constants::SIGNER_IMAGE_DEFAULT, load_jwt_secrets, utils::load_env_var, CommitBoostConfig,
SIGNER_PORT_ENV,
load_jwt_secrets, load_optional_env_var, utils::load_env_var, CommitBoostConfig,
SIGNER_ENDPOINT_ENV, SIGNER_IMAGE_DEFAULT,
};
use crate::{
config::{DIRK_CA_CERT_ENV, DIRK_CERT_ENV, DIRK_DIR_SECRETS_ENV, DIRK_KEY_ENV},
signer::{ProxyStore, SignerLoader},
signer::{ProxyStore, SignerLoader, DEFAULT_SIGNER_PORT},
types::{Chain, ModuleId},
utils::{default_host, default_u16},
};

#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "snake_case")]
pub struct SignerConfig {
/// Host address to listen for signer API calls on
#[serde(default = "default_host")]
pub host: Ipv4Addr,
/// Port to listen for signer API calls on
#[serde(default = "default_u16::<DEFAULT_SIGNER_PORT>")]
pub port: u16,
/// Docker image of the module
#[serde(default = "default_signer")]
pub docker_image: String,
Expand Down Expand Up @@ -87,7 +98,7 @@ pub struct StartSignerConfig {
pub chain: Chain,
pub loader: Option<SignerLoader>,
pub store: Option<ProxyStore>,
pub server_port: u16,
pub endpoint: SocketAddr,
pub jwts: HashMap<ModuleId, String>,
pub dirk: Option<DirkConfig>,
}
Expand All @@ -97,15 +108,22 @@ impl StartSignerConfig {
let config = CommitBoostConfig::from_env_path()?;

let jwts = load_jwt_secrets()?;
let server_port = load_env_var(SIGNER_PORT_ENV)?.parse()?;

let signer = config.signer.ok_or_eyre("Signer config is missing")?.inner;
let signer_config = config.signer.ok_or_eyre("Signer config is missing")?;

// Load the server endpoint first from the env var if present, otherwise the
// config
let endpoint = if let Some(endpoint) = load_optional_env_var(SIGNER_ENDPOINT_ENV) {
endpoint.parse()?
} else {
SocketAddr::from((signer_config.host, signer_config.port))
};

match signer {
match signer_config.inner {
SignerType::Local { loader, store, .. } => Ok(StartSignerConfig {
chain: config.chain,
loader: Some(loader),
server_port,
endpoint,
jwts,
store,
dirk: None,
Expand Down Expand Up @@ -133,7 +151,7 @@ impl StartSignerConfig {

Ok(StartSignerConfig {
chain: config.chain,
server_port,
endpoint,
jwts,
loader: None,
store,
Expand Down
1 change: 1 addition & 0 deletions crates/common/src/signer/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub const DEFAULT_SIGNER_PORT: u16 = 20000;
2 changes: 2 additions & 0 deletions crates/common/src/signer/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
mod constants;
mod loader;
mod schemes;
mod store;
mod types;

pub use constants::*;
pub use loader::*;
pub use schemes::*;
pub use store::*;
Expand Down
7 changes: 3 additions & 4 deletions crates/signer/src/service.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{collections::HashMap, net::SocketAddr, sync::Arc};
use std::{collections::HashMap, sync::Arc};

use axum::{
extract::{Request, State},
Expand Down Expand Up @@ -67,7 +67,7 @@ impl SigningService {
let loaded_consensus = state.manager.read().await.available_consensus_signers();
let loaded_proxies = state.manager.read().await.available_proxy_signers();

info!(version = COMMIT_BOOST_VERSION, commit_hash = COMMIT_BOOST_COMMIT, modules =? module_ids, port =? config.server_port, loaded_consensus, loaded_proxies, "Starting signing service");
info!(version = COMMIT_BOOST_VERSION, commit_hash = COMMIT_BOOST_COMMIT, modules =? module_ids, endpoint =? config.endpoint, loaded_consensus, loaded_proxies, "Starting signing service");

SigningService::init_metrics(config.chain)?;

Expand All @@ -81,8 +81,7 @@ impl SigningService {
.route_layer(middleware::from_fn(log_request))
.route(STATUS_PATH, get(handle_status));

let address = SocketAddr::from(([0, 0, 0, 0], config.server_port));
let listener = TcpListener::bind(address).await?;
let listener = TcpListener::bind(config.endpoint).await?;

axum::serve(listener, app).await.wrap_err("signer server exited")
}
Expand Down
11 changes: 6 additions & 5 deletions docs/docs/get_started/building.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ url = "https://0xafa4c6985aa049fb79dd37010438cfebeb0f2bd42b115b89dd678dab0670c1d
enabled = true

[signer]
port = 20000

[signer.local.loader]
format = "lighthouse"
keys_path = "/tmp/keys"
Expand Down Expand Up @@ -155,20 +157,19 @@ This will create a binary in `./target/release/commit-boost-signer`. To verify i
The signer needs the following environment variables set:
- `CB_CONFIG` = path of your config file.
- `CB_JWTS` = a dummy key-value pair of [JWT](https://en.wikipedia.org/wiki/JSON_Web_Token) values for various services. Since we don't need them for the sake of just testing the binary, we can use something like `"test_jwts=dummy"`.
- `CB_SIGNER_PORT` = the network port to listen for signer requests on. Default is `20000`.

Set these values, create the `keys` and `secrets` directories listed in the configuration file, and run the binary:

```
mkdir -p /tmp/keys && mkdir -p /tmp/secrets
CB_CONFIG=cb-config.toml CB_JWTS="test_jwts=dummy" CB_SIGNER_PORT=20000 ./target/release/commit-boost-signer
CB_CONFIG=cb-config.toml CB_JWTS="test_jwts=dummy" ./target/release/commit-boost-signer
```

You should see output like this:
```
2025-05-07T21:43:46.385535Z WARN Proxy store not configured. Proxies keys and delegations will not be persisted
2025-05-07T21:43:46.393507Z INFO Starting signing service version="0.7.0" commit_hash="58082edb1213596667afe8c3950cd997ab85f4f3" modules=["test_jwts"] port=20000 loaded_consensus=0 loaded_proxies=0
2025-05-07T21:43:46.393574Z WARN No metrics server configured
2025-06-03T04:57:19.815702Z WARN Proxy store not configured. Proxies keys and delegations will not be persisted
2025-06-03T04:57:19.818193Z INFO Starting signing service version="0.8.0-rc.1" commit_hash="3eed5268f07803c55cca7d7e2e14a7017098f797" modules=["test"] endpoint=127.0.0.1:20000 loaded_consensus=0 loaded_proxies=0
2025-06-03T04:57:19.818229Z WARN No metrics server configured
```

If you do, then the binary works.
33 changes: 33 additions & 0 deletions docs/docs/get_started/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ Commit-Boost supports both local and remote signers. The signer module is respon
To start a local signer module, you need to include its parameters in the config file

```toml
[pbs]
...
with_signer = true

[signer]
port = 20000

[signer.local.loader]
format = "lighthouse"
keys_path = "/path/to/keys"
Expand All @@ -64,7 +71,13 @@ We currently support Lighthouse, Prysm, Teku and Lodestar's keystores so it's ea

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

[signer]
port = 20000

[signer.local.loader]
format = "lighthouse"
keys_path = "keys"
Expand All @@ -87,7 +100,13 @@ We currently support Lighthouse, Prysm, Teku and Lodestar's keystores so it's ea

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

[signer]
port = 20000

[signer.local.loader]
format = "prysm"
keys_path = "wallet/direct/accounts/all-accounts.keystore.json"
Expand All @@ -110,7 +129,13 @@ We currently support Lighthouse, Prysm, Teku and Lodestar's keystores so it's ea

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

[signer]
port = 20000

[signer.local.loader]
format = "teku"
keys_path = "keys"
Expand All @@ -132,7 +157,13 @@ We currently support Lighthouse, Prysm, Teku and Lodestar's keystores so it's ea

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

[signer]
port = 20000

[signer.local.loader]
format = "lodestar"
keys_path = "keys"
Expand Down Expand Up @@ -299,6 +330,8 @@ port = 18550
url = ""

[signer]
port = 20000

[signer.loader]
format = "lighthouse"
keys_path = "/path/to/keys"
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/get_started/running/binary.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ Modules need some environment variables to work correctly.

### PBS Module
- `CB_BUILDER_URLS`: optional, comma-separated list of urls to `events` modules where to post builder events.
- `CB_PBS_ENDPOINT`: optional, override the endpoint where the PBS module will open the port for the beacon node.
- `CB_PBS_ENDPOINT`: optional, override to specify the `IP:port` endpoint where the PBS module will open the port for the beacon node.
- `CB_MUX_PATH_{ID}`: optional, override where to load mux validator keys for mux with `id=\{ID\}`.

### Signer Module
- `CB_SIGNER_PORT`: required, port to open the signer server on.
- `CB_SIGNER_ENDPOINT`: optional, override to specify the `IP:port` endpoint to bind the signer server to.
- For loading keys we currently support:
- `CB_SIGNER_LOADER_FILE`: path to a `.json` with plaintext keys (for testing purposes only).
- `CB_SIGNER_LOADER_FORMAT`, `CB_SIGNER_LOADER_KEYS_DIR` and `CB_SIGNER_LOADER_SECRETS_DIR`: paths to the `keys` and `secrets` directories or files (ERC-2335 style keystores, see [Signer config](../configuration/#signer-module) for more info).
Expand Down
Loading