Skip to content

Commit

Permalink
Merge pull request #108 from chainbound/chore/refactor-config
Browse files Browse the repository at this point in the history
feat: refactor config and add ChainConfig
  • Loading branch information
merklefruit authored Jul 4, 2024
2 parents d074de9 + 35cd0c6 commit 4f87242
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 128 deletions.
2 changes: 1 addition & 1 deletion bolt-sidecar/bin/sidecar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ async fn main() -> eyre::Result<()> {
let mut consensus_state = ConsensusState::new(
&config.beacon_api_url,
&config.validator_indexes,
config.commitment_deadline,
config.chain.commitment_deadline(),
);

// TODO: this can be replaced with ethereum_consensus::clock::from_system_time()
Expand Down
4 changes: 2 additions & 2 deletions bolt-sidecar/src/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
primitives::{
BuilderBid, GetPayloadResponse, PayloadAndBid, PayloadAndBlobs, SignedBuilderBid,
},
Chain, Config,
ChainConfig, Config,
};

/// Basic block template handler that can keep track of
Expand Down Expand Up @@ -73,7 +73,7 @@ pub struct LocalBuilder {
secret_key: SecretKey,
/// Chain configuration
/// (necessary for signing messages with the correct domain)
chain: Chain,
chain: ChainConfig,
/// Async fallback payload builder to generate valid payloads with
/// the engine API's `engine_newPayloadV3` response error.
fallback_builder: FallbackPayloadBuilder,
Expand Down
16 changes: 8 additions & 8 deletions bolt-sidecar/src/builder/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ use ethereum_consensus::ssz::prelude::{HashTreeRoot, MerkleizationError};
use tree_hash::TreeHash;
use tree_hash_derive::TreeHash;

use crate::Chain;
use crate::ChainConfig;

/// Sign a SSZ object a BLS secret key, using the Application Builder domain
/// for signing arbitrary builder-api messages in the out-of-protocol specifications.
///
/// Fun Note: we use a `blst` secret key to sign a message, and produce an `alloy` signature,
/// which is then converted to an `ethereum-consensus` signature.
pub fn sign_builder_message<T: HashTreeRoot>(
chain: &Chain,
chain: &ChainConfig,
sk: &SecretKey,
msg: &T,
) -> Result<Signature, MerkleizationError> {
Expand All @@ -33,7 +33,7 @@ pub fn sign_builder_message<T: HashTreeRoot>(
/// Verify a SSZ object signed with a BLS public key, using the Application Builder domain
/// for signing arbitrary builder-api messages in the out-of-protocol specifications.
pub fn verify_signed_builder_message<T: HashTreeRoot>(
chain: &Chain,
chain: &ChainConfig,
pubkey: &PublicKey,
msg: &T,
signature: &BlsSignature,
Expand Down Expand Up @@ -115,29 +115,29 @@ pub fn compute_builder_domain(

#[cfg(test)]
mod tests {
use crate::{builder::signature::compute_builder_domain, config::Chain};
use crate::{builder::signature::compute_builder_domain, ChainConfig};

#[test]
fn test_compute_builder_domain() {
let mainnet = Chain::Mainnet;
let mainnet = ChainConfig::mainnet();
assert_eq!(
compute_builder_domain(mainnet.fork_version(), None),
mainnet.builder_domain()
);

let holesky = Chain::Holesky;
let holesky = ChainConfig::holesky();
assert_eq!(
compute_builder_domain(holesky.fork_version(), None),
holesky.builder_domain()
);

let kurtosis = Chain::Kurtosis;
let kurtosis = ChainConfig::kurtosis(0, 0);
assert_eq!(
compute_builder_domain(kurtosis.fork_version(), None),
kurtosis.builder_domain()
);

let helder = Chain::Helder;
let helder = ChainConfig::helder();
assert_eq!(
compute_builder_domain(helder.fork_version(), None),
helder.builder_domain()
Expand Down
152 changes: 152 additions & 0 deletions bolt-sidecar/src/config/chain.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
use std::time::Duration;

use alloy_primitives::b256;
use clap::{Args, ValueEnum};

/// Default commitment deadline duration.
///
/// The sidecar will stop accepting new commitments for the next block
/// after this deadline has passed. This is to ensure that builders and
/// relays have enough time to build valid payloads.
pub const DEFAULT_COMMITMENT_DEADLINE_IN_MILLIS: u64 = 8_000;

/// Default slot time duration in seconds.
pub const DEFAULT_SLOT_TIME_IN_SECONDS: u64 = 12;

/// Builder domain for signing messages on Ethereum Mainnet.
const BUILDER_DOMAIN_MAINNET: [u8; 32] =
b256!("00000001f5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a9").0;

/// Builder domain for signing messages on Holesky.
const BUILDER_DOMAIN_HOLESKY: [u8; 32] =
b256!("000000015b83a23759c560b2d0c64576e1dcfc34ea94c4988f3e0d9f77f05387").0;

/// Builder domain for signing messages on stock Kurtosis devnets.
const BUILDER_DOMAIN_KURTOSIS: [u8; 32] =
b256!("000000010b41be4cdb34d183dddca5398337626dcdcfaf1720c1202d3b95f84e").0;

/// Builder domain for signing messages on Helder.
const BUILDER_DOMAIN_HELDER: [u8; 32] =
b256!("0000000194c41af484fff7964969e0bdd922f82dff0f4be87a60d0664cc9d1ff").0;

/// Configuration for the chain the sidecar is running on.
/// This allows to customize the slot time for custom Kurtosis devnets.
#[derive(Debug, Clone, Args)]
pub struct ChainConfig {
/// Chain on which the sidecar is running
#[clap(short = 'C', long, default_value = "mainnet")]
chain: Chain,
/// The deadline in the slot at which the sidecar will stop accepting
/// new commitments for the next block (parsed as milliseconds).
#[clap(short = 'd', long, default_value_t = DEFAULT_COMMITMENT_DEADLINE_IN_MILLIS)]
commitment_deadline: u64,
/// The slot time duration in seconds. If provided,
/// it overrides the default for the selected [Chain].
#[clap(short = 's', long, default_value_t = DEFAULT_SLOT_TIME_IN_SECONDS)]
slot_time_in_seconds: u64,
}

impl Default for ChainConfig {
fn default() -> Self {
Self {
chain: Chain::Mainnet,
commitment_deadline: DEFAULT_COMMITMENT_DEADLINE_IN_MILLIS,
slot_time_in_seconds: DEFAULT_SLOT_TIME_IN_SECONDS,
}
}
}

/// Supported chains for the sidecar
#[derive(Debug, Clone, ValueEnum)]
#[clap(rename_all = "kebab_case")]
#[allow(missing_docs)]
pub enum Chain {
Mainnet,
Holesky,
Helder,
Kurtosis,
}

impl ChainConfig {
/// Get the chain ID for the given chain.
pub fn chain_id(&self) -> u64 {
match self.chain {
Chain::Mainnet => 1,
Chain::Holesky => 17000,
Chain::Helder => 7014190335,
Chain::Kurtosis => 3151908,
}
}

/// Get the chain name for the given chain.
pub fn name(&self) -> &'static str {
match self.chain {
Chain::Mainnet => "mainnet",
Chain::Holesky => "holesky",
Chain::Helder => "helder",
Chain::Kurtosis => "kurtosis",
}
}

/// Get the slot time for the given chain in seconds.
pub fn slot_time(&self) -> u64 {
self.slot_time_in_seconds
}

/// Get the domain for signing messages on the given chain.
pub fn builder_domain(&self) -> [u8; 32] {
match self.chain {
Chain::Mainnet => BUILDER_DOMAIN_MAINNET,
Chain::Holesky => BUILDER_DOMAIN_HOLESKY,
Chain::Helder => BUILDER_DOMAIN_HELDER,
Chain::Kurtosis => BUILDER_DOMAIN_KURTOSIS,
}
}

/// Get the fork version for the given chain.
pub fn fork_version(&self) -> [u8; 4] {
match self.chain {
Chain::Mainnet => [0u8; 4],
Chain::Holesky => [1, 1, 112, 0],
Chain::Helder => [16, 0, 0, 0],
Chain::Kurtosis => [16, 0, 0, 56],
}
}

/// Get the commitment deadline duration for the given chain.
pub fn commitment_deadline(&self) -> Duration {
Duration::from_millis(self.commitment_deadline)
}
}

#[cfg(test)]
impl ChainConfig {
pub fn mainnet() -> Self {
Self {
chain: Chain::Mainnet,
..Default::default()
}
}

pub fn holesky() -> Self {
Self {
chain: Chain::Holesky,
..Default::default()
}
}

pub fn helder() -> Self {
Self {
chain: Chain::Helder,
..Default::default()
}
}

pub fn kurtosis(slot_time_in_seconds: u64, commitment_deadline: u64) -> Self {
Self {
chain: Chain::Kurtosis,
slot_time_in_seconds,
commitment_deadline,
}
}
}
Loading

0 comments on commit 4f87242

Please sign in to comment.