Skip to content

Commit

Permalink
Merge pull request #299 from chainbound/lore/feat/keystore-secrets
Browse files Browse the repository at this point in the history
feat(sidecar): keystore secrets path in config
  • Loading branch information
thedevbirb authored Oct 18, 2024
2 parents 50806b7 + a1d6e8b commit 45e078a
Show file tree
Hide file tree
Showing 28 changed files with 482 additions and 206 deletions.
17 changes: 11 additions & 6 deletions bolt-sidecar/.env.example
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@

# node + PBS URLs
# Ethereum node connections
BOLT_SIDECAR_EXECUTION_API_URL=http://localhost:4485
BOLT_SIDECAR_BEACON_API_URL=http://localhost:4400
BOLT_SIDECAR_ENGINE_API_URL=http://localhost:4451
BOLT_SIDECAR_ENGINE_JWT_HEX=

# Constraint URL: should point to the constraint API sidecar.
# Usually this corresponds to `mev-boost` or `bolt-boost`
BOLT_SIDECAR_CONSTRAINTS_URL=http://localhost:19550

# Commit-boost specific options (optional)
BOLT_SIDECAR_CB_SIGNER_URL=http://localhost:19551
BOLT_SIDECAR_CB_JWT_HEX=

# server ports
BOLT_SIDECAR_PORT=8000
Expand All @@ -15,14 +21,13 @@ BOLT_SIDECAR_MAX_COMMITMENTS=128
BOLT_SIDECAR_MAX_COMMITTED_GAS=10000000

# chain configs
BOLT_SIDECAR_CHAIN=helder
BOLT_SIDECAR_CHAIN=holesky
BOLT_SIDECAR_COMMITMENT_DEADLINE=8000
BOLT_SIDECAR_SLOT_TIME=12

# sidecar security configs
BOLT_SIDECAR_VALIDATOR_INDEXES=
BOLT_SIDECAR_JWT_HEX=
BOLT_SIDECAR_CB_JWT_HEX=
BOLT_SIDECAR_FEE_RECIPIENT=
BOLT_SIDECAR_BUILDER_PRIVATE_KEY=
BOLT_SIDECAR_PRIVATE_KEY=
BOLT_SIDECAR_CONSTRAINT_PRIVATE_KEY=
BOLT_SIDECAR_COMMITMENT_PRIVATE_KEY=
3 changes: 2 additions & 1 deletion bolt-sidecar/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
target/
.env
.env.dev
.env.*
!.env.example
19 changes: 9 additions & 10 deletions bolt-sidecar/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions bolt-sidecar/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ default-run = "bolt-sidecar"

[dependencies]
# core
clap = { version = "4.5.4", features = ["derive", "env"] }
clap = { version = "4.5.20", features = ["derive", "env"] }
tokio = { version = "1", features = ["full"] }
axum = { version = "0.7", features = ["macros"] }
tower-http = { version = "0.5.2", features = ["timeout"] }
Expand Down Expand Up @@ -79,7 +79,6 @@ cb-common = { git = "https://github.com/Commit-Boost/commit-boost-client", rev =

[dev-dependencies]
alloy-node-bindings = "0.2.0"
tempfile = "3.13.0"


[[bin]]
Expand Down
20 changes: 17 additions & 3 deletions bolt-sidecar/Config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,29 @@ metrics_port = 3300
execution_api_url = "http://localhost:8545"
beacon_api_url = "http://localhost:5052"
engine_api_url = "http://localhost:8551"
engine_jwt_hex = "0x573300d0cd9a8e253429998a3ceecf358aa4868d96772d1344a80144d3b7b593"

# constraints options
constraints_url = "http://localhost:3030"
constraints_api_url = "http://localhost:3030"
constraints_proxy_port = 18551

validator_indexes = "0..64"
fee_recipient = "0x0155ef0C0fE550C297c1216585e0DE1478EA30e4"

builder_private_key = "0x359c156600e1f5715a58c9e09f17c8d04e7ee3a9f88b39f6e489ffca0148fabe"
commitment_private_key = "0x359c156600e1f5715a58c9e09f17c8d04e7ee3a9f88b39f6e489ffca0148fabe"

# chain options
chain = "kurtosis"
[chain]
chain = "Kurtosis"
slot_time = 2
commitment_deadline = 8000

[telemetry]
metrics_port = 3300
disable_metrics = false

# signing options
private_key = "0x359c156600e1f5715a58c9e09f17c8d04e7ee3a9f88b39f6e489ffca0148fabe"
[constraint_signing]
constraint_private_key = "0x359c156600e1f5715a58c9e09f17c8d04e7ee3a9f88b39f6e489ffca0148fabe"
delegations_path = "./delegations.json"
12 changes: 6 additions & 6 deletions bolt-sidecar/bin/sidecar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,25 @@ async fn main() -> Result<()> {

info!(chain = opts.chain.name(), "Starting Bolt sidecar");

if opts.signing.private_key.is_some() {
if opts.constraint_signing.constraint_private_key.is_some() {
match SidecarDriver::with_local_signer(&opts).await {
Ok(driver) => driver.run_forever().await,
Err(err) => {
bail!("Failed to initialize the sidecar driver with local signer: {:?}", err)
}
}
} else if opts.signing.keystore_password.is_some() {
match SidecarDriver::with_keystore_signer(&opts).await {
} else if opts.constraint_signing.commit_boost_signer_url.is_some() {
match SidecarDriver::with_commit_boost_signer(&opts).await {
Ok(driver) => driver.run_forever().await,
Err(err) => {
bail!("Failed to initialize the sidecar driver with keystore signer: {:?}", err)
bail!("Failed to initialize the sidecar driver with commit boost: {:?}", err)
}
}
} else {
match SidecarDriver::with_commit_boost_signer(&opts).await {
match SidecarDriver::with_keystore_signer(&opts).await {
Ok(driver) => driver.run_forever().await,
Err(err) => {
bail!("Failed to initialize the sidecar driver with commit boost: {:?}", err)
bail!("Failed to initialize the sidecar driver with keystore signer: {:?}", err)
}
}
}
Expand Down
3 changes: 0 additions & 3 deletions bolt-sidecar/keys/.gitignore

This file was deleted.

2 changes: 1 addition & 1 deletion bolt-sidecar/src/builder/payload_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl FallbackPayloadBuilder {
pub fn new(config: &Opts, beacon_api_client: BeaconClient, genesis_time: u64) -> Self {
let engine_hinter = EngineHinter {
client: reqwest::Client::new(),
jwt_hex: config.jwt_hex.to_string(),
jwt_hex: config.engine_jwt_hex.to_string(),
engine_rpc_url: config.engine_api_url.clone(),
};

Expand Down
46 changes: 45 additions & 1 deletion bolt-sidecar/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{
path::Path,
};

use alloy::primitives::U256;
use alloy::{primitives::U256, signers::k256::ecdsa::SigningKey};
use blst::min_pk::SecretKey;
use rand::{Rng, RngCore};
use reth_primitives::PooledTransactionsElement;
Expand Down Expand Up @@ -139,6 +139,50 @@ impl fmt::Display for BlsSecretKeyWrapper {
}
}

#[derive(Clone, Debug)]
pub struct EcdsaSecretKeyWrapper(pub SigningKey);

impl EcdsaSecretKeyWrapper {
/// Generate a new random ECDSA secret key.
#[allow(dead_code)]
pub fn random() -> Self {
Self(SigningKey::random(&mut rand::thread_rng()))
}
}

impl<'de> Deserialize<'de> for EcdsaSecretKeyWrapper {
fn deserialize<D>(deserializer: D) -> Result<EcdsaSecretKeyWrapper, D::Error>
where
D: Deserializer<'de>,
{
let sk = String::deserialize(deserializer)?;
Ok(EcdsaSecretKeyWrapper::from(sk.as_str()))
}
}

impl From<&str> for EcdsaSecretKeyWrapper {
fn from(sk: &str) -> Self {
let hex_sk = sk.strip_prefix("0x").unwrap_or(sk);
let bytes = hex::decode(hex_sk).expect("valid hex");
let sk = SigningKey::from_slice(&bytes).expect("valid sk");
EcdsaSecretKeyWrapper(sk)
}
}

impl Display for EcdsaSecretKeyWrapper {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "0x{}", hex::encode(self.0.to_bytes()))
}
}

impl Deref for EcdsaSecretKeyWrapper {
type Target = SigningKey;

fn deref(&self) -> &Self::Target {
&self.0
}
}

#[derive(Debug, Clone)]
pub struct JwtSecretConfig(pub String);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,49 +1,54 @@
use std::{fmt, net::SocketAddr};
use std::{fmt, path::PathBuf};

use clap::{ArgGroup, Args};
use lighthouse_account_utils::ZeroizeString;
use reqwest::Url;
use serde::Deserialize;

use crate::common::{BlsSecretKeyWrapper, JwtSecretConfig};

/// Command-line options for signing
/// Command-line options for signing constraint messages
#[derive(Args, Deserialize)]
#[clap(
group = ArgGroup::new("signing-opts").required(true)
.args(&["private_key", "commit_boost_address", "keystore_password"])
.args(&["constraint_private_key", "commit_boost_signer_url", "keystore_password", "keystore_secrets_path"])
)]
pub struct SigningOpts {
/// Private key to use for signing preconfirmation requests
#[clap(long, env = "BOLT_SIDECAR_PRIVATE_KEY")]
pub private_key: Option<BlsSecretKeyWrapper>,
/// Socket address for the commit-boost sidecar
pub struct ConstraintSigningOpts {
/// Private key to use for signing constraint messages
#[clap(long, env = "BOLT_SIDECAR_CONSTRAINT_PRIVATE_KEY")]
pub constraint_private_key: Option<BlsSecretKeyWrapper>,
/// URL for the commit-boost sidecar
#[clap(long, env = "BOLT_SIDECAR_CB_SIGNER_URL", requires("commit_boost_jwt_hex"))]
pub commit_boost_address: Option<SocketAddr>,
pub commit_boost_signer_url: Option<Url>,
/// JWT in hexadecimal format for authenticating with the commit-boost service
#[clap(long, env = "BOLT_SIDECAR_CB_JWT_HEX", requires("commit_boost_address"))]
#[clap(long, env = "BOLT_SIDECAR_CB_JWT_HEX", requires("commit_boost_signer_url"))]
pub commit_boost_jwt_hex: Option<JwtSecretConfig>,
/// The password for the ERC-2335 keystore.
/// Reference: https://eips.ethereum.org/EIPS/eip-2335
#[clap(long, env = "BOLT_SIDECAR_KEYSTORE_PASSWORD")]
pub keystore_password: Option<ZeroizeString>,
/// The path to the ERC-2335 keystore secret passwords
/// Reference: https://eips.ethereum.org/EIPS/eip-2335
#[clap(long, env = "BOLT_SIDECAR_KEYSTORE_SECRETS_PATH", conflicts_with("keystore_password"))]
pub keystore_secrets_path: Option<PathBuf>,
/// Path to the keystores folder. If not provided, the default path is used.
#[clap(long, env = "BOLT_SIDECAR_KEYSTORE_PATH", requires("keystore_password"))]
pub keystore_path: Option<String>,
#[clap(long, env = "BOLT_SIDECAR_KEYSTORE_PATH")]
pub keystore_path: Option<PathBuf>,
/// Path to the delegations file. If not provided, the default path is used.
#[clap(long, env = "BOLT_SIDECAR_DELEGATIONS_PATH")]
pub delegations_path: Option<String>,
pub delegations_path: Option<PathBuf>,
}

// Implement Debug manually to hide the keystore_password field
impl fmt::Debug for SigningOpts {
impl fmt::Debug for ConstraintSigningOpts {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SigningOpts")
.field("private_key", &self.private_key)
.field("commit_boost_url", &self.commit_boost_address)
.field("constraint_private_key", &"********") // Hides the actual private key
.field("commit_boost_signer_url", &self.commit_boost_signer_url)
.field("commit_boost_jwt_hex", &self.commit_boost_jwt_hex)
.field("keystore_password", &"********") // Hides the actual password
.field("keystore_path", &self.keystore_path)
.field("delegations_path", &self.delegations_path)
.field("keystore_secrets_path", &self.keystore_secrets_path)
.finish()
}
}
Loading

0 comments on commit 45e078a

Please sign in to comment.