diff --git a/benches/pbs/src/main.rs b/benches/pbs/src/main.rs index abb6ee3d..aedde1e3 100644 --- a/benches/pbs/src/main.rs +++ b/benches/pbs/src/main.rs @@ -4,8 +4,9 @@ use alloy::{primitives::B256, rpc::types::beacon::BlsPublicKey}; use cb_common::{ config::RelayConfig, pbs::{GetHeaderResponse, RelayClient, RelayEntry}, - signer::{BlsSecretKey, BlsSigner}, + signer::BlsSecretKey, types::Chain, + utils::blst_pubkey_to_alloy, }; use cb_tests::mock_relay::{start_mock_relay_service, MockRelayState}; use comfy_table::Table; @@ -137,9 +138,10 @@ const MOCK_RELAY_SECRET: [u8; 32] = [ 152, 98, 59, 240, 181, 131, 47, 1, 180, 255, 245, ]; async fn start_mock_relay(chain: Chain, relay_config: RelayConfig) { - let signer = BlsSigner::Local(BlsSecretKey::key_gen(&MOCK_RELAY_SECRET, &[]).unwrap()); + let signer = BlsSecretKey::key_gen(&MOCK_RELAY_SECRET, &[]).unwrap(); + let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()); - assert_eq!(relay_config.entry.pubkey, *signer.pubkey(), "Expected relay pubkey to be 0xb060572f535ba5615b874ebfef757fbe6825352ad257e31d724e57fe25a067a13cfddd0f00cb17bf3a3d2e901a380c17"); + assert_eq!(relay_config.entry.pubkey, pubkey, "Expected relay pubkey to be 0xb060572f535ba5615b874ebfef757fbe6825352ad257e31d724e57fe25a067a13cfddd0f00cb17bf3a3d2e901a380c17"); let relay_port = relay_config.entry.url.port().expect("missing port"); diff --git a/crates/common/src/commit/request.rs b/crates/common/src/commit/request.rs index df6ba8e7..85c3872d 100644 --- a/crates/common/src/commit/request.rs +++ b/crates/common/src/commit/request.rs @@ -9,8 +9,9 @@ use tree_hash::TreeHash; use tree_hash_derive::TreeHash; use crate::{ + constants::COMMIT_BOOST_DOMAIN, error::BlstErrorWrapper, - signature::verify_signed_builder_message, + signature::verify_signed_message, signer::schemes::{bls::BlsPublicKey, ecdsa::EcdsaPublicKey}, types::Chain, }; @@ -54,11 +55,12 @@ pub type SignedProxyDelegationEcdsa = SignedProxyDelegation; impl SignedProxyDelegation { pub fn validate(&self, chain: Chain) -> Result<(), BlstErrorWrapper> { - verify_signed_builder_message( + verify_signed_message( chain, &self.message.delegator, &self.message, &self.signature, + COMMIT_BOOST_DOMAIN, ) } } diff --git a/crates/common/src/constants.rs b/crates/common/src/constants.rs index 036cd719..ee75909f 100644 --- a/crates/common/src/constants.rs +++ b/crates/common/src/constants.rs @@ -2,6 +2,7 @@ pub const APPLICATION_BUILDER_DOMAIN: [u8; 4] = [0, 0, 0, 1]; pub const GENESIS_VALIDATORS_ROOT: [u8; 32] = [0; 32]; +pub const COMMIT_BOOST_DOMAIN: [u8; 4] = [109, 109, 111, 67]; // MAINNET pub const MAINNET_FORK_VERSION: [u8; 4] = [0u8; 4]; @@ -19,14 +20,6 @@ pub const HOLESKY_BUILDER_DOMAIN: [u8; 32] = [ ]; pub const HOLESKY_GENESIS_TIME_SECONDS: u64 = 1695902400; -// RHEA DEVNET -pub const RHEA_FORK_VERSION: [u8; 4] = [16, 0, 0, 56]; -pub const RHEA_BUILDER_DOMAIN: [u8; 32] = [ - 0, 0, 0, 1, 11, 65, 190, 76, 219, 52, 209, 131, 221, 220, 165, 57, 131, 55, 98, 109, 205, 207, - 175, 23, 32, 193, 32, 45, 59, 149, 248, 78, -]; -pub const RHEA_GENESIS_TIME_SECONDS: u64 = 1718117531; - // HELDER pub const HELDER_FORK_VERSION: [u8; 4] = [16, 0, 0, 0]; pub const HELDER_BUILDER_DOMAIN: [u8; 32] = [ diff --git a/crates/common/src/pbs/types/get_header.rs b/crates/common/src/pbs/types/get_header.rs index c5b6a28a..c040f9ea 100644 --- a/crates/common/src/pbs/types/get_header.rs +++ b/crates/common/src/pbs/types/get_header.rs @@ -69,7 +69,9 @@ mod tests { use alloy::primitives::U256; use super::GetHeaderResponse; - use crate::{signature::verify_signed_builder_message, types::Chain}; + use crate::{ + constants::APPLICATION_BUILDER_DOMAIN, signature::verify_signed_message, types::Chain, + }; #[test] fn test_get_header() { @@ -115,11 +117,12 @@ mod tests { assert_eq!(parsed.message.value(), U256::from(4293912964927787u64)); - assert!(verify_signed_builder_message( + assert!(verify_signed_message( Chain::Holesky, &parsed.message.pubkey.into(), &parsed.message, &parsed.signature, + APPLICATION_BUILDER_DOMAIN ) .is_ok()) } diff --git a/crates/common/src/signature.rs b/crates/common/src/signature.rs index 2e6a40dd..c939cd41 100644 --- a/crates/common/src/signature.rs +++ b/crates/common/src/signature.rs @@ -4,7 +4,7 @@ use tree_hash::TreeHash; use tree_hash_derive::TreeHash; use crate::{ - constants::{APPLICATION_BUILDER_DOMAIN, GENESIS_VALIDATORS_ROOT}, + constants::{COMMIT_BOOST_DOMAIN, GENESIS_VALIDATORS_ROOT}, error::BlstErrorWrapper, signer::{schemes::bls::verify_bls_signature, BlsSecretKey}, types::Chain, @@ -26,8 +26,7 @@ pub fn compute_signing_root(object_root: [u8; 32], signing_domain: [u8; 32]) -> signing_data.tree_hash_root().0 } -#[allow(dead_code)] -fn compute_builder_domain(chain: Chain) -> [u8; 32] { +pub fn compute_domain(chain: Chain, domain_mask: [u8; 4]) -> [u8; 32] { #[derive(Debug, Encode, Decode, TreeHash)] struct ForkData { fork_version: [u8; 4], @@ -35,7 +34,7 @@ fn compute_builder_domain(chain: Chain) -> [u8; 32] { } let mut domain = [0u8; 32]; - domain[..4].copy_from_slice(&APPLICATION_BUILDER_DOMAIN); + domain[..4].copy_from_slice(&domain_mask); let fork_version = chain.fork_version(); let fd = ForkData { fork_version, genesis_validators_root: GENESIS_VALIDATORS_ROOT }; @@ -46,13 +45,14 @@ fn compute_builder_domain(chain: Chain) -> [u8; 32] { domain } -pub fn verify_signed_builder_message( +pub fn verify_signed_message( chain: Chain, pubkey: &BlsPublicKey, msg: &T, signature: &BlsSignature, + domain_mask: [u8; 4], ) -> Result<(), BlstErrorWrapper> { - let domain = chain.builder_domain(); + let domain = compute_domain(chain, domain_mask); let signing_root = compute_signing_root(msg.tree_hash_root().0, domain); verify_bls_signature(pubkey, &signing_root, signature) @@ -76,17 +76,35 @@ pub fn sign_builder_root( sign_message(secret_key, &signing_root) } +pub fn sign_commit_boost_root( + chain: Chain, + secret_key: &BlsSecretKey, + object_root: [u8; 32], +) -> BlsSignature { + let domain = compute_domain(chain, COMMIT_BOOST_DOMAIN); + let signing_root = compute_signing_root(object_root, domain); + sign_message(secret_key, &signing_root) +} + #[cfg(test)] mod tests { - use super::compute_builder_domain; - use crate::types::Chain; + use super::compute_domain; + use crate::{constants::APPLICATION_BUILDER_DOMAIN, types::Chain}; #[test] fn test_builder_domains() { - assert_eq!(compute_builder_domain(Chain::Mainnet), Chain::Mainnet.builder_domain()); - assert_eq!(compute_builder_domain(Chain::Holesky), Chain::Holesky.builder_domain()); - assert_eq!(compute_builder_domain(Chain::Rhea), Chain::Rhea.builder_domain()); - assert_eq!(compute_builder_domain(Chain::Helder), Chain::Helder.builder_domain()); + assert_eq!( + compute_domain(Chain::Mainnet, APPLICATION_BUILDER_DOMAIN), + Chain::Mainnet.builder_domain() + ); + assert_eq!( + compute_domain(Chain::Holesky, APPLICATION_BUILDER_DOMAIN), + Chain::Holesky.builder_domain() + ); + assert_eq!( + compute_domain(Chain::Helder, APPLICATION_BUILDER_DOMAIN), + Chain::Helder.builder_domain() + ); } } diff --git a/crates/common/src/signer/schemes/bls.rs b/crates/common/src/signer/schemes/bls.rs index 00911766..39942ca7 100644 --- a/crates/common/src/signer/schemes/bls.rs +++ b/crates/common/src/signer/schemes/bls.rs @@ -8,7 +8,7 @@ use tree_hash::TreeHash; use tree_hash_derive::TreeHash; use crate::{ - error::BlstErrorWrapper, signature::sign_builder_root, types::Chain, + error::BlstErrorWrapper, signature::sign_commit_boost_root, types::Chain, utils::blst_pubkey_to_alloy, }; @@ -61,7 +61,7 @@ impl BlsSigner { pub async fn sign(&self, chain: Chain, object_root: [u8; 32]) -> BlsSignature { match self { - BlsSigner::Local(sk) => sign_builder_root(chain, sk, object_root), + BlsSigner::Local(sk) => sign_commit_boost_root(chain, sk, object_root), } } @@ -70,7 +70,7 @@ impl BlsSigner { } } -fn random_secret() -> BlsSecretKey { +pub fn random_secret() -> BlsSecretKey { use rand::RngCore; let mut rng = rand::thread_rng(); diff --git a/crates/common/src/signer/schemes/ecdsa.rs b/crates/common/src/signer/schemes/ecdsa.rs index 359a3054..df4f4840 100644 --- a/crates/common/src/signer/schemes/ecdsa.rs +++ b/crates/common/src/signer/schemes/ecdsa.rs @@ -14,7 +14,11 @@ use ssz_types::{ }; use tree_hash::TreeHash; -use crate::{signature::compute_signing_root, types::Chain}; +use crate::{ + constants::COMMIT_BOOST_DOMAIN, + signature::{compute_domain, compute_signing_root}, + types::Chain, +}; pub type EcdsaSecretKey = k256::ecdsa::SigningKey; @@ -205,7 +209,7 @@ impl EcdsaSigner { pub async fn sign(&self, chain: Chain, object_root: [u8; 32]) -> EcdsaSignature { match self { EcdsaSigner::Local(sk) => { - let domain = chain.builder_domain(); + let domain = compute_domain(chain, COMMIT_BOOST_DOMAIN); let signing_root = compute_signing_root(object_root, domain); k256::ecdsa::signature::Signer::::sign(sk, &signing_root) .into() diff --git a/crates/common/src/types.rs b/crates/common/src/types.rs index 3e9b9e35..f570da66 100644 --- a/crates/common/src/types.rs +++ b/crates/common/src/types.rs @@ -5,14 +5,13 @@ use crate::constants::{ HELDER_BUILDER_DOMAIN, HELDER_FORK_VERSION, HELDER_GENESIS_TIME_SECONDS, HOLESKY_BUILDER_DOMAIN, HOLESKY_FORK_VERSION, HOLESKY_GENESIS_TIME_SECONDS, MAINNET_BUILDER_DOMAIN, MAINNET_FORK_VERSION, MAINNET_GENESIS_TIME_SECONDS, - RHEA_BUILDER_DOMAIN, RHEA_FORK_VERSION, RHEA_GENESIS_TIME_SECONDS, }; #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)] pub enum Chain { Mainnet, Holesky, - Rhea, + Helder, } @@ -21,7 +20,6 @@ impl Chain { match self { Chain::Mainnet => MAINNET_BUILDER_DOMAIN, Chain::Holesky => HOLESKY_BUILDER_DOMAIN, - Chain::Rhea => RHEA_BUILDER_DOMAIN, Chain::Helder => HELDER_BUILDER_DOMAIN, } } @@ -30,7 +28,6 @@ impl Chain { match self { Chain::Mainnet => MAINNET_FORK_VERSION, Chain::Holesky => HOLESKY_FORK_VERSION, - Chain::Rhea => RHEA_FORK_VERSION, Chain::Helder => HELDER_FORK_VERSION, } } @@ -39,7 +36,6 @@ impl Chain { match self { Chain::Mainnet => MAINNET_GENESIS_TIME_SECONDS, Chain::Holesky => HOLESKY_GENESIS_TIME_SECONDS, - Chain::Rhea => RHEA_GENESIS_TIME_SECONDS, Chain::Helder => HELDER_GENESIS_TIME_SECONDS, } } diff --git a/crates/pbs/src/mev_boost/get_header.rs b/crates/pbs/src/mev_boost/get_header.rs index 7be054f7..97c5f798 100644 --- a/crates/pbs/src/mev_boost/get_header.rs +++ b/crates/pbs/src/mev_boost/get_header.rs @@ -7,12 +7,13 @@ use alloy::{ use axum::http::{HeaderMap, HeaderValue}; use cb_common::{ config::PbsConfig, + constants::APPLICATION_BUILDER_DOMAIN, pbs::{ error::{PbsError, ValidationError}, GetHeaderParams, GetHeaderResponse, RelayClient, SignedExecutionPayloadHeader, EMPTY_TX_ROOT_HASH, HEADER_SLOT_UUID_KEY, HEADER_START_TIME_UNIX_MS, }, - signature::verify_signed_builder_message, + signature::verify_signed_message, types::Chain, utils::{get_user_agent_with_version, ms_into_slot, utcnow_ms}, }; @@ -318,11 +319,12 @@ fn validate_header( } if !skip_sig_verify { - verify_signed_builder_message( + verify_signed_message( chain, &received_relay_pubkey, &signed_header.message, &signed_header.signature, + APPLICATION_BUILDER_DOMAIN, ) .map_err(ValidationError::Sigverify)?; } diff --git a/crates/signer/src/manager.rs b/crates/signer/src/manager.rs index 5353edfc..59c7dc3d 100644 --- a/crates/signer/src/manager.rs +++ b/crates/signer/src/manager.rs @@ -219,13 +219,14 @@ mod tests { use super::*; + const CHAIN: Chain = Chain::Holesky; + lazy_static! { - static ref CHAIN: Chain = Chain::Holesky; static ref MODULE_ID: ModuleId = ModuleId("SAMPLE_MODULE".to_string()); } fn init_signing_manager() -> (SigningManager, BlsPublicKey) { - let mut signing_manager = SigningManager::new(*CHAIN); + let mut signing_manager = SigningManager::new(CHAIN); let consensus_signer = ConsensusSigner::new_random(); let consensus_pk = consensus_signer.pubkey(); @@ -236,7 +237,10 @@ mod tests { } mod test_proxy_bls { - use cb_common::signer::schemes::bls::verify_bls_signature; + use cb_common::{ + constants::COMMIT_BOOST_DOMAIN, signature::compute_domain, + signer::schemes::bls::verify_bls_signature, + }; use super::*; @@ -249,7 +253,7 @@ mod tests { .await .unwrap(); - let validation_result = signed_delegation.validate(*CHAIN); + let validation_result = signed_delegation.validate(CHAIN); assert!( validation_result.is_ok(), @@ -274,7 +278,7 @@ mod tests { let m = &mut signed_delegation.signature.0[0]; (*m, _) = m.overflowing_add(1); - let validation_result = signed_delegation.validate(*CHAIN); + let validation_result = signed_delegation.validate(CHAIN); assert!(validation_result.is_err(), "Tampered proxy key must be invalid."); } @@ -298,7 +302,7 @@ mod tests { .unwrap(); // Verify signature - let domain = CHAIN.builder_domain(); + let domain = compute_domain(CHAIN, COMMIT_BOOST_DOMAIN); let signing_root = compute_signing_root(data_root_bytes.tree_hash_root().0, domain); let validation_result = verify_bls_signature(&proxy_pk, &signing_root, &sig); @@ -311,7 +315,10 @@ mod tests { } mod test_proxy_ecdsa { - use cb_common::signer::schemes::ecdsa::verify_ecdsa_signature; + use cb_common::{ + constants::COMMIT_BOOST_DOMAIN, signature::compute_domain, + signer::schemes::ecdsa::verify_ecdsa_signature, + }; use super::*; @@ -324,7 +331,7 @@ mod tests { .await .unwrap(); - let validation_result = signed_delegation.validate(*CHAIN); + let validation_result = signed_delegation.validate(CHAIN); assert!( validation_result.is_ok(), @@ -349,7 +356,7 @@ mod tests { let m = &mut signed_delegation.signature.0[0]; (*m, _) = m.overflowing_add(1); - let validation_result = signed_delegation.validate(*CHAIN); + let validation_result = signed_delegation.validate(CHAIN); assert!(validation_result.is_err(), "Tampered proxy key must be invalid."); } @@ -373,7 +380,7 @@ mod tests { .unwrap(); // Verify signature - let domain = CHAIN.builder_domain(); + let domain = compute_domain(CHAIN, COMMIT_BOOST_DOMAIN); let signing_root = compute_signing_root(data_root_bytes.tree_hash_root().0, domain); let validation_result = verify_ecdsa_signature(&proxy_pk, &signing_root, &sig); diff --git a/tests/src/mock_relay.rs b/tests/src/mock_relay.rs index 4ceceef2..628be616 100644 --- a/tests/src/mock_relay.rs +++ b/tests/src/mock_relay.rs @@ -19,8 +19,10 @@ use cb_common::{ GetHeaderParams, GetHeaderResponse, SubmitBlindedBlockResponse, BUILDER_API_PATH, GET_HEADER_PATH, GET_STATUS_PATH, REGISTER_VALIDATOR_PATH, SUBMIT_BLOCK_PATH, }, - signer::ConsensusSigner, + signature::sign_builder_root, + signer::BlsSecretKey, types::Chain, + utils::blst_pubkey_to_alloy, }; use tokio::net::TcpListener; use tracing::debug; @@ -38,7 +40,7 @@ pub async fn start_mock_relay_service(state: Arc, port: u16) -> pub struct MockRelayState { pub chain: Chain, - pub signer: ConsensusSigner, + pub signer: BlsSecretKey, received_get_header: Arc, received_get_status: Arc, received_register_validator: Arc, @@ -61,11 +63,10 @@ impl MockRelayState { } impl MockRelayState { - pub fn new(chain: Chain, signer: ConsensusSigner) -> Self { + pub fn new(chain: Chain, signer: BlsSecretKey) -> Self { Self { chain, signer, - received_get_header: Default::default(), received_get_status: Default::default(), received_register_validator: Default::default(), @@ -95,9 +96,9 @@ async fn handle_get_header( response.data.message.header.parent_hash = parent_hash; response.data.message.header.block_hash.0[0] = 1; response.data.message.set_value(U256::from(10)); - response.data.message.pubkey = state.signer.pubkey().into(); + response.data.message.pubkey = blst_pubkey_to_alloy(&state.signer.sk_to_pk()); let object_root = response.data.message.tree_hash_root().0; - response.data.signature = state.signer.sign(state.chain, object_root).await; + response.data.signature = sign_builder_root(state.chain, &state.signer, object_root); (StatusCode::OK, axum::Json(response)).into_response() } diff --git a/tests/tests/pbs_integration.rs b/tests/tests/pbs_integration.rs index 13300854..750d0147 100644 --- a/tests/tests/pbs_integration.rs +++ b/tests/tests/pbs_integration.rs @@ -4,8 +4,9 @@ use alloy::primitives::U256; use cb_common::{ config::{PbsConfig, PbsModuleConfig}, pbs::RelayClient, - signer::ConsensusSigner, + signer::{schemes::bls::random_secret, BlsPublicKey}, types::Chain, + utils::blst_pubkey_to_alloy, }; use cb_pbs::{DefaultBuilderApi, PbsService, PbsState}; use cb_tests::{ @@ -43,13 +44,14 @@ fn to_pbs_config(chain: Chain, pbs_config: PbsConfig, relays: Vec) #[tokio::test] async fn test_get_header() -> Result<()> { setup_test_env(); - let signer = ConsensusSigner::new_random(); + let signer = random_secret(); + let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()).into(); let chain = Chain::Holesky; let port = 3000; - let mock_relay = generate_mock_relay(port + 1, *signer.pubkey())?; let mock_state = Arc::new(MockRelayState::new(chain, signer)); + let mock_relay = generate_mock_relay(port + 1, *pubkey)?; tokio::spawn(start_mock_relay_service(mock_state.clone(), port + 1)); let config = to_pbs_config(chain, get_pbs_static_config(port), vec![mock_relay]); @@ -71,15 +73,14 @@ async fn test_get_header() -> Result<()> { #[tokio::test] async fn test_get_status() -> Result<()> { setup_test_env(); - let signer = ConsensusSigner::new_random(); + let signer = random_secret(); + let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()).into(); let chain = Chain::Holesky; let port = 3100; - let relays = vec![ - generate_mock_relay(port + 1, *signer.pubkey())?, - generate_mock_relay(port + 2, *signer.pubkey())?, - ]; + let relays = + vec![generate_mock_relay(port + 1, *pubkey)?, generate_mock_relay(port + 2, *pubkey)?]; let mock_state = Arc::new(MockRelayState::new(chain, signer)); tokio::spawn(start_mock_relay_service(mock_state.clone(), port + 1)); tokio::spawn(start_mock_relay_service(mock_state.clone(), port + 2)); @@ -103,12 +104,13 @@ async fn test_get_status() -> Result<()> { #[tokio::test] async fn test_register_validators() -> Result<()> { setup_test_env(); - let signer = ConsensusSigner::new_random(); + let signer = random_secret(); + let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()).into(); let chain = Chain::Holesky; let port = 3300; - let relays = vec![generate_mock_relay(port + 1, *signer.pubkey())?]; + let relays = vec![generate_mock_relay(port + 1, *pubkey)?]; let mock_state = Arc::new(MockRelayState::new(chain, signer)); tokio::spawn(start_mock_relay_service(mock_state.clone(), port + 1)); @@ -131,12 +133,13 @@ async fn test_register_validators() -> Result<()> { #[tokio::test] async fn test_submit_block() -> Result<()> { setup_test_env(); - let signer = ConsensusSigner::new_random(); + let signer = random_secret(); + let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()).into(); let chain = Chain::Holesky; let port = 3400; - let relays = vec![generate_mock_relay(port + 1, *signer.pubkey())?]; + let relays = vec![generate_mock_relay(port + 1, *pubkey)?]; let mock_state = Arc::new(MockRelayState::new(chain, signer)); tokio::spawn(start_mock_relay_service(mock_state.clone(), port + 1));